Update LLVM to r103004.
This commit is contained in:
parent
5f970ec96e
commit
750ce4d809
11
Makefile
11
Makefile
@ -69,6 +69,14 @@ ifeq ($(MAKECMDGOALS),install-clang)
|
||||
NO_INSTALL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),install-clang-c)
|
||||
DIRS := tools/clang/tools/driver tools/clang/lib/Headers \
|
||||
tools/clang/tools/libclang tools/clang/tools/c-index-test \
|
||||
tools/clang/include/clang-c
|
||||
OPTIONAL_DIRS :=
|
||||
NO_INSTALL = 1
|
||||
endif
|
||||
|
||||
ifeq ($(MAKECMDGOALS),clang-only)
|
||||
DIRS := $(filter-out tools runtime docs unittests, $(DIRS)) tools/clang
|
||||
OPTIONAL_DIRS :=
|
||||
@ -110,6 +118,8 @@ cross-compile-build-tools:
|
||||
ENABLE_COVERAGE=$(ENABLE_COVERAGE) \
|
||||
DISABLE_ASSERTIONS=$(DISABLE_ASSERTIONS) \
|
||||
ENABLE_EXPENSIVE_CHECKS=$(ENABLE_EXPENSIVE_CHECKS) \
|
||||
CFLAGS= \
|
||||
CXXFLAGS= \
|
||||
) || exit 1;
|
||||
endif
|
||||
|
||||
@ -143,6 +153,7 @@ clang-only: all
|
||||
tools-only: all
|
||||
libs-only: all
|
||||
install-clang: install
|
||||
install-clang-c: install
|
||||
install-libs: install
|
||||
|
||||
#------------------------------------------------------------------------
|
||||
|
@ -337,3 +337,7 @@ ENABLE_LLVMC_DYNAMIC_PLUGINS = 1
|
||||
NO_MISSING_FIELD_INITIALIZERS = @NO_MISSING_FIELD_INITIALIZERS@
|
||||
# -Wno-variadic-macros
|
||||
NO_VARIADIC_MACROS = @NO_VARIADIC_MACROS@
|
||||
|
||||
# Flags supported by the linker.
|
||||
# bfd ld / gold -retain-symbols-file file
|
||||
HAVE_LINK_RETAIN_SYMBOLS_FILE = @HAVE_LINK_RETAIN_SYMBOLS_FILE@
|
||||
|
@ -388,7 +388,6 @@ endif
|
||||
# If REQUIRES_RTTI=1 is specified then don't disable run-time type id.
|
||||
ifneq ($(REQUIRES_RTTI), 1)
|
||||
CXX.Flags += -fno-rtti
|
||||
CXXFLAGS += -fno-rtti
|
||||
endif
|
||||
|
||||
ifdef ENABLE_COVERAGE
|
||||
@ -561,7 +560,7 @@ ifeq ($(HOST_OS),Darwin)
|
||||
# Get "4" out of 10.4 for later pieces in the makefile.
|
||||
DARWIN_MAJVERS := $(shell echo $(DARWIN_VERSION)| sed -E 's/10.([0-9]).*/\1/')
|
||||
|
||||
SharedLinkOptions=-Wl,-flat_namespace -Wl,-undefined -Wl,suppress \
|
||||
SharedLinkOptions=-Wl,-flat_namespace -Wl,-undefined,suppress \
|
||||
-dynamiclib
|
||||
ifneq ($(ARCH),ARM)
|
||||
SharedLinkOptions += -mmacosx-version-min=$(DARWIN_VERSION)
|
||||
@ -581,13 +580,6 @@ ifeq ($(TARGET_OS),Darwin)
|
||||
endif
|
||||
endif
|
||||
|
||||
# Adjust LD.Flags depending on the kind of library that is to be built. Note
|
||||
# that if LOADABLE_MODULE is specified then the resulting shared library can
|
||||
# be opened with dlopen.
|
||||
ifdef LOADABLE_MODULE
|
||||
LD.Flags += -module
|
||||
endif
|
||||
|
||||
ifdef SHARED_LIBRARY
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
LD.Flags += $(RPATH) -Wl,$(LibDir)
|
||||
@ -640,6 +632,8 @@ CompileCommonOpts += -pedantic -Wno-long-long
|
||||
endif
|
||||
CompileCommonOpts += -Wall -W -Wno-unused-parameter -Wwrite-strings \
|
||||
$(EXTRA_OPTIONS)
|
||||
# Enable cast-qual for C++; the workaround is to use const_cast.
|
||||
CXX.Flags += -Wcast-qual
|
||||
|
||||
ifeq ($(HOST_OS),HP-UX)
|
||||
CompileCommonOpts := -D_REENTRANT -D_HPUX_SOURCE
|
||||
@ -970,6 +964,36 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# Set up the library exports file.
|
||||
ifdef EXPORTED_SYMBOL_FILE
|
||||
|
||||
# First, set up the native export file, which may differ from the source
|
||||
# export file.
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
# Darwin convention prefixes symbols with underscores.
|
||||
NativeExportsFile := $(ObjDir)/$(notdir $(EXPORTED_SYMBOL_FILE)).sed
|
||||
$(NativeExportsFile): $(EXPORTED_SYMBOL_FILE) $(ObjDir)/.dir
|
||||
$(Verb) sed -e 's/[[:<:]]/_/' < $< > $@
|
||||
clean-local::
|
||||
-$(Verb) $(RM) -f $(NativeExportsFile)
|
||||
else
|
||||
NativeExportsFile := $(EXPORTED_SYMBOL_FILE)
|
||||
endif
|
||||
|
||||
# Now add the linker command-line options to use the native export file.
|
||||
|
||||
ifeq ($(HOST_OS),Darwin)
|
||||
LLVMLibsOptions += -Wl,-exported_symbols_list,$(NativeExportsFile)
|
||||
endif
|
||||
|
||||
# gold, bfd ld, etc.
|
||||
ifeq ($(HAVE_LINK_RETAIN_SYMBOLS_FILE),1)
|
||||
LLVMLibsOptions += -Wl,-retain-symbols-file,$(NativeExportsFile)
|
||||
endif
|
||||
|
||||
endif
|
||||
|
||||
###############################################################################
|
||||
# Library Build Rules: Four ways to build a library
|
||||
###############################################################################
|
||||
@ -1060,6 +1084,10 @@ ifdef SHARED_LIBRARY
|
||||
|
||||
all-local:: $(LibName.SO)
|
||||
|
||||
ifdef EXPORTED_SYMBOL_FILE
|
||||
$(LibName.SO): $(NativeExportsFile)
|
||||
endif
|
||||
|
||||
ifdef LINK_LIBS_IN_SHARED
|
||||
ifdef LOADABLE_MODULE
|
||||
SharedLibKindMessage := "Loadable Module"
|
||||
@ -1207,6 +1235,12 @@ install-local::
|
||||
uninstall-local::
|
||||
$(Echo) Uninstall circumvented with NO_INSTALL
|
||||
else
|
||||
ifdef NO_INSTALL_ARCHIVES
|
||||
install-local::
|
||||
$(Echo) Install circumvented with NO_INSTALL
|
||||
uninstall-local::
|
||||
$(Echo) Uninstall circumvented with NO_INSTALL
|
||||
else
|
||||
DestArchiveLib := $(DESTDIR)$(PROJ_libdir)/lib$(LIBRARYNAME).a
|
||||
|
||||
install-local:: $(DestArchiveLib)
|
||||
@ -1221,6 +1255,7 @@ uninstall-local::
|
||||
-$(Verb) $(RM) -f $(DestArchiveLib)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
# endif LIBRARYNAME
|
||||
endif
|
||||
@ -1262,7 +1297,7 @@ ifeq ($(HOST_OS),Darwin)
|
||||
|
||||
# Tiger tools don't support this.
|
||||
ifneq ($(DARWIN_MAJVERS),4)
|
||||
LD.Flags += -Wl,-exported_symbol -Wl,_main
|
||||
LD.Flags += -Wl,-exported_symbol,_main
|
||||
endif
|
||||
endif
|
||||
|
||||
@ -1331,7 +1366,7 @@ DestToolAlias = $(DESTDIR)$(PROJ_bindir)/$(TOOLALIAS)$(EXEEXT)
|
||||
|
||||
install-local:: $(DestToolAlias)
|
||||
|
||||
$(DestToolAlias): $(DestTool) $(PROJ_bindir)
|
||||
$(DestToolAlias): $(DestTool)
|
||||
$(Echo) Installing $(BuildMode) $(DestToolAlias)
|
||||
$(Verb) $(RM) -f $(DestToolAlias)
|
||||
$(Verb) $(AliasTool) $(TOOLEXENAME) $(DestToolAlias)
|
||||
|
@ -159,6 +159,11 @@ AC_CACHE_CHECK([type of operating system we're going to host on],
|
||||
llvm_cv_no_link_all_option="-Wl,-noall_load"
|
||||
llvm_cv_os_type="Darwin"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-minix*)
|
||||
llvm_cv_link_all_option="-Wl,-all_load"
|
||||
llvm_cv_no_link_all_option="-Wl,-noall_load"
|
||||
llvm_cv_os_type="Minix"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-freebsd*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
@ -247,6 +252,8 @@ AC_CACHE_CHECK([type of operating system we're going to target],
|
||||
llvm_cv_target_os_type="Cygwin" ;;
|
||||
*-*-darwin*)
|
||||
llvm_cv_target_os_type="Darwin" ;;
|
||||
*-*-minix*)
|
||||
llvm_cv_target_os_type="Minix" ;;
|
||||
*-*-freebsd*)
|
||||
llvm_cv_target_os_type="FreeBSD" ;;
|
||||
*-*-openbsd*)
|
||||
@ -721,8 +728,9 @@ AC_MSG_CHECKING([optimization flags])
|
||||
case "$withval" in
|
||||
default)
|
||||
case "$llvm_cv_os_type" in
|
||||
MingW) optimize_option=-O3 ;;
|
||||
*) optimize_option=-O2 ;;
|
||||
FreeBSD) optimize_option=-O2 ;;
|
||||
MingW) optimize_option=-O2 ;;
|
||||
*) optimize_option=-O3 ;;
|
||||
esac ;;
|
||||
*) optimize_option="$withval" ;;
|
||||
esac
|
||||
@ -1015,6 +1023,9 @@ AC_LINK_USE_R
|
||||
dnl Determine whether the linker supports the -export-dynamic option.
|
||||
AC_LINK_EXPORT_DYNAMIC
|
||||
|
||||
dnl Determine whether the linker supports the -retain-symbols-file option.
|
||||
AC_LINK_RETAIN_SYMBOLS_FILE
|
||||
|
||||
dnl Check for libtool and the library that has dlopen function (which must come
|
||||
dnl before the AC_PROG_LIBTOOL check in order to enable dlopening libraries with
|
||||
dnl libtool).
|
||||
@ -1283,7 +1294,7 @@ AC_CHECK_FUNCS([backtrace ceilf floorf roundf rintf nearbyintf getcwd ])
|
||||
AC_CHECK_FUNCS([powf fmodf strtof round ])
|
||||
AC_CHECK_FUNCS([getpagesize getrusage getrlimit setrlimit gettimeofday ])
|
||||
AC_CHECK_FUNCS([isatty mkdtemp mkstemp ])
|
||||
AC_CHECK_FUNCS([mktemp realpath sbrk setrlimit strdup ])
|
||||
AC_CHECK_FUNCS([mktemp posix_spawn realpath sbrk setrlimit strdup ])
|
||||
AC_CHECK_FUNCS([strerror strerror_r strerror_s setenv ])
|
||||
AC_CHECK_FUNCS([strtoll strtoq sysconf malloc_zone_statistics ])
|
||||
AC_CHECK_FUNCS([setjmp longjmp sigsetjmp siglongjmp])
|
||||
|
@ -8,7 +8,7 @@ AC_DEFUN([AC_LINK_USE_R],
|
||||
[ AC_LANG_PUSH([C])
|
||||
oldcflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wl,-R."
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[int main() { return 0; }]])],
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
|
||||
[llvm_cv_link_use_r=yes],[llvm_cv_link_use_r=no])
|
||||
CFLAGS="$oldcflags"
|
||||
AC_LANG_POP([C])
|
||||
@ -29,7 +29,7 @@ AC_DEFUN([AC_LINK_EXPORT_DYNAMIC],
|
||||
[ AC_LANG_PUSH([C])
|
||||
oldcflags="$CFLAGS"
|
||||
CFLAGS="$CFLAGS -Wl,-export-dynamic"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[int main() { return 0; }]])],
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
|
||||
[llvm_cv_link_use_export_dynamic=yes],[llvm_cv_link_use_export_dynamic=no])
|
||||
CFLAGS="$oldcflags"
|
||||
AC_LANG_POP([C])
|
||||
@ -39,3 +39,46 @@ if test "$llvm_cv_link_use_export_dynamic" = yes ; then
|
||||
fi
|
||||
])
|
||||
|
||||
#
|
||||
# Determine if the system can handle the -retain-symbols-file option being
|
||||
# passed to the linker.
|
||||
#
|
||||
# This macro is specific to LLVM.
|
||||
#
|
||||
AC_DEFUN([AC_LINK_RETAIN_SYMBOLS_FILE],
|
||||
[AC_CACHE_CHECK([for compiler -Wl,-retain-symbols-file option],
|
||||
[llvm_cv_link_use_retain_symbols_file],
|
||||
[ AC_LANG_PUSH([C])
|
||||
oldcflags="$CFLAGS"
|
||||
|
||||
# The following code is from the autoconf manual,
|
||||
# "11.13: Limitations of Usual Tools".
|
||||
# Create a temporary directory $tmp in $TMPDIR (default /tmp).
|
||||
# Use mktemp if possible; otherwise fall back on mkdir,
|
||||
# with $RANDOM to make collisions less likely.
|
||||
: ${TMPDIR=/tmp}
|
||||
{
|
||||
tmp=`
|
||||
(umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null
|
||||
` &&
|
||||
test -n "$tmp" && test -d "$tmp"
|
||||
} || {
|
||||
tmp=$TMPDIR/foo$$-$RANDOM
|
||||
(umask 077 && mkdir "$tmp")
|
||||
} || exit $?
|
||||
|
||||
echo "main" > "$tmp/exports"
|
||||
|
||||
CFLAGS="$CFLAGS -Wl,-retain-symbols-file=$tmp/exports"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])],
|
||||
[llvm_cv_link_use_retain_symbols_file=yes],[llvm_cv_link_use_retain_symbols_file=no])
|
||||
rm "$tmp/exports"
|
||||
rmdir "$tmp"
|
||||
CFLAGS="$oldcflags"
|
||||
AC_LANG_POP([C])
|
||||
])
|
||||
if test "$llvm_cv_link_use_retain_symbols_file" = yes ; then
|
||||
AC_SUBST(HAVE_LINK_RETAIN_SYMBOLS_FILE,1)
|
||||
fi
|
||||
])
|
||||
|
||||
|
@ -90,13 +90,13 @@ module Attribute = struct
|
||||
| Optsize
|
||||
| Ssp
|
||||
| Sspreq
|
||||
| Alignment
|
||||
| Alignment of int
|
||||
| Nocapture
|
||||
| Noredzone
|
||||
| Noimplicitfloat
|
||||
| Naked
|
||||
| Inlinehint
|
||||
| Stackalignment
|
||||
| Stackalignment of int
|
||||
end
|
||||
|
||||
module Icmp = struct
|
||||
@ -170,6 +170,8 @@ external delete_type_name : string -> llmodule -> unit
|
||||
external type_by_name : llmodule -> string -> lltype option
|
||||
= "llvm_type_by_name"
|
||||
external dump_module : llmodule -> unit = "llvm_dump_module"
|
||||
external set_module_inline_asm : llmodule -> string -> unit
|
||||
= "llvm_set_module_inline_asm"
|
||||
|
||||
(*===-- Types -------------------------------------------------------------===*)
|
||||
external classify_type : lltype -> TypeKind.t = "llvm_classify_type"
|
||||
@ -548,10 +550,42 @@ let rec fold_right_function_range f i e init =
|
||||
let fold_right_functions f m init =
|
||||
fold_right_function_range f (function_end m) (At_start m) init
|
||||
|
||||
external add_function_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_add_function_attr"
|
||||
external remove_function_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_remove_function_attr"
|
||||
external llvm_add_function_attr : llvalue -> int -> unit
|
||||
= "llvm_add_function_attr"
|
||||
external llvm_remove_function_attr : llvalue -> int -> unit
|
||||
= "llvm_remove_function_attr"
|
||||
|
||||
let pack_attr (attr:Attribute.t) : int =
|
||||
match attr with
|
||||
Attribute.Zext -> 1 lsl 0
|
||||
| Attribute.Sext -> 1 lsl 1
|
||||
| Attribute.Noreturn -> 1 lsl 2
|
||||
| Attribute.Inreg -> 1 lsl 3
|
||||
| Attribute.Structret -> 1 lsl 4
|
||||
| Attribute.Nounwind -> 1 lsl 5
|
||||
| Attribute.Noalias -> 1 lsl 6
|
||||
| Attribute.Byval -> 1 lsl 7
|
||||
| Attribute.Nest -> 1 lsl 8
|
||||
| Attribute.Readnone -> 1 lsl 9
|
||||
| Attribute.Readonly -> 1 lsl 10
|
||||
| Attribute.Noinline -> 1 lsl 11
|
||||
| Attribute.Alwaysinline -> 1 lsl 12
|
||||
| Attribute.Optsize -> 1 lsl 13
|
||||
| Attribute.Ssp -> 1 lsl 14
|
||||
| Attribute.Sspreq -> 1 lsl 15
|
||||
| Attribute.Alignment n -> n lsl 16
|
||||
| Attribute.Nocapture -> 1 lsl 21
|
||||
| Attribute.Noredzone -> 1 lsl 22
|
||||
| Attribute.Noimplicitfloat -> 1 lsl 23
|
||||
| Attribute.Naked -> 1 lsl 24
|
||||
| Attribute.Inlinehint -> 1 lsl 25
|
||||
| Attribute.Stackalignment n -> n lsl 26
|
||||
|
||||
let add_function_attr llval attr =
|
||||
llvm_add_function_attr llval (pack_attr attr)
|
||||
|
||||
let remove_function_attr llval attr =
|
||||
llvm_remove_function_attr llval (pack_attr attr)
|
||||
|
||||
(*--... Operations on params ...............................................--*)
|
||||
external params : llvalue -> llvalue array = "llvm_params"
|
||||
@ -602,10 +636,17 @@ let rec fold_right_param_range f init i e =
|
||||
let fold_right_params f fn init =
|
||||
fold_right_param_range f init (param_end fn) (At_start fn)
|
||||
|
||||
external add_param_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_add_param_attr"
|
||||
external remove_param_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_remove_param_attr"
|
||||
external llvm_add_param_attr : llvalue -> int -> unit
|
||||
= "llvm_add_param_attr"
|
||||
external llvm_remove_param_attr : llvalue -> int -> unit
|
||||
= "llvm_remove_param_attr"
|
||||
|
||||
let add_param_attr llval attr =
|
||||
llvm_add_param_attr llval (pack_attr attr)
|
||||
|
||||
let remove_param_attr llval attr =
|
||||
llvm_remove_param_attr llval (pack_attr attr)
|
||||
|
||||
external set_param_alignment : llvalue -> int -> unit
|
||||
= "llvm_set_param_alignment"
|
||||
|
||||
@ -727,10 +768,17 @@ external instruction_call_conv: llvalue -> int
|
||||
= "llvm_instruction_call_conv"
|
||||
external set_instruction_call_conv: int -> llvalue -> unit
|
||||
= "llvm_set_instruction_call_conv"
|
||||
external add_instruction_param_attr : llvalue -> int -> Attribute.t -> unit
|
||||
= "llvm_add_instruction_param_attr"
|
||||
external remove_instruction_param_attr : llvalue -> int -> Attribute.t -> unit
|
||||
= "llvm_remove_instruction_param_attr"
|
||||
|
||||
external llvm_add_instruction_param_attr : llvalue -> int -> int -> unit
|
||||
= "llvm_add_instruction_param_attr"
|
||||
external llvm_remove_instruction_param_attr : llvalue -> int -> int -> unit
|
||||
= "llvm_remove_instruction_param_attr"
|
||||
|
||||
let add_instruction_param_attr llval i attr =
|
||||
llvm_add_instruction_param_attr llval i (pack_attr attr)
|
||||
|
||||
let remove_instruction_param_attr llval i attr =
|
||||
llvm_remove_instruction_param_attr llval i (pack_attr attr)
|
||||
|
||||
(*--... Operations on call instructions (only) .............................--*)
|
||||
external is_tail_call : llvalue -> bool = "llvm_is_tail_call"
|
||||
|
@ -139,13 +139,13 @@ module Attribute : sig
|
||||
| Optsize
|
||||
| Ssp
|
||||
| Sspreq
|
||||
| Alignment
|
||||
| Alignment of int
|
||||
| Nocapture
|
||||
| Noredzone
|
||||
| Noimplicitfloat
|
||||
| Naked
|
||||
| Inlinehint
|
||||
| Stackalignment
|
||||
| Stackalignment of int
|
||||
end
|
||||
|
||||
(** The predicate for an integer comparison ([icmp]) instruction.
|
||||
@ -284,6 +284,11 @@ external type_by_name : llmodule -> string -> lltype option
|
||||
error. See the method [llvm::Module::dump]. *)
|
||||
external dump_module : llmodule -> unit = "llvm_dump_module"
|
||||
|
||||
(** [set_module_inline_asm m asm] sets the inline assembler for the module. See
|
||||
the method [llvm::Module::setModuleInlineAsm]. *)
|
||||
external set_module_inline_asm : llmodule -> string -> unit
|
||||
= "llvm_set_module_inline_asm"
|
||||
|
||||
|
||||
(** {6 Types} *)
|
||||
|
||||
@ -1282,13 +1287,11 @@ external set_gc : string option -> llvalue -> unit = "llvm_set_gc"
|
||||
|
||||
(** [add_function_attr f a] adds attribute [a] to the return type of function
|
||||
[f]. *)
|
||||
external add_function_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_add_function_attr"
|
||||
val add_function_attr : llvalue -> Attribute.t -> unit
|
||||
|
||||
(** [remove_function_attr f a] removes attribute [a] from the return type of
|
||||
function [f]. *)
|
||||
external remove_function_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_remove_function_attr"
|
||||
val remove_function_attr : llvalue -> Attribute.t -> unit
|
||||
|
||||
(** {7 Operations on params} *)
|
||||
|
||||
@ -1343,11 +1346,10 @@ val rev_iter_params : (llvalue -> unit) -> llvalue -> unit
|
||||
val fold_right_params : (llvalue -> 'a -> 'a) -> llvalue -> 'a -> 'a
|
||||
|
||||
(** [add_param p a] adds attribute [a] to parameter [p]. *)
|
||||
external add_param_attr : llvalue -> Attribute.t -> unit = "llvm_add_param_attr"
|
||||
val add_param_attr : llvalue -> Attribute.t -> unit
|
||||
|
||||
(** [remove_param_attr p a] removes attribute [a] from parameter [p]. *)
|
||||
external remove_param_attr : llvalue -> Attribute.t -> unit
|
||||
= "llvm_remove_param_attr"
|
||||
val remove_param_attr : llvalue -> Attribute.t -> unit
|
||||
|
||||
(** [set_param_alignment p a] set the alignment of parameter [p] to [a]. *)
|
||||
external set_param_alignment : llvalue -> int -> unit
|
||||
@ -1499,14 +1501,12 @@ external set_instruction_call_conv: int -> llvalue -> unit
|
||||
(** [add_instruction_param_attr ci i a] adds attribute [a] to the [i]th
|
||||
parameter of the call or invoke instruction [ci]. [i]=0 denotes the return
|
||||
value. *)
|
||||
external add_instruction_param_attr : llvalue -> int -> Attribute.t -> unit
|
||||
= "llvm_add_instruction_param_attr"
|
||||
val add_instruction_param_attr : llvalue -> int -> Attribute.t -> unit
|
||||
|
||||
(** [remove_instruction_param_attr ci i a] removes attribute [a] from the
|
||||
[i]th parameter of the call or invoke instruction [ci]. [i]=0 denotes the
|
||||
return value. *)
|
||||
external remove_instruction_param_attr : llvalue -> int -> Attribute.t -> unit
|
||||
= "llvm_remove_instruction_param_attr"
|
||||
val remove_instruction_param_attr : llvalue -> int -> Attribute.t -> unit
|
||||
|
||||
(** {Operations on call instructions (only)} *)
|
||||
|
||||
|
@ -182,6 +182,11 @@ CAMLprim value llvm_dump_module(LLVMModuleRef M) {
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llmodule -> string -> unit */
|
||||
CAMLprim value llvm_set_module_inline_asm(LLVMModuleRef M, value Asm) {
|
||||
LLVMSetModuleInlineAsm(M, String_val(Asm));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/*===-- Types -------------------------------------------------------------===*/
|
||||
|
||||
@ -941,13 +946,13 @@ CAMLprim value llvm_set_gc(value GC, LLVMValueRef Fn) {
|
||||
|
||||
/* llvalue -> Attribute.t -> unit */
|
||||
CAMLprim value llvm_add_function_attr(LLVMValueRef Arg, value PA) {
|
||||
LLVMAddFunctionAttr(Arg, 1<<Int_val(PA));
|
||||
LLVMAddFunctionAttr(Arg, Int_val(PA));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> Attribute.t -> unit */
|
||||
CAMLprim value llvm_remove_function_attr(LLVMValueRef Arg, value PA) {
|
||||
LLVMRemoveFunctionAttr(Arg, 1<<Int_val(PA));
|
||||
LLVMRemoveFunctionAttr(Arg, Int_val(PA));
|
||||
return Val_unit;
|
||||
}
|
||||
/*--... Operations on parameters ...........................................--*/
|
||||
@ -968,13 +973,13 @@ CAMLprim value llvm_params(LLVMValueRef Fn, value Index) {
|
||||
|
||||
/* llvalue -> Attribute.t -> unit */
|
||||
CAMLprim value llvm_add_param_attr(LLVMValueRef Arg, value PA) {
|
||||
LLVMAddAttribute(Arg, 1<<Int_val(PA));
|
||||
LLVMAddAttribute(Arg, Int_val(PA));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
/* llvalue -> Attribute.t -> unit */
|
||||
CAMLprim value llvm_remove_param_attr(LLVMValueRef Arg, value PA) {
|
||||
LLVMRemoveAttribute(Arg, 1<<Int_val(PA));
|
||||
LLVMRemoveAttribute(Arg, Int_val(PA));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
@ -1042,7 +1047,7 @@ CAMLprim value llvm_set_instruction_call_conv(value CC, LLVMValueRef Inst) {
|
||||
CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
|
||||
value index,
|
||||
value PA) {
|
||||
LLVMAddInstrAttribute(Instr, Int_val(index), 1<<Int_val(PA));
|
||||
LLVMAddInstrAttribute(Instr, Int_val(index), Int_val(PA));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
@ -1050,7 +1055,7 @@ CAMLprim value llvm_add_instruction_param_attr(LLVMValueRef Instr,
|
||||
CAMLprim value llvm_remove_instruction_param_attr(LLVMValueRef Instr,
|
||||
value index,
|
||||
value PA) {
|
||||
LLVMRemoveInstrAttribute(Instr, Int_val(index), 1<<Int_val(PA));
|
||||
LLVMRemoveInstrAttribute(Instr, Int_val(index), Int_val(PA));
|
||||
return Val_unit;
|
||||
}
|
||||
|
||||
|
135
configure
vendored
135
configure
vendored
@ -749,6 +749,7 @@ OCAMLOPT
|
||||
OCAMLDEP
|
||||
OCAMLDOC
|
||||
GAS
|
||||
HAVE_LINK_RETAIN_SYMBOLS_FILE
|
||||
INSTALL_LTDL_TRUE
|
||||
INSTALL_LTDL_FALSE
|
||||
CONVENIENCE_LTDL_TRUE
|
||||
@ -2166,6 +2167,11 @@ else
|
||||
llvm_cv_no_link_all_option="-Wl,-noall_load"
|
||||
llvm_cv_os_type="Darwin"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-minix*)
|
||||
llvm_cv_link_all_option="-Wl,-all_load"
|
||||
llvm_cv_no_link_all_option="-Wl,-noall_load"
|
||||
llvm_cv_os_type="Minix"
|
||||
llvm_cv_platform_type="Unix" ;;
|
||||
*-*-freebsd*)
|
||||
llvm_cv_link_all_option="-Wl,--whole-archive"
|
||||
llvm_cv_no_link_all_option="-Wl,--no-whole-archive"
|
||||
@ -2260,6 +2266,8 @@ else
|
||||
llvm_cv_target_os_type="Cygwin" ;;
|
||||
*-*-darwin*)
|
||||
llvm_cv_target_os_type="Darwin" ;;
|
||||
*-*-minix*)
|
||||
llvm_cv_target_os_type="Minix" ;;
|
||||
*-*-freebsd*)
|
||||
llvm_cv_target_os_type="FreeBSD" ;;
|
||||
*-*-openbsd*)
|
||||
@ -5162,8 +5170,9 @@ 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 ;;
|
||||
FreeBSD) optimize_option=-O2 ;;
|
||||
MingW) optimize_option=-O2 ;;
|
||||
*) optimize_option=-O3 ;;
|
||||
esac ;;
|
||||
*) optimize_option="$withval" ;;
|
||||
esac
|
||||
@ -8626,7 +8635,7 @@ cat >>conftest.$ac_ext <<_ACEOF
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int main() { return 0; }
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@ -8718,7 +8727,7 @@ cat >>conftest.$ac_ext <<_ACEOF
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int main() { return 0; }
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
@ -8787,6 +8796,116 @@ _ACEOF
|
||||
fi
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for compiler -Wl,-retain-symbols-file option" >&5
|
||||
echo $ECHO_N "checking for compiler -Wl,-retain-symbols-file option... $ECHO_C" >&6; }
|
||||
if test "${llvm_cv_link_use_retain_symbols_file+set}" = set; then
|
||||
echo $ECHO_N "(cached) $ECHO_C" >&6
|
||||
else
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
oldcflags="$CFLAGS"
|
||||
|
||||
# The following code is from the autoconf manual,
|
||||
# "11.13: Limitations of Usual Tools".
|
||||
# Create a temporary directory $tmp in $TMPDIR (default /tmp).
|
||||
# Use mktemp if possible; otherwise fall back on mkdir,
|
||||
# with $RANDOM to make collisions less likely.
|
||||
: ${TMPDIR=/tmp}
|
||||
{
|
||||
tmp=`
|
||||
(umask 077 && mktemp -d "$TMPDIR/fooXXXXXX") 2>/dev/null
|
||||
` &&
|
||||
test -n "$tmp" && test -d "$tmp"
|
||||
} || {
|
||||
tmp=$TMPDIR/foo$$-$RANDOM
|
||||
(umask 077 && mkdir "$tmp")
|
||||
} || exit $?
|
||||
|
||||
echo "main" > "$tmp/exports"
|
||||
|
||||
CFLAGS="$CFLAGS -Wl,-retain-symbols-file=$tmp/exports"
|
||||
cat >conftest.$ac_ext <<_ACEOF
|
||||
/* confdefs.h. */
|
||||
_ACEOF
|
||||
cat confdefs.h >>conftest.$ac_ext
|
||||
cat >>conftest.$ac_ext <<_ACEOF
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
rm -f conftest.$ac_objext conftest$ac_exeext
|
||||
if { (ac_try="$ac_link"
|
||||
case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_link") 2>conftest.er1
|
||||
ac_status=$?
|
||||
grep -v '^ *+' conftest.er1 >conftest.err
|
||||
rm -f conftest.er1
|
||||
cat conftest.err >&5
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); } &&
|
||||
{ ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; } &&
|
||||
{ ac_try='test -s conftest$ac_exeext'
|
||||
{ (case "(($ac_try" in
|
||||
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
|
||||
*) ac_try_echo=$ac_try;;
|
||||
esac
|
||||
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
|
||||
(eval "$ac_try") 2>&5
|
||||
ac_status=$?
|
||||
echo "$as_me:$LINENO: \$? = $ac_status" >&5
|
||||
(exit $ac_status); }; }; then
|
||||
llvm_cv_link_use_retain_symbols_file=yes
|
||||
else
|
||||
echo "$as_me: failed program was:" >&5
|
||||
sed 's/^/| /' conftest.$ac_ext >&5
|
||||
|
||||
llvm_cv_link_use_retain_symbols_file=no
|
||||
fi
|
||||
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
rm "$tmp/exports"
|
||||
rmdir "$tmp"
|
||||
CFLAGS="$oldcflags"
|
||||
ac_ext=c
|
||||
ac_cpp='$CPP $CPPFLAGS'
|
||||
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
|
||||
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
|
||||
ac_compiler_gnu=$ac_cv_c_compiler_gnu
|
||||
|
||||
|
||||
fi
|
||||
{ echo "$as_me:$LINENO: result: $llvm_cv_link_use_retain_symbols_file" >&5
|
||||
echo "${ECHO_T}$llvm_cv_link_use_retain_symbols_file" >&6; }
|
||||
if test "$llvm_cv_link_use_retain_symbols_file" = yes ; then
|
||||
HAVE_LINK_RETAIN_SYMBOLS_FILE=1
|
||||
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
||||
{ echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
|
||||
@ -11156,7 +11275,7 @@ else
|
||||
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
|
||||
lt_status=$lt_dlunknown
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 11159 "configure"
|
||||
#line 11278 "configure"
|
||||
#include "confdefs.h"
|
||||
|
||||
#if HAVE_DLFCN_H
|
||||
@ -17749,7 +17868,8 @@ done
|
||||
|
||||
|
||||
|
||||
for ac_func in mktemp realpath sbrk setrlimit strdup
|
||||
|
||||
for ac_func in mktemp posix_spawn realpath sbrk setrlimit strdup
|
||||
do
|
||||
as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
|
||||
{ echo "$as_me:$LINENO: checking for $ac_func" >&5
|
||||
@ -21069,6 +21189,7 @@ OCAMLOPT!$OCAMLOPT$ac_delim
|
||||
OCAMLDEP!$OCAMLDEP$ac_delim
|
||||
OCAMLDOC!$OCAMLDOC$ac_delim
|
||||
GAS!$GAS$ac_delim
|
||||
HAVE_LINK_RETAIN_SYMBOLS_FILE!$HAVE_LINK_RETAIN_SYMBOLS_FILE$ac_delim
|
||||
INSTALL_LTDL_TRUE!$INSTALL_LTDL_TRUE$ac_delim
|
||||
INSTALL_LTDL_FALSE!$INSTALL_LTDL_FALSE$ac_delim
|
||||
CONVENIENCE_LTDL_TRUE!$CONVENIENCE_LTDL_TRUE$ac_delim
|
||||
@ -21112,7 +21233,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` = 91; then
|
||||
if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 92; then
|
||||
break
|
||||
elif $ac_last_try; then
|
||||
{ { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
|
||||
|
@ -1430,7 +1430,7 @@ bool RegMapping_Fer::compatible_class(MachineFunction &mf,
|
||||
instruction,
|
||||
use <tt>TargetInstrInfo::get(opcode)::ImplicitUses</tt>. Pre-colored
|
||||
registers impose constraints on any register allocation algorithm. The
|
||||
register allocator must make sure that none of them is been overwritten by
|
||||
register allocator must make sure that none of them are overwritten by
|
||||
the values of virtual registers while still alive.</p>
|
||||
|
||||
</div>
|
||||
@ -2162,7 +2162,7 @@ MOVSX32rm16 -> movsx, 32-bit register, 16-bit memory
|
||||
|
||||
<a href="mailto:sabre@nondot.org">Chris Lattner</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2010-03-25 01:03:04 +0100 (Thu, 25 Mar 2010) $
|
||||
Last modified: $Date: 2010-04-09 20:39:54 +0200 (Fri, 09 Apr 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -145,9 +145,9 @@ Disable fusing of spill code into instructions.
|
||||
|
||||
Make the -lowerinvoke pass insert expensive, but correct, EH code.
|
||||
|
||||
=item B<-enable-eh>
|
||||
=item B<-jit-enable-eh>
|
||||
|
||||
Exception handling should be emitted.
|
||||
Exception handling should be enabled in the just-in-time compiler.
|
||||
|
||||
=item B<-join-liveintervals>
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
<p>Building with link time optimization requires cooperation from the
|
||||
system linker. LTO support on Linux systems requires that you use
|
||||
the <a href="http://sourceware.org/binutils">gold linker</a> which supports
|
||||
LTO via plugins. This is the same system used by the upcoming
|
||||
LTO via plugins. This is the same mechanism used by the
|
||||
<a href="http://gcc.gnu.org/wiki/LinkTimeOptimization">GCC LTO</a>
|
||||
project.</p>
|
||||
<p>The LLVM gold plugin implements the
|
||||
@ -41,10 +41,15 @@ The same plugin can also be used by other tools such as <tt>ar</tt> and
|
||||
<div class="doc_section"><a name="build">How to build it</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
<p>You need to build gold with plugin support and build the LLVMgold
|
||||
plugin.</p>
|
||||
<p>You need to have gold with plugin support and build the LLVMgold
|
||||
plugin. Check whether you have gold running <tt>/usr/bin/ld -v</tt>. It will
|
||||
report “GNU gold” or else “GNU ld” if not. If you have
|
||||
gold, check for plugin support by running <tt>/usr/bin/ld -plugin</tt>. If it
|
||||
complains “missing argument” then you have plugin support. If not,
|
||||
such as an “unknown option” error then you will either need to
|
||||
build gold or install a version with plugin support.</p>
|
||||
<ul>
|
||||
<li>Build gold with plugin support:
|
||||
<li>To build gold with plugin support:
|
||||
<pre class="doc_code">
|
||||
mkdir binutils
|
||||
cd binutils
|
||||
@ -56,9 +61,11 @@ cd build
|
||||
../src/configure --enable-gold --enable-plugins
|
||||
make all-gold
|
||||
</pre>
|
||||
That should leave you with binutils/build/gold/ld-new which supports the
|
||||
<tt>-plugin</tt> option.
|
||||
|
||||
That should leave you with <tt>binutils/build/gold/ld-new</tt> which supports the <tt>-plugin</tt> option. It also built would have
|
||||
<tt>binutils/build/binutils/ar</tt> and <tt>nm-new</tt> which support plugins
|
||||
but don't have a visible -plugin option, instead relying on the gold plugin
|
||||
being present in <tt>../lib/bfd-plugins</tt> relative to where the binaries are
|
||||
placed.
|
||||
<li>Build the LLVMgold plugin: Configure LLVM with
|
||||
<tt>--with-binutils-include=/path/to/binutils/src/include</tt> and run
|
||||
<tt>make</tt>.
|
||||
@ -72,7 +79,7 @@ make all-gold
|
||||
the plugin <tt>.so</tt> file. To find out what link command <tt>gcc</tt>
|
||||
would run in a given situation, run <tt>gcc -v <em>[...]</em></tt> and look
|
||||
for the line where it runs <tt>collect2</tt>. Replace that with
|
||||
<tt>ld-new -plugin /path/to/LLVMgold.so</tt> to test it out. Once you're
|
||||
<tt>ld-new -plugin /path/to/libLLVMgold.so</tt> to test it out. Once you're
|
||||
ready to switch to using gold, backup your existing <tt>/usr/bin/ld</tt>
|
||||
then replace it with <tt>ld-new</tt>.</p>
|
||||
<p>You can produce bitcode files from <tt>llvm-gcc</tt> using
|
||||
@ -83,6 +90,11 @@ make all-gold
|
||||
passes the <tt>-plugin</tt> option to ld. It will not look for an alternate
|
||||
linker, which is why you need gold to be the installed system linker in your
|
||||
path.</p>
|
||||
<p>If you want <tt>ar</tt> and <tt>nm</tt> to work seamlessly as well, install
|
||||
<tt>libLLVMgold.so</tt> to <tt>/usr/lib/bfd-plugins</tt>. If you built your
|
||||
own gold, be sure to install the <tt>ar</tt> and <tt>nm-new</tt> you built to
|
||||
<tt>/usr/bin</tt>.
|
||||
<p>
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
@ -141,8 +153,9 @@ $ llvm-gcc -use-gold-plugin a.a b.o -o main # <-- link with LLVMgold plugin
|
||||
<div class="doc_section"><a name="lto_autotools">Quickstart for using LTO with autotooled projects</a></div>
|
||||
<!--=========================================================================-->
|
||||
<div class="doc_text">
|
||||
<p><tt>gold</tt>, <tt>ar</tt> and <tt>nm</tt> all support plugins now, so everything should be
|
||||
in place for an easy to use LTO build of autotooled projects:</p>
|
||||
<p>Once your system <tt>ld</tt>, <tt>ar</tt> and <tt>nm</tt> all support LLVM
|
||||
bitcode, everything is in place for an easy to use LTO build of autotooled
|
||||
projects:</p>
|
||||
<ul>
|
||||
<li>Follow the instructions <a href="#build">on how to build libLLVMgold.so</a>.</li>
|
||||
<li>Install the newly built binutils to <tt>$PREFIX</tt></li>
|
||||
@ -194,7 +207,7 @@ as much as gold could without the plugin.</p>
|
||||
src="http://www.w3.org/Icons/valid-html401-blue" alt="Valid HTML 4.01"></a>
|
||||
<a href="mailto:nicholas@metrix.on.ca">Nick Lewycky</a><br>
|
||||
<a href="http://llvm.org">The LLVM Compiler Infrastructure</a><br>
|
||||
Last modified: $Date: 2009-01-01 23:10:51 -0800 (Thu, 01 Jan 2009) $
|
||||
Last modified: $Date: 2010-04-16 23:58:21 -0800 (Fri, 16 Apr 2010) $
|
||||
</address>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -186,9 +186,6 @@ foo.bc, one of the following commands should fail:</p>
|
||||
<li><tt><b>llc</b> foo.bc</tt></li>
|
||||
<li><tt><b>llc</b> foo.bc -relocation-model=pic</tt></li>
|
||||
<li><tt><b>llc</b> foo.bc -relocation-model=static</tt></li>
|
||||
<li><tt><b>llc</b> foo.bc -enable-eh</tt></li>
|
||||
<li><tt><b>llc</b> foo.bc -relocation-model=pic -enable-eh</tt></li>
|
||||
<li><tt><b>llc</b> foo.bc -relocation-model=static -enable-eh</tt></li>
|
||||
</ol>
|
||||
|
||||
<p>If none of these crash, please follow the instructions for a
|
||||
@ -202,11 +199,6 @@ the one corresponding to the command above that failed):</p>
|
||||
-relocation-model=pic</tt></li>
|
||||
<li><tt><b>bugpoint</b> -run-llc foo.bc --tool-args
|
||||
-relocation-model=static</tt></li>
|
||||
<li><tt><b>bugpoint</b> -run-llc foo.bc --tool-args -enable-eh</tt></li>
|
||||
<li><tt><b>bugpoint</b> -run-llc foo.bc --tool-args
|
||||
-relocation-model=pic -enable-eh</tt></li>
|
||||
<li><tt><b>bugpoint</b> -run-llc foo.bc --tool-args
|
||||
-relocation-model=static -enable-eh</tt></li>
|
||||
</ol>
|
||||
|
||||
<p>Please run this, then file a bug with the instructions and reduced .bc file
|
||||
@ -348,7 +340,7 @@ the following:</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-12 16:46:08 +0200 (Mon, 12 Oct 2009) $
|
||||
Last modified: $Date: 2010-05-02 17:36:26 +0200 (Sun, 02 May 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -50,6 +50,7 @@
|
||||
<li><a href="#moduleasm">Module-Level Inline Assembly</a></li>
|
||||
<li><a href="#datalayout">Data Layout</a></li>
|
||||
<li><a href="#pointeraliasing">Pointer Aliasing Rules</a></li>
|
||||
<li><a href="#volatile">Volatile Memory Accesses</a></li>
|
||||
</ol>
|
||||
</li>
|
||||
<li><a href="#typesystem">Type System</a>
|
||||
@ -89,6 +90,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="#trapvalues">Trap Values</a></li>
|
||||
<li><a href="#blockaddress">Addresses of Basic Blocks</a></li>
|
||||
<li><a href="#constantexprs">Constant Expressions</a></li>
|
||||
</ol>
|
||||
@ -849,11 +851,15 @@ define i32 @main() { <i>; i32()* </i>
|
||||
<p>LLVM allows an explicit section to be specified for globals. If the target
|
||||
supports it, it will emit globals to the section specified.</p>
|
||||
|
||||
<p>An explicit alignment may be specified for a global. If not present, or if
|
||||
the alignment is set to zero, the alignment of the global is set by the
|
||||
target to whatever it feels convenient. If an explicit alignment is
|
||||
specified, the global is forced to have at least that much alignment. All
|
||||
alignments must be a power of 2.</p>
|
||||
<p>An explicit alignment may be specified for a global, which must be a power
|
||||
of 2. If not present, or if the alignment is set to zero, the alignment of
|
||||
the global is set by the target to whatever it feels convenient. If an
|
||||
explicit alignment is specified, the global is forced to have exactly that
|
||||
alignment. Targets and optimizers are not allowed to over-align the global
|
||||
if the global has an assigned section. In this case, the extra alignment
|
||||
could be observable: for example, code could assume that the globals are
|
||||
densely packed in their section and try to iterate over them as an array,
|
||||
alignment padding would break this iteration.</p>
|
||||
|
||||
<p>For example, the following defines a global in a numbered address space with
|
||||
an initializer, section, and alignment:</p>
|
||||
@ -1297,7 +1303,7 @@ target datalayout = "<i>layout specification</i>"
|
||||
</dl>
|
||||
|
||||
<p>When constructing the data layout for a given target, LLVM starts with a
|
||||
default set of specifications which are then (possibly) overriden by the
|
||||
default set of specifications which are then (possibly) overridden by the
|
||||
specifications in the <tt>datalayout</tt> keyword. The default specifications
|
||||
are given in this list:</p>
|
||||
|
||||
@ -1393,6 +1399,24 @@ to implement type-based alias analysis.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection">
|
||||
<a name="volatile">Volatile Memory Accesses</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Certain memory accesses, such as <a href="#i_load"><tt>load</tt></a>s, <a
|
||||
href="#i_store"><tt>store</tt></a>s, and <a
|
||||
href="#int_memcpy"><tt>llvm.memcpy</tt></a>s may be marked <tt>volatile</tt>.
|
||||
The optimizers must not change the number of volatile operations or change their
|
||||
order of execution relative to other volatile operations. The optimizers
|
||||
<i>may</i> change the order of volatile operations relative to non-volatile
|
||||
operations. This is not Java's "volatile" and has no cross-thread
|
||||
synchronization behavior.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- *********************************************************************** -->
|
||||
<div class="doc_section"> <a name="typesystem">Type System</a> </div>
|
||||
<!-- *********************************************************************** -->
|
||||
@ -2302,6 +2326,114 @@ has undefined behavior.</p>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="trapvalues">Trap Values</a></div>
|
||||
<div class="doc_text">
|
||||
|
||||
<p>Trap values are similar to <a href="#undefvalues">undef values</a>, however
|
||||
instead of representing an unspecified bit pattern, they represent the
|
||||
fact that an instruction or constant expression which cannot evoke side
|
||||
effects has nevertheless detected a condition which results in undefined
|
||||
behavior.</p>
|
||||
|
||||
<p>There is currently no way of representing a trap value in the IR; they
|
||||
only exist when produced by operations such as
|
||||
<a href="#i_add"><tt>add</tt></a> with the <tt>nsw</tt> flag.</p>
|
||||
|
||||
<p>Trap value behavior is defined in terms of value <i>dependence</i>:</p>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Values other than <a href="#i_phi"><tt>phi</tt></a> nodes depend on
|
||||
their operands.</li>
|
||||
|
||||
<li><a href="#i_phi"><tt>Phi</tt></a> nodes depend on the operand corresponding
|
||||
to their dynamic predecessor basic block.</li>
|
||||
|
||||
<li>Function arguments depend on the corresponding actual argument values in
|
||||
the dynamic callers of their functions.</li>
|
||||
|
||||
<li><a href="#i_call"><tt>Call</tt></a> instructions depend on the
|
||||
<a href="#i_ret"><tt>ret</tt></a> instructions that dynamically transfer
|
||||
control back to them.</li>
|
||||
|
||||
<li><a href="#i_invoke"><tt>Invoke</tt></a> instructions depend on the
|
||||
<a href="#i_ret"><tt>ret</tt></a>, <a href="#i_unwind"><tt>unwind</tt></a>,
|
||||
or exception-throwing call instructions that dynamically transfer control
|
||||
back to them.</li>
|
||||
|
||||
<li>Non-volatile loads and stores depend on the most recent stores to all of the
|
||||
referenced memory addresses, following the order in the IR
|
||||
(including loads and stores implied by intrinsics such as
|
||||
<a href="#int_memcpy"><tt>@llvm.memcpy</tt></a>.)</li>
|
||||
|
||||
<!-- TODO: In the case of multiple threads, this only applies if the store
|
||||
"happens-before" the load or store. -->
|
||||
|
||||
<!-- TODO: floating-point exception state -->
|
||||
|
||||
<li>An instruction with externally visible side effects depends on the most
|
||||
recent preceding instruction with externally visible side effects, following
|
||||
the order in the IR. (This includes volatile loads and stores.)</li>
|
||||
|
||||
<li>An instruction <i>control-depends</i> on a
|
||||
<a href="#terminators">terminator instruction</a>
|
||||
if the terminator instruction has multiple successors and the instruction
|
||||
is always executed when control transfers to one of the successors, and
|
||||
may not be executed when control is transfered to another.</li>
|
||||
|
||||
<li>Dependence is transitive.</li>
|
||||
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<p>Whenever a trap value is generated, all values which depend on it evaluate
|
||||
to trap. If they have side effects, the evoke their side effects as if each
|
||||
operand with a trap value were undef. If they have externally-visible side
|
||||
effects, the behavior is undefined.</p>
|
||||
|
||||
<p>Here are some examples:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
entry:
|
||||
%trap = sub nuw i32 0, 1 ; Results in a trap value.
|
||||
%still_trap = and i32 %trap, 0 ; Whereas (and i32 undef, 0) would return 0.
|
||||
%trap_yet_again = getelementptr i32* @h, i32 %still_trap
|
||||
store i32 0, i32* %trap_yet_again ; undefined behavior
|
||||
|
||||
store i32 %trap, i32* @g ; Trap value conceptually stored to memory.
|
||||
%trap2 = load i32* @g ; Returns a trap value, not just undef.
|
||||
|
||||
volatile store i32 %trap, i32* @g ; External observation; undefined behavior.
|
||||
|
||||
%narrowaddr = bitcast i32* @g to i16*
|
||||
%wideaddr = bitcast i32* @g to i64*
|
||||
%trap3 = load 16* %narrowaddr ; Returns a trap value.
|
||||
%trap4 = load i64* %widaddr ; Returns a trap value.
|
||||
|
||||
%cmp = icmp i32 slt %trap, 0 ; Returns a trap value.
|
||||
%br i1 %cmp, %true, %end ; Branch to either destination.
|
||||
|
||||
true:
|
||||
volatile store i32 0, i32* @g ; This is control-dependent on %cmp, so
|
||||
; it has undefined behavior.
|
||||
br label %end
|
||||
|
||||
end:
|
||||
%p = phi i32 [ 0, %entry ], [ 1, %true ]
|
||||
; Both edges into this PHI are
|
||||
; control-dependent on %cmp, so this
|
||||
; always results in a trap value.
|
||||
|
||||
volatile store i32 0, i32* @g ; %end is control-equivalent to %entry
|
||||
; so this is defined (ignoring earlier
|
||||
; undefined behavior in this example).
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- ======================================================================= -->
|
||||
<div class="doc_subsection"><a name="blockaddress">Addresses of Basic
|
||||
Blocks</a></div>
|
||||
@ -2516,6 +2648,31 @@ call void asm alignstack "eieio", ""()
|
||||
documented here. Constraints on what can be done (e.g. duplication, moving,
|
||||
etc need to be documented). This is probably best done by reference to
|
||||
another document that covers inline asm from a holistic perspective.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_subsubsection">
|
||||
<a name="inlineasm_md">Inline Asm Metadata</a>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>The call instructions that wrap inline asm nodes may have a "!srcloc" MDNode
|
||||
attached to it that contains a constant integer. If present, the code
|
||||
generator will use the integer as the location cookie value when report
|
||||
errors through the LLVMContext error reporting mechanisms. This allows a
|
||||
front-end to correlate backend errors that occur with inline asm back to the
|
||||
source code that produced it. For example:</p>
|
||||
|
||||
<div class="doc_code">
|
||||
<pre>
|
||||
call void asm sideeffect "something bad", ""()<b>, !srcloc !42</b>
|
||||
...
|
||||
!42 = !{ i32 1234567 }
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<p>It is up to the front-end to make sense of the magic numbers it places in the
|
||||
IR.</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -2637,8 +2794,12 @@ should not be exposed to source languages.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
|
||||
<p>TODO: Describe this.</p>
|
||||
<pre>
|
||||
%0 = type { i32, void ()* }
|
||||
@llvm.global_ctors = appending global [1 x %0] [%0 { i32 65535, void ()* @ctor }]
|
||||
</pre>
|
||||
<p>The <tt>@llvm.global_ctors</tt> array contains a list of constructor functions and associated priorities. The functions referenced by this array will be called in ascending order of priority (i.e. lowest first) when the module is loaded. The order of functions with the same priority is not defined.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -2648,8 +2809,13 @@ should not be exposed to source languages.</p>
|
||||
</div>
|
||||
|
||||
<div class="doc_text">
|
||||
<pre>
|
||||
%0 = type { i32, void ()* }
|
||||
@llvm.global_dtors = appending global [1 x %0] [%0 { i32 65535, void ()* @dtor }]
|
||||
</pre>
|
||||
|
||||
<p>TODO: Describe this.</p>
|
||||
<p>The <tt>@llvm.global_dtors</tt> array contains a list of destructor functions and associated priorities. The functions referenced by this array will be called in descending order of priority (i.e. highest first) when the module is loaded. The order of functions with the same priority is not defined.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
@ -2682,7 +2848,7 @@ Instructions</a> </div>
|
||||
control flow, not values (the one exception being the
|
||||
'<a href="#i_invoke"><tt>invoke</tt></a>' instruction).</p>
|
||||
|
||||
<p>There are six different terminator instructions: the
|
||||
<p>There are seven different terminator instructions: the
|
||||
'<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
|
||||
@ -3079,7 +3245,8 @@ Instruction</a> </div>
|
||||
<p><tt>nuw</tt> and <tt>nsw</tt> stand for "No Unsigned Wrap"
|
||||
and "No Signed Wrap", respectively. If the <tt>nuw</tt> and/or
|
||||
<tt>nsw</tt> keywords are present, the result value of the <tt>add</tt>
|
||||
is undefined if unsigned and/or signed overflow, respectively, occurs.</p>
|
||||
is a <a href="#trapvalues">trap value</a> if unsigned and/or signed overflow,
|
||||
respectively, occurs.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
@ -3159,7 +3326,8 @@ Instruction</a> </div>
|
||||
<p><tt>nuw</tt> and <tt>nsw</tt> stand for "No Unsigned Wrap"
|
||||
and "No Signed Wrap", respectively. If the <tt>nuw</tt> and/or
|
||||
<tt>nsw</tt> keywords are present, the result value of the <tt>sub</tt>
|
||||
is undefined if unsigned and/or signed overflow, respectively, occurs.</p>
|
||||
is a <a href="#trapvalues">trap value</a> if unsigned and/or signed overflow,
|
||||
respectively, occurs.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
@ -3245,7 +3413,8 @@ Instruction</a> </div>
|
||||
<p><tt>nuw</tt> and <tt>nsw</tt> stand for "No Unsigned Wrap"
|
||||
and "No Signed Wrap", respectively. If the <tt>nuw</tt> and/or
|
||||
<tt>nsw</tt> keywords are present, the result value of the <tt>mul</tt>
|
||||
is undefined if unsigned and/or signed overflow, respectively, occurs.</p>
|
||||
is a <a href="#trapvalues">trap value</a> if unsigned and/or signed overflow,
|
||||
respectively, occurs.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
@ -3350,8 +3519,8 @@ Instruction</a> </div>
|
||||
a 32-bit division of -2147483648 by -1.</p>
|
||||
|
||||
<p>If the <tt>exact</tt> keyword is present, the result value of the
|
||||
<tt>sdiv</tt> is undefined if the result would be rounded or if overflow
|
||||
would occur.</p>
|
||||
<tt>sdiv</tt> is a <a href="#trapvalues">trap value</a> if the result would
|
||||
be rounded or if overflow would occur.</p>
|
||||
|
||||
<h5>Example:</h5>
|
||||
<pre>
|
||||
@ -4133,9 +4302,8 @@ Instruction</a> </div>
|
||||
from which to load. The pointer must point to
|
||||
a <a href="#t_firstclass">first class</a> type. If the <tt>load</tt> is
|
||||
marked as <tt>volatile</tt>, then the optimizer is not allowed to modify the
|
||||
number or order of execution of this <tt>load</tt> with other
|
||||
volatile <tt>load</tt> and <tt><a href="#i_store">store</a></tt>
|
||||
instructions.</p>
|
||||
number or order of execution of this <tt>load</tt> with other <a
|
||||
href="#volatile">volatile operations</a>.</p>
|
||||
|
||||
<p>The optional constant <tt>align</tt> argument specifies the alignment of the
|
||||
operation (that is, the alignment of the memory address). A value of 0 or an
|
||||
@ -4191,11 +4359,10 @@ Instruction</a> </div>
|
||||
and an address at which to store it. The type of the
|
||||
'<tt><pointer></tt>' operand must be a pointer to
|
||||
the <a href="#t_firstclass">first class</a> type of the
|
||||
'<tt><value></tt>' operand. If the <tt>store</tt> is marked
|
||||
as <tt>volatile</tt>, then the optimizer is not allowed to modify the number
|
||||
or order of execution of this <tt>store</tt> with other
|
||||
volatile <tt>load</tt> and <tt><a href="#i_store">store</a></tt>
|
||||
instructions.</p>
|
||||
'<tt><value></tt>' operand. If the <tt>store</tt> is marked as
|
||||
<tt>volatile</tt>, then the optimizer is not allowed to modify the number or
|
||||
order of execution of this <tt>store</tt> with other <a
|
||||
href="#volatile">volatile operations</a>.</p>
|
||||
|
||||
<p>The optional constant "align" argument specifies the alignment of the
|
||||
operation (that is, the alignment of the memory address). A value of 0 or an
|
||||
@ -4334,13 +4501,14 @@ entry:
|
||||
</pre>
|
||||
|
||||
<p>If the <tt>inbounds</tt> keyword is present, the result value of the
|
||||
<tt>getelementptr</tt> is undefined if the base pointer is not an
|
||||
<i>in bounds</i> address of an allocated object, or if any of the addresses
|
||||
that would be formed by successive addition of the offsets implied by the
|
||||
indices to the base address with infinitely precise arithmetic are not an
|
||||
<i>in bounds</i> address of that allocated object.
|
||||
The <i>in bounds</i> addresses for an allocated object are all the addresses
|
||||
that point into the object, plus the address one byte past the end.</p>
|
||||
<tt>getelementptr</tt> is a <a href="#trapvalues">trap value</a> if the
|
||||
base pointer is not an <i>in bounds</i> address of an allocated object,
|
||||
or if any of the addresses that would be formed by successive addition of
|
||||
the offsets implied by the indices to the base address with infinitely
|
||||
precise arithmetic are not an <i>in bounds</i> address of that allocated
|
||||
object. The <i>in bounds</i> addresses for an allocated object are all
|
||||
the addresses that point into the object, plus the address one byte past
|
||||
the end.</p>
|
||||
|
||||
<p>If the <tt>inbounds</tt> keyword is not present, the offsets are added to
|
||||
the base address with silently-wrapping two's complement arithmetic, and
|
||||
@ -5865,17 +6033,14 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>This is an overloaded intrinsic. You can use <tt>llvm.memcpy</tt> on any
|
||||
integer bit width. Not all targets support all bit widths however.</p>
|
||||
integer bit width and for different address spaces. Not all targets support
|
||||
all bit widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare void @llvm.memcpy.i8(i8 * <dest>, i8 * <src>,
|
||||
i8 <len>, i32 <align>)
|
||||
declare void @llvm.memcpy.i16(i8 * <dest>, i8 * <src>,
|
||||
i16 <len>, i32 <align>)
|
||||
declare void @llvm.memcpy.i32(i8 * <dest>, i8 * <src>,
|
||||
i32 <len>, i32 <align>)
|
||||
declare void @llvm.memcpy.i64(i8 * <dest>, i8 * <src>,
|
||||
i64 <len>, i32 <align>)
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i32(i8 * <dest>, i8 * <src>,
|
||||
i32 <len>, i32 <align>, i1 <isvolatile>)
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8 * <dest>, i8 * <src>,
|
||||
i64 <len>, i32 <align>, i1 <isvolatile>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -5883,19 +6048,28 @@ LLVM</a>.</p>
|
||||
source location to the destination location.</p>
|
||||
|
||||
<p>Note that, unlike the standard libc function, the <tt>llvm.memcpy.*</tt>
|
||||
intrinsics do not return a value, and takes an extra alignment argument.</p>
|
||||
intrinsics do not return a value, takes extra alignment/isvolatile arguments
|
||||
and the pointers can be in specified address spaces.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
|
||||
<p>The first argument is a pointer to the destination, the second is a pointer
|
||||
to the source. The third argument is an integer argument specifying the
|
||||
number of bytes to copy, and the fourth argument is the alignment of the
|
||||
source and destination locations.</p>
|
||||
number of bytes to copy, the fourth argument is the alignment of the
|
||||
source and destination locations, and the fifth is a boolean indicating a
|
||||
volatile access.</p>
|
||||
|
||||
<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
|
||||
then the caller guarantees that both the source and destination pointers are
|
||||
aligned to that boundary.</p>
|
||||
|
||||
<p>If the <tt>isvolatile</tt> parameter is <tt>true</tt>, the
|
||||
<tt>llvm.memcpy</tt> call is a <a href="#volatile">volatile operation</a>.
|
||||
The detailed access behavior is not very cleanly specified and it is unwise
|
||||
to depend on it.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
|
||||
<p>The '<tt>llvm.memcpy.*</tt>' intrinsics copy a block of memory from the
|
||||
source location to the destination location, which are not allowed to
|
||||
overlap. It copies "len" bytes of memory over. If the argument is known to
|
||||
@ -5913,17 +6087,14 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>This is an overloaded intrinsic. You can use llvm.memmove on any integer bit
|
||||
width. Not all targets support all bit widths however.</p>
|
||||
width and for different address space. Not all targets support all bit
|
||||
widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare void @llvm.memmove.i8(i8 * <dest>, i8 * <src>,
|
||||
i8 <len>, i32 <align>)
|
||||
declare void @llvm.memmove.i16(i8 * <dest>, i8 * <src>,
|
||||
i16 <len>, i32 <align>)
|
||||
declare void @llvm.memmove.i32(i8 * <dest>, i8 * <src>,
|
||||
i32 <len>, i32 <align>)
|
||||
declare void @llvm.memmove.i64(i8 * <dest>, i8 * <src>,
|
||||
i64 <len>, i32 <align>)
|
||||
declare void @llvm.memmove.p0i8.p0i8.i32(i8 * <dest>, i8 * <src>,
|
||||
i32 <len>, i32 <align>, i1 <isvolatile>)
|
||||
declare void @llvm.memmove.p0i8.p0i8.i64(i8 * <dest>, i8 * <src>,
|
||||
i64 <len>, i32 <align>, i1 <isvolatile>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -5933,19 +6104,28 @@ LLVM</a>.</p>
|
||||
overlap.</p>
|
||||
|
||||
<p>Note that, unlike the standard libc function, the <tt>llvm.memmove.*</tt>
|
||||
intrinsics do not return a value, and takes an extra alignment argument.</p>
|
||||
intrinsics do not return a value, takes extra alignment/isvolatile arguments
|
||||
and the pointers can be in specified address spaces.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
|
||||
<p>The first argument is a pointer to the destination, the second is a pointer
|
||||
to the source. The third argument is an integer argument specifying the
|
||||
number of bytes to copy, and the fourth argument is the alignment of the
|
||||
source and destination locations.</p>
|
||||
number of bytes to copy, the fourth argument is the alignment of the
|
||||
source and destination locations, and the fifth is a boolean indicating a
|
||||
volatile access.</p>
|
||||
|
||||
<p>If the call to this intrinsic has an alignment value that is not 0 or 1,
|
||||
then the caller guarantees that the source and destination pointers are
|
||||
aligned to that boundary.</p>
|
||||
|
||||
<p>If the <tt>isvolatile</tt> parameter is <tt>true</tt>, the
|
||||
<tt>llvm.memmove</tt> call is a <a href="#volatile">volatile operation</a>.
|
||||
The detailed access behavior is not very cleanly specified and it is unwise
|
||||
to depend on it.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
|
||||
<p>The '<tt>llvm.memmove.*</tt>' intrinsics copy a block of memory from the
|
||||
source location to the destination location, which may overlap. It copies
|
||||
"len" bytes of memory over. If the argument is known to be aligned to some
|
||||
@ -5963,17 +6143,14 @@ LLVM</a>.</p>
|
||||
|
||||
<h5>Syntax:</h5>
|
||||
<p>This is an overloaded intrinsic. You can use llvm.memset on any integer bit
|
||||
width. Not all targets support all bit widths however.</p>
|
||||
width and for different address spaces. Not all targets support all bit
|
||||
widths however.</p>
|
||||
|
||||
<pre>
|
||||
declare void @llvm.memset.i8(i8 * <dest>, i8 <val>,
|
||||
i8 <len>, i32 <align>)
|
||||
declare void @llvm.memset.i16(i8 * <dest>, i8 <val>,
|
||||
i16 <len>, i32 <align>)
|
||||
declare void @llvm.memset.i32(i8 * <dest>, i8 <val>,
|
||||
i32 <len>, i32 <align>)
|
||||
declare void @llvm.memset.i64(i8 * <dest>, i8 <val>,
|
||||
i64 <len>, i32 <align>)
|
||||
declare void @llvm.memset.p0i8.i32(i8 * <dest>, i8 <val>,
|
||||
i32 <len>, i32 <align>, i1 <isvolatile>)
|
||||
declare void @llvm.memset.p0i8.i64(i8 * <dest>, i8 <val>,
|
||||
i64 <len>, i32 <align>, i1 <isvolatile>)
|
||||
</pre>
|
||||
|
||||
<h5>Overview:</h5>
|
||||
@ -5981,7 +6158,8 @@ LLVM</a>.</p>
|
||||
particular byte value.</p>
|
||||
|
||||
<p>Note that, unlike the standard libc function, the <tt>llvm.memset</tt>
|
||||
intrinsic does not return a value, and takes an extra alignment argument.</p>
|
||||
intrinsic does not return a value, takes extra alignment/volatile arguments,
|
||||
and the destination can be in an arbitrary address space.</p>
|
||||
|
||||
<h5>Arguments:</h5>
|
||||
<p>The first argument is a pointer to the destination to fill, the second is the
|
||||
@ -5993,6 +6171,11 @@ LLVM</a>.</p>
|
||||
then the caller guarantees that the destination pointer is aligned to that
|
||||
boundary.</p>
|
||||
|
||||
<p>If the <tt>isvolatile</tt> parameter is <tt>true</tt>, the
|
||||
<tt>llvm.memset</tt> call is a <a href="#volatile">volatile operation</a>.
|
||||
The detailed access behavior is not very cleanly specified and it is unwise
|
||||
to depend on it.</p>
|
||||
|
||||
<h5>Semantics:</h5>
|
||||
<p>The '<tt>llvm.memset.*</tt>' intrinsics fill "len" bytes of memory starting
|
||||
at the destination location. If the argument is known to be aligned to some
|
||||
@ -7590,7 +7773,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: 2010-03-15 05:12:21 +0100 (Mon, 15 Mar 2010) $
|
||||
Last modified: $Date: 2010-05-03 16:59:34 +0200 (Mon, 03 May 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -256,7 +256,7 @@ $ llvm-gcc a.o main.o -o main # <-- standard link command without any modific
|
||||
<p>In this phase, the linker reads optimized a native object file and
|
||||
updates the internal global symbol table to reflect any changes. The linker
|
||||
also collects information about any changes in use of external symbols by
|
||||
LLVM bitcode files. In the examle above, the linker notes that
|
||||
LLVM bitcode files. In the example above, the linker notes that
|
||||
<tt>foo4()</tt> is not used any more. If dead code stripping is enabled then
|
||||
the linker refreshes the live symbol information appropriately and performs
|
||||
dead code stripping.</p>
|
||||
@ -382,7 +382,7 @@ of the native object files.</p>
|
||||
|
||||
Devang Patel and Nick Kledzik<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: 2010-04-25 00:01:40 +0200 (Sun, 25 Apr 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -114,7 +114,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
<tr><td><a href="#block-placement">-block-placement</a></td><td>Profile Guided Basic Block Placement</td></tr>
|
||||
<tr><td><a href="#break-crit-edges">-break-crit-edges</a></td><td>Break critical edges in CFG</td></tr>
|
||||
<tr><td><a href="#codegenprepare">-codegenprepare</a></td><td>Prepare a function for code generation </td></tr>
|
||||
<tr><td><a href="#condprop">-condprop</a></td><td>Conditional Propagation</td></tr>
|
||||
<tr><td><a href="#constmerge">-constmerge</a></td><td>Merge Duplicate Global Constants</td></tr>
|
||||
<tr><td><a href="#constprop">-constprop</a></td><td>Simple constant propagation</td></tr>
|
||||
<tr><td><a href="#dce">-dce</a></td><td>Dead Code Elimination</td></tr>
|
||||
@ -639,15 +638,6 @@ perl -e '$/ = undef; for (split(/\n/, <>)) { s:^ *///? ?::; print " <p>\n" if !
|
||||
basic-block-at-a-time approach. It should eventually be removed.
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
<div class="doc_subsection">
|
||||
<a name="condprop">Conditional Propagation</a>
|
||||
</div>
|
||||
<div class="doc_text">
|
||||
<p>This pass propagates information about conditional expressions through the
|
||||
program, allowing it to eliminate conditional branches in some cases.</p>
|
||||
</div>
|
||||
|
||||
<!-------------------------------------------------------------------------- -->
|
||||
<div class="doc_subsection">
|
||||
<a name="constmerge">Merge Duplicate Global Constants</a>
|
||||
@ -1773,7 +1763,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: 2010-03-01 20:24:17 +0100 (Mon, 01 Mar 2010) $
|
||||
Last modified: $Date: 2010-04-22 22:48:34 +0200 (Thu, 22 Apr 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -333,8 +333,9 @@ The TableGen types are:</p>
|
||||
<dd>This type represents a nestable directed graph of elements.</dd>
|
||||
|
||||
<dt><tt><b>code</b></tt></dt>
|
||||
<dd>This represents a big hunk of text. NOTE: I don't remember why this is
|
||||
distinct from string!</dd>
|
||||
<dd>This represents a big hunk of text. This is lexically distinct from
|
||||
string values because it doesn't require escapeing double quotes and other
|
||||
common characters that occur in code.</dd>
|
||||
</dl>
|
||||
|
||||
<p>To date, these types have been sufficient for describing things that
|
||||
@ -794,7 +795,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: 2010-03-27 03:53:27 +0100 (Sat, 27 Mar 2010) $
|
||||
Last modified: $Date: 2010-04-22 18:45:27 +0200 (Thu, 22 Apr 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -607,7 +607,7 @@ fast).</p>
|
||||
<div class="doc_text">
|
||||
|
||||
<div class="doc_code"><pre>
|
||||
<b>virtual bool</b> runOnSCC(const std::vector<CallGraphNode *> &SCCM) = 0;
|
||||
<b>virtual bool</b> runOnSCC(CallGraphSCC &SCC) = 0;
|
||||
</pre></div>
|
||||
|
||||
<p>The <tt>runOnSCC</tt> method performs the interesting work of the pass, and
|
||||
@ -1835,7 +1835,7 @@ Despite that, we have kept the LLVM passes SMP ready, and you should too.</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: 2010-03-10 02:29:39 +0100 (Wed, 10 Mar 2010) $
|
||||
Last modified: $Date: 2010-04-17 01:07:44 +0200 (Sat, 17 Apr 2010) $
|
||||
</address>
|
||||
|
||||
</body>
|
||||
|
@ -813,8 +813,7 @@ _Unwind_Reason_Code ourPersonality(int version,
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint8_t* lsda = (uint8_t*)
|
||||
_Unwind_GetLanguageSpecificData(context);
|
||||
const uint8_t* lsda = _Unwind_GetLanguageSpecificData(context);
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf(stderr,
|
||||
@ -1949,7 +1948,7 @@ int main(int argc, char* argv[]) {
|
||||
}
|
||||
|
||||
// If not set, exception handling will not be turned on
|
||||
llvm::DwarfExceptionHandling = true;
|
||||
llvm::JITExceptionHandling = true;
|
||||
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::LLVMContext& context = llvm::getGlobalContext();
|
||||
|
@ -9,9 +9,8 @@
|
||||
LEVEL = ../..
|
||||
TOOLNAME = ExceptionDemo
|
||||
EXAMPLE_TOOL = 1
|
||||
REQUIRES_EH = 1
|
||||
|
||||
LINK_COMPONENTS := jit interpreter nativecodegen
|
||||
|
||||
include $(LEVEL)/Makefile.common
|
||||
|
||||
CXXFLAGS += -fexceptions
|
||||
|
@ -319,6 +319,8 @@ LLVMTypeRef LLVMGetTypeByName(LLVMModuleRef M, const char *Name);
|
||||
/** See Module::dump. */
|
||||
void LLVMDumpModule(LLVMModuleRef M);
|
||||
|
||||
/** See Module::setModuleInlineAsm. */
|
||||
void LLVMSetModuleInlineAsm(LLVMModuleRef M, const char *Asm);
|
||||
|
||||
/*===-- Types -------------------------------------------------------------===*/
|
||||
|
||||
|
@ -55,7 +55,8 @@ typedef enum {
|
||||
/*! @constant kEDAssemblySyntaxX86Intel Intel syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86Intel = 0,
|
||||
/*! @constant kEDAssemblySyntaxX86ATT AT&T syntax for i386 and x86_64. */
|
||||
kEDAssemblySyntaxX86ATT = 1
|
||||
kEDAssemblySyntaxX86ATT = 1,
|
||||
kEDAssemblySyntaxARMUAL = 2
|
||||
} EDAssemblySyntax_t;
|
||||
|
||||
/*!
|
||||
|
@ -32,18 +32,18 @@ typedef struct LLVMOpaqueTargetData *LLVMTargetDataRef;
|
||||
typedef struct LLVMStructLayout *LLVMStructLayoutRef;
|
||||
|
||||
/* Declare all of the target-initialization functions that are available. */
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo();
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##TargetInfo(void);
|
||||
#include "llvm/Config/Targets.def"
|
||||
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
|
||||
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target();
|
||||
#define LLVM_TARGET(TargetName) void LLVMInitialize##TargetName##Target(void);
|
||||
#include "llvm/Config/Targets.def"
|
||||
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
|
||||
|
||||
/** LLVMInitializeAllTargetInfos - The main program should call this function if
|
||||
it wants access to all available targets that LLVM is configured to
|
||||
support. */
|
||||
static inline void LLVMInitializeAllTargetInfos() {
|
||||
static inline void LLVMInitializeAllTargetInfos(void) {
|
||||
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##TargetInfo();
|
||||
#include "llvm/Config/Targets.def"
|
||||
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
|
||||
@ -52,7 +52,7 @@ static inline void LLVMInitializeAllTargetInfos() {
|
||||
/** LLVMInitializeAllTargets - The main program should call this function if it
|
||||
wants to link in all available targets that LLVM is configured to
|
||||
support. */
|
||||
static inline void LLVMInitializeAllTargets() {
|
||||
static inline void LLVMInitializeAllTargets(void) {
|
||||
#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##Target();
|
||||
#include "llvm/Config/Targets.def"
|
||||
#undef LLVM_TARGET /* Explicit undef to make SWIG happier */
|
||||
@ -61,7 +61,7 @@ static inline void LLVMInitializeAllTargets() {
|
||||
/** LLVMInitializeNativeTarget - The main program should call this function to
|
||||
initialize the native target corresponding to the host. This is useful
|
||||
for JIT applications to ensure that the target gets linked in correctly. */
|
||||
static inline LLVMBool LLVMInitializeNativeTarget() {
|
||||
static inline LLVMBool LLVMInitializeNativeTarget(void) {
|
||||
/* If we have a native target, initialize it to ensure it is linked in. */
|
||||
#ifdef LLVM_NATIVE_ARCH
|
||||
#define DoInit2(TARG) \
|
||||
|
@ -54,6 +54,12 @@ void LLVMAddLowerSetJmpPass(LLVMPassManagerRef PM);
|
||||
/** See llvm::createPruneEHPass function. */
|
||||
void LLVMAddPruneEHPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createIPSCCPPass function. */
|
||||
void LLVMAddIPSCCPPass(LLVMPassManagerRef PM);
|
||||
|
||||
/** See llvm::createInternalizePass function. */
|
||||
void LLVMAddInternalizePass(LLVMPassManagerRef, unsigned AllButMain);
|
||||
|
||||
// FIXME: Remove in LLVM 3.0.
|
||||
void LLVMAddRaiseAllocationsPass(LLVMPassManagerRef PM);
|
||||
|
||||
|
@ -870,12 +870,28 @@ class APInt {
|
||||
/// @brief Unsigned less than comparison
|
||||
bool ult(const APInt& RHS) const;
|
||||
|
||||
/// Regards both *this as an unsigned quantity and compares it with RHS for
|
||||
/// the validity of the less-than relationship.
|
||||
/// @returns true if *this < RHS when considered unsigned.
|
||||
/// @brief Unsigned less than comparison
|
||||
bool ult(uint64_t RHS) const {
|
||||
return ult(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as signed quantities and compares them for
|
||||
/// validity of the less-than relationship.
|
||||
/// @returns true if *this < RHS when both are considered signed.
|
||||
/// @brief Signed less than comparison
|
||||
bool slt(const APInt& RHS) const;
|
||||
|
||||
/// Regards both *this as a signed quantity and compares it with RHS for
|
||||
/// the validity of the less-than relationship.
|
||||
/// @returns true if *this < RHS when considered signed.
|
||||
/// @brief Signed less than comparison
|
||||
bool slt(uint64_t RHS) const {
|
||||
return slt(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as unsigned quantities and compares them for
|
||||
/// validity of the less-or-equal relationship.
|
||||
/// @returns true if *this <= RHS when both are considered unsigned.
|
||||
@ -884,6 +900,14 @@ class APInt {
|
||||
return ult(RHS) || eq(RHS);
|
||||
}
|
||||
|
||||
/// Regards both *this as an unsigned quantity and compares it with RHS for
|
||||
/// the validity of the less-or-equal relationship.
|
||||
/// @returns true if *this <= RHS when considered unsigned.
|
||||
/// @brief Unsigned less or equal comparison
|
||||
bool ule(uint64_t RHS) const {
|
||||
return ule(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as signed quantities and compares them for
|
||||
/// validity of the less-or-equal relationship.
|
||||
/// @returns true if *this <= RHS when both are considered signed.
|
||||
@ -892,6 +916,14 @@ class APInt {
|
||||
return slt(RHS) || eq(RHS);
|
||||
}
|
||||
|
||||
/// Regards both *this as a signed quantity and compares it with RHS for
|
||||
/// the validity of the less-or-equal relationship.
|
||||
/// @returns true if *this <= RHS when considered signed.
|
||||
/// @brief Signed less or equal comparison
|
||||
bool sle(uint64_t RHS) const {
|
||||
return sle(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as unsigned quantities and compares them for
|
||||
/// the validity of the greater-than relationship.
|
||||
/// @returns true if *this > RHS when both are considered unsigned.
|
||||
@ -900,6 +932,14 @@ class APInt {
|
||||
return !ult(RHS) && !eq(RHS);
|
||||
}
|
||||
|
||||
/// Regards both *this as an unsigned quantity and compares it with RHS for
|
||||
/// the validity of the greater-than relationship.
|
||||
/// @returns true if *this > RHS when considered unsigned.
|
||||
/// @brief Unsigned greater than comparison
|
||||
bool ugt(uint64_t RHS) const {
|
||||
return ugt(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as signed quantities and compares them for
|
||||
/// the validity of the greater-than relationship.
|
||||
/// @returns true if *this > RHS when both are considered signed.
|
||||
@ -908,6 +948,14 @@ class APInt {
|
||||
return !slt(RHS) && !eq(RHS);
|
||||
}
|
||||
|
||||
/// Regards both *this as a signed quantity and compares it with RHS for
|
||||
/// the validity of the greater-than relationship.
|
||||
/// @returns true if *this > RHS when considered signed.
|
||||
/// @brief Signed greater than comparison
|
||||
bool sgt(uint64_t RHS) const {
|
||||
return sgt(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as unsigned quantities and compares them for
|
||||
/// validity of the greater-or-equal relationship.
|
||||
/// @returns true if *this >= RHS when both are considered unsigned.
|
||||
@ -916,6 +964,14 @@ class APInt {
|
||||
return !ult(RHS);
|
||||
}
|
||||
|
||||
/// Regards both *this as an unsigned quantity and compares it with RHS for
|
||||
/// the validity of the greater-or-equal relationship.
|
||||
/// @returns true if *this >= RHS when considered unsigned.
|
||||
/// @brief Unsigned greater or equal comparison
|
||||
bool uge(uint64_t RHS) const {
|
||||
return uge(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// Regards both *this and RHS as signed quantities and compares them for
|
||||
/// validity of the greater-or-equal relationship.
|
||||
/// @returns true if *this >= RHS when both are considered signed.
|
||||
@ -924,6 +980,14 @@ class APInt {
|
||||
return !slt(RHS);
|
||||
}
|
||||
|
||||
/// Regards both *this as a signed quantity and compares it with RHS for
|
||||
/// the validity of the greater-or-equal relationship.
|
||||
/// @returns true if *this >= RHS when considered signed.
|
||||
/// @brief Signed greater or equal comparison
|
||||
bool sge(uint64_t RHS) const {
|
||||
return sge(APInt(getBitWidth(), RHS));
|
||||
}
|
||||
|
||||
/// This operation tests if there are any pairs of corresponding bits
|
||||
/// between this APInt and RHS that are both set.
|
||||
bool intersects(const APInt &RHS) const {
|
||||
|
@ -49,6 +49,11 @@ class BitVector {
|
||||
|
||||
~reference() {}
|
||||
|
||||
reference &operator=(reference t) {
|
||||
*this = bool(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference& operator=(bool t) {
|
||||
if (t)
|
||||
*WordRef |= 1L << BitPos;
|
||||
|
@ -92,6 +92,16 @@ template<> struct DenseMapInfo<unsigned long long> {
|
||||
}
|
||||
};
|
||||
|
||||
// Provide DenseMapInfo for ints.
|
||||
template<> struct DenseMapInfo<int> {
|
||||
static inline int getEmptyKey() { return 0x7fffffff; }
|
||||
static inline int getTombstoneKey() { return -0x7fffffff - 1; }
|
||||
static unsigned getHashValue(const int& Val) { return (unsigned)(Val * 37); }
|
||||
static bool isEqual(const int& LHS, const int& RHS) {
|
||||
return LHS == RHS;
|
||||
}
|
||||
};
|
||||
|
||||
// Provide DenseMapInfo for long longs.
|
||||
template<> struct DenseMapInfo<long long> {
|
||||
static inline long long getEmptyKey() { return 0x7fffffffffffffffLL; }
|
||||
|
@ -189,6 +189,8 @@ class ImutAVLTree : public FoldingSetNode {
|
||||
unsigned verify() const {
|
||||
unsigned HL = getLeft() ? getLeft()->verify() : 0;
|
||||
unsigned HR = getRight() ? getRight()->verify() : 0;
|
||||
(void) HL;
|
||||
(void) HR;
|
||||
|
||||
assert(getHeight() == ( HL > HR ? HL : HR ) + 1
|
||||
&& "Height calculation wrong");
|
||||
|
66
include/llvm/ADT/Optional.h
Normal file
66
include/llvm/ADT/Optional.h
Normal file
@ -0,0 +1,66 @@
|
||||
//===-- Optional.h - Simple variant for passing optional values ---*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file provides Optional, a template class modeled in the spirit of
|
||||
// OCaml's 'opt' variant. The idea is to strongly type whether or not
|
||||
// a value can be optional.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ADT_OPTIONAL
|
||||
#define LLVM_ADT_OPTIONAL
|
||||
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
template<typename T>
|
||||
class Optional {
|
||||
T x;
|
||||
unsigned hasVal : 1;
|
||||
public:
|
||||
explicit Optional() : x(), hasVal(false) {}
|
||||
Optional(const T &y) : x(y), hasVal(true) {}
|
||||
|
||||
static inline Optional create(const T* y) {
|
||||
return y ? Optional(*y) : Optional();
|
||||
}
|
||||
|
||||
Optional &operator=(const T &y) {
|
||||
x = y;
|
||||
hasVal = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const T* getPointer() const { assert(hasVal); return &x; }
|
||||
const T& getValue() const { assert(hasVal); return x; }
|
||||
|
||||
operator bool() const { return hasVal; }
|
||||
bool hasValue() const { return hasVal; }
|
||||
const T* operator->() const { return getPointer(); }
|
||||
const T& operator*() const { assert(hasVal); return x; }
|
||||
};
|
||||
|
||||
template<typename T> struct simplify_type;
|
||||
|
||||
template <typename T>
|
||||
struct simplify_type<const Optional<T> > {
|
||||
typedef const T* SimpleType;
|
||||
static SimpleType getSimplifiedValue(const Optional<T> &Val) {
|
||||
return Val.getPointer();
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct simplify_type<Optional<T> >
|
||||
: public simplify_type<const Optional<T> > {};
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
@ -66,7 +66,7 @@ class scc_iterator
|
||||
std::vector<unsigned> MinVisitNumStack;
|
||||
|
||||
// A single "visit" within the non-recursive DFS traversal.
|
||||
void DFSVisitOne(NodeType* N) {
|
||||
void DFSVisitOne(NodeType *N) {
|
||||
++visitNum; // Global counter for the visit order
|
||||
nodeVisitNumbers[N] = visitNum;
|
||||
SCCNodeStack.push_back(N);
|
||||
@ -83,13 +83,14 @@ class scc_iterator
|
||||
// TOS has at least one more child so continue DFS
|
||||
NodeType *childN = *VisitStack.back().second++;
|
||||
if (!nodeVisitNumbers.count(childN)) {
|
||||
// this node has never been seen
|
||||
// this node has never been seen.
|
||||
DFSVisitOne(childN);
|
||||
} else {
|
||||
unsigned childNum = nodeVisitNumbers[childN];
|
||||
if (MinVisitNumStack.back() > childNum)
|
||||
MinVisitNumStack.back() = childNum;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned childNum = nodeVisitNumbers[childN];
|
||||
if (MinVisitNumStack.back() > childNum)
|
||||
MinVisitNumStack.back() = childNum;
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,7 +101,7 @@ class scc_iterator
|
||||
while (!VisitStack.empty()) {
|
||||
DFSVisitChildren();
|
||||
assert(VisitStack.back().second ==GT::child_end(VisitStack.back().first));
|
||||
NodeType* visitingN = VisitStack.back().first;
|
||||
NodeType *visitingN = VisitStack.back().first;
|
||||
unsigned minVisitNum = MinVisitNumStack.back();
|
||||
VisitStack.pop_back();
|
||||
MinVisitNumStack.pop_back();
|
||||
@ -111,18 +112,19 @@ class scc_iterator
|
||||
// " : minVisitNum = " << minVisitNum << "; Node visit num = " <<
|
||||
// nodeVisitNumbers[visitingN] << "\n";
|
||||
|
||||
if (minVisitNum == nodeVisitNumbers[visitingN]) {
|
||||
// A full SCC is on the SCCNodeStack! It includes all nodes below
|
||||
// visitingN on the stack. Copy those nodes to CurrentSCC,
|
||||
// reset their minVisit values, and return (this suspends
|
||||
// the DFS traversal till the next ++).
|
||||
do {
|
||||
CurrentSCC.push_back(SCCNodeStack.back());
|
||||
SCCNodeStack.pop_back();
|
||||
nodeVisitNumbers[CurrentSCC.back()] = ~0U;
|
||||
} while (CurrentSCC.back() != visitingN);
|
||||
return;
|
||||
}
|
||||
if (minVisitNum != nodeVisitNumbers[visitingN])
|
||||
continue;
|
||||
|
||||
// A full SCC is on the SCCNodeStack! It includes all nodes below
|
||||
// visitingN on the stack. Copy those nodes to CurrentSCC,
|
||||
// reset their minVisit values, and return (this suspends
|
||||
// the DFS traversal till the next ++).
|
||||
do {
|
||||
CurrentSCC.push_back(SCCNodeStack.back());
|
||||
SCCNodeStack.pop_back();
|
||||
nodeVisitNumbers[CurrentSCC.back()] = ~0U;
|
||||
} while (CurrentSCC.back() != visitingN);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@ -136,11 +138,11 @@ class scc_iterator
|
||||
typedef scc_iterator<GraphT, GT> _Self;
|
||||
|
||||
// Provide static "constructors"...
|
||||
static inline _Self begin(const GraphT& G) { return _Self(GT::getEntryNode(G)); }
|
||||
static inline _Self end (const GraphT& G) { return _Self(); }
|
||||
static inline _Self begin(const GraphT &G){return _Self(GT::getEntryNode(G));}
|
||||
static inline _Self end (const GraphT &G) { return _Self(); }
|
||||
|
||||
// Direct loop termination test (I.fini() is more efficient than I == end())
|
||||
inline bool fini() const {
|
||||
// Direct loop termination test: I.isAtEnd() is more efficient than I == end()
|
||||
inline bool isAtEnd() const {
|
||||
assert(!CurrentSCC.empty() || VisitStack.empty());
|
||||
return CurrentSCC.empty();
|
||||
}
|
||||
@ -181,28 +183,36 @@ class scc_iterator
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/// ReplaceNode - This informs the scc_iterator that the specified Old node
|
||||
/// has been deleted, and New is to be used in its place.
|
||||
void ReplaceNode(NodeType *Old, NodeType *New) {
|
||||
assert(nodeVisitNumbers.count(Old) && "Old not in scc_iterator?");
|
||||
nodeVisitNumbers[New] = nodeVisitNumbers[Old];
|
||||
nodeVisitNumbers.erase(Old);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Global constructor for the SCC iterator.
|
||||
template <class T>
|
||||
scc_iterator<T> scc_begin(const T& G) {
|
||||
scc_iterator<T> scc_begin(const T &G) {
|
||||
return scc_iterator<T>::begin(G);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
scc_iterator<T> scc_end(const T& G) {
|
||||
scc_iterator<T> scc_end(const T &G) {
|
||||
return scc_iterator<T>::end(G);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
scc_iterator<Inverse<T> > scc_begin(const Inverse<T>& G) {
|
||||
return scc_iterator<Inverse<T> >::begin(G);
|
||||
scc_iterator<Inverse<T> > scc_begin(const Inverse<T> &G) {
|
||||
return scc_iterator<Inverse<T> >::begin(G);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
scc_iterator<Inverse<T> > scc_end(const Inverse<T>& G) {
|
||||
return scc_iterator<Inverse<T> >::end(G);
|
||||
scc_iterator<Inverse<T> > scc_end(const Inverse<T> &G) {
|
||||
return scc_iterator<Inverse<T> >::end(G);
|
||||
}
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -15,7 +15,6 @@
|
||||
#define LLVM_ADT_SMALLBITVECTOR_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include <cassert>
|
||||
|
||||
@ -32,48 +31,85 @@ class SmallBitVector {
|
||||
// TODO: In "large" mode, a pointer to a BitVector is used, leading to an
|
||||
// unnecessary level of indirection. It would be more efficient to use a
|
||||
// pointer to memory containing size, allocation size, and the array of bits.
|
||||
PointerIntPair<BitVector *, 1, uintptr_t> X;
|
||||
uintptr_t X;
|
||||
|
||||
// The number of bits in this class.
|
||||
static const size_t NumBaseBits = sizeof(uintptr_t) * CHAR_BIT;
|
||||
enum {
|
||||
// The number of bits in this class.
|
||||
NumBaseBits = sizeof(uintptr_t) * CHAR_BIT,
|
||||
|
||||
// One bit is used to discriminate between small and large mode. The
|
||||
// remaining bits are used for the small-mode representation.
|
||||
static const size_t SmallNumRawBits = NumBaseBits - 1;
|
||||
// One bit is used to discriminate between small and large mode. The
|
||||
// remaining bits are used for the small-mode representation.
|
||||
SmallNumRawBits = NumBaseBits - 1,
|
||||
|
||||
// A few more bits are used to store the size of the bit set in small mode.
|
||||
// Theoretically this is a ceil-log2. These bits are encoded in the most
|
||||
// significant bits of the raw bits.
|
||||
static const size_t SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
|
||||
NumBaseBits == 64 ? 6 :
|
||||
SmallNumRawBits);
|
||||
// A few more bits are used to store the size of the bit set in small mode.
|
||||
// Theoretically this is a ceil-log2. These bits are encoded in the most
|
||||
// significant bits of the raw bits.
|
||||
SmallNumSizeBits = (NumBaseBits == 32 ? 5 :
|
||||
NumBaseBits == 64 ? 6 :
|
||||
SmallNumRawBits),
|
||||
|
||||
// The remaining bits are used to store the actual set in small mode.
|
||||
static const size_t SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits;
|
||||
// The remaining bits are used to store the actual set in small mode.
|
||||
SmallNumDataBits = SmallNumRawBits - SmallNumSizeBits
|
||||
};
|
||||
|
||||
public:
|
||||
// Encapsulation of a single bit.
|
||||
class reference {
|
||||
SmallBitVector &TheVector;
|
||||
unsigned BitPos;
|
||||
|
||||
public:
|
||||
reference(SmallBitVector &b, unsigned Idx) : TheVector(b), BitPos(Idx) {}
|
||||
|
||||
reference& operator=(reference t) {
|
||||
*this = bool(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
reference& operator=(bool t) {
|
||||
if (t)
|
||||
TheVector.set(BitPos);
|
||||
else
|
||||
TheVector.reset(BitPos);
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
return const_cast<const SmallBitVector &>(TheVector).operator[](BitPos);
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
bool isSmall() const {
|
||||
return X.getInt();
|
||||
return X & uintptr_t(1);
|
||||
}
|
||||
|
||||
BitVector *getPointer() const {
|
||||
assert(!isSmall());
|
||||
return reinterpret_cast<BitVector *>(X);
|
||||
}
|
||||
|
||||
void switchToSmall(uintptr_t NewSmallBits, size_t NewSize) {
|
||||
X.setInt(true);
|
||||
X = 1;
|
||||
setSmallSize(NewSize);
|
||||
setSmallBits(NewSmallBits);
|
||||
}
|
||||
|
||||
void switchToLarge(BitVector *BV) {
|
||||
X.setInt(false);
|
||||
X.setPointer(BV);
|
||||
X = reinterpret_cast<uintptr_t>(BV);
|
||||
assert(!isSmall() && "Tried to use an unaligned pointer");
|
||||
}
|
||||
|
||||
// Return all the bits used for the "small" representation; this includes
|
||||
// bits for the size as well as the element bits.
|
||||
uintptr_t getSmallRawBits() const {
|
||||
return reinterpret_cast<uintptr_t>(X.getPointer()) >> 1;
|
||||
assert(isSmall());
|
||||
return X >> 1;
|
||||
}
|
||||
|
||||
void setSmallRawBits(uintptr_t NewRawBits) {
|
||||
return X.setPointer(reinterpret_cast<BitVector *>(NewRawBits << 1));
|
||||
assert(isSmall());
|
||||
X = (NewRawBits << 1) | uintptr_t(1);
|
||||
}
|
||||
|
||||
// Return the size.
|
||||
@ -87,22 +123,22 @@ class SmallBitVector {
|
||||
|
||||
// Return the element bits.
|
||||
uintptr_t getSmallBits() const {
|
||||
return getSmallRawBits() & ~(~uintptr_t(0) << SmallNumDataBits);
|
||||
return getSmallRawBits() & ~(~uintptr_t(0) << getSmallSize());
|
||||
}
|
||||
|
||||
void setSmallBits(uintptr_t NewBits) {
|
||||
setSmallRawBits((getSmallRawBits() & (~uintptr_t(0) << SmallNumDataBits)) |
|
||||
(NewBits & ~(~uintptr_t(0) << getSmallSize())));
|
||||
setSmallRawBits((NewBits & ~(~uintptr_t(0) << getSmallSize())) |
|
||||
(getSmallSize() << SmallNumDataBits));
|
||||
}
|
||||
|
||||
public:
|
||||
/// SmallBitVector default ctor - Creates an empty bitvector.
|
||||
SmallBitVector() : X(0, 1) {}
|
||||
SmallBitVector() : X(1) {}
|
||||
|
||||
/// SmallBitVector ctor - Creates a bitvector of specified number of bits. All
|
||||
/// bits are initialized to the specified value.
|
||||
explicit SmallBitVector(unsigned s, bool t = false) : X(0, 1) {
|
||||
if (s <= SmallNumRawBits)
|
||||
explicit SmallBitVector(unsigned s, bool t = false) {
|
||||
if (s <= SmallNumDataBits)
|
||||
switchToSmall(t ? ~uintptr_t(0) : 0, s);
|
||||
else
|
||||
switchToLarge(new BitVector(s, t));
|
||||
@ -113,22 +149,22 @@ class SmallBitVector {
|
||||
if (RHS.isSmall())
|
||||
X = RHS.X;
|
||||
else
|
||||
switchToLarge(new BitVector(*RHS.X.getPointer()));
|
||||
switchToLarge(new BitVector(*RHS.getPointer()));
|
||||
}
|
||||
|
||||
~SmallBitVector() {
|
||||
if (!isSmall())
|
||||
delete X.getPointer();
|
||||
delete getPointer();
|
||||
}
|
||||
|
||||
/// empty - Tests whether there are no bits in this bitvector.
|
||||
bool empty() const {
|
||||
return isSmall() ? getSmallSize() == 0 : X.getPointer()->empty();
|
||||
return isSmall() ? getSmallSize() == 0 : getPointer()->empty();
|
||||
}
|
||||
|
||||
/// size - Returns the number of bits in this bitvector.
|
||||
size_t size() const {
|
||||
return isSmall() ? getSmallSize() : X.getPointer()->size();
|
||||
return isSmall() ? getSmallSize() : getPointer()->size();
|
||||
}
|
||||
|
||||
/// count - Returns the number of bits which are set.
|
||||
@ -141,21 +177,21 @@ class SmallBitVector {
|
||||
return CountPopulation_64(Bits);
|
||||
assert(0 && "Unsupported!");
|
||||
}
|
||||
return X.getPointer()->count();
|
||||
return getPointer()->count();
|
||||
}
|
||||
|
||||
/// any - Returns true if any bit is set.
|
||||
bool any() const {
|
||||
if (isSmall())
|
||||
return getSmallBits() != 0;
|
||||
return X.getPointer()->any();
|
||||
return getPointer()->any();
|
||||
}
|
||||
|
||||
/// none - Returns true if none of the bits are set.
|
||||
bool none() const {
|
||||
if (isSmall())
|
||||
return getSmallBits() == 0;
|
||||
return X.getPointer()->none();
|
||||
return getPointer()->none();
|
||||
}
|
||||
|
||||
/// find_first - Returns the index of the first set bit, -1 if none
|
||||
@ -163,13 +199,15 @@ class SmallBitVector {
|
||||
int find_first() const {
|
||||
if (isSmall()) {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
if (Bits == 0)
|
||||
return -1;
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
return CountTrailingZeros_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
return CountTrailingZeros_64(Bits);
|
||||
assert(0 && "Unsupported!");
|
||||
}
|
||||
return X.getPointer()->find_first();
|
||||
return getPointer()->find_first();
|
||||
}
|
||||
|
||||
/// find_next - Returns the index of the next set bit following the
|
||||
@ -178,30 +216,33 @@ class SmallBitVector {
|
||||
if (isSmall()) {
|
||||
uintptr_t Bits = getSmallBits();
|
||||
// Mask off previous bits.
|
||||
Bits &= ~uintptr_t(0) << Prev;
|
||||
Bits &= ~uintptr_t(0) << (Prev + 1);
|
||||
if (Bits == 0 || Prev + 1 >= getSmallSize())
|
||||
return -1;
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 32)
|
||||
return CountTrailingZeros_32(Bits);
|
||||
if (sizeof(uintptr_t) * CHAR_BIT == 64)
|
||||
return CountTrailingZeros_64(Bits);
|
||||
assert(0 && "Unsupported!");
|
||||
}
|
||||
return X.getPointer()->find_next(Prev);
|
||||
return getPointer()->find_next(Prev);
|
||||
}
|
||||
|
||||
/// clear - Clear all bits.
|
||||
void clear() {
|
||||
if (!isSmall())
|
||||
delete X.getPointer();
|
||||
delete getPointer();
|
||||
switchToSmall(0, 0);
|
||||
}
|
||||
|
||||
/// resize - Grow or shrink the bitvector.
|
||||
void resize(unsigned N, bool t = false) {
|
||||
if (!isSmall()) {
|
||||
X.getPointer()->resize(N, t);
|
||||
} else if (getSmallSize() >= N) {
|
||||
getPointer()->resize(N, t);
|
||||
} else if (SmallNumDataBits >= N) {
|
||||
uintptr_t NewBits = t ? ~uintptr_t(0) << getSmallSize() : 0;
|
||||
setSmallSize(N);
|
||||
setSmallBits(getSmallBits());
|
||||
setSmallBits(NewBits | getSmallBits());
|
||||
} else {
|
||||
BitVector *BV = new BitVector(N, t);
|
||||
uintptr_t OldBits = getSmallBits();
|
||||
@ -224,7 +265,7 @@ class SmallBitVector {
|
||||
switchToLarge(BV);
|
||||
}
|
||||
} else {
|
||||
X.getPointer()->reserve(N);
|
||||
getPointer()->reserve(N);
|
||||
}
|
||||
}
|
||||
|
||||
@ -233,7 +274,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(~uintptr_t(0));
|
||||
else
|
||||
X.getPointer()->set();
|
||||
getPointer()->set();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -241,7 +282,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() | (uintptr_t(1) << Idx));
|
||||
else
|
||||
X.getPointer()->set(Idx);
|
||||
getPointer()->set(Idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -249,7 +290,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(0);
|
||||
else
|
||||
X.getPointer()->reset();
|
||||
getPointer()->reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -257,7 +298,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
|
||||
else
|
||||
X.getPointer()->reset(Idx);
|
||||
getPointer()->reset(Idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -265,7 +306,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(~getSmallBits());
|
||||
else
|
||||
X.getPointer()->flip();
|
||||
getPointer()->flip();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -273,7 +314,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() ^ (uintptr_t(1) << Idx));
|
||||
else
|
||||
X.getPointer()->flip(Idx);
|
||||
getPointer()->flip(Idx);
|
||||
return *this;
|
||||
}
|
||||
|
||||
@ -283,12 +324,16 @@ class SmallBitVector {
|
||||
}
|
||||
|
||||
// Indexing.
|
||||
// TODO: Add an index operator which returns a "reference" (proxy class).
|
||||
reference operator[](unsigned Idx) {
|
||||
assert(Idx < size() && "Out-of-bounds Bit access.");
|
||||
return reference(*this, Idx);
|
||||
}
|
||||
|
||||
bool operator[](unsigned Idx) const {
|
||||
assert(Idx < size() && "Out-of-bounds Bit access.");
|
||||
if (isSmall())
|
||||
return ((getSmallBits() >> Idx) & 1) != 0;
|
||||
return X.getPointer()->operator[](Idx);
|
||||
return getPointer()->operator[](Idx);
|
||||
}
|
||||
|
||||
bool test(unsigned Idx) const {
|
||||
@ -302,7 +347,7 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
return getSmallBits() == RHS.getSmallBits();
|
||||
else
|
||||
return *X.getPointer() == *RHS.X.getPointer();
|
||||
return *getPointer() == *RHS.getPointer();
|
||||
}
|
||||
|
||||
bool operator!=(const SmallBitVector &RHS) const {
|
||||
@ -315,11 +360,11 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() & RHS.getSmallBits());
|
||||
else if (!RHS.isSmall())
|
||||
X.getPointer()->operator&=(*RHS.X.getPointer());
|
||||
getPointer()->operator&=(*RHS.getPointer());
|
||||
else {
|
||||
SmallBitVector Copy = RHS;
|
||||
Copy.resize(size());
|
||||
X.getPointer()->operator&=(*Copy.X.getPointer());
|
||||
getPointer()->operator&=(*Copy.getPointer());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -329,11 +374,11 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() | RHS.getSmallBits());
|
||||
else if (!RHS.isSmall())
|
||||
X.getPointer()->operator|=(*RHS.X.getPointer());
|
||||
getPointer()->operator|=(*RHS.getPointer());
|
||||
else {
|
||||
SmallBitVector Copy = RHS;
|
||||
Copy.resize(size());
|
||||
X.getPointer()->operator|=(*Copy.X.getPointer());
|
||||
getPointer()->operator|=(*Copy.getPointer());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -343,11 +388,11 @@ class SmallBitVector {
|
||||
if (isSmall())
|
||||
setSmallBits(getSmallBits() ^ RHS.getSmallBits());
|
||||
else if (!RHS.isSmall())
|
||||
X.getPointer()->operator^=(*RHS.X.getPointer());
|
||||
getPointer()->operator^=(*RHS.getPointer());
|
||||
else {
|
||||
SmallBitVector Copy = RHS;
|
||||
Copy.resize(size());
|
||||
X.getPointer()->operator^=(*Copy.X.getPointer());
|
||||
getPointer()->operator^=(*Copy.getPointer());
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
@ -358,12 +403,12 @@ class SmallBitVector {
|
||||
if (RHS.isSmall())
|
||||
X = RHS.X;
|
||||
else
|
||||
switchToLarge(new BitVector(*RHS.X.getPointer()));
|
||||
switchToLarge(new BitVector(*RHS.getPointer()));
|
||||
} else {
|
||||
if (!RHS.isSmall())
|
||||
*X.getPointer() = *RHS.X.getPointer();
|
||||
*getPointer() = *RHS.getPointer();
|
||||
else {
|
||||
delete X.getPointer();
|
||||
delete getPointer();
|
||||
X = RHS.X;
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ class SmallVectorBase {
|
||||
// number of union instances for the space, which guarantee maximal alignment.
|
||||
struct U {
|
||||
#ifdef __GNUC__
|
||||
char X __attribute__((aligned));
|
||||
char X __attribute__((aligned(8)));
|
||||
#else
|
||||
union {
|
||||
double D;
|
||||
|
@ -57,15 +57,14 @@ static inline char *utohex_buffer(IntTy X, char *BufferEnd) {
|
||||
}
|
||||
|
||||
static inline std::string utohexstr(uint64_t X) {
|
||||
char Buffer[40];
|
||||
return utohex_buffer(X, Buffer+40);
|
||||
char Buffer[17];
|
||||
return utohex_buffer(X, Buffer+17);
|
||||
}
|
||||
|
||||
static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
|
||||
char Buffer[20];
|
||||
char *BufPtr = Buffer+19;
|
||||
char Buffer[11];
|
||||
char *BufPtr = Buffer+11;
|
||||
|
||||
*BufPtr = 0; // Null terminate buffer...
|
||||
if (X == 0) *--BufPtr = '0'; // Handle special case...
|
||||
|
||||
while (X) {
|
||||
@ -75,17 +74,13 @@ static inline std::string utostr_32(uint32_t X, bool isNeg = false) {
|
||||
|
||||
if (isNeg) *--BufPtr = '-'; // Add negative sign...
|
||||
|
||||
return std::string(BufPtr);
|
||||
return std::string(BufPtr, Buffer+11);
|
||||
}
|
||||
|
||||
static inline std::string utostr(uint64_t X, bool isNeg = false) {
|
||||
if (X == uint32_t(X))
|
||||
return utostr_32(uint32_t(X), isNeg);
|
||||
char Buffer[21];
|
||||
char *BufPtr = Buffer+21;
|
||||
|
||||
char Buffer[40];
|
||||
char *BufPtr = Buffer+39;
|
||||
|
||||
*BufPtr = 0; // Null terminate buffer...
|
||||
if (X == 0) *--BufPtr = '0'; // Handle special case...
|
||||
|
||||
while (X) {
|
||||
@ -94,7 +89,7 @@ static inline std::string utostr(uint64_t X, bool isNeg = false) {
|
||||
}
|
||||
|
||||
if (isNeg) *--BufPtr = '-'; // Add negative sign...
|
||||
return std::string(BufPtr);
|
||||
return std::string(BufPtr, Buffer+21);
|
||||
}
|
||||
|
||||
|
||||
|
@ -44,8 +44,8 @@ namespace llvm {
|
||||
// Workaround PR5482: nearly all gcc 4.x miscompile StringRef and std::min()
|
||||
// Changing the arg of min to be an integer, instead of a reference to an
|
||||
// integer works around this bug.
|
||||
size_t min(size_t a, size_t b) const { return a < b ? a : b; }
|
||||
size_t max(size_t a, size_t b) const { return a > b ? a : b; }
|
||||
static size_t min(size_t a, size_t b) { return a < b ? a : b; }
|
||||
static size_t max(size_t a, size_t b) { return a > b ? a : b; }
|
||||
|
||||
public:
|
||||
/// @name Constructors
|
||||
|
@ -187,6 +187,9 @@ class CallGraphNode {
|
||||
|
||||
// CallGraphNode ctor - Create a node for the specified function.
|
||||
inline CallGraphNode(Function *f) : F(f), NumReferences(0) {}
|
||||
~CallGraphNode() {
|
||||
assert(NumReferences == 0 && "Node deleted while references remain");
|
||||
}
|
||||
|
||||
//===---------------------------------------------------------------------
|
||||
// Accessor methods.
|
||||
@ -277,6 +280,11 @@ class CallGraphNode {
|
||||
/// time, so it should be used sparingly.
|
||||
void replaceCallEdge(CallSite CS, CallSite NewCS, CallGraphNode *NewNode);
|
||||
|
||||
/// allReferencesDropped - This is a special function that should only be
|
||||
/// used by the CallGraph class.
|
||||
void allReferencesDropped() {
|
||||
NumReferences = 0;
|
||||
}
|
||||
};
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -392,6 +392,7 @@ namespace llvm {
|
||||
return getFieldAs<DICompositeType>(13);
|
||||
}
|
||||
unsigned isArtificial() const { return getUnsignedField(14); }
|
||||
unsigned isOptimized() const;
|
||||
|
||||
StringRef getFilename() const {
|
||||
if (getVersion() == llvm::LLVMDebugVersion7)
|
||||
@ -474,6 +475,10 @@ namespace llvm {
|
||||
return getType().isBlockByrefStruct();
|
||||
}
|
||||
|
||||
/// isInlinedFnArgument - Return trule if this variable provides debugging
|
||||
/// information for an inlined function arguments.
|
||||
bool isInlinedFnArgument(const Function *CurFn);
|
||||
|
||||
/// dump - print variable.
|
||||
void dump() const;
|
||||
};
|
||||
@ -638,7 +643,8 @@ namespace llvm {
|
||||
unsigned VK = 0,
|
||||
unsigned VIndex = 0,
|
||||
DIType = DIType(),
|
||||
bool isArtificial = 0);
|
||||
bool isArtificial = 0,
|
||||
bool isOptimized = false);
|
||||
|
||||
/// CreateSubprogramDefinition - Create new subprogram descriptor for the
|
||||
/// given declaration.
|
||||
|
@ -16,6 +16,7 @@
|
||||
#define LLVM_ANALYSIS_IVUSERS_H
|
||||
|
||||
#include "llvm/Analysis/LoopPass.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
||||
#include "llvm/Support/ValueHandle.h"
|
||||
|
||||
namespace llvm {
|
||||
@ -26,17 +27,17 @@ class Value;
|
||||
class IVUsers;
|
||||
class ScalarEvolution;
|
||||
class SCEV;
|
||||
class IVUsers;
|
||||
|
||||
/// IVStrideUse - Keep track of one use of a strided induction variable.
|
||||
/// The Expr member keeps track of the expression, User is the actual user
|
||||
/// instruction of the operand, and 'OperandValToReplace' is the operand of
|
||||
/// the User that is the use.
|
||||
class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
friend class IVUsers;
|
||||
public:
|
||||
IVStrideUse(IVUsers *P, const SCEV *S, const SCEV *Off,
|
||||
Instruction* U, Value *O)
|
||||
: CallbackVH(U), Parent(P), Stride(S), Offset(Off),
|
||||
OperandValToReplace(O), IsUseOfPostIncrementedValue(false) {
|
||||
IVStrideUse(IVUsers *P, Instruction* U, Value *O)
|
||||
: CallbackVH(U), Parent(P), OperandValToReplace(O) {
|
||||
}
|
||||
|
||||
/// getUser - Return the user instruction for this use.
|
||||
@ -49,28 +50,6 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
setValPtr(NewUser);
|
||||
}
|
||||
|
||||
/// getParent - Return a pointer to the IVUsers that owns
|
||||
/// this IVStrideUse.
|
||||
IVUsers *getParent() const { return Parent; }
|
||||
|
||||
/// getStride - Return the expression for the stride for the use.
|
||||
const SCEV *getStride() const { return Stride; }
|
||||
|
||||
/// setStride - Assign a new stride to this use.
|
||||
void setStride(const SCEV *Val) {
|
||||
Stride = Val;
|
||||
}
|
||||
|
||||
/// getOffset - Return the offset to add to a theoretical induction
|
||||
/// variable that starts at zero and counts up by the stride to compute
|
||||
/// the value for the use. This always has the same type as the stride.
|
||||
const SCEV *getOffset() const { return Offset; }
|
||||
|
||||
/// setOffset - Assign a new offset to this use.
|
||||
void setOffset(const SCEV *Val) {
|
||||
Offset = Val;
|
||||
}
|
||||
|
||||
/// getOperandValToReplace - Return the Value of the operand in the user
|
||||
/// instruction that this IVStrideUse is representing.
|
||||
Value *getOperandValToReplace() const {
|
||||
@ -83,37 +62,27 @@ class IVStrideUse : public CallbackVH, public ilist_node<IVStrideUse> {
|
||||
OperandValToReplace = Op;
|
||||
}
|
||||
|
||||
/// isUseOfPostIncrementedValue - True if this should use the
|
||||
/// post-incremented version of this IV, not the preincremented version.
|
||||
/// This can only be set in special cases, such as the terminating setcc
|
||||
/// instruction for a loop or uses dominated by the loop.
|
||||
bool isUseOfPostIncrementedValue() const {
|
||||
return IsUseOfPostIncrementedValue;
|
||||
/// getPostIncLoops - Return the set of loops for which the expression has
|
||||
/// been adjusted to use post-inc mode.
|
||||
const PostIncLoopSet &getPostIncLoops() const {
|
||||
return PostIncLoops;
|
||||
}
|
||||
|
||||
/// setIsUseOfPostIncrmentedValue - set the flag that indicates whether
|
||||
/// this is a post-increment use.
|
||||
void setIsUseOfPostIncrementedValue(bool Val) {
|
||||
IsUseOfPostIncrementedValue = Val;
|
||||
}
|
||||
/// transformToPostInc - Transform the expression to post-inc form for the
|
||||
/// given loop.
|
||||
void transformToPostInc(const Loop *L);
|
||||
|
||||
private:
|
||||
/// Parent - a pointer to the IVUsers that owns this IVStrideUse.
|
||||
IVUsers *Parent;
|
||||
|
||||
/// Stride - The stride for this use.
|
||||
const SCEV *Stride;
|
||||
|
||||
/// Offset - The offset to add to the base induction expression.
|
||||
const SCEV *Offset;
|
||||
|
||||
/// OperandValToReplace - The Value of the operand in the user instruction
|
||||
/// that this IVStrideUse is representing.
|
||||
WeakVH OperandValToReplace;
|
||||
|
||||
/// IsUseOfPostIncrementedValue - True if this should use the
|
||||
/// post-incremented version of this IV, not the preincremented version.
|
||||
bool IsUseOfPostIncrementedValue;
|
||||
/// PostIncLoops - The set of loops for which Expr has been adjusted to
|
||||
/// use post-inc mode. This corresponds with SCEVExpander's post-inc concept.
|
||||
PostIncLoopSet PostIncLoops;
|
||||
|
||||
/// Deleted - Implementation of CallbackVH virtual function to
|
||||
/// receive notification when the User is deleted.
|
||||
@ -174,17 +143,16 @@ class IVUsers : public LoopPass {
|
||||
/// return true. Otherwise, return false.
|
||||
bool AddUsersIfInteresting(Instruction *I);
|
||||
|
||||
IVStrideUse &AddUser(const SCEV *Stride, const SCEV *Offset,
|
||||
Instruction *User, Value *Operand);
|
||||
IVStrideUse &AddUser(Instruction *User, Value *Operand);
|
||||
|
||||
/// getReplacementExpr - Return a SCEV expression which computes the
|
||||
/// value of the OperandValToReplace of the given IVStrideUse.
|
||||
const SCEV *getReplacementExpr(const IVStrideUse &U) const;
|
||||
const SCEV *getReplacementExpr(const IVStrideUse &IU) const;
|
||||
|
||||
/// getCanonicalExpr - Return a SCEV expression which computes the
|
||||
/// value of the SCEV of the given IVStrideUse, ignoring the
|
||||
/// isUseOfPostIncrementedValue flag.
|
||||
const SCEV *getCanonicalExpr(const IVStrideUse &U) const;
|
||||
/// getExpr - Return the expression for the use.
|
||||
const SCEV *getExpr(const IVStrideUse &IU) const;
|
||||
|
||||
const SCEV *getStride(const IVStrideUse &IU, const Loop *L) const;
|
||||
|
||||
typedef ilist<IVStrideUse>::iterator iterator;
|
||||
typedef ilist<IVStrideUse>::const_iterator const_iterator;
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- InlineCost.cpp - Cost analysis for inliner ---------------*- C++ -*-===//
|
||||
//===- InlineCost.h - Cost analysis for inliner -----------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -16,9 +16,9 @@
|
||||
|
||||
#include <cassert>
|
||||
#include <climits>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/ValueMap.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -165,7 +165,9 @@ namespace llvm {
|
||||
void analyzeFunction(Function *F);
|
||||
};
|
||||
|
||||
std::map<const Function *, FunctionInfo> CachedFunctionInfo;
|
||||
// The Function* for a function can be changed (by ArgumentPromotion);
|
||||
// the ValueMap will update itself when this happens.
|
||||
ValueMap<const Function *, FunctionInfo> CachedFunctionInfo;
|
||||
|
||||
public:
|
||||
|
||||
@ -174,6 +176,14 @@ namespace llvm {
|
||||
///
|
||||
InlineCost getInlineCost(CallSite CS,
|
||||
SmallPtrSet<const Function *, 16> &NeverInline);
|
||||
/// getCalledFunction - The heuristic used to determine if we should inline
|
||||
/// the function call or not. The callee is explicitly specified, to allow
|
||||
/// you to calculate the cost of inlining a function via a pointer. The
|
||||
/// result assumes that the inlined version will always be used. You should
|
||||
/// weight it yourself in cases where this callee will not always be called.
|
||||
InlineCost getInlineCost(CallSite CS,
|
||||
Function *Callee,
|
||||
SmallPtrSet<const Function *, 16> &NeverInline);
|
||||
|
||||
/// getInlineFudgeFactor - Return a > 1.0 factor if the inliner should use a
|
||||
/// higher threshold to determine if the function call should be inlined.
|
||||
@ -189,6 +199,10 @@ namespace llvm {
|
||||
/// eliminated.
|
||||
void growCachedCostInfo(Function* Caller, Function* Callee);
|
||||
};
|
||||
|
||||
/// callIsSmall - If a call is likely to lower to a single target instruction,
|
||||
/// or is otherwise deemed small return true.
|
||||
bool callIsSmall(const Function *Callee);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -46,6 +46,10 @@ namespace llvm {
|
||||
Value *SimplifyFCmpInst(unsigned Predicate, Value *LHS, Value *RHS,
|
||||
const TargetData *TD = 0);
|
||||
|
||||
/// SimplifySelectInst - Given operands for a SelectInst, see if we can fold
|
||||
/// the result. If not, this returns null.
|
||||
Value *SimplifySelectInst(Value *Cond, Value *TrueVal, Value *FalseVal,
|
||||
const TargetData *TD = 0);
|
||||
|
||||
/// SimplifyGEPInst - Given operands for an GetElementPtrInst, see if we can
|
||||
/// fold the result. If not, this returns null.
|
||||
|
52
include/llvm/Analysis/Lint.h
Normal file
52
include/llvm/Analysis/Lint.h
Normal file
@ -0,0 +1,52 @@
|
||||
//===-- llvm/Analysis/Lint.h - LLVM IR Lint ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines lint interfaces that can be used for some sanity checking
|
||||
// of input to the system, and for checking that transformations
|
||||
// haven't done something bad. In contrast to the Verifier, the Lint checker
|
||||
// checks for undefined behavior or constructions with likely unintended
|
||||
// behavior.
|
||||
//
|
||||
// To see what specifically is checked, look at Lint.cpp
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_LINT_H
|
||||
#define LLVM_ANALYSIS_LINT_H
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class FunctionPass;
|
||||
class Module;
|
||||
class Function;
|
||||
|
||||
/// @brief Create a lint pass.
|
||||
///
|
||||
/// Check a module or function.
|
||||
FunctionPass *createLintPass();
|
||||
|
||||
/// @brief Check a module.
|
||||
///
|
||||
/// This should only be used for debugging, because it plays games with
|
||||
/// PassManagers and stuff.
|
||||
void lintModule(
|
||||
const Module &M, ///< The module to be checked
|
||||
std::string *ErrorInfo = 0 ///< Information about failures.
|
||||
);
|
||||
|
||||
// lintFunction - Check a function.
|
||||
void lintFunction(
|
||||
const Function &F ///< The function to be checked
|
||||
);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -27,7 +27,7 @@
|
||||
#ifndef LLVM_ANALYSIS_POINTERTRACKING_H
|
||||
#define LLVM_ANALYSIS_POINTERTRACKING_H
|
||||
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/Analysis/Dominators.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Pass.h"
|
||||
|
@ -351,7 +351,8 @@ namespace llvm {
|
||||
/// (which may not be an immediate predecessor) which has exactly one
|
||||
/// successor from which BB is reachable, or null if no such block is
|
||||
/// found.
|
||||
BasicBlock* getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
|
||||
std::pair<BasicBlock *, BasicBlock *>
|
||||
getPredecessorWithUniqueSuccessorForBB(BasicBlock *BB);
|
||||
|
||||
/// isImpliedCond - Test whether the condition described by Pred, LHS,
|
||||
/// and RHS is true whenever the given Cond value evaluates to true.
|
||||
@ -380,6 +381,13 @@ namespace llvm {
|
||||
Constant *getConstantEvolutionLoopExitValue(PHINode *PN, const APInt& BEs,
|
||||
const Loop *L);
|
||||
|
||||
/// isKnownPredicateWithRanges - Test if the given expression is known to
|
||||
/// satisfy the condition described by Pred and the known constant ranges
|
||||
/// of LHS and RHS.
|
||||
///
|
||||
bool isKnownPredicateWithRanges(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
public:
|
||||
static char ID; // Pass identification, replacement for typeid
|
||||
ScalarEvolution();
|
||||
@ -554,11 +562,11 @@ namespace llvm {
|
||||
/// getSCEVAtScope(getSCEV(V), L).
|
||||
const SCEV *getSCEVAtScope(Value *V, const Loop *L);
|
||||
|
||||
/// isLoopGuardedByCond - Test whether entry to the loop is protected by
|
||||
/// a conditional between LHS and RHS. This is used to help avoid max
|
||||
/// isLoopEntryGuardedByCond - Test whether entry to the loop is protected
|
||||
/// by a conditional between LHS and RHS. This is used to help avoid max
|
||||
/// expressions in loop trip counts, and to eliminate casts.
|
||||
bool isLoopGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
bool isLoopEntryGuardedByCond(const Loop *L, ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// isLoopBackedgeGuardedByCond - Test whether the backedge of the loop is
|
||||
/// protected by a conditional between LHS and RHS. This is used to
|
||||
@ -636,12 +644,21 @@ namespace llvm {
|
||||
///
|
||||
bool isKnownNonZero(const SCEV *S);
|
||||
|
||||
/// isKnownNonZero - Test if the given expression is known to satisfy
|
||||
/// isKnownPredicate - Test if the given expression is known to satisfy
|
||||
/// the condition described by Pred, LHS, and RHS.
|
||||
///
|
||||
bool isKnownPredicate(ICmpInst::Predicate Pred,
|
||||
const SCEV *LHS, const SCEV *RHS);
|
||||
|
||||
/// SimplifyICmpOperands - Simplify LHS and RHS in a comparison with
|
||||
/// predicate Pred. Return true iff any changes were made. If the
|
||||
/// operands are provably equal or inequal, LHS and RHS are set to
|
||||
/// the same value and Pred is set to either ICMP_EQ or ICMP_NE.
|
||||
///
|
||||
bool SimplifyICmpOperands(ICmpInst::Predicate &Pred,
|
||||
const SCEV *&LHS,
|
||||
const SCEV *&RHS);
|
||||
|
||||
virtual bool runOnFunction(Function &F);
|
||||
virtual void releaseMemory();
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define LLVM_ANALYSIS_SCALAREVOLUTION_EXPANDER_H
|
||||
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionNormalization.h"
|
||||
#include "llvm/Support/IRBuilder.h"
|
||||
#include "llvm/Support/TargetFolder.h"
|
||||
#include <set>
|
||||
@ -32,12 +33,12 @@ namespace llvm {
|
||||
InsertedExpressions;
|
||||
std::set<Value*> InsertedValues;
|
||||
|
||||
/// PostIncLoop - When non-null, expanded addrecs referring to the given
|
||||
/// loop expanded in post-inc mode. For example, expanding {1,+,1}<L> in
|
||||
/// post-inc mode returns the add instruction that adds one to the phi
|
||||
/// for {0,+,1}<L>, as opposed to a new phi starting at 1. This is only
|
||||
/// supported in non-canonical mode.
|
||||
const Loop *PostIncLoop;
|
||||
/// PostIncLoops - Addrecs referring to any of the given loops are expanded
|
||||
/// in post-inc mode. For example, expanding {1,+,1}<L> in post-inc mode
|
||||
/// returns the add instruction that adds one to the phi for {0,+,1}<L>,
|
||||
/// as opposed to a new phi starting at 1. This is only supported in
|
||||
/// non-canonical mode.
|
||||
PostIncLoopSet PostIncLoops;
|
||||
|
||||
/// IVIncInsertPos - When this is non-null, addrecs expanded in the
|
||||
/// loop it indicates should be inserted with increments at
|
||||
@ -62,7 +63,7 @@ namespace llvm {
|
||||
public:
|
||||
/// SCEVExpander - Construct a SCEVExpander in "canonical" mode.
|
||||
explicit SCEVExpander(ScalarEvolution &se)
|
||||
: SE(se), PostIncLoop(0), IVIncInsertLoop(0), CanonicalMode(true),
|
||||
: SE(se), IVIncInsertLoop(0), CanonicalMode(true),
|
||||
Builder(se.getContext(), TargetFolder(se.TD)) {}
|
||||
|
||||
/// clear - Erase the contents of the InsertedExpressions map so that users
|
||||
@ -89,14 +90,18 @@ namespace llvm {
|
||||
IVIncInsertPos = Pos;
|
||||
}
|
||||
|
||||
/// setPostInc - If L is non-null, enable post-inc expansion for addrecs
|
||||
/// referring to the given loop. If L is null, disable post-inc expansion
|
||||
/// completely. Post-inc expansion is only supported in non-canonical
|
||||
/// setPostInc - Enable post-inc expansion for addrecs referring to the
|
||||
/// given loops. Post-inc expansion is only supported in non-canonical
|
||||
/// mode.
|
||||
void setPostInc(const Loop *L) {
|
||||
void setPostInc(const PostIncLoopSet &L) {
|
||||
assert(!CanonicalMode &&
|
||||
"Post-inc expansion is not supported in CanonicalMode");
|
||||
PostIncLoop = L;
|
||||
PostIncLoops = L;
|
||||
}
|
||||
|
||||
/// clearPostInc - Disable all post-inc expansion.
|
||||
void clearPostInc() {
|
||||
PostIncLoops.clear();
|
||||
}
|
||||
|
||||
/// disableCanonicalMode - Disable the behavior of expanding expressions in
|
||||
|
78
include/llvm/Analysis/ScalarEvolutionNormalization.h
Normal file
78
include/llvm/Analysis/ScalarEvolutionNormalization.h
Normal file
@ -0,0 +1,78 @@
|
||||
//===- llvm/Analysis/ScalarEvolutionNormalization.h - See below -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines utilities for working with "normalized" ScalarEvolution
|
||||
// expressions.
|
||||
//
|
||||
// The following example illustrates post-increment uses and how normalized
|
||||
// expressions help.
|
||||
//
|
||||
// for (i=0; i!=n; ++i) {
|
||||
// ...
|
||||
// }
|
||||
// use(i);
|
||||
//
|
||||
// While the expression for most uses of i inside the loop is {0,+,1}<%L>, the
|
||||
// expression for the use of i outside the loop is {1,+,1}<%L>, since i is
|
||||
// incremented at the end of the loop body. This is inconveient, since it
|
||||
// suggests that we need two different induction variables, one that starts
|
||||
// at 0 and one that starts at 1. We'd prefer to be able to think of these as
|
||||
// the same induction variable, with uses inside the loop using the
|
||||
// "pre-incremented" value, and uses after the loop using the
|
||||
// "post-incremented" value.
|
||||
//
|
||||
// Expressions for post-incremented uses are represented as an expression
|
||||
// paired with a set of loops for which the expression is in "post-increment"
|
||||
// mode (there may be multiple loops).
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H
|
||||
#define LLVM_ANALYSIS_SCALAREVOLUTION_NORMALIZATION_H
|
||||
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Instruction;
|
||||
class DominatorTree;
|
||||
class Loop;
|
||||
class ScalarEvolution;
|
||||
class SCEV;
|
||||
class Value;
|
||||
|
||||
/// TransformKind - Different types of transformations that
|
||||
/// TransformForPostIncUse can do.
|
||||
enum TransformKind {
|
||||
/// Normalize - Normalize according to the given loops.
|
||||
Normalize,
|
||||
/// NormalizeAutodetect - Detect post-inc opportunities on new expressions,
|
||||
/// update the given loop set, and normalize.
|
||||
NormalizeAutodetect,
|
||||
/// Denormalize - Perform the inverse transform on the expression with the
|
||||
/// given loop set.
|
||||
Denormalize
|
||||
};
|
||||
|
||||
/// PostIncLoopSet - A set of loops.
|
||||
typedef SmallPtrSet<const Loop *, 2> PostIncLoopSet;
|
||||
|
||||
/// TransformForPostIncUse - Transform the given expression according to the
|
||||
/// given transformation kind.
|
||||
const SCEV *TransformForPostIncUse(TransformKind Kind,
|
||||
const SCEV *S,
|
||||
Instruction *User,
|
||||
Value *OperandValToReplace,
|
||||
PostIncLoopSet &Loops,
|
||||
ScalarEvolution &SE,
|
||||
DominatorTree &DT);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
@ -122,7 +122,8 @@ namespace llvm {
|
||||
/// StopAtNul is set to true (the default), the returned string is truncated
|
||||
/// by a nul character in the global. If StopAtNul is false, the nul
|
||||
/// character is included in the result string.
|
||||
bool GetConstantStringInfo(Value *V, std::string &Str, uint64_t Offset = 0,
|
||||
bool GetConstantStringInfo(const Value *V, std::string &Str,
|
||||
uint64_t Offset = 0,
|
||||
bool StopAtNul = true);
|
||||
|
||||
/// GetStringLength - If we can compute the length of the string pointed to by
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===-- llvm/Analysis/Verifier.h - Module Verifier --------------*- C++ -*-===//
|
||||
//===-- llvm/Analysis/Verifier.h - LLVM IR Verifier -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -107,7 +107,7 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
|
||||
/// into memory, the return value will be null.
|
||||
/// @returns a pointer to the member's data.
|
||||
/// @brief Get the data content of the archive member
|
||||
const void* getData() const { return data; }
|
||||
const char* getData() const { return data; }
|
||||
|
||||
/// This method determines if the member is a regular compressed file.
|
||||
/// @returns true iff the archive member is a compressed regular file.
|
||||
@ -172,7 +172,7 @@ class ArchiveMember : public ilist_node<ArchiveMember> {
|
||||
sys::PathWithStatus path; ///< Path of file containing the member
|
||||
sys::FileStatus info; ///< Status info (size,mode,date)
|
||||
unsigned flags; ///< Flags about the archive member
|
||||
const void* data; ///< Data for the member
|
||||
const char* data; ///< Data for the member
|
||||
|
||||
/// @}
|
||||
/// @name Constructors
|
||||
|
@ -29,9 +29,10 @@ namespace llvm {
|
||||
class CallGraphNode;
|
||||
class CallGraph;
|
||||
class PMStack;
|
||||
|
||||
struct CallGraphSCCPass : public Pass {
|
||||
|
||||
class CallGraphSCC;
|
||||
|
||||
class CallGraphSCCPass : public Pass {
|
||||
public:
|
||||
explicit CallGraphSCCPass(intptr_t pid) : Pass(PT_CallGraphSCC, pid) {}
|
||||
explicit CallGraphSCCPass(void *pid) : Pass(PT_CallGraphSCC, pid) {}
|
||||
|
||||
@ -53,7 +54,7 @@ struct CallGraphSCCPass : public Pass {
|
||||
/// SCC passes that add or delete functions to the SCC are required to update
|
||||
/// the SCC list, otherwise stale pointers may be dereferenced.
|
||||
///
|
||||
virtual bool runOnSCC(std::vector<CallGraphNode *> &SCC) = 0;
|
||||
virtual bool runOnSCC(CallGraphSCC &SCC) = 0;
|
||||
|
||||
/// doFinalization - This method is called after the SCC's of the program has
|
||||
/// been processed, allowing the pass to do final cleanup as necessary.
|
||||
@ -63,7 +64,7 @@ struct CallGraphSCCPass : public Pass {
|
||||
|
||||
/// Assign pass manager to manager this pass
|
||||
virtual void assignPassManager(PMStack &PMS,
|
||||
PassManagerType PMT = PMT_CallGraphPassManager);
|
||||
PassManagerType PMT =PMT_CallGraphPassManager);
|
||||
|
||||
/// Return what kind of Pass Manager can manage this pass.
|
||||
virtual PassManagerType getPotentialPassManagerType() const {
|
||||
@ -76,6 +77,29 @@ struct CallGraphSCCPass : public Pass {
|
||||
virtual void getAnalysisUsage(AnalysisUsage &Info) const;
|
||||
};
|
||||
|
||||
/// CallGraphSCC - This is a single SCC that a CallGraphSCCPass is run on.
|
||||
class CallGraphSCC {
|
||||
void *Context; // The CGPassManager object that is vending this.
|
||||
std::vector<CallGraphNode*> Nodes;
|
||||
public:
|
||||
CallGraphSCC(void *context) : Context(context) {}
|
||||
|
||||
void initialize(CallGraphNode*const*I, CallGraphNode*const*E) {
|
||||
Nodes.assign(I, E);
|
||||
}
|
||||
|
||||
bool isSingular() const { return Nodes.size() == 1; }
|
||||
unsigned size() const { return Nodes.size(); }
|
||||
|
||||
/// ReplaceNode - This informs the SCC and the pass manager that the specified
|
||||
/// Old node has been deleted, and New is to be used in its place.
|
||||
void ReplaceNode(CallGraphNode *Old, CallGraphNode *New);
|
||||
|
||||
typedef std::vector<CallGraphNode*>::const_iterator iterator;
|
||||
iterator begin() const { return Nodes.begin(); }
|
||||
iterator end() const { return Nodes.end(); }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
|
80
include/llvm/CodeGen/Analysis.h
Normal file
80
include/llvm/CodeGen/Analysis.h
Normal file
@ -0,0 +1,80 @@
|
||||
//===- CodeGen/Analysis.h - CodeGen LLVM IR Analysis Utilities --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares several CodeGen-specific LLVM IR analysis utilties.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_ANALYSIS_H
|
||||
#define LLVM_CODEGEN_ANALYSIS_H
|
||||
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/InlineAsm.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
#include "llvm/Support/CallSite.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class TargetLowering;
|
||||
class GlobalVariable;
|
||||
|
||||
/// ComputeLinearIndex - Given an LLVM IR aggregate type and a sequence
|
||||
/// of insertvalue or extractvalue indices that identify a member, return
|
||||
/// the linearized index of the start of the member.
|
||||
///
|
||||
unsigned ComputeLinearIndex(const TargetLowering &TLI, const Type *Ty,
|
||||
const unsigned *Indices,
|
||||
const unsigned *IndicesEnd,
|
||||
unsigned CurIndex = 0);
|
||||
|
||||
/// ComputeValueVTs - Given an LLVM IR type, compute a sequence of
|
||||
/// EVTs that represent all the individual underlying
|
||||
/// non-aggregate types that comprise it.
|
||||
///
|
||||
/// If Offsets is non-null, it points to a vector to be filled in
|
||||
/// with the in-memory offsets of each of the individual values.
|
||||
///
|
||||
void ComputeValueVTs(const TargetLowering &TLI, const Type *Ty,
|
||||
SmallVectorImpl<EVT> &ValueVTs,
|
||||
SmallVectorImpl<uint64_t> *Offsets = 0,
|
||||
uint64_t StartingOffset = 0);
|
||||
|
||||
/// ExtractTypeInfo - Returns the type info, possibly bitcast, encoded in V.
|
||||
GlobalVariable *ExtractTypeInfo(Value *V);
|
||||
|
||||
/// hasInlineAsmMemConstraint - Return true if the inline asm instruction being
|
||||
/// processed uses a memory 'm' constraint.
|
||||
bool hasInlineAsmMemConstraint(std::vector<InlineAsm::ConstraintInfo> &CInfos,
|
||||
const TargetLowering &TLI);
|
||||
|
||||
/// getFCmpCondCode - Return the ISD condition code corresponding to
|
||||
/// the given LLVM IR floating-point condition code. This includes
|
||||
/// consideration of global floating-point math flags.
|
||||
///
|
||||
ISD::CondCode getFCmpCondCode(FCmpInst::Predicate Pred);
|
||||
|
||||
/// getICmpCondCode - Return the ISD condition code corresponding to
|
||||
/// the given LLVM IR integer condition code.
|
||||
///
|
||||
ISD::CondCode getICmpCondCode(ICmpInst::Predicate Pred);
|
||||
|
||||
/// Test if the given instruction is in a position to be optimized
|
||||
/// with a tail-call. This roughly means that it's in a block with
|
||||
/// a return and there's nothing that needs to be scheduled
|
||||
/// between it and the return.
|
||||
///
|
||||
/// This function only tests target-independent requirements.
|
||||
bool isInTailCallPosition(ImmutableCallSite CS, Attributes CalleeRetAttr,
|
||||
const TargetLowering &TLI);
|
||||
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
@ -34,6 +34,7 @@ namespace llvm {
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineLocation;
|
||||
class MachineLoopInfo;
|
||||
class MachineLoop;
|
||||
class MachineConstantPool;
|
||||
@ -129,7 +130,7 @@ namespace llvm {
|
||||
unsigned getFunctionNumber() const;
|
||||
|
||||
/// getObjFileLowering - Return information about object file lowering.
|
||||
TargetLoweringObjectFile &getObjFileLowering() const;
|
||||
const TargetLoweringObjectFile &getObjFileLowering() const;
|
||||
|
||||
/// getTargetData - Return information about data layout.
|
||||
const TargetData &getTargetData() const;
|
||||
@ -203,29 +204,16 @@ namespace llvm {
|
||||
/// EmitAlignment - Emit an alignment directive to the specified power of
|
||||
/// two boundary. For example, if you pass in 3 here, you will get an 8
|
||||
/// byte alignment. If a global value is specified, and if that global has
|
||||
/// an explicit alignment requested, it will unconditionally override the
|
||||
/// alignment request. However, if ForcedAlignBits is specified, this value
|
||||
/// has final say: the ultimate alignment will be the max of ForcedAlignBits
|
||||
/// and the alignment computed with NumBits and the global. If UseFillExpr
|
||||
/// is true, it also emits an optional second value FillValue which the
|
||||
/// assembler uses to fill gaps to match alignment for text sections if the
|
||||
/// has specified a non-zero fill value.
|
||||
/// an explicit alignment requested, it will override the alignment request
|
||||
/// if required for correctness.
|
||||
///
|
||||
/// The algorithm is:
|
||||
/// Align = NumBits;
|
||||
/// if (GV && GV->hasalignment) Align = GV->getalignment();
|
||||
/// Align = std::max(Align, ForcedAlignBits);
|
||||
///
|
||||
void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0,
|
||||
unsigned ForcedAlignBits = 0,
|
||||
bool UseFillExpr = true) const;
|
||||
void EmitAlignment(unsigned NumBits, const GlobalValue *GV = 0) const;
|
||||
|
||||
/// EmitBasicBlockStart - This method prints the label for the specified
|
||||
/// MachineBasicBlock, an alignment (if present) and a comment describing
|
||||
/// it if appropriate.
|
||||
void EmitBasicBlockStart(const MachineBasicBlock *MBB) const;
|
||||
|
||||
|
||||
/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
|
||||
void EmitGlobalConstant(const Constant *CV, unsigned AddrSpace = 0);
|
||||
|
||||
@ -333,6 +321,12 @@ namespace llvm {
|
||||
void EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
|
||||
unsigned Size) const;
|
||||
|
||||
/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
|
||||
/// where the size in bytes of the directive is specified by Size and Hi/Lo
|
||||
/// specify the labels. This implicitly uses .set if it is available.
|
||||
void EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
|
||||
const MCSymbol *Lo, unsigned Size) const;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Dwarf Emission Helper Routines
|
||||
//===------------------------------------------------------------------===//
|
||||
@ -370,7 +364,11 @@ namespace llvm {
|
||||
/// that Label lives in.
|
||||
void EmitSectionOffset(const MCSymbol *Label,
|
||||
const MCSymbol *SectionLabel) const;
|
||||
|
||||
|
||||
/// getDebugValueLocation - Get location information encoded by DBG_VALUE
|
||||
/// operands.
|
||||
virtual MachineLocation getDebugValueLocation(const MachineInstr *MI) const;
|
||||
|
||||
//===------------------------------------------------------------------===//
|
||||
// Dwarf Lowering Routines
|
||||
//===------------------------------------------------------------------===//
|
||||
|
@ -15,8 +15,10 @@
|
||||
#define LLVM_CODEGEN_FASTISEL_H
|
||||
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#ifndef NDEBUG
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
||||
#endif
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -26,6 +28,7 @@ class Instruction;
|
||||
class MachineBasicBlock;
|
||||
class MachineConstantPool;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineFrameInfo;
|
||||
class MachineRegisterInfo;
|
||||
class TargetData;
|
||||
@ -44,8 +47,9 @@ class FastISel {
|
||||
DenseMap<const Value *, unsigned> &ValueMap;
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &MBBMap;
|
||||
DenseMap<const AllocaInst *, int> &StaticAllocaMap;
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate;
|
||||
#ifndef NDEBUG
|
||||
SmallSet<Instruction*, 8> &CatchInfoLost;
|
||||
SmallSet<const Instruction *, 8> &CatchInfoLost;
|
||||
#endif
|
||||
MachineFunction &MF;
|
||||
MachineRegisterInfo &MRI;
|
||||
@ -73,11 +77,6 @@ class FastISel {
|
||||
MBB = mbb;
|
||||
}
|
||||
|
||||
/// setCurDebugLoc - Set the current debug location information, which is used
|
||||
/// when creating a machine instruction.
|
||||
///
|
||||
void setCurDebugLoc(DebugLoc dl) { DL = dl; }
|
||||
|
||||
/// getCurDebugLoc() - Return current debug location information.
|
||||
DebugLoc getCurDebugLoc() const { return DL; }
|
||||
|
||||
@ -85,28 +84,28 @@ class FastISel {
|
||||
/// LLVM IR instruction, and append generated machine instructions to
|
||||
/// the current block. Return true if selection was successful.
|
||||
///
|
||||
bool SelectInstruction(Instruction *I);
|
||||
bool SelectInstruction(const Instruction *I);
|
||||
|
||||
/// SelectOperator - Do "fast" instruction selection for the given
|
||||
/// LLVM IR operator (Instruction or ConstantExpr), and append
|
||||
/// generated machine instructions to the current block. Return true
|
||||
/// if selection was successful.
|
||||
///
|
||||
bool SelectOperator(User *I, unsigned Opcode);
|
||||
bool SelectOperator(const User *I, unsigned Opcode);
|
||||
|
||||
/// getRegForValue - Create a virtual register and arrange for it to
|
||||
/// be assigned the value for the given LLVM value.
|
||||
unsigned getRegForValue(Value *V);
|
||||
unsigned getRegForValue(const Value *V);
|
||||
|
||||
/// lookUpRegForValue - Look up the value to see if its value is already
|
||||
/// cached in a register. It may be defined by instructions across blocks or
|
||||
/// defined locally.
|
||||
unsigned lookUpRegForValue(Value *V);
|
||||
unsigned lookUpRegForValue(const Value *V);
|
||||
|
||||
/// getRegForGEPIndex - This is a wrapper around getRegForValue that also
|
||||
/// takes care of truncating or sign-extending the given getelementptr
|
||||
/// index value.
|
||||
unsigned getRegForGEPIndex(Value *V);
|
||||
unsigned getRegForGEPIndex(const Value *V);
|
||||
|
||||
virtual ~FastISel();
|
||||
|
||||
@ -114,9 +113,10 @@ class FastISel {
|
||||
FastISel(MachineFunction &mf,
|
||||
DenseMap<const Value *, unsigned> &vm,
|
||||
DenseMap<const BasicBlock *, MachineBasicBlock *> &bm,
|
||||
DenseMap<const AllocaInst *, int> &am
|
||||
DenseMap<const AllocaInst *, int> &am,
|
||||
std::vector<std::pair<MachineInstr*, unsigned> > &PHINodesToUpdate
|
||||
#ifndef NDEBUG
|
||||
, SmallSet<Instruction*, 8> &cil
|
||||
, SmallSet<const Instruction *, 8> &cil
|
||||
#endif
|
||||
);
|
||||
|
||||
@ -126,7 +126,7 @@ class FastISel {
|
||||
/// fit into FastISel's framework. It returns true if it was successful.
|
||||
///
|
||||
virtual bool
|
||||
TargetSelectInstruction(Instruction *I) = 0;
|
||||
TargetSelectInstruction(const Instruction *I) = 0;
|
||||
|
||||
/// FastEmit_r - This method is called by target-independent code
|
||||
/// to request that an instruction with the given type and opcode
|
||||
@ -168,7 +168,7 @@ class FastISel {
|
||||
virtual unsigned FastEmit_rf(MVT VT,
|
||||
MVT RetVT,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, ConstantFP *FPImm);
|
||||
unsigned Op0, const ConstantFP *FPImm);
|
||||
|
||||
/// FastEmit_rri - This method is called by target-independent code
|
||||
/// to request that an instruction with the given type, opcode, and
|
||||
@ -194,7 +194,7 @@ class FastISel {
|
||||
/// FastEmit_rr instead.
|
||||
unsigned FastEmit_rf_(MVT VT,
|
||||
unsigned Opcode,
|
||||
unsigned Op0, ConstantFP *FPImm,
|
||||
unsigned Op0, const ConstantFP *FPImm,
|
||||
MVT ImmType);
|
||||
|
||||
/// FastEmit_i - This method is called by target-independent code
|
||||
@ -211,7 +211,7 @@ class FastISel {
|
||||
virtual unsigned FastEmit_f(MVT VT,
|
||||
MVT RetVT,
|
||||
unsigned Opcode,
|
||||
ConstantFP *FPImm);
|
||||
const ConstantFP *FPImm);
|
||||
|
||||
/// FastEmitInst_ - Emit a MachineInstr with no operands and a
|
||||
/// result register in the given register class.
|
||||
@ -245,7 +245,7 @@ class FastISel {
|
||||
///
|
||||
unsigned FastEmitInst_rf(unsigned MachineInstOpcode,
|
||||
const TargetRegisterClass *RC,
|
||||
unsigned Op0, ConstantFP *FPImm);
|
||||
unsigned Op0, const ConstantFP *FPImm);
|
||||
|
||||
/// FastEmitInst_rri - Emit a MachineInstr with two register operands,
|
||||
/// an immediate, and a result register in the given register class.
|
||||
@ -275,34 +275,47 @@ class FastISel {
|
||||
/// the CFG.
|
||||
void FastEmitBranch(MachineBasicBlock *MBB);
|
||||
|
||||
unsigned UpdateValueMap(Value* I, unsigned Reg);
|
||||
unsigned UpdateValueMap(const Value* I, unsigned Reg);
|
||||
|
||||
unsigned createResultReg(const TargetRegisterClass *RC);
|
||||
|
||||
/// TargetMaterializeConstant - Emit a constant in a register using
|
||||
/// target-specific logic, such as constant pool loads.
|
||||
virtual unsigned TargetMaterializeConstant(Constant* C) {
|
||||
virtual unsigned TargetMaterializeConstant(const Constant* C) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// TargetMaterializeAlloca - Emit an alloca address in a register using
|
||||
/// target-specific logic.
|
||||
virtual unsigned TargetMaterializeAlloca(AllocaInst* C) {
|
||||
virtual unsigned TargetMaterializeAlloca(const AllocaInst* C) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
private:
|
||||
bool SelectBinaryOp(User *I, unsigned ISDOpcode);
|
||||
bool SelectBinaryOp(const User *I, unsigned ISDOpcode);
|
||||
|
||||
bool SelectFNeg(User *I);
|
||||
bool SelectFNeg(const User *I);
|
||||
|
||||
bool SelectGetElementPtr(User *I);
|
||||
bool SelectGetElementPtr(const User *I);
|
||||
|
||||
bool SelectCall(User *I);
|
||||
bool SelectCall(const User *I);
|
||||
|
||||
bool SelectBitCast(User *I);
|
||||
bool SelectBitCast(const User *I);
|
||||
|
||||
bool SelectCast(User *I, unsigned Opcode);
|
||||
bool SelectCast(const User *I, unsigned Opcode);
|
||||
|
||||
/// HandlePHINodesInSuccessorBlocks - Handle PHI nodes in successor blocks.
|
||||
/// Emit code to ensure constants are copied into registers when needed.
|
||||
/// Remember the virtual registers that need to be added to the Machine PHI
|
||||
/// nodes as input. We cannot just directly add them, because expansion
|
||||
/// might result in multiple MBB's for one BB. As such, the start of the
|
||||
/// BB might correspond to a different MBB than the end.
|
||||
bool HandlePHINodesInSuccessorBlocks(const BasicBlock *LLVMBB);
|
||||
|
||||
/// materializeRegForValue - Helper for getRegForVale. This function is
|
||||
/// called when the value isn't already available in a register and must
|
||||
/// be materialized with new instructions.
|
||||
unsigned materializeRegForValue(const Value *V, MVT VT);
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ namespace llvm {
|
||||
struct GCRoot {
|
||||
int Num; //< Usually a frame index.
|
||||
int StackOffset; //< Offset from the stack pointer.
|
||||
Constant *Metadata; //< Metadata straight from the call to llvm.gcroot.
|
||||
const Constant *Metadata;//< Metadata straight from the call to llvm.gcroot.
|
||||
|
||||
GCRoot(int N, Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
|
||||
GCRoot(int N, const Constant *MD) : Num(N), StackOffset(-1), Metadata(MD) {}
|
||||
};
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ namespace llvm {
|
||||
/// addStackRoot - Registers a root that lives on the stack. Num is the
|
||||
/// stack object ID for the alloca (if the code generator is
|
||||
// using MachineFrameInfo).
|
||||
void addStackRoot(int Num, Constant *Metadata) {
|
||||
void addStackRoot(int Num, const Constant *Metadata) {
|
||||
Roots.push_back(GCRoot(Num, Metadata));
|
||||
}
|
||||
|
||||
|
765
include/llvm/CodeGen/ISDOpcodes.h
Normal file
765
include/llvm/CodeGen/ISDOpcodes.h
Normal file
@ -0,0 +1,765 @@
|
||||
//===-- llvm/CodeGen/ISDOpcodes.h - CodeGen opcodes -------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file declares codegen opcodes and related utilities.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CODEGEN_ISDOPCODES_H
|
||||
#define LLVM_CODEGEN_ISDOPCODES_H
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// ISD namespace - This namespace contains an enum which represents all of the
|
||||
/// SelectionDAG node types and value types.
|
||||
///
|
||||
namespace ISD {
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISD::NodeType enum - This enum defines the target-independent operators
|
||||
/// for a SelectionDAG.
|
||||
///
|
||||
/// Targets may also define target-dependent operator codes for SDNodes. For
|
||||
/// example, on x86, these are the enum values in the X86ISD namespace.
|
||||
/// Targets should aim to use target-independent operators to model their
|
||||
/// instruction sets as much as possible, and only use target-dependent
|
||||
/// operators when they have special requirements.
|
||||
///
|
||||
/// Finally, during and after selection proper, SNodes may use special
|
||||
/// operator codes that correspond directly with MachineInstr opcodes. These
|
||||
/// are used to represent selected instructions. See the isMachineOpcode()
|
||||
/// and getMachineOpcode() member functions of SDNode.
|
||||
///
|
||||
enum NodeType {
|
||||
// DELETED_NODE - This is an illegal value that is used to catch
|
||||
// errors. This opcode is not a legal opcode for any node.
|
||||
DELETED_NODE,
|
||||
|
||||
// EntryToken - This is the marker used to indicate the start of the region.
|
||||
EntryToken,
|
||||
|
||||
// TokenFactor - This node takes multiple tokens as input and produces a
|
||||
// single token result. This is used to represent the fact that the operand
|
||||
// operators are independent of each other.
|
||||
TokenFactor,
|
||||
|
||||
// AssertSext, AssertZext - These nodes record if a register contains a
|
||||
// value that has already been zero or sign extended from a narrower type.
|
||||
// These nodes take two operands. The first is the node that has already
|
||||
// been extended, and the second is a value type node indicating the width
|
||||
// of the extension
|
||||
AssertSext, AssertZext,
|
||||
|
||||
// Various leaf nodes.
|
||||
BasicBlock, VALUETYPE, CONDCODE, Register,
|
||||
Constant, ConstantFP,
|
||||
GlobalAddress, GlobalTLSAddress, FrameIndex,
|
||||
JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
|
||||
|
||||
// The address of the GOT
|
||||
GLOBAL_OFFSET_TABLE,
|
||||
|
||||
// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
|
||||
// llvm.returnaddress on the DAG. These nodes take one operand, the index
|
||||
// of the frame or return address to return. An index of zero corresponds
|
||||
// to the current function's frame or return address, an index of one to the
|
||||
// parent's frame or return address, and so on.
|
||||
FRAMEADDR, RETURNADDR,
|
||||
|
||||
// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
|
||||
// first (possible) on-stack argument. This is needed for correct stack
|
||||
// adjustment during unwind.
|
||||
FRAME_TO_ARGS_OFFSET,
|
||||
|
||||
// RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
|
||||
// address of the exception block on entry to an landing pad block.
|
||||
EXCEPTIONADDR,
|
||||
|
||||
// RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
|
||||
// address of the Language Specific Data Area for the enclosing function.
|
||||
LSDAADDR,
|
||||
|
||||
// RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
|
||||
// the selection index of the exception thrown.
|
||||
EHSELECTION,
|
||||
|
||||
// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
|
||||
// 'eh_return' gcc dwarf builtin, which is used to return from
|
||||
// exception. The general meaning is: adjust stack by OFFSET and pass
|
||||
// execution to HANDLER. Many platform-related details also :)
|
||||
EH_RETURN,
|
||||
|
||||
// TargetConstant* - Like Constant*, but the DAG does not do any folding,
|
||||
// simplification, or lowering of the constant. They are used for constants
|
||||
// which are known to fit in the immediate fields of their users, or for
|
||||
// carrying magic numbers which are not values which need to be materialized
|
||||
// in registers.
|
||||
TargetConstant,
|
||||
TargetConstantFP,
|
||||
|
||||
// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
|
||||
// anything else with this node, and this is valid in the target-specific
|
||||
// dag, turning into a GlobalAddress operand.
|
||||
TargetGlobalAddress,
|
||||
TargetGlobalTLSAddress,
|
||||
TargetFrameIndex,
|
||||
TargetJumpTable,
|
||||
TargetConstantPool,
|
||||
TargetExternalSymbol,
|
||||
TargetBlockAddress,
|
||||
|
||||
/// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
|
||||
/// This node represents a target intrinsic function with no side effects.
|
||||
/// The first operand is the ID number of the intrinsic from the
|
||||
/// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
|
||||
/// node has returns the result of the intrinsic.
|
||||
INTRINSIC_WO_CHAIN,
|
||||
|
||||
/// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
|
||||
/// This node represents a target intrinsic function with side effects that
|
||||
/// returns a result. The first operand is a chain pointer. The second is
|
||||
/// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
|
||||
/// operands to the intrinsic follow. The node has two results, the result
|
||||
/// of the intrinsic and an output chain.
|
||||
INTRINSIC_W_CHAIN,
|
||||
|
||||
/// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
|
||||
/// This node represents a target intrinsic function with side effects that
|
||||
/// does not return a result. The first operand is a chain pointer. The
|
||||
/// second is the ID number of the intrinsic from the llvm::Intrinsic
|
||||
/// namespace. The operands to the intrinsic follow.
|
||||
INTRINSIC_VOID,
|
||||
|
||||
// CopyToReg - This node has three operands: a chain, a register number to
|
||||
// set to this value, and a value.
|
||||
CopyToReg,
|
||||
|
||||
// CopyFromReg - This node indicates that the input value is a virtual or
|
||||
// physical register that is defined outside of the scope of this
|
||||
// SelectionDAG. The register is available from the RegisterSDNode object.
|
||||
CopyFromReg,
|
||||
|
||||
// UNDEF - An undefined node
|
||||
UNDEF,
|
||||
|
||||
// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
|
||||
// a Constant, which is required to be operand #1) half of the integer or
|
||||
// float value specified as operand #0. This is only for use before
|
||||
// legalization, for values that will be broken into multiple registers.
|
||||
EXTRACT_ELEMENT,
|
||||
|
||||
// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
|
||||
// two values of the same integer value type, this produces a value twice as
|
||||
// big. Like EXTRACT_ELEMENT, this can only be used before legalization.
|
||||
BUILD_PAIR,
|
||||
|
||||
// MERGE_VALUES - This node takes multiple discrete operands and returns
|
||||
// them all as its individual results. This nodes has exactly the same
|
||||
// number of inputs and outputs. This node is useful for some pieces of the
|
||||
// code generator that want to think about a single node with multiple
|
||||
// results, not multiple nodes.
|
||||
MERGE_VALUES,
|
||||
|
||||
// Simple integer binary arithmetic operators.
|
||||
ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
|
||||
|
||||
// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
|
||||
// a signed/unsigned value of type i[2*N], and return the full value as
|
||||
// two results, each of type iN.
|
||||
SMUL_LOHI, UMUL_LOHI,
|
||||
|
||||
// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
|
||||
// remainder result.
|
||||
SDIVREM, UDIVREM,
|
||||
|
||||
// CARRY_FALSE - This node is used when folding other nodes,
|
||||
// like ADDC/SUBC, which indicate the carry result is always false.
|
||||
CARRY_FALSE,
|
||||
|
||||
// Carry-setting nodes for multiple precision addition and subtraction.
|
||||
// These nodes take two operands of the same value type, and produce two
|
||||
// results. The first result is the normal add or sub result, the second
|
||||
// result is the carry flag result.
|
||||
ADDC, SUBC,
|
||||
|
||||
// Carry-using nodes for multiple precision addition and subtraction. These
|
||||
// nodes take three operands: The first two are the normal lhs and rhs to
|
||||
// the add or sub, and the third is the input carry flag. These nodes
|
||||
// produce two results; the normal result of the add or sub, and the output
|
||||
// carry flag. These nodes both read and write a carry flag to allow them
|
||||
// to them to be chained together for add and sub of arbitrarily large
|
||||
// values.
|
||||
ADDE, SUBE,
|
||||
|
||||
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
|
||||
// These nodes take two operands: the normal LHS and RHS to the add. They
|
||||
// produce two results: the normal result of the add, and a boolean that
|
||||
// indicates if an overflow occured (*not* a flag, because it may be stored
|
||||
// to memory, etc.). If the type of the boolean is not i1 then the high
|
||||
// bits conform to getBooleanContents.
|
||||
// These nodes are generated from the llvm.[su]add.with.overflow intrinsics.
|
||||
SADDO, UADDO,
|
||||
|
||||
// Same for subtraction
|
||||
SSUBO, USUBO,
|
||||
|
||||
// Same for multiplication
|
||||
SMULO, UMULO,
|
||||
|
||||
// Simple binary floating point operators.
|
||||
FADD, FSUB, FMUL, FDIV, FREM,
|
||||
|
||||
// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
|
||||
// DAG node does not require that X and Y have the same type, just that they
|
||||
// are both floating point. X and the result must have the same type.
|
||||
// FCOPYSIGN(f32, f64) is allowed.
|
||||
FCOPYSIGN,
|
||||
|
||||
// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
|
||||
// value as an integer 0/1 value.
|
||||
FGETSIGN,
|
||||
|
||||
/// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the
|
||||
/// specified, possibly variable, elements. The number of elements is
|
||||
/// required to be a power of two. The types of the operands must all be
|
||||
/// the same and must match the vector element type, except that integer
|
||||
/// types are allowed to be larger than the element type, in which case
|
||||
/// the operands are implicitly truncated.
|
||||
BUILD_VECTOR,
|
||||
|
||||
/// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
|
||||
/// at IDX replaced with VAL. If the type of VAL is larger than the vector
|
||||
/// element type then VAL is truncated before replacement.
|
||||
INSERT_VECTOR_ELT,
|
||||
|
||||
/// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
|
||||
/// identified by the (potentially variable) element number IDX. If the
|
||||
/// return type is an integer type larger than the element type of the
|
||||
/// vector, the result is extended to the width of the return type.
|
||||
EXTRACT_VECTOR_ELT,
|
||||
|
||||
/// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
|
||||
/// vector type with the same length and element type, this produces a
|
||||
/// concatenated vector result value, with length equal to the sum of the
|
||||
/// lengths of the input vectors.
|
||||
CONCAT_VECTORS,
|
||||
|
||||
/// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
|
||||
/// vector value) starting with the (potentially variable) element number
|
||||
/// IDX, which must be a multiple of the result vector length.
|
||||
EXTRACT_SUBVECTOR,
|
||||
|
||||
/// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
|
||||
/// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int
|
||||
/// values that indicate which value (or undef) each result element will
|
||||
/// get. These constant ints are accessible through the
|
||||
/// ShuffleVectorSDNode class. This is quite similar to the Altivec
|
||||
/// 'vperm' instruction, except that the indices must be constants and are
|
||||
/// in terms of the element size of VEC1/VEC2, not in terms of bytes.
|
||||
VECTOR_SHUFFLE,
|
||||
|
||||
/// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
|
||||
/// scalar value into element 0 of the resultant vector type. The top
|
||||
/// elements 1 to N-1 of the N-element vector are undefined. The type
|
||||
/// of the operand must match the vector element type, except when they
|
||||
/// are integer types. In this case the operand is allowed to be wider
|
||||
/// than the vector element type, and is implicitly truncated to it.
|
||||
SCALAR_TO_VECTOR,
|
||||
|
||||
// MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
|
||||
// an unsigned/signed value of type i[2*N], then return the top part.
|
||||
MULHU, MULHS,
|
||||
|
||||
// Bitwise operators - logical and, logical or, logical xor, shift left,
|
||||
// shift right algebraic (shift in sign bits), shift right logical (shift in
|
||||
// zeroes), rotate left, rotate right, and byteswap.
|
||||
AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP,
|
||||
|
||||
// Counting operators
|
||||
CTTZ, CTLZ, CTPOP,
|
||||
|
||||
// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
|
||||
// i1 then the high bits must conform to getBooleanContents.
|
||||
SELECT,
|
||||
|
||||
// Select with condition operator - This selects between a true value and
|
||||
// a false value (ops #2 and #3) based on the boolean result of comparing
|
||||
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
|
||||
// condition code in op #4, a CondCodeSDNode.
|
||||
SELECT_CC,
|
||||
|
||||
// SetCC operator - This evaluates to a true value iff the condition is
|
||||
// true. If the result value type is not i1 then the high bits conform
|
||||
// to getBooleanContents. The operands to this are the left and right
|
||||
// operands to compare (ops #0, and #1) and the condition code to compare
|
||||
// them with (op #2) as a CondCodeSDNode.
|
||||
SETCC,
|
||||
|
||||
// RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of
|
||||
// integer elements with all bits of the result elements set to true if the
|
||||
// comparison is true or all cleared if the comparison is false. The
|
||||
// operands to this are the left and right operands to compare (LHS/RHS) and
|
||||
// the condition code to compare them with (COND) as a CondCodeSDNode.
|
||||
VSETCC,
|
||||
|
||||
// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
|
||||
// integer shift operations, just like ADD/SUB_PARTS. The operation
|
||||
// ordering is:
|
||||
// [Lo,Hi] = op [LoLHS,HiLHS], Amt
|
||||
SHL_PARTS, SRA_PARTS, SRL_PARTS,
|
||||
|
||||
// Conversion operators. These are all single input single output
|
||||
// operations. For all of these, the result type must be strictly
|
||||
// wider or narrower (depending on the operation) than the source
|
||||
// type.
|
||||
|
||||
// SIGN_EXTEND - Used for integer types, replicating the sign bit
|
||||
// into new bits.
|
||||
SIGN_EXTEND,
|
||||
|
||||
// ZERO_EXTEND - Used for integer types, zeroing the new bits.
|
||||
ZERO_EXTEND,
|
||||
|
||||
// ANY_EXTEND - Used for integer types. The high bits are undefined.
|
||||
ANY_EXTEND,
|
||||
|
||||
// TRUNCATE - Completely drop the high bits.
|
||||
TRUNCATE,
|
||||
|
||||
// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
|
||||
// depends on the first letter) to floating point.
|
||||
SINT_TO_FP,
|
||||
UINT_TO_FP,
|
||||
|
||||
// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
|
||||
// sign extend a small value in a large integer register (e.g. sign
|
||||
// extending the low 8 bits of a 32-bit register to fill the top 24 bits
|
||||
// with the 7th bit). The size of the smaller type is indicated by the 1th
|
||||
// operand, a ValueType node.
|
||||
SIGN_EXTEND_INREG,
|
||||
|
||||
/// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
|
||||
/// integer.
|
||||
FP_TO_SINT,
|
||||
FP_TO_UINT,
|
||||
|
||||
/// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
|
||||
/// down to the precision of the destination VT. TRUNC is a flag, which is
|
||||
/// always an integer that is zero or one. If TRUNC is 0, this is a
|
||||
/// normal rounding, if it is 1, this FP_ROUND is known to not change the
|
||||
/// value of Y.
|
||||
///
|
||||
/// The TRUNC = 1 case is used in cases where we know that the value will
|
||||
/// not be modified by the node, because Y is not using any of the extra
|
||||
/// precision of source type. This allows certain transformations like
|
||||
/// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for
|
||||
/// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
|
||||
FP_ROUND,
|
||||
|
||||
// FLT_ROUNDS_ - Returns current rounding mode:
|
||||
// -1 Undefined
|
||||
// 0 Round to 0
|
||||
// 1 Round to nearest
|
||||
// 2 Round to +inf
|
||||
// 3 Round to -inf
|
||||
FLT_ROUNDS_,
|
||||
|
||||
/// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and
|
||||
/// rounds it to a floating point value. It then promotes it and returns it
|
||||
/// in a register of the same size. This operation effectively just
|
||||
/// discards excess precision. The type to round down to is specified by
|
||||
/// the VT operand, a VTSDNode.
|
||||
FP_ROUND_INREG,
|
||||
|
||||
/// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
|
||||
FP_EXTEND,
|
||||
|
||||
// BIT_CONVERT - This operator converts between integer, vector and FP
|
||||
// values, as if the value was stored to memory with one type and loaded
|
||||
// from the same address with the other type (or equivalently for vector
|
||||
// format conversions, etc). The source and result are required to have
|
||||
// the same bit size (e.g. f32 <-> i32). This can also be used for
|
||||
// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
|
||||
// getNode().
|
||||
BIT_CONVERT,
|
||||
|
||||
// CONVERT_RNDSAT - This operator is used to support various conversions
|
||||
// between various types (float, signed, unsigned and vectors of those
|
||||
// types) with rounding and saturation. NOTE: Avoid using this operator as
|
||||
// most target don't support it and the operator might be removed in the
|
||||
// future. It takes the following arguments:
|
||||
// 0) value
|
||||
// 1) dest type (type to convert to)
|
||||
// 2) src type (type to convert from)
|
||||
// 3) rounding imm
|
||||
// 4) saturation imm
|
||||
// 5) ISD::CvtCode indicating the type of conversion to do
|
||||
CONVERT_RNDSAT,
|
||||
|
||||
// FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform
|
||||
// promotions and truncation for half-precision (16 bit) floating
|
||||
// numbers. We need special nodes since FP16 is a storage-only type with
|
||||
// special semantics of operations.
|
||||
FP16_TO_FP32, FP32_TO_FP16,
|
||||
|
||||
// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
|
||||
// FLOG, FLOG2, FLOG10, FEXP, FEXP2,
|
||||
// FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
|
||||
// point operations. These are inspired by libm.
|
||||
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
|
||||
FLOG, FLOG2, FLOG10, FEXP, FEXP2,
|
||||
FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
|
||||
|
||||
// LOAD and STORE have token chains as their first operand, then the same
|
||||
// operands as an LLVM load/store instruction, then an offset node that
|
||||
// is added / subtracted from the base pointer to form the address (for
|
||||
// indexed memory ops).
|
||||
LOAD, STORE,
|
||||
|
||||
// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
|
||||
// to a specified boundary. This node always has two return values: a new
|
||||
// stack pointer value and a chain. The first operand is the token chain,
|
||||
// the second is the number of bytes to allocate, and the third is the
|
||||
// alignment boundary. The size is guaranteed to be a multiple of the stack
|
||||
// alignment, and the alignment is guaranteed to be bigger than the stack
|
||||
// alignment (if required) or 0 to get standard stack alignment.
|
||||
DYNAMIC_STACKALLOC,
|
||||
|
||||
// Control flow instructions. These all have token chains.
|
||||
|
||||
// BR - Unconditional branch. The first operand is the chain
|
||||
// operand, the second is the MBB to branch to.
|
||||
BR,
|
||||
|
||||
// BRIND - Indirect branch. The first operand is the chain, the second
|
||||
// is the value to branch to, which must be of the same type as the target's
|
||||
// pointer type.
|
||||
BRIND,
|
||||
|
||||
// BR_JT - Jumptable branch. The first operand is the chain, the second
|
||||
// is the jumptable index, the last one is the jumptable entry index.
|
||||
BR_JT,
|
||||
|
||||
// BRCOND - Conditional branch. The first operand is the chain, the
|
||||
// second is the condition, the third is the block to branch to if the
|
||||
// condition is true. If the type of the condition is not i1, then the
|
||||
// high bits must conform to getBooleanContents.
|
||||
BRCOND,
|
||||
|
||||
// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
|
||||
// that the condition is represented as condition code, and two nodes to
|
||||
// compare, rather than as a combined SetCC node. The operands in order are
|
||||
// chain, cc, lhs, rhs, block to branch to if condition is true.
|
||||
BR_CC,
|
||||
|
||||
// INLINEASM - Represents an inline asm block. This node always has two
|
||||
// return values: a chain and a flag result. The inputs are as follows:
|
||||
// Operand #0 : Input chain.
|
||||
// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
|
||||
// Operand #2 : a MDNodeSDNode with the !srcloc metadata.
|
||||
// After this, it is followed by a list of operands with this format:
|
||||
// ConstantSDNode: Flags that encode whether it is a mem or not, the
|
||||
// of operands that follow, etc. See InlineAsm.h.
|
||||
// ... however many operands ...
|
||||
// Operand #last: Optional, an incoming flag.
|
||||
//
|
||||
// The variable width operands are required to represent target addressing
|
||||
// modes as a single "operand", even though they may have multiple
|
||||
// SDOperands.
|
||||
INLINEASM,
|
||||
|
||||
// EH_LABEL - Represents a label in mid basic block used to track
|
||||
// locations needed for debug and exception handling tables. These nodes
|
||||
// take a chain as input and return a chain.
|
||||
EH_LABEL,
|
||||
|
||||
// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
|
||||
// value, the same type as the pointer type for the system, and an output
|
||||
// chain.
|
||||
STACKSAVE,
|
||||
|
||||
// STACKRESTORE has two operands, an input chain and a pointer to restore to
|
||||
// it returns an output chain.
|
||||
STACKRESTORE,
|
||||
|
||||
// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
|
||||
// a call sequence, and carry arbitrary information that target might want
|
||||
// to know. The first operand is a chain, the rest are specified by the
|
||||
// target and not touched by the DAG optimizers.
|
||||
// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
|
||||
CALLSEQ_START, // Beginning of a call sequence
|
||||
CALLSEQ_END, // End of a call sequence
|
||||
|
||||
// VAARG - VAARG has three operands: an input chain, a pointer, and a
|
||||
// SRCVALUE. It returns a pair of values: the vaarg value and a new chain.
|
||||
VAARG,
|
||||
|
||||
// VACOPY - VACOPY has five operands: an input chain, a destination pointer,
|
||||
// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
|
||||
// source.
|
||||
VACOPY,
|
||||
|
||||
// VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
|
||||
// pointer, and a SRCVALUE.
|
||||
VAEND, VASTART,
|
||||
|
||||
// SRCVALUE - This is a node type that holds a Value* that is used to
|
||||
// make reference to a value in the LLVM IR.
|
||||
SRCVALUE,
|
||||
|
||||
// MDNODE_SDNODE - This is a node that holdes an MDNode*, which is used to
|
||||
// reference metadata in the IR.
|
||||
MDNODE_SDNODE,
|
||||
|
||||
// PCMARKER - This corresponds to the pcmarker intrinsic.
|
||||
PCMARKER,
|
||||
|
||||
// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
|
||||
// The only operand is a chain and a value and a chain are produced. The
|
||||
// value is the contents of the architecture specific cycle counter like
|
||||
// register (or other high accuracy low latency clock source)
|
||||
READCYCLECOUNTER,
|
||||
|
||||
// HANDLENODE node - Used as a handle for various purposes.
|
||||
HANDLENODE,
|
||||
|
||||
// TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
|
||||
// It takes as input a token chain, the pointer to the trampoline,
|
||||
// the pointer to the nested function, the pointer to pass for the
|
||||
// 'nest' parameter, a SRCVALUE for the trampoline and another for
|
||||
// the nested function (allowing targets to access the original
|
||||
// Function*). It produces the result of the intrinsic and a token
|
||||
// chain as output.
|
||||
TRAMPOLINE,
|
||||
|
||||
// TRAP - Trapping instruction
|
||||
TRAP,
|
||||
|
||||
// PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are
|
||||
// their first operand. The other operands are the address to prefetch,
|
||||
// read / write specifier, and locality specifier.
|
||||
PREFETCH,
|
||||
|
||||
// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,
|
||||
// store-store, device)
|
||||
// This corresponds to the memory.barrier intrinsic.
|
||||
// it takes an input chain, 4 operands to specify the type of barrier, an
|
||||
// operand specifying if the barrier applies to device and uncached memory
|
||||
// and produces an output chain.
|
||||
MEMBARRIER,
|
||||
|
||||
// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
|
||||
// this corresponds to the atomic.lcs intrinsic.
|
||||
// cmp is compared to *ptr, and if equal, swap is stored in *ptr.
|
||||
// the return is always the original value in *ptr
|
||||
ATOMIC_CMP_SWAP,
|
||||
|
||||
// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
|
||||
// this corresponds to the atomic.swap intrinsic.
|
||||
// amt is stored to *ptr atomically.
|
||||
// the return is always the original value in *ptr
|
||||
ATOMIC_SWAP,
|
||||
|
||||
// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
|
||||
// this corresponds to the atomic.load.[OpName] intrinsic.
|
||||
// op(*ptr, amt) is stored to *ptr atomically.
|
||||
// the return is always the original value in *ptr
|
||||
ATOMIC_LOAD_ADD,
|
||||
ATOMIC_LOAD_SUB,
|
||||
ATOMIC_LOAD_AND,
|
||||
ATOMIC_LOAD_OR,
|
||||
ATOMIC_LOAD_XOR,
|
||||
ATOMIC_LOAD_NAND,
|
||||
ATOMIC_LOAD_MIN,
|
||||
ATOMIC_LOAD_MAX,
|
||||
ATOMIC_LOAD_UMIN,
|
||||
ATOMIC_LOAD_UMAX,
|
||||
|
||||
/// BUILTIN_OP_END - This must be the last enum value in this list.
|
||||
/// The target-specific pre-isel opcode values start here.
|
||||
BUILTIN_OP_END
|
||||
};
|
||||
|
||||
/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
|
||||
/// which do not reference a specific memory location should be less than
|
||||
/// this value. Those that do must not be less than this value, and can
|
||||
/// be used with SelectionDAG::getMemIntrinsicNode.
|
||||
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100;
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// MemIndexedMode enum - This enum defines the load / store indexed
|
||||
/// addressing modes.
|
||||
///
|
||||
/// UNINDEXED "Normal" load / store. The effective address is already
|
||||
/// computed and is available in the base pointer. The offset
|
||||
/// operand is always undefined. In addition to producing a
|
||||
/// chain, an unindexed load produces one value (result of the
|
||||
/// load); an unindexed store does not produce a value.
|
||||
///
|
||||
/// PRE_INC Similar to the unindexed mode where the effective address is
|
||||
/// PRE_DEC the value of the base pointer add / subtract the offset.
|
||||
/// It considers the computation as being folded into the load /
|
||||
/// store operation (i.e. the load / store does the address
|
||||
/// computation as well as performing the memory transaction).
|
||||
/// The base operand is always undefined. In addition to
|
||||
/// producing a chain, pre-indexed load produces two values
|
||||
/// (result of the load and the result of the address
|
||||
/// computation); a pre-indexed store produces one value (result
|
||||
/// of the address computation).
|
||||
///
|
||||
/// POST_INC The effective address is the value of the base pointer. The
|
||||
/// POST_DEC value of the offset operand is then added to / subtracted
|
||||
/// from the base after memory transaction. In addition to
|
||||
/// producing a chain, post-indexed load produces two values
|
||||
/// (the result of the load and the result of the base +/- offset
|
||||
/// computation); a post-indexed store produces one value (the
|
||||
/// the result of the base +/- offset computation).
|
||||
///
|
||||
enum MemIndexedMode {
|
||||
UNINDEXED = 0,
|
||||
PRE_INC,
|
||||
PRE_DEC,
|
||||
POST_INC,
|
||||
POST_DEC,
|
||||
LAST_INDEXED_MODE
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// LoadExtType enum - This enum defines the three variants of LOADEXT
|
||||
/// (load with extension).
|
||||
///
|
||||
/// SEXTLOAD loads the integer operand and sign extends it to a larger
|
||||
/// integer result type.
|
||||
/// ZEXTLOAD loads the integer operand and zero extends it to a larger
|
||||
/// integer result type.
|
||||
/// EXTLOAD is used for three things: floating point extending loads,
|
||||
/// integer extending loads [the top bits are undefined], and vector
|
||||
/// extending loads [load into low elt].
|
||||
///
|
||||
enum LoadExtType {
|
||||
NON_EXTLOAD = 0,
|
||||
EXTLOAD,
|
||||
SEXTLOAD,
|
||||
ZEXTLOAD,
|
||||
LAST_LOADEXT_TYPE
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISD::CondCode enum - These are ordered carefully to make the bitfields
|
||||
/// below work out, when considering SETFALSE (something that never exists
|
||||
/// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
|
||||
/// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
|
||||
/// to. If the "N" column is 1, the result of the comparison is undefined if
|
||||
/// the input is a NAN.
|
||||
///
|
||||
/// All of these (except for the 'always folded ops') should be handled for
|
||||
/// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
|
||||
/// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
|
||||
///
|
||||
/// Note that these are laid out in a specific order to allow bit-twiddling
|
||||
/// to transform conditions.
|
||||
enum CondCode {
|
||||
// Opcode N U L G E Intuitive operation
|
||||
SETFALSE, // 0 0 0 0 Always false (always folded)
|
||||
SETOEQ, // 0 0 0 1 True if ordered and equal
|
||||
SETOGT, // 0 0 1 0 True if ordered and greater than
|
||||
SETOGE, // 0 0 1 1 True if ordered and greater than or equal
|
||||
SETOLT, // 0 1 0 0 True if ordered and less than
|
||||
SETOLE, // 0 1 0 1 True if ordered and less than or equal
|
||||
SETONE, // 0 1 1 0 True if ordered and operands are unequal
|
||||
SETO, // 0 1 1 1 True if ordered (no nans)
|
||||
SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
|
||||
SETUEQ, // 1 0 0 1 True if unordered or equal
|
||||
SETUGT, // 1 0 1 0 True if unordered or greater than
|
||||
SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
|
||||
SETULT, // 1 1 0 0 True if unordered or less than
|
||||
SETULE, // 1 1 0 1 True if unordered, less than, or equal
|
||||
SETUNE, // 1 1 1 0 True if unordered or not equal
|
||||
SETTRUE, // 1 1 1 1 Always true (always folded)
|
||||
// Don't care operations: undefined if the input is a nan.
|
||||
SETFALSE2, // 1 X 0 0 0 Always false (always folded)
|
||||
SETEQ, // 1 X 0 0 1 True if equal
|
||||
SETGT, // 1 X 0 1 0 True if greater than
|
||||
SETGE, // 1 X 0 1 1 True if greater than or equal
|
||||
SETLT, // 1 X 1 0 0 True if less than
|
||||
SETLE, // 1 X 1 0 1 True if less than or equal
|
||||
SETNE, // 1 X 1 1 0 True if not equal
|
||||
SETTRUE2, // 1 X 1 1 1 Always true (always folded)
|
||||
|
||||
SETCC_INVALID // Marker value.
|
||||
};
|
||||
|
||||
/// isSignedIntSetCC - Return true if this is a setcc instruction that
|
||||
/// performs a signed comparison when used with integer operands.
|
||||
inline bool isSignedIntSetCC(CondCode Code) {
|
||||
return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
|
||||
}
|
||||
|
||||
/// isUnsignedIntSetCC - Return true if this is a setcc instruction that
|
||||
/// performs an unsigned comparison when used with integer operands.
|
||||
inline bool isUnsignedIntSetCC(CondCode Code) {
|
||||
return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
|
||||
}
|
||||
|
||||
/// isTrueWhenEqual - Return true if the specified condition returns true if
|
||||
/// the two operands to the condition are equal. Note that if one of the two
|
||||
/// operands is a NaN, this value is meaningless.
|
||||
inline bool isTrueWhenEqual(CondCode Cond) {
|
||||
return ((int)Cond & 1) != 0;
|
||||
}
|
||||
|
||||
/// getUnorderedFlavor - This function returns 0 if the condition is always
|
||||
/// false if an operand is a NaN, 1 if the condition is always true if the
|
||||
/// operand is a NaN, and 2 if the condition is undefined if the operand is a
|
||||
/// NaN.
|
||||
inline unsigned getUnorderedFlavor(CondCode Cond) {
|
||||
return ((int)Cond >> 3) & 3;
|
||||
}
|
||||
|
||||
/// getSetCCInverse - Return the operation corresponding to !(X op Y), where
|
||||
/// 'op' is a valid SetCC operation.
|
||||
CondCode getSetCCInverse(CondCode Operation, bool isInteger);
|
||||
|
||||
/// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
|
||||
/// when given the operation for (X op Y).
|
||||
CondCode getSetCCSwappedOperands(CondCode Operation);
|
||||
|
||||
/// getSetCCOrOperation - Return the result of a logical OR between different
|
||||
/// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This
|
||||
/// function returns SETCC_INVALID if it is not possible to represent the
|
||||
/// resultant comparison.
|
||||
CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);
|
||||
|
||||
/// getSetCCAndOperation - Return the result of a logical AND between
|
||||
/// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This
|
||||
/// function returns SETCC_INVALID if it is not possible to represent the
|
||||
/// resultant comparison.
|
||||
CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT
|
||||
/// supports.
|
||||
enum CvtCode {
|
||||
CVT_FF, // Float from Float
|
||||
CVT_FS, // Float from Signed
|
||||
CVT_FU, // Float from Unsigned
|
||||
CVT_SF, // Signed from Float
|
||||
CVT_UF, // Unsigned from Float
|
||||
CVT_SS, // Signed from Signed
|
||||
CVT_SU, // Signed from Unsigned
|
||||
CVT_US, // Unsigned from Signed
|
||||
CVT_UU, // Unsigned from Unsigned
|
||||
CVT_INVALID // Marker - Invalid opcode
|
||||
};
|
||||
|
||||
} // end llvm::ISD namespace
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
@ -21,6 +21,7 @@
|
||||
#include "llvm/System/DataTypes.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/CodeGen/MachineCodeEmitter.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -173,13 +174,20 @@ class JITCodeEmitter : public MachineCodeEmitter {
|
||||
|
||||
/// emitULEB128Bytes - This callback is invoked when a ULEB128 needs to be
|
||||
/// written to the output stream.
|
||||
void emitULEB128Bytes(uint64_t Value) {
|
||||
void emitULEB128Bytes(uint64_t Value, unsigned PadTo = 0) {
|
||||
do {
|
||||
uint8_t Byte = Value & 0x7f;
|
||||
Value >>= 7;
|
||||
if (Value) Byte |= 0x80;
|
||||
if (Value || PadTo != 0) Byte |= 0x80;
|
||||
emitByte(Byte);
|
||||
} while (Value);
|
||||
|
||||
if (PadTo) {
|
||||
do {
|
||||
uint8_t Byte = (PadTo > 1) ? 0x80 : 0x0;
|
||||
emitByte(Byte);
|
||||
} while (--PadTo);
|
||||
}
|
||||
}
|
||||
|
||||
/// emitSLEB128Bytes - This callback is invoked when a SLEB128 needs to be
|
||||
@ -324,6 +332,10 @@ class JITCodeEmitter : public MachineCodeEmitter {
|
||||
/// Specifies the MachineModuleInfo object. This is used for exception handling
|
||||
/// purposes.
|
||||
virtual void setModuleInfo(MachineModuleInfo* Info) = 0;
|
||||
|
||||
/// getLabelLocations - Return the label locations map of the label IDs to
|
||||
/// their address.
|
||||
virtual DenseMap<MCSymbol*, uintptr_t> *getLabelLocations() { return 0; }
|
||||
};
|
||||
|
||||
} // End llvm namespace
|
||||
|
@ -34,6 +34,7 @@ namespace {
|
||||
(void) llvm::createDeadMachineInstructionElimPass();
|
||||
|
||||
(void) llvm::createLocalRegisterAllocator();
|
||||
(void) llvm::createFastRegisterAllocator();
|
||||
(void) llvm::createLinearScanRegisterAllocator();
|
||||
(void) llvm::createPBQPRegisterAllocator();
|
||||
|
||||
|
@ -111,6 +111,12 @@ namespace llvm {
|
||||
double getScaledIntervalSize(LiveInterval& I) {
|
||||
return (1000.0 * I.getSize()) / indexes_->getIndexesLength();
|
||||
}
|
||||
|
||||
/// getFuncInstructionCount - Return the number of instructions in the
|
||||
/// current function.
|
||||
unsigned getFuncInstructionCount() {
|
||||
return indexes_->getFunctionSize();
|
||||
}
|
||||
|
||||
/// getApproximateInstructionCount - computes an estimate of the number
|
||||
/// of instructions in a given LiveInterval.
|
||||
|
@ -201,12 +201,9 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
|
||||
// Iteration support for live in sets. These sets are kept in sorted
|
||||
// order by their register number.
|
||||
typedef std::vector<unsigned>::iterator livein_iterator;
|
||||
typedef std::vector<unsigned>::const_iterator const_livein_iterator;
|
||||
livein_iterator livein_begin() { return LiveIns.begin(); }
|
||||
const_livein_iterator livein_begin() const { return LiveIns.begin(); }
|
||||
livein_iterator livein_end() { return LiveIns.end(); }
|
||||
const_livein_iterator livein_end() const { return LiveIns.end(); }
|
||||
typedef std::vector<unsigned>::const_iterator livein_iterator;
|
||||
livein_iterator livein_begin() const { return LiveIns.begin(); }
|
||||
livein_iterator livein_end() const { return LiveIns.end(); }
|
||||
bool livein_empty() const { return LiveIns.empty(); }
|
||||
|
||||
/// getAlignment - Return alignment of the basic block.
|
||||
|
@ -74,7 +74,7 @@ class MachineConstantPoolEntry {
|
||||
public:
|
||||
/// The constant itself.
|
||||
union {
|
||||
Constant *ConstVal;
|
||||
const Constant *ConstVal;
|
||||
MachineConstantPoolValue *MachineCPVal;
|
||||
} Val;
|
||||
|
||||
@ -82,7 +82,7 @@ class MachineConstantPoolEntry {
|
||||
/// a MachineConstantPoolValue.
|
||||
unsigned Alignment;
|
||||
|
||||
MachineConstantPoolEntry(Constant *V, unsigned A)
|
||||
MachineConstantPoolEntry(const Constant *V, unsigned A)
|
||||
: Alignment(A) {
|
||||
Val.ConstVal = V;
|
||||
}
|
||||
@ -143,7 +143,7 @@ class MachineConstantPool {
|
||||
/// getConstantPoolIndex - Create a new entry in the constant pool or return
|
||||
/// an existing one. User must specify the minimum required alignment for
|
||||
/// the object.
|
||||
unsigned getConstantPoolIndex(Constant *C, unsigned Alignment);
|
||||
unsigned getConstantPoolIndex(const Constant *C, unsigned Alignment);
|
||||
unsigned getConstantPoolIndex(MachineConstantPoolValue *V,unsigned Alignment);
|
||||
|
||||
/// isEmpty - Return true if this constant pool contains no constants.
|
||||
|
@ -70,7 +70,7 @@ struct MachineFunctionInfo {
|
||||
};
|
||||
|
||||
class MachineFunction {
|
||||
Function *Fn;
|
||||
const Function *Fn;
|
||||
const TargetMachine &Target;
|
||||
MCContext &Ctx;
|
||||
MachineModuleInfo &MMI;
|
||||
@ -109,10 +109,6 @@ class MachineFunction {
|
||||
typedef ilist<MachineBasicBlock> BasicBlockListType;
|
||||
BasicBlockListType BasicBlocks;
|
||||
|
||||
/// Default debug location. Used to print out the debug label at the beginning
|
||||
/// of a function.
|
||||
DebugLoc DefaultDebugLoc;
|
||||
|
||||
/// FunctionNumber - This provides a unique ID for each function emitted in
|
||||
/// this translation unit.
|
||||
///
|
||||
@ -124,8 +120,8 @@ class MachineFunction {
|
||||
MachineFunction(const MachineFunction &); // DO NOT IMPLEMENT
|
||||
void operator=(const MachineFunction&); // DO NOT IMPLEMENT
|
||||
public:
|
||||
MachineFunction(Function *Fn, const TargetMachine &TM, unsigned FunctionNum,
|
||||
MachineModuleInfo &MMI);
|
||||
MachineFunction(const Function *Fn, const TargetMachine &TM,
|
||||
unsigned FunctionNum, MachineModuleInfo &MMI);
|
||||
~MachineFunction();
|
||||
|
||||
MachineModuleInfo &getMMI() const { return MMI; }
|
||||
@ -133,7 +129,7 @@ class MachineFunction {
|
||||
|
||||
/// getFunction - Return the LLVM function that this machine code represents
|
||||
///
|
||||
Function *getFunction() const { return Fn; }
|
||||
const Function *getFunction() const { return Fn; }
|
||||
|
||||
/// getFunctionNumber - Return a unique ID for the current function.
|
||||
///
|
||||
@ -394,19 +390,6 @@ class MachineFunction {
|
||||
/// normal 'L' label is returned.
|
||||
MCSymbol *getJTISymbol(unsigned JTI, MCContext &Ctx,
|
||||
bool isLinkerPrivate = false) const;
|
||||
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
// Debug location.
|
||||
//
|
||||
|
||||
/// getDefaultDebugLoc - Get the default debug location for the machine
|
||||
/// function.
|
||||
DebugLoc getDefaultDebugLoc() const { return DefaultDebugLoc; }
|
||||
|
||||
/// setDefaultDebugLoc - Get the default debug location for the machine
|
||||
/// function.
|
||||
void setDefaultDebugLoc(DebugLoc DL) { DefaultDebugLoc = DL; }
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
|
@ -91,15 +91,14 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
// over time, the non-DebugLoc versions should be phased out and eventually
|
||||
// removed.
|
||||
|
||||
/// MachineInstr ctor - This constructor create a MachineInstr and add the
|
||||
/// implicit operands. It reserves space for number of operands specified by
|
||||
/// TargetInstrDesc. The version with a DebugLoc should be preferred.
|
||||
/// MachineInstr ctor - This constructor creates a MachineInstr and adds the
|
||||
/// implicit operands. It reserves space for the number of operands specified
|
||||
/// by the TargetInstrDesc. The version with a DebugLoc should be preferred.
|
||||
explicit MachineInstr(const TargetInstrDesc &TID, bool NoImp = false);
|
||||
|
||||
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
|
||||
/// the MachineInstr is created and added to the end of the specified basic
|
||||
/// block. The version with a DebugLoc should be preferred.
|
||||
///
|
||||
MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &TID);
|
||||
|
||||
/// MachineInstr ctor - This constructor create a MachineInstr and add the
|
||||
@ -111,7 +110,6 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
/// MachineInstr ctor - Work exactly the same as the ctor above, except that
|
||||
/// the MachineInstr is created and added to the end of the specified basic
|
||||
/// block.
|
||||
///
|
||||
MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl,
|
||||
const TargetInstrDesc &TID);
|
||||
|
||||
@ -357,6 +355,10 @@ class MachineInstr : public ilist_node<MachineInstr> {
|
||||
/// return 0.
|
||||
unsigned isConstantValuePHI() const;
|
||||
|
||||
/// allDefsAreDead - Return true if all the defs of this instruction are dead.
|
||||
///
|
||||
bool allDefsAreDead() const;
|
||||
|
||||
//
|
||||
// Debugging support
|
||||
//
|
||||
|
@ -104,7 +104,7 @@ class MachineInstrBuilder {
|
||||
return *this;
|
||||
}
|
||||
|
||||
const MachineInstrBuilder &addGlobalAddress(GlobalValue *GV,
|
||||
const MachineInstrBuilder &addGlobalAddress(const GlobalValue *GV,
|
||||
int64_t Offset = 0,
|
||||
unsigned char TargetFlags = 0) const {
|
||||
MI->addOperand(MachineOperand::CreateGA(GV, Offset, TargetFlags));
|
||||
|
@ -82,7 +82,7 @@ struct LandingPadInfo {
|
||||
SmallVector<MCSymbol*, 1> BeginLabels; // Labels prior to invoke.
|
||||
SmallVector<MCSymbol*, 1> EndLabels; // Labels after invoke.
|
||||
MCSymbol *LandingPadLabel; // Label at beginning of landing pad.
|
||||
Function *Personality; // Personality function.
|
||||
const Function *Personality; // Personality function.
|
||||
std::vector<int> TypeIds; // List of type ids (filters negative)
|
||||
|
||||
explicit LandingPadInfo(MachineBasicBlock *MBB)
|
||||
@ -101,7 +101,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
MCContext Context;
|
||||
|
||||
/// TheModule - This is the LLVM Module being worked on.
|
||||
Module *TheModule;
|
||||
const Module *TheModule;
|
||||
|
||||
/// ObjFileMMI - This is the object-file-format-specific implementation of
|
||||
/// MachineModuleInfoImpl, which lets targets accumulate whatever info they
|
||||
@ -125,7 +125,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
// TypeInfos - List of C++ TypeInfo used in the current function.
|
||||
//
|
||||
std::vector<GlobalVariable *> TypeInfos;
|
||||
std::vector<const GlobalVariable *> TypeInfos;
|
||||
|
||||
// FilterIds - List of typeids encoding filters used in the current function.
|
||||
//
|
||||
@ -138,7 +138,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
// Personalities - Vector of all personality functions ever seen. Used to emit
|
||||
// common EH frames.
|
||||
std::vector<Function *> Personalities;
|
||||
std::vector<const Function *> Personalities;
|
||||
|
||||
/// UsedFunctions - The functions in the @llvm.used list in a more easily
|
||||
/// searchable format. This does not include the functions in
|
||||
@ -179,8 +179,8 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
const MCContext &getContext() const { return Context; }
|
||||
MCContext &getContext() { return Context; }
|
||||
|
||||
void setModule(Module *M) { TheModule = M; }
|
||||
Module *getModule() const { return TheModule; }
|
||||
void setModule(const Module *M) { TheModule = M; }
|
||||
const Module *getModule() const { return TheModule; }
|
||||
|
||||
/// getInfo - Keep track of various per-function pieces of information for
|
||||
/// backends that would like to do so.
|
||||
@ -199,7 +199,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
/// AnalyzeModule - Scan the module for global debug information.
|
||||
///
|
||||
void AnalyzeModule(Module &M);
|
||||
void AnalyzeModule(const Module &M);
|
||||
|
||||
/// hasDebugInfo - Returns true if valid debug info is present.
|
||||
///
|
||||
@ -252,14 +252,15 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
/// addPersonality - Provide the personality function for the exception
|
||||
/// information.
|
||||
void addPersonality(MachineBasicBlock *LandingPad, Function *Personality);
|
||||
void addPersonality(MachineBasicBlock *LandingPad,
|
||||
const Function *Personality);
|
||||
|
||||
/// getPersonalityIndex - Get index of the current personality function inside
|
||||
/// Personalitites array
|
||||
unsigned getPersonalityIndex() const;
|
||||
|
||||
/// getPersonalities - Return array of personality functions ever seen.
|
||||
const std::vector<Function *>& getPersonalities() const {
|
||||
const std::vector<const Function *>& getPersonalities() const {
|
||||
return Personalities;
|
||||
}
|
||||
|
||||
@ -273,12 +274,12 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
/// addCatchTypeInfo - Provide the catch typeinfo for a landing pad.
|
||||
///
|
||||
void addCatchTypeInfo(MachineBasicBlock *LandingPad,
|
||||
std::vector<GlobalVariable *> &TyInfo);
|
||||
std::vector<const GlobalVariable *> &TyInfo);
|
||||
|
||||
/// addFilterTypeInfo - Provide the filter typeinfo for a landing pad.
|
||||
///
|
||||
void addFilterTypeInfo(MachineBasicBlock *LandingPad,
|
||||
std::vector<GlobalVariable *> &TyInfo);
|
||||
std::vector<const GlobalVariable *> &TyInfo);
|
||||
|
||||
/// addCleanup - Add a cleanup action for a landing pad.
|
||||
///
|
||||
@ -286,7 +287,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
/// getTypeIDFor - Return the type id for the specified typeinfo. This is
|
||||
/// function wide.
|
||||
unsigned getTypeIDFor(GlobalVariable *TI);
|
||||
unsigned getTypeIDFor(const GlobalVariable *TI);
|
||||
|
||||
/// getFilterIDFor - Return the id of the filter encoded by TyIds. This is
|
||||
/// function wide.
|
||||
@ -294,7 +295,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
/// TidyLandingPads - Remap landing pad labels and remove any deleted landing
|
||||
/// pads.
|
||||
void TidyLandingPads();
|
||||
void TidyLandingPads(DenseMap<MCSymbol*, uintptr_t> *LPMap = 0);
|
||||
|
||||
/// getLandingPads - Return a reference to the landing pad info for the
|
||||
/// current function.
|
||||
@ -323,7 +324,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
/// getTypeInfos - Return a reference to the C++ typeinfo for the current
|
||||
/// function.
|
||||
const std::vector<GlobalVariable *> &getTypeInfos() const {
|
||||
const std::vector<const GlobalVariable *> &getTypeInfos() const {
|
||||
return TypeInfos;
|
||||
}
|
||||
|
||||
@ -335,7 +336,7 @@ class MachineModuleInfo : public ImmutablePass {
|
||||
|
||||
/// getPersonality - Return a personality function if available. The presence
|
||||
/// of one is required to emit exception handling info.
|
||||
Function *getPersonality() const;
|
||||
const Function *getPersonality() const;
|
||||
|
||||
/// setVariableDbgInfo - Collect information used to emit debugging
|
||||
/// information of a variable.
|
||||
|
@ -117,8 +117,8 @@ class MachineOperand {
|
||||
union {
|
||||
int Index; // For MO_*Index - The index itself.
|
||||
const char *SymbolName; // For MO_ExternalSymbol.
|
||||
GlobalValue *GV; // For MO_GlobalAddress.
|
||||
BlockAddress *BA; // For MO_BlockAddress.
|
||||
const GlobalValue *GV; // For MO_GlobalAddress.
|
||||
const BlockAddress *BA; // For MO_BlockAddress.
|
||||
} Val;
|
||||
int64_t Offset; // An offset from the object.
|
||||
} OffsetedInfo;
|
||||
@ -315,12 +315,12 @@ class MachineOperand {
|
||||
return Contents.OffsetedInfo.Val.Index;
|
||||
}
|
||||
|
||||
GlobalValue *getGlobal() const {
|
||||
const GlobalValue *getGlobal() const {
|
||||
assert(isGlobal() && "Wrong MachineOperand accessor");
|
||||
return Contents.OffsetedInfo.Val.GV;
|
||||
}
|
||||
|
||||
BlockAddress *getBlockAddress() const {
|
||||
const BlockAddress *getBlockAddress() const {
|
||||
assert(isBlockAddress() && "Wrong MachineOperand accessor");
|
||||
return Contents.OffsetedInfo.Val.BA;
|
||||
}
|
||||
@ -457,7 +457,7 @@ class MachineOperand {
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateGA(GlobalValue *GV, int64_t Offset,
|
||||
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_GlobalAddress);
|
||||
Op.Contents.OffsetedInfo.Val.GV = GV;
|
||||
@ -473,7 +473,7 @@ class MachineOperand {
|
||||
Op.setTargetFlags(TargetFlags);
|
||||
return Op;
|
||||
}
|
||||
static MachineOperand CreateBA(BlockAddress *BA,
|
||||
static MachineOperand CreateBA(const BlockAddress *BA,
|
||||
unsigned char TargetFlags = 0) {
|
||||
MachineOperand Op(MachineOperand::MO_BlockAddress);
|
||||
Op.Contents.OffsetedInfo.Val.BA = BA;
|
||||
|
@ -258,18 +258,18 @@ class MachineRegisterInfo {
|
||||
liveout_iterator liveout_end() const { return LiveOuts.end(); }
|
||||
bool liveout_empty() const { return LiveOuts.empty(); }
|
||||
|
||||
bool isLiveIn(unsigned Reg) const {
|
||||
for (livein_iterator I = livein_begin(), E = livein_end(); I != E; ++I)
|
||||
if (I->first == Reg || I->second == Reg)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool isLiveOut(unsigned Reg) const {
|
||||
for (liveout_iterator I = liveout_begin(), E = liveout_end(); I != E; ++I)
|
||||
if (*I == Reg)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
bool isLiveIn(unsigned Reg) const;
|
||||
bool isLiveOut(unsigned Reg) const;
|
||||
|
||||
/// getLiveInPhysReg - If VReg is a live-in virtual register, return the
|
||||
/// corresponding live-in physical register.
|
||||
unsigned getLiveInPhysReg(unsigned VReg) const;
|
||||
|
||||
/// EmitLiveInCopies - Emit copies to initialize livein virtual registers
|
||||
/// into the given entry block.
|
||||
void EmitLiveInCopies(MachineBasicBlock *EntryMBB,
|
||||
const TargetRegisterInfo &TRI,
|
||||
const TargetInstrInfo &TII);
|
||||
|
||||
private:
|
||||
void HandleVRegListReallocation();
|
||||
|
@ -23,22 +23,27 @@ namespace llvm {
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterClass;
|
||||
template<typename T> class SmallVectorImpl;
|
||||
class BumpPtrAllocator;
|
||||
|
||||
/// MachineSSAUpdater - This class updates SSA form for a set of virtual
|
||||
/// registers defined in multiple blocks. This is used when code duplication
|
||||
/// or another unstructured transformation wants to rewrite a set of uses of one
|
||||
/// vreg with uses of a set of vregs.
|
||||
class MachineSSAUpdater {
|
||||
public:
|
||||
class BBInfo;
|
||||
typedef SmallVectorImpl<BBInfo*> BlockListTy;
|
||||
|
||||
private:
|
||||
/// AvailableVals - This keeps track of which value to use on a per-block
|
||||
/// basis. When we insert PHI nodes, we keep track of them here.
|
||||
//typedef DenseMap<MachineBasicBlock*, unsigned > AvailableValsTy;
|
||||
void *AV;
|
||||
|
||||
/// IncomingPredInfo - We use this as scratch space when doing our recursive
|
||||
/// walk. This should only be used in GetValueInBlockInternal, normally it
|
||||
/// should be empty.
|
||||
//std::vector<std::pair<MachineBasicBlock*, unsigned > > IncomingPredInfo;
|
||||
void *IPI;
|
||||
/// BBMap - The GetValueAtEndOfBlock method maintains this mapping from
|
||||
/// basic blocks to BBInfo structures.
|
||||
/// typedef DenseMap<MachineBasicBlock*, BBInfo*> BBMapTy;
|
||||
void *BM;
|
||||
|
||||
/// VR - Current virtual register whose uses are being updated.
|
||||
unsigned VR;
|
||||
@ -106,6 +111,15 @@ class MachineSSAUpdater {
|
||||
private:
|
||||
void ReplaceRegWith(unsigned OldReg, unsigned NewReg);
|
||||
unsigned GetValueAtEndOfBlockInternal(MachineBasicBlock *BB);
|
||||
void BuildBlockList(MachineBasicBlock *BB, BlockListTy *BlockList,
|
||||
BumpPtrAllocator *Allocator);
|
||||
void FindDominators(BlockListTy *BlockList);
|
||||
void FindPHIPlacement(BlockListTy *BlockList);
|
||||
void FindAvailableVals(BlockListTy *BlockList);
|
||||
void FindExistingPHI(MachineBasicBlock *BB, BlockListTy *BlockList);
|
||||
bool CheckIfPHIMatches(MachineInstr *PHI);
|
||||
void RecordMatchingPHI(MachineInstr *PHI);
|
||||
|
||||
void operator=(const MachineSSAUpdater&); // DO NOT IMPLEMENT
|
||||
MachineSSAUpdater(const MachineSSAUpdater&); // DO NOT IMPLEMENT
|
||||
};
|
||||
|
@ -95,6 +95,11 @@ namespace llvm {
|
||||
///
|
||||
FunctionPass *createLocalRegisterAllocator();
|
||||
|
||||
/// FastRegisterAllocation Pass - This pass register allocates as fast as
|
||||
/// possible. It is best suited for debug code where live ranges are short.
|
||||
///
|
||||
FunctionPass *createFastRegisterAllocator();
|
||||
|
||||
/// LinearScanRegisterAllocation Pass - This pass implements the linear scan
|
||||
/// register allocation algorithm, a global register allocator.
|
||||
///
|
||||
@ -170,7 +175,7 @@ namespace llvm {
|
||||
|
||||
/// createMachineLICMPass - This pass performs LICM on machine instructions.
|
||||
///
|
||||
FunctionPass *createMachineLICMPass();
|
||||
FunctionPass *createMachineLICMPass(bool PreRegAlloc = true);
|
||||
|
||||
/// createMachineSinkingPass - This pass performs sinking on machine
|
||||
/// instructions.
|
||||
@ -199,7 +204,7 @@ namespace llvm {
|
||||
|
||||
/// createDwarfEHPass - This pass mulches exception handling code into a form
|
||||
/// adapted to code generation. Required if using dwarf exception handling.
|
||||
FunctionPass *createDwarfEHPass(const TargetLowering *tli, bool fast);
|
||||
FunctionPass *createDwarfEHPass(const TargetMachine *tm, bool fast);
|
||||
|
||||
/// createSjLjEHPass - This pass adapts exception handling code to use
|
||||
/// the GCC-style builtin setjmp/longjmp (sjlj) to handling EH control flow.
|
||||
|
@ -459,7 +459,6 @@ namespace llvm {
|
||||
const TargetLowering *TLI; // Target lowering info
|
||||
MachineFunction &MF; // Machine function
|
||||
MachineRegisterInfo &MRI; // Virtual/real register map
|
||||
MachineConstantPool *ConstPool; // Target constant pool
|
||||
std::vector<SUnit*> Sequence; // The schedule. Null SUnit*'s
|
||||
// represent noop instructions.
|
||||
std::vector<SUnit> SUnits; // The scheduling units.
|
||||
@ -478,8 +477,7 @@ namespace llvm {
|
||||
/// EmitSchedule - Insert MachineInstrs into the MachineBasicBlock
|
||||
/// according to the order specified in Sequence.
|
||||
///
|
||||
virtual MachineBasicBlock*
|
||||
EmitSchedule(DenseMap<MachineBasicBlock*, MachineBasicBlock*>*) = 0;
|
||||
virtual MachineBasicBlock *EmitSchedule() = 0;
|
||||
|
||||
void dumpSchedule() const;
|
||||
|
||||
|
@ -62,8 +62,15 @@ template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
|
||||
/// instead the info is kept off to the side in this structure. Each SDNode may
|
||||
/// have one or more associated dbg_value entries. This information is kept in
|
||||
/// DbgValMap.
|
||||
/// Byval parameters are handled separately because they don't use alloca's,
|
||||
/// which busts the normal mechanism. There is good reason for handling all
|
||||
/// parameters separately: they may not have code generated for them, they
|
||||
/// should always go at the beginning of the function regardless of other code
|
||||
/// motion, and debug info for them is potentially useful even if the parameter
|
||||
/// is unused. Right now only byval parameters are handled separately.
|
||||
class SDDbgInfo {
|
||||
SmallVector<SDDbgValue*, 32> DbgValues;
|
||||
SmallVector<SDDbgValue*, 32> ByvalParmDbgValues;
|
||||
DenseMap<const SDNode*, SmallVector<SDDbgValue*, 2> > DbgValMap;
|
||||
|
||||
void operator=(const SDDbgInfo&); // Do not implement.
|
||||
@ -71,19 +78,22 @@ class SDDbgInfo {
|
||||
public:
|
||||
SDDbgInfo() {}
|
||||
|
||||
void add(SDDbgValue *V, const SDNode *Node = 0) {
|
||||
void add(SDDbgValue *V, const SDNode *Node, bool isParameter) {
|
||||
if (isParameter) {
|
||||
ByvalParmDbgValues.push_back(V);
|
||||
} else DbgValues.push_back(V);
|
||||
if (Node)
|
||||
DbgValMap[Node].push_back(V);
|
||||
DbgValues.push_back(V);
|
||||
}
|
||||
|
||||
void clear() {
|
||||
DbgValMap.clear();
|
||||
DbgValues.clear();
|
||||
ByvalParmDbgValues.clear();
|
||||
}
|
||||
|
||||
bool empty() const {
|
||||
return DbgValues.empty();
|
||||
return DbgValues.empty() && ByvalParmDbgValues.empty();
|
||||
}
|
||||
|
||||
SmallVector<SDDbgValue*,2> &getSDDbgValues(const SDNode *Node) {
|
||||
@ -93,6 +103,8 @@ class SDDbgInfo {
|
||||
typedef SmallVector<SDDbgValue*,32>::iterator DbgIterator;
|
||||
DbgIterator DbgBegin() { return DbgValues.begin(); }
|
||||
DbgIterator DbgEnd() { return DbgValues.end(); }
|
||||
DbgIterator ByvalParmDbgBegin() { return ByvalParmDbgValues.begin(); }
|
||||
DbgIterator ByvalParmDbgEnd() { return ByvalParmDbgValues.end(); }
|
||||
};
|
||||
|
||||
enum CombineLevel {
|
||||
@ -117,7 +129,8 @@ void checkForCycles(const SelectionDAG *DAG);
|
||||
/// linear form.
|
||||
///
|
||||
class SelectionDAG {
|
||||
TargetLowering &TLI;
|
||||
const TargetMachine &TM;
|
||||
const TargetLowering &TLI;
|
||||
MachineFunction *MF;
|
||||
FunctionLoweringInfo &FLI;
|
||||
LLVMContext *Context;
|
||||
@ -172,7 +185,7 @@ class SelectionDAG {
|
||||
SelectionDAG(const SelectionDAG&); // Do not implement.
|
||||
|
||||
public:
|
||||
SelectionDAG(TargetLowering &tli, FunctionLoweringInfo &fli);
|
||||
SelectionDAG(const TargetMachine &TM, FunctionLoweringInfo &fli);
|
||||
~SelectionDAG();
|
||||
|
||||
/// init - Prepare this SelectionDAG to process code in the given
|
||||
@ -186,8 +199,8 @@ class SelectionDAG {
|
||||
void clear();
|
||||
|
||||
MachineFunction &getMachineFunction() const { return *MF; }
|
||||
const TargetMachine &getTarget() const;
|
||||
TargetLowering &getTargetLoweringInfo() const { return TLI; }
|
||||
const TargetMachine &getTarget() const { return TM; }
|
||||
const TargetLowering &getTargetLoweringInfo() const { return TLI; }
|
||||
FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
|
||||
LLVMContext *getContext() const {return Context; }
|
||||
|
||||
@ -350,10 +363,10 @@ class SelectionDAG {
|
||||
SDValue getTargetJumpTable(int JTI, EVT VT, unsigned char TargetFlags = 0) {
|
||||
return getJumpTable(JTI, VT, true, TargetFlags);
|
||||
}
|
||||
SDValue getConstantPool(Constant *C, EVT VT,
|
||||
SDValue getConstantPool(const Constant *C, EVT VT,
|
||||
unsigned Align = 0, int Offs = 0, bool isT=false,
|
||||
unsigned char TargetFlags = 0);
|
||||
SDValue getTargetConstantPool(Constant *C, EVT VT,
|
||||
SDValue getTargetConstantPool(const Constant *C, EVT VT,
|
||||
unsigned Align = 0, int Offset = 0,
|
||||
unsigned char TargetFlags = 0) {
|
||||
return getConstantPool(C, VT, Align, Offset, true, TargetFlags);
|
||||
@ -377,7 +390,7 @@ class SelectionDAG {
|
||||
SDValue getValueType(EVT);
|
||||
SDValue getRegister(unsigned Reg, EVT VT);
|
||||
SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label);
|
||||
SDValue getBlockAddress(BlockAddress *BA, EVT VT,
|
||||
SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
|
||||
bool isTarget = false, unsigned char TargetFlags = 0);
|
||||
|
||||
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
|
||||
@ -650,6 +663,9 @@ class SelectionDAG {
|
||||
/// getSrcValue - Construct a node to track a Value* through the backend.
|
||||
SDValue getSrcValue(const Value *v);
|
||||
|
||||
/// getMDNode - Return an MDNodeSDNode which holds an MDNode.
|
||||
SDValue getMDNode(const MDNode *MD);
|
||||
|
||||
/// getShiftAmountOperand - Return the specified value casted to
|
||||
/// the target's desired shift amount type.
|
||||
SDValue getShiftAmountOperand(SDValue Op);
|
||||
@ -764,7 +780,7 @@ class SelectionDAG {
|
||||
///
|
||||
SDDbgValue *getDbgValue(MDNode *MDPtr, SDNode *N, unsigned R, uint64_t Off,
|
||||
DebugLoc DL, unsigned O);
|
||||
SDDbgValue *getDbgValue(MDNode *MDPtr, Value *C, uint64_t Off,
|
||||
SDDbgValue *getDbgValue(MDNode *MDPtr, const Value *C, uint64_t Off,
|
||||
DebugLoc DL, unsigned O);
|
||||
SDDbgValue *getDbgValue(MDNode *MDPtr, unsigned FI, uint64_t Off,
|
||||
DebugLoc DL, unsigned O);
|
||||
@ -873,7 +889,7 @@ class SelectionDAG {
|
||||
|
||||
/// AddDbgValue - Add a dbg_value SDNode. If SD is non-null that means the
|
||||
/// value is produced by SD.
|
||||
void AddDbgValue(SDDbgValue *DB, SDNode *SD = 0);
|
||||
void AddDbgValue(SDDbgValue *DB, SDNode *SD, bool isParameter);
|
||||
|
||||
/// GetDbgValues - Get the debug values which reference the given SDNode.
|
||||
SmallVector<SDDbgValue*,2> &GetDbgValues(const SDNode* SD) {
|
||||
@ -886,6 +902,12 @@ class SelectionDAG {
|
||||
|
||||
SDDbgInfo::DbgIterator DbgBegin() { return DbgInfo->DbgBegin(); }
|
||||
SDDbgInfo::DbgIterator DbgEnd() { return DbgInfo->DbgEnd(); }
|
||||
SDDbgInfo::DbgIterator ByvalParmDbgBegin() {
|
||||
return DbgInfo->ByvalParmDbgBegin();
|
||||
}
|
||||
SDDbgInfo::DbgIterator ByvalParmDbgEnd() {
|
||||
return DbgInfo->ByvalParmDbgEnd();
|
||||
}
|
||||
|
||||
void dump() const;
|
||||
|
||||
|
@ -17,7 +17,6 @@
|
||||
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Constant.h"
|
||||
#include "llvm/CodeGen/SelectionDAG.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
|
||||
@ -41,31 +40,28 @@ namespace llvm {
|
||||
class SelectionDAGISel : public MachineFunctionPass {
|
||||
public:
|
||||
const TargetMachine &TM;
|
||||
TargetLowering &TLI;
|
||||
const TargetLowering &TLI;
|
||||
FunctionLoweringInfo *FuncInfo;
|
||||
MachineFunction *MF;
|
||||
MachineRegisterInfo *RegInfo;
|
||||
SelectionDAG *CurDAG;
|
||||
SelectionDAGBuilder *SDB;
|
||||
MachineBasicBlock *BB;
|
||||
AliasAnalysis *AA;
|
||||
GCFunctionInfo *GFI;
|
||||
CodeGenOpt::Level OptLevel;
|
||||
static char ID;
|
||||
|
||||
explicit SelectionDAGISel(TargetMachine &tm,
|
||||
explicit SelectionDAGISel(const TargetMachine &tm,
|
||||
CodeGenOpt::Level OL = CodeGenOpt::Default);
|
||||
virtual ~SelectionDAGISel();
|
||||
|
||||
TargetLowering &getTargetLowering() { return TLI; }
|
||||
const TargetLowering &getTargetLowering() { return TLI; }
|
||||
|
||||
virtual void getAnalysisUsage(AnalysisUsage &AU) const;
|
||||
|
||||
virtual bool runOnMachineFunction(MachineFunction &MF);
|
||||
|
||||
unsigned MakeReg(EVT VT);
|
||||
|
||||
virtual void EmitFunctionEntryCode(Function &Fn, MachineFunction &MF) {}
|
||||
virtual void EmitFunctionEntryCode() {}
|
||||
|
||||
/// PreprocessISelDAG - This hook allows targets to hack on the graph before
|
||||
/// instruction selection starts.
|
||||
@ -95,8 +91,11 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
|
||||
/// IsLegalToFold - Returns true if the specific operand node N of
|
||||
/// U can be folded during instruction selection that starts at Root.
|
||||
bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
|
||||
bool IgnoreChains = false) const;
|
||||
/// FIXME: This is a static member function because the PIC16 target,
|
||||
/// which uses it during lowering.
|
||||
static bool IsLegalToFold(SDValue N, SDNode *U, SDNode *Root,
|
||||
CodeGenOpt::Level OptLevel,
|
||||
bool IgnoreChains = false);
|
||||
|
||||
/// CreateTargetHazardRecognizer - Return a newly allocated hazard recognizer
|
||||
/// to use for this target when scheduling the DAG.
|
||||
@ -281,24 +280,21 @@ class SelectionDAGISel : public MachineFunctionPass {
|
||||
SDNode *MorphNode(SDNode *Node, unsigned TargetOpc, SDVTList VTs,
|
||||
const SDValue *Ops, unsigned NumOps, unsigned EmitNodeInfo);
|
||||
|
||||
void SelectAllBasicBlocks(Function &Fn, MachineFunction &MF,
|
||||
const TargetInstrInfo &TII);
|
||||
void FinishBasicBlock();
|
||||
void PrepareEHLandingPad(MachineBasicBlock *BB);
|
||||
void SelectAllBasicBlocks(const Function &Fn);
|
||||
void FinishBasicBlock(MachineBasicBlock *BB);
|
||||
|
||||
void SelectBasicBlock(BasicBlock *LLVMBB,
|
||||
BasicBlock::iterator Begin,
|
||||
BasicBlock::iterator End,
|
||||
bool &HadTailCall);
|
||||
void CodeGenAndEmitDAG();
|
||||
void LowerArguments(BasicBlock *BB);
|
||||
MachineBasicBlock *SelectBasicBlock(MachineBasicBlock *BB,
|
||||
const BasicBlock *LLVMBB,
|
||||
BasicBlock::const_iterator Begin,
|
||||
BasicBlock::const_iterator End,
|
||||
bool &HadTailCall);
|
||||
MachineBasicBlock *CodeGenAndEmitDAG(MachineBasicBlock *BB);
|
||||
void LowerArguments(const BasicBlock *BB);
|
||||
|
||||
void ShrinkDemandedOps();
|
||||
void ComputeLiveOutVRegInfo();
|
||||
|
||||
void HandlePHINodesInSuccessorBlocks(BasicBlock *LLVMBB);
|
||||
|
||||
bool HandlePHINodesInSuccessorBlocksFast(BasicBlock *LLVMBB, FastISel *F);
|
||||
|
||||
/// Create the scheduler. If a specific scheduler was specified
|
||||
/// via the SchedulerRegistry, use it, otherwise select the
|
||||
/// one preferred by the target.
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "llvm/ADT/ilist_node.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
@ -56,568 +57,7 @@ struct SDVTList {
|
||||
unsigned int NumVTs;
|
||||
};
|
||||
|
||||
/// ISD namespace - This namespace contains an enum which represents all of the
|
||||
/// SelectionDAG node types and value types.
|
||||
///
|
||||
namespace ISD {
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISD::NodeType enum - This enum defines the target-independent operators
|
||||
/// for a SelectionDAG.
|
||||
///
|
||||
/// Targets may also define target-dependent operator codes for SDNodes. For
|
||||
/// example, on x86, these are the enum values in the X86ISD namespace.
|
||||
/// Targets should aim to use target-independent operators to model their
|
||||
/// instruction sets as much as possible, and only use target-dependent
|
||||
/// operators when they have special requirements.
|
||||
///
|
||||
/// Finally, during and after selection proper, SNodes may use special
|
||||
/// operator codes that correspond directly with MachineInstr opcodes. These
|
||||
/// are used to represent selected instructions. See the isMachineOpcode()
|
||||
/// and getMachineOpcode() member functions of SDNode.
|
||||
///
|
||||
enum NodeType {
|
||||
// DELETED_NODE - This is an illegal value that is used to catch
|
||||
// errors. This opcode is not a legal opcode for any node.
|
||||
DELETED_NODE,
|
||||
|
||||
// EntryToken - This is the marker used to indicate the start of the region.
|
||||
EntryToken,
|
||||
|
||||
// TokenFactor - This node takes multiple tokens as input and produces a
|
||||
// single token result. This is used to represent the fact that the operand
|
||||
// operators are independent of each other.
|
||||
TokenFactor,
|
||||
|
||||
// AssertSext, AssertZext - These nodes record if a register contains a
|
||||
// value that has already been zero or sign extended from a narrower type.
|
||||
// These nodes take two operands. The first is the node that has already
|
||||
// been extended, and the second is a value type node indicating the width
|
||||
// of the extension
|
||||
AssertSext, AssertZext,
|
||||
|
||||
// Various leaf nodes.
|
||||
BasicBlock, VALUETYPE, CONDCODE, Register,
|
||||
Constant, ConstantFP,
|
||||
GlobalAddress, GlobalTLSAddress, FrameIndex,
|
||||
JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
|
||||
|
||||
// The address of the GOT
|
||||
GLOBAL_OFFSET_TABLE,
|
||||
|
||||
// FRAMEADDR, RETURNADDR - These nodes represent llvm.frameaddress and
|
||||
// llvm.returnaddress on the DAG. These nodes take one operand, the index
|
||||
// of the frame or return address to return. An index of zero corresponds
|
||||
// to the current function's frame or return address, an index of one to the
|
||||
// parent's frame or return address, and so on.
|
||||
FRAMEADDR, RETURNADDR,
|
||||
|
||||
// FRAME_TO_ARGS_OFFSET - This node represents offset from frame pointer to
|
||||
// first (possible) on-stack argument. This is needed for correct stack
|
||||
// adjustment during unwind.
|
||||
FRAME_TO_ARGS_OFFSET,
|
||||
|
||||
// RESULT, OUTCHAIN = EXCEPTIONADDR(INCHAIN) - This node represents the
|
||||
// address of the exception block on entry to an landing pad block.
|
||||
EXCEPTIONADDR,
|
||||
|
||||
// RESULT, OUTCHAIN = LSDAADDR(INCHAIN) - This node represents the
|
||||
// address of the Language Specific Data Area for the enclosing function.
|
||||
LSDAADDR,
|
||||
|
||||
// RESULT, OUTCHAIN = EHSELECTION(INCHAIN, EXCEPTION) - This node represents
|
||||
// the selection index of the exception thrown.
|
||||
EHSELECTION,
|
||||
|
||||
// OUTCHAIN = EH_RETURN(INCHAIN, OFFSET, HANDLER) - This node represents
|
||||
// 'eh_return' gcc dwarf builtin, which is used to return from
|
||||
// exception. The general meaning is: adjust stack by OFFSET and pass
|
||||
// execution to HANDLER. Many platform-related details also :)
|
||||
EH_RETURN,
|
||||
|
||||
// TargetConstant* - Like Constant*, but the DAG does not do any folding or
|
||||
// simplification of the constant.
|
||||
TargetConstant,
|
||||
TargetConstantFP,
|
||||
|
||||
// TargetGlobalAddress - Like GlobalAddress, but the DAG does no folding or
|
||||
// anything else with this node, and this is valid in the target-specific
|
||||
// dag, turning into a GlobalAddress operand.
|
||||
TargetGlobalAddress,
|
||||
TargetGlobalTLSAddress,
|
||||
TargetFrameIndex,
|
||||
TargetJumpTable,
|
||||
TargetConstantPool,
|
||||
TargetExternalSymbol,
|
||||
TargetBlockAddress,
|
||||
|
||||
/// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
|
||||
/// This node represents a target intrinsic function with no side effects.
|
||||
/// The first operand is the ID number of the intrinsic from the
|
||||
/// llvm::Intrinsic namespace. The operands to the intrinsic follow. The
|
||||
/// node has returns the result of the intrinsic.
|
||||
INTRINSIC_WO_CHAIN,
|
||||
|
||||
/// RESULT,OUTCHAIN = INTRINSIC_W_CHAIN(INCHAIN, INTRINSICID, arg1, ...)
|
||||
/// This node represents a target intrinsic function with side effects that
|
||||
/// returns a result. The first operand is a chain pointer. The second is
|
||||
/// the ID number of the intrinsic from the llvm::Intrinsic namespace. The
|
||||
/// operands to the intrinsic follow. The node has two results, the result
|
||||
/// of the intrinsic and an output chain.
|
||||
INTRINSIC_W_CHAIN,
|
||||
|
||||
/// OUTCHAIN = INTRINSIC_VOID(INCHAIN, INTRINSICID, arg1, arg2, ...)
|
||||
/// This node represents a target intrinsic function with side effects that
|
||||
/// does not return a result. The first operand is a chain pointer. The
|
||||
/// second is the ID number of the intrinsic from the llvm::Intrinsic
|
||||
/// namespace. The operands to the intrinsic follow.
|
||||
INTRINSIC_VOID,
|
||||
|
||||
// CopyToReg - This node has three operands: a chain, a register number to
|
||||
// set to this value, and a value.
|
||||
CopyToReg,
|
||||
|
||||
// CopyFromReg - This node indicates that the input value is a virtual or
|
||||
// physical register that is defined outside of the scope of this
|
||||
// SelectionDAG. The register is available from the RegisterSDNode object.
|
||||
CopyFromReg,
|
||||
|
||||
// UNDEF - An undefined node
|
||||
UNDEF,
|
||||
|
||||
// EXTRACT_ELEMENT - This is used to get the lower or upper (determined by
|
||||
// a Constant, which is required to be operand #1) half of the integer or
|
||||
// float value specified as operand #0. This is only for use before
|
||||
// legalization, for values that will be broken into multiple registers.
|
||||
EXTRACT_ELEMENT,
|
||||
|
||||
// BUILD_PAIR - This is the opposite of EXTRACT_ELEMENT in some ways. Given
|
||||
// two values of the same integer value type, this produces a value twice as
|
||||
// big. Like EXTRACT_ELEMENT, this can only be used before legalization.
|
||||
BUILD_PAIR,
|
||||
|
||||
// MERGE_VALUES - This node takes multiple discrete operands and returns
|
||||
// them all as its individual results. This nodes has exactly the same
|
||||
// number of inputs and outputs. This node is useful for some pieces of the
|
||||
// code generator that want to think about a single node with multiple
|
||||
// results, not multiple nodes.
|
||||
MERGE_VALUES,
|
||||
|
||||
// Simple integer binary arithmetic operators.
|
||||
ADD, SUB, MUL, SDIV, UDIV, SREM, UREM,
|
||||
|
||||
// SMUL_LOHI/UMUL_LOHI - Multiply two integers of type iN, producing
|
||||
// a signed/unsigned value of type i[2*N], and return the full value as
|
||||
// two results, each of type iN.
|
||||
SMUL_LOHI, UMUL_LOHI,
|
||||
|
||||
// SDIVREM/UDIVREM - Divide two integers and produce both a quotient and
|
||||
// remainder result.
|
||||
SDIVREM, UDIVREM,
|
||||
|
||||
// CARRY_FALSE - This node is used when folding other nodes,
|
||||
// like ADDC/SUBC, which indicate the carry result is always false.
|
||||
CARRY_FALSE,
|
||||
|
||||
// Carry-setting nodes for multiple precision addition and subtraction.
|
||||
// These nodes take two operands of the same value type, and produce two
|
||||
// results. The first result is the normal add or sub result, the second
|
||||
// result is the carry flag result.
|
||||
ADDC, SUBC,
|
||||
|
||||
// Carry-using nodes for multiple precision addition and subtraction. These
|
||||
// nodes take three operands: The first two are the normal lhs and rhs to
|
||||
// the add or sub, and the third is the input carry flag. These nodes
|
||||
// produce two results; the normal result of the add or sub, and the output
|
||||
// carry flag. These nodes both read and write a carry flag to allow them
|
||||
// to them to be chained together for add and sub of arbitrarily large
|
||||
// values.
|
||||
ADDE, SUBE,
|
||||
|
||||
// RESULT, BOOL = [SU]ADDO(LHS, RHS) - Overflow-aware nodes for addition.
|
||||
// These nodes take two operands: the normal LHS and RHS to the add. They
|
||||
// produce two results: the normal result of the add, and a boolean that
|
||||
// indicates if an overflow occured (*not* a flag, because it may be stored
|
||||
// to memory, etc.). If the type of the boolean is not i1 then the high
|
||||
// bits conform to getBooleanContents.
|
||||
// These nodes are generated from the llvm.[su]add.with.overflow intrinsics.
|
||||
SADDO, UADDO,
|
||||
|
||||
// Same for subtraction
|
||||
SSUBO, USUBO,
|
||||
|
||||
// Same for multiplication
|
||||
SMULO, UMULO,
|
||||
|
||||
// Simple binary floating point operators.
|
||||
FADD, FSUB, FMUL, FDIV, FREM,
|
||||
|
||||
// FCOPYSIGN(X, Y) - Return the value of X with the sign of Y. NOTE: This
|
||||
// DAG node does not require that X and Y have the same type, just that they
|
||||
// are both floating point. X and the result must have the same type.
|
||||
// FCOPYSIGN(f32, f64) is allowed.
|
||||
FCOPYSIGN,
|
||||
|
||||
// INT = FGETSIGN(FP) - Return the sign bit of the specified floating point
|
||||
// value as an integer 0/1 value.
|
||||
FGETSIGN,
|
||||
|
||||
/// BUILD_VECTOR(ELT0, ELT1, ELT2, ELT3,...) - Return a vector with the
|
||||
/// specified, possibly variable, elements. The number of elements is
|
||||
/// required to be a power of two. The types of the operands must all be
|
||||
/// the same and must match the vector element type, except that integer
|
||||
/// types are allowed to be larger than the element type, in which case
|
||||
/// the operands are implicitly truncated.
|
||||
BUILD_VECTOR,
|
||||
|
||||
/// INSERT_VECTOR_ELT(VECTOR, VAL, IDX) - Returns VECTOR with the element
|
||||
/// at IDX replaced with VAL. If the type of VAL is larger than the vector
|
||||
/// element type then VAL is truncated before replacement.
|
||||
INSERT_VECTOR_ELT,
|
||||
|
||||
/// EXTRACT_VECTOR_ELT(VECTOR, IDX) - Returns a single element from VECTOR
|
||||
/// identified by the (potentially variable) element number IDX. If the
|
||||
/// return type is an integer type larger than the element type of the
|
||||
/// vector, the result is extended to the width of the return type.
|
||||
EXTRACT_VECTOR_ELT,
|
||||
|
||||
/// CONCAT_VECTORS(VECTOR0, VECTOR1, ...) - Given a number of values of
|
||||
/// vector type with the same length and element type, this produces a
|
||||
/// concatenated vector result value, with length equal to the sum of the
|
||||
/// lengths of the input vectors.
|
||||
CONCAT_VECTORS,
|
||||
|
||||
/// EXTRACT_SUBVECTOR(VECTOR, IDX) - Returns a subvector from VECTOR (an
|
||||
/// vector value) starting with the (potentially variable) element number
|
||||
/// IDX, which must be a multiple of the result vector length.
|
||||
EXTRACT_SUBVECTOR,
|
||||
|
||||
/// VECTOR_SHUFFLE(VEC1, VEC2) - Returns a vector, of the same type as
|
||||
/// VEC1/VEC2. A VECTOR_SHUFFLE node also contains an array of constant int
|
||||
/// values that indicate which value (or undef) each result element will
|
||||
/// get. These constant ints are accessible through the
|
||||
/// ShuffleVectorSDNode class. This is quite similar to the Altivec
|
||||
/// 'vperm' instruction, except that the indices must be constants and are
|
||||
/// in terms of the element size of VEC1/VEC2, not in terms of bytes.
|
||||
VECTOR_SHUFFLE,
|
||||
|
||||
/// SCALAR_TO_VECTOR(VAL) - This represents the operation of loading a
|
||||
/// scalar value into element 0 of the resultant vector type. The top
|
||||
/// elements 1 to N-1 of the N-element vector are undefined. The type
|
||||
/// of the operand must match the vector element type, except when they
|
||||
/// are integer types. In this case the operand is allowed to be wider
|
||||
/// than the vector element type, and is implicitly truncated to it.
|
||||
SCALAR_TO_VECTOR,
|
||||
|
||||
// MULHU/MULHS - Multiply high - Multiply two integers of type iN, producing
|
||||
// an unsigned/signed value of type i[2*N], then return the top part.
|
||||
MULHU, MULHS,
|
||||
|
||||
// Bitwise operators - logical and, logical or, logical xor, shift left,
|
||||
// shift right algebraic (shift in sign bits), shift right logical (shift in
|
||||
// zeroes), rotate left, rotate right, and byteswap.
|
||||
AND, OR, XOR, SHL, SRA, SRL, ROTL, ROTR, BSWAP,
|
||||
|
||||
// Counting operators
|
||||
CTTZ, CTLZ, CTPOP,
|
||||
|
||||
// Select(COND, TRUEVAL, FALSEVAL). If the type of the boolean COND is not
|
||||
// i1 then the high bits must conform to getBooleanContents.
|
||||
SELECT,
|
||||
|
||||
// Select with condition operator - This selects between a true value and
|
||||
// a false value (ops #2 and #3) based on the boolean result of comparing
|
||||
// the lhs and rhs (ops #0 and #1) of a conditional expression with the
|
||||
// condition code in op #4, a CondCodeSDNode.
|
||||
SELECT_CC,
|
||||
|
||||
// SetCC operator - This evaluates to a true value iff the condition is
|
||||
// true. If the result value type is not i1 then the high bits conform
|
||||
// to getBooleanContents. The operands to this are the left and right
|
||||
// operands to compare (ops #0, and #1) and the condition code to compare
|
||||
// them with (op #2) as a CondCodeSDNode.
|
||||
SETCC,
|
||||
|
||||
// RESULT = VSETCC(LHS, RHS, COND) operator - This evaluates to a vector of
|
||||
// integer elements with all bits of the result elements set to true if the
|
||||
// comparison is true or all cleared if the comparison is false. The
|
||||
// operands to this are the left and right operands to compare (LHS/RHS) and
|
||||
// the condition code to compare them with (COND) as a CondCodeSDNode.
|
||||
VSETCC,
|
||||
|
||||
// SHL_PARTS/SRA_PARTS/SRL_PARTS - These operators are used for expanded
|
||||
// integer shift operations, just like ADD/SUB_PARTS. The operation
|
||||
// ordering is:
|
||||
// [Lo,Hi] = op [LoLHS,HiLHS], Amt
|
||||
SHL_PARTS, SRA_PARTS, SRL_PARTS,
|
||||
|
||||
// Conversion operators. These are all single input single output
|
||||
// operations. For all of these, the result type must be strictly
|
||||
// wider or narrower (depending on the operation) than the source
|
||||
// type.
|
||||
|
||||
// SIGN_EXTEND - Used for integer types, replicating the sign bit
|
||||
// into new bits.
|
||||
SIGN_EXTEND,
|
||||
|
||||
// ZERO_EXTEND - Used for integer types, zeroing the new bits.
|
||||
ZERO_EXTEND,
|
||||
|
||||
// ANY_EXTEND - Used for integer types. The high bits are undefined.
|
||||
ANY_EXTEND,
|
||||
|
||||
// TRUNCATE - Completely drop the high bits.
|
||||
TRUNCATE,
|
||||
|
||||
// [SU]INT_TO_FP - These operators convert integers (whose interpreted sign
|
||||
// depends on the first letter) to floating point.
|
||||
SINT_TO_FP,
|
||||
UINT_TO_FP,
|
||||
|
||||
// SIGN_EXTEND_INREG - This operator atomically performs a SHL/SRA pair to
|
||||
// sign extend a small value in a large integer register (e.g. sign
|
||||
// extending the low 8 bits of a 32-bit register to fill the top 24 bits
|
||||
// with the 7th bit). The size of the smaller type is indicated by the 1th
|
||||
// operand, a ValueType node.
|
||||
SIGN_EXTEND_INREG,
|
||||
|
||||
/// FP_TO_[US]INT - Convert a floating point value to a signed or unsigned
|
||||
/// integer.
|
||||
FP_TO_SINT,
|
||||
FP_TO_UINT,
|
||||
|
||||
/// X = FP_ROUND(Y, TRUNC) - Rounding 'Y' from a larger floating point type
|
||||
/// down to the precision of the destination VT. TRUNC is a flag, which is
|
||||
/// always an integer that is zero or one. If TRUNC is 0, this is a
|
||||
/// normal rounding, if it is 1, this FP_ROUND is known to not change the
|
||||
/// value of Y.
|
||||
///
|
||||
/// The TRUNC = 1 case is used in cases where we know that the value will
|
||||
/// not be modified by the node, because Y is not using any of the extra
|
||||
/// precision of source type. This allows certain transformations like
|
||||
/// FP_EXTEND(FP_ROUND(X,1)) -> X which are not safe for
|
||||
/// FP_EXTEND(FP_ROUND(X,0)) because the extra bits aren't removed.
|
||||
FP_ROUND,
|
||||
|
||||
// FLT_ROUNDS_ - Returns current rounding mode:
|
||||
// -1 Undefined
|
||||
// 0 Round to 0
|
||||
// 1 Round to nearest
|
||||
// 2 Round to +inf
|
||||
// 3 Round to -inf
|
||||
FLT_ROUNDS_,
|
||||
|
||||
/// X = FP_ROUND_INREG(Y, VT) - This operator takes an FP register, and
|
||||
/// rounds it to a floating point value. It then promotes it and returns it
|
||||
/// in a register of the same size. This operation effectively just
|
||||
/// discards excess precision. The type to round down to is specified by
|
||||
/// the VT operand, a VTSDNode.
|
||||
FP_ROUND_INREG,
|
||||
|
||||
/// X = FP_EXTEND(Y) - Extend a smaller FP type into a larger FP type.
|
||||
FP_EXTEND,
|
||||
|
||||
// BIT_CONVERT - This operator converts between integer, vector and FP
|
||||
// values, as if the value was stored to memory with one type and loaded
|
||||
// from the same address with the other type (or equivalently for vector
|
||||
// format conversions, etc). The source and result are required to have
|
||||
// the same bit size (e.g. f32 <-> i32). This can also be used for
|
||||
// int-to-int or fp-to-fp conversions, but that is a noop, deleted by
|
||||
// getNode().
|
||||
BIT_CONVERT,
|
||||
|
||||
// CONVERT_RNDSAT - This operator is used to support various conversions
|
||||
// between various types (float, signed, unsigned and vectors of those
|
||||
// types) with rounding and saturation. NOTE: Avoid using this operator as
|
||||
// most target don't support it and the operator might be removed in the
|
||||
// future. It takes the following arguments:
|
||||
// 0) value
|
||||
// 1) dest type (type to convert to)
|
||||
// 2) src type (type to convert from)
|
||||
// 3) rounding imm
|
||||
// 4) saturation imm
|
||||
// 5) ISD::CvtCode indicating the type of conversion to do
|
||||
CONVERT_RNDSAT,
|
||||
|
||||
// FP16_TO_FP32, FP32_TO_FP16 - These operators are used to perform
|
||||
// promotions and truncation for half-precision (16 bit) floating
|
||||
// numbers. We need special nodes since FP16 is a storage-only type with
|
||||
// special semantics of operations.
|
||||
FP16_TO_FP32, FP32_TO_FP16,
|
||||
|
||||
// FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
|
||||
// FLOG, FLOG2, FLOG10, FEXP, FEXP2,
|
||||
// FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR - Perform various unary floating
|
||||
// point operations. These are inspired by libm.
|
||||
FNEG, FABS, FSQRT, FSIN, FCOS, FPOWI, FPOW,
|
||||
FLOG, FLOG2, FLOG10, FEXP, FEXP2,
|
||||
FCEIL, FTRUNC, FRINT, FNEARBYINT, FFLOOR,
|
||||
|
||||
// LOAD and STORE have token chains as their first operand, then the same
|
||||
// operands as an LLVM load/store instruction, then an offset node that
|
||||
// is added / subtracted from the base pointer to form the address (for
|
||||
// indexed memory ops).
|
||||
LOAD, STORE,
|
||||
|
||||
// DYNAMIC_STACKALLOC - Allocate some number of bytes on the stack aligned
|
||||
// to a specified boundary. This node always has two return values: a new
|
||||
// stack pointer value and a chain. The first operand is the token chain,
|
||||
// the second is the number of bytes to allocate, and the third is the
|
||||
// alignment boundary. The size is guaranteed to be a multiple of the stack
|
||||
// alignment, and the alignment is guaranteed to be bigger than the stack
|
||||
// alignment (if required) or 0 to get standard stack alignment.
|
||||
DYNAMIC_STACKALLOC,
|
||||
|
||||
// Control flow instructions. These all have token chains.
|
||||
|
||||
// BR - Unconditional branch. The first operand is the chain
|
||||
// operand, the second is the MBB to branch to.
|
||||
BR,
|
||||
|
||||
// BRIND - Indirect branch. The first operand is the chain, the second
|
||||
// is the value to branch to, which must be of the same type as the target's
|
||||
// pointer type.
|
||||
BRIND,
|
||||
|
||||
// BR_JT - Jumptable branch. The first operand is the chain, the second
|
||||
// is the jumptable index, the last one is the jumptable entry index.
|
||||
BR_JT,
|
||||
|
||||
// BRCOND - Conditional branch. The first operand is the chain, the
|
||||
// second is the condition, the third is the block to branch to if the
|
||||
// condition is true. If the type of the condition is not i1, then the
|
||||
// high bits must conform to getBooleanContents.
|
||||
BRCOND,
|
||||
|
||||
// BR_CC - Conditional branch. The behavior is like that of SELECT_CC, in
|
||||
// that the condition is represented as condition code, and two nodes to
|
||||
// compare, rather than as a combined SetCC node. The operands in order are
|
||||
// chain, cc, lhs, rhs, block to branch to if condition is true.
|
||||
BR_CC,
|
||||
|
||||
// INLINEASM - Represents an inline asm block. This node always has two
|
||||
// return values: a chain and a flag result. The inputs are as follows:
|
||||
// Operand #0 : Input chain.
|
||||
// Operand #1 : a ExternalSymbolSDNode with a pointer to the asm string.
|
||||
// Operand #2n+2: A RegisterNode.
|
||||
// Operand #2n+3: A TargetConstant, indicating if the reg is a use/def
|
||||
// Operand #last: Optional, an incoming flag.
|
||||
INLINEASM,
|
||||
|
||||
// EH_LABEL - Represents a label in mid basic block used to track
|
||||
// locations needed for debug and exception handling tables. These nodes
|
||||
// take a chain as input and return a chain.
|
||||
EH_LABEL,
|
||||
|
||||
// STACKSAVE - STACKSAVE has one operand, an input chain. It produces a
|
||||
// value, the same type as the pointer type for the system, and an output
|
||||
// chain.
|
||||
STACKSAVE,
|
||||
|
||||
// STACKRESTORE has two operands, an input chain and a pointer to restore to
|
||||
// it returns an output chain.
|
||||
STACKRESTORE,
|
||||
|
||||
// CALLSEQ_START/CALLSEQ_END - These operators mark the beginning and end of
|
||||
// a call sequence, and carry arbitrary information that target might want
|
||||
// to know. The first operand is a chain, the rest are specified by the
|
||||
// target and not touched by the DAG optimizers.
|
||||
// CALLSEQ_START..CALLSEQ_END pairs may not be nested.
|
||||
CALLSEQ_START, // Beginning of a call sequence
|
||||
CALLSEQ_END, // End of a call sequence
|
||||
|
||||
// VAARG - VAARG has three operands: an input chain, a pointer, and a
|
||||
// SRCVALUE. It returns a pair of values: the vaarg value and a new chain.
|
||||
VAARG,
|
||||
|
||||
// VACOPY - VACOPY has five operands: an input chain, a destination pointer,
|
||||
// a source pointer, a SRCVALUE for the destination, and a SRCVALUE for the
|
||||
// source.
|
||||
VACOPY,
|
||||
|
||||
// VAEND, VASTART - VAEND and VASTART have three operands: an input chain, a
|
||||
// pointer, and a SRCVALUE.
|
||||
VAEND, VASTART,
|
||||
|
||||
// SRCVALUE - This is a node type that holds a Value* that is used to
|
||||
// make reference to a value in the LLVM IR.
|
||||
SRCVALUE,
|
||||
|
||||
// PCMARKER - This corresponds to the pcmarker intrinsic.
|
||||
PCMARKER,
|
||||
|
||||
// READCYCLECOUNTER - This corresponds to the readcyclecounter intrinsic.
|
||||
// The only operand is a chain and a value and a chain are produced. The
|
||||
// value is the contents of the architecture specific cycle counter like
|
||||
// register (or other high accuracy low latency clock source)
|
||||
READCYCLECOUNTER,
|
||||
|
||||
// HANDLENODE node - Used as a handle for various purposes.
|
||||
HANDLENODE,
|
||||
|
||||
// TRAMPOLINE - This corresponds to the init_trampoline intrinsic.
|
||||
// It takes as input a token chain, the pointer to the trampoline,
|
||||
// the pointer to the nested function, the pointer to pass for the
|
||||
// 'nest' parameter, a SRCVALUE for the trampoline and another for
|
||||
// the nested function (allowing targets to access the original
|
||||
// Function*). It produces the result of the intrinsic and a token
|
||||
// chain as output.
|
||||
TRAMPOLINE,
|
||||
|
||||
// TRAP - Trapping instruction
|
||||
TRAP,
|
||||
|
||||
// PREFETCH - This corresponds to a prefetch intrinsic. It takes chains are
|
||||
// their first operand. The other operands are the address to prefetch,
|
||||
// read / write specifier, and locality specifier.
|
||||
PREFETCH,
|
||||
|
||||
// OUTCHAIN = MEMBARRIER(INCHAIN, load-load, load-store, store-load,
|
||||
// store-store, device)
|
||||
// This corresponds to the memory.barrier intrinsic.
|
||||
// it takes an input chain, 4 operands to specify the type of barrier, an
|
||||
// operand specifying if the barrier applies to device and uncached memory
|
||||
// and produces an output chain.
|
||||
MEMBARRIER,
|
||||
|
||||
// Val, OUTCHAIN = ATOMIC_CMP_SWAP(INCHAIN, ptr, cmp, swap)
|
||||
// this corresponds to the atomic.lcs intrinsic.
|
||||
// cmp is compared to *ptr, and if equal, swap is stored in *ptr.
|
||||
// the return is always the original value in *ptr
|
||||
ATOMIC_CMP_SWAP,
|
||||
|
||||
// Val, OUTCHAIN = ATOMIC_SWAP(INCHAIN, ptr, amt)
|
||||
// this corresponds to the atomic.swap intrinsic.
|
||||
// amt is stored to *ptr atomically.
|
||||
// the return is always the original value in *ptr
|
||||
ATOMIC_SWAP,
|
||||
|
||||
// Val, OUTCHAIN = ATOMIC_LOAD_[OpName](INCHAIN, ptr, amt)
|
||||
// this corresponds to the atomic.load.[OpName] intrinsic.
|
||||
// op(*ptr, amt) is stored to *ptr atomically.
|
||||
// the return is always the original value in *ptr
|
||||
ATOMIC_LOAD_ADD,
|
||||
ATOMIC_LOAD_SUB,
|
||||
ATOMIC_LOAD_AND,
|
||||
ATOMIC_LOAD_OR,
|
||||
ATOMIC_LOAD_XOR,
|
||||
ATOMIC_LOAD_NAND,
|
||||
ATOMIC_LOAD_MIN,
|
||||
ATOMIC_LOAD_MAX,
|
||||
ATOMIC_LOAD_UMIN,
|
||||
ATOMIC_LOAD_UMAX,
|
||||
|
||||
/// BUILTIN_OP_END - This must be the last enum value in this list.
|
||||
/// The target-specific pre-isel opcode values start here.
|
||||
BUILTIN_OP_END
|
||||
};
|
||||
|
||||
/// FIRST_TARGET_MEMORY_OPCODE - Target-specific pre-isel operations
|
||||
/// which do not reference a specific memory location should be less than
|
||||
/// this value. Those that do must not be less than this value, and can
|
||||
/// be used with SelectionDAG::getMemIntrinsicNode.
|
||||
static const int FIRST_TARGET_MEMORY_OPCODE = BUILTIN_OP_END+100;
|
||||
|
||||
/// Node predicates
|
||||
|
||||
/// isBuildVectorAllOnes - Return true if the specified node is a
|
||||
@ -632,174 +72,7 @@ namespace ISD {
|
||||
/// ISD::SCALAR_TO_VECTOR node or a BUILD_VECTOR node where only the low
|
||||
/// element is not an undef.
|
||||
bool isScalarToVector(const SDNode *N);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// MemIndexedMode enum - This enum defines the load / store indexed
|
||||
/// addressing modes.
|
||||
///
|
||||
/// UNINDEXED "Normal" load / store. The effective address is already
|
||||
/// computed and is available in the base pointer. The offset
|
||||
/// operand is always undefined. In addition to producing a
|
||||
/// chain, an unindexed load produces one value (result of the
|
||||
/// load); an unindexed store does not produce a value.
|
||||
///
|
||||
/// PRE_INC Similar to the unindexed mode where the effective address is
|
||||
/// PRE_DEC the value of the base pointer add / subtract the offset.
|
||||
/// It considers the computation as being folded into the load /
|
||||
/// store operation (i.e. the load / store does the address
|
||||
/// computation as well as performing the memory transaction).
|
||||
/// The base operand is always undefined. In addition to
|
||||
/// producing a chain, pre-indexed load produces two values
|
||||
/// (result of the load and the result of the address
|
||||
/// computation); a pre-indexed store produces one value (result
|
||||
/// of the address computation).
|
||||
///
|
||||
/// POST_INC The effective address is the value of the base pointer. The
|
||||
/// POST_DEC value of the offset operand is then added to / subtracted
|
||||
/// from the base after memory transaction. In addition to
|
||||
/// producing a chain, post-indexed load produces two values
|
||||
/// (the result of the load and the result of the base +/- offset
|
||||
/// computation); a post-indexed store produces one value (the
|
||||
/// the result of the base +/- offset computation).
|
||||
///
|
||||
enum MemIndexedMode {
|
||||
UNINDEXED = 0,
|
||||
PRE_INC,
|
||||
PRE_DEC,
|
||||
POST_INC,
|
||||
POST_DEC,
|
||||
LAST_INDEXED_MODE
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// LoadExtType enum - This enum defines the three variants of LOADEXT
|
||||
/// (load with extension).
|
||||
///
|
||||
/// SEXTLOAD loads the integer operand and sign extends it to a larger
|
||||
/// integer result type.
|
||||
/// ZEXTLOAD loads the integer operand and zero extends it to a larger
|
||||
/// integer result type.
|
||||
/// EXTLOAD is used for three things: floating point extending loads,
|
||||
/// integer extending loads [the top bits are undefined], and vector
|
||||
/// extending loads [load into low elt].
|
||||
///
|
||||
enum LoadExtType {
|
||||
NON_EXTLOAD = 0,
|
||||
EXTLOAD,
|
||||
SEXTLOAD,
|
||||
ZEXTLOAD,
|
||||
LAST_LOADEXT_TYPE
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// ISD::CondCode enum - These are ordered carefully to make the bitfields
|
||||
/// below work out, when considering SETFALSE (something that never exists
|
||||
/// dynamically) as 0. "U" -> Unsigned (for integer operands) or Unordered
|
||||
/// (for floating point), "L" -> Less than, "G" -> Greater than, "E" -> Equal
|
||||
/// to. If the "N" column is 1, the result of the comparison is undefined if
|
||||
/// the input is a NAN.
|
||||
///
|
||||
/// All of these (except for the 'always folded ops') should be handled for
|
||||
/// floating point. For integer, only the SETEQ,SETNE,SETLT,SETLE,SETGT,
|
||||
/// SETGE,SETULT,SETULE,SETUGT, and SETUGE opcodes are used.
|
||||
///
|
||||
/// Note that these are laid out in a specific order to allow bit-twiddling
|
||||
/// to transform conditions.
|
||||
enum CondCode {
|
||||
// Opcode N U L G E Intuitive operation
|
||||
SETFALSE, // 0 0 0 0 Always false (always folded)
|
||||
SETOEQ, // 0 0 0 1 True if ordered and equal
|
||||
SETOGT, // 0 0 1 0 True if ordered and greater than
|
||||
SETOGE, // 0 0 1 1 True if ordered and greater than or equal
|
||||
SETOLT, // 0 1 0 0 True if ordered and less than
|
||||
SETOLE, // 0 1 0 1 True if ordered and less than or equal
|
||||
SETONE, // 0 1 1 0 True if ordered and operands are unequal
|
||||
SETO, // 0 1 1 1 True if ordered (no nans)
|
||||
SETUO, // 1 0 0 0 True if unordered: isnan(X) | isnan(Y)
|
||||
SETUEQ, // 1 0 0 1 True if unordered or equal
|
||||
SETUGT, // 1 0 1 0 True if unordered or greater than
|
||||
SETUGE, // 1 0 1 1 True if unordered, greater than, or equal
|
||||
SETULT, // 1 1 0 0 True if unordered or less than
|
||||
SETULE, // 1 1 0 1 True if unordered, less than, or equal
|
||||
SETUNE, // 1 1 1 0 True if unordered or not equal
|
||||
SETTRUE, // 1 1 1 1 Always true (always folded)
|
||||
// Don't care operations: undefined if the input is a nan.
|
||||
SETFALSE2, // 1 X 0 0 0 Always false (always folded)
|
||||
SETEQ, // 1 X 0 0 1 True if equal
|
||||
SETGT, // 1 X 0 1 0 True if greater than
|
||||
SETGE, // 1 X 0 1 1 True if greater than or equal
|
||||
SETLT, // 1 X 1 0 0 True if less than
|
||||
SETLE, // 1 X 1 0 1 True if less than or equal
|
||||
SETNE, // 1 X 1 1 0 True if not equal
|
||||
SETTRUE2, // 1 X 1 1 1 Always true (always folded)
|
||||
|
||||
SETCC_INVALID // Marker value.
|
||||
};
|
||||
|
||||
/// isSignedIntSetCC - Return true if this is a setcc instruction that
|
||||
/// performs a signed comparison when used with integer operands.
|
||||
inline bool isSignedIntSetCC(CondCode Code) {
|
||||
return Code == SETGT || Code == SETGE || Code == SETLT || Code == SETLE;
|
||||
}
|
||||
|
||||
/// isUnsignedIntSetCC - Return true if this is a setcc instruction that
|
||||
/// performs an unsigned comparison when used with integer operands.
|
||||
inline bool isUnsignedIntSetCC(CondCode Code) {
|
||||
return Code == SETUGT || Code == SETUGE || Code == SETULT || Code == SETULE;
|
||||
}
|
||||
|
||||
/// isTrueWhenEqual - Return true if the specified condition returns true if
|
||||
/// the two operands to the condition are equal. Note that if one of the two
|
||||
/// operands is a NaN, this value is meaningless.
|
||||
inline bool isTrueWhenEqual(CondCode Cond) {
|
||||
return ((int)Cond & 1) != 0;
|
||||
}
|
||||
|
||||
/// getUnorderedFlavor - This function returns 0 if the condition is always
|
||||
/// false if an operand is a NaN, 1 if the condition is always true if the
|
||||
/// operand is a NaN, and 2 if the condition is undefined if the operand is a
|
||||
/// NaN.
|
||||
inline unsigned getUnorderedFlavor(CondCode Cond) {
|
||||
return ((int)Cond >> 3) & 3;
|
||||
}
|
||||
|
||||
/// getSetCCInverse - Return the operation corresponding to !(X op Y), where
|
||||
/// 'op' is a valid SetCC operation.
|
||||
CondCode getSetCCInverse(CondCode Operation, bool isInteger);
|
||||
|
||||
/// getSetCCSwappedOperands - Return the operation corresponding to (Y op X)
|
||||
/// when given the operation for (X op Y).
|
||||
CondCode getSetCCSwappedOperands(CondCode Operation);
|
||||
|
||||
/// getSetCCOrOperation - Return the result of a logical OR between different
|
||||
/// comparisons of identical values: ((X op1 Y) | (X op2 Y)). This
|
||||
/// function returns SETCC_INVALID if it is not possible to represent the
|
||||
/// resultant comparison.
|
||||
CondCode getSetCCOrOperation(CondCode Op1, CondCode Op2, bool isInteger);
|
||||
|
||||
/// getSetCCAndOperation - Return the result of a logical AND between
|
||||
/// different comparisons of identical values: ((X op1 Y) & (X op2 Y)). This
|
||||
/// function returns SETCC_INVALID if it is not possible to represent the
|
||||
/// resultant comparison.
|
||||
CondCode getSetCCAndOperation(CondCode Op1, CondCode Op2, bool isInteger);
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// CvtCode enum - This enum defines the various converts CONVERT_RNDSAT
|
||||
/// supports.
|
||||
enum CvtCode {
|
||||
CVT_FF, // Float from Float
|
||||
CVT_FS, // Float from Signed
|
||||
CVT_FU, // Float from Unsigned
|
||||
CVT_SF, // Signed from Float
|
||||
CVT_UF, // Unsigned from Float
|
||||
CVT_SS, // Signed from Signed
|
||||
CVT_SU, // Signed from Unsigned
|
||||
CVT_US, // Unsigned from Signed
|
||||
CVT_UU, // Unsigned from Unsigned
|
||||
CVT_INVALID // Marker - Invalid opcode
|
||||
};
|
||||
} // end llvm::ISD namespace
|
||||
|
||||
} // end llvm:ISD namespace
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// SDValue - Unlike LLVM values, Selection DAG nodes may return multiple
|
||||
@ -1564,7 +837,7 @@ class HandleSDNode : public SDNode {
|
||||
public:
|
||||
// FIXME: Remove the "noinline" attribute once <rdar://problem/5852746> is
|
||||
// fixed.
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__==4 && __GNUC_MINOR__==2 && defined(__APPLE__) && !defined(__llvm__)
|
||||
explicit __attribute__((__noinline__)) HandleSDNode(SDValue X)
|
||||
#else
|
||||
explicit HandleSDNode(SDValue X)
|
||||
@ -1867,7 +1140,7 @@ class ConstantFPSDNode : public SDNode {
|
||||
};
|
||||
|
||||
class GlobalAddressSDNode : public SDNode {
|
||||
GlobalValue *TheGlobal;
|
||||
const GlobalValue *TheGlobal;
|
||||
int64_t Offset;
|
||||
unsigned char TargetFlags;
|
||||
friend class SelectionDAG;
|
||||
@ -1875,7 +1148,7 @@ class GlobalAddressSDNode : public SDNode {
|
||||
int64_t o, unsigned char TargetFlags);
|
||||
public:
|
||||
|
||||
GlobalValue *getGlobal() const { return TheGlobal; }
|
||||
const GlobalValue *getGlobal() const { return TheGlobal; }
|
||||
int64_t getOffset() const { return Offset; }
|
||||
unsigned char getTargetFlags() const { return TargetFlags; }
|
||||
// Return the address space this GlobalAddress belongs to.
|
||||
@ -1930,15 +1203,15 @@ class JumpTableSDNode : public SDNode {
|
||||
|
||||
class ConstantPoolSDNode : public SDNode {
|
||||
union {
|
||||
Constant *ConstVal;
|
||||
const Constant *ConstVal;
|
||||
MachineConstantPoolValue *MachineCPVal;
|
||||
} Val;
|
||||
int Offset; // It's a MachineConstantPoolValue if top bit is set.
|
||||
unsigned Alignment; // Minimum alignment requirement of CP (not log2 value).
|
||||
unsigned char TargetFlags;
|
||||
friend class SelectionDAG;
|
||||
ConstantPoolSDNode(bool isTarget, Constant *c, EVT VT, int o, unsigned Align,
|
||||
unsigned char TF)
|
||||
ConstantPoolSDNode(bool isTarget, const Constant *c, EVT VT, int o,
|
||||
unsigned Align, unsigned char TF)
|
||||
: SDNode(isTarget ? ISD::TargetConstantPool : ISD::ConstantPool,
|
||||
DebugLoc(),
|
||||
getSDVTList(VT)), Offset(o), Alignment(Align), TargetFlags(TF) {
|
||||
@ -1961,7 +1234,7 @@ class ConstantPoolSDNode : public SDNode {
|
||||
return (int)Offset < 0;
|
||||
}
|
||||
|
||||
Constant *getConstVal() const {
|
||||
const Constant *getConstVal() const {
|
||||
assert(!isMachineConstantPoolEntry() && "Wrong constantpool type");
|
||||
return Val.ConstVal;
|
||||
}
|
||||
@ -2053,6 +1326,21 @@ class SrcValueSDNode : public SDNode {
|
||||
return N->getOpcode() == ISD::SRCVALUE;
|
||||
}
|
||||
};
|
||||
|
||||
class MDNodeSDNode : public SDNode {
|
||||
const MDNode *MD;
|
||||
friend class SelectionDAG;
|
||||
explicit MDNodeSDNode(const MDNode *md)
|
||||
: SDNode(ISD::MDNODE_SDNODE, DebugLoc(), getSDVTList(MVT::Other)), MD(md) {}
|
||||
public:
|
||||
|
||||
const MDNode *getMD() const { return MD; }
|
||||
|
||||
static bool classof(const MDNodeSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return N->getOpcode() == ISD::MDNODE_SDNODE;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class RegisterSDNode : public SDNode {
|
||||
@ -2072,16 +1360,16 @@ class RegisterSDNode : public SDNode {
|
||||
};
|
||||
|
||||
class BlockAddressSDNode : public SDNode {
|
||||
BlockAddress *BA;
|
||||
const BlockAddress *BA;
|
||||
unsigned char TargetFlags;
|
||||
friend class SelectionDAG;
|
||||
BlockAddressSDNode(unsigned NodeTy, EVT VT, BlockAddress *ba,
|
||||
BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
|
||||
unsigned char Flags)
|
||||
: SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
|
||||
BA(ba), TargetFlags(Flags) {
|
||||
}
|
||||
public:
|
||||
BlockAddress *getBlockAddress() const { return BA; }
|
||||
const BlockAddress *getBlockAddress() const { return BA; }
|
||||
unsigned char getTargetFlags() const { return TargetFlags; }
|
||||
|
||||
static bool classof(const BlockAddressSDNode *) { return true; }
|
||||
@ -2588,7 +1876,6 @@ namespace ISD {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end llvm namespace
|
||||
|
||||
#endif
|
||||
|
@ -28,7 +28,6 @@
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -37,8 +36,6 @@ namespace llvm {
|
||||
/// SlotIndex & SlotIndexes classes for the public interface to this
|
||||
/// information.
|
||||
class IndexListEntry {
|
||||
private:
|
||||
|
||||
static const unsigned EMPTY_KEY_INDEX = ~0U & ~3U,
|
||||
TOMBSTONE_KEY_INDEX = ~0U & ~7U;
|
||||
|
||||
@ -66,10 +63,9 @@ namespace llvm {
|
||||
public:
|
||||
|
||||
IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {
|
||||
if (index == EMPTY_KEY_INDEX || index == TOMBSTONE_KEY_INDEX) {
|
||||
llvm_report_error("Attempt to create invalid index. "
|
||||
"Available indexes may have been exhausted?.");
|
||||
}
|
||||
assert(index != EMPTY_KEY_INDEX && index != TOMBSTONE_KEY_INDEX &&
|
||||
"Attempt to create invalid index. "
|
||||
"Available indexes may have been exhausted?.");
|
||||
}
|
||||
|
||||
bool isValid() const {
|
||||
|
@ -33,7 +33,6 @@ namespace llvm {
|
||||
|
||||
|
||||
class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
|
||||
mutable void *UniquingMap;
|
||||
protected:
|
||||
/// TLSDataSection - Section directive for Thread Local data.
|
||||
///
|
||||
@ -52,14 +51,9 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
|
||||
const MCSection *MergeableConst4Section;
|
||||
const MCSection *MergeableConst8Section;
|
||||
const MCSection *MergeableConst16Section;
|
||||
|
||||
protected:
|
||||
const MCSection *getELFSection(StringRef Section, unsigned Type,
|
||||
unsigned Flags, SectionKind Kind,
|
||||
bool IsExplicit = false) const;
|
||||
public:
|
||||
TargetLoweringObjectFileELF() : UniquingMap(0) {}
|
||||
~TargetLoweringObjectFileELF();
|
||||
TargetLoweringObjectFileELF() {}
|
||||
~TargetLoweringObjectFileELF() {}
|
||||
|
||||
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
|
||||
@ -90,8 +84,6 @@ class TargetLoweringObjectFileELF : public TargetLoweringObjectFile {
|
||||
|
||||
|
||||
class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
|
||||
mutable void *UniquingMap;
|
||||
|
||||
const MCSection *CStringSection;
|
||||
const MCSection *UStringSection;
|
||||
const MCSection *TextCoalSection;
|
||||
@ -108,8 +100,8 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
|
||||
const MCSection *LazySymbolPointerSection;
|
||||
const MCSection *NonLazySymbolPointerSection;
|
||||
public:
|
||||
TargetLoweringObjectFileMachO() : UniquingMap(0) {}
|
||||
~TargetLoweringObjectFileMachO();
|
||||
TargetLoweringObjectFileMachO() {}
|
||||
~TargetLoweringObjectFileMachO() {}
|
||||
|
||||
virtual void Initialize(MCContext &Ctx, const TargetMachine &TM);
|
||||
|
||||
@ -129,20 +121,6 @@ class TargetLoweringObjectFileMachO : public TargetLoweringObjectFile {
|
||||
virtual bool shouldEmitUsedDirectiveFor(const GlobalValue *GV,
|
||||
Mangler *) const;
|
||||
|
||||
/// getMachOSection - Return the MCSection for the specified mach-o section.
|
||||
/// This requires the operands to be valid.
|
||||
const MCSectionMachO *getMachOSection(StringRef Segment,
|
||||
StringRef Section,
|
||||
unsigned TypeAndAttributes,
|
||||
SectionKind K) const {
|
||||
return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
|
||||
}
|
||||
const MCSectionMachO *getMachOSection(StringRef Segment,
|
||||
StringRef Section,
|
||||
unsigned TypeAndAttributes,
|
||||
unsigned Reserved2,
|
||||
SectionKind K) const;
|
||||
|
||||
/// getTextCoalSection - Return the "__TEXT,__textcoal_nt" section we put weak
|
||||
/// text symbols into.
|
||||
const MCSection *getTextCoalSection() const {
|
||||
|
@ -264,6 +264,9 @@
|
||||
/* Define to 1 if you have the `opendir' function. */
|
||||
#undef HAVE_OPENDIR
|
||||
|
||||
/* Define to 1 if you have the `posix_spawn' function. */
|
||||
#undef HAVE_POSIX_SPAWN
|
||||
|
||||
/* Define to 1 if you have the `powf' function. */
|
||||
#undef HAVE_POWF
|
||||
|
||||
|
@ -146,6 +146,49 @@ class InlineAsm : public Value {
|
||||
return V->getValueID() == Value::InlineAsmVal;
|
||||
}
|
||||
|
||||
|
||||
// These are helper methods for dealing with flags in the INLINEASM SDNode
|
||||
// in the backend.
|
||||
|
||||
enum {
|
||||
Op_InputChain = 0,
|
||||
Op_AsmString = 1,
|
||||
Op_MDNode = 2,
|
||||
Op_FirstOperand = 3,
|
||||
|
||||
Kind_RegUse = 1,
|
||||
Kind_RegDef = 2,
|
||||
Kind_Imm = 3,
|
||||
Kind_Mem = 4,
|
||||
Kind_RegDefEarlyClobber = 6,
|
||||
|
||||
Flag_MatchingOperand = 0x80000000
|
||||
};
|
||||
|
||||
static unsigned getFlagWord(unsigned Kind, unsigned NumOps) {
|
||||
assert(((NumOps << 3) & ~0xffff) == 0 && "Too many inline asm operands!");
|
||||
return Kind | (NumOps << 3);
|
||||
}
|
||||
|
||||
/// getFlagWordForMatchingOp - Augment an existing flag word returned by
|
||||
/// getFlagWord with information indicating that this input operand is tied
|
||||
/// to a previous output operand.
|
||||
static unsigned getFlagWordForMatchingOp(unsigned InputFlag,
|
||||
unsigned MatchedOperandNo) {
|
||||
return InputFlag | Flag_MatchingOperand | (MatchedOperandNo << 16);
|
||||
}
|
||||
|
||||
static unsigned getKind(unsigned Flags) {
|
||||
return Flags & 7;
|
||||
}
|
||||
|
||||
static bool isRegDefKind(unsigned Flag){ return getKind(Flag) == Kind_RegDef;}
|
||||
static bool isImmKind(unsigned Flag) { return getKind(Flag) == Kind_Imm; }
|
||||
static bool isMemKind(unsigned Flag) { return getKind(Flag) == Kind_Mem; }
|
||||
static bool isRegDefEarlyClobberKind(unsigned Flag) {
|
||||
return getKind(Flag) == Kind_RegDefEarlyClobber;
|
||||
}
|
||||
|
||||
/// getNumOperandRegisters - Extract the number of registers field from the
|
||||
/// inline asm operand flag.
|
||||
static unsigned getNumOperandRegisters(unsigned Flag) {
|
||||
@ -155,9 +198,9 @@ class InlineAsm : public Value {
|
||||
/// isUseOperandTiedToDef - Return true if the flag of the inline asm
|
||||
/// operand indicates it is an use operand that's matched to a def operand.
|
||||
static bool isUseOperandTiedToDef(unsigned Flag, unsigned &Idx) {
|
||||
if ((Flag & 0x80000000) == 0)
|
||||
if ((Flag & Flag_MatchingOperand) == 0)
|
||||
return false;
|
||||
Idx = (Flag & ~0x80000000) >> 16;
|
||||
Idx = (Flag & ~Flag_MatchingOperand) >> 16;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -105,8 +105,7 @@ namespace llvm {
|
||||
return cast<ConstantInt>(
|
||||
const_cast<Value*>(getOperand(2)))->getZExtValue();
|
||||
}
|
||||
const MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); }
|
||||
MDNode *getVariable() { return cast<MDNode>(getOperand(3)); }
|
||||
MDNode *getVariable() const { return cast<MDNode>(getOperand(3)); }
|
||||
|
||||
// Methods for support type inquiry through isa, cast, and dyn_cast:
|
||||
static inline bool classof(const DbgValueInst *) { return true; }
|
||||
|
@ -669,16 +669,6 @@ let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
Intrinsic<[llvm_v4i32_ty], [llvm_v4i32_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
// Align ops
|
||||
let TargetPrefix = "x86" in { // All intrinsics start with "llvm.x86.".
|
||||
def int_x86_ssse3_palign_r :
|
||||
Intrinsic<[llvm_v1i64_ty], [llvm_v1i64_ty,
|
||||
llvm_v1i64_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
def int_x86_ssse3_palign_r_128 :
|
||||
Intrinsic<[llvm_v2i64_ty], [llvm_v2i64_ty,
|
||||
llvm_v2i64_ty, llvm_i8_ty], [IntrNoMem]>;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// SSE4.1
|
||||
|
||||
|
@ -19,6 +19,7 @@ namespace llvm {
|
||||
|
||||
class LLVMContextImpl;
|
||||
class StringRef;
|
||||
class Instruction;
|
||||
template <typename T> class SmallVectorImpl;
|
||||
|
||||
/// This is an important class for using LLVM in a threaded context. It
|
||||
@ -68,6 +69,15 @@ class LLVMContext {
|
||||
/// setInlineAsmDiagnosticHandler.
|
||||
void *getInlineAsmDiagnosticContext() const;
|
||||
|
||||
|
||||
/// emitError - Emit an error message to the currently installed error handler
|
||||
/// with optional location information. This function returns, so code should
|
||||
/// be prepared to drop the erroneous construct on the floor and "not crash".
|
||||
/// The generated code need not be correct. The error message will be
|
||||
/// implicitly prefixed with "error: " and should not end with a ".".
|
||||
void emitError(unsigned LocCookie, StringRef ErrorStr);
|
||||
void emitError(const Instruction *I, StringRef ErrorStr);
|
||||
void emitError(StringRef ErrorStr);
|
||||
};
|
||||
|
||||
/// getGlobalContext - Returns a global context. This is for LLVM clients that
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "llvm/Analysis/PointerTracking.h"
|
||||
#include "llvm/Analysis/PostDominators.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/Lint.h"
|
||||
#include "llvm/Assembly/PrintModulePass.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Function.h"
|
||||
@ -135,8 +136,8 @@ namespace {
|
||||
(void) llvm::createSSIPass();
|
||||
(void) llvm::createSSIEverythingPass();
|
||||
(void) llvm::createGEPSplitterPass();
|
||||
(void) llvm::createSCCVNPass();
|
||||
(void) llvm::createABCDPass();
|
||||
(void) llvm::createLintPass();
|
||||
|
||||
(void)new llvm::IntervalPartition();
|
||||
(void)new llvm::FindUsedTypes();
|
||||
|
29
include/llvm/MC/EDInstInfo.h
Normal file
29
include/llvm/MC/EDInstInfo.h
Normal file
@ -0,0 +1,29 @@
|
||||
//===-- llvm/MC/EDInstInfo.h - EDis instruction info ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
#ifndef EDINSTINFO_H
|
||||
#define EDINSTINFO_H
|
||||
|
||||
#include "llvm/System/DataTypes.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
#define EDIS_MAX_OPERANDS 13
|
||||
#define EDIS_MAX_SYNTAXES 2
|
||||
|
||||
struct EDInstInfo {
|
||||
uint8_t instructionType;
|
||||
uint8_t numOperands;
|
||||
uint8_t operandTypes[EDIS_MAX_OPERANDS];
|
||||
uint8_t operandFlags[EDIS_MAX_OPERANDS];
|
||||
const char operandOrders[EDIS_MAX_SYNTAXES][EDIS_MAX_OPERANDS];
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
@ -97,7 +97,11 @@ namespace llvm {
|
||||
/// AllowNameToStartWithDigit - This is true if the assembler allows symbol
|
||||
/// names to start with a digit (e.g., "0x0021"). This defaults to false.
|
||||
bool AllowNameToStartWithDigit;
|
||||
|
||||
|
||||
/// AllowPeriodsInName - This is true if the assembler allows periods in
|
||||
/// symbol names. This defaults to true.
|
||||
bool AllowPeriodsInName;
|
||||
|
||||
//===--- Data Emission Directives -------------------------------------===//
|
||||
|
||||
/// ZeroDirective - this should be set to the directive used to get some
|
||||
@ -280,7 +284,7 @@ namespace llvm {
|
||||
/// getNonexecutableStackSection - Targets can implement this method to
|
||||
/// specify a section to switch to if the translation unit doesn't have any
|
||||
/// trampolines that require an executable stack.
|
||||
virtual MCSection *getNonexecutableStackSection(MCContext &Ctx) const {
|
||||
virtual const MCSection *getNonexecutableStackSection(MCContext &Ctx) const{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -341,6 +345,9 @@ namespace llvm {
|
||||
bool doesAllowNameToStartWithDigit() const {
|
||||
return AllowNameToStartWithDigit;
|
||||
}
|
||||
bool doesAllowPeriodsInName() const {
|
||||
return AllowPeriodsInName;
|
||||
}
|
||||
const char *getZeroDirective() const {
|
||||
return ZeroDirective;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#ifndef LLVM_MC_MCCONTEXT_H
|
||||
#define LLVM_MC_MCCONTEXT_H
|
||||
|
||||
#include "llvm/MC/SectionKind.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
@ -21,6 +22,7 @@ namespace llvm {
|
||||
class MCSymbol;
|
||||
class StringRef;
|
||||
class Twine;
|
||||
class MCSectionMachO;
|
||||
|
||||
/// MCContext - Context object for machine code objects. This class owns all
|
||||
/// of the sections that it creates.
|
||||
@ -47,6 +49,8 @@ namespace llvm {
|
||||
/// We use a bump pointer allocator to avoid the need to track all allocated
|
||||
/// objects.
|
||||
BumpPtrAllocator Allocator;
|
||||
|
||||
void *MachOUniquingMap, *ELFUniquingMap;
|
||||
public:
|
||||
explicit MCContext(const MCAsmInfo &MAI);
|
||||
~MCContext();
|
||||
@ -72,6 +76,29 @@ namespace llvm {
|
||||
MCSymbol *LookupSymbol(StringRef Name) const;
|
||||
|
||||
/// @}
|
||||
|
||||
/// @name Section Managment
|
||||
/// @{
|
||||
|
||||
/// getMachOSection - Return the MCSection for the specified mach-o section.
|
||||
/// This requires the operands to be valid.
|
||||
const MCSectionMachO *getMachOSection(StringRef Segment,
|
||||
StringRef Section,
|
||||
unsigned TypeAndAttributes,
|
||||
unsigned Reserved2,
|
||||
SectionKind K);
|
||||
const MCSectionMachO *getMachOSection(StringRef Segment,
|
||||
StringRef Section,
|
||||
unsigned TypeAndAttributes,
|
||||
SectionKind K) {
|
||||
return getMachOSection(Segment, Section, TypeAndAttributes, 0, K);
|
||||
}
|
||||
|
||||
const MCSection *getELFSection(StringRef Section, unsigned Type,
|
||||
unsigned Flags, SectionKind Kind,
|
||||
bool IsExplicit = false);
|
||||
|
||||
/// @}
|
||||
|
||||
void *Allocate(unsigned Size, unsigned Align = 8) {
|
||||
return Allocator.Allocate(Size, Align);
|
||||
|
@ -16,6 +16,8 @@ namespace llvm {
|
||||
class MCInst;
|
||||
class MemoryObject;
|
||||
class raw_ostream;
|
||||
|
||||
struct EDInstInfo;
|
||||
|
||||
/// MCDisassembler - Superclass for all disassemblers. Consumes a memory region
|
||||
/// and provides an array of assembly instructions.
|
||||
@ -43,7 +45,15 @@ class MCDisassembler {
|
||||
const MemoryObject ®ion,
|
||||
uint64_t address,
|
||||
raw_ostream &vStream) const = 0;
|
||||
};
|
||||
|
||||
/// getEDInfo - Returns the enhanced insturction information corresponding to
|
||||
/// the disassembler.
|
||||
///
|
||||
/// @return - An array of instruction information, with one entry for
|
||||
/// each MCInst opcode this disassembler returns.
|
||||
/// NULL if there is no info for this target.
|
||||
virtual EDInstInfo *getEDInfo() const { return (EDInstInfo*)0; }
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
|
@ -49,7 +49,7 @@ class MCObjectWriter {
|
||||
public:
|
||||
virtual ~MCObjectWriter();
|
||||
|
||||
bool isLittleEndian() { return IsLittleEndian; }
|
||||
bool isLittleEndian() const { return IsLittleEndian; }
|
||||
|
||||
raw_ostream &getStream() { return OS; }
|
||||
|
||||
|
@ -14,7 +14,6 @@
|
||||
#ifndef ASMPARSER_H
|
||||
#define ASMPARSER_H
|
||||
|
||||
#include <vector>
|
||||
#include "llvm/MC/MCParser/AsmLexer.h"
|
||||
#include "llvm/MC/MCParser/AsmCond.h"
|
||||
#include "llvm/MC/MCParser/MCAsmParser.h"
|
||||
@ -22,6 +21,7 @@
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/ADT/StringMap.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
class AsmCond;
|
||||
@ -50,10 +50,6 @@ class AsmParser : public MCAsmParser {
|
||||
AsmCond TheCondState;
|
||||
std::vector<AsmCond> TheCondStack;
|
||||
|
||||
// FIXME: Figure out where this should leave, the code is a copy of that which
|
||||
// is also used by TargetLoweringObjectFile.
|
||||
mutable void *SectionUniquingMap;
|
||||
|
||||
/// DirectiveMap - This is a table handlers for directives. Each handler is
|
||||
/// invoked after the directive identifier is read and is responsible for
|
||||
/// parsing and validating the rest of the directive. The handler is passed
|
||||
@ -97,13 +93,6 @@ class AsmParser : public MCAsmParser {
|
||||
private:
|
||||
MCSymbol *CreateSymbol(StringRef Name);
|
||||
|
||||
// FIXME: See comment on SectionUniquingMap.
|
||||
const MCSection *getMachOSection(const StringRef &Segment,
|
||||
const StringRef &Section,
|
||||
unsigned TypeAndAttributes,
|
||||
unsigned Reserved2,
|
||||
SectionKind Kind) const;
|
||||
|
||||
bool ParseStatement();
|
||||
|
||||
bool TokError(const char *Msg);
|
||||
@ -113,8 +102,6 @@ class AsmParser : public MCAsmParser {
|
||||
/// EnterIncludeFile - Enter the specified file. This returns true on failure.
|
||||
bool EnterIncludeFile(const std::string &Filename);
|
||||
|
||||
bool ParseConditionalAssemblyDirectives(StringRef Directive,
|
||||
SMLoc DirectiveLoc);
|
||||
void EatToEndOfStatement();
|
||||
|
||||
bool ParseAssignment(const StringRef &Name);
|
||||
|
@ -42,7 +42,7 @@ class AsmToken {
|
||||
Plus, Minus, Tilde,
|
||||
Slash, // '/'
|
||||
LParen, RParen, LBrac, RBrac, LCurly, RCurly,
|
||||
Star, Comma, Dollar, Equal, EqualEqual,
|
||||
Star, Dot, Comma, Dollar, Equal, EqualEqual,
|
||||
|
||||
Pipe, PipePipe, Caret,
|
||||
Amp, AmpAmp, Exclaim, ExclaimEqual, Percent, Hash,
|
||||
|
@ -36,16 +36,14 @@ class MCSectionELF : public MCSection {
|
||||
/// explicit section specified.
|
||||
bool IsExplicit;
|
||||
|
||||
protected:
|
||||
private:
|
||||
friend class MCContext;
|
||||
MCSectionELF(StringRef Section, unsigned type, unsigned flags,
|
||||
SectionKind K, bool isExplicit)
|
||||
: MCSection(K), SectionName(Section), Type(type), Flags(flags),
|
||||
IsExplicit(isExplicit) {}
|
||||
~MCSectionELF();
|
||||
public:
|
||||
|
||||
static MCSectionELF *Create(StringRef Section, unsigned Type,
|
||||
unsigned Flags, SectionKind K, bool isExplicit,
|
||||
MCContext &Ctx);
|
||||
|
||||
/// ShouldOmitSectionDirective - Decides whether a '.section' directive
|
||||
/// should be printed before the section name
|
||||
@ -153,40 +151,33 @@ class MCSectionELF : public MCSection {
|
||||
|
||||
// This section holds Thread-Local Storage.
|
||||
SHF_TLS = 0x400U,
|
||||
|
||||
/// FIRST_TARGET_DEP_FLAG - This is the first flag that subclasses are
|
||||
/// allowed to specify.
|
||||
FIRST_TARGET_DEP_FLAG = 0x800U,
|
||||
|
||||
/// TARGET_INDEP_SHF - This is the bitmask for all the target independent
|
||||
/// section flags. Targets can define their own target flags above these.
|
||||
/// If they do that, they should implement their own MCSectionELF subclasses
|
||||
/// and implement the virtual method hooks below to handle printing needs.
|
||||
TARGET_INDEP_SHF = FIRST_TARGET_DEP_FLAG-1U
|
||||
|
||||
// Start of target-specific flags.
|
||||
|
||||
/// XCORE_SHF_CP_SECTION - All sections with the "c" flag are grouped
|
||||
/// together by the linker to form the constant pool and the cp register is
|
||||
/// set to the start of the constant pool by the boot code.
|
||||
XCORE_SHF_CP_SECTION = 0x800U,
|
||||
|
||||
/// XCORE_SHF_DP_SECTION - All sections with the "d" flag are grouped
|
||||
/// together by the linker to form the data section and the dp register is
|
||||
/// set to the start of the section by the boot code.
|
||||
XCORE_SHF_DP_SECTION = 0x1000U
|
||||
};
|
||||
|
||||
StringRef getSectionName() const { return SectionName; }
|
||||
unsigned getType() const { return Type; }
|
||||
unsigned getFlags() const { return Flags; }
|
||||
|
||||
virtual void PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const;
|
||||
void PrintSwitchToSection(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const;
|
||||
|
||||
/// isBaseAddressKnownZero - We know that non-allocatable sections (like
|
||||
/// debug info) have a base of zero.
|
||||
virtual bool isBaseAddressKnownZero() const {
|
||||
return (getFlags() & SHF_ALLOC) == 0;
|
||||
}
|
||||
|
||||
/// PrintTargetSpecificSectionFlags - Targets that define their own
|
||||
/// MCSectionELF subclasses with target specific section flags should
|
||||
/// implement this method if they end up adding letters to the attributes
|
||||
/// list.
|
||||
virtual void PrintTargetSpecificSectionFlags(const MCAsmInfo &MAI,
|
||||
raw_ostream &OS) const {
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
@ -34,30 +34,10 @@ class MCSectionMachO : public MCSection {
|
||||
unsigned Reserved2;
|
||||
|
||||
MCSectionMachO(StringRef Segment, StringRef Section,
|
||||
unsigned TAA, unsigned reserved2, SectionKind K)
|
||||
: MCSection(K), TypeAndAttributes(TAA), Reserved2(reserved2) {
|
||||
assert(Segment.size() <= 16 && Section.size() <= 16 &&
|
||||
"Segment or section string too long");
|
||||
for (unsigned i = 0; i != 16; ++i) {
|
||||
if (i < Segment.size())
|
||||
SegmentName[i] = Segment[i];
|
||||
else
|
||||
SegmentName[i] = 0;
|
||||
|
||||
if (i < Section.size())
|
||||
SectionName[i] = Section[i];
|
||||
else
|
||||
SectionName[i] = 0;
|
||||
}
|
||||
}
|
||||
unsigned TAA, unsigned reserved2, SectionKind K);
|
||||
friend class MCContext;
|
||||
public:
|
||||
|
||||
static MCSectionMachO *Create(StringRef Segment,
|
||||
StringRef Section,
|
||||
unsigned TypeAndAttributes,
|
||||
unsigned Reserved2,
|
||||
SectionKind K, MCContext &Ctx);
|
||||
|
||||
/// These are the section type and attributes fields. A MachO section can
|
||||
/// have only one Type, but can have any of the attributes specified.
|
||||
enum {
|
||||
|
@ -91,7 +91,7 @@ class MDNode : public Value, public FoldingSetNode {
|
||||
FunctionLocalBit = 1 << 0,
|
||||
|
||||
/// NotUniquedBit - This is set on MDNodes that are not uniqued because they
|
||||
/// have a null perand.
|
||||
/// have a null operand.
|
||||
NotUniquedBit = 1 << 1,
|
||||
|
||||
/// DestroyFlag - This bit is set by destroy() so the destructor can assert
|
||||
|
@ -236,4 +236,6 @@ inline void *operator new(size_t Size, llvm::BumpPtrAllocator &Allocator) {
|
||||
offsetof(S, x)));
|
||||
}
|
||||
|
||||
inline void operator delete(void *, llvm::BumpPtrAllocator &) {}
|
||||
|
||||
#endif // LLVM_SUPPORT_ALLOCATOR_H
|
||||
|
@ -25,28 +25,29 @@ namespace llvm {
|
||||
// BasicBlock pred_iterator definition
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
template <class _Ptr, class _USE_iterator> // Predecessor Iterator
|
||||
template <class Ptr, class USE_iterator> // Predecessor Iterator
|
||||
class PredIterator : public std::iterator<std::forward_iterator_tag,
|
||||
_Ptr, ptrdiff_t> {
|
||||
typedef std::iterator<std::forward_iterator_tag, _Ptr, ptrdiff_t> super;
|
||||
_USE_iterator It;
|
||||
public:
|
||||
typedef PredIterator<_Ptr,_USE_iterator> _Self;
|
||||
typedef typename super::pointer pointer;
|
||||
Ptr, ptrdiff_t> {
|
||||
typedef std::iterator<std::forward_iterator_tag, Ptr, ptrdiff_t> super;
|
||||
typedef PredIterator<Ptr, USE_iterator> Self;
|
||||
USE_iterator It;
|
||||
|
||||
inline void advancePastNonTerminators() {
|
||||
// Loop to ignore non terminator uses (for example PHI nodes)...
|
||||
// Loop to ignore non terminator uses (for example PHI nodes).
|
||||
while (!It.atEnd() && !isa<TerminatorInst>(*It))
|
||||
++It;
|
||||
}
|
||||
|
||||
inline PredIterator(_Ptr *bb) : It(bb->use_begin()) {
|
||||
public:
|
||||
typedef typename super::pointer pointer;
|
||||
|
||||
explicit inline PredIterator(Ptr *bb) : It(bb->use_begin()) {
|
||||
advancePastNonTerminators();
|
||||
}
|
||||
inline PredIterator(_Ptr *bb, bool) : It(bb->use_end()) {}
|
||||
inline PredIterator(Ptr *bb, bool) : It(bb->use_end()) {}
|
||||
|
||||
inline bool operator==(const _Self& x) const { return It == x.It; }
|
||||
inline bool operator!=(const _Self& x) const { return !operator==(x); }
|
||||
inline bool operator==(const Self& x) const { return It == x.It; }
|
||||
inline bool operator!=(const Self& x) const { return !operator==(x); }
|
||||
|
||||
inline pointer operator*() const {
|
||||
assert(!It.atEnd() && "pred_iterator out of range!");
|
||||
@ -54,14 +55,14 @@ class PredIterator : public std::iterator<std::forward_iterator_tag,
|
||||
}
|
||||
inline pointer *operator->() const { return &(operator*()); }
|
||||
|
||||
inline _Self& operator++() { // Preincrement
|
||||
inline Self& operator++() { // Preincrement
|
||||
assert(!It.atEnd() && "pred_iterator out of range!");
|
||||
++It; advancePastNonTerminators();
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline _Self operator++(int) { // Postincrement
|
||||
_Self tmp = *this; ++*this; return tmp;
|
||||
inline Self operator++(int) { // Postincrement
|
||||
Self tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
};
|
||||
|
||||
@ -90,12 +91,17 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
const Term_ Term;
|
||||
unsigned idx;
|
||||
typedef std::iterator<std::bidirectional_iterator_tag, BB_, ptrdiff_t> super;
|
||||
typedef SuccIterator<Term_, BB_> Self;
|
||||
|
||||
inline bool index_is_valid(int idx) {
|
||||
return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
|
||||
}
|
||||
|
||||
public:
|
||||
typedef SuccIterator<Term_, BB_> _Self;
|
||||
typedef typename super::pointer pointer;
|
||||
// TODO: This can be random access iterator, only operator[] missing.
|
||||
|
||||
inline SuccIterator(Term_ T) : Term(T), idx(0) { // begin iterator
|
||||
explicit inline SuccIterator(Term_ T) : Term(T), idx(0) {// begin iterator
|
||||
assert(T && "getTerminator returned null!");
|
||||
}
|
||||
inline SuccIterator(Term_ T, bool) // end iterator
|
||||
@ -103,78 +109,74 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
assert(T && "getTerminator returned null!");
|
||||
}
|
||||
|
||||
inline const _Self &operator=(const _Self &I) {
|
||||
inline const Self &operator=(const Self &I) {
|
||||
assert(Term == I.Term &&"Cannot assign iterators to two different blocks!");
|
||||
idx = I.idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline bool index_is_valid (int idx) {
|
||||
return idx >= 0 && (unsigned) idx < Term->getNumSuccessors();
|
||||
}
|
||||
|
||||
/// getSuccessorIndex - This is used to interface between code that wants to
|
||||
/// operate on terminator instructions directly.
|
||||
unsigned getSuccessorIndex() const { return idx; }
|
||||
|
||||
inline bool operator==(const _Self& x) const { return idx == x.idx; }
|
||||
inline bool operator!=(const _Self& x) const { return !operator==(x); }
|
||||
inline bool operator==(const Self& x) const { return idx == x.idx; }
|
||||
inline bool operator!=(const Self& x) const { return !operator==(x); }
|
||||
|
||||
inline pointer operator*() const { return Term->getSuccessor(idx); }
|
||||
inline pointer operator->() const { return operator*(); }
|
||||
|
||||
inline _Self& operator++() { ++idx; return *this; } // Preincrement
|
||||
inline Self& operator++() { ++idx; return *this; } // Preincrement
|
||||
|
||||
inline _Self operator++(int) { // Postincrement
|
||||
_Self tmp = *this; ++*this; return tmp;
|
||||
inline Self operator++(int) { // Postincrement
|
||||
Self tmp = *this; ++*this; return tmp;
|
||||
}
|
||||
|
||||
inline _Self& operator--() { --idx; return *this; } // Predecrement
|
||||
inline _Self operator--(int) { // Postdecrement
|
||||
_Self tmp = *this; --*this; return tmp;
|
||||
inline Self& operator--() { --idx; return *this; } // Predecrement
|
||||
inline Self operator--(int) { // Postdecrement
|
||||
Self tmp = *this; --*this; return tmp;
|
||||
}
|
||||
|
||||
inline bool operator<(const _Self& x) const {
|
||||
inline bool operator<(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx < x.idx;
|
||||
}
|
||||
|
||||
inline bool operator<=(const _Self& x) const {
|
||||
inline bool operator<=(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx <= x.idx;
|
||||
}
|
||||
inline bool operator>=(const _Self& x) const {
|
||||
inline bool operator>=(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx >= x.idx;
|
||||
}
|
||||
|
||||
inline bool operator>(const _Self& x) const {
|
||||
inline bool operator>(const Self& x) const {
|
||||
assert(Term == x.Term && "Cannot compare iterators of different blocks!");
|
||||
return idx > x.idx;
|
||||
}
|
||||
|
||||
inline _Self& operator+=(int Right) {
|
||||
inline Self& operator+=(int Right) {
|
||||
unsigned new_idx = idx + Right;
|
||||
assert(index_is_valid(new_idx) && "Iterator index out of bound");
|
||||
idx = new_idx;
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline _Self operator+(int Right) {
|
||||
_Self tmp = *this;
|
||||
inline Self operator+(int Right) {
|
||||
Self tmp = *this;
|
||||
tmp += Right;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
inline _Self& operator-=(int Right) {
|
||||
inline Self& operator-=(int Right) {
|
||||
return operator+=(-Right);
|
||||
}
|
||||
|
||||
inline _Self operator-(int Right) {
|
||||
inline Self operator-(int Right) {
|
||||
return operator+(-Right);
|
||||
}
|
||||
|
||||
inline int operator-(const _Self& x) {
|
||||
inline int operator-(const Self& x) {
|
||||
assert(Term == x.Term && "Cannot work on iterators of different blocks!");
|
||||
int distance = idx - x.idx;
|
||||
return distance;
|
||||
@ -185,14 +187,14 @@ class SuccIterator : public std::iterator<std::bidirectional_iterator_tag,
|
||||
// be modified are not available.
|
||||
//
|
||||
// inline pointer operator[](int offset) {
|
||||
// _Self tmp = *this;
|
||||
// Self tmp = *this;
|
||||
// tmp += offset;
|
||||
// return tmp.operator*();
|
||||
// }
|
||||
|
||||
/// Get the source BB of this iterator.
|
||||
inline BB_ *getSource() {
|
||||
return Term->getParent();
|
||||
return Term->getParent();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/CallingConv.h"
|
||||
#include "llvm/Instruction.h"
|
||||
#include "llvm/Instructions.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
@ -150,6 +150,108 @@ class CallSiteBase {
|
||||
bool arg_empty() const { return arg_end() == arg_begin(); }
|
||||
unsigned arg_size() const { return unsigned(arg_end() - arg_begin()); }
|
||||
|
||||
/// getType - Return the type of the instruction that generated this call site
|
||||
///
|
||||
const Type *getType() const { return (*this)->getType(); }
|
||||
|
||||
/// getCaller - Return the caller function for this call site
|
||||
///
|
||||
FunTy *getCaller() const { return (*this)->getParent()->getParent(); }
|
||||
|
||||
#define CALLSITE_DELEGATE_GETTER(METHOD) \
|
||||
InstrTy *II = getInstruction(); \
|
||||
return isCall() \
|
||||
? cast<CallInst>(II)->METHOD \
|
||||
: cast<InvokeInst>(II)->METHOD
|
||||
|
||||
#define CALLSITE_DELEGATE_SETTER(METHOD) \
|
||||
InstrTy *II = getInstruction(); \
|
||||
if (isCall()) \
|
||||
cast<CallInst>(II)->METHOD; \
|
||||
else \
|
||||
cast<InvokeInst>(II)->METHOD
|
||||
|
||||
/// getCallingConv/setCallingConv - get or set the calling convention of the
|
||||
/// call.
|
||||
CallingConv::ID getCallingConv() const {
|
||||
CALLSITE_DELEGATE_GETTER(getCallingConv());
|
||||
}
|
||||
void setCallingConv(CallingConv::ID CC) {
|
||||
CALLSITE_DELEGATE_SETTER(setCallingConv(CC));
|
||||
}
|
||||
|
||||
/// getAttributes/setAttributes - get or set the parameter attributes of
|
||||
/// the call.
|
||||
const AttrListPtr &getAttributes() const {
|
||||
CALLSITE_DELEGATE_GETTER(getAttributes());
|
||||
}
|
||||
void setAttributes(const AttrListPtr &PAL) {
|
||||
CALLSITE_DELEGATE_SETTER(setAttributes(PAL));
|
||||
}
|
||||
|
||||
/// paramHasAttr - whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, Attributes attr) const {
|
||||
CALLSITE_DELEGATE_GETTER(paramHasAttr(i, attr));
|
||||
}
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const {
|
||||
CALLSITE_DELEGATE_GETTER(getParamAlignment(i));
|
||||
}
|
||||
|
||||
/// @brief Return true if the call should not be inlined.
|
||||
bool isNoInline() const {
|
||||
CALLSITE_DELEGATE_GETTER(isNoInline());
|
||||
}
|
||||
void setIsNoInline(bool Value = true) {
|
||||
CALLSITE_DELEGATE_GETTER(setIsNoInline(Value));
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotAccessMemory());
|
||||
}
|
||||
void setDoesNotAccessMemory(bool doesNotAccessMemory = true) {
|
||||
CALLSITE_DELEGATE_SETTER(setDoesNotAccessMemory(doesNotAccessMemory));
|
||||
}
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const {
|
||||
CALLSITE_DELEGATE_GETTER(onlyReadsMemory());
|
||||
}
|
||||
void setOnlyReadsMemory(bool onlyReadsMemory = true) {
|
||||
CALLSITE_DELEGATE_SETTER(setOnlyReadsMemory(onlyReadsMemory));
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotReturn());
|
||||
}
|
||||
void setDoesNotReturn(bool doesNotReturn = true) {
|
||||
CALLSITE_DELEGATE_SETTER(setDoesNotReturn(doesNotReturn));
|
||||
}
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool doesNotThrow() const {
|
||||
CALLSITE_DELEGATE_GETTER(doesNotThrow());
|
||||
}
|
||||
void setDoesNotThrow(bool doesNotThrow = true) {
|
||||
CALLSITE_DELEGATE_SETTER(setDoesNotThrow(doesNotThrow));
|
||||
}
|
||||
|
||||
#undef CALLSITE_DELEGATE_GETTER
|
||||
#undef CALLSITE_DELEGATE_SETTER
|
||||
|
||||
/// hasArgument - Returns true if this CallSite passes the given Value* as an
|
||||
/// argument to the called function.
|
||||
bool hasArgument(const Value *Arg) const {
|
||||
for (arg_iterator AI = this->arg_begin(), E = this->arg_end(); AI != E;
|
||||
++AI)
|
||||
if (AI->get() == Arg)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
/// Returns the operand number of the first argument
|
||||
unsigned getArgumentOffset() const {
|
||||
@ -179,24 +281,24 @@ class CallSiteBase {
|
||||
|
||||
/// ImmutableCallSite - establish a view to a call site for examination
|
||||
class ImmutableCallSite : public CallSiteBase<> {
|
||||
typedef CallSiteBase<> _Base;
|
||||
typedef CallSiteBase<> Base;
|
||||
public:
|
||||
ImmutableCallSite(const Value* V) : _Base(V) {}
|
||||
ImmutableCallSite(const CallInst *CI) : _Base(CI) {}
|
||||
ImmutableCallSite(const InvokeInst *II) : _Base(II) {}
|
||||
ImmutableCallSite(const Instruction *II) : _Base(II) {}
|
||||
ImmutableCallSite(const Value* V) : Base(V) {}
|
||||
ImmutableCallSite(const CallInst *CI) : Base(CI) {}
|
||||
ImmutableCallSite(const InvokeInst *II) : Base(II) {}
|
||||
ImmutableCallSite(const Instruction *II) : Base(II) {}
|
||||
};
|
||||
|
||||
class CallSite : public CallSiteBase<Function, Value, User, Instruction,
|
||||
CallInst, InvokeInst, User::op_iterator> {
|
||||
typedef CallSiteBase<Function, Value, User, Instruction,
|
||||
CallInst, InvokeInst, User::op_iterator> _Base;
|
||||
CallInst, InvokeInst, User::op_iterator> Base;
|
||||
public:
|
||||
CallSite() {}
|
||||
CallSite(_Base B) : _Base(B) {}
|
||||
CallSite(CallInst *CI) : _Base(CI) {}
|
||||
CallSite(InvokeInst *II) : _Base(II) {}
|
||||
CallSite(Instruction *II) : _Base(II) {}
|
||||
CallSite(Base B) : Base(B) {}
|
||||
CallSite(CallInst *CI) : Base(CI) {}
|
||||
CallSite(InvokeInst *II) : Base(II) {}
|
||||
CallSite(Instruction *II) : Base(II) {}
|
||||
|
||||
bool operator==(const CallSite &CS) const { return I == CS.I; }
|
||||
bool operator!=(const CallSite &CS) const { return I != CS.I; }
|
||||
@ -207,57 +309,9 @@ class CallSite : public CallSiteBase<Function, Value, User, Instruction,
|
||||
/// NOT a call site.
|
||||
///
|
||||
static CallSite get(Value *V) {
|
||||
return _Base::get(V);
|
||||
return Base::get(V);
|
||||
}
|
||||
|
||||
/// getCallingConv/setCallingConv - get or set the calling convention of the
|
||||
/// call.
|
||||
CallingConv::ID getCallingConv() const;
|
||||
void setCallingConv(CallingConv::ID CC);
|
||||
|
||||
/// getAttributes/setAttributes - get or set the parameter attributes of
|
||||
/// the call.
|
||||
const AttrListPtr &getAttributes() const;
|
||||
void setAttributes(const AttrListPtr &PAL);
|
||||
|
||||
/// paramHasAttr - whether the call or the callee has the given attribute.
|
||||
bool paramHasAttr(uint16_t i, Attributes attr) const;
|
||||
|
||||
/// @brief Extract the alignment for a call or parameter (0=unknown).
|
||||
uint16_t getParamAlignment(uint16_t i) const;
|
||||
|
||||
/// @brief Return true if the call should not be inlined.
|
||||
bool isNoInline() const;
|
||||
void setIsNoInline(bool Value = true);
|
||||
|
||||
/// @brief Determine if the call does not access memory.
|
||||
bool doesNotAccessMemory() const;
|
||||
void setDoesNotAccessMemory(bool doesNotAccessMemory = true);
|
||||
|
||||
/// @brief Determine if the call does not access or only reads memory.
|
||||
bool onlyReadsMemory() const;
|
||||
void setOnlyReadsMemory(bool onlyReadsMemory = true);
|
||||
|
||||
/// @brief Determine if the call cannot return.
|
||||
bool doesNotReturn() const;
|
||||
void setDoesNotReturn(bool doesNotReturn = true);
|
||||
|
||||
/// @brief Determine if the call cannot unwind.
|
||||
bool doesNotThrow() const;
|
||||
void setDoesNotThrow(bool doesNotThrow = true);
|
||||
|
||||
/// getType - Return the type of the instruction that generated this call site
|
||||
///
|
||||
const Type *getType() const { return (*this)->getType(); }
|
||||
|
||||
/// getCaller - Return the caller function for this call site
|
||||
///
|
||||
Function *getCaller() const { return (*this)->getParent()->getParent(); }
|
||||
|
||||
/// hasArgument - Returns true if this CallSite passes the given Value* as an
|
||||
/// argument to the called function.
|
||||
bool hasArgument(const Value *Arg) const;
|
||||
|
||||
bool operator<(const CallSite &CS) const {
|
||||
return getInstruction() < CS.getInstruction();
|
||||
}
|
||||
|
@ -230,6 +230,7 @@ enum dwarf_constants {
|
||||
DW_AT_APPLE_block = 0x3fe4,
|
||||
DW_AT_APPLE_major_runtime_vers = 0x3fe5,
|
||||
DW_AT_APPLE_runtime_class = 0x3fe6,
|
||||
DW_AT_APPLE_omit_frame_ptr = 0x3fe7,
|
||||
|
||||
// Attribute form encodings
|
||||
DW_FORM_addr = 0x01,
|
||||
|
@ -99,6 +99,12 @@ enum {
|
||||
ET_HIPROC = 0xffff // Processor-specific
|
||||
};
|
||||
|
||||
// Versioning
|
||||
enum {
|
||||
EV_NONE = 0,
|
||||
EV_CURRENT = 1
|
||||
};
|
||||
|
||||
// Machine architectures
|
||||
enum {
|
||||
EM_NONE = 0, // No machine
|
||||
@ -129,6 +135,11 @@ enum {
|
||||
ELFDATA2MSB = 2 // Big-endian object file
|
||||
};
|
||||
|
||||
// OS ABI identification -- unused.
|
||||
enum {
|
||||
ELFOSABI_NONE = 0
|
||||
};
|
||||
|
||||
// Section header.
|
||||
struct Elf32_Shdr {
|
||||
Elf32_Word sh_name; // Section name (index into string table)
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===- llvm/Support/ErrorHandling.h - Callbacks for errors ------*- C++ -*-===//
|
||||
//===- llvm/Support/ErrorHandling.h - Fatal error handling ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,8 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines an API used to indicate error conditions.
|
||||
// Callbacks can be registered for these errors through this API.
|
||||
// This file defines an API used to indicate fatal error conditions. Non-fatal
|
||||
// errors (most of them) should be handled through LLVMContext.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -22,10 +22,10 @@ namespace llvm {
|
||||
class Twine;
|
||||
|
||||
/// An error handler callback.
|
||||
typedef void (*llvm_error_handler_t)(void *user_data,
|
||||
const std::string& reason);
|
||||
typedef void (*fatal_error_handler_t)(void *user_data,
|
||||
const std::string& reason);
|
||||
|
||||
/// llvm_instal_error_handler - Installs a new error handler to be used
|
||||
/// install_fatal_error_handler - Installs a new error handler to be used
|
||||
/// whenever a serious (non-recoverable) error is encountered by LLVM.
|
||||
///
|
||||
/// If you are using llvm_start_multithreaded, you should register the handler
|
||||
@ -44,13 +44,13 @@ namespace llvm {
|
||||
///
|
||||
/// \param user_data - An argument which will be passed to the install error
|
||||
/// handler.
|
||||
void llvm_install_error_handler(llvm_error_handler_t handler,
|
||||
void *user_data = 0);
|
||||
void install_fatal_error_handler(fatal_error_handler_t handler,
|
||||
void *user_data = 0);
|
||||
|
||||
/// Restores default error handling behaviour.
|
||||
/// This must not be called between llvm_start_multithreaded() and
|
||||
/// llvm_stop_multithreaded().
|
||||
void llvm_remove_error_handler();
|
||||
void remove_fatal_error_handler();
|
||||
|
||||
/// Reports a serious error, calling any installed error handler. These
|
||||
/// functions are intended to be used for error conditions which are outside
|
||||
@ -60,9 +60,9 @@ namespace llvm {
|
||||
/// standard error, followed by a newline.
|
||||
/// After the error handler is called this function will call exit(1), it
|
||||
/// does not return.
|
||||
NORETURN void llvm_report_error(const char *reason);
|
||||
NORETURN void llvm_report_error(const std::string &reason);
|
||||
NORETURN void llvm_report_error(const Twine &reason);
|
||||
NORETURN void report_fatal_error(const char *reason);
|
||||
NORETURN void report_fatal_error(const std::string &reason);
|
||||
NORETURN void report_fatal_error(const Twine &reason);
|
||||
|
||||
/// This function calls abort(), and prints the optional message to stderr.
|
||||
/// Use the llvm_unreachable macro (that adds location info), instead of
|
||||
|
@ -174,7 +174,8 @@ class GraphWriter {
|
||||
unsigned i = 0, e = DTraits.numEdgeDestLabels(Node);
|
||||
for (; i != e && i != 64; ++i) {
|
||||
if (i) O << "|";
|
||||
O << "<d" << i << ">" << DTraits.getEdgeDestLabel(Node, i);
|
||||
O << "<d" << i << ">"
|
||||
<< DOT::EscapeString(DTraits.getEdgeDestLabel(Node, i));
|
||||
}
|
||||
|
||||
if (i != e)
|
||||
@ -230,7 +231,7 @@ class GraphWriter {
|
||||
for (unsigned i = 0; i != NumEdgeSources; ++i) {
|
||||
if (i) O << "|";
|
||||
O << "<s" << i << ">";
|
||||
if (EdgeSourceLabels) O << (*EdgeSourceLabels)[i];
|
||||
if (EdgeSourceLabels) O << DOT::EscapeString((*EdgeSourceLabels)[i]);
|
||||
}
|
||||
O << "}}";
|
||||
}
|
||||
|
@ -432,12 +432,19 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
return Folder.CreateFRem(LC, RC);
|
||||
return Insert(BinaryOperator::CreateFRem(LHS, RHS), Name);
|
||||
}
|
||||
|
||||
Value *CreateShl(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS))
|
||||
return Folder.CreateShl(LC, RC);
|
||||
return Insert(BinaryOperator::CreateShl(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateShl(Value *LHS, const APInt &RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateShl(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateShl(LHS, RHSC), Name);
|
||||
}
|
||||
Value *CreateShl(Value *LHS, uint64_t RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
@ -451,23 +458,35 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
return Folder.CreateLShr(LC, RC);
|
||||
return Insert(BinaryOperator::CreateLShr(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateLShr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateLShr(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
|
||||
}
|
||||
Value *CreateLShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateLShr(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateLShr(LHS, RHSC), Name);
|
||||
}
|
||||
|
||||
|
||||
Value *CreateAShr(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS))
|
||||
return Folder.CreateAShr(LC, RC);
|
||||
return Insert(BinaryOperator::CreateAShr(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateAShr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateAShr(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
|
||||
}
|
||||
Value *CreateAShr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateSShr(LC, RHSC);
|
||||
return Folder.CreateAShr(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateAShr(LHS, RHSC), Name);
|
||||
}
|
||||
|
||||
@ -480,6 +499,19 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
}
|
||||
return Insert(BinaryOperator::CreateAnd(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateAnd(Value *LHS, const APInt &RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateAnd(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name);
|
||||
}
|
||||
Value *CreateAnd(Value *LHS, uint64_t RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateAnd(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateAnd(LHS, RHSC), Name);
|
||||
}
|
||||
|
||||
Value *CreateOr(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS)) {
|
||||
if (RC->isNullValue())
|
||||
@ -489,12 +521,37 @@ class IRBuilder : public IRBuilderBase, public Inserter {
|
||||
}
|
||||
return Insert(BinaryOperator::CreateOr(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateOr(Value *LHS, const APInt &RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateOr(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name);
|
||||
}
|
||||
Value *CreateOr(Value *LHS, uint64_t RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateOr(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateOr(LHS, RHSC), Name);
|
||||
}
|
||||
|
||||
Value *CreateXor(Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
if (Constant *RC = dyn_cast<Constant>(RHS))
|
||||
return Folder.CreateXor(LC, RC);
|
||||
return Insert(BinaryOperator::CreateXor(LHS, RHS), Name);
|
||||
}
|
||||
Value *CreateXor(Value *LHS, const APInt &RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateXor(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name);
|
||||
}
|
||||
Value *CreateXor(Value *LHS, uint64_t RHS, const Twine &Name = "") {
|
||||
Constant *RHSC = ConstantInt::get(LHS->getType(), RHS);
|
||||
if (Constant *LC = dyn_cast<Constant>(LHS))
|
||||
return Folder.CreateXor(LC, RHSC);
|
||||
return Insert(BinaryOperator::CreateXor(LHS, RHSC), Name);
|
||||
}
|
||||
|
||||
Value *CreateBinOp(Instruction::BinaryOps Opc,
|
||||
Value *LHS, Value *RHS, const Twine &Name = "") {
|
||||
|
@ -38,8 +38,7 @@ namespace llvm {
|
||||
std::string ErrMsg;
|
||||
Module *M = getLazyBitcodeModule(Buffer, Context, &ErrMsg);
|
||||
if (M == 0) {
|
||||
Err = SMDiagnostic(SMLoc(), Buffer->getBufferIdentifier(), -1, -1,
|
||||
ErrMsg, "");
|
||||
Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg);
|
||||
// ParseBitcodeFile does not take ownership of the Buffer in the
|
||||
// case of an error.
|
||||
delete Buffer;
|
||||
@ -60,8 +59,8 @@ namespace llvm {
|
||||
std::string ErrMsg;
|
||||
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
|
||||
if (F == 0) {
|
||||
Err = SMDiagnostic(SMLoc(), Filename, -1, -1,
|
||||
"Could not open input file '" + Filename + "'", "");
|
||||
Err = SMDiagnostic(Filename,
|
||||
"Could not open input file '" + Filename + "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -82,8 +81,7 @@ namespace llvm {
|
||||
// ParseBitcodeFile does not take ownership of the Buffer.
|
||||
delete Buffer;
|
||||
if (M == 0)
|
||||
Err = SMDiagnostic(SMLoc(), Buffer->getBufferIdentifier(),
|
||||
-1, -1, ErrMsg, "");
|
||||
Err = SMDiagnostic(Buffer->getBufferIdentifier(), ErrMsg);
|
||||
return M;
|
||||
}
|
||||
|
||||
@ -99,8 +97,8 @@ namespace llvm {
|
||||
std::string ErrMsg;
|
||||
MemoryBuffer *F = MemoryBuffer::getFileOrSTDIN(Filename.c_str(), &ErrMsg);
|
||||
if (F == 0) {
|
||||
Err = SMDiagnostic(SMLoc(), Filename, -1, -1,
|
||||
"Could not open input file '" + Filename + "'", "");
|
||||
Err = SMDiagnostic(Filename,
|
||||
"Could not open input file '" + Filename + "'");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -63,4 +63,11 @@ inline void *operator new(size_t,
|
||||
return Allocator.Allocate();
|
||||
}
|
||||
|
||||
template<class AllocatorType, class T, size_t Size, size_t Align>
|
||||
inline void operator delete(void *E,
|
||||
llvm::RecyclingAllocator<AllocatorType,
|
||||
T, Size, Align> &A) {
|
||||
A.Deallocate(E);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -148,6 +148,7 @@ class SourceMgr {
|
||||
/// SMDiagnostic - Instances of this class encapsulate one diagnostic report,
|
||||
/// allowing printing to a raw_ostream as a caret diagnostic.
|
||||
class SMDiagnostic {
|
||||
const SourceMgr *SM;
|
||||
SMLoc Loc;
|
||||
std::string Filename;
|
||||
int LineNo, ColumnNo;
|
||||
@ -155,15 +156,25 @@ class SMDiagnostic {
|
||||
unsigned ShowLine : 1;
|
||||
|
||||
public:
|
||||
SMDiagnostic() : LineNo(0), ColumnNo(0), ShowLine(0) {}
|
||||
SMDiagnostic(SMLoc L, const std::string &FN, int Line, int Col,
|
||||
// Null diagnostic.
|
||||
SMDiagnostic() : SM(0), LineNo(0), ColumnNo(0), ShowLine(0) {}
|
||||
// Diagnostic with no location (e.g. file not found, command line arg error).
|
||||
SMDiagnostic(const std::string &filename, const std::string &Msg,
|
||||
bool showline = true)
|
||||
: SM(0), Loc(), Filename(filename), LineNo(-1), ColumnNo(-1),
|
||||
Message(Msg), LineContents(""), ShowLine(showline) {}
|
||||
|
||||
// Diagnostic with a location.
|
||||
SMDiagnostic(const SourceMgr &sm, SMLoc L, const std::string &FN,
|
||||
int Line, int Col,
|
||||
const std::string &Msg, const std::string &LineStr,
|
||||
bool showline = true)
|
||||
: Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
|
||||
: SM(&sm), Loc(L), Filename(FN), LineNo(Line), ColumnNo(Col), Message(Msg),
|
||||
LineContents(LineStr), ShowLine(showline) {}
|
||||
|
||||
const SourceMgr *getSourceMgr() const { return SM; }
|
||||
SMLoc getLoc() const { return Loc; }
|
||||
const std::string getFilename() { return Filename; }
|
||||
const std::string &getFilename() { return Filename; }
|
||||
int getLineNo() const { return LineNo; }
|
||||
int getColumnNo() const { return ColumnNo; }
|
||||
const std::string &getMessage() const { return Message; }
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user