From 9fc809e980d70b713a4650a167b3f8d57c2166a9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 05:10:16 +0000 Subject: [PATCH 001/682] Make tblgen more portable, allowing it to build with ICC. Patch by Robert Zeh! llvm-svn: 62750 --- llvm/utils/TableGen/TGParser.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/utils/TableGen/TGParser.h b/llvm/utils/TableGen/TGParser.h index a5435afacf29..fd33aec0fb32 100644 --- a/llvm/utils/TableGen/TGParser.h +++ b/llvm/utils/TableGen/TGParser.h @@ -20,8 +20,8 @@ namespace llvm { class Record; class RecordVal; - class RecTy; - class Init; + struct RecTy; + struct Init; struct MultiClass; struct SubClassReference; -- GitLab From c4b1d8295d8cb2593c3b853a183bc8354789976b Mon Sep 17 00:00:00 2001 From: Tanya Lattner Date: Thu, 22 Jan 2009 05:17:59 +0000 Subject: [PATCH 002/682] Bump to 2.6svn. Regenerate configure (last regen was with the wrong version). llvm-svn: 62751 --- llvm/autoconf/configure.ac | 2 +- llvm/configure | 4792 +++++++++++++++++++------- llvm/include/llvm/Config/config.h.in | 6 + 3 files changed, 3577 insertions(+), 1223 deletions(-) diff --git a/llvm/autoconf/configure.ac b/llvm/autoconf/configure.ac index b9585def2cb9..5d551a70699d 100644 --- a/llvm/autoconf/configure.ac +++ b/llvm/autoconf/configure.ac @@ -31,7 +31,7 @@ dnl=== dnl===-----------------------------------------------------------------------=== dnl Initialize autoconf and define the package name, version number and dnl email address for reporting bugs. -AC_INIT([[llvm]],[[2.5svn]],[llvmbugs@cs.uiuc.edu]) +AC_INIT([[llvm]],[[2.6svn]],[llvmbugs@cs.uiuc.edu]) dnl Provide a copyright substitution and ensure the copyright notice is included dnl in the output of --version option of the generated configure script. diff --git a/llvm/configure b/llvm/configure index 517fe93ce23b..2ee80e749723 100755 --- a/llvm/configure +++ b/llvm/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.61 for llvm 2.5svn. +# Generated by GNU Autoconf 2.60 for llvm 2.6svn. # # Report bugs to . # @@ -14,8 +14,7 @@ ## M4sh Initialization. ## ## --------------------- ## -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh +# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -24,13 +23,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi - - +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR @@ -223,7 +219,7 @@ test \$exitcode = 0) || { (exit 1); exit 1; } else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +for as_dir in /usr/bin/posix$PATH_SEPARATOR/bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. @@ -241,6 +237,7 @@ IFS=$as_save_IFS # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF +# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -249,12 +246,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi - +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh : _ASEOF @@ -262,6 +257,7 @@ _ASEOF CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF +# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -270,12 +266,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi - +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh : (as_func_return () { @@ -522,28 +516,19 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' + as_executable_p=: fi -as_executable_p=$as_test_x +rm -f conf$$.file # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -730,44 +715,44 @@ SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME='llvm' PACKAGE_TARNAME='-llvm-' -PACKAGE_VERSION='2.5svn' -PACKAGE_STRING='llvm 2.5svn' +PACKAGE_VERSION='2.6svn' +PACKAGE_STRING='llvm 2.6svn' PACKAGE_BUGREPORT='llvmbugs@cs.uiuc.edu' ac_unique_file="lib/VMCore/Module.cpp" # Factoring default headers for most tests. ac_includes_default="\ #include -#ifdef HAVE_SYS_TYPES_H +#if HAVE_SYS_TYPES_H # include #endif -#ifdef HAVE_SYS_STAT_H +#if HAVE_SYS_STAT_H # include #endif -#ifdef STDC_HEADERS +#if STDC_HEADERS # include # include #else -# ifdef HAVE_STDLIB_H +# if HAVE_STDLIB_H # include # endif #endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H +#if HAVE_STRING_H +# if !STDC_HEADERS && HAVE_MEMORY_H # include # endif # include #endif -#ifdef HAVE_STRINGS_H +#if HAVE_STRINGS_H # include #endif -#ifdef HAVE_INTTYPES_H +#if HAVE_INTTYPES_H # include #endif -#ifdef HAVE_STDINT_H +#if HAVE_STDINT_H # include #endif -#ifdef HAVE_UNISTD_H +#if HAVE_UNISTD_H # include #endif" @@ -861,8 +846,8 @@ CXX CXXFLAGS ac_ct_CXX LEX -LEX_OUTPUT_ROOT LEXLIB +LEX_OUTPUT_ROOT FLEX YACC YFLAGS @@ -955,7 +940,6 @@ target_alias CC CFLAGS LDFLAGS -LIBS CPPFLAGS CPP CXX @@ -1082,10 +1066,10 @@ do -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) @@ -1101,10 +1085,10 @@ do -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } - ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + ac_feature=`echo $ac_feature | sed 's/-/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ @@ -1298,19 +1282,19 @@ do -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + ac_package=`echo $ac_package| sed 's/-/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. - expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } - ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + ac_package=`echo $ac_package | sed 's/-/_/g'` eval with_$ac_package=no ;; --x) @@ -1479,7 +1463,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures llvm 2.5svn to adapt to many kinds of systems. +\`configure' configures llvm 2.6svn to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1545,7 +1529,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of llvm 2.5svn:";; + short | recursive ) echo "Configuration of llvm 2.6svn:";; esac cat <<\_ACEOF @@ -1602,7 +1586,6 @@ Some influential environment variables: CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory - LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor @@ -1681,8 +1664,8 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -llvm configure 2.5svn -generated by GNU Autoconf 2.61 +llvm configure 2.6svn +generated by GNU Autoconf 2.60 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. @@ -1697,8 +1680,8 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by llvm $as_me 2.5svn, which was -generated by GNU Autoconf 2.61. Invocation command line was +It was created by llvm $as_me 2.6svn, which was +generated by GNU Autoconf 2.60. Invocation command line was $ $0 $@ @@ -2443,7 +2426,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2483,7 +2466,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2540,7 +2523,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2581,7 +2564,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -2639,7 +2622,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2683,7 +2666,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -2824,7 +2807,7 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. -for ac_file in $ac_files '' +for ac_file in $ac_files do test -f "$ac_file" || continue case $ac_file in @@ -2852,12 +2835,6 @@ done test "$ac_cv_exeext" = no && ac_cv_exeext= else - ac_file='' -fi - -{ echo "$as_me:$LINENO: result: $ac_file" >&5 -echo "${ECHO_T}$ac_file" >&6; } -if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 @@ -2869,6 +2846,8 @@ See \`config.log' for more details." >&2;} fi ac_exeext=$ac_cv_exeext +{ echo "$as_me:$LINENO: result: $ac_file" >&5 +echo "${ECHO_T}$ac_file" >&6; } # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. @@ -3046,10 +3025,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -3104,10 +3100,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -3142,10 +3155,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 : else echo "$as_me: failed program was:" >&5 @@ -3181,10 +3211,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -3300,10 +3347,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 @@ -3393,10 +3457,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 @@ -3430,10 +3501,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else @@ -3498,10 +3576,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 @@ -3535,10 +3620,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else @@ -3593,7 +3685,7 @@ do for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue + { test -f "$ac_path_GREP" && $as_executable_p "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in @@ -3675,7 +3767,7 @@ do for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue + { test -f "$ac_path_EGREP" && $as_executable_p "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in @@ -3771,10 +3863,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 @@ -3950,10 +4059,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -3995,8 +4121,7 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -#if ! (defined BYTE_ORDER && defined BIG_ENDIAN && defined LITTLE_ENDIAN \ - && BYTE_ORDER && BIG_ENDIAN && LITTLE_ENDIAN) +#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN bogus endian macros #endif @@ -4017,10 +4142,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 # It does; now see whether it defined to BIG_ENDIAN or not. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ @@ -4055,10 +4197,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_c_bigendian=yes else echo "$as_me: failed program was:" >&5 @@ -4109,10 +4268,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then ac_cv_c_bigendian=yes fi @@ -4242,7 +4418,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="${ac_build_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4280,7 +4456,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4319,7 +4495,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue @@ -4409,7 +4585,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CXX="${ac_build_prefix}g++" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4447,7 +4623,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_BUILD_CXX="g++" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -4486,7 +4662,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/c++"; then ac_prog_rejected=yes continue @@ -4939,10 +5115,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 @@ -4976,10 +5159,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else @@ -5044,10 +5234,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 @@ -5081,10 +5278,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else @@ -5141,7 +5345,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5185,7 +5389,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5303,10 +5507,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -5361,10 +5582,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -5399,10 +5637,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 : else echo "$as_me: failed program was:" >&5 @@ -5438,10 +5693,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 @@ -5557,10 +5829,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 @@ -5625,7 +5914,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CXX="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5669,7 +5958,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CXX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -5782,10 +6071,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -5840,10 +6146,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 @@ -5878,10 +6201,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 : else echo "$as_me: failed program was:" >&5 @@ -5917,10 +6257,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_prog_cxx_g=yes else echo "$as_me: failed program was:" >&5 @@ -5984,7 +6341,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_LEX="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6009,69 +6366,116 @@ fi done test -n "$LEX" || LEX=":" -if test "x$LEX" != "x:"; then - cat >conftest.l <<_ACEOF -%% -a { ECHO; } -b { REJECT; } -c { yymore (); } -d { yyless (1); } -e { yyless (input () != 0); } -f { unput (yytext[0]); } -. { BEGIN INITIAL; } -%% -#ifdef YYTEXT_POINTER -extern char *yytext; +if test -z "$LEXLIB" +then + { echo "$as_me:$LINENO: checking for yywrap in -lfl" >&5 +echo $ECHO_N "checking for yywrap in -lfl... $ECHO_C" >&6; } +if test "${ac_cv_lib_fl_yywrap+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lfl $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" #endif +char yywrap (); int -main (void) +main () { - return ! yylex () + ! yywrap (); +return yywrap (); + ; + return 0; } _ACEOF -{ (ac_try="$LEX conftest.l" +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 "$LEX conftest.l") 2>&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); } -{ echo "$as_me:$LINENO: checking lex output file root" >&5 -echo $ECHO_N "checking lex output file root... $ECHO_C" >&6; } -if test "${ac_cv_prog_lex_root+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 + (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 + ac_cv_lib_fl_yywrap=yes else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 -if test -f lex.yy.c; then - ac_cv_prog_lex_root=lex.yy -elif test -f lexyy.c; then - ac_cv_prog_lex_root=lexyy -else - { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 -echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} - { (exit 1); exit 1; }; } -fi + ac_cv_lib_fl_yywrap=no fi -{ echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 -echo "${ECHO_T}$ac_cv_prog_lex_root" >&6; } -LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root -if test -z "${LEXLIB+set}"; then - { echo "$as_me:$LINENO: checking lex library" >&5 -echo $ECHO_N "checking lex library... $ECHO_C" >&6; } -if test "${ac_cv_lib_lex+set}" = set; then +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_fl_yywrap" >&5 +echo "${ECHO_T}$ac_cv_lib_fl_yywrap" >&6; } +if test $ac_cv_lib_fl_yywrap = yes; then + LEXLIB="-lfl" +else + { echo "$as_me:$LINENO: checking for yywrap in -ll" >&5 +echo $ECHO_N "checking for yywrap in -ll... $ECHO_C" >&6; } +if test "${ac_cv_lib_l_yywrap+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else + ac_check_lib_save_LIBS=$LIBS +LIBS="-ll $LIBS" +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ - ac_save_LIBS=$LIBS - ac_cv_lib_lex='none needed' - for ac_lib in '' -lfl -ll; do - LIBS="$ac_lib $ac_save_LIBS" - cat >conftest.$ac_ext <<_ACEOF -`cat $LEX_OUTPUT_ROOT.c` +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char yywrap (); +int +main () +{ +return yywrap (); + ; + return 0; +} _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" @@ -6086,31 +6490,85 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - ac_cv_lib_lex=$ac_lib + (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 + ac_cv_lib_l_yywrap=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 - + ac_cv_lib_l_yywrap=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext - test "$ac_cv_lib_lex" != 'none needed' && break - done - LIBS=$ac_save_LIBS +LIBS=$ac_check_lib_save_LIBS +fi +{ echo "$as_me:$LINENO: result: $ac_cv_lib_l_yywrap" >&5 +echo "${ECHO_T}$ac_cv_lib_l_yywrap" >&6; } +if test $ac_cv_lib_l_yywrap = yes; then + LEXLIB="-ll" +fi fi -{ echo "$as_me:$LINENO: result: $ac_cv_lib_lex" >&5 -echo "${ECHO_T}$ac_cv_lib_lex" >&6; } - test "$ac_cv_lib_lex" != 'none needed' && LEXLIB=$ac_cv_lib_lex + fi +if test "x$LEX" != "x:"; then + { echo "$as_me:$LINENO: checking lex output file root" >&5 +echo $ECHO_N "checking lex output file root... $ECHO_C" >&6; } +if test "${ac_cv_prog_lex_root+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + # The minimal lex program is just a single line: %%. But some broken lexes +# (Solaris, I think it was) want two %% lines, so accommodate them. +cat >conftest.l <<_ACEOF +%% +%% +_ACEOF +{ (ac_try="$LEX conftest.l" +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 "$LEX conftest.l") 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } +if test -f lex.yy.c; then + ac_cv_prog_lex_root=lex.yy +elif test -f lexyy.c; then + ac_cv_prog_lex_root=lexyy +else + { { echo "$as_me:$LINENO: error: cannot find output from $LEX; giving up" >&5 +echo "$as_me: error: cannot find output from $LEX; giving up" >&2;} + { (exit 1); exit 1; }; } +fi +fi +{ echo "$as_me:$LINENO: result: $ac_cv_prog_lex_root" >&5 +echo "${ECHO_T}$ac_cv_prog_lex_root" >&6; } +rm -f conftest.l +LEX_OUTPUT_ROOT=$ac_cv_prog_lex_root { echo "$as_me:$LINENO: checking whether yytext is a pointer" >&5 echo $ECHO_N "checking whether yytext is a pointer... $ECHO_C" >&6; } @@ -6118,13 +6576,13 @@ if test "${ac_cv_prog_lex_yytext_pointer+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # POSIX says lex can declare yytext either as a pointer or an array; the -# default is implementation-dependent. Figure out which it is, since +# default is implementation-dependent. Figure out which it is, since # not all implementations provide the %pointer and %array declarations. ac_cv_prog_lex_yytext_pointer=no +echo 'extern char *yytext;' >>$LEX_OUTPUT_ROOT.c ac_save_LIBS=$LIBS -LIBS="$LEXLIB $ac_save_LIBS" +LIBS="$LIBS $LEXLIB" cat >conftest.$ac_ext <<_ACEOF -#define YYTEXT_POINTER 1 `cat $LEX_OUTPUT_ROOT.c` _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext @@ -6140,11 +6598,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_prog_lex_yytext_pointer=yes else echo "$as_me: failed program was:" >&5 @@ -6153,9 +6627,10 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_save_LIBS +rm -f "${LEX_OUTPUT_ROOT}.c" fi { echo "$as_me:$LINENO: result: $ac_cv_prog_lex_yytext_pointer" >&5 @@ -6167,7 +6642,6 @@ cat >>confdefs.h <<\_ACEOF _ACEOF fi -rm -f conftest.l $LEX_OUTPUT_ROOT.c fi @@ -6206,7 +6680,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_YACC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6353,7 +6827,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CMP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6394,7 +6868,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_CP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6435,7 +6909,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DATE="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6476,7 +6950,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_FIND="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6517,7 +6991,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GREP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6558,7 +7032,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MKDIR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6599,7 +7073,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_MV="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6639,7 +7113,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6679,7 +7153,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6736,7 +7210,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RM="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6777,7 +7251,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6818,7 +7292,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TAR="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6859,7 +7333,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_BINPWD="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6901,7 +7375,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GRAPHVIZ="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -6957,7 +7431,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7015,7 +7489,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GV="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7074,7 +7548,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOTTY="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7132,7 +7606,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7216,7 +7690,7 @@ case $as_dir/ in # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. @@ -7279,7 +7753,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_BZIP2="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7319,7 +7793,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_DOXYGEN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7359,7 +7833,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GROFF="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7399,7 +7873,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7439,7 +7913,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_POD2HTML="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7479,7 +7953,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_POD2MAN="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7519,7 +7993,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_RUNTEST="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7592,7 +8066,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_TCLSH="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7649,7 +8123,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_ZIP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7691,7 +8165,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7736,7 +8210,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLOPT="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7781,7 +8255,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLDEP="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7826,7 +8300,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_OCAMLDOC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7871,7 +8345,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_GAS="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -7938,11 +8412,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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_r=yes else echo "$as_me: failed program was:" >&5 @@ -7951,7 +8441,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 llvm_cv_link_use_r=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext CFLAGS="$oldcflags" ac_ext=c @@ -7994,10 +8484,10 @@ main () #ifndef __cplusplus /* Ultrix mips cc rejects this. */ typedef int charset[2]; - const charset cs; + const charset x; /* SunOS 4.1.1 cc rejects this. */ - char const *const *pcpcc; - char **ppc; + char const *const *ccp; + char **p; /* NEC SVR4.0.2 mips cc rejects this. */ struct point {int x, y;}; static struct point const zero = {0,0}; @@ -8006,11 +8496,11 @@ main () an arm of an if-expression whose if-part is not a constant expression */ const char *g = "string"; - pcpcc = &g + (g ? g-g : 0); + ccp = &g + (g ? g-g : 0); /* HPUX 7.0 cc rejects these. */ - ++pcpcc; - ppc = (char**) pcpcc; - pcpcc = (char const *const *) ppc; + ++ccp; + p = (char**) ccp; + ccp = (char const *const *) p; { /* SCO 3.2v4 cc rejects this. */ char *t; char const *s = 0 ? (char *) 0 : (char const *) 0; @@ -8037,7 +8527,7 @@ main () const int foo = 10; if (!foo) return 0; } - return !cs[0] && !zero.x; + return !x[0] && !zero.x; #endif ; @@ -8057,10 +8547,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_c_const=yes else echo "$as_me: failed program was:" >&5 @@ -8125,10 +8632,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -8201,11 +8725,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -8214,7 +8754,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -8285,11 +8825,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -8298,7 +8854,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -8361,10 +8917,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -8400,10 +8973,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -9497,11 +10077,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -9510,7 +10106,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 @@ -9564,11 +10160,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -9577,7 +10189,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -9633,11 +10245,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -9646,7 +10274,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -9691,11 +10319,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 cat >>confdefs.h <<\_ACEOF #define HAVE_LIBDL 1 @@ -9747,11 +10391,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -9760,7 +10420,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -9816,11 +10476,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 @@ -9829,7 +10505,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -9906,11 +10582,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_func__dyld_func_lookup=yes else echo "$as_me: failed program was:" >&5 @@ -9919,7 +10611,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func__dyld_func_lookup=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func__dyld_func_lookup" >&5 @@ -9941,7 +10633,7 @@ fi fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi @@ -10024,11 +10716,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -10037,7 +10745,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -10124,7 +10832,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -10392,10 +11117,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -10500,10 +11232,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_error_t=yes else echo "$as_me: failed program was:" >&5 @@ -10603,11 +11352,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -10616,7 +11381,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -10696,10 +11461,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -10735,10 +11517,189 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then + ac_header_preproc=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_preproc=no +fi + +rm -f conftest.err conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 +echo "${ECHO_T}$ac_header_preproc" >&6; } + +# So? What about this header? +case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in + yes:no: ) + { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 +echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} + ac_header_preproc=yes + ;; + no:yes:* ) + { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 +echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 +echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 +echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 +echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 +echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} + { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 +echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} + ( cat <<\_ASBOX +## ----------------------------------- ## +## Report this to llvmbugs@cs.uiuc.edu ## +## ----------------------------------- ## +_ASBOX + ) | sed "s/^/$as_me: WARNING: /" >&2 + ;; +esac +{ echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + eval "$as_ac_Header=\$ac_header_preproc" +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } + +fi +if test `eval echo '${'$as_ac_Header'}'` = yes; then + cat >>confdefs.h <<_ACEOF +#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 +_ACEOF + +fi + +done + + + + + +for ac_header in dl.h sys/dl.h dld.h mach-o/dyld.h +do +as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + { echo "$as_me:$LINENO: checking for $ac_header" >&5 +echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } +if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +fi +ac_res=`eval echo '${'$as_ac_Header'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +else + # Is the header compilable? +{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 +echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +$ac_includes_default +#include <$ac_header> +_ACEOF +rm -f conftest.$ac_objext +if { (ac_try="$ac_compile" +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_compile") 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_objext' + { (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 + ac_header_compiler=yes +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + ac_header_compiler=no +fi + +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext +{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 +echo "${ECHO_T}$ac_header_compiler" >&6; } + +# Is the header present? +{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 +echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } +cat >conftest.$ac_ext <<_ACEOF +/* confdefs.h. */ +_ACEOF +cat confdefs.h >>conftest.$ac_ext +cat >>conftest.$ac_ext <<_ACEOF +/* end confdefs.h. */ +#include <$ac_header> +_ACEOF +if { (ac_try="$ac_cpp conftest.$ac_ext" +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_cpp conftest.$ac_ext") 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); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -10804,9 +11765,7 @@ done - - -for ac_header in dl.h sys/dl.h dld.h mach-o/dyld.h +for ac_header in string.h strings.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then @@ -10844,156 +11803,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking $ac_header presence" >&5 -echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include <$ac_header> -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in + (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_cpp conftest.$ac_ext") 2>conftest.er1 + (eval "$ac_try") 2>&5 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); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5 -echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## ----------------------------------- ## -## Report this to llvmbugs@cs.uiuc.edu ## -## ----------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - eval "$as_ac_Header=\$ac_header_preproc" -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } - -fi -if test `eval echo '${'$as_ac_Header'}'` = yes; then - cat >>confdefs.h <<_ACEOF -#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - - -for ac_header in string.h strings.h -do -as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - { echo "$as_me:$LINENO: checking for $ac_header" >&5 -echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } -if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -ac_res=`eval echo '${'$as_ac_Header'}'` - { echo "$as_me:$LINENO: result: $ac_res" >&5 -echo "${ECHO_T}$ac_res" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking $ac_header usability" >&5 -echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include <$ac_header> -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -case "(($ac_try" in + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (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_compile") 2>conftest.er1 + (eval "$ac_try") 2>&5 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); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); }; }; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -11029,10 +11859,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -11165,11 +12002,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11178,7 +12031,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11260,11 +12113,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11273,7 +12142,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11355,11 +12224,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11368,7 +12253,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11450,11 +12335,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11463,7 +12364,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -11546,11 +12447,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -11559,7 +12476,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -12059,7 +12976,7 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 12062 "configure"' > conftest.$ac_ext + echo '#line 12979 "configure"' > conftest.$ac_ext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? @@ -12183,11 +13100,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 lt_cv_cc_needs_belf=yes else echo "$as_me: failed program was:" >&5 @@ -12196,7 +13129,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 lt_cv_cc_needs_belf=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' @@ -12291,10 +13224,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 @@ -12328,10 +13268,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else @@ -12396,10 +13343,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then : else echo "$as_me: failed program was:" >&5 @@ -12433,10 +13387,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_cxx_preproc_warn_flag$ac_cxx_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_cxx_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then # Broken: success on invalid input. continue else @@ -12477,7 +13438,7 @@ ac_compile='$F77 -c $FFLAGS conftest.$ac_ext >&5' ac_link='$F77 -o conftest$ac_exeext $FFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_f77_compiler_gnu if test -n "$ac_tool_prefix"; then - for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn + for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 @@ -12495,7 +13456,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_F77="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12521,7 +13482,7 @@ fi fi if test -z "$F77"; then ac_ct_F77=$F77 - for ac_prog in g77 xlf f77 frt pgf77 cf77 fort77 fl32 af77 xlf90 f90 pgf90 pghpf epcf90 gfortran g95 xlf95 f95 fort ifort ifc efc pgf95 lf95 ftn + for ac_prog in g77 f77 xlf frt pgf77 cf77 fort77 fl32 af77 f90 xlf90 pgf90 pghpf epcf90 gfortran g95 f95 fort xlf95 ifort ifc efc pgf95 lf95 ftn do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 @@ -12539,7 +13500,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_F77="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -12646,10 +13607,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_f77_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_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_objext' + { (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 ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 @@ -12692,10 +13670,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_f77_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_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_objext' + { (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 ac_cv_prog_f77_g=yes else echo "$as_me: failed program was:" >&5 @@ -13150,7 +14145,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_AR="${ac_tool_prefix}ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13190,7 +14185,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_AR="ar" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13246,7 +14241,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13286,7 +14281,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_RANLIB="ranlib" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13342,7 +14337,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_STRIP="${ac_tool_prefix}strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13382,7 +14377,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_STRIP="strip" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -13699,11 +14694,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13702: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14697: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13706: \$? = $ac_status" >&5 + echo "$as_me:14701: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -13967,11 +14962,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:13970: $lt_compile\"" >&5) + (eval echo "\"\$as_me:14965: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:13974: \$? = $ac_status" >&5 + echo "$as_me:14969: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -14071,11 +15066,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:14074: $lt_compile\"" >&5) + (eval echo "\"\$as_me:15069: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:14078: \$? = $ac_status" >&5 + echo "$as_me:15073: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -14551,11 +15546,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -14569,7 +15580,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -14610,11 +15621,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -14628,7 +15655,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -15876,11 +16903,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -15889,7 +16932,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -15971,11 +17014,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_func_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -15984,7 +17043,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_shl_load" >&5 @@ -16034,11 +17093,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dld_shl_load=yes else echo "$as_me: failed program was:" >&5 @@ -16047,7 +17122,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_shl_load=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -16119,11 +17194,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_func_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -16132,7 +17223,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_dlopen" >&5 @@ -16182,11 +17273,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dl_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -16195,7 +17302,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dl_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -16246,11 +17353,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_svld_dlopen=yes else echo "$as_me: failed program was:" >&5 @@ -16259,7 +17382,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_svld_dlopen=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -16310,11 +17433,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_dld_dld_link=yes else echo "$as_me: failed program was:" >&5 @@ -16323,7 +17462,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_dld_dld_link=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -16379,7 +17518,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext < conftest.$ac_ext <&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then - -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } -}'`; fi -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" - - archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag_CXX="-z nodefs" - archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an empty executable. - 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 + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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 + +aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'` +# Check for a 64-bit object if we didn't find anything. +if test -z "$aix_libpath"; then aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } +}'`; fi +else + echo "$as_me: failed program was:" >&5 +sed 's/^/| /' conftest.$ac_ext >&5 + + +fi + +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi + + hardcode_libdir_flag_spec_CXX='${wl}-blibpath:$libdir:'"$aix_libpath" + + archive_expsym_cmds_CXX="\$CC"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then echo "${wl}${allow_undefined_flag}"; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" + else + if test "$host_cpu" = ia64; then + hardcode_libdir_flag_spec_CXX='${wl}-R $libdir:/usr/lib:/lib' + allow_undefined_flag_CXX="-z nodefs" + archive_expsym_cmds_CXX="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" + else + # Determine the default libpath from the value encoded in an empty executable. + 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_cxx_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_link") 2>conftest.er1 + (eval "$ac_try") 2>&5 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); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -17644,7 +18815,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -18815,11 +19986,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18818: $lt_compile\"" >&5) + (eval echo "\"\$as_me:19989: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:18822: \$? = $ac_status" >&5 + echo "$as_me:19993: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -18919,11 +20090,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:18922: $lt_compile\"" >&5) + (eval echo "\"\$as_me:20093: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:18926: \$? = $ac_status" >&5 + echo "$as_me:20097: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -20489,11 +21660,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:20492: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21663: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:20496: \$? = $ac_status" >&5 + echo "$as_me:21667: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -20593,11 +21764,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:20596: $lt_compile\"" >&5) + (eval echo "\"\$as_me:21767: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:20600: \$? = $ac_status" >&5 + echo "$as_me:21771: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -21063,11 +22234,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_f77_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -21081,7 +22268,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -21112,11 +22299,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_f77_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_f77_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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -21130,7 +22333,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -22796,11 +23999,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:22799: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24002: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:22803: \$? = $ac_status" >&5 + echo "$as_me:24006: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -23064,11 +24267,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23067: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24270: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "$as_me:23071: \$? = $ac_status" >&5 + echo "$as_me:24274: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -23168,11 +24371,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:23171: $lt_compile\"" >&5) + (eval echo "\"\$as_me:24374: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "$as_me:23175: \$? = $ac_status" >&5 + echo "$as_me:24378: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -23648,11 +24851,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -23666,7 +24885,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -23707,11 +24926,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -23725,7 +24960,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi @@ -25865,7 +27100,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LLVMGCC="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -25905,7 +27140,7 @@ do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do - if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_LLVMGXX="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 @@ -25989,10 +27224,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 : else echo "$as_me: failed program was:" >&5 @@ -26060,11 +27312,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_elf_elf_begin=yes else echo "$as_me: failed program was:" >&5 @@ -26073,7 +27341,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_elf_elf_begin=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -26131,11 +27399,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_m_sin=yes else echo "$as_me: failed program was:" >&5 @@ -26144,7 +27428,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_m_sin=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -26197,11 +27481,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_imagehlp_main=yes else echo "$as_me: failed program was:" >&5 @@ -26210,7 +27510,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_imagehlp_main=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -26262,11 +27562,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_psapi_main=yes else echo "$as_me: failed program was:" >&5 @@ -26275,7 +27591,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_psapi_main=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -26340,11 +27656,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_dlopen=$ac_res else echo "$as_me: failed program was:" >&5 @@ -26353,7 +27685,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_dlopen+set}" = set; then break @@ -26431,11 +27763,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_ffi_call=$ac_res else echo "$as_me: failed program was:" >&5 @@ -26444,7 +27792,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_ffi_call+set}" = set; then break @@ -26522,11 +27870,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_mallinfo=$ac_res else echo "$as_me: failed program was:" >&5 @@ -26535,7 +27899,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_mallinfo+set}" = set; then break @@ -26606,11 +27970,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_pthread_pthread_mutex_init=yes else echo "$as_me: failed program was:" >&5 @@ -26619,7 +27999,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_pthread_pthread_mutex_init=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -26682,11 +28062,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_pthread_mutex_lock=$ac_res else echo "$as_me: failed program was:" >&5 @@ -26695,7 +28091,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_pthread_mutex_lock+set}" = set; then break @@ -26776,11 +28172,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_lib_udis86_ud_init=yes else echo "$as_me: failed program was:" >&5 @@ -26789,7 +28201,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_udis86_ud_init=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi @@ -26866,10 +28278,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 @@ -26942,11 +28371,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -26955,7 +28400,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -27026,11 +28471,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_search_opendir=$ac_res else echo "$as_me: failed program was:" >&5 @@ -27039,7 +28500,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext if test "${ac_cv_search_opendir+set}" = set; then break @@ -27104,10 +28565,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_header_mmap_anon=yes else echo "$as_me: failed program was:" >&5 @@ -27150,48 +28628,38 @@ cat >>conftest.$ac_ext <<_ACEOF #include #if defined S_ISBLK && defined S_IFDIR -extern char c1[S_ISBLK (S_IFDIR) ? -1 : 1]; +# if S_ISBLK (S_IFDIR) +You lose. +# endif #endif #if defined S_ISBLK && defined S_IFCHR -extern char c2[S_ISBLK (S_IFCHR) ? -1 : 1]; +# if S_ISBLK (S_IFCHR) +You lose. +# endif #endif #if defined S_ISLNK && defined S_IFREG -extern char c3[S_ISLNK (S_IFREG) ? -1 : 1]; +# if S_ISLNK (S_IFREG) +You lose. +# endif #endif #if defined S_ISSOCK && defined S_IFREG -extern char c4[S_ISSOCK (S_IFREG) ? -1 : 1]; +# if S_ISSOCK (S_IFREG) +You lose. +# endif #endif _ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -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_compile") 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); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then - ac_cv_header_stat_broken=no +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "You lose" >/dev/null 2>&1; then + ac_cv_header_stat_broken=yes else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_cv_header_stat_broken=yes + ac_cv_header_stat_broken=no fi +rm -f conftest* -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_header_stat_broken" >&5 echo "${ECHO_T}$ac_cv_header_stat_broken" >&6; } @@ -27240,10 +28708,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 @@ -27420,10 +28905,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_header_sys_wait_h=yes else echo "$as_me: failed program was:" >&5 @@ -27481,10 +28983,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_header_time=yes else echo "$as_me: failed program was:" >&5 @@ -27550,10 +29069,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -27589,10 +29125,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -27700,10 +29243,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -27739,10 +29299,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -27845,10 +29412,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -27884,10 +29468,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -27993,10 +29584,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -28032,10 +29640,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -28140,10 +29755,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -28179,10 +29811,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -28286,10 +29925,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -28325,10 +29981,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -28435,10 +30098,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -28474,10 +30154,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -28574,10 +30261,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -28613,10 +30317,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -28682,7 +30393,6 @@ fi - { echo "$as_me:$LINENO: checking for HUGE_VAL sanity" >&5 echo $ECHO_N "checking for HUGE_VAL sanity... $ECHO_C" >&6; } if test "${ac_cv_huge_val_sanity+set}" = set; then @@ -28797,10 +30507,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_pid_t=yes else echo "$as_me: failed program was:" >&5 @@ -28860,10 +30587,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_size_t=yes else echo "$as_me: failed program was:" >&5 @@ -28921,10 +30665,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_signal=int else echo "$as_me: failed program was:" >&5 @@ -28960,9 +30721,7 @@ cat >>conftest.$ac_ext <<_ACEOF int main () { -struct tm tm; - int *p = &tm.tm_sec; - return !p; +struct tm *tp; tp->tm_sec; ; return 0; } @@ -28980,10 +30739,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_struct_tm=time.h else echo "$as_me: failed program was:" >&5 @@ -29041,10 +30817,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_int64_t=yes else echo "$as_me: failed program was:" >&5 @@ -29107,10 +30900,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_uint64_t=yes else echo "$as_me: failed program was:" >&5 @@ -29168,10 +30978,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_cv_type_u_int64_t=yes else echo "$as_me: failed program was:" >&5 @@ -29274,11 +31101,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29287,7 +31130,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -29371,11 +31214,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29384,7 +31243,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -29469,11 +31328,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29482,7 +31357,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -29565,11 +31440,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29578,7 +31469,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -29665,11 +31556,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29678,7 +31585,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -29762,11 +31669,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29775,7 +31698,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -29859,11 +31782,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -29872,7 +31811,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -30016,11 +31955,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_working_alloca_h=yes else echo "$as_me: failed program was:" >&5 @@ -30029,7 +31984,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_working_alloca_h=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_working_alloca_h" >&5 @@ -30060,7 +32015,7 @@ cat >>conftest.$ac_ext <<_ACEOF # include # define alloca _alloca # else -# ifdef HAVE_ALLOCA_H +# if HAVE_ALLOCA_H # include # else # ifdef _AIX @@ -30096,11 +32051,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 ac_cv_func_alloca_works=yes else echo "$as_me: failed program was:" >&5 @@ -30109,7 +32080,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_func_alloca_works=no fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_func_alloca_works" >&5 @@ -30229,11 +32200,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -30242,7 +32229,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -30379,10 +32366,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_rand48=yes else echo "$as_me: failed program was:" >&5 @@ -30450,10 +32454,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_namespaces=yes else echo "$as_me: failed program was:" >&5 @@ -30524,10 +32545,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_std_ext_hash_map=yes else echo "$as_me: failed program was:" >&5 @@ -30604,10 +32642,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_gnu_ext_hash_map=yes else echo "$as_me: failed program was:" >&5 @@ -30681,10 +32736,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_global_hash_map=yes else echo "$as_me: failed program was:" >&5 @@ -30761,10 +32833,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_std_ext_hash_set=yes else echo "$as_me: failed program was:" >&5 @@ -30841,10 +32930,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_gnu_ext_hash_set=yes else echo "$as_me: failed program was:" >&5 @@ -30918,10 +33024,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_global_hash_set=yes else echo "$as_me: failed program was:" >&5 @@ -30998,10 +33121,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_std_iterator=yes else echo "$as_me: failed program was:" >&5 @@ -31079,10 +33219,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_bi_iterator=yes else echo "$as_me: failed program was:" >&5 @@ -31160,10 +33317,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_cxx_have_fwd_iterator=yes else echo "$as_me: failed program was:" >&5 @@ -31238,10 +33412,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_isnan_in_math_h=yes else echo "$as_me: failed program was:" >&5 @@ -31309,10 +33500,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_isnan_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -31379,10 +33587,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_std_isnan_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -31450,10 +33675,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_isinf_in_math_h=yes else echo "$as_me: failed program was:" >&5 @@ -31520,10 +33762,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_isinf_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -31590,10 +33849,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_std_isinf_in_cmath=yes else echo "$as_me: failed program was:" >&5 @@ -31660,10 +33936,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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 ac_cv_func_finite_in_ieeefp_h=yes else echo "$as_me: failed program was:" >&5 @@ -31734,10 +34027,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (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_objext' + { (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 ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 @@ -31773,10 +34083,17 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } >/dev/null && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then + (exit $ac_status); } >/dev/null; then + if test -s conftest.err; then + ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag + else + ac_cpp_err= + fi +else + ac_cpp_err=yes +fi +if test -z "$ac_cpp_err"; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 @@ -31907,11 +34224,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -31920,7 +34253,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -31977,21 +34310,21 @@ $ac_includes_default #include #include -#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H +#if !STDC_HEADERS && !HAVE_STDLIB_H char *malloc (); #endif /* This mess was copied from the GNU getpagesize.h. */ -#ifndef HAVE_GETPAGESIZE +#if !HAVE_GETPAGESIZE /* Assume that all systems that can run configure have sys/param.h. */ -# ifndef HAVE_SYS_PARAM_H +# if !HAVE_SYS_PARAM_H # define HAVE_SYS_PARAM_H 1 # endif # ifdef _SC_PAGESIZE # define getpagesize() sysconf(_SC_PAGESIZE) # else /* no _SC_PAGESIZE */ -# ifdef HAVE_SYS_PARAM_H +# if HAVE_SYS_PARAM_H # include # ifdef EXEC_PAGESIZE # define getpagesize() EXEC_PAGESIZE @@ -32314,11 +34647,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && - $as_test_x conftest$ac_exeext; then + (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 eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 @@ -32327,7 +34676,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi -rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ +rm -f core conftest.err conftest.$ac_objext \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` @@ -32577,10 +34926,27 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); } && { - test -z "$ac_cxx_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then + (exit $ac_status); } && + { ac_try='test -z "$ac_cxx_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_objext' + { (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_cxx_visibility_inlines_hidden=yes else echo "$as_me: failed program was:" >&5 @@ -32810,8 +35176,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF ## M4sh Initialization. ## ## --------------------- ## -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh +# Be Bourne compatible if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: @@ -32820,13 +35185,10 @@ if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else - case `(set -o) 2>/dev/null` in - *posix*) set -o posix ;; -esac - + case `(set -o) 2>/dev/null` in *posix*) set -o posix;; esac fi - - +BIN_SH=xpg4; export BIN_SH # for Tru64 +DUALCASE=1; export DUALCASE # for MKS sh # PATH needs CR @@ -33050,28 +35412,19 @@ else as_mkdir_p=false fi -if test -x / >/dev/null 2>&1; then - as_test_x='test -x' +# Find out whether ``test -x'' works. Don't use a zero-byte file, as +# systems may use methods other than mode bits to determine executability. +cat >conf$$.file <<_ASEOF +#! /bin/sh +exit 0 +_ASEOF +chmod +x conf$$.file +if test -x conf$$.file >/dev/null 2>&1; then + as_executable_p="test -x" else - if ls -dL / >/dev/null 2>&1; then - as_ls_L_option=L - else - as_ls_L_option= - fi - as_test_x=' - eval sh -c '\'' - if test -d "$1"; then - test -d "$1/."; - else - case $1 in - -*)set "./$1";; - esac; - case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in - ???[sx]*):;;*)false;;esac;fi - '\'' sh - ' + as_executable_p=: fi -as_executable_p=$as_test_x +rm -f conf$$.file # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" @@ -33086,8 +35439,8 @@ exec 6>&1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by llvm $as_me 2.5svn, which was -generated by GNU Autoconf 2.61. Invocation command line was +This file was extended by llvm $as_me 2.6svn, which was +generated by GNU Autoconf 2.60. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS @@ -33116,7 +35469,7 @@ current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit + -V, --version print version number, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions @@ -33139,8 +35492,8 @@ Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ -llvm config.status 2.5svn -configured by $0, generated by GNU Autoconf 2.61, +llvm config.status 2.6svn +configured by $0, generated by GNU Autoconf 2.60, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. @@ -33427,8 +35780,8 @@ CXX!$CXX$ac_delim CXXFLAGS!$CXXFLAGS$ac_delim ac_ct_CXX!$ac_ct_CXX$ac_delim LEX!$LEX$ac_delim -LEX_OUTPUT_ROOT!$LEX_OUTPUT_ROOT$ac_delim LEXLIB!$LEXLIB$ac_delim +LEX_OUTPUT_ROOT!$LEX_OUTPUT_ROOT$ac_delim FLEX!$FLEX$ac_delim YACC!$YACC$ac_delim YFLAGS!$YFLAGS$ac_delim @@ -34066,12 +36419,7 @@ if test "$no_recursion" != yes; then case $ac_arg in *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac - ac_sub_configure_args="'$ac_arg' $ac_sub_configure_args" - - # Pass --silent - if test "$silent" = yes; then - ac_sub_configure_args="--silent $ac_sub_configure_args" - fi + ac_sub_configure_args="$ac_arg $ac_sub_configure_args" ac_popdir=`pwd` for ac_dir in : $subdirs; do test "x$ac_dir" = x: && continue diff --git a/llvm/include/llvm/Config/config.h.in b/llvm/include/llvm/Config/config.h.in index b70cfe140f4e..df1a2d38be50 100644 --- a/llvm/include/llvm/Config/config.h.in +++ b/llvm/include/llvm/Config/config.h.in @@ -20,6 +20,9 @@ /* Define if threads enabled */ #undef ENABLE_THREADS +/* Path to ffi.h */ +#undef FFI_HEADER + /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA @@ -184,6 +187,9 @@ /* Define to 1 if you have the `elf' library (-lelf). */ #undef HAVE_LIBELF +/* Define to 1 if you have the libffi library (-lffi). */ +#undef HAVE_LIBFFI + /* Define to 1 if you have the `imagehlp' library (-limagehlp). */ #undef HAVE_LIBIMAGEHLP -- GitLab From f09619d53352acadfbaaf22ea9b68ebb87e0e069 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 07:04:01 +0000 Subject: [PATCH 003/682] Fix PR3358, a really nasty bug where recursive phi translated analyses could be run without the caches properly sorted. This can fix all sorts of weirdness. Many thanks to Bill for coming up with the 'issorted' verification idea. llvm-svn: 62757 --- .../lib/Analysis/MemoryDependenceAnalysis.cpp | 39 ++++++++++++- .../GVN/2009-01-21-SortInvalidation.ll | 55 +++++++++++++++++++ 2 files changed, 91 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/GVN/2009-01-21-SortInvalidation.ll diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 6818da83ba78..ddfb26eebc16 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -326,6 +326,19 @@ MemDepResult MemoryDependenceAnalysis::getDependency(Instruction *QueryInst) { return LocalCache; } +#ifndef NDEBUG +/// AssertSorted - This method is used when -debug is specified to verify that +/// cache arrays are properly kept sorted. +static void AssertSorted(MemoryDependenceAnalysis::NonLocalDepInfo &Cache, + int Count = -1) { + if (Count == -1) Count = Cache.size(); + if (Count == 0) return; + + for (unsigned i = 1; i != unsigned(Count); ++i) + assert(Cache[i-1] <= Cache[i] && "Cache isn't sorted!"); +} +#endif + /// getNonLocalCallDependency - Perform a full dependency query for the /// specified call, returning the set of blocks that the value is /// potentially live across. The returned set of results will include a @@ -386,6 +399,7 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) { SmallPtrSet Visited; unsigned NumSortedEntries = Cache.size(); + DEBUG(AssertSorted(Cache)); // Iterate while we still have blocks to update. while (!DirtyBlocks.empty()) { @@ -398,6 +412,7 @@ MemoryDependenceAnalysis::getNonLocalCallDependency(CallSite QueryCS) { // Do a binary search to see if we already have an entry for this block in // the cache set. If so, find it. + DEBUG(AssertSorted(Cache, NumSortedEntries)); NonLocalDepInfo::iterator Entry = std::upper_bound(Cache.begin(), Cache.begin()+NumSortedEntries, std::make_pair(DirtyBB, MemDepResult())); @@ -647,6 +662,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // won't get any reuse from currently inserted values, because we don't // revisit blocks after we insert info for them. unsigned NumSortedEntries = Cache->size(); + DEBUG(AssertSorted(*Cache)); while (!Worklist.empty()) { BasicBlock *BB = Worklist.pop_back_val(); @@ -659,6 +675,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // Get the dependency info for Pointer in BB. If we have cached // information, we will use it, otherwise we compute it. + DEBUG(AssertSorted(*Cache, NumSortedEntries)); MemDepResult Dep = GetNonLocalInfoForBlock(Pointer, PointeeSize, isLoad, BB, Cache, NumSortedEntries); @@ -705,7 +722,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // If this is directly a PHI node, just use the incoming values for each // pred as the phi translated version. if (PHINode *PtrPHI = dyn_cast(PtrInst)) { - for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI){ + for (BasicBlock **PI = PredCache->GetPreds(BB); *PI; ++PI) { BasicBlock *Pred = *PI; Value *PredPtr = PtrPHI->getIncomingValueForBlock(Pred); @@ -728,6 +745,21 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // treat this as a phi translation failure. goto PredTranslationFailure; } + + // We may have added values to the cache list before this PHI + // translation. If so, we haven't done anything to ensure that the + // cache remains sorted. Sort it now (if needed) so that recursive + // invocations of getNonLocalPointerDepFromBB that could reuse the cache + // value will only see properly sorted cache arrays. + if (NumSortedEntries != Cache->size()) { + std::sort(Cache->begin(), Cache->end()); + NumSortedEntries = Cache->size(); + } + + // FIXME: it is entirely possible that PHI translating will end up with + // the same value. Consider PHI translating something like: + // X = phi [x, bb1], [y, bb2]. PHI translating for bb1 doesn't *need* + // to recurse here, pedantically speaking. // If we have a problem phi translating, fall through to the code below // to handle the failure condition. @@ -739,7 +771,8 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // Refresh the CacheInfo/Cache pointer so that it isn't invalidated. CacheInfo = &NonLocalPointerDeps[CacheKey]; Cache = &CacheInfo->second; - + NumSortedEntries = Cache->size(); + // Since we did phi translation, the "Cache" set won't contain all of the // results for the query. This is ok (we can still use it to accelerate // specific block queries) but we can't do the fastpath "return all @@ -817,7 +850,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // Added many values, do a full scale sort. std::sort(Cache->begin(), Cache->end()); } - + DEBUG(AssertSorted(*Cache)); return false; } diff --git a/llvm/test/Transforms/GVN/2009-01-21-SortInvalidation.ll b/llvm/test/Transforms/GVN/2009-01-21-SortInvalidation.ll new file mode 100644 index 000000000000..51ca6cb34ee5 --- /dev/null +++ b/llvm/test/Transforms/GVN/2009-01-21-SortInvalidation.ll @@ -0,0 +1,55 @@ +; RUN: llvm-as < %s | opt -gvn | llvm-dis +; PR3358 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.re_pattern_buffer = type { i8*, i64, i64, i64, i8*, i8*, i64, i8 } + %struct.re_registers = type { i32, i32*, i32* } + +define fastcc i32 @byte_re_match_2_internal(%struct.re_pattern_buffer* nocapture %bufp, i8* %string1, i32 %size1, i8* %string2, i32 %size2, i32 %pos, %struct.re_registers* %regs, i32 %stop) nounwind { +entry: + br label %bb159 + +succeed_label: ; preds = %bb159 + ret i32 0 + +bb159: ; preds = %bb664, %bb554, %bb159, %bb159, %bb159, %entry + %d.0 = phi i8* [ null, %entry ], [ %d.0, %bb159 ], [ %d.0, %bb554 ], [ %d.0, %bb159 ], [ %d.0, %bb159 ], [ %d.12, %bb664 ] ; [#uses=5] + switch i32 0, label %bb661 [ + i32 0, label %bb159 + i32 1, label %succeed_label + i32 13, label %bb159 + i32 14, label %bb159 + i32 16, label %bb411 + i32 24, label %bb622 + i32 28, label %bb543 + ] + +bb411: ; preds = %bb411, %bb159 + br label %bb411 + +bb543: ; preds = %bb159 + br i1 false, label %bb549, label %bb550 + +bb549: ; preds = %bb543 + br label %bb554 + +bb550: ; preds = %bb543 + br i1 false, label %bb554, label %bb552 + +bb552: ; preds = %bb550 + %0 = load i8* %d.0, align 8 ; [#uses=0] + br label %bb554 + +bb554: ; preds = %bb552, %bb550, %bb549 + br i1 false, label %bb159, label %bb661 + +bb622: ; preds = %bb622, %bb159 + br label %bb622 + +bb661: ; preds = %bb554, %bb159 + %d.12 = select i1 false, i8* null, i8* null ; [#uses=1] + br label %bb664 + +bb664: ; preds = %bb664, %bb661 + br i1 false, label %bb159, label %bb664 +} -- GitLab From bed6be62e4eaadeaf720dd4146bf069d39a443d5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 07:08:58 +0000 Subject: [PATCH 004/682] fix a testcase. llvm-svn: 62758 --- .../2009-01-19-UnconditionalTrappingConstantExpr.ll | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll b/llvm/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll index 7a6128081bf0..e65bafa6805d 100644 --- a/llvm/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll +++ b/llvm/test/Transforms/SimplifyCFG/2009-01-19-UnconditionalTrappingConstantExpr.ll @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | opt -simplifycfg | llvm-dis | grep {br i1 } | count 4 -; XFAIL: * ; PR3354 ; Do not merge bb1 into the entry block, it might trap. @@ -23,7 +22,7 @@ define i32 @test2(i32 %tmp21, i32 %tmp24, i1 %tmp34) { br i1 %tmp34, label %bb5, label %bb6 bb5: ; preds = %bb4 - br i1 icmp sgt (i32 sdiv (i32 32767, i32 0), i32 0), label %bb6, label %bb7 + br i1 icmp sgt (i32 sdiv (i32 32767, i32 ptrtoint (i32* @G to i32)), i32 0), label %bb6, label %bb7 bb6: ret i32 42 bb7: -- GitLab From 705ac7082bc04df287288053bea63791d7fcd201 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 07:16:03 +0000 Subject: [PATCH 005/682] add a note llvm-svn: 62760 --- llvm/lib/Target/README.txt | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/llvm/lib/Target/README.txt b/llvm/lib/Target/README.txt index 756f38a64913..c679fd83c0da 100644 --- a/llvm/lib/Target/README.txt +++ b/llvm/lib/Target/README.txt @@ -1673,3 +1673,13 @@ while it could get this: sarl $5, %eax //===---------------------------------------------------------------------===// + +GCC PR31029: + +int test(int x) { return 1-x == x; } // --> return false +int test2(int x) { return 2-x == x; } // --> return x == 1 ? + +Always foldable for odd constants, what is the rule for even? + +//===---------------------------------------------------------------------===// + -- GitLab From e09d631d8e6d43c66047dfa49d55192481b6c04e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 07:21:55 +0000 Subject: [PATCH 006/682] fix a typo llvm-svn: 62761 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 2a456dce33d6..e498647c447c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4380,7 +4380,7 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To, assert(From != To.getNode() && "Cannot replace uses of with self"); // Iterate over all the existing uses of From. This specifically avoids - // visiting any new uses of From that arrise while the replacement is + // visiting any new uses of From that arise while the replacement is // happening, because any such uses would be the result of CSE: If an // existing node looks like From after one of its operands is replaced // by To, we don't want to replace of all its users with To too. -- GitLab From 4a0bf66eb886221be5f4417a40f9576ac71ffa3e Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Thu, 22 Jan 2009 09:10:11 +0000 Subject: [PATCH 007/682] Eliminate a couple of fields from TargetRegisterClass: SubRegClasses and SuperRegClasses. These are not necessary. Also eliminate getSubRegisterRegClass and getSuperRegisterRegClass. These are slow and their results can change if register file names change. Just use TargetLowering::getRegClassFor() to get the right TargetRegisterClass instead. llvm-svn: 62762 --- llvm/include/llvm/CodeGen/FastISel.h | 5 +- llvm/include/llvm/Target/TargetRegisterInfo.h | 29 ------- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 6 +- .../SelectionDAG/ScheduleDAGSDNodesEmit.cpp | 35 +-------- llvm/lib/Target/X86/X86FastISel.cpp | 3 +- llvm/utils/TableGen/FastISelEmitter.cpp | 5 +- llvm/utils/TableGen/RegisterInfoEmitter.cpp | 78 ------------------- 7 files changed, 13 insertions(+), 148 deletions(-) diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h index 0b8d67bfcdb4..8c048480694a 100644 --- a/llvm/include/llvm/CodeGen/FastISel.h +++ b/llvm/include/llvm/CodeGen/FastISel.h @@ -259,8 +259,9 @@ protected: uint64_t Imm); /// FastEmitInst_extractsubreg - Emit a MachineInstr for an extract_subreg - /// from a specified index of a superregister. - unsigned FastEmitInst_extractsubreg(unsigned Op0, uint32_t Idx); + /// from a specified index of a superregister to a specified type. + unsigned FastEmitInst_extractsubreg(MVT::SimpleValueType RetVT, + unsigned Op0, uint32_t Idx); /// FastEmitBranch - Emit an unconditional branch to the given block, /// unless it is the immediate (fall-through) successor, and update diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h index fbc0bbc6f404..c7b8290335c5 100644 --- a/llvm/include/llvm/Target/TargetRegisterInfo.h +++ b/llvm/include/llvm/Target/TargetRegisterInfo.h @@ -60,8 +60,6 @@ private: const vt_iterator VTs; const sc_iterator SubClasses; const sc_iterator SuperClasses; - const sc_iterator SubRegClasses; - const sc_iterator SuperRegClasses; const unsigned RegSize, Alignment; // Size & Alignment of register in bytes const int CopyCost; const iterator RegsBegin, RegsEnd; @@ -70,12 +68,9 @@ public: const MVT *vts, const TargetRegisterClass * const *subcs, const TargetRegisterClass * const *supcs, - const TargetRegisterClass * const *subregcs, - const TargetRegisterClass * const *superregcs, unsigned RS, unsigned Al, int CC, iterator RB, iterator RE) : ID(id), VTs(vts), SubClasses(subcs), SuperClasses(supcs), - SubRegClasses(subregcs), SuperRegClasses(superregcs), RegSize(RS), Alignment(Al), CopyCost(CC), RegsBegin(RB), RegsEnd(RE) {} virtual ~TargetRegisterClass() {} // Allow subclasses @@ -170,30 +165,6 @@ public: return I; } - /// subregclasses_begin / subregclasses_end - Loop over all of - /// the subregister classes of this register class. - sc_iterator subregclasses_begin() const { - return SubRegClasses; - } - - sc_iterator subregclasses_end() const { - sc_iterator I = SubRegClasses; - while (*I != NULL) ++I; - return I; - } - - /// superregclasses_begin / superregclasses_end - Loop over all of - /// the superregister classes of this register class. - sc_iterator superregclasses_begin() const { - return SuperRegClasses; - } - - sc_iterator superregclasses_end() const { - sc_iterator I = SuperRegClasses; - while (*I != NULL) ++I; - return I; - } - /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register /// allocate, and the preferred order to allocate them in. For example, diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index dff75510ac13..18cbfe440474 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -943,11 +943,11 @@ unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode, return ResultReg; } -unsigned FastISel::FastEmitInst_extractsubreg(unsigned Op0, uint32_t Idx) { +unsigned FastISel::FastEmitInst_extractsubreg(MVT::SimpleValueType RetVT, + unsigned Op0, uint32_t Idx) { const TargetRegisterClass* RC = MRI.getRegClass(Op0); - const TargetRegisterClass* SRC = *(RC->subregclasses_begin()+Idx-1); - unsigned ResultReg = createResultReg(SRC); + unsigned ResultReg = createResultReg(TLI.getRegClassFor(RetVT)); const TargetInstrDesc &II = TII.get(TargetInstrInfo::EXTRACT_SUBREG); if (II.getNumDefs() >= 1) diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp index 2fa53e08e220..c6f98bf1e974 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp @@ -333,33 +333,6 @@ void ScheduleDAGSDNodes::AddOperand(MachineInstr *MI, SDValue Op, } } -/// getSubRegisterRegClass - Returns the register class of specified register -/// class' "SubIdx"'th sub-register class. -static const TargetRegisterClass* -getSubRegisterRegClass(const TargetRegisterClass *TRC, unsigned SubIdx) { - // Pick the register class of the subregister - TargetRegisterInfo::regclass_iterator I = - TRC->subregclasses_begin() + SubIdx-1; - assert(I < TRC->subregclasses_end() && - "Invalid subregister index for register class"); - return *I; -} - -/// getSuperRegisterRegClass - Returns the register class of a superreg A whose -/// "SubIdx"'th sub-register class is the specified register class and whose -/// type matches the specified type. -static const TargetRegisterClass* -getSuperRegisterRegClass(const TargetRegisterClass *TRC, - unsigned SubIdx, MVT VT) { - // Pick the register class of the superegister for this type - for (TargetRegisterInfo::regclass_iterator I = TRC->superregclasses_begin(), - E = TRC->superregclasses_end(); I != E; ++I) - if ((*I)->hasType(VT) && getSubRegisterRegClass(*I, SubIdx) == TRC) - return *I; - assert(false && "Couldn't find the register class"); - return 0; -} - /// EmitSubregNode - Generate machine code for subreg nodes. /// void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, @@ -389,9 +362,7 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, MachineInstr *MI = BuildMI(MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG)); // Figure out the register class to create for the destreg. - unsigned VReg = getVR(Node->getOperand(0), VRBaseMap); - const TargetRegisterClass *TRC = MRI.getRegClass(VReg); - const TargetRegisterClass *SRC = getSubRegisterRegClass(TRC, SubIdx); + const TargetRegisterClass *SRC = TLI->getRegClassFor(Node->getValueType(0)); if (VRBase) { // Grab the destination register @@ -416,7 +387,6 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, SDValue N0 = Node->getOperand(0); SDValue N1 = Node->getOperand(1); SDValue N2 = Node->getOperand(2); - unsigned SubReg = getVR(N1, VRBaseMap); unsigned SubIdx = cast(N2)->getZExtValue(); @@ -425,8 +395,7 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, if (VRBase) { TRC = MRI.getRegClass(VRBase); } else { - TRC = getSuperRegisterRegClass(MRI.getRegClass(SubReg), SubIdx, - Node->getValueType(0)); + TRC = TLI->getRegClassFor(Node->getValueType(0)); assert(TRC && "Couldn't determine register class for insert_subreg"); VRBase = MRI.createVirtualRegister(TRC); // Create the reg } diff --git a/llvm/lib/Target/X86/X86FastISel.cpp b/llvm/lib/Target/X86/X86FastISel.cpp index f657d37d6adb..d85d2fbea3fc 100644 --- a/llvm/lib/Target/X86/X86FastISel.cpp +++ b/llvm/lib/Target/X86/X86FastISel.cpp @@ -1011,7 +1011,8 @@ bool X86FastISel::X86SelectTrunc(Instruction *I) { BuildMI(MBB, TII.get(CopyOpc), CopyReg).addReg(InputReg); // Then issue an extract_subreg. - unsigned ResultReg = FastEmitInst_extractsubreg(CopyReg, X86::SUBREG_8BIT); + unsigned ResultReg = FastEmitInst_extractsubreg(DstVT.getSimpleVT(), + CopyReg, X86::SUBREG_8BIT); if (!ResultReg) return false; diff --git a/llvm/utils/TableGen/FastISelEmitter.cpp b/llvm/utils/TableGen/FastISelEmitter.cpp index 3ce764259898..201a2cc5fef5 100644 --- a/llvm/utils/TableGen/FastISelEmitter.cpp +++ b/llvm/utils/TableGen/FastISelEmitter.cpp @@ -440,7 +440,8 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) { Operands.PrintArguments(OS, *Memo.PhysRegs); OS << ");\n"; } else { - OS << "extractsubreg(Op0, "; + OS << "extractsubreg(" << getName(RetVT); + OS << ", Op0, "; OS << (unsigned)Memo.SubRegNo; OS << ");\n"; } @@ -534,7 +535,7 @@ void FastISelMap::PrintFunctionDefinitions(std::ostream &OS) { Operands.PrintArguments(OS, *Memo.PhysRegs); OS << ");\n"; } else { - OS << "extractsubreg(Op0, "; + OS << "extractsubreg(RetVT, Op0, "; OS << (unsigned)Memo.SubRegNo; OS << ");\n"; } diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp index 06f43d5d2d2c..67d1cfcf4d34 100644 --- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp +++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp @@ -240,83 +240,7 @@ void RegisterInfoEmitter::run(std::ostream &OS) { << RegisterClasses[i].getName() << "RegClass;\n"; std::map > SuperClassMap; - std::map > SuperRegClassMap; OS << "\n"; - - // Emit the sub-register classes for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); - - OS << " // " << Name - << " Sub-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SubRegClasses [] = {\n "; - - bool Empty = true; - - for (unsigned subrc = 0, subrcMax = RC.SubRegClasses.size(); - subrc != subrcMax; ++subrc) { - unsigned rc2 = 0, e2 = RegisterClasses.size(); - for (; rc2 != e2; ++rc2) { - const CodeGenRegisterClass &RC2 = RegisterClasses[rc2]; - if (RC.SubRegClasses[subrc]->getName() == RC2.getName()) { - if (!Empty) - OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - - std::map >::iterator SCMI = - SuperRegClassMap.find(rc2); - if (SCMI == SuperRegClassMap.end()) { - SuperRegClassMap.insert(std::make_pair(rc2, std::set())); - SCMI = SuperRegClassMap.find(rc2); - } - SCMI->second.insert(rc); - break; - } - } - if (rc2 == e2) - throw "Register Class member '" + - RC.SubRegClasses[subrc]->getName() + - "' is not a valid RegisterClass!"; - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; - } - - // Emit the super-register classes for each RegisterClass - for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { - const CodeGenRegisterClass &RC = RegisterClasses[rc]; - - // Give the register class a legal C name if it's anonymous. - std::string Name = RC.TheDef->getName(); - - OS << " // " << Name - << " Super-register Classes...\n" - << " static const TargetRegisterClass* const " - << Name << "SuperRegClasses [] = {\n "; - - bool Empty = true; - std::map >::iterator I = - SuperRegClassMap.find(rc); - if (I != SuperRegClassMap.end()) { - for (std::set::iterator II = I->second.begin(), - EE = I->second.end(); II != EE; ++II) { - const CodeGenRegisterClass &RC2 = RegisterClasses[*II]; - if (!Empty) - OS << ", "; - OS << "&" << getQualifiedName(RC2.TheDef) << "RegClass"; - Empty = false; - } - } - - OS << (!Empty ? ", " : "") << "NULL"; - OS << "\n };\n\n"; - } // Emit the sub-classes array for each RegisterClass for (unsigned rc = 0, e = RegisterClasses.size(); rc != e; ++rc) { @@ -398,8 +322,6 @@ void RegisterInfoEmitter::run(std::ostream &OS) { << RC.getName() + "VTs" << ", " << RC.getName() + "Subclasses" << ", " << RC.getName() + "Superclasses" << ", " - << RC.getName() + "SubRegClasses" << ", " - << RC.getName() + "SuperRegClasses" << ", " << RC.SpillSize/8 << ", " << RC.SpillAlignment/8 << ", " << RC.CopyCost << ", " -- GitLab From 4186ddfc5ac59b48f466a005ac8619dc29e4b1db Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Thu, 22 Jan 2009 10:14:21 +0000 Subject: [PATCH 008/682] Few targets like the tiny little PIC16 have only 16-bit pointers. llvm-svn: 62763 --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 5b665a0c2213..5085fd4bdab5 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -1516,6 +1516,10 @@ void AsmPrinter::printDataDirective(const Type *type) { assert(TAI->getData64bitsDirective() && "Target cannot handle 64-bit pointer exprs!"); O << TAI->getData64bitsDirective(); + } else if (TD->getPointerSize() == 2) { + O << TAI->getData16bitsDirective(); + } else if (TD->getPointerSize() == 1) { + O << TAI->getData8bitsDirective(); } else { O << TAI->getData32bitsDirective(); } -- GitLab From ac6f7eeb05431f3b40dfceb4cfdab5f9137aae2e Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Thu, 22 Jan 2009 15:07:15 +0000 Subject: [PATCH 009/682] This passes on linux. llvm-svn: 62764 --- llvm/test/FrontendC++/2006-11-06-StackTrace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp b/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp index d1b60c9b59ae..a81b21f6e853 100644 --- a/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp +++ b/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp @@ -11,7 +11,7 @@ // Only works on ppc, x86 and x86_64. Should generalize? // FIXME: Un-XFAIL this test for Linux when debug stuff is working again. -// XFAIL: alpha|ia64|arm|linux +// XFAIL: alpha|ia64|arm #include -- GitLab From e3a26635fbf1c826d19f96b039e8aa08f185ca73 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Thu, 22 Jan 2009 15:37:29 +0000 Subject: [PATCH 010/682] Remove no-longer relevant comment. Pointed out by Gabor. llvm-svn: 62765 --- llvm/test/FrontendC++/2006-11-06-StackTrace.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp b/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp index a81b21f6e853..55b34ad82d52 100644 --- a/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp +++ b/llvm/test/FrontendC++/2006-11-06-StackTrace.cpp @@ -10,7 +10,6 @@ // RUN: grep {#7 0x.* in main.*(argc=\[12\],.*argv=.*)} // Only works on ppc, x86 and x86_64. Should generalize? -// FIXME: Un-XFAIL this test for Linux when debug stuff is working again. // XFAIL: alpha|ia64|arm #include -- GitLab From 2d9dde0e0fc0a8a9013c32ca2ac170d628c5f86c Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 22 Jan 2009 16:23:54 +0000 Subject: [PATCH 011/682] EXTWARNify the warning about unnamed typedefs of enums llvm-svn: 62766 --- clang/include/clang/Basic/DiagnosticKinds.def | 2 +- clang/lib/Sema/SemaDecl.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 664d3af36539..259265c2bfc8 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -606,7 +606,7 @@ DIAG(err_expected_unqualified_id, ERROR, "expected unqualified-id") DIAG(err_no_declarators, ERROR, "declaration does not declare anything") -DIAG(warn_no_declarators, WARNING, +DIAG(ext_typedef_without_a_name, EXTWARN, "typedef requires a name") DIAG(err_func_def_no_params, ERROR, "function definition does not declare parameters") diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index dbf1e7b41659..276f2e24e85d 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -736,11 +736,12 @@ Sema::DeclTy *Sema::ParsedFreeStandingDeclSpec(Scope *S, DeclSpec &DS) { return Tag; } - // Permit typedefs without declarators as a Microsoft extension. if (!DS.isMissingDeclaratorOk()) { + // Warn about typedefs of enums without names, since this is an + // extension in both Microsoft an GNU. if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef && Tag && isa(Tag)) { - Diag(DS.getSourceRange().getBegin(), diag::warn_no_declarators) + Diag(DS.getSourceRange().getBegin(), diag::ext_typedef_without_a_name) << DS.getSourceRange(); return Tag; } -- GitLab From b2e6ca7ff3633d99909da5268afeb76dd4212400 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Thu, 22 Jan 2009 17:31:11 +0000 Subject: [PATCH 012/682] Add a switch that allows disabling the smart pointers. Uncomment the define in Ownership.h to disable the smart pointers. Disabled, the smart pointers no longer contain a pointer to the action, and no longer have special destruction or copying semantics. They are, compiler willing, raw pointers or ActionResult equivalents. llvm-svn: 62767 --- clang/include/clang/Parse/Ownership.h | 101 ++++++++++++++++++++++++-- clang/lib/Parse/AstGuard.h | 14 ++++ 2 files changed, 107 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Parse/Ownership.h b/clang/include/clang/Parse/Ownership.h index a04b81879e97..2144481c3d1d 100644 --- a/clang/include/clang/Parse/Ownership.h +++ b/clang/include/clang/Parse/Ownership.h @@ -102,6 +102,9 @@ // move_* functions, which help the compiler out with some explicit // conversions. +// Flip this switch to measure performance impact of the smart pointers. +//#define DISABLE_SMART_POINTERS + namespace clang { // Basic @@ -178,6 +181,7 @@ namespace clang /// the individual pointers, not the array holding them. template class ASTMultiPtr; +#if !defined(DISABLE_SMART_POINTERS) namespace moving { /// Move emulation helper for ASTOwningResult. NEVER EVER use this class /// directly if you don't know what you're doing. @@ -221,13 +225,17 @@ namespace clang void release(); }; } +#endif template class ASTOwningPtr { +#if !defined(DISABLE_SMART_POINTERS) ActionBase *Actions; +#endif void *Node; +#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTPtrMover; ASTOwningPtr(ASTOwningPtr&); // DO NOT IMPLEMENT @@ -239,8 +247,10 @@ namespace clang (Actions->*Destroyer)(Node); } } +#endif public: +#if !defined(DISABLE_SMART_POINTERS) explicit ASTOwningPtr(ActionBase &actions) : Actions(&actions), Node(0) {} ASTOwningPtr(ActionBase &actions, void *node) @@ -257,21 +267,35 @@ namespace clang } /// Assignment from a raw pointer. Takes ownership - beware! - ASTOwningPtr & operator =(void *raw) - { + ASTOwningPtr & operator =(void *raw) { assert((Actions || !raw) && "Cannot assign non-null raw without Action"); Node = raw; return *this; } +#else // Different set if smart pointers are disabled + explicit ASTOwningPtr(ActionBase &) : Node(0) {} + ASTOwningPtr(ActionBase &, void *node) : Node(node) {} + // Normal copying operators are defined implicitly. + explicit ASTOwningPtr(void *ptr) : Node(ptr) {} + + ASTOwningPtr & operator =(void *raw) { + Node = raw; + return *this; + } +#endif /// Access to the raw pointer. void * get() const { return Node; } /// Release the raw pointer. void * take() { +#if !defined(DISABLE_SMART_POINTERS) void *tmp = Node; Node = 0; return tmp; +#else + return Node; +#endif } /// Alias for interface familiarity with unique_ptr. @@ -279,13 +303,12 @@ namespace clang return take(); } - /// Get the Action associated with the node. - ActionBase* getActions() const { return Actions; } - +#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTPtrMover() { return moving::ASTPtrMover(*this); } +#endif }; template @@ -294,10 +317,12 @@ namespace clang ASTOwningPtr Ptr; bool Invalid; +#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTResultMover; ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT +#endif public: typedef ActionBase::ActionResult::UID> DumbResult; @@ -308,6 +333,7 @@ namespace clang : Ptr(actions, node), Invalid(false) {} ASTOwningResult(ActionBase &actions, const DumbResult &res) : Ptr(actions, res.Val), Invalid(res.isInvalid) {} +#if !defined(DISABLE_SMART_POINTERS) /// Move from another owning result ASTOwningResult(moving::ASTResultMover mover) : Ptr(moving::ASTPtrMover(mover->Ptr)), @@ -315,7 +341,13 @@ namespace clang /// Move from an owning pointer ASTOwningResult(moving::ASTPtrMover mover) : Ptr(mover), Invalid(false) {} +#else + // Normal copying semantics are defined implicitly. + // The fake movers need this: + explicit ASTOwningResult(void *ptr) : Ptr(ptr), Invalid(false) {} +#endif +#if !defined(DISABLE_SMART_POINTERS) /// Move assignment from another owning result ASTOwningResult & operator =(moving::ASTResultMover mover) { Ptr = move(mover->Ptr); @@ -329,6 +361,7 @@ namespace clang Invalid = false; return *this; } +#endif /// Assignment from a raw pointer. Takes ownership - beware! ASTOwningResult & operator =(void *raw) @@ -371,9 +404,7 @@ namespace clang return Ptr.take(); } - /// Get the Action associated with the node. - ActionBase* getActions() const { return Ptr.getActions(); } - +#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTResultMover() { return moving::ASTResultMover(*this); @@ -383,15 +414,19 @@ namespace clang moving::ASTPtrMover ptr_move() { return moving::ASTPtrMover(Ptr); } +#endif }; template class ASTMultiPtr { +#if !defined(DISABLE_SMART_POINTERS) ActionBase &Actions; +#endif void **Nodes; unsigned Count; +#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTMultiMover; ASTMultiPtr(ASTMultiPtr&); // DO NOT IMPLEMENT @@ -404,8 +439,10 @@ namespace clang (Actions.*Destroyer)(Nodes[i]); } } +#endif public: +#if !defined(DISABLE_SMART_POINTERS) explicit ASTMultiPtr(ActionBase &actions) : Actions(actions), Nodes(0), Count(0) {} ASTMultiPtr(ActionBase &actions, void **nodes, unsigned count) @@ -415,7 +452,16 @@ namespace clang : Actions(mover->Actions), Nodes(mover->Nodes), Count(mover->Count) { mover.release(); } +#else + // Normal copying implicitly defined + explicit ASTMultiPtr(ActionBase &) : Nodes(0), Count(0) {} + ASTMultiPtr(ActionBase &, void **nodes, unsigned count) + : Nodes(nodes), Count(count) {} + // Fake mover in Parse/AstGuard.h needs this: + ASTMultiPtr(void **nodes, unsigned count) : Nodes(nodes), Count(count) {} +#endif +#if !defined(DISABLE_SMART_POINTERS) /// Move assignment ASTMultiPtr & operator =(moving::ASTMultiMover mover) { destroy(); @@ -424,6 +470,7 @@ namespace clang mover.release(); return *this; } +#endif /// Access to the raw pointers. void ** get() const { return Nodes; } @@ -432,18 +479,26 @@ namespace clang unsigned size() const { return Count; } void ** release() { +#if !defined(DISABLE_SMART_POINTERS) void **tmp = Nodes; Nodes = 0; Count = 0; return tmp; +#else + return Nodes; +#endif } +#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTMultiMover() { return moving::ASTMultiMover(*this); } +#endif }; +#if !defined(DISABLE_SMART_POINTERS) + // Out-of-line implementations due to definition dependencies template inline @@ -481,6 +536,36 @@ namespace clang return ASTOwningResult(moving::ASTPtrMover(ptr)); } +#else + + // These versions are hopefully no-ops. + template inline + ASTOwningResult& move(ASTOwningResult &ptr) { + return ptr; + } + + template inline + ASTOwningPtr& move(ASTOwningPtr &ptr) { + return ptr; + } + + template inline + ASTMultiPtr& move(ASTMultiPtr &ptr) { + return ptr; + } + + template inline + ASTOwningPtr move_arg(ASTOwningResult &ptr) { + return ASTOwningPtr(ptr.take()); + } + + template inline + ASTOwningResult move_res(ASTOwningPtr &ptr) { + return ASTOwningResult(ptr.get()); + } + +#endif + } #endif diff --git a/clang/lib/Parse/AstGuard.h b/clang/lib/Parse/AstGuard.h index d755ea76c9d9..602fea51dc10 100644 --- a/clang/lib/Parse/AstGuard.h +++ b/clang/lib/Parse/AstGuard.h @@ -26,6 +26,7 @@ namespace clang template class ASTVector : public llvm::SmallVector { private: +#if !defined(DISABLE_SMART_POINTERS) Action &Actions; bool Owns; @@ -40,18 +41,27 @@ namespace clang ASTVector(const ASTVector&); // DO NOT IMPLEMENT // Reference member prevents copy assignment. +#endif public: +#if !defined(DISABLE_SMART_POINTERS) ASTVector(Action &actions) : Actions(actions), Owns(true) {} ~ASTVector() { destroy(); } +#else + ASTVector(Action &) {} +#endif void **take() { +#if !defined(DISABLE_SMART_POINTERS) Owns = false; +#endif return &(*this)[0]; } +#if !defined(DISABLE_SMART_POINTERS) Action &getActions() const { return Actions; } +#endif }; /// A SmallVector of statements, with stack size 32 (as that is the only one @@ -62,7 +72,11 @@ namespace clang template inline ASTMultiPtr move_arg(ASTVector &vec) { +#if !defined(DISABLE_SMART_POINTERS) return ASTMultiPtr(vec.getActions(), vec.take(), vec.size()); +#else + return ASTMultiPtr(vec.take(), vec.size()); +#endif } } -- GitLab From c58900504bd56fe25b953d49be491da249f0b76a Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Thu, 22 Jan 2009 17:39:32 +0000 Subject: [PATCH 013/682] Add SelectionDAG::getNOT method to construct bitwise NOT operations, corresponding to the "not" and "vnot" PatFrags. Use the new method in some places where it seems appropriate. llvm-svn: 62768 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 3 ++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 +++++----- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 6 ++-- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 ++++++++++ .../CodeGen/SelectionDAG/TargetLowering.cpp | 28 +++++++++---------- llvm/lib/Target/X86/X86ISelLowering.cpp | 11 ++------ 6 files changed, 44 insertions(+), 34 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index f93b6207b8f9..8f41b5c208c9 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -366,6 +366,9 @@ public: /// value assuming it was the smaller SrcTy value. SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy); + /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). + SDValue getNOT(SDValue Val, MVT VT); + /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have /// a flag result (to ensure it's not CSE'd). SDValue getCALLSEQ_START(SDValue Chain, SDValue Op) { diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 062b9d9a9330..f7c1d061c6bd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2759,15 +2759,15 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { } // fold select C, 0, X -> ~C & X if (VT == VT0 && VT == MVT::i1 && N1C && N1C->isNullValue()) { - SDValue XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); - AddToWorkList(XORNode.getNode()); - return DAG.getNode(ISD::AND, VT, XORNode, N2); + SDValue NOTNode = DAG.getNOT(N0, VT); + AddToWorkList(NOTNode.getNode()); + return DAG.getNode(ISD::AND, VT, NOTNode, N2); } // fold select C, X, 1 -> ~C | X if (VT == VT0 && VT == MVT::i1 && N2C && N2C->getAPIntValue() == 1) { - SDValue XORNode = DAG.getNode(ISD::XOR, VT, N0, DAG.getConstant(1, VT)); - AddToWorkList(XORNode.getNode()); - return DAG.getNode(ISD::OR, VT, XORNode, N1); + SDValue NOTNode = DAG.getNOT(N0, VT); + AddToWorkList(NOTNode.getNode()); + return DAG.getNode(ISD::OR, VT, NOTNode, N1); } // fold select C, X, 0 -> C & X // FIXME: this should check for C type == X type, not i1? @@ -5574,8 +5574,7 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, if (N1C && N1C->isNullValue() && CC == ISD::SETGT) { SDValue NegN0 = DAG.getNode(ISD::SUB, XType, DAG.getConstant(0, XType), N0); - SDValue NotN0 = DAG.getNode(ISD::XOR, XType, N0, - DAG.getConstant(~0ULL, XType)); + SDValue NotN0 = DAG.getNOT(N0, XType); return DAG.getNode(ISD::SRL, XType, DAG.getNode(ISD::AND, XType, NegN0, NotN0), DAG.getConstant(XType.getSizeInBits()-1, diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 608dde214441..10baccbdf997 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -6318,7 +6318,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3)); } - Op = DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(~0ULL, VT)); + Op = DAG.getNOT(Op, VT); return DAG.getNode(ISD::CTPOP, VT, Op); } case ISD::CTTZ: { @@ -6327,9 +6327,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { // { return 32 - nlz(~x & (x-1)); } // see also http://www.hackersdelight.org/HDcode/ntz.cc MVT VT = Op.getValueType(); - SDValue Tmp2 = DAG.getConstant(~0ULL, VT); - SDValue Tmp3 = DAG.getNode(ISD::AND, VT, - DAG.getNode(ISD::XOR, VT, Op, Tmp2), + SDValue Tmp3 = DAG.getNode(ISD::AND, VT, DAG.getNOT(Op, VT), DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT))); // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. if (!TLI.isOperationLegal(ISD::CTPOP, VT) && diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index e498647c447c..a08856022ab6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -816,6 +816,21 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, MVT VT) { getConstant(Imm, Op.getValueType())); } +/// getNOT - Create a bitwise NOT operation as (XOR Val, -1). +/// +SDValue SelectionDAG::getNOT(SDValue Val, MVT VT) { + SDValue NegOne; + if (VT.isVector()) { + MVT EltVT = VT.getVectorElementType(); + SDValue NegOneElt = getConstant(EltVT.getIntegerVTBitMask(), EltVT); + std::vector NegOnes(VT.getVectorNumElements(), NegOneElt); + NegOne = getNode(ISD::BUILD_VECTOR, VT, &NegOnes[0], NegOnes.size()); + } else + NegOne = getConstant(VT.getIntegerVTBitMask(), VT); + + return getNode(ISD::XOR, VT, Val, NegOne); +} + SDValue SelectionDAG::getConstant(uint64_t Val, MVT VT, bool isT) { MVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT; return getConstant(APInt(EltVT.getSizeInBits(), Val), VT, isT); diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 364a12177ff2..cd5df4ff0911 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1798,39 +1798,39 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (N0.getValueType() == MVT::i1 && foldBooleans) { switch (Cond) { default: assert(0 && "Unknown integer setcc!"); - case ISD::SETEQ: // X == Y -> (X^Y)^1 + case ISD::SETEQ: // X == Y -> ~(X^Y) Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); - N0 = DAG.getNode(ISD::XOR, MVT::i1, Temp, DAG.getConstant(1, MVT::i1)); + N0 = DAG.getNOT(Temp, MVT::i1); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETNE: // X != Y --> (X^Y) N0 = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); break; - case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> X^1 & Y - case ISD::SETULT: // X X == 0 & Y == 1 --> X^1 & Y - Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1)); + case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> ~X & Y + case ISD::SETULT: // X X == 0 & Y == 1 --> ~X & Y + Temp = DAG.getNOT(N0, MVT::i1); N0 = DAG.getNode(ISD::AND, MVT::i1, N1, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; - case ISD::SETLT: // X X == 1 & Y == 0 --> Y^1 & X - case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> Y^1 & X - Temp = DAG.getNode(ISD::XOR, MVT::i1, N1, DAG.getConstant(1, MVT::i1)); + case ISD::SETLT: // X X == 1 & Y == 0 --> ~Y & X + case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> ~Y & X + Temp = DAG.getNOT(N1, MVT::i1); N0 = DAG.getNode(ISD::AND, MVT::i1, N0, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; - case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> X^1 | Y - case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> X^1 | Y - Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, DAG.getConstant(1, MVT::i1)); + case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> ~X | Y + case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> ~X | Y + Temp = DAG.getNOT(N0, MVT::i1); N0 = DAG.getNode(ISD::OR, MVT::i1, N1, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; - case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> Y^1 | X - case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> Y^1 | X - Temp = DAG.getNode(ISD::XOR, MVT::i1, N1, DAG.getConstant(1, MVT::i1)); + case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> ~Y | X + case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> ~Y | X + Temp = DAG.getNOT(N1, MVT::i1); N0 = DAG.getNode(ISD::OR, MVT::i1, N0, Temp); break; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index c59e9cd77237..a2ae6095f504 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5253,14 +5253,9 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) { SDValue Result = DAG.getNode(Opc, VT, Op0, Op1); // If the logical-not of the result is required, perform that now. - if (Invert) { - MVT EltVT = VT.getVectorElementType(); - SDValue NegOne = DAG.getConstant(EltVT.getIntegerVTBitMask(), EltVT); - std::vector NegOnes(VT.getVectorNumElements(), NegOne); - SDValue NegOneV = DAG.getNode(ISD::BUILD_VECTOR, VT, &NegOnes[0], - NegOnes.size()); - Result = DAG.getNode(ISD::XOR, VT, Result, NegOneV); - } + if (Invert) + Result = DAG.getNOT(Result, VT); + return Result; } -- GitLab From 74040833e4fc20920330bdff5e4928362821f62e Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 18:23:34 +0000 Subject: [PATCH 014/682] Static analyzer: Remove a bunch of outdated SymbolData objects and their associated APIs. We no longer need separate SymbolData objects for fields, variables, etc. Instead, we now associated symbols with the "rvalue" of a MemRegion (i.e., the value stored at that region). Now we only have two kinds of SymbolData objects: SymbolRegionRValue and SymbolConjured. This cleanup also makes the distinction between a SymbolicRegion and a symbolic value that is a location much clearer. A SymbolicRegion represents a chunk of symbolic memory, while a symbolic location is just a "pointer" with different possible values. Without any specific knowledge, a symbolic location resolves (i.e., via a dereference) to a SymbolicRegion. In the future, when we do better alias reasoning, a symbolic location can become an alias for another location, thus merging the constraints on the referred SymbolicRegion with the other region. llvm-svn: 62769 --- .../clang/Analysis/PathSensitive/GRState.h | 2 +- .../clang/Analysis/PathSensitive/SVals.h | 14 +-- .../Analysis/PathSensitive/SymbolManager.h | 117 ++++-------------- clang/lib/Analysis/BasicConstraintManager.cpp | 9 +- clang/lib/Analysis/BasicStore.cpp | 7 +- clang/lib/Analysis/RegionStore.cpp | 9 +- clang/lib/Analysis/SVals.cpp | 38 ++---- clang/lib/Analysis/SymbolManager.cpp | 117 +++--------------- 8 files changed, 64 insertions(+), 249 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h index 7cf3a43bfa8f..74cd01f51577 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRState.h +++ b/clang/include/clang/Analysis/PathSensitive/GRState.h @@ -310,7 +310,7 @@ public: ISetFactory(alloc), GDMFactory(alloc), BasicVals(Ctx, alloc), - SymMgr(alloc), + SymMgr(Ctx, alloc), Alloc(alloc), cfg(c), codedecl(cd), diff --git a/clang/include/clang/Analysis/PathSensitive/SVals.h b/clang/include/clang/Analysis/PathSensitive/SVals.h index ca36187530ee..dbeba45c833a 100644 --- a/clang/include/clang/Analysis/PathSensitive/SVals.h +++ b/clang/include/clang/Analysis/PathSensitive/SVals.h @@ -72,17 +72,9 @@ public: return !(*this == R); } - /// MakeSymbolValue - make a unique symbol value for the region R according to - /// its kind. R should be a scalar region. The symbol value T has the same - /// type as R's rvalue type. - static SVal MakeSymbolValue(SymbolManager& SymMgr, const MemRegion* R, - QualType T); - - static SVal GetSymbolValue(SymbolManager& SymMgr, VarDecl *D); - static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, - const llvm::APSInt* Idx, QualType T); - static SVal getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, - const FieldDecl* FD, QualType T); + /// GetRValueSymbolVal - make a unique symbol for value of R. + static SVal GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R); + inline bool isUnknown() const { return getRawKind() == UnknownKind; diff --git a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h b/clang/include/clang/Analysis/PathSensitive/SymbolManager.h index e326166dfc9d..6b777be0c507 100644 --- a/clang/include/clang/Analysis/PathSensitive/SymbolManager.h +++ b/clang/include/clang/Analysis/PathSensitive/SymbolManager.h @@ -32,6 +32,7 @@ namespace clang { class MemRegion; class SymbolManager; +class ASTContext; class SymbolRef { unsigned Data; @@ -80,8 +81,7 @@ namespace clang { class SymbolData : public llvm::FoldingSetNode { public: - enum Kind { UndefKind, ParmKind, GlobalKind, ElementKind, FieldKind, - ConjuredKind }; + enum Kind { RegionRValue, ConjuredKind }; private: Kind K; @@ -97,105 +97,36 @@ public: SymbolRef getSymbol() const { return Sym; } - QualType getType(const SymbolManager& SymMgr) const; + virtual QualType getType(ASTContext&) const = 0; virtual void Profile(llvm::FoldingSetNodeID& profile) = 0; // Implement isa support. static inline bool classof(const SymbolData*) { return true; } }; - -class SymbolDataParmVar : public SymbolData { - const ParmVarDecl *VD; - -public: - SymbolDataParmVar(SymbolRef MySym, const ParmVarDecl* vd) - : SymbolData(ParmKind, MySym), VD(vd) {} - - const ParmVarDecl* getDecl() const { return VD; } - - static void Profile(llvm::FoldingSetNodeID& profile, const ParmVarDecl* VD) { - profile.AddInteger((unsigned) ParmKind); - profile.AddPointer(VD); - } - virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, VD); - } - - // Implement isa support. - static inline bool classof(const SymbolData* D) { - return D->getKind() == ParmKind; - } -}; - -class SymbolDataGlobalVar : public SymbolData { - const VarDecl *VD; - +class SymbolRegionRValue : public SymbolData { + const MemRegion *R; public: - SymbolDataGlobalVar(SymbolRef MySym, const VarDecl* vd) : - SymbolData(GlobalKind, MySym), VD(vd) {} - - const VarDecl* getDecl() const { return VD; } + SymbolRegionRValue(SymbolRef MySym, const MemRegion *r) + : SymbolData(RegionRValue, MySym), R(r) {} - static void Profile(llvm::FoldingSetNodeID& profile, const VarDecl* VD) { - profile.AddInteger((unsigned) GlobalKind); - profile.AddPointer(VD); + const MemRegion* getRegion() const { return R; } + + static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R) { + profile.AddInteger((unsigned) RegionRValue); + profile.AddPointer(R); } virtual void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, VD); + Profile(profile, R); } + QualType getType(ASTContext&) const; + // Implement isa support. static inline bool classof(const SymbolData* D) { - return D->getKind() == GlobalKind; - } -}; - -class SymbolDataElement : public SymbolData { - const MemRegion* R; - const llvm::APSInt* Idx; - -public: - SymbolDataElement(SymbolRef MySym, const MemRegion* r, const llvm::APSInt* idx) - : SymbolData(ElementKind, MySym), R(r), Idx(idx) {} - - static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, - const llvm::APSInt* Idx) { - profile.AddPointer(R); - profile.AddPointer(Idx); - } - - void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R, Idx); - } - - static bool classof(const SymbolData* D) { - return D->getKind() == ElementKind; - } -}; - -class SymbolDataField : public SymbolData { - const MemRegion* R; - const FieldDecl* D; - -public: - SymbolDataField(SymbolRef MySym, const MemRegion* r, const FieldDecl* d) - : SymbolData(FieldKind, MySym), R(r), D(d) {} - - static void Profile(llvm::FoldingSetNodeID& profile, const MemRegion* R, - const FieldDecl* D) { - profile.AddPointer(R); - profile.AddPointer(D); - } - - void Profile(llvm::FoldingSetNodeID& profile) { - Profile(profile, R, D); - } - - static bool classof(const SymbolData* D) { - return D->getKind() == FieldKind; + return D->getKind() == RegionRValue; } }; @@ -210,7 +141,7 @@ public: Stmt* getStmt() const { return S; } unsigned getCount() const { return Count; } - QualType getType() const { return T; } + QualType getType(ASTContext&) const; static void Profile(llvm::FoldingSetNodeID& profile, Stmt* S, QualType T, unsigned Count) { @@ -271,18 +202,16 @@ class SymbolManager { unsigned SymbolCounter; llvm::BumpPtrAllocator& BPAlloc; + ASTContext& Ctx; public: - SymbolManager(llvm::BumpPtrAllocator& bpalloc) - : SymbolCounter(0), BPAlloc(bpalloc) {} + SymbolManager(ASTContext& ctx, llvm::BumpPtrAllocator& bpalloc) + : SymbolCounter(0), BPAlloc(bpalloc), Ctx(ctx) {} ~SymbolManager(); /// Make a unique symbol for MemRegion R according to its kind. - SymbolRef getSymbol(const MemRegion* R); - SymbolRef getSymbol(const VarDecl* D); - SymbolRef getElementSymbol(const MemRegion* R, const llvm::APSInt* Idx); - SymbolRef getFieldSymbol(const MemRegion* R, const FieldDecl* D); + SymbolRef getRegionRValueSymbol(const MemRegion* R); SymbolRef getConjuredSymbol(Stmt* E, QualType T, unsigned VisitCount); SymbolRef getConjuredSymbol(Expr* E, unsigned VisitCount) { return getConjuredSymbol(E, E->getType(), VisitCount); @@ -291,8 +220,10 @@ public: const SymbolData& getSymbolData(SymbolRef ID) const; QualType getType(SymbolRef ID) const { - return getSymbolData(ID).getType(*this); + return getSymbolData(ID).getType(Ctx); } + + ASTContext& getContext() { return Ctx; } }; class SymbolReaper { diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp index 450c38f20b96..c875691167a5 100644 --- a/clang/lib/Analysis/BasicConstraintManager.cpp +++ b/clang/lib/Analysis/BasicConstraintManager.cpp @@ -204,13 +204,12 @@ BasicConstraintManager::AssumeAux(const GRState* St,NonLoc Cond, case nonloc::SymbolValKind: { nonloc::SymbolVal& SV = cast(Cond); SymbolRef sym = SV.getSymbol(); - + QualType T = SymMgr.getType(sym); + if (Assumption) - return AssumeSymNE(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)), - isFeasible); + return AssumeSymNE(St, sym, BasicVals.getValue(0, T), isFeasible); else - return AssumeSymEQ(St, sym, BasicVals.getValue(0, SymMgr.getType(sym)), - isFeasible); + return AssumeSymEQ(St, sym, BasicVals.getValue(0, T), isFeasible); } case nonloc::SymIntConstraintValKind: diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index 7315ec71ace5..a36a239e0de2 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -454,12 +454,13 @@ Store BasicStoreManager::getInitialStore() { if (Loc::IsLocType(T) || T->isIntegerType()) { // Initialize globals and parameters to symbolic values. // Initialize local variables to undefined. + const MemRegion *R = StateMgr.getRegion(VD); SVal X = (VD->hasGlobalStorage() || isa(VD) || isa(VD)) - ? SVal::GetSymbolValue(StateMgr.getSymbolManager(), VD) - : UndefinedVal(); + ? SVal::GetRValueSymbolVal(StateMgr.getSymbolManager(), R) + : UndefinedVal(); - St = BindInternal(St, Loc::MakeVal(MRMgr.getVarRegion(VD)), X); + St = BindInternal(St, Loc::MakeVal(R), X); } } } diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 3faae70885d8..5a13a1dbc25b 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -552,8 +552,7 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { // We treat function parameters as symbolic values. if (const VarRegion* VR = dyn_cast(R)) if (isa(VR->getDecl())) - return SVal::MakeSymbolValue(getSymbolManager(), VR, - VR->getRValueType(getContext())); + return SVal::GetRValueSymbolVal(getSymbolManager(), VR); if (MRMgr.onStack(R) || MRMgr.onHeap(R)) { // All stack variables are considered to have undefined values @@ -564,8 +563,7 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { } // All other values are symbolic. - return SVal::MakeSymbolValue(getSymbolManager(), R, - cast(R)->getRValueType(getContext())); + return SVal::GetRValueSymbolVal(getSymbolManager(), R); // FIXME: consider default values for elements and fields. } @@ -603,8 +601,7 @@ SVal RegionStoreManager::RetrieveStruct(const GRState* St,const TypedRegion* R){ if (MRMgr.onStack(FR) || MRMgr.onHeap(FR)) FieldValue = UndefinedVal(); else - FieldValue = SVal::MakeSymbolValue(getSymbolManager(), FR, - FR->getRValueType(getContext())); + FieldValue = SVal::GetRValueSymbolVal(getSymbolManager(), FR); } StructVal = getBasicVals().consVals(FieldValue, StructVal); diff --git a/clang/lib/Analysis/SVals.cpp b/clang/lib/Analysis/SVals.cpp index 6cc5e914f40d..6847764871d1 100644 --- a/clang/lib/Analysis/SVals.cpp +++ b/clang/lib/Analysis/SVals.cpp @@ -286,38 +286,14 @@ NonLoc NonLoc::MakeCompoundVal(QualType T, llvm::ImmutableList Vals, return nonloc::CompoundVal(BasicVals.getCompoundValData(T, Vals)); } -SVal SVal::MakeSymbolValue(SymbolManager& SymMgr, const MemRegion* R, - QualType T) { - if (Loc::IsLocType(T)) - return Loc::MakeVal(SymMgr.getSymbol(R)); - else - return NonLoc::MakeVal(SymMgr.getSymbol(R)); -} - -SVal SVal::GetSymbolValue(SymbolManager& SymMgr, VarDecl* D) { - - QualType T = D->getType(); - - if (Loc::IsLocType(T)) - return loc::SymbolVal(SymMgr.getSymbol(D)); +SVal SVal::GetRValueSymbolVal(SymbolManager& SymMgr, const MemRegion* R) { + SymbolRef sym = SymMgr.getRegionRValueSymbol(R); + + if (const TypedRegion* TR = cast(R)) + if (Loc::IsLocType(TR->getRValueType(SymMgr.getContext()))) + return Loc::MakeVal(sym); - return nonloc::SymbolVal(SymMgr.getSymbol(D)); -} - -SVal SVal::getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, - const llvm::APSInt* Idx, QualType T) { - if (Loc::IsLocType(T)) - return loc::SymbolVal(SymMgr.getElementSymbol(R, Idx)); - else - return nonloc::SymbolVal(SymMgr.getElementSymbol(R, Idx)); -} - -SVal SVal::getSymbolValue(SymbolManager& SymMgr, const MemRegion* R, - const FieldDecl* FD, QualType T) { - if (Loc::IsLocType(T)) - return loc::SymbolVal(SymMgr.getFieldSymbol(R, FD)); - else - return nonloc::SymbolVal(SymMgr.getFieldSymbol(R, FD)); + return NonLoc::MakeVal(sym); } nonloc::LocAsInteger nonloc::LocAsInteger::Make(BasicValueFactory& Vals, Loc V, diff --git a/clang/lib/Analysis/SymbolManager.cpp b/clang/lib/Analysis/SymbolManager.cpp index d0099e15fa8f..54ba7b1d9370 100644 --- a/clang/lib/Analysis/SymbolManager.cpp +++ b/clang/lib/Analysis/SymbolManager.cpp @@ -22,99 +22,23 @@ void SymbolRef::print(llvm::raw_ostream& os) const { os << getNumber(); } -SymbolRef SymbolManager::getSymbol(const MemRegion* R) { - switch (R->getKind()) { - default: - assert(0 && "unprocessed region"); - case MemRegion::VarRegionKind: - return getSymbol(cast(R)->getDecl()); - - case MemRegion::ElementRegionKind: { - const ElementRegion* ER = cast(R); - const llvm::APSInt& Idx = - cast(ER->getIndex()).getValue(); - return getElementSymbol(ER->getSuperRegion(), &Idx); - } - - case MemRegion::FieldRegionKind: { - const FieldRegion* FR = cast(R); - return getFieldSymbol(FR->getSuperRegion(), FR->getDecl()); - } - } -} - -SymbolRef SymbolManager::getSymbol(const VarDecl* D) { - - assert (isa(D) || isa(D) || - D->hasGlobalStorage()); - +SymbolRef SymbolManager::getRegionRValueSymbol(const MemRegion* R) { llvm::FoldingSetNodeID profile; - - const ParmVarDecl* PD = dyn_cast(D); - - if (PD) - SymbolDataParmVar::Profile(profile, PD); - else - SymbolDataGlobalVar::Profile(profile, D); - - void* InsertPos; - - SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); - if (SD) - return SD->getSymbol(); - - if (PD) { - SD = (SymbolData*) BPAlloc.Allocate(); - new (SD) SymbolDataParmVar(SymbolCounter, PD); - } - else { - SD = (SymbolData*) BPAlloc.Allocate(); - new (SD) SymbolDataGlobalVar(SymbolCounter, D); - } + SymbolRegionRValue::Profile(profile, R); + void* InsertPos; + SymbolData* SD = DataSet.FindNodeOrInsertPos(profile, InsertPos); + if (SD) return SD->getSymbol(); + SD = (SymbolData*) BPAlloc.Allocate(); + new (SD) SymbolRegionRValue(SymbolCounter, R); DataSet.InsertNode(SD, InsertPos); - - DataMap[SymbolCounter] = SD; - return SymbolCounter++; -} - -SymbolRef SymbolManager::getElementSymbol(const MemRegion* R, - const llvm::APSInt* Idx){ - llvm::FoldingSetNodeID ID; - SymbolDataElement::Profile(ID, R, Idx); - void* InsertPos; - SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos); - - if (SD) - return SD->getSymbol(); - - SD = (SymbolData*) BPAlloc.Allocate(); - new (SD) SymbolDataElement(SymbolCounter, R, Idx); - - DataSet.InsertNode(SD, InsertPos); - DataMap[SymbolCounter] = SD; + DataMap[SymbolCounter] = SD; return SymbolCounter++; -} - -SymbolRef SymbolManager::getFieldSymbol(const MemRegion* R, const FieldDecl* D) { - llvm::FoldingSetNodeID ID; - SymbolDataField::Profile(ID, R, D); - void* InsertPos; - SymbolData* SD = DataSet.FindNodeOrInsertPos(ID, InsertPos); - if (SD) - return SD->getSymbol(); - - SD = (SymbolData*) BPAlloc.Allocate(); - new (SD) SymbolDataField(SymbolCounter, R, D); - - DataSet.InsertNode(SD, InsertPos); - DataMap[SymbolCounter] = SD; - return SymbolCounter++; } -SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count) { +SymbolRef SymbolManager::getConjuredSymbol(Stmt* E, QualType T, unsigned Count){ llvm::FoldingSetNodeID profile; SymbolConjured::Profile(profile, E, T, Count); @@ -141,20 +65,15 @@ const SymbolData& SymbolManager::getSymbolData(SymbolRef Sym) const { } -QualType SymbolData::getType(const SymbolManager& SymMgr) const { - switch (getKind()) { - default: - assert (false && "getType() not implemented for this symbol."); - - case ParmKind: - return cast(this)->getDecl()->getType(); - - case GlobalKind: - return cast(this)->getDecl()->getType(); +QualType SymbolConjured::getType(ASTContext&) const { + return T; +} - case ConjuredKind: - return cast(this)->getType(); - } +QualType SymbolRegionRValue::getType(ASTContext& C) const { + if (const TypedRegion* TR = dyn_cast(R)) + return TR->getRValueType(C); + + return QualType(); } SymbolManager::~SymbolManager() {} @@ -172,7 +91,7 @@ bool SymbolReaper::maybeDead(SymbolRef sym) { return true; } -bool SymbolReaper::isLive(SymbolRef sym) { +bool SymbolReaper::isLive(SymbolRef sym) { return TheLiving.contains(sym); } -- GitLab From dec7fe2e71df234f56f4e5fd59ef376a2568bc0e Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Thu, 22 Jan 2009 18:28:11 +0000 Subject: [PATCH 015/682] Do not use buggy llvm-gcc to generate testcases. llvm-svn: 62770 --- llvm/test/CodeGen/X86/2006-07-19-ATTAsm.ll | 2 +- .../2009-01-15-RecordVariableCrash.ll | 20 +++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/llvm/test/CodeGen/X86/2006-07-19-ATTAsm.ll b/llvm/test/CodeGen/X86/2006-07-19-ATTAsm.ll index f426e529f016..78167f631e1b 100644 --- a/llvm/test/CodeGen/X86/2006-07-19-ATTAsm.ll +++ b/llvm/test/CodeGen/X86/2006-07-19-ATTAsm.ll @@ -10,7 +10,7 @@ target triple = "i386-unknown-freebsd6.1" %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8 *, i8*, { }*, i32, { }*, i1, i1, { }* } @x = global i32 0 ; [#uses=1] @llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { - i32 458804, + i32 327732, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @str, i64 0, i64 0), diff --git a/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll b/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll index e9b4eeb1b6f6..0fa216700dc9 100644 --- a/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll +++ b/llvm/test/DebugInfo/2009-01-15-RecordVariableCrash.ll @@ -22,29 +22,27 @@ @.str5 = internal constant [2 x i8] c"i\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] @llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 22, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] @.str6 = internal constant [8 x i8] c"islower\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] -@.str7 = internal constant [8 x i8] c"ctype.h\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] -@.str8 = internal constant [13 x i8] c"/usr/include\00", section "llvm.metadata" ; <[13 x i8]*> [#uses=1] -@llvm.dbg.subprogram9 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 267, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@llvm.dbg.subprogram9 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 267, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] @.str10 = internal constant [3 x i8] c"_c\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] -@llvm.dbg.variable11 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 266, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.variable11 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram9 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 266, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] @.str12 = internal constant [9 x i8] c"__istype\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1] -@llvm.dbg.subprogram13 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 171, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@llvm.dbg.subprogram13 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([9 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 171, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] @.str14 = internal constant [19 x i8] c"__darwin_ct_rune_t\00", section "llvm.metadata" ; <[19 x i8]*> [#uses=1] @.str15 = internal constant [9 x i8] c"_types.h\00", section "llvm.metadata" ; <[9 x i8]*> [#uses=1] @.str16 = internal constant [18 x i8] c"/usr/include/i386\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1] @llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458774, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([19 x i8]* @.str14, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 70, i64 0, i64 0, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([9 x i8]* @.str15, i32 0, i32 0), i8* getelementptr ([18 x i8]* @.str16, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] -@llvm.dbg.variable17 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.variable17 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] @.str18 = internal constant [18 x i8] c"long unsigned int\00", section "llvm.metadata" ; <[18 x i8]*> [#uses=1] @llvm.dbg.basictype19 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([18 x i8]* @.str18, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 7, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] @.str20 = internal constant [3 x i8] c"_f\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] -@llvm.dbg.variable21 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str20, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.variable21 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram13 to { }*), i8* getelementptr ([3 x i8]* @.str20, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 170, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype19 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] @_DefaultRuneLocale = external global %struct._RuneLocale ; <%struct._RuneLocale*> [#uses=1] @.str22 = internal constant [8 x i8] c"isascii\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] -@llvm.dbg.subprogram23 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 153, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] -@llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 152, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.subprogram23 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str22, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 153, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram23 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 152, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] @.str25 = internal constant [8 x i8] c"toupper\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] -@llvm.dbg.subprogram26 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 316, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] -@llvm.dbg.variable27 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 315, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([8 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([13 x i8]* @.str8, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.subprogram26 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* getelementptr ([8 x i8]* @.str25, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 316, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i1 true, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@llvm.dbg.variable27 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram26 to { }*), i8* getelementptr ([3 x i8]* @.str10, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 315, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] define i32 @main() nounwind { entry: -- GitLab From 2dd9c9cbd7917ffaa1c0658c8d3d53dc9d0833e1 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 18:51:33 +0000 Subject: [PATCH 016/682] SymbolReaper::isLive(SymbolRef) now always returns true for SymbolRegionRvalues because these represent the symbolic values for parameters/globals upon entry to the function. These values are always ;live' because they represent constraints on the context of how the function was called. This will be useful for both summary generation but is also necessary to get RegionStore's lazy-binding of locations to symbols to work in practice with RemoveDeadBindings. llvm-svn: 62771 --- clang/lib/Analysis/SymbolManager.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/SymbolManager.cpp b/clang/lib/Analysis/SymbolManager.cpp index 54ba7b1d9370..1672af8c611c 100644 --- a/clang/lib/Analysis/SymbolManager.cpp +++ b/clang/lib/Analysis/SymbolManager.cpp @@ -92,6 +92,11 @@ bool SymbolReaper::maybeDead(SymbolRef sym) { } bool SymbolReaper::isLive(SymbolRef sym) { - return TheLiving.contains(sym); + if (TheLiving.contains(sym)) + return true; + + // Interogate the symbol. It may derive from an input value to + // the analyzed function/method. + return isa(SymMgr.getSymbolData(sym)); } -- GitLab From 556c3709d6f0c77ec3179f7e40f9cef6c1cab54b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 18:53:15 +0000 Subject: [PATCH 017/682] The 'misc-ps.m' test case now passes with RegionStore. One case needed to be split out into 'misc-ps-basic-store.m' and 'misc-ps-region-store.m' because the behavior was different between the two store models (RegionStore flags an additional valid bug). llvm-svn: 62772 --- clang/test/Analysis/misc-ps-basic-store.m | 21 +++++++++++++++++++++ clang/test/Analysis/misc-ps-region-store.m | 21 +++++++++++++++++++++ clang/test/Analysis/misc-ps.m | 18 +++--------------- 3 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 clang/test/Analysis/misc-ps-basic-store.m create mode 100644 clang/test/Analysis/misc-ps-region-store.m diff --git a/clang/test/Analysis/misc-ps-basic-store.m b/clang/test/Analysis/misc-ps-basic-store.m new file mode 100644 index 000000000000..8d7ac87b268d --- /dev/null +++ b/clang/test/Analysis/misc-ps-basic-store.m @@ -0,0 +1,21 @@ +// RUN: clang -analyze -checker-cfref --analyzer-store-basic --verify -fblocks %s + +//--------------------------------------------------------------------------- +// Test case 'checkaccess_union' differs for region store and basic store. +// The basic store doesn't reason about compound literals, so the code +// below won't fire an "uninitialized value" warning. +//--------------------------------------------------------------------------- + +// PR 2948 (testcase; crash on VisitLValue for union types) +// http://llvm.org/bugs/show_bug.cgi?id=2948 + +void checkaccess_union() { + int ret = 0, status; + if (((((__extension__ (((union { // no-warning + __typeof (status) __in; int __i;} + ) + { + .__in = (status)} + ).__i))) & 0xff00) >> 8) == 1) + ret = 1; +} diff --git a/clang/test/Analysis/misc-ps-region-store.m b/clang/test/Analysis/misc-ps-region-store.m new file mode 100644 index 000000000000..940d277b9247 --- /dev/null +++ b/clang/test/Analysis/misc-ps-region-store.m @@ -0,0 +1,21 @@ +// RUN: clang -analyze -checker-cfref --analyzer-store-region --verify -fblocks %s + +//--------------------------------------------------------------------------- +// Test case 'checkaccess_union' differs for region store and basic store. +// The basic store doesn't reason about compound literals, so the code +// below won't fire an "uninitialized value" warning. +//--------------------------------------------------------------------------- + +// PR 2948 (testcase; crash on VisitLValue for union types) +// http://llvm.org/bugs/show_bug.cgi?id=2948 + +void checkaccess_union() { + int ret = 0, status; + if (((((__extension__ (((union { // expected-warning {{ Branch condition evaluates to an uninitialized value.}} + __typeof (status) __in; int __i;} + ) + { + .__in = (status)} + ).__i))) & 0xff00) >> 8) == 1) + ret = 1; +} diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index f9f1bdd4513b..f221f8b989f1 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/test/Analysis/misc-ps.m @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-cfref --verify -fblocks %s +// RUN: clang -analyze -checker-cfref --analyzer-store-basic --verify -fblocks %s && +// RUN: clang -analyze -checker-cfref --analyzer-store-region --verify -fblocks %s + // Reduced test case from crash in @class NSObject; @@ -43,20 +45,6 @@ void divzeroassumeB(unsigned x, unsigned j) { if (j == 0) x = x / 0; // no-warning } -// PR 2948 (testcase; crash on VisitLValue for union types) -// http://llvm.org/bugs/show_bug.cgi?id=2948 - -void checkaccess_union() { - int ret = 0, status; - if (((((__extension__ (((union { - __typeof (status) __in; int __i;} - ) - { - .__in = (status)} - ).__i))) & 0xff00) >> 8) == 1) - ret = 1; -} - // InitListExpr processing typedef float __m128 __attribute__((__vector_size__(16), __may_alias__)); -- GitLab From e5ea41b5c4f06f7b152f166d00455982abe85c5f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 18:54:47 +0000 Subject: [PATCH 018/682] These test cases now pass with RegionStore. llvm-svn: 62773 --- clang/test/Analysis/CheckNSError.m | 3 ++- clang/test/Analysis/NSPanel.m | 3 ++- clang/test/Analysis/NSString.m | 3 ++- clang/test/Analysis/NSWindow.m | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/clang/test/Analysis/CheckNSError.m b/clang/test/Analysis/CheckNSError.m index 7da12c04b893..b3eacda20d2d 100644 --- a/clang/test/Analysis/CheckNSError.m +++ b/clang/test/Analysis/CheckNSError.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s typedef signed char BOOL; typedef int NSInteger; diff --git a/clang/test/Analysis/NSPanel.m b/clang/test/Analysis/NSPanel.m index 8a64581b2eff..5f9f26c88bf9 100644 --- a/clang/test/Analysis/NSPanel.m +++ b/clang/test/Analysis/NSPanel.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s // BEGIN delta-debugging reduced header stuff diff --git a/clang/test/Analysis/NSString.m b/clang/test/Analysis/NSString.m index af8909f838b1..e01c994d313d 100644 --- a/clang/test/Analysis/NSString.m +++ b/clang/test/Analysis/NSString.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from diff --git a/clang/test/Analysis/NSWindow.m b/clang/test/Analysis/NSWindow.m index f7202f556384..bcb6c41abab2 100644 --- a/clang/test/Analysis/NSWindow.m +++ b/clang/test/Analysis/NSWindow.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -warn-dead-stores -verify %s +// RUN: clang -analyze -checker-cfref -warn-dead-stores -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -warn-dead-stores -analyzer-store-region -verify %s // These declarations were reduced using Delta-Debugging from Foundation.h // on Mac OS X. The test cases are below. -- GitLab From 4da04a4e82c6d4083b8b532baf1db9892b89e8f8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 19:21:44 +0000 Subject: [PATCH 019/682] inline Sema::getLangOptions, rdar://6515190. This speeds up fsyntax-only with PTH by 3%. llvm-svn: 62774 --- clang/lib/Sema/Sema.cpp | 7 ++----- clang/lib/Sema/Sema.h | 3 ++- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index a8cc40490725..7e61bbd14c5f 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -114,7 +114,8 @@ void Sema::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { } Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer) - : PP(pp), Context(ctxt), Consumer(consumer), Diags(PP.getDiagnostics()), + : LangOpts(pp.getLangOptions()), PP(pp), Context(ctxt), Consumer(consumer), + Diags(PP.getDiagnostics()), SourceMgr(PP.getSourceManager()), CurContext(0), PreDeclaratorDC(0), CurBlock(0), PackContext(0), IdResolver(pp.getLangOptions()), GlobalNewDeleteDeclared(false) { @@ -197,10 +198,6 @@ void Sema::ActOnEndOfTranslationUnit() { // Helper functions. //===----------------------------------------------------------------------===// -const LangOptions &Sema::getLangOptions() const { - return PP.getLangOptions(); -} - /// getCurFunctionDecl - If inside of a function body, this returns a pointer /// to the function decl for the function being parsed. If we're currently /// in a 'block', this returns the containing context. diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index b574dc360e3f..9f1f2a3c3189 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -108,6 +108,7 @@ public: /// Sema - This implements semantic analysis and AST building for C. class Sema : public Action { public: + const LangOptions &LangOpts; Preprocessor &PP; ASTContext &Context; ASTConsumer &Consumer; @@ -236,7 +237,7 @@ public: public: Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer); - const LangOptions &getLangOptions() const; + const LangOptions &getLangOptions() const { return LangOpts; } Diagnostic &getDiagnostics() const { return Diags; } SourceManager &getSourceManager() const { return SourceMgr; } -- GitLab From fec5470f0376e4019be40fd2b89c1ebc9e63c5af Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 19:48:26 +0000 Subject: [PATCH 020/682] remove Read8/Read24, which are dead. Rename Read16/Read32 to be more descriptive. llvm-svn: 62775 --- clang/lib/Lex/PTHLexer.cpp | 88 +++++++++++++------------------------- 1 file changed, 30 insertions(+), 58 deletions(-) diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 9fa2bb2b0fbf..497e225b4706 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -31,42 +31,14 @@ using namespace clang; // Utility methods for reading from the mmap'ed PTH file. //===----------------------------------------------------------------------===// -static inline uint8_t Read8(const unsigned char *&Data) { - uint8_t V = Data[0]; - Data += 1; - return V; -} - -static inline uint16_t Read16(const unsigned char *&Data) { -// Targets that directly support unaligned little-endian 16-bit loads can just -// use them. -#if defined(__i386__) || defined(__x86_64__) - uint16_t V = *((uint16_t*)Data); -#else +static inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) { uint16_t V = ((uint16_t)Data[0] << 0) | ((uint16_t)Data[1] << 8); -#endif Data += 2; return V; } -static inline uint32_t Read24(const unsigned char *&Data) { -// Targets that directly support unaligned little-endian 16-bit loads can just -// use them. -#if defined(__i386__) || defined(__x86_64__) - uint32_t V = ((uint16_t*)Data)[0] | - ((uint32_t)Data[2] << 16); -#else - uint32_t V = ((uint32_t)Data[0] << 0) | - ((uint32_t)Data[1] << 8) | - ((uint32_t)Data[2] << 16); -#endif - - Data += 3; - return V; -} - -static inline uint32_t Read32(const unsigned char *&Data) { +static inline uint32_t ReadLE32(const unsigned char *&Data) { // Targets that directly support unaligned little-endian 32-bit loads can just // use them. #if defined(__i386__) || defined(__x86_64__) @@ -107,9 +79,9 @@ LexNextToken: const unsigned char *CurPtrShadow = CurPtr; // Read in the data for the token. - unsigned Word0 = Read32(CurPtrShadow); - uint32_t IdentifierID = Read32(CurPtrShadow); - uint32_t FileOffset = Read32(CurPtrShadow); + unsigned Word0 = ReadLE32(CurPtrShadow); + uint32_t IdentifierID = ReadLE32(CurPtrShadow); + uint32_t FileOffset = ReadLE32(CurPtrShadow); tok::TokenKind TKind = (tok::TokenKind) (Word0 & 0xFF); Token::TokenFlags TFlags = (Token::TokenFlags) ((Word0 >> 8) & 0xFF); @@ -232,10 +204,10 @@ bool PTHLexer::SkipBlock() { do { // Read the token offset from the side-table. - Offset = Read32(CurPPCondPtr); + Offset = ReadLE32(CurPPCondPtr); // Read the target table index from the side-table. - TableIdx = Read32(CurPPCondPtr); + TableIdx = ReadLE32(CurPPCondPtr); // Compute the actual memory address of the '#' token data for this entry. HashEntryI = TokBuf + Offset; @@ -252,14 +224,14 @@ bool PTHLexer::SkipBlock() { PPCond + TableIdx*(sizeof(uint32_t)*2); assert(NextPPCondPtr >= CurPPCondPtr); // Read where we should jump to. - uint32_t TmpOffset = Read32(NextPPCondPtr); + uint32_t TmpOffset = ReadLE32(NextPPCondPtr); const unsigned char* HashEntryJ = TokBuf + TmpOffset; if (HashEntryJ <= LastHashTokPtr) { // Jump directly to the next entry in the side table. HashEntryI = HashEntryJ; Offset = TmpOffset; - TableIdx = Read32(NextPPCondPtr); + TableIdx = ReadLE32(NextPPCondPtr); CurPPCondPtr = NextPPCondPtr; } } @@ -274,8 +246,8 @@ bool PTHLexer::SkipBlock() { CurPPCondPtr = NextPPCondPtr; // Read where we should jump to. - HashEntryI = TokBuf + Read32(NextPPCondPtr); - uint32_t NextIdx = Read32(NextPPCondPtr); + HashEntryI = TokBuf + ReadLE32(NextPPCondPtr); + uint32_t NextIdx = ReadLE32(NextPPCondPtr); // By construction NextIdx will be zero if this is a #endif. This is useful // to know to obviate lexing another token. @@ -325,7 +297,7 @@ SourceLocation PTHLexer::getSourceLocation() { // data buffer to construct the SourceLocation object. // NOTE: This is a virtual function; hence it is defined out-of-line. const unsigned char *OffsetPtr = CurPtr + (DISK_TOKEN_SIZE - 4); - uint32_t Offset = Read32(OffsetPtr); + uint32_t Offset = ReadLE32(OffsetPtr); return FileStartLoc.getFileLocWithOffset(Offset); } @@ -358,7 +330,7 @@ unsigned PTHManager::getSpellingAtPTHOffset(unsigned PTHOffset, // The string is prefixed by 16 bits for its length, followed by the string // itself. - unsigned Len = Read16(Ptr); + unsigned Len = ReadUnalignedLE16(Ptr); Buffer = (const char *)Ptr; return Len; } @@ -372,14 +344,14 @@ unsigned PTHSpellingSearch::getSpellingLinearSearch(unsigned FPos, return getSpellingBinarySearch(FPos, Buffer); do { - uint32_t TokOffset = Read32(Ptr); + uint32_t TokOffset = ReadLE32(Ptr); if (TokOffset > FPos) return getSpellingBinarySearch(FPos, Buffer); // Did we find a matching token offset for this spelling? if (TokOffset == FPos) { - uint32_t SpellingPTHOffset = Read32(Ptr); + uint32_t SpellingPTHOffset = ReadLE32(Ptr); Len = PTHMgr.getSpellingAtPTHOffset(SpellingPTHOffset, Buffer); break; } @@ -407,7 +379,7 @@ unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned FPos, unsigned i = (max - min) / 2 + min; const unsigned char *Ptr = tb + (i * SpellingEntrySize); - uint32_t TokOffset = Read32(Ptr); + uint32_t TokOffset = ReadLE32(Ptr); if (TokOffset > FPos) { max = i; assert(!(max == min) || (min == i)); @@ -422,7 +394,7 @@ unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned FPos, continue; } - uint32_t SpellingPTHOffset = Read32(Ptr); + uint32_t SpellingPTHOffset = ReadLE32(Ptr); return PTHMgr.getSpellingAtPTHOffset(SpellingPTHOffset, Buffer); } while (min != max); @@ -498,16 +470,16 @@ public: } void ReadTable(const unsigned char* D) { - uint32_t N = Read32(D); // Read the length of the table. + uint32_t N = ReadLE32(D); // Read the length of the table. for ( ; N > 0; --N) { // The rest of the data is the table itself. - uint32_t Len = Read32(D); + uint32_t Len = ReadLE32(D); const char* s = (const char *)D; D += Len; - uint32_t TokenOff = Read32(D); - uint32_t PPCondOff = Read32(D); - uint32_t SpellingOff = Read32(D); + uint32_t TokenOff = ReadLE32(D); + uint32_t PPCondOff = ReadLE32(D); + uint32_t SpellingOff = ReadLE32(D); FileMap.GetOrCreateValue(s, s+Len).getValue() = Val(TokenOff, PPCondOff, SpellingOff); @@ -561,7 +533,7 @@ PTHManager* PTHManager::Create(const std::string& file) { // Construct the file lookup table. This will be used for mapping from // FileEntry*'s to cached tokens. const unsigned char* FileTableOffset = EndTable + sizeof(uint32_t)*3; - const unsigned char* FileTable = BufBeg + Read32(FileTableOffset); + const unsigned char* FileTable = BufBeg + ReadLE32(FileTableOffset); if (!(FileTable > BufBeg && FileTable < BufEnd)) { assert(false && "Invalid PTH file."); @@ -577,7 +549,7 @@ PTHManager* PTHManager::Create(const std::string& file) { // Get the location of the table mapping from persistent ids to the // data needed to reconstruct identifiers. const unsigned char* IDTableOffset = EndTable + sizeof(uint32_t)*1; - const unsigned char* IData = BufBeg + Read32(IDTableOffset); + const unsigned char* IData = BufBeg + ReadLE32(IDTableOffset); if (!(IData >= BufBeg && IData < BufEnd)) { assert(false && "Invalid PTH file."); @@ -586,14 +558,14 @@ PTHManager* PTHManager::Create(const std::string& file) { // Get the location of the lexigraphically-sorted table of persistent IDs. const unsigned char* SortedIdTableOffset = EndTable + sizeof(uint32_t)*2; - const unsigned char* SortedIdTable = BufBeg + Read32(SortedIdTableOffset); + const unsigned char* SortedIdTable = BufBeg + ReadLE32(SortedIdTableOffset); if (!(SortedIdTable >= BufBeg && SortedIdTable < BufEnd)) { assert(false && "Invalid PTH file."); return 0; // FIXME: Proper error diagnostic? } // Get the number of IdentifierInfos and pre-allocate the identifier cache. - uint32_t NumIds = Read32(IData); + uint32_t NumIds = ReadLE32(IData); // Pre-allocate the peristent ID -> IdentifierInfo* cache. We use calloc() // so that we in the best case only zero out memory once when the OS returns @@ -616,7 +588,7 @@ IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) { // Look in the PTH file for the string data for the IdentifierInfo object. const unsigned char* TableEntry = IdDataTable + sizeof(uint32_t)*PersistentID; const unsigned char* IDData = - (const unsigned char*)Buf->getBufferStart() + Read32(TableEntry); + (const unsigned char*)Buf->getBufferStart() + ReadLE32(TableEntry); assert(IDData < (const unsigned char*)Buf->getBufferEnd()); // Allocate the object. @@ -641,7 +613,7 @@ IdentifierInfo* PTHManager::get(const char *NameStart, const char *NameEnd) { const unsigned char *Ptr = SortedIdTable + (i * 4); // Read the persistentID. - unsigned perID = Read32(Ptr); + unsigned perID = ReadLE32(Ptr); // Get the IdentifierInfo. IdentifierInfo* II = GetIdentifierInfo(perID); @@ -694,13 +666,13 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) { // Get the location of pp-conditional table. const unsigned char* ppcond = BufStart + FileData.getPPCondOffset(); - uint32_t Len = Read32(ppcond); + uint32_t Len = ReadLE32(ppcond); if (Len == 0) ppcond = 0; // Get the location of the spelling table. const unsigned char* spellingTable = BufStart + FileData.getSpellingOffset(); - Len = Read32(spellingTable); + Len = ReadLE32(spellingTable); if (Len == 0) spellingTable = 0; assert(data < (const unsigned char*)Buf->getBufferEnd()); -- GitLab From aa1212271a3199c16c2e76ffe6efbaec4b10bfb7 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 19:53:00 +0000 Subject: [PATCH 021/682] rename methods in System/Host to be more consistent. llvm-svn: 62776 --- llvm/include/llvm/System/Host.h | 14 +++++++------- llvm/lib/ExecutionEngine/ExecutionEngine.cpp | 8 ++++---- llvm/lib/System/Unix/Host.inc | 4 ++-- llvm/lib/System/Win32/Host.inc | 4 ++-- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/llvm/include/llvm/System/Host.h b/llvm/include/llvm/System/Host.h index 711959325d98..22e36e7ba7b5 100644 --- a/llvm/include/llvm/System/Host.h +++ b/llvm/include/llvm/System/Host.h @@ -19,7 +19,7 @@ namespace llvm { namespace sys { - inline bool littleEndianHost() { + inline bool isLittleEndianHost() { union { int i; char c; @@ -28,17 +28,17 @@ namespace sys { return c; } - inline bool bigEndianHost() { - return !littleEndianHost(); + inline bool isBigEndianHost() { + return !isLittleEndianHost(); } - /// osName() - Return the name of the host operating system or "" if + /// getOSName() - Return the name of the host operating system or "" if /// unknown. - std::string osName(); + std::string getOSName(); - /// osVersion() - Return the operating system version as a string or + /// getOSVersion() - Return the operating system version as a string or /// "" if unknown. - std::string osVersion(); + std::string getOSVersion(); } } diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index a1fbdd281241..d1a406c99607 100644 --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -692,7 +692,7 @@ static void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, assert((IntVal.getBitWidth()+7)/8 >= StoreBytes && "Integer too small!"); uint8_t *Src = (uint8_t *)IntVal.getRawData(); - if (sys::littleEndianHost()) + if (sys::isLittleEndianHost()) // Little-endian host - the source is ordered from LSB to MSB. Order the // destination from LSB to MSB: Do a straight copy. memcpy(Dst, Src, StoreBytes); @@ -751,7 +751,7 @@ void ExecutionEngine::StoreValueToMemory(const GenericValue &Val, cerr << "Cannot store value of type " << *Ty << "!\n"; } - if (sys::littleEndianHost() != getTargetData()->isLittleEndian()) + if (sys::isLittleEndianHost() != getTargetData()->isLittleEndian()) // Host and target are different endian - reverse the stored bytes. std::reverse((uint8_t*)Ptr, StoreBytes + (uint8_t*)Ptr); } @@ -762,7 +762,7 @@ static void LoadIntFromMemory(APInt &IntVal, uint8_t *Src, unsigned LoadBytes) { assert((IntVal.getBitWidth()+7)/8 >= LoadBytes && "Integer too small!"); uint8_t *Dst = (uint8_t *)IntVal.getRawData(); - if (sys::littleEndianHost()) + if (sys::isLittleEndianHost()) // Little-endian host - the destination must be ordered from LSB to MSB. // The source is ordered from LSB to MSB: Do a straight copy. memcpy(Dst, Src, LoadBytes); @@ -789,7 +789,7 @@ void ExecutionEngine::LoadValueFromMemory(GenericValue &Result, const Type *Ty) { const unsigned LoadBytes = getTargetData()->getTypeStoreSize(Ty); - if (sys::littleEndianHost() != getTargetData()->isLittleEndian()) { + if (sys::isLittleEndianHost() != getTargetData()->isLittleEndian()) { // Host and target are different endian - reverse copy the stored // bytes into a buffer, and load from that. uint8_t *Src = (uint8_t*)Ptr; diff --git a/llvm/lib/System/Unix/Host.inc b/llvm/lib/System/Unix/Host.inc index 7bee66fd0d63..205ce2362c79 100644 --- a/llvm/lib/System/Unix/Host.inc +++ b/llvm/lib/System/Unix/Host.inc @@ -23,7 +23,7 @@ using namespace llvm; -std::string llvm::sys::osName() { +std::string llvm::sys::getOSName() { struct utsname info; if (uname(&info)) @@ -32,7 +32,7 @@ std::string llvm::sys::osName() { return info.sysname; } -std::string llvm::sys::osVersion() { +std::string llvm::sys::getOSVersion() { struct utsname info; if (uname(&info)) diff --git a/llvm/lib/System/Win32/Host.inc b/llvm/lib/System/Win32/Host.inc index 7bbf2bd346ed..4fabc78adebf 100644 --- a/llvm/lib/System/Win32/Host.inc +++ b/llvm/lib/System/Win32/Host.inc @@ -17,11 +17,11 @@ using namespace llvm; -std::string sys::osName() { +std::string sys::getOSName() { return "Windows"; } -std::string sys::osVersion() { +std::string sys::getOSVersion() { OSVERSIONINFO osvi; memset(&osvi, 0, sizeof(osvi)); -- GitLab From 9a8602ce50de26a2cf42a401aada3f270a366466 Mon Sep 17 00:00:00 2001 From: Tanya Lattner Date: Thu, 22 Jan 2009 20:09:20 +0000 Subject: [PATCH 022/682] Revert r62553 and r62616 due to issues with portability. llvm-svn: 62777 --- llvm/autoconf/configure.ac | 9 - .../Interpreter/ExternalFunctions.cpp | 702 +++++++++++++----- 2 files changed, 496 insertions(+), 215 deletions(-) diff --git a/llvm/autoconf/configure.ac b/llvm/autoconf/configure.ac index 5d551a70699d..3a218eaeb9c6 100644 --- a/llvm/autoconf/configure.ac +++ b/llvm/autoconf/configure.ac @@ -717,11 +717,6 @@ AC_SEARCH_LIBS(dlopen,dl,AC_DEFINE([HAVE_DLOPEN],[1], [Define if dlopen() is available on this platform.]), AC_MSG_WARN([dlopen() not found - disabling plugin support])) -dnl libffi is optional; used to call external functions from the interpreter -AC_SEARCH_LIBS(ffi_call,ffi,AC_DEFINE([HAVE_LIBFFI],[1], - [Define to 1 if you have the libffi library (-lffi).]), - AC_MSG_WARN([libffi not found - disabling external calls from interpreter])) - dnl mallinfo is optional; the code can compile (minus features) without it AC_SEARCH_LIBS(mallinfo,malloc,AC_DEFINE([HAVE_MALLINFO],[1], [Define if mallinfo() is available on this platform.])) @@ -784,10 +779,6 @@ else AC_SUBST(HAVE_PTHREAD, 0) fi -dnl Debian vs. the world. -AC_CHECK_HEADER(ffi/ffi.h, AC_DEFINE(FFI_HEADER, ["ffi/ffi.h"], [Path to ffi.h])) -AC_CHECK_HEADER(ffi.h, AC_DEFINE(FFI_HEADER, ["ffi.h"], [Path to ffi.h])) - dnl===-----------------------------------------------------------------------=== dnl=== dnl=== SECTION 7: Check for types and structures diff --git a/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp b/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp index 9f44a63654cb..66a26cff3c63 100644 --- a/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp +++ b/llvm/lib/ExecutionEngine/Interpreter/ExternalFunctions.cpp @@ -10,19 +10,18 @@ // This file contains both code to deal with invoking "external" functions, but // also contains code that implements "exported" external functions. // -// There are currently two mechanisms for handling external functions in the -// Interpreter. The first is to implement lle_* wrapper functions that are -// specific to well-known library functions which manually translate the -// arguments from GenericValues and make the call. If such a wrapper does -// not exist, and libffi is available, then the Interpreter will attempt to -// invoke the function using libffi, after finding its address. +// External functions in the interpreter are implemented by +// using the system's dynamic loader to look up the address of the function +// we want to invoke. If a function is found, then one of the +// many lle_* wrapper functions in this file will translate its arguments from +// GenericValues to the types the function is actually expecting, before the +// function is called. // //===----------------------------------------------------------------------===// #include "Interpreter.h" #include "llvm/DerivedTypes.h" #include "llvm/Module.h" -#include "llvm/Config/config.h" // Detect libffi #include "llvm/Support/Streams.h" #include "llvm/System/DynamicLibrary.h" #include "llvm/Target/TargetData.h" @@ -33,22 +32,18 @@ #include #include -#ifdef HAVE_LIBFFI -#include FFI_HEADER +#ifdef __linux__ +#include #endif +using std::vector; + using namespace llvm; -typedef GenericValue (*ExFunc)(const FunctionType *, - const std::vector &); -static ManagedStatic > ExportedFunctions; +typedef GenericValue (*ExFunc)(FunctionType *, const vector &); +static ManagedStatic > Functions; static std::map FuncNames; -#ifdef HAVE_LIBFFI -typedef void (*RawFunc)(void); -static ManagedStatic > RawFunctions; -#endif // HAVE_LIBFFI - static Interpreter *TheInterpreter; static char getTypeID(const Type *Ty) { @@ -94,181 +89,34 @@ static ExFunc lookupFunction(const Function *F) { if (FnPtr == 0) // Try calling a generic function... if it exists... FnPtr = (ExFunc)(intptr_t)sys::DynamicLibrary::SearchForAddressOfSymbol( ("lle_X_"+F->getName()).c_str()); + if (FnPtr == 0) + FnPtr = (ExFunc)(intptr_t) + sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName()); if (FnPtr != 0) - ExportedFunctions->insert(std::make_pair(F, FnPtr)); // Cache for later + Functions->insert(std::make_pair(F, FnPtr)); // Cache for later return FnPtr; } -#ifdef HAVE_LIBFFI -static ffi_type *ffiTypeFor(const Type *Ty) { - switch (Ty->getTypeID()) { - case Type::VoidTyID: return &ffi_type_void; - case Type::IntegerTyID: - switch (cast(Ty)->getBitWidth()) { - case 8: return &ffi_type_sint8; - case 16: return &ffi_type_sint16; - case 32: return &ffi_type_sint32; - case 64: return &ffi_type_sint64; - } - case Type::FloatTyID: return &ffi_type_float; - case Type::DoubleTyID: return &ffi_type_double; - case Type::PointerTyID: return &ffi_type_pointer; - default: break; - } - // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc. - cerr << "Type could not be mapped for use with libffi.\n"; - abort(); - return NULL; -} - -static void *ffiValueFor(const Type *Ty, const GenericValue &AV, - void *ArgDataPtr) { - switch (Ty->getTypeID()) { - case Type::IntegerTyID: - switch (cast(Ty)->getBitWidth()) { - case 8: { - int8_t *I8Ptr = (int8_t *) ArgDataPtr; - *I8Ptr = (int8_t) AV.IntVal.getZExtValue(); - return ArgDataPtr; - } - case 16: { - int16_t *I16Ptr = (int16_t *) ArgDataPtr; - *I16Ptr = (int16_t) AV.IntVal.getZExtValue(); - return ArgDataPtr; - } - case 32: { - int32_t *I32Ptr = (int32_t *) ArgDataPtr; - *I32Ptr = (int32_t) AV.IntVal.getZExtValue(); - return ArgDataPtr; - } - case 64: { - int64_t *I64Ptr = (int64_t *) ArgDataPtr; - *I64Ptr = (int64_t) AV.IntVal.getZExtValue(); - return ArgDataPtr; - } - } - case Type::FloatTyID: { - float *FloatPtr = (float *) ArgDataPtr; - *FloatPtr = AV.FloatVal; - return ArgDataPtr; - } - case Type::DoubleTyID: { - double *DoublePtr = (double *) ArgDataPtr; - *DoublePtr = AV.DoubleVal; - return ArgDataPtr; - } - case Type::PointerTyID: { - void **PtrPtr = (void **) ArgDataPtr; - *PtrPtr = GVTOP(AV); - return ArgDataPtr; - } - default: break; - } - // TODO: Support other types such as StructTyID, ArrayTyID, OpaqueTyID, etc. - cerr << "Type value could not be mapped for use with libffi.\n"; - abort(); - return NULL; -} - -static bool ffiInvoke(RawFunc Fn, Function *F, - const std::vector &ArgVals, - const TargetData *TD, GenericValue &Result) { - ffi_cif cif; - const FunctionType *FTy = F->getFunctionType(); - const unsigned NumArgs = F->arg_size(); - - // TODO: We don't have type information about the remaining arguments, because - // this information is never passed into ExecutionEngine::runFunction(). - if (ArgVals.size() > NumArgs && F->isVarArg()) { - cerr << "Calling external var arg function '" << F->getName() - << "' is not supported by the Interpreter.\n"; - abort(); - } - - unsigned ArgBytes = 0; - - std::vector args(NumArgs); - for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end(); - A != E; ++A) { - const unsigned ArgNo = A->getArgNo(); - const Type *ArgTy = FTy->getParamType(ArgNo); - args[ArgNo] = ffiTypeFor(ArgTy); - ArgBytes += TD->getTypeStoreSize(ArgTy); - } - - uint8_t *ArgData = (uint8_t*) alloca(ArgBytes); - uint8_t *ArgDataPtr = ArgData; - std::vector values(NumArgs); - for (Function::const_arg_iterator A = F->arg_begin(), E = F->arg_end(); - A != E; ++A) { - const unsigned ArgNo = A->getArgNo(); - const Type *ArgTy = FTy->getParamType(ArgNo); - values[ArgNo] = ffiValueFor(ArgTy, ArgVals[ArgNo], ArgDataPtr); - ArgDataPtr += TD->getTypeStoreSize(ArgTy); - } - - const Type *RetTy = FTy->getReturnType(); - ffi_type *rtype = ffiTypeFor(RetTy); - - if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, NumArgs, rtype, &args[0]) == FFI_OK) { - void *ret = NULL; - if (RetTy->getTypeID() != Type::VoidTyID) - ret = alloca(TD->getTypeStoreSize(RetTy)); - ffi_call(&cif, Fn, ret, &values[0]); - switch (RetTy->getTypeID()) { - case Type::IntegerTyID: - switch (cast(RetTy)->getBitWidth()) { - case 8: Result.IntVal = APInt(8 , *(int8_t *) ret); break; - case 16: Result.IntVal = APInt(16, *(int16_t*) ret); break; - case 32: Result.IntVal = APInt(32, *(int32_t*) ret); break; - case 64: Result.IntVal = APInt(64, *(int64_t*) ret); break; - } - break; - case Type::FloatTyID: Result.FloatVal = *(float *) ret; break; - case Type::DoubleTyID: Result.DoubleVal = *(double*) ret; break; - case Type::PointerTyID: Result.PointerVal = *(void **) ret; break; - default: break; - } - return true; - } - - return false; -} -#endif // HAVE_LIBFFI - GenericValue Interpreter::callExternalFunction(Function *F, const std::vector &ArgVals) { TheInterpreter = this; // Do a lookup to see if the function is in our cache... this should just be a // deferred annotation! - std::map::iterator FI = ExportedFunctions->find(F); - if (ExFunc Fn = (FI == ExportedFunctions->end()) ? lookupFunction(F) - : FI->second) - return Fn(F->getFunctionType(), ArgVals); - -#ifdef HAVE_LIBFFI - std::map::iterator RF = RawFunctions->find(F); - RawFunc RawFn; - if (RF == RawFunctions->end()) { - RawFn = (RawFunc)(intptr_t) - sys::DynamicLibrary::SearchForAddressOfSymbol(F->getName()); - if (RawFn != 0) - RawFunctions->insert(std::make_pair(F, RawFn)); // Cache for later - } else { - RawFn = RF->second; + std::map::iterator FI = Functions->find(F); + ExFunc Fn = (FI == Functions->end()) ? lookupFunction(F) : FI->second; + if (Fn == 0) { + cerr << "Tried to execute an unknown external function: " + << F->getType()->getDescription() << " " << F->getName() << "\n"; + if (F->getName() == "__main") + return GenericValue(); + abort(); } - GenericValue Result; - if (RawFn != 0 && ffiInvoke(RawFn, F, ArgVals, getTargetData(), Result)) - return Result; -#endif // HAVE_LIBFFI - - cerr << "Tried to execute an unknown external function: " - << F->getType()->getDescription() << " " << F->getName() << "\n"; - if (F->getName() != "__main") - abort(); - return GenericValue(); + // TODO: FIXME when types are not const! + GenericValue Result = Fn(const_cast(F->getFunctionType()), + ArgVals); + return Result; } @@ -277,9 +125,24 @@ GenericValue Interpreter::callExternalFunction(Function *F, // extern "C" { // Don't add C++ manglings to llvm mangling :) +// void putchar(ubyte) +GenericValue lle_X_putchar(FunctionType *FT, const vector &Args){ + cout << ((char)Args[0].IntVal.getZExtValue()) << std::flush; + return Args[0]; +} + +// void _IO_putc(int c, FILE* fp) +GenericValue lle_X__IO_putc(FunctionType *FT, const vector &Args){ +#ifdef __linux__ + _IO_putc((char)Args[0].IntVal.getZExtValue(), (FILE*) Args[1].PointerVal); +#else + assert(0 && "Can't call _IO_putc on this platform"); +#endif + return Args[0]; +} + // void atexit(Function*) -GenericValue lle_X_atexit(const FunctionType *FT, - const std::vector &Args) { +GenericValue lle_X_atexit(FunctionType *FT, const vector &Args) { assert(Args.size() == 1); TheInterpreter->addAtExitHandler((Function*)GVTOP(Args[0])); GenericValue GV; @@ -288,23 +151,163 @@ GenericValue lle_X_atexit(const FunctionType *FT, } // void exit(int) -GenericValue lle_X_exit(const FunctionType *FT, - const std::vector &Args) { +GenericValue lle_X_exit(FunctionType *FT, const vector &Args) { TheInterpreter->exitCalled(Args[0]); return GenericValue(); } // void abort(void) -GenericValue lle_X_abort(const FunctionType *FT, - const std::vector &Args) { +GenericValue lle_X_abort(FunctionType *FT, const vector &Args) { raise (SIGABRT); return GenericValue(); } -// int sprintf(char *, const char *, ...) - a very rough implementation to make +// void *malloc(uint) +GenericValue lle_X_malloc(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1 && "Malloc expects one argument!"); + assert(isa(FT->getReturnType()) && "malloc must return pointer"); + return PTOGV(malloc(Args[0].IntVal.getZExtValue())); +} + +// void *calloc(uint, uint) +GenericValue lle_X_calloc(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2 && "calloc expects two arguments!"); + assert(isa(FT->getReturnType()) && "calloc must return pointer"); + return PTOGV(calloc(Args[0].IntVal.getZExtValue(), + Args[1].IntVal.getZExtValue())); +} + +// void *calloc(uint, uint) +GenericValue lle_X_realloc(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2 && "calloc expects two arguments!"); + assert(isa(FT->getReturnType()) &&"realloc must return pointer"); + return PTOGV(realloc(GVTOP(Args[0]), Args[1].IntVal.getZExtValue())); +} + +// void free(void *) +GenericValue lle_X_free(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + free(GVTOP(Args[0])); + return GenericValue(); +} + +// int atoi(char *) +GenericValue lle_X_atoi(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = APInt(32, atoi((char*)GVTOP(Args[0]))); + return GV; +} + +// double pow(double, double) +GenericValue lle_X_pow(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + GenericValue GV; + GV.DoubleVal = pow(Args[0].DoubleVal, Args[1].DoubleVal); + return GV; +} + +// double sin(double) +GenericValue lle_X_sin(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = sin(Args[0].DoubleVal); + return GV; +} + +// double cos(double) +GenericValue lle_X_cos(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = cos(Args[0].DoubleVal); + return GV; +} + +// double exp(double) +GenericValue lle_X_exp(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = exp(Args[0].DoubleVal); + return GV; +} + +// double sqrt(double) +GenericValue lle_X_sqrt(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = sqrt(Args[0].DoubleVal); + return GV; +} + +// double log(double) +GenericValue lle_X_log(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = log(Args[0].DoubleVal); + return GV; +} + +// double floor(double) +GenericValue lle_X_floor(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.DoubleVal = floor(Args[0].DoubleVal); + return GV; +} + +#ifdef HAVE_RAND48 + +// double drand48() +GenericValue lle_X_drand48(FunctionType *FT, const vector &Args) { + assert(Args.empty()); + GenericValue GV; + GV.DoubleVal = drand48(); + return GV; +} + +// long lrand48() +GenericValue lle_X_lrand48(FunctionType *FT, const vector &Args) { + assert(Args.empty()); + GenericValue GV; + GV.IntVal = APInt(32, lrand48()); + return GV; +} + +// void srand48(long) +GenericValue lle_X_srand48(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + srand48(Args[0].IntVal.getZExtValue()); + return GenericValue(); +} + +#endif + +// int rand() +GenericValue lle_X_rand(FunctionType *FT, const vector &Args) { + assert(Args.empty()); + GenericValue GV; + GV.IntVal = APInt(32, rand()); + return GV; +} + +// void srand(uint) +GenericValue lle_X_srand(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + srand(Args[0].IntVal.getZExtValue()); + return GenericValue(); +} + +// int puts(const char*) +GenericValue lle_X_puts(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = APInt(32, puts((char*)GVTOP(Args[0]))); + return GV; +} + +// int sprintf(sbyte *, sbyte *, ...) - a very rough implementation to make // output useful. -GenericValue lle_X_sprintf(const FunctionType *FT, - const std::vector &Args) { +GenericValue lle_X_sprintf(FunctionType *FT, const vector &Args) { char *OutputBuffer = (char *)GVTOP(Args[0]); const char *FmtStr = (const char *)GVTOP(Args[1]); unsigned ArgNo = 2; @@ -381,12 +384,10 @@ GenericValue lle_X_sprintf(const FunctionType *FT, return GV; } -// int printf(const char *, ...) - a very rough implementation to make output -// useful. -GenericValue lle_X_printf(const FunctionType *FT, - const std::vector &Args) { +// int printf(sbyte *, ...) - a very rough implementation to make output useful. +GenericValue lle_X_printf(FunctionType *FT, const vector &Args) { char Buffer[10000]; - std::vector NewArgs; + vector NewArgs; NewArgs.push_back(PTOGV((void*)&Buffer[0])); NewArgs.insert(NewArgs.end(), Args.begin(), Args.end()); GenericValue GV = lle_X_sprintf(FT, NewArgs); @@ -471,8 +472,7 @@ static void ByteswapSCANFResults(const char *Fmt, void *Arg0, void *Arg1, } // int sscanf(const char *format, ...); -GenericValue lle_X_sscanf(const FunctionType *FT, - const std::vector &args) { +GenericValue lle_X_sscanf(FunctionType *FT, const vector &args) { assert(args.size() < 10 && "Only handle up to 10 args to sscanf right now!"); char *Args[10]; @@ -488,8 +488,7 @@ GenericValue lle_X_sscanf(const FunctionType *FT, } // int scanf(const char *format, ...); -GenericValue lle_X_scanf(const FunctionType *FT, - const std::vector &args) { +GenericValue lle_X_scanf(FunctionType *FT, const vector &args) { assert(args.size() < 10 && "Only handle up to 10 args to scanf right now!"); char *Args[10]; @@ -504,33 +503,324 @@ GenericValue lle_X_scanf(const FunctionType *FT, return GV; } -// int fprintf(FILE *, const char *, ...) - a very rough implementation to make -// output useful. -GenericValue lle_X_fprintf(const FunctionType *FT, - const std::vector &Args) { + +// int clock(void) - Profiling implementation +GenericValue lle_i_clock(FunctionType *FT, const vector &Args) { + extern unsigned int clock(void); + GenericValue GV; + GV.IntVal = APInt(32, clock()); + return GV; +} + + +//===----------------------------------------------------------------------===// +// String Functions... +//===----------------------------------------------------------------------===// + +// int strcmp(const char *S1, const char *S2); +GenericValue lle_X_strcmp(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + GenericValue Ret; + Ret.IntVal = APInt(32, strcmp((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]))); + return Ret; +} + +// char *strcat(char *Dest, const char *src); +GenericValue lle_X_strcat(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + assert(isa(FT->getReturnType()) &&"strcat must return pointer"); + return PTOGV(strcat((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]))); +} + +// char *strcpy(char *Dest, const char *src); +GenericValue lle_X_strcpy(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + assert(isa(FT->getReturnType()) &&"strcpy must return pointer"); + return PTOGV(strcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]))); +} + +static GenericValue size_t_to_GV (size_t n) { + GenericValue Ret; + if (sizeof (size_t) == sizeof (uint64_t)) { + Ret.IntVal = APInt(64, n); + } else { + assert (sizeof (size_t) == sizeof (unsigned int)); + Ret.IntVal = APInt(32, n); + } + return Ret; +} + +static size_t GV_to_size_t (GenericValue GV) { + size_t count; + if (sizeof (size_t) == sizeof (uint64_t)) { + count = (size_t)GV.IntVal.getZExtValue(); + } else { + assert (sizeof (size_t) == sizeof (unsigned int)); + count = (size_t)GV.IntVal.getZExtValue(); + } + return count; +} + +// size_t strlen(const char *src); +GenericValue lle_X_strlen(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + size_t strlenResult = strlen ((char *) GVTOP (Args[0])); + return size_t_to_GV (strlenResult); +} + +// char *strdup(const char *src); +GenericValue lle_X_strdup(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + assert(isa(FT->getReturnType()) && "strdup must return pointer"); + return PTOGV(strdup((char*)GVTOP(Args[0]))); +} + +// char *__strdup(const char *src); +GenericValue lle_X___strdup(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + assert(isa(FT->getReturnType()) &&"_strdup must return pointer"); + return PTOGV(strdup((char*)GVTOP(Args[0]))); +} + +// void *memset(void *S, int C, size_t N) +GenericValue lle_X_memset(FunctionType *FT, const vector &Args) { + assert(Args.size() == 3); + size_t count = GV_to_size_t (Args[2]); + assert(isa(FT->getReturnType()) && "memset must return pointer"); + return PTOGV(memset(GVTOP(Args[0]), uint32_t(Args[1].IntVal.getZExtValue()), + count)); +} + +// void *memcpy(void *Dest, void *src, size_t Size); +GenericValue lle_X_memcpy(FunctionType *FT, const vector &Args) { + assert(Args.size() == 3); + assert(isa(FT->getReturnType()) && "memcpy must return pointer"); + size_t count = GV_to_size_t (Args[2]); + return PTOGV(memcpy((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count)); +} + +// void *memcpy(void *Dest, void *src, size_t Size); +GenericValue lle_X_memmove(FunctionType *FT, const vector &Args) { + assert(Args.size() == 3); + assert(isa(FT->getReturnType()) && "memmove must return pointer"); + size_t count = GV_to_size_t (Args[2]); + return PTOGV(memmove((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), count)); +} + +//===----------------------------------------------------------------------===// +// IO Functions... +//===----------------------------------------------------------------------===// + +// getFILE - Turn a pointer in the host address space into a legit pointer in +// the interpreter address space. This is an identity transformation. +#define getFILE(ptr) ((FILE*)ptr) + +// FILE *fopen(const char *filename, const char *mode); +GenericValue lle_X_fopen(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + assert(isa(FT->getReturnType()) && "fopen must return pointer"); + return PTOGV(fopen((const char *)GVTOP(Args[0]), + (const char *)GVTOP(Args[1]))); +} + +// int fclose(FILE *F); +GenericValue lle_X_fclose(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = APInt(32, fclose(getFILE(GVTOP(Args[0])))); + return GV; +} + +// int feof(FILE *stream); +GenericValue lle_X_feof(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + + GV.IntVal = APInt(32, feof(getFILE(GVTOP(Args[0])))); + return GV; +} + +// size_t fread(void *ptr, size_t size, size_t nitems, FILE *stream); +GenericValue lle_X_fread(FunctionType *FT, const vector &Args) { + assert(Args.size() == 4); + size_t result; + + result = fread((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]), + GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3]))); + return size_t_to_GV (result); +} + +// size_t fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream); +GenericValue lle_X_fwrite(FunctionType *FT, const vector &Args) { + assert(Args.size() == 4); + size_t result; + + result = fwrite((void*)GVTOP(Args[0]), GV_to_size_t (Args[1]), + GV_to_size_t (Args[2]), getFILE(GVTOP(Args[3]))); + return size_t_to_GV (result); +} + +// char *fgets(char *s, int n, FILE *stream); +GenericValue lle_X_fgets(FunctionType *FT, const vector &Args) { + assert(Args.size() == 3); + return PTOGV(fgets((char*)GVTOP(Args[0]), Args[1].IntVal.getZExtValue(), + getFILE(GVTOP(Args[2])))); +} + +// FILE *freopen(const char *path, const char *mode, FILE *stream); +GenericValue lle_X_freopen(FunctionType *FT, const vector &Args) { + assert(Args.size() == 3); + assert(isa(FT->getReturnType()) &&"freopen must return pointer"); + return PTOGV(freopen((char*)GVTOP(Args[0]), (char*)GVTOP(Args[1]), + getFILE(GVTOP(Args[2])))); +} + +// int fflush(FILE *stream); +GenericValue lle_X_fflush(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = APInt(32, fflush(getFILE(GVTOP(Args[0])))); + return GV; +} + +// int getc(FILE *stream); +GenericValue lle_X_getc(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = APInt(32, getc(getFILE(GVTOP(Args[0])))); + return GV; +} + +// int _IO_getc(FILE *stream); +GenericValue lle_X__IO_getc(FunctionType *F, const vector &Args) { + return lle_X_getc(F, Args); +} + +// int fputc(int C, FILE *stream); +GenericValue lle_X_fputc(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + GenericValue GV; + GV.IntVal = APInt(32, fputc(Args[0].IntVal.getZExtValue(), + getFILE(GVTOP(Args[1])))); + return GV; +} + +// int ungetc(int C, FILE *stream); +GenericValue lle_X_ungetc(FunctionType *FT, const vector &Args) { + assert(Args.size() == 2); + GenericValue GV; + GV.IntVal = APInt(32, ungetc(Args[0].IntVal.getZExtValue(), + getFILE(GVTOP(Args[1])))); + return GV; +} + +// int ferror (FILE *stream); +GenericValue lle_X_ferror(FunctionType *FT, const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; + GV.IntVal = APInt(32, ferror (getFILE(GVTOP(Args[0])))); + return GV; +} + +// int fprintf(FILE *,sbyte *, ...) - a very rough implementation to make output +// useful. +GenericValue lle_X_fprintf(FunctionType *FT, const vector &Args) { assert(Args.size() >= 2); char Buffer[10000]; - std::vector NewArgs; + vector NewArgs; NewArgs.push_back(PTOGV(Buffer)); NewArgs.insert(NewArgs.end(), Args.begin()+1, Args.end()); GenericValue GV = lle_X_sprintf(FT, NewArgs); - fputs(Buffer, (FILE *) GVTOP(Args[0])); + fputs(Buffer, getFILE(GVTOP(Args[0]))); return GV; } +// int __cxa_guard_acquire (__guard *g); +GenericValue lle_X___cxa_guard_acquire(FunctionType *FT, + const vector &Args) { + assert(Args.size() == 1); + GenericValue GV; +#ifdef __linux__ + GV.IntVal = APInt(32, __cxxabiv1::__cxa_guard_acquire ( + (__cxxabiv1::__guard*)GVTOP(Args[0]))); +#else + assert(0 && "Can't call __cxa_guard_acquire on this platform"); +#endif + return GV; +} + +// void __cxa_guard_release (__guard *g); +GenericValue lle_X___cxa_guard_release(FunctionType *FT, + const vector &Args) { + assert(Args.size() == 1); +#ifdef __linux__ + __cxxabiv1::__cxa_guard_release ((__cxxabiv1::__guard*)GVTOP(Args[0])); +#else + assert(0 && "Can't call __cxa_guard_release on this platform"); +#endif + return GenericValue(); +} + } // End extern "C" void Interpreter::initializeExternalFunctions() { - FuncNames["lle_X_atexit"] = lle_X_atexit; + FuncNames["lle_X_putchar"] = lle_X_putchar; + FuncNames["lle_X__IO_putc"] = lle_X__IO_putc; FuncNames["lle_X_exit"] = lle_X_exit; FuncNames["lle_X_abort"] = lle_X_abort; - + FuncNames["lle_X_malloc"] = lle_X_malloc; + FuncNames["lle_X_calloc"] = lle_X_calloc; + FuncNames["lle_X_realloc"] = lle_X_realloc; + FuncNames["lle_X_free"] = lle_X_free; + FuncNames["lle_X_atoi"] = lle_X_atoi; + FuncNames["lle_X_pow"] = lle_X_pow; + FuncNames["lle_X_sin"] = lle_X_sin; + FuncNames["lle_X_cos"] = lle_X_cos; + FuncNames["lle_X_exp"] = lle_X_exp; + FuncNames["lle_X_log"] = lle_X_log; + FuncNames["lle_X_floor"] = lle_X_floor; + FuncNames["lle_X_srand"] = lle_X_srand; + FuncNames["lle_X_rand"] = lle_X_rand; +#ifdef HAVE_RAND48 + FuncNames["lle_X_drand48"] = lle_X_drand48; + FuncNames["lle_X_srand48"] = lle_X_srand48; + FuncNames["lle_X_lrand48"] = lle_X_lrand48; +#endif + FuncNames["lle_X_sqrt"] = lle_X_sqrt; + FuncNames["lle_X_puts"] = lle_X_puts; FuncNames["lle_X_printf"] = lle_X_printf; FuncNames["lle_X_sprintf"] = lle_X_sprintf; FuncNames["lle_X_sscanf"] = lle_X_sscanf; FuncNames["lle_X_scanf"] = lle_X_scanf; + FuncNames["lle_i_clock"] = lle_i_clock; + + FuncNames["lle_X_strcmp"] = lle_X_strcmp; + FuncNames["lle_X_strcat"] = lle_X_strcat; + FuncNames["lle_X_strcpy"] = lle_X_strcpy; + FuncNames["lle_X_strlen"] = lle_X_strlen; + FuncNames["lle_X___strdup"] = lle_X___strdup; + FuncNames["lle_X_memset"] = lle_X_memset; + FuncNames["lle_X_memcpy"] = lle_X_memcpy; + FuncNames["lle_X_memmove"] = lle_X_memmove; + + FuncNames["lle_X_fopen"] = lle_X_fopen; + FuncNames["lle_X_fclose"] = lle_X_fclose; + FuncNames["lle_X_feof"] = lle_X_feof; + FuncNames["lle_X_fread"] = lle_X_fread; + FuncNames["lle_X_fwrite"] = lle_X_fwrite; + FuncNames["lle_X_fgets"] = lle_X_fgets; + FuncNames["lle_X_fflush"] = lle_X_fflush; + FuncNames["lle_X_fgetc"] = lle_X_getc; + FuncNames["lle_X_getc"] = lle_X_getc; + FuncNames["lle_X__IO_getc"] = lle_X__IO_getc; + FuncNames["lle_X_fputc"] = lle_X_fputc; + FuncNames["lle_X_ungetc"] = lle_X_ungetc; FuncNames["lle_X_fprintf"] = lle_X_fprintf; + FuncNames["lle_X_freopen"] = lle_X_freopen; + + FuncNames["lle_X___cxa_guard_acquire"] = lle_X___cxa_guard_acquire; + FuncNames["lle_X____cxa_guard_release"] = lle_X___cxa_guard_release; } -- GitLab From 483e12e09e0d9016a754be6c45e967435f8d31e0 Mon Sep 17 00:00:00 2001 From: Tanya Lattner Date: Thu, 22 Jan 2009 20:11:17 +0000 Subject: [PATCH 023/682] Regenerated configure after backing out 62553 and r62616. llvm-svn: 62778 --- llvm/configure | 434 --------------------------- llvm/include/llvm/Config/config.h.in | 6 - 2 files changed, 440 deletions(-) diff --git a/llvm/configure b/llvm/configure index 2ee80e749723..19dfdf679923 100755 --- a/llvm/configure +++ b/llvm/configure @@ -27715,113 +27715,6 @@ echo "$as_me: WARNING: dlopen() not found - disabling plugin support" >&2;} fi -{ echo "$as_me:$LINENO: checking for library containing ffi_call" >&5 -echo $ECHO_N "checking for library containing ffi_call... $ECHO_C" >&6; } -if test "${ac_cv_search_ffi_call+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_func_search_save_LIBS=$LIBS -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char ffi_call (); -int -main () -{ -return ffi_call (); - ; - return 0; -} -_ACEOF -for ac_lib in '' ffi; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - 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 - ac_cv_search_ffi_call=$ac_res -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - -fi - -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if test "${ac_cv_search_ffi_call+set}" = set; then - break -fi -done -if test "${ac_cv_search_ffi_call+set}" = set; then - : -else - ac_cv_search_ffi_call=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ echo "$as_me:$LINENO: result: $ac_cv_search_ffi_call" >&5 -echo "${ECHO_T}$ac_cv_search_ffi_call" >&6; } -ac_res=$ac_cv_search_ffi_call -if test "$ac_res" != no; then - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -cat >>confdefs.h <<\_ACEOF -#define HAVE_LIBFFI 1 -_ACEOF - -else - { echo "$as_me:$LINENO: WARNING: libffi not found - disabling external calls from interpreter" >&5 -echo "$as_me: WARNING: libffi not found - disabling external calls from interpreter" >&2;} -fi - - { echo "$as_me:$LINENO: checking for library containing mallinfo" >&5 echo $ECHO_N "checking for library containing mallinfo... $ECHO_C" >&6; } if test "${ac_cv_search_mallinfo+set}" = set; then @@ -30064,333 +29957,6 @@ else fi -if test "${ac_cv_header_ffi_ffi_h+set}" = set; then - { echo "$as_me:$LINENO: checking for ffi/ffi.h" >&5 -echo $ECHO_N "checking for ffi/ffi.h... $ECHO_C" >&6; } -if test "${ac_cv_header_ffi_ffi_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_ffi_ffi_h" >&5 -echo "${ECHO_T}$ac_cv_header_ffi_ffi_h" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking ffi/ffi.h usability" >&5 -echo $ECHO_N "checking ffi/ffi.h usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -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_compile") 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_objext' - { (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 - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking ffi/ffi.h presence" >&5 -echo $ECHO_N "checking ffi/ffi.h presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -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_cpp conftest.$ac_ext") 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); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: ffi/ffi.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: ffi/ffi.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: ffi/ffi.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: ffi/ffi.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: ffi/ffi.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: ffi/ffi.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: ffi/ffi.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi/ffi.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: ffi/ffi.h: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## ----------------------------------- ## -## Report this to llvmbugs@cs.uiuc.edu ## -## ----------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for ffi/ffi.h" >&5 -echo $ECHO_N "checking for ffi/ffi.h... $ECHO_C" >&6; } -if test "${ac_cv_header_ffi_ffi_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_ffi_ffi_h=$ac_header_preproc -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_ffi_ffi_h" >&5 -echo "${ECHO_T}$ac_cv_header_ffi_ffi_h" >&6; } - -fi -if test $ac_cv_header_ffi_ffi_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define FFI_HEADER "ffi/ffi.h" -_ACEOF - -fi - - -if test "${ac_cv_header_ffi_h+set}" = set; then - { echo "$as_me:$LINENO: checking for ffi.h" >&5 -echo $ECHO_N "checking for ffi.h... $ECHO_C" >&6; } -if test "${ac_cv_header_ffi_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_ffi_h" >&5 -echo "${ECHO_T}$ac_cv_header_ffi_h" >&6; } -else - # Is the header compilable? -{ echo "$as_me:$LINENO: checking ffi.h usability" >&5 -echo $ECHO_N "checking ffi.h usability... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -$ac_includes_default -#include -_ACEOF -rm -f conftest.$ac_objext -if { (ac_try="$ac_compile" -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_compile") 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_objext' - { (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 - ac_header_compiler=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_compiler=no -fi - -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 -echo "${ECHO_T}$ac_header_compiler" >&6; } - -# Is the header present? -{ echo "$as_me:$LINENO: checking ffi.h presence" >&5 -echo $ECHO_N "checking ffi.h presence... $ECHO_C" >&6; } -cat >conftest.$ac_ext <<_ACEOF -/* confdefs.h. */ -_ACEOF -cat confdefs.h >>conftest.$ac_ext -cat >>conftest.$ac_ext <<_ACEOF -/* end confdefs.h. */ -#include -_ACEOF -if { (ac_try="$ac_cpp conftest.$ac_ext" -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_cpp conftest.$ac_ext") 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); } >/dev/null; then - if test -s conftest.err; then - ac_cpp_err=$ac_c_preproc_warn_flag - ac_cpp_err=$ac_cpp_err$ac_c_werror_flag - else - ac_cpp_err= - fi -else - ac_cpp_err=yes -fi -if test -z "$ac_cpp_err"; then - ac_header_preproc=yes -else - echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_header_preproc=no -fi - -rm -f conftest.err conftest.$ac_ext -{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 -echo "${ECHO_T}$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in - yes:no: ) - { echo "$as_me:$LINENO: WARNING: ffi.h: accepted by the compiler, rejected by the preprocessor!" >&5 -echo "$as_me: WARNING: ffi.h: accepted by the compiler, rejected by the preprocessor!" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi.h: proceeding with the compiler's result" >&5 -echo "$as_me: WARNING: ffi.h: proceeding with the compiler's result" >&2;} - ac_header_preproc=yes - ;; - no:yes:* ) - { echo "$as_me:$LINENO: WARNING: ffi.h: present but cannot be compiled" >&5 -echo "$as_me: WARNING: ffi.h: present but cannot be compiled" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi.h: check for missing prerequisite headers?" >&5 -echo "$as_me: WARNING: ffi.h: check for missing prerequisite headers?" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi.h: see the Autoconf documentation" >&5 -echo "$as_me: WARNING: ffi.h: see the Autoconf documentation" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi.h: section \"Present But Cannot Be Compiled\"" >&5 -echo "$as_me: WARNING: ffi.h: section \"Present But Cannot Be Compiled\"" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi.h: proceeding with the preprocessor's result" >&5 -echo "$as_me: WARNING: ffi.h: proceeding with the preprocessor's result" >&2;} - { echo "$as_me:$LINENO: WARNING: ffi.h: in the future, the compiler will take precedence" >&5 -echo "$as_me: WARNING: ffi.h: in the future, the compiler will take precedence" >&2;} - ( cat <<\_ASBOX -## ----------------------------------- ## -## Report this to llvmbugs@cs.uiuc.edu ## -## ----------------------------------- ## -_ASBOX - ) | sed "s/^/$as_me: WARNING: /" >&2 - ;; -esac -{ echo "$as_me:$LINENO: checking for ffi.h" >&5 -echo $ECHO_N "checking for ffi.h... $ECHO_C" >&6; } -if test "${ac_cv_header_ffi_h+set}" = set; then - echo $ECHO_N "(cached) $ECHO_C" >&6 -else - ac_cv_header_ffi_h=$ac_header_preproc -fi -{ echo "$as_me:$LINENO: result: $ac_cv_header_ffi_h" >&5 -echo "${ECHO_T}$ac_cv_header_ffi_h" >&6; } - -fi -if test $ac_cv_header_ffi_h = yes; then - -cat >>confdefs.h <<\_ACEOF -#define FFI_HEADER "ffi.h" -_ACEOF - -fi - - - { echo "$as_me:$LINENO: checking for HUGE_VAL sanity" >&5 diff --git a/llvm/include/llvm/Config/config.h.in b/llvm/include/llvm/Config/config.h.in index df1a2d38be50..b70cfe140f4e 100644 --- a/llvm/include/llvm/Config/config.h.in +++ b/llvm/include/llvm/Config/config.h.in @@ -20,9 +20,6 @@ /* Define if threads enabled */ #undef ENABLE_THREADS -/* Path to ffi.h */ -#undef FFI_HEADER - /* Define to 1 if you have `alloca', as a function or macro. */ #undef HAVE_ALLOCA @@ -187,9 +184,6 @@ /* Define to 1 if you have the `elf' library (-lelf). */ #undef HAVE_LIBELF -/* Define to 1 if you have the libffi library (-lffi). */ -#undef HAVE_LIBFFI - /* Define to 1 if you have the `imagehlp' library (-limagehlp). */ #undef HAVE_LIBIMAGEHLP -- GitLab From 92d48a71f551093efbbbd53f402c4257cf91f8d3 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 20:27:48 +0000 Subject: [PATCH 024/682] Fix RegionStore::getLValueElement() to handle the case when the base region is not an ElementRegion (also do some cleanups of its core logic). This gets array-struct.c to work with RegionStore. llvm-svn: 62781 --- clang/lib/Analysis/RegionStore.cpp | 87 +++++++++++++++++------------- clang/test/Analysis/array-struct.c | 5 +- clang/test/Analysis/outofbound.c | 2 +- 3 files changed, 54 insertions(+), 40 deletions(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 5a13a1dbc25b..6f0ec1d0b73b 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -327,49 +327,62 @@ SVal RegionStoreManager::getLValueElement(const GRState* St, if (Base.isUnknownOrUndef() || isa(Base)) return Base; - loc::MemRegionVal& BaseL = cast(Base); - - // Pointer of any type can be cast and used as array base. We do not support - // that case yet. - if (!isa(BaseL.getRegion())) { - // Record what we have seen in real code. - assert(isa(BaseL.getRegion())); + // Only handle integer offsets... for now. + if (!isa(Offset)) return UnknownVal(); - } - - // We expect BaseR is an ElementRegion, not a base VarRegion. - - const ElementRegion* ElemR = cast(BaseL.getRegion()); - - SVal Idx = ElemR->getIndex(); - nonloc::ConcreteInt *CI1, *CI2; + const TypedRegion *BaseRegion = + cast(cast(Base).getRegion()); - // Only handle integer indices for now. - if ((CI1 = dyn_cast(&Idx)) && - (CI2 = dyn_cast(&Offset))) { - - // Temporary SVal to hold a potential signed and extended APSInt. - SVal SignedInt; - - // Index might be unsigned. We have to convert it to signed. It might also - // be less wide than the size. We have to extend it. - if (CI2->getValue().isUnsigned() || - CI2->getValue().getBitWidth() < CI1->getValue().getBitWidth()) { - llvm::APSInt SI = CI2->getValue(); - if (CI2->getValue().getBitWidth() < CI1->getValue().getBitWidth()) - SI.extend(CI1->getValue().getBitWidth()); - SI.setIsSigned(true); - SignedInt = nonloc::ConcreteInt(getBasicVals().getValue(SI)); - CI2 = cast(&SignedInt); - } + // Pointer of any type can be cast and used as array base. + const ElementRegion *ElemR = dyn_cast(BaseRegion); + + if (!ElemR) { + // + // If the base region is not an ElementRegion, create one. + // This can happen in the following example: + // + // char *p = __builtin_alloc(10); + // p[1] = 8; + // + // Observe that 'p' binds to an AnonTypedRegion. + // + return loc::MemRegionVal(MRMgr.getElementRegion(Offset, BaseRegion)); + } + + SVal BaseIdx = ElemR->getIndex(); + + if (!isa(BaseIdx)) + return UnknownVal(); + + const llvm::APSInt& BaseIdxI = cast(BaseIdx).getValue(); + const llvm::APSInt& OffI = cast(Offset).getValue(); + assert(BaseIdxI.isSigned()); + + // FIXME: This appears to be the assumption of this code. We should review + // whether or not BaseIdxI.getBitWidth() < OffI.getBitWidth(). If it + // can't we need to put a comment here. If it can, we should handle it. + assert(BaseIdxI.getBitWidth() >= OffI.getBitWidth()); - SVal NewIdx = CI1->EvalBinOp(getBasicVals(), BinaryOperator::Add, *CI2); - return loc::MemRegionVal(MRMgr.getElementRegion(NewIdx, - ElemR->getArrayRegion())); + const TypedRegion *ArrayR = ElemR->getArrayRegion(); + SVal NewIdx; + + if (OffI.isUnsigned() || OffI.getBitWidth() < BaseIdxI.getBitWidth()) { + // 'Offset' might be unsigned. We have to convert it to signed and + // possibly extend it. + llvm::APSInt Tmp = OffI; + + if (OffI.getBitWidth() < BaseIdxI.getBitWidth()) + Tmp.extend(BaseIdxI.getBitWidth()); + + Tmp.setIsSigned(true); + Tmp += BaseIdxI; // Compute the new offset. + NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(Tmp)); } + else + NewIdx = nonloc::ConcreteInt(getBasicVals().getValue(BaseIdxI + OffI)); - return UnknownVal(); + return loc::MemRegionVal(MRMgr.getElementRegion(NewIdx, ArrayR)); } SVal RegionStoreManager::getSizeInElements(const GRState* St, diff --git a/clang/test/Analysis/array-struct.c b/clang/test/Analysis/array-struct.c index 1d5e9448e928..4257220f9bd6 100644 --- a/clang/test/Analysis/array-struct.c +++ b/clang/test/Analysis/array-struct.c @@ -1,5 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s -// DISABLE: clang -analyze -checker-simple -analyzer-store-region -verify %s +// RUN: clang -analyze -checker-simple -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s struct s { int data; diff --git a/clang/test/Analysis/outofbound.c b/clang/test/Analysis/outofbound.c index ab9c0cfa4c8a..b0c2db438629 100644 --- a/clang/test/Analysis/outofbound.c +++ b/clang/test/Analysis/outofbound.c @@ -2,5 +2,5 @@ char f1() { char* s = "abcd"; - return s[5]; // expected-warning{{Load or store into an out-of-bound memory position.}} + return s[6]; // expected-warning{{Load or store into an out-of-bound memory position.}} } -- GitLab From e54b87f477ff073d8543d13d06acb620617c5780 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 20:36:33 +0000 Subject: [PATCH 025/682] Test more array logic in outofbound.c llvm-svn: 62782 --- clang/test/Analysis/outofbound.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/outofbound.c b/clang/test/Analysis/outofbound.c index b0c2db438629..e496425eb91a 100644 --- a/clang/test/Analysis/outofbound.c +++ b/clang/test/Analysis/outofbound.c @@ -2,5 +2,6 @@ char f1() { char* s = "abcd"; - return s[6]; // expected-warning{{Load or store into an out-of-bound memory position.}} + char c = s[4]; // no-warning + return s[5] + c; // expected-warning{{Load or store into an out-of-bound memory position.}} } -- GitLab From 8c5ffd07610476f5e7fd95fca8817e12c76584f4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 20:57:52 +0000 Subject: [PATCH 026/682] Adjust to api change. llvm-svn: 62785 --- clang/Driver/clang.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 900e0a03905b..9d28720ce2d1 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -833,7 +833,7 @@ static std::string CreateTargetTriple() { Triple.resize(DarwinDashIdx + strlen("-darwin")); // Only add the major part of the os version. - std::string Version = llvm::sys::osVersion(); + std::string Version = llvm::sys::getOSVersion(); Triple += Version.substr(0, Version.find('.')); } } -- GitLab From f4013373cd9919fb7f4425ad549e4fdf0c875fba Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Thu, 22 Jan 2009 21:35:57 +0000 Subject: [PATCH 027/682] introduce a useful abstraction to find out if a Use is in the call position of an instruction llvm-svn: 62788 --- llvm/include/llvm/Support/CallSite.h | 4 ++++ llvm/lib/Analysis/IPA/CallGraph.cpp | 3 ++- llvm/lib/Transforms/IPO/ArgumentPromotion.cpp | 2 +- llvm/lib/Transforms/IPO/IPConstantPropagation.cpp | 7 ++++--- llvm/lib/Transforms/IPO/StructRetPromotion.cpp | 5 +---- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/Support/CallSite.h b/llvm/include/llvm/Support/CallSite.h index 520f8de79fb5..dc41590fb8a5 100644 --- a/llvm/include/llvm/Support/CallSite.h +++ b/llvm/include/llvm/Support/CallSite.h @@ -180,6 +180,10 @@ public: return getInstruction() < CS.getInstruction(); } + bool isCallee(Value::use_iterator UI) const { + return getInstruction()->op_begin() == &UI.getUse(); + } + private: /// Returns the operand number of the first argument unsigned getArgumentOffset() const { diff --git a/llvm/lib/Analysis/IPA/CallGraph.cpp b/llvm/lib/Analysis/IPA/CallGraph.cpp index c8f1d920658e..ea7d7feb4cd8 100644 --- a/llvm/lib/Analysis/IPA/CallGraph.cpp +++ b/llvm/lib/Analysis/IPA/CallGraph.cpp @@ -126,7 +126,8 @@ private: // Loop over all of the users of the function, looking for non-call uses. for (Value::use_iterator I = F->use_begin(), E = F->use_end(); I != E; ++I) - if ((!isa(*I) && !isa(*I)) || I.getOperandNo()) { + if ((!isa(I) && !isa(I)) + || !CallSite(cast(I)).isCallee(I)) { // Not a call, or being used as a parameter rather than as the callee. ExternalCallingNode->addCalledFunction(CallSite(), Node); break; diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp index 69e427e8ad1b..183e1a1e0a4c 100644 --- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -135,7 +135,7 @@ bool ArgPromotion::PromoteArguments(CallGraphNode *CGN) { // Ensure that this call site is CALLING the function, not passing it as // an argument. - if (UI.getOperandNo() != 0) + if (!CS.isCallee(UI)) return false; } diff --git a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp index 6ae8276d5247..2dc855824691 100644 --- a/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp +++ b/llvm/lib/Transforms/IPO/IPConstantPropagation.cpp @@ -88,11 +88,12 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) { for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) { // Used by a non-instruction, or not the callee of a function, do not // transform. - if (UI.getOperandNo() != 0 || - (!isa(*UI) && !isa(*UI))) + if (!isa(*UI) && !isa(*UI)) return false; CallSite CS = CallSite::get(cast(*UI)); + if (!CS.isCallee(UI)) + return false; // Check out all of the potentially constant arguments. Note that we don't // inspect varargs here. @@ -219,7 +220,7 @@ bool IPCP::PropagateConstantReturn(Function &F) { // Not a call instruction or a call instruction that's not calling F // directly? - if (!Call || UI.getOperandNo() != 0) + if (!Call || !CS.isCallee(UI)) continue; // Call result not used? diff --git a/llvm/lib/Transforms/IPO/StructRetPromotion.cpp b/llvm/lib/Transforms/IPO/StructRetPromotion.cpp index 00556f963352..9f54388aa45e 100644 --- a/llvm/lib/Transforms/IPO/StructRetPromotion.cpp +++ b/llvm/lib/Transforms/IPO/StructRetPromotion.cpp @@ -149,14 +149,11 @@ bool SRETPromotion::isSafeToUpdateAllCallers(Function *F) { FnUseI != FnUseE; ++FnUseI) { // The function is passed in as an argument to (possibly) another function, // we can't change it! - if (FnUseI.getOperandNo() != 0) - return false; - CallSite CS = CallSite::get(*FnUseI); Instruction *Call = CS.getInstruction(); // The function is used by something else than a call or invoke instruction, // we can't change it! - if (!Call) + if (!Call || !CS.isCallee(FnUseI)) return false; CallSite::arg_iterator AI = CS.arg_begin(); Value *FirstArg = *AI; -- GitLab From 1f3411de47805b1cd44b4734b19e032cbdc2b8c7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 22 Jan 2009 21:58:43 +0000 Subject: [PATCH 028/682] Don't create ISD::FNEG nodes after legalize if they aren't legal. Simplify x+0 to x in unsafe-fp-math mode. This avoids a bunch of redundant work in many cases, because in unsafe-fp-math mode, ISD::FADD with a constant is considered free to negate, so the DAGCombiner often negates x+0 to -0-x thinking it's free, when in reality the end result is -x, which is more expensive than x. Also, combine x*0 to 0. This fixes PR3374. llvm-svn: 62789 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 23 +- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 +- llvm/test/CodeGen/X86/negate-add-zero.ll | 1145 +++++++++++++++++ 3 files changed, 1175 insertions(+), 8 deletions(-) create mode 100644 llvm/test/CodeGen/X86/negate-add-zero.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index f7c1d061c6bd..e494da3644d6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3814,6 +3814,9 @@ SDValue DAGCombiner::visitFADD(SDNode *N) { // canonicalize constant to RHS if (N0CFP && !N1CFP) return DAG.getNode(ISD::FADD, VT, N1, N0); + // fold (A + 0) -> A + if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) + return N0; // fold (A + (-B)) -> A-B if (isNegatibleForFree(N1, LegalOperations) == 2) return DAG.getNode(ISD::FSUB, VT, N0, @@ -3852,7 +3855,8 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) { if (isNegatibleForFree(N1, LegalOperations)) return GetNegatedExpression(N1, DAG, LegalOperations); - return DAG.getNode(ISD::FNEG, VT, N1); + if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) + return DAG.getNode(ISD::FNEG, VT, N1); } // fold (A-(-B)) -> A+B if (isNegatibleForFree(N1, LegalOperations)) @@ -3881,12 +3885,16 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { // canonicalize constant to RHS if (N0CFP && !N1CFP) return DAG.getNode(ISD::FMUL, VT, N1, N0); + // fold (A * 0) -> 0 + if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) + return N1; // fold (fmul X, 2.0) -> (fadd X, X) if (N1CFP && N1CFP->isExactlyValue(+2.0)) return DAG.getNode(ISD::FADD, VT, N0, N0); // fold (fmul X, -1.0) -> (fneg X) if (N1CFP && N1CFP->isExactlyValue(-1.0)) - return DAG.getNode(ISD::FNEG, VT, N0); + if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) + return DAG.getNode(ISD::FNEG, VT, N0); // -X * -Y -> X*Y if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) { @@ -3970,10 +3978,13 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { const APFloat& V = N1CFP->getValueAPF(); // copysign(x, c1) -> fabs(x) iff ispos(c1) // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1) - if (!V.isNegative()) - return DAG.getNode(ISD::FABS, VT, N0); - else - return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); + if (!V.isNegative()) { + if (!LegalOperations || TLI.isOperationLegal(ISD::FABS, VT)) + return DAG.getNode(ISD::FABS, VT, N0); + } else { + if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) + return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); + } } // copysign(fabs(x), y) -> copysign(x, y) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index a08856022ab6..29744862089d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -27,6 +27,7 @@ #include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetData.h" #include "llvm/Target/TargetLowering.h" +#include "llvm/Target/TargetOptions.h" #include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Support/CommandLine.h" @@ -2391,16 +2392,26 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, case ISD::UREM: case ISD::MULHU: case ISD::MULHS: - assert(VT.isInteger() && "This operator does not apply to FP types!"); - // fall through case ISD::MUL: case ISD::SDIV: case ISD::SREM: + assert(VT.isInteger() && "This operator does not apply to FP types!"); + // fall through case ISD::FADD: case ISD::FSUB: case ISD::FMUL: case ISD::FDIV: case ISD::FREM: + if (UnsafeFPMath && Opcode == ISD::FADD) { + // 0+x --> x + if (ConstantFPSDNode *CFP = dyn_cast(N1)) + if (CFP->getValueAPF().isZero()) + return N2; + // x+0 --> x + if (ConstantFPSDNode *CFP = dyn_cast(N2)) + if (CFP->getValueAPF().isZero()) + return N1; + } assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); break; diff --git a/llvm/test/CodeGen/X86/negate-add-zero.ll b/llvm/test/CodeGen/X86/negate-add-zero.ll new file mode 100644 index 000000000000..59a2bd09c18f --- /dev/null +++ b/llvm/test/CodeGen/X86/negate-add-zero.ll @@ -0,0 +1,1145 @@ +; RUN: llvm-as < %s | llc -enable-unsafe-fp-math -march=x86 | not grep xor +; PR3374 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + %struct.AtomList = type { %"struct.CDSListRep"* } + %struct.AtomTree = type { %struct.IVM*, %"struct.CDSList >" } + %"struct.CDS::DefaultAlloc" = type <{ i8 }> + %"struct.CDS::SingularError" = type { %"struct.CDS::exception" } + %"struct.CDS::auto_ptr" = type { %struct.IVMAtom* } + %"struct.CDS::exception" = type { [300 x i8] } + %"struct.CDSList >" = type { %"struct.CDSListRep >"* } + %"struct.CDSList >" = type { %"struct.CDSListRep >"* } + %"struct.CDSList" = type { %"struct.CDSListRep"* } + %"struct.CDSList" = type { %"struct.CDSListRep"* } + %"struct.CDSList" = type { %"struct.CDSListRep"* } + %"struct.CDSList >" = type { %"struct.CDSListRep >"* } + %"struct.CDSList" = type { %"struct.CDSListRep"* } + %"struct.CDSListRep >" = type opaque + %"struct.CDSListRep >" = type opaque + %"struct.CDSListRep" = type { i32, i32, %struct.HingeNode**, i32 } + %"struct.CDSListRep" = type { i32, i32, %struct.IVMAtom**, i32 } + %"struct.CDSListRep" = type opaque + %"struct.CDSListRep" = type opaque + %"struct.CDSListRep >" = type opaque + %"struct.CDSListRep" = type { i32, i32, i32*, i32 } + %"struct.CDSMatrixBase" = type { %"struct.CDSMatrixRep"* } + %"struct.CDSMatrixRep" = type opaque + %"struct.CDSStringRep" = type { i8*, i32, i32, i32, i32 } + %"struct.CDSVector" = type { %"struct.CDSVectorBase" } + %"struct.CDSVector" = type { %"struct.CDSVectorBase" } + %"struct.CDSVectorBase" = type { %"struct.CDSVectorRep"* } + %"struct.CDSVectorBase" = type { %"struct.CDSVectorRep"* } + %"struct.CDSVectorRep" = type { i32, %"struct.CDS::DefaultAlloc", %struct.Vec3*, i32 } + %"struct.CDSVectorRep" = type { i32, %"struct.CDS::DefaultAlloc", double*, i32 } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrix" = type { %"struct.FixedMatrixBase" } + %"struct.FixedMatrixBase" = type { [1 x double] } + %"struct.FixedMatrixBase" = type { [3 x double] } + %"struct.FixedMatrixBase" = type { [6 x double] } + %"struct.FixedMatrixBase" = type { [4 x double] } + %"struct.FixedMatrixBase" = type { [12 x double] } + %"struct.FixedMatrixBase" = type { [9 x double] } + %"struct.FixedMatrixBase" = type { [18 x double] } + %"struct.FixedMatrixBase" = type { [25 x double] } + %"struct.FixedMatrixBase" = type { [30 x double] } + %"struct.FixedMatrixBase" = type { [36 x double] } + %"struct.FixedVector" = type { %"struct.FixedVectorBase" } + %"struct.FixedVector" = type { %"struct.FixedVectorBase" } + %"struct.FixedVectorBase" = type { [2 x double] } + %"struct.FixedVectorBase" = type { [5 x double] } + %struct.HNodeOrigin = type { %struct.HingeNode } + %struct.HNodeRotate2 = type { %"struct.HingeNodeSpec<2>", %struct.Vec3, %struct.Vec3, %struct.Vec3, %struct.Vec3, %struct.Vec3, %struct.Mat3, %struct.Mat3, %struct.Vec3, %"struct.CDS::auto_ptr", %"struct.CDSVector" } + %struct.HNodeRotate3 = type { %"struct.HingeNodeSpec<3>", %struct.Vec4, %struct.Vec4, %struct.Vec4, %struct.Vec3, %"struct.CDS::auto_ptr", %"struct.CDSVector", double, double, double, double, double, double, i8 } + %struct.HNodeTorsion = type { %"struct.HingeNodeSpec<1>", %struct.Vec3, %"struct.CDSVector", %struct.Vec3, %struct.Mat3 } + %struct.HNodeTranslate = type { %"struct.HingeNodeSpec<3>", %struct.IVMAtom*, %struct.Vec3, %"struct.CDSVector" } + %struct.HNodeTranslateRotate2 = type { %"struct.HingeNodeSpec<5>", %struct.Vec3, %struct.Vec3, %struct.Vec3, %struct.Vec3, %struct.Vec3, %struct.Mat3, %struct.Mat3, %struct.Vec3, %"struct.CDS::auto_ptr", %"struct.CDSVector" } + %struct.HNodeTranslateRotate3 = type { %"struct.HingeNodeSpec<6>", %struct.Vec4, %struct.Vec4, %struct.Vec4, %struct.Vec3, %"struct.CDS::auto_ptr", %"struct.CDSVector", double, double, double, double, double, double, i8 } + %struct.HingeNode = type { i32 (...)**, %struct.HingeNode*, %"struct.CDSList", i32, %struct.AtomList, %"struct.FixedMatrix", %"struct.FixedMatrix", %struct.PhiMatrix, %struct.Mat6, %struct.Mat6, %"struct.FixedMatrix", %struct.Mat6, %"struct.FixedMatrix", %struct.Mat3, %struct.Mat6, %struct.IVM*, %struct.IVMAtom* } + %"struct.HingeNodeSpec<1>" = type { %struct.HingeNode, i32, double, %struct.InertiaTensor, %struct.Mat6, %struct.Vec3, %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix" } + %"struct.HingeNodeSpec<2>" = type { %struct.HingeNode, i32, double, %struct.InertiaTensor, %struct.Mat6, %struct.Vec3, %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedMatrix", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedMatrix", %"struct.FixedMatrix" } + %"struct.HingeNodeSpec<3>" = type { %struct.HingeNode, i32, double, %struct.InertiaTensor, %struct.Mat6, %struct.Vec3, %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix" } + %"struct.HingeNodeSpec<5>" = type { %struct.HingeNode, i32, double, %struct.InertiaTensor, %struct.Mat6, %struct.Vec3, %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedMatrix", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedVector", %"struct.FixedMatrix", %"struct.FixedMatrix" } + %"struct.HingeNodeSpec<6>" = type { %struct.HingeNode, i32, double, %struct.InertiaTensor, %struct.Mat6, %struct.Vec3, %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %struct.Mat6, %"struct.FixedMatrix", %"struct.FixedMatrix", %"struct.FixedMatrix", %struct.Mat6, %struct.Mat6 } + %struct.IVM = type { i32 (...)**, %struct.AtomTree*, %struct.Integrator*, %struct.LengthConstraints*, i32, i32, i32, i8, i8, i8, i8, double, double, double, double, double, double, double, double, double, i32, double, double, double, double, double, double, %"struct.CDSList", %"struct.CDSList >", %struct.AtomList, %"struct.CDSList >", %"struct.CDSList", %struct.String, %"struct.CDSList", i32 (%"struct.CDSVector"*)*, double (%"struct.CDSVector"*, %"struct.CDSVector"*)*, i32 (%"struct.CDSVector"*)*, double (%"struct.CDSVector"*, %"struct.CDSVector"*)* } + %struct.IVMAtom = type { i32, %struct.HingeNode*, %struct.AtomList, %struct.Vec3, %struct.Vec3, %struct.Vec3, double, double } + %struct.InertiaTensor = type { %struct.Mat3 } + %struct.Integrator = type { i32 (...)**, %"struct.CDSVector", %"struct.CDSVector", %struct.IVM* } + %"struct.InternalDynamics::HingeSpec" = type { %struct.String, i32, i32, %"struct.CDSList" } + %struct.LengthConstraints = type { double, i32, i32, %struct.IVM*, %struct.LengthConstraintsPrivates* } + %struct.LengthConstraintsPrivates = type opaque + %struct.Mat3 = type { %"struct.FixedMatrix" } + %struct.Mat6 = type { %"struct.FixedMatrixBase" } + %"struct.MatrixTools::InverseResults >" = type { %"struct.CDSVector", i32 } + %struct.PhiMatrix = type { %struct.Vec3 } + %struct.PhiMatrixTranspose = type { %struct.PhiMatrix* } + %struct.RMat = type { %"struct.CDSMatrixBase" } + %struct.String = type { %"struct.CDSStringRep"* } + %"struct.SubMatrix >" = type { %struct.Mat6*, i32, i32, i32, i32 } + %"struct.SubVector >" = type { %"struct.CDSVector"*, i32, i32 } + %"struct.SubVector >" = type { %"struct.FixedMatrix"*, i32, i32 } + %struct.Vec3 = type { %"struct.FixedMatrix" } + %struct.Vec4 = type { %"struct.FixedMatrix" } + %struct.__class_type_info_pseudo = type { %struct.__type_info_pseudo } + %struct.__si_class_type_info_pseudo = type { %struct.__type_info_pseudo, %"struct.std::type_info"* } + %struct.__type_info_pseudo = type { i8*, i8* } + %"struct.std::basic_ios >" = type { %"struct.std::ios_base", %"struct.std::basic_ostream >"*, i8, i8, %"struct.std::basic_streambuf >"*, %"struct.std::ctype"*, %"struct.std::num_get > >"*, %"struct.std::num_get > >"* } + %"struct.std::basic_ostream >" = type { i32 (...)**, %"struct.std::basic_ios >" } + %"struct.std::basic_streambuf >" = type { i32 (...)**, i8*, i8*, i8*, i8*, i8*, i8*, %"struct.std::locale" } + %"struct.std::ctype" = type { %"struct.std::locale::facet", i32*, i8, i32*, i32*, i32*, i8, [256 x i8], [256 x i8], i8 } + %"struct.std::ios_base" = type { i32 (...)**, i32, i32, i32, i32, i32, %"struct.std::ios_base::_Callback_list"*, %"struct.std::ios_base::_Words", [8 x %"struct.std::ios_base::_Words"], i32, %"struct.std::ios_base::_Words"*, %"struct.std::locale" } + %"struct.std::ios_base::_Callback_list" = type { %"struct.std::ios_base::_Callback_list"*, void (i32, %"struct.std::ios_base"*, i32)*, i32, i32 } + %"struct.std::ios_base::_Words" = type { i8*, i32 } + %"struct.std::locale" = type { %"struct.std::locale::_Impl"* } + %"struct.std::locale::_Impl" = type { i32, %"struct.std::locale::facet"**, i32, %"struct.std::locale::facet"**, i8** } + %"struct.std::locale::facet" = type { i32 (...)**, i32 } + %"struct.std::num_get > >" = type { %"struct.std::locale::facet" } + %"struct.std::type_info" = type { i32 (...)**, i8* } +@_ZN9HingeNode7DEG2RADE = external constant double, align 8 ; [#uses=0] +@"\01LC" = external constant [8 x i8] ; <[8 x i8]*> [#uses=0] +@"\01LC1" = external constant [7 x i8] ; <[7 x i8]*> [#uses=0] +@"\01LC2" = external constant [10 x i8] ; <[10 x i8]*> [#uses=0] +@"\01LC3" = external constant [5 x i8] ; <[5 x i8]*> [#uses=0] +@"\01LC4" = external constant [8 x i8] ; <[8 x i8]*> [#uses=0] +@"\01LC5" = external constant [8 x i8] ; <[8 x i8]*> [#uses=0] +@"\01LC6" = external constant [7 x i8] ; <[7 x i8]*> [#uses=0] +@"\01LC7" = external constant [8 x i8] ; <[8 x i8]*> [#uses=0] +@"\01LC8" = external constant [3 x i8] ; <[3 x i8]*> [#uses=0] +@"\01LC9" = external constant [3 x i8] ; <[3 x i8]*> [#uses=0] +@"\01LC10" = external constant [3 x i8] ; <[3 x i8]*> [#uses=0] +@_ZStL8__ioinit = external global %"struct.CDS::DefaultAlloc" ; <%"struct.CDS::DefaultAlloc"*> [#uses=0] +@__dso_handle = external global i8* ; [#uses=0] +@_ZTIN9HingeNode17VirtualBaseMethodE = external constant %struct.__class_type_info_pseudo ; <%struct.__class_type_info_pseudo*> [#uses=0] +@_ZTVN10__cxxabiv117__class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=0] +@_ZTSN9HingeNode17VirtualBaseMethodE = external constant [32 x i8], align 4 ; <[32 x i8]*> [#uses=0] +@_ZTV9HingeNode = external constant [31 x i32 (...)*], align 32 ; <[31 x i32 (...)*]*> [#uses=0] +@_ZTI9HingeNode = external constant %struct.__class_type_info_pseudo ; <%struct.__class_type_info_pseudo*> [#uses=0] +@_ZTS9HingeNode = external constant [11 x i8] ; <[11 x i8]*> [#uses=0] +@_ZTV11HNodeOrigin = external constant [31 x i32 (...)*], align 32 ; <[31 x i32 (...)*]*> [#uses=0] +@_ZTI11HNodeOrigin = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTVN10__cxxabiv120__si_class_type_infoE = external constant [0 x i32 (...)*] ; <[0 x i32 (...)*]*> [#uses=0] +@_ZTS11HNodeOrigin = external constant [14 x i8] ; <[14 x i8]*> [#uses=0] +@_ZTV13HingeNodeSpecILi1EE = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI13HingeNodeSpecILi1EE = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS13HingeNodeSpecILi1EE = external constant [22 x i8] ; <[22 x i8]*> [#uses=0] +@_ZTV13HingeNodeSpecILi3EE = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI13HingeNodeSpecILi3EE = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS13HingeNodeSpecILi3EE = external constant [22 x i8] ; <[22 x i8]*> [#uses=0] +@_ZTV13HingeNodeSpecILi2EE = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI13HingeNodeSpecILi2EE = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS13HingeNodeSpecILi2EE = external constant [22 x i8] ; <[22 x i8]*> [#uses=0] +@_ZTV13HingeNodeSpecILi6EE = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI13HingeNodeSpecILi6EE = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS13HingeNodeSpecILi6EE = external constant [22 x i8] ; <[22 x i8]*> [#uses=0] +@_ZTV13HingeNodeSpecILi5EE = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI13HingeNodeSpecILi5EE = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS13HingeNodeSpecILi5EE = external constant [22 x i8] ; <[22 x i8]*> [#uses=0] +@_ZSt4cout = external global %"struct.std::basic_ostream >" ; <%"struct.std::basic_ostream >"*> [#uses=0] +@"\01LC11" = external constant [10 x i8] ; <[10 x i8]*> [#uses=0] +@"\01LC12" = external constant [8 x i8] ; <[8 x i8]*> [#uses=0] +@"\01LC13" = external constant [10 x i8] ; <[10 x i8]*> [#uses=0] +@_ZSt4cerr = external global %"struct.std::basic_ostream >" ; <%"struct.std::basic_ostream >"*> [#uses=0] +@"\01LC14" = external constant [29 x i8] ; <[29 x i8]*> [#uses=0] +@"\01LC15" = external constant [11 x i8] ; <[11 x i8]*> [#uses=0] +@"\01LC16" = external constant [13 x i8] ; <[13 x i8]*> [#uses=0] +@"\01LC17" = external constant [21 x i8] ; <[21 x i8]*> [#uses=0] +@"\01LC18" = external constant [8 x i8] ; <[8 x i8]*> [#uses=0] +@"\01LC19" = external constant [4 x i8] ; <[4 x i8]*> [#uses=0] +@"\01LC20" = external constant [42 x i8] ; <[42 x i8]*> [#uses=0] +@_ZTIN16InternalDynamics9ExceptionE = external constant %struct.__class_type_info_pseudo ; <%struct.__class_type_info_pseudo*> [#uses=0] +@_ZTSN16InternalDynamics9ExceptionE = external constant [31 x i8], align 4 ; <[31 x i8]*> [#uses=0] +@_ZTIN3CDS13SingularErrorE = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTSN3CDS13SingularErrorE = external constant [22 x i8] ; <[22 x i8]*> [#uses=0] +@_ZTIN3CDS9exceptionE = external constant %struct.__class_type_info_pseudo ; <%struct.__class_type_info_pseudo*> [#uses=0] +@_ZTSN3CDS9exceptionE = external constant [17 x i8] ; <[17 x i8]*> [#uses=0] +@_ZTV12HNodeTorsion = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI12HNodeTorsion = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS12HNodeTorsion = external constant [15 x i8] ; <[15 x i8]*> [#uses=0] +@_ZTV12HNodeRotate3 = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI12HNodeRotate3 = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS12HNodeRotate3 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0] +@_ZTV12HNodeRotate2 = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI12HNodeRotate2 = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS12HNodeRotate2 = external constant [15 x i8] ; <[15 x i8]*> [#uses=0] +@_ZTV21HNodeTranslateRotate3 = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI21HNodeTranslateRotate3 = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS21HNodeTranslateRotate3 = external constant [24 x i8] ; <[24 x i8]*> [#uses=0] +@_ZTV21HNodeTranslateRotate2 = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI21HNodeTranslateRotate2 = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS21HNodeTranslateRotate2 = external constant [24 x i8] ; <[24 x i8]*> [#uses=0] +@_ZTV14HNodeTranslate = external constant [33 x i32 (...)*], align 32 ; <[33 x i32 (...)*]*> [#uses=0] +@_ZTI14HNodeTranslate = external constant %struct.__si_class_type_info_pseudo ; <%struct.__si_class_type_info_pseudo*> [#uses=0] +@_ZTS14HNodeTranslate = external constant [17 x i8] ; <[17 x i8]*> [#uses=0] +@"\01LC21" = external constant [31 x i8] ; <[31 x i8]*> [#uses=0] +@"\01LC22" = external constant [6 x i8] ; <[6 x i8]*> [#uses=0] +@"\01LC23" = external constant [12 x i8] ; <[12 x i8]*> [#uses=0] +@"\01LC24" = external constant [5 x i8] ; <[5 x i8]*> [#uses=0] +@"\01LC25" = external constant [7 x i8] ; <[7 x i8]*> [#uses=0] +@"\01LC26" = external constant [7 x i8] ; <[7 x i8]*> [#uses=0] +@"\01LC27" = external constant [43 x i8] ; <[43 x i8]*> [#uses=0] +@"\01LC28" = external constant [15 x i8] ; <[15 x i8]*> [#uses=0] +@"\01LC29" = external constant [20 x i8] ; <[20 x i8]*> [#uses=0] +@"\01LC30" = external constant [41 x i8] ; <[41 x i8]*> [#uses=0] +@llvm.global_ctors = external global [1 x { i32, void ()* }] ; <[1 x { i32, void ()* }]*> [#uses=0] + +declare void @_GLOBAL__I__ZN9HingeNode7DEG2RADE() section "__TEXT,__StaticInit,regular,pure_instructions" + +declare void @_ZN9HingeNode16velFromCartesianEv(%struct.HingeNode*) nounwind + +declare i32 @_ZNK9HingeNode6offsetEv(%struct.HingeNode*) nounwind + +declare i32 @_ZNK9HingeNode6getDOFEv(%struct.HingeNode*) nounwind + +declare i32 @_ZNK9HingeNode6getDimEv(%struct.HingeNode*) nounwind + +declare double @_ZN9HingeNode8kineticEEv(%struct.HingeNode*) nounwind + +declare double @_ZN9HingeNode8approxKEEv(%struct.HingeNode*) nounwind + +declare i8* @_ZN9HingeNode4typeEv(%struct.HingeNode*) nounwind + +declare i8* @_ZN11HNodeOrigin4typeEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin5calcPEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin5calcZEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin9calcPandZEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin9calcAccelEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin17calcInternalForceEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin18prepareVelInternalEv(%struct.HNodeOrigin*) nounwind + +declare void @_ZN11HNodeOrigin13propagateSVelERK11FixedVectorIdLi6ELi0EE(%struct.HNodeOrigin*, %"struct.FixedMatrix"*) nounwind + +declare void @_ZN11HNodeOrigin9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%struct.HNodeOrigin*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeOrigin*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%struct.HNodeOrigin*, %"struct.FixedMatrix"*) nounwind + +declare void @_ZN11HNodeOrigin18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES4_(%struct.HNodeOrigin*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin5printEi(%struct.HNodeOrigin*, i32) nounwind + +declare void @_ZN11HNodeOrigin6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeOrigin*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeOrigin*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeOrigin*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeOrigin*, %"struct.CDSVector"*) nounwind + +declare void @_ZN11HNodeOrigin5calcYEv(%struct.HNodeOrigin*) nounwind + +declare i8* @_ZN14HNodeTranslate4typeEv(%struct.HNodeTranslate*) nounwind + +declare i8* @_ZN21HNodeTranslateRotate34typeEv(%struct.HNodeTranslateRotate3*) nounwind + +declare i32 @_ZNK21HNodeTranslateRotate36getDimEv(%struct.HNodeTranslateRotate3*) nounwind + +declare i8* @_ZN12HNodeRotate34typeEv(%struct.HNodeRotate3*) nounwind + +declare i32 @_ZNK12HNodeRotate36getDimEv(%struct.HNodeRotate3*) nounwind + +declare i8* @_ZN12HNodeRotate24typeEv(%struct.HNodeRotate2*) nounwind + +declare i32 @_ZNK12HNodeRotate26getDimEv(%struct.HNodeRotate2*) nounwind + +declare i8* @_ZN21HNodeTranslateRotate24typeEv(%struct.HNodeTranslateRotate2*) nounwind + +declare i32 @_ZNK21HNodeTranslateRotate26getDimEv(%struct.HNodeTranslateRotate2*) nounwind + +declare i8* @_ZN12HNodeTorsion4typeEv(%struct.HNodeTorsion*) nounwind + +declare fastcc double @_ZL12sumMassToTipPK9HingeNode(%struct.HingeNode*) + +declare void @_ZN13InertiaTensor4calcERK4Vec3RK7CDSListIP7IVMAtomE(%struct.InertiaTensor*, %struct.Vec3*, %struct.AtomList*) nounwind + +declare fastcc double @_ZL15sumInertiaToTipPK9HingeNodeRK4Vec3S4_(%struct.HingeNode*, %struct.Vec3*, %struct.Vec3*) + +declare %"struct.std::basic_ostream >"* @_ZlsI11FixedVectorIdLi6ELi0EEERSoS2_RK9SubVectorIT_E(%"struct.std::basic_ostream >"*, %"struct.SubVector >"*) + +declare %"struct.std::basic_ostream >"* @_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St5_Setw(%"struct.std::basic_ostream >"*, i32) + +declare %"struct.std::basic_ostream >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc(%"struct.std::basic_ostream >"*, i8*) + +declare %"struct.std::basic_ostream >"* @_ZNSolsEd(%"struct.std::basic_ostream >"*, double) + +declare void @_Z14orthoTransformIdLi3ELi3EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZN12HNodeRotate27calcRotEv(%struct.HNodeRotate2*) + +declare void @_ZN21HNodeTranslateRotate27calcRotEv(%struct.HNodeTranslateRotate2*) + +declare void @_ZmlIdLi6ELi6EE11FixedVectorIT_XT0_ELi0EERK11FixedMatrixIS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi6ELi6ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%struct.Mat6* noalias sret, %struct.Mat6*, %struct.Mat6*) + +declare void @_ZmlIdLi6ELi6ELi3EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi6ELi6ELi2EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi5ELi6EE11FixedVectorIT_XT0_ELi0EERK11FixedMatrixIS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_ELi0EE(%"struct.FixedVector"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi6ELi6ELi5EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZN12HNodeRotate39setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%struct.HNodeRotate3*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate29setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%struct.HNodeRotate2*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate39setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%struct.HNodeTranslateRotate3*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate29setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare i32 @_ZNK13HingeNodeSpecILi1EE6offsetEv(%"struct.HingeNodeSpec<1>"*) nounwind + +declare %struct.Vec3* @_ZNK13HingeNodeSpecILi1EE5posCMEv(%"struct.HingeNodeSpec<1>"*) nounwind + +declare double* @_ZNK13HingeNodeSpecILi1EE4massEv(%"struct.HingeNodeSpec<1>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi1EE9calcPandZEv(%"struct.HingeNodeSpec<1>"*) + +declare i32 @_ZNK13HingeNodeSpecILi1EE6getDOFEv(%"struct.HingeNodeSpec<1>"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi1EE6getDimEv(%"struct.HingeNodeSpec<1>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi1EE18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi5EE6offsetEv(%"struct.HingeNodeSpec<5>"*) nounwind + +declare %struct.Vec3* @_ZNK13HingeNodeSpecILi5EE5posCMEv(%"struct.HingeNodeSpec<5>"*) nounwind + +declare double* @_ZNK13HingeNodeSpecILi5EE4massEv(%"struct.HingeNodeSpec<5>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi5EE9calcPandZEv(%"struct.HingeNodeSpec<5>"*) + +declare i32 @_ZNK13HingeNodeSpecILi5EE6getDOFEv(%"struct.HingeNodeSpec<5>"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi5EE6getDimEv(%"struct.HingeNodeSpec<5>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi5EE18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi2EE6offsetEv(%"struct.HingeNodeSpec<2>"*) nounwind + +declare %struct.Vec3* @_ZNK13HingeNodeSpecILi2EE5posCMEv(%"struct.HingeNodeSpec<2>"*) nounwind + +declare double* @_ZNK13HingeNodeSpecILi2EE4massEv(%"struct.HingeNodeSpec<2>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi2EE9calcPandZEv(%"struct.HingeNodeSpec<2>"*) + +declare i32 @_ZNK13HingeNodeSpecILi2EE6getDOFEv(%"struct.HingeNodeSpec<2>"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi2EE6getDimEv(%"struct.HingeNodeSpec<2>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi2EE18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi3EE6offsetEv(%"struct.HingeNodeSpec<3>"*) nounwind + +declare %struct.Vec3* @_ZNK13HingeNodeSpecILi3EE5posCMEv(%"struct.HingeNodeSpec<3>"*) nounwind + +declare double* @_ZNK13HingeNodeSpecILi3EE4massEv(%"struct.HingeNodeSpec<3>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi3EE9calcPandZEv(%"struct.HingeNodeSpec<3>"*) + +declare i32 @_ZNK13HingeNodeSpecILi3EE6getDOFEv(%"struct.HingeNodeSpec<3>"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi6EE6offsetEv(%"struct.HingeNodeSpec<6>"*) nounwind + +declare %struct.Vec3* @_ZNK13HingeNodeSpecILi6EE5posCMEv(%"struct.HingeNodeSpec<6>"*) nounwind + +declare double* @_ZNK13HingeNodeSpecILi6EE4massEv(%"struct.HingeNodeSpec<6>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi6EE9calcPandZEv(%"struct.HingeNodeSpec<6>"*) + +declare i32 @_ZNK13HingeNodeSpecILi6EE6getDOFEv(%"struct.HingeNodeSpec<6>"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi6EE6getDimEv(%"struct.HingeNodeSpec<6>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi6EE9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES6_(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi6EE18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare i32 @_ZNK13HingeNodeSpecILi3EE6getDimEv(%"struct.HingeNodeSpec<3>"*) nounwind + +declare void @_ZN13HingeNodeSpecILi3EE9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES6_(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi3EE18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) nounwind + +declare void @_Z14orthoTransformIdLi6ELi6EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%struct.Mat6* noalias sret, %struct.Mat6*, %struct.Mat6*) + +declare double @_ZN13HingeNodeSpecILi1EE8kineticEEv(%"struct.HingeNodeSpec<1>"*) + +declare double @_ZN13HingeNodeSpecILi3EE8kineticEEv(%"struct.HingeNodeSpec<3>"*) + +declare double @_ZN13HingeNodeSpecILi2EE8kineticEEv(%"struct.HingeNodeSpec<2>"*) + +declare double @_ZN13HingeNodeSpecILi6EE8kineticEEv(%"struct.HingeNodeSpec<6>"*) + +declare double @_ZN13HingeNodeSpecILi5EE8kineticEEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZmlIdLi6ELi5ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%struct.Mat6* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi1EE9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES6_(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi5EE9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES6_(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi2EE9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES6_(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_Z14orthoTransformIdLi3ELi6EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%struct.Mat6* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi6ELi1ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%struct.Mat6* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi6ELi5ELi5EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_Z14orthoTransformIdLi5ELi6EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%struct.Mat6* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_Z14orthoTransformIdLi2ELi6EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%struct.Mat6* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi1ELi6ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %struct.Mat6*) + +declare void @_ZmlIdLi5ELi6ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %struct.Mat6*) + +declare void @_Z14orthoTransformIdLi6ELi5EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi2ELi6ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %struct.Mat6*) + +declare void @_Z14orthoTransformIdLi6ELi2EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZmlIdLi3ELi6ELi6EE11FixedMatrixIT_XT0_EXT2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT1_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %struct.Mat6*) + +declare void @_Z14orthoTransformIdLi6ELi3EE11FixedMatrixIT_XT1_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT0_ELi0ELi0EERKS0_IS1_XT1_EXT0_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, %"struct.FixedMatrix"*) + +declare void @_ZNSt8ios_base4InitC1Ev(%"struct.CDS::DefaultAlloc"*) + +declare i32 @__cxa_atexit(void (i8*)*, i8*, i8*) nounwind + +declare void @__tcf_0(i8* nocapture) + +declare void @_ZNSt8ios_base4InitD1Ev(%"struct.CDS::DefaultAlloc"*) + +declare %"struct.std::basic_ostream >"* @_ZlsRSoRK9HingeNode(%"struct.std::basic_ostream >"*, %struct.HingeNode*) + +declare %"struct.std::basic_ostream >"* @_ZlsRSoPK7IVMAtom(%"struct.std::basic_ostream >"*, %struct.IVMAtom*) + +declare void @_ZN9HingeNode8addChildEPS_(%struct.HingeNode*, %struct.HingeNode*) + +declare void @_ZN7CDSListIP9HingeNodeE6appendES1_(%"struct.CDSList"*, %struct.HingeNode*) + +declare void @_ZN9HingeNode4getHEv(%struct.RMat* noalias sret, %struct.HingeNode*) + +declare i8* @__cxa_allocate_exception(i32) nounwind + +declare void @__cxa_throw(i8*, i8*, void (i8*)*) noreturn + +declare void @_ZN9HingeNode16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HingeNode*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode9calcAccelEv(%struct.HingeNode*) + +declare void @_ZN9HingeNode8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HingeNode*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HingeNode*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HingeNode*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode5printEi(%struct.HingeNode*, i32) + +declare void @_ZN9HingeNode18enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES4_(%struct.HingeNode*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%struct.HingeNode*, %"struct.FixedMatrix"*) + +declare void @_ZN9HingeNode6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HingeNode*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode9setPosVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEES5_(%struct.HingeNode*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN9HingeNode13propagateSVelERK11FixedVectorIdLi6ELi0EE(%struct.HingeNode*, %"struct.FixedMatrix"*) + +declare void @_ZN9HingeNode18prepareVelInternalEv(%struct.HingeNode*) + +declare void @_ZN9HingeNode17calcInternalForceEv(%struct.HingeNode*) + +declare void @_ZN9HingeNode5calcYEv(%struct.HingeNode*) + +declare void @_ZN9HingeNode9calcPandZEv(%struct.HingeNode*) + +declare void @_ZN9HingeNode5calcZEv(%struct.HingeNode*) + +declare void @_ZN9HingeNode5calcPEv(%struct.HingeNode*) + +declare double* @_ZNK9HingeNode4massEv(%struct.HingeNode*) + +declare %struct.Vec3* @_ZNK9HingeNode5posCMEv(%struct.HingeNode*) + +declare i8* @_Znam(i32) + +declare void @_ZN7CDSListIP9HingeNodeEC1Eii(%"struct.CDSList"*, i32, i32) + +declare i8* @_Znwm(i32) + +declare i8* @llvm.eh.exception() nounwind + +declare i32 @llvm.eh.selector.i32(i8*, i8*, ...) nounwind + +declare i32 @llvm.eh.typeid.for.i32(i8*) nounwind + +declare void @_ZdlPv(i8*) nounwind + +declare i32 @__gxx_personality_v0(...) + +declare void @_Unwind_Resume_or_Rethrow(i8*) + +declare void @_ZN7CDSListIP7IVMAtomEC1Eii(%struct.AtomList*, i32, i32) + +declare void @_ZN13CDSVectorBaseIdN3CDS12DefaultAllocEE8splitRepEv(%"struct.CDSVectorBase"*) + +declare void @_ZN12HNodeTorsion16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTorsion*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi1EE8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi1EE6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi1EE6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi1EE16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate316getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate3*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi3EE16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi3EE8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi3EE6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi3EE6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate216getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate2*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate28getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate2*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate26getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate2*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate26getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate2*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate38getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate3*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate36getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate3*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate36getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate3*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi2EE16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi2EE8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi2EE6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi2EE6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate316getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate3*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate38getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate3*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate36getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate3*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate36getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate3*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi6EE16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi6EE8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi6EE6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi6EE6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate216getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate28getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate26getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate26getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi5EE16getInternalForceER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi5EE8getAccelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi5EE6getVelER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi5EE6getPosER9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*) + +declare void @_ZN13CDSVectorBaseI4Vec3N3CDS12DefaultAllocEE8splitRepEv(%"struct.CDSVectorBase"*) + +declare void @_ZN7CDSListIP7IVMAtomE8splitRepEv(%struct.AtomList*) + +declare void @_ZN7CDSListIP9HingeNodeE8splitRepEv(%"struct.CDSList"*) + +declare void @_ZdaPv(i8*) nounwind + +declare void @_ZSt9terminatev() noreturn nounwind + +declare void @_ZN9HingeNodeC2EPK3IVMP7IVMAtomPKS3_PS_(%struct.HingeNode*, %struct.IVM*, %struct.IVMAtom*, %struct.IVMAtom*, %struct.HingeNode*) + +declare void @_ZN9HingeNodeD1Ev(%struct.HingeNode*) + +declare void @_ZN9HingeNodeD0Ev(%struct.HingeNode*) + +declare void @_ZN7CDSListIP7IVMAtomE6appendES1_(%struct.AtomList*, %struct.IVMAtom*) + +declare void @_ZN9HingeNodeC1EPK3IVMP7IVMAtomPKS3_PS_(%struct.HingeNode*, %struct.IVM*, %struct.IVMAtom*, %struct.IVMAtom*, %struct.HingeNode*) + +declare void @_ZN9HingeNodeD2Ev(%struct.HingeNode*) + +declare void @_ZN11HNodeOriginD0Ev(%struct.HNodeOrigin*) + +declare void @_ZN11HNodeOriginD1Ev(%struct.HNodeOrigin*) + +declare void @_ZN13HingeNodeSpecILi1EED0Ev(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EED1Ev(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE5calcPEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE5calcZEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE5calcYEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE17calcInternalForceEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE18prepareVelInternalEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE13propagateSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<1>"*, %"struct.FixedMatrix"*) + +declare double @_ZN13HingeNodeSpecILi1EE8approxKEEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<1>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi1EE14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<1>"*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi1EE5printEi(%"struct.HingeNodeSpec<1>"*, i32) + +declare void @_ZN13HingeNodeSpecILi1EE9calcAccelEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi1EE4getHEv(%struct.RMat* noalias sret, %"struct.HingeNodeSpec<1>"*) + +declare void @__cxa_pure_virtual() nounwind + +declare void @_ZN13HingeNodeSpecILi3EED0Ev(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EED1Ev(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE5calcPEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE5calcZEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE5calcYEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE17calcInternalForceEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE18prepareVelInternalEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE13propagateSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<3>"*, %"struct.FixedMatrix"*) + +declare double @_ZN13HingeNodeSpecILi3EE8approxKEEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<3>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi3EE14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<3>"*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi3EE5printEi(%"struct.HingeNodeSpec<3>"*, i32) + +declare void @_ZN13HingeNodeSpecILi3EE9calcAccelEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi3EE4getHEv(%struct.RMat* noalias sret, %"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi2EED0Ev(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EED1Ev(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE5calcPEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE5calcZEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE5calcYEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE17calcInternalForceEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE18prepareVelInternalEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE13propagateSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<2>"*, %"struct.FixedMatrix"*) + +declare double @_ZN13HingeNodeSpecILi2EE8approxKEEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<2>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi2EE14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<2>"*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi2EE5printEi(%"struct.HingeNodeSpec<2>"*, i32) + +declare void @_ZN13HingeNodeSpecILi2EE9calcAccelEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi2EE4getHEv(%struct.RMat* noalias sret, %"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi6EED0Ev(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EED1Ev(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE5calcPEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE5calcZEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE5calcYEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE17calcInternalForceEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE18prepareVelInternalEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE13propagateSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<6>"*, %"struct.FixedMatrix"*) + +declare double @_ZN13HingeNodeSpecILi6EE8approxKEEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<6>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi6EE14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<6>"*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi6EE5printEi(%"struct.HingeNodeSpec<6>"*, i32) + +declare void @_ZN13HingeNodeSpecILi6EE9calcAccelEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi6EE4getHEv(%struct.RMat* noalias sret, %"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi5EED0Ev(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EED1Ev(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE5calcPEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE5calcZEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE5calcYEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE17calcInternalForceEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE18prepareVelInternalEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE13propagateSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<5>"*, %"struct.FixedMatrix"*) + +declare double @_ZN13HingeNodeSpecILi5EE8approxKEEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE6setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%"struct.HingeNodeSpec<5>"*, %"struct.CDSVector"*) + +declare void @_ZN13HingeNodeSpecILi5EE14setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%"struct.HingeNodeSpec<5>"*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi5EE5printEi(%"struct.HingeNodeSpec<5>"*, i32) + +declare void @_ZN13HingeNodeSpecILi5EE9calcAccelEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN13HingeNodeSpecILi5EE4getHEv(%struct.RMat* noalias sret, %"struct.HingeNodeSpec<5>"*) + +declare void @_ZN12HNodeTorsion7calcRotEv(%struct.HNodeTorsion*) + +declare double @sin(double) nounwind readnone + +declare double @cos(double) nounwind readnone + +declare void @_ZN12HNodeRotate37calcRotEv(%struct.HNodeRotate3*) + +declare void @_ZN21HNodeTranslateRotate37calcRotEv(%struct.HNodeTranslateRotate3*) + +declare void @_ZN9HingeNodeC2ERKS_(%struct.HingeNode*, %struct.HingeNode*) + +declare void @_ZN7CDSListIP9HingeNodeEC1ERKS2_(%"struct.CDSList"*, %"struct.CDSList"*) + +declare void @_ZN7CDSListIP7IVMAtomEC1ERKS2_(%struct.AtomList*, %struct.AtomList*) + +declare void @_ZN11HNodeOriginC2EPK9HingeNode(%struct.HNodeOrigin*, %struct.HingeNode*) + +declare void @_ZN13HingeNodeSpecILi1EEC2EPK9HingeNodeRi(%"struct.HingeNodeSpec<1>"*, %struct.HingeNode*, i32*) + +declare void @_ZN13HingeNodeSpecILi3EEC2EPK9HingeNodeRi(%"struct.HingeNodeSpec<3>"*, %struct.HingeNode*, i32*) + +declare void @_ZN13HingeNodeSpecILi2EEC2EPK9HingeNodeRi(%"struct.HingeNodeSpec<2>"*, %struct.HingeNode*, i32*) + +declare void @_ZN13HingeNodeSpecILi6EEC2EPK9HingeNodeRi(%"struct.HingeNodeSpec<6>"*, %struct.HingeNode*, i32*) + +declare void @_ZN13HingeNodeSpecILi5EEC2EPK9HingeNodeRi(%"struct.HingeNodeSpec<5>"*, %struct.HingeNode*, i32*) + +declare void @_ZplI4Vec3K11FixedVectorIdLi6ELi0EEET_RK9SubVectorIT0_ERKS4_(%struct.Vec3* noalias sret, %"struct.SubVector >"*, %struct.Vec3*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi1ELi6ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare void @_ZN12HNodeRotate314setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%struct.HNodeRotate3*, %"struct.FixedMatrix"*) + +declare void @_ZN12HNodeRotate214setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%struct.HNodeRotate2*, %"struct.FixedMatrix"*) + +declare void @_ZN21HNodeTranslateRotate314setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%struct.HNodeTranslateRotate3*, %"struct.FixedMatrix"*) + +declare void @_ZN21HNodeTranslateRotate214setVelFromSVelERK11FixedVectorIdLi6ELi0EE(%struct.HNodeTranslateRotate2*, %"struct.FixedMatrix"*) + +declare void @_ZN13HingeNodeSpecILi1EE9calcPropsEv(%"struct.HingeNodeSpec<1>"*) + +declare zeroext i8 @_ZNK3IVM12minimizationEv(%struct.IVM*) + +declare void @_Z8blockVecIdLi3ELi3EE11FixedVectorIT_XplT0_T1_ELi0EERKS0_IS1_XT0_ELi0EERKS0_IS1_XT1_ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZN12HNodeTorsion11toCartesianEv(%struct.HNodeTorsion*) + +declare void @_ZN13HingeNodeSpecILi1EE18calcCartesianForceEv(%"struct.HingeNodeSpec<1>"*) + +declare void @_ZN13HingeNodeSpecILi3EE18calcCartesianForceEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN13HingeNodeSpecILi2EE18calcCartesianForceEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN13HingeNodeSpecILi6EE18calcCartesianForceEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN13HingeNodeSpecILi5EE18calcCartesianForceEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN12HNodeTorsion5calcHEv(%struct.HNodeTorsion*) + +declare void @_Z10blockMat12IdLi1ELi3ELi3EE11FixedMatrixIT_XT0_EXplT1_T2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZN13CDSMatrixBaseIdEC2I11FixedMatrixIdLi1ELi6ELi0ELi0EEEERKT_(%"struct.CDSMatrixBase"*, %"struct.FixedMatrix"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi6ELi1ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare %"struct.std::basic_ostream >"* @_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St13_Setprecision(%"struct.std::basic_ostream >"*, i32) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi6EERSoS0_RK15FixedVectorBaseIT_XT0_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_c(%"struct.std::basic_ostream >"*, i8 signext) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi3EERSoS0_RK15FixedVectorBaseIT_XT0_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi1EERSoS0_RK15FixedVectorBaseIT_XT0_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare void @_ZN11FixedVectorIdLi3ELi0EE6subColILi6ELi1ELi0ELi0EEES0_RK11FixedMatrixIdXT_EXT0_EXT1_EXT2_EEiii(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, i32, i32, i32) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedMatrixBaseIdLi6ELi6EEpLERKS0_(%"struct.FixedMatrixBase"*, %"struct.FixedMatrixBase"*) + +declare void @_ZN13HingeNodeSpecILi6EE9calcPropsEv(%"struct.HingeNodeSpec<6>"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi6ELi6ELi0ELi0EEEENT_13TransposeTypeERKS3_(%struct.Mat6* noalias sret, %struct.Mat6*) + +declare void @_ZN21HNodeTranslateRotate311toCartesianEv(%struct.HNodeTranslateRotate3*) + +define linkonce void @_ZN21HNodeTranslateRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate3* %this, %"struct.CDSVector"* %velv) { +entry: + %0 = add i32 0, -1 ; [#uses=1] + %1 = getelementptr double* null, i32 %0 ; [#uses=1] + %2 = load double* %1, align 8 ; [#uses=1] + %3 = load double* null, align 8 ; [#uses=2] + %4 = load double* null, align 8 ; [#uses=2] + %5 = load double* null, align 8 ; [#uses=3] + %6 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 2, i32 0, i32 0, i32 0, i32 0 ; [#uses=0] + %7 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 2, i32 0, i32 0, i32 0, i32 1 ; [#uses=0] + %8 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 2, i32 0, i32 0, i32 0, i32 2 ; [#uses=0] + %9 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 2, i32 0, i32 0, i32 0, i32 3 ; [#uses=0] + %10 = load double* null, align 8 ; [#uses=2] + %11 = sub double -0.000000e+00, %10 ; [#uses=1] + %12 = load double* null, align 8 ; [#uses=2] + %13 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 1, i32 0, i32 0, i32 0, i32 3 ; [#uses=1] + %14 = load double* %13, align 8 ; [#uses=2] + %15 = sub double -0.000000e+00, %14 ; [#uses=1] + %16 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 1, i32 0, i32 0, i32 0, i32 2 ; [#uses=1] + %17 = load double* %16, align 8 ; [#uses=2] + %18 = sub double -0.000000e+00, %17 ; [#uses=1] + %19 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 0 ; [#uses=0] + %20 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 3 ; [#uses=0] + %21 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 6 ; [#uses=0] + %22 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 9 ; [#uses=0] + %23 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 1 ; [#uses=0] + %24 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 4 ; [#uses=0] + %25 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 7 ; [#uses=0] + %26 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 10 ; [#uses=0] + %27 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 2 ; [#uses=0] + %28 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 5 ; [#uses=0] + %29 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 8 ; [#uses=0] + %30 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 11 ; [#uses=0] + %31 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 0 ; [#uses=0] + %32 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 1 ; [#uses=1] + %33 = getelementptr %"struct.FixedMatrix"* null, i32 0, i32 0, i32 0, i32 2 ; [#uses=1] + %34 = mul double %17, %5 ; [#uses=1] + %35 = add double 0.000000e+00, %34 ; [#uses=1] + %36 = add double 0.000000e+00, 0.000000e+00 ; [#uses=1] + %37 = mul double %14, %3 ; [#uses=1] + %38 = add double %36, %37 ; [#uses=1] + %39 = mul double %12, %4 ; [#uses=1] + %40 = add double %38, %39 ; [#uses=1] + %41 = mul double %5, %11 ; [#uses=1] + %42 = add double %40, %41 ; [#uses=2] + store double %42, double* %32, align 8 + %43 = mul double %2, %15 ; [#uses=1] + %44 = add double %43, 0.000000e+00 ; [#uses=1] + %45 = mul double %3, %18 ; [#uses=1] + %46 = add double %44, %45 ; [#uses=1] + %47 = mul double %10, %4 ; [#uses=1] + %48 = add double %46, %47 ; [#uses=1] + %49 = mul double %12, %5 ; [#uses=1] + %50 = add double %48, %49 ; [#uses=2] + store double %50, double* %33, align 8 + %51 = mul double %35, 2.000000e+00 ; [#uses=1] + %52 = mul double %42, 2.000000e+00 ; [#uses=1] + %53 = mul double %50, 2.000000e+00 ; [#uses=1] + %54 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 0, i32 10, i32 0, i32 0, i32 0 ; [#uses=1] + store double %51, double* %54, align 8 + %55 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 0, i32 10, i32 0, i32 0, i32 1 ; [#uses=1] + store double %52, double* %55, align 8 + %56 = getelementptr %struct.HNodeTranslateRotate3* %this, i32 0, i32 0, i32 10, i32 0, i32 0, i32 2 ; [#uses=1] + store double %53, double* %56, align 8 + %57 = add i32 0, 4 ; [#uses=1] + %58 = getelementptr %"struct.SubVector >"* null, i32 0, i32 0 ; <%"struct.CDSVector"**> [#uses=1] + store %"struct.CDSVector"* %velv, %"struct.CDSVector"** %58, align 8 + %59 = getelementptr %"struct.SubVector >"* null, i32 0, i32 1 ; [#uses=1] + store i32 %57, i32* %59, align 4 + %60 = getelementptr %"struct.SubVector >"* null, i32 0, i32 2 ; [#uses=1] + store i32 3, i32* %60, align 8 + unreachable +} + +declare void @_ZmlRK11FixedMatrixIdLi6ELi6ELi0ELi0EERK18PhiMatrixTranspose(%struct.Mat6* noalias sret, %struct.Mat6*, %struct.PhiMatrixTranspose*) + +declare void @_ZmlI4Mat3K11FixedMatrixIdLi6ELi6ELi0ELi0EEET_RK9SubMatrixIT0_ERKS4_(%struct.Mat3* noalias sret, %"struct.SubMatrix >"*, %struct.Mat3*) + +declare void @_ZmiI4Mat3K11FixedMatrixIdLi6ELi6ELi0ELi0EEET_RK9SubMatrixIT0_ERKS4_(%struct.Mat3* noalias sret, %"struct.SubMatrix >"*, %struct.Mat3*) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedMatrixBaseIdLi3ELi3EEmIERKS0_(%"struct.FixedMatrixBase"*, %"struct.FixedMatrixBase"*) + +declare void @_ZplI4Mat311FixedMatrixIdLi6ELi6ELi0ELi0EEET_RKS3_RK9SubMatrixIT0_E(%struct.Mat3* noalias sret, %struct.Mat3*, %"struct.SubMatrix >"*) + +declare void @_ZN13CDSVectorBaseIdN3CDS12DefaultAllocEED2Ev(%"struct.CDSVectorBase"*) + +declare void @_ZN13HingeNodeSpecILi1EE7calcD_GERK11FixedMatrixIdLi6ELi6ELi0ELi0EE(%"struct.HingeNodeSpec<1>"*, %struct.Mat6*) + +declare void @_ZN11MatrixTools7inverseI11FixedMatrixIdLi1ELi1ELi0ELi0EEEET_RKS3_NS_14InverseResultsINS3_10MatrixTypeEEE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.MatrixTools::InverseResults >"*) + +declare i8* @__cxa_get_exception_ptr(i8*) nounwind + +declare i8* @__cxa_begin_catch(i8*) nounwind + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi1ELi1EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi1ELi6EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZNSolsEi(%"struct.std::basic_ostream >"*, i32) + +declare %"struct.std::basic_ostream >"* @_ZlsIcERSoS0_RK9CDSStringIT_E(%"struct.std::basic_ostream >"*, %struct.String*) + +declare %"struct.std::basic_ostream >"* @_ZNSolsEPFRSoS_E(%"struct.std::basic_ostream >"*, %"struct.std::basic_ostream >"* (%"struct.std::basic_ostream >"*)*) + +declare %"struct.std::basic_ostream >"* @_ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_(%"struct.std::basic_ostream >"*) + +declare void @__cxa_end_catch() + +declare void @_ZmlI4Mat311FixedMatrixIdLi6ELi6ELi0ELi0EEET_RKS3_RK9SubMatrixIT0_E(%struct.Mat3* noalias sret, %struct.Mat3*, %"struct.SubMatrix >"*) + +declare void @_ZmlI4Mat311FixedMatrixIdLi6ELi6ELi0ELi0EEET_RK9SubMatrixIT0_ERKS3_(%struct.Mat3* noalias sret, %"struct.SubMatrix >"*, %struct.Mat3*) + +declare void @_ZmiI4Mat311FixedMatrixIdLi6ELi6ELi0ELi0EEET_RK9SubMatrixIT0_ERKS3_(%struct.Mat3* noalias sret, %"struct.SubMatrix >"*, %struct.Mat3*) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedMatrixBaseIdLi6ELi6EEmIERKS0_(%"struct.FixedMatrixBase"*, %"struct.FixedMatrixBase"*) + +declare void @_ZN13CDSVectorBaseI4Vec3N3CDS12DefaultAllocEEC2EiS2_(%"struct.CDSVectorBase"*, i32, %"struct.CDS::DefaultAlloc"* byval align 4) + +declare void @_ZN13CDSVectorBaseI4Vec3N3CDS12DefaultAllocEED2Ev(%"struct.CDSVectorBase"*) + +declare void @_ZN12HNodeTorsionD0Ev(%struct.HNodeTorsion*) + +declare void @_ZN12HNodeTorsionD1Ev(%struct.HNodeTorsion*) + +declare void @_ZN12HNodeRotate3D0Ev(%struct.HNodeRotate3*) + +declare void @_ZN12HNodeRotate3D1Ev(%struct.HNodeRotate3*) + +declare void @_ZN12HNodeRotate36setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate3*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate318enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES4_(%struct.HNodeRotate3*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate35printEi(%struct.HNodeRotate3*, i32) + +declare void @_ZN12HNodeRotate35calcHEv(%struct.HNodeRotate3*) + +declare void @_ZN12HNodeRotate311toCartesianEv(%struct.HNodeRotate3*) + +declare void @_ZN12HNodeRotate2D0Ev(%struct.HNodeRotate2*) + +declare void @_ZN12HNodeRotate2D1Ev(%struct.HNodeRotate2*) + +declare void @_ZN12HNodeRotate26setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeRotate2*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate218enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES4_(%struct.HNodeRotate2*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN12HNodeRotate25printEi(%struct.HNodeRotate2*, i32) + +declare void @_ZN12HNodeRotate25calcHEv(%struct.HNodeRotate2*) + +declare void @_ZN12HNodeRotate211toCartesianEv(%struct.HNodeRotate2*) + +declare void @_ZN21HNodeTranslateRotate3D0Ev(%struct.HNodeTranslateRotate3*) + +declare void @_ZN21HNodeTranslateRotate3D1Ev(%struct.HNodeTranslateRotate3*) + +declare void @_ZN21HNodeTranslateRotate318enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES4_(%struct.HNodeTranslateRotate3*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate35printEi(%struct.HNodeTranslateRotate3*, i32) + +declare void @_ZN21HNodeTranslateRotate35calcHEv(%struct.HNodeTranslateRotate3*) + +declare void @_ZN21HNodeTranslateRotate2D0Ev(%struct.HNodeTranslateRotate2*) + +declare void @_ZN21HNodeTranslateRotate2D1Ev(%struct.HNodeTranslateRotate2*) + +declare void @_ZN21HNodeTranslateRotate26setVelERK9CDSVectorIdLi1EN3CDS12DefaultAllocEE(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate218enforceConstraintsER9CDSVectorIdLi1EN3CDS12DefaultAllocEES4_(%struct.HNodeTranslateRotate2*, %"struct.CDSVector"*, %"struct.CDSVector"*) + +declare void @_ZN21HNodeTranslateRotate25printEi(%struct.HNodeTranslateRotate2*, i32) + +declare void @_ZN21HNodeTranslateRotate25calcHEv(%struct.HNodeTranslateRotate2*) + +declare void @_ZN21HNodeTranslateRotate211toCartesianEv(%struct.HNodeTranslateRotate2*) + +declare void @_ZN14HNodeTranslateC2EPK9HingeNodeP7IVMAtomRi(%struct.HNodeTranslate*, %struct.HingeNode*, %struct.IVMAtom*, i32*) + +declare void @_ZN14HNodeTranslateD1Ev(%struct.HNodeTranslate*) + +declare void @_ZN14HNodeTranslateD0Ev(%struct.HNodeTranslate*) + +declare void @_ZN14HNodeTranslate5calcHEv(%struct.HNodeTranslate*) + +declare void @_ZN14HNodeTranslate11toCartesianEv(%struct.HNodeTranslate*) + +declare void @_ZN12HNodeRotate3C2EPK9HingeNodeP7IVMAtomRib(%struct.HNodeRotate3*, %struct.HingeNode*, %struct.IVMAtom*, i32*, i8 zeroext) + +declare void @_ZN8AtomTree6findCMEPK9HingeNode(%struct.Vec3* noalias sret, %struct.HingeNode*) + +declare %struct.IVMAtom** @_ZN7CDSListIP7IVMAtomE7prependERKS1_(%struct.AtomList*, %struct.IVMAtom**) + +declare %"struct.CDSVectorBase"* @_ZN13CDSVectorBaseI4Vec3N3CDS12DefaultAllocEE6resizeEi(%"struct.CDSVectorBase"*, i32) + +declare void @_ZN12HNodeRotate2C2EPK9HingeNodeRK4Vec3Ri(%struct.HNodeRotate2*, %struct.HingeNode*, %struct.Vec3*, i32*) + +declare void @_ZN21HNodeTranslateRotate3C2EPK9HingeNodeP7IVMAtomRib(%struct.HNodeTranslateRotate3*, %struct.HingeNode*, %struct.IVMAtom*, i32*, i8 zeroext) + +declare void @_ZN13HingeNodeSpecILi3EE9calcPropsEv(%"struct.HingeNodeSpec<3>"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi3ELi6ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare void @_ZN11MatrixTools9transposeI4Mat3EENT_13TransposeTypeERKS2_(%struct.Mat3* noalias sret, %struct.Mat3*) + +declare void @_Z10blockMat12IdLi3ELi3ELi3EE11FixedMatrixIT_XT0_EXplT1_T2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZN13CDSMatrixBaseIdEC2I11FixedMatrixIdLi3ELi6ELi0ELi0EEEERKT_(%"struct.CDSMatrixBase"*, %"struct.FixedMatrix"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi6ELi3ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi4EERSoS0_RK15FixedVectorBaseIT_XT0_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare double @_Z4normIdLi4EET_RK11FixedVectorIS0_XT0_ELi0EE(%"struct.FixedMatrix"*) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedVectorBaseIdLi4EEdVERKd(%"struct.FixedMatrixBase"*, double*) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedVectorBaseIdLi4EEmIERKS0_(%"struct.FixedMatrixBase"*, %"struct.FixedMatrixBase"*) + +declare void @_ZN11FixedVectorIdLi3ELi0EE6subColILi6ELi3ELi0ELi0EEES0_RK11FixedMatrixIdXT_EXT0_EXT1_EXT2_EEiii(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, i32, i32, i32) + +declare void @_ZN13HingeNodeSpecILi3EE7calcD_GERK11FixedMatrixIdLi6ELi6ELi0ELi0EE(%"struct.HingeNodeSpec<3>"*, %struct.Mat6*) + +declare void @_ZN11MatrixTools7inverseI11FixedMatrixIdLi3ELi3ELi0ELi0EEEET_RKS3_NS_14InverseResultsINS3_10MatrixTypeEEE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.MatrixTools::InverseResults >"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi3ELi3EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi3ELi6EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare void @_Z7unitVecRK4Vec3(%struct.Vec3* noalias sret, %struct.Vec3*) + +declare double @_Z4normIdLi3EET_RK11FixedVectorIS0_XT0_ELi0EE(%"struct.FixedMatrix"*) + +declare void @_ZN12HNodeTorsionC2EPK9HingeNodeRK4Vec3Ri(%struct.HNodeTorsion*, %struct.HingeNode*, %struct.Vec3*, i32*) + +declare double @acos(double) nounwind readnone + +declare double @atan2(double, double) nounwind readnone + +declare void @_ZN21HNodeTranslateRotate2C2EPK9HingeNodeRi(%struct.HNodeTranslateRotate2*, %struct.HingeNode*, i32*) + +declare void @_ZN13HingeNodeSpecILi2EE9calcPropsEv(%"struct.HingeNodeSpec<2>"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi2ELi6ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare void @_Z10blockMat21IdLi1ELi3ELi1EE11FixedMatrixIT_XplT0_T2_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT2_EXT1_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_Z10blockMat12IdLi2ELi3ELi3EE11FixedMatrixIT_XT0_EXplT1_T2_ELi0ELi0EERKS0_IS1_XT0_EXT1_ELi0ELi0EERKS0_IS1_XT0_EXT2_ELi0ELi0EE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.FixedMatrix"*) + +declare void @_ZN13CDSMatrixBaseIdEC2I11FixedMatrixIdLi2ELi6ELi0ELi0EEEERKT_(%"struct.CDSMatrixBase"*, %"struct.FixedMatrix"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi6ELi2ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi2EERSoS0_RK15FixedVectorBaseIT_XT0_EE(%"struct.std::basic_ostream >"*, %"struct.FixedVectorBase"*) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedVectorBaseIdLi3EEdVERKd(%"struct.FixedMatrixBase"*, double*) + +declare %"struct.FixedMatrixBase"* @_ZN15FixedVectorBaseIdLi3EEmIERKS0_(%"struct.FixedMatrixBase"*, %"struct.FixedMatrixBase"*) + +declare void @_ZN11FixedVectorIdLi3ELi0EE6subColILi6ELi2ELi0ELi0EEES0_RK11FixedMatrixIdXT_EXT0_EXT1_EXT2_EEiii(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, i32, i32, i32) + +declare void @_ZN13HingeNodeSpecILi2EE7calcD_GERK11FixedMatrixIdLi6ELi6ELi0ELi0EE(%"struct.HingeNodeSpec<2>"*, %struct.Mat6*) + +declare void @_ZN11MatrixTools7inverseI11FixedMatrixIdLi2ELi2ELi0ELi0EEEET_RKS3_NS_14InverseResultsINS3_10MatrixTypeEEE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.MatrixTools::InverseResults >"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi2ELi2EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi2ELi6EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare zeroext i8 @_ZNK9CDSStringIcE7matchesEPKcb(%struct.String*, i8*, i8 zeroext) + +declare %struct.HingeNode* @_Z9constructP9HingeNodeRKN16InternalDynamics9HingeSpecERi(%struct.HingeNode*, %"struct.InternalDynamics::HingeSpec"*, i32*) + +declare void @_ZN9CDSStringIcEC1ERKS0_(%struct.String*, %struct.String*) + +declare void @_ZN9CDSStringIcE8downcaseEv(%struct.String*) + +declare %struct.String* @_ZN9CDSStringIcEaSEPKc(%struct.String*, i8*) + +declare %"struct.std::basic_ostream >"* @_ZlsIP7IVMAtomERSoS2_RK7CDSListIT_E(%"struct.std::basic_ostream >"*, %struct.AtomList*) + +declare i32 @_ZNK7CDSListIP9HingeNodeE8getIndexERKS1_(%"struct.CDSList"*, %struct.HingeNode**) + +declare void @_ZN13CDSMatrixBaseIdEC2I11FixedMatrixIdLi6ELi6ELi0ELi0EEEERKT_(%"struct.CDSMatrixBase"*, %struct.Mat6*) + +declare void @_ZN11FixedVectorIdLi3ELi0EE6subColILi6ELi6ELi0ELi0EEES0_RK11FixedMatrixIdXT_EXT0_EXT1_EXT2_EEiii(%"struct.FixedMatrix"* noalias sret, %struct.Mat6*, i32, i32, i32) + +declare void @_ZN13HingeNodeSpecILi6EE7calcD_GERK11FixedMatrixIdLi6ELi6ELi0ELi0EE(%"struct.HingeNodeSpec<6>"*, %struct.Mat6*) + +declare void @_ZN11MatrixTools7inverseI11FixedMatrixIdLi6ELi6ELi0ELi0EEEET_RKS3_NS_14InverseResultsINS3_10MatrixTypeEEE(%struct.Mat6* noalias sret, %struct.Mat6*, %"struct.MatrixTools::InverseResults >"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi6ELi6EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare void @_ZN13HingeNodeSpecILi5EE9calcPropsEv(%"struct.HingeNodeSpec<5>"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi5ELi6ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare void @_ZN13CDSMatrixBaseIdEC2I11FixedMatrixIdLi5ELi6ELi0ELi0EEEERKT_(%"struct.CDSMatrixBase"*, %"struct.FixedMatrix"*) + +declare void @_ZN11MatrixTools9transposeI11FixedMatrixIdLi6ELi5ELi0ELi0EEEENT_13TransposeTypeERKS3_(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi5EERSoS0_RK15FixedVectorBaseIT_XT0_EE(%"struct.std::basic_ostream >"*, %"struct.FixedVectorBase"*) + +declare void @_ZN11FixedVectorIdLi3ELi0EE6subColILi6ELi5ELi0ELi0EEES0_RK11FixedMatrixIdXT_EXT0_EXT1_EXT2_EEiii(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, i32, i32, i32) + +declare void @_ZN13HingeNodeSpecILi5EE7calcD_GERK11FixedMatrixIdLi6ELi6ELi0ELi0EE(%"struct.HingeNodeSpec<5>"*, %struct.Mat6*) + +declare void @_ZN11MatrixTools7inverseI11FixedMatrixIdLi5ELi5ELi0ELi0EEEET_RKS3_NS_14InverseResultsINS3_10MatrixTypeEEE(%"struct.FixedMatrix"* noalias sret, %"struct.FixedMatrix"*, %"struct.MatrixTools::InverseResults >"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi5ELi5EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare %"struct.std::basic_ostream >"* @_ZlsIdLi5ELi6EERSoS0_RK15FixedMatrixBaseIT_XT0_EXT1_EE(%"struct.std::basic_ostream >"*, %"struct.FixedMatrixBase"*) + +declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind -- GitLab From c2dc7ee5d0782b63e3b5dc7da115200e2fe30f78 Mon Sep 17 00:00:00 2001 From: Bob Wilson Date: Thu, 22 Jan 2009 22:05:48 +0000 Subject: [PATCH 029/682] Fix a minor bug in DAGCombiner's folding of SELECT. Folding "select C, 0, 1" to "C ^ 1" is only valid when C is known to be either 0 or 1. Most of the similar foldings in this function only handle "i1" types, but this one appears intentionally written to handle larger integer types. If C has an integer type larger than "i1", this needs to check if the high bits of a boolean are known to be zero. I also changed the comment to describe this folding as "C ^ 1" instead of "~C", since that is what the code does and since the latter would only be valid for "i1" types. The good news is that most LLVM targets use TargetLowering::ZeroOrOneBooleanContent so this change will not disable the optimization; the bad news is that I've been unable to come up with a testcase to demonstrate the problem. I have also removed a "FIXME" comment for folding "select C, X, 0" to "C & X", since the code looks correct to me. It could be made more aggressive by not limiting the type to "i1", but that would then require checking for TargetLowering::ZeroOrNegativeOneBooleanContent. Similar changes could be done for the other SELECT foldings, but it was decided to be not worth the trouble and complexity (see e.g., r44663). llvm-svn: 62790 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e494da3644d6..7e8e46fba50f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2746,8 +2746,11 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { // fold select C, 1, X -> C | X if (VT == MVT::i1 && N1C && N1C->getAPIntValue() == 1) return DAG.getNode(ISD::OR, VT, N0, N2); - // fold select C, 0, 1 -> ~C - if (VT.isInteger() && VT0.isInteger() && + // fold select C, 0, 1 -> C ^ 1 + if (VT.isInteger() && + (VT0 == MVT::i1 || + (VT0.isInteger() && + TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent)) && N1C && N2C && N1C->isNullValue() && N2C->getAPIntValue() == 1) { SDValue XORNode = DAG.getNode(ISD::XOR, VT0, N0, DAG.getConstant(1, VT0)); if (VT == VT0) @@ -2770,7 +2773,6 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { return DAG.getNode(ISD::OR, VT, NOTNode, N1); } // fold select C, X, 0 -> C & X - // FIXME: this should check for C type == X type, not i1? if (VT == MVT::i1 && N2C && N2C->isNullValue()) return DAG.getNode(ISD::AND, VT, N0, N1); // fold X ? X : Y --> X ? 1 : Y --> X | Y -- GitLab From b6eec2c9795e7ef0bd9300d547052e717ecfa1a2 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:40:54 +0000 Subject: [PATCH 030/682] This test case now passes with RegionStore. llvm-svn: 62795 --- clang/test/Analysis/complex.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/complex.c b/clang/test/Analysis/complex.c index 22a239aace69..fd3d429a1ab8 100644 --- a/clang/test/Analysis/complex.c +++ b/clang/test/Analysis/complex.c @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s +// RUN: clang -analyze -checker-simple -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s #include -- GitLab From 36199e6201368ac9827311e10cba433a328618fa Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:42:16 +0000 Subject: [PATCH 031/682] This test case now passes with RegionStore. llvm-svn: 62796 --- clang/test/Analysis/exercise-ps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c index f561912d21a9..6d58e92c31f2 100644 --- a/clang/test/Analysis/exercise-ps.c +++ b/clang/test/Analysis/exercise-ps.c @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s +// RUN: clang -analyze -checker-simple -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s // // Just exercise the analyzer (no assertions). -- GitLab From dabd546875c7b5ab2914695baf6d7ec0672060be Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:42:59 +0000 Subject: [PATCH 032/682] This test case now passes with RegionStore. llvm-svn: 62798 --- clang/test/Analysis/fields.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/fields.c b/clang/test/Analysis/fields.c index defa19ead992..60353d93adf0 100644 --- a/clang/test/Analysis/fields.c +++ b/clang/test/Analysis/fields.c @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref %s -verify && +// RUN: clang -analyze -checker-cfref %s --analyzer-store-basic -verify && +// RUN: clang -analyze -checker-cfref %s --analyzer-store-region -verify && // RUN: clang -analyze -checker-simple %s -verify unsigned foo(); -- GitLab From 23dd50933245a9da38080a4021424a320728ead4 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:43:59 +0000 Subject: [PATCH 033/682] This test case now passes with RegionStore. llvm-svn: 62799 --- clang/test/Analysis/func.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/func.c b/clang/test/Analysis/func.c index 53c4432a4d05..49f273125691 100644 --- a/clang/test/Analysis/func.c +++ b/clang/test/Analysis/func.c @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s +// RUN: clang -analyze -checker-simple -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s void f(void) { void (*p)(void); -- GitLab From 5324e074a92875f2caf34e18e48a1e1072d6f61e Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:45:21 +0000 Subject: [PATCH 034/682] This test case now passes with RegionStore. llvm-svn: 62800 --- clang/test/Analysis/no-exit-cfg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/no-exit-cfg.c b/clang/test/Analysis/no-exit-cfg.c index 60637a1916e3..362fd88edaf1 100644 --- a/clang/test/Analysis/no-exit-cfg.c +++ b/clang/test/Analysis/no-exit-cfg.c @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s // This is a test case for the issue reported in PR 2819: // http://llvm.org/bugs/show_bug.cgi?id=2819 -- GitLab From 21288a0f1757e635cf420c866794175dcb99825f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:46:40 +0000 Subject: [PATCH 035/682] Enhance test case to test RegionStore with -checker-cfref. llvm-svn: 62801 --- clang/test/Analysis/null-deref-ps.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/null-deref-ps.c b/clang/test/Analysis/null-deref-ps.c index 18884c12aeab..6daedf0f93e3 100644 --- a/clang/test/Analysis/null-deref-ps.c +++ b/clang/test/Analysis/null-deref-ps.c @@ -1,5 +1,6 @@ // RUN: clang -analyze -std=gnu99 -checker-simple -verify %s && -// RUN: clang -analyze -std=gnu99 -checker-simple -analyzer-store-region -analyzer-purge-dead=false -verify %s +// RUN: clang -analyze -std=gnu99 -checker-simple -analyzer-store-region -analyzer-purge-dead=false -verify %s && +// RUN: clang -analyze -std=gnu99 -checker-cfref -analyzer-store-region -verify %s #include #include -- GitLab From c3a28bdb9d63a19b973da273619a3db294ec1aa2 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:49:49 +0000 Subject: [PATCH 036/682] This test case now passes with RegionStore. llvm-svn: 62802 --- clang/test/Analysis/stack-addr-ps.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/stack-addr-ps.c b/clang/test/Analysis/stack-addr-ps.c index 57ce7dc88502..f9de9c0d7254 100644 --- a/clang/test/Analysis/stack-addr-ps.c +++ b/clang/test/Analysis/stack-addr-ps.c @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s +// RUN: clang -analyze -checker-simple -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s #include #include -- GitLab From c15118b03e932a13782037a3f45adc3421f5ecbe Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:50:46 +0000 Subject: [PATCH 037/682] This test case now passes with RegionStore. llvm-svn: 62803 --- clang/test/Analysis/uninit-msg-expr.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/uninit-msg-expr.m b/clang/test/Analysis/uninit-msg-expr.m index 3bceca0e6c37..024e59e86517 100644 --- a/clang/test/Analysis/uninit-msg-expr.m +++ b/clang/test/Analysis/uninit-msg-expr.m @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s +// RUN: clang -analyze -checker-simple -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s //===----------------------------------------------------------------------===// // The following code is reduced using delta-debugging from -- GitLab From db7b61c1b0c4446724ed10e8a2b15ad4d541d7b2 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:51:46 +0000 Subject: [PATCH 038/682] This test case now passes with RegionStore. llvm-svn: 62804 --- clang/test/Analysis/uninit-ps-rdar6145427.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/uninit-ps-rdar6145427.m b/clang/test/Analysis/uninit-ps-rdar6145427.m index 530139da932f..3850846e8fb2 100644 --- a/clang/test/Analysis/uninit-ps-rdar6145427.m +++ b/clang/test/Analysis/uninit-ps-rdar6145427.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -verify -checker-cfref %s +// RUN: clang -analyze -verify -analyzer-store-basic -checker-cfref %s && +// RUN: clang -analyze -verify -analyzer-store-region -checker-cfref %s // Delta-Debugging reduced preamble. typedef signed char BOOL; -- GitLab From c6252091ddd93ceff3b2f4fa00af190782729403 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 22:53:05 +0000 Subject: [PATCH 039/682] This test case now passes with RegionStore. llvm-svn: 62805 --- clang/test/Analysis/uninit-vals.m | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/test/Analysis/uninit-vals.m b/clang/test/Analysis/uninit-vals.m index f7a7df766e50..f89ffeacdfe4 100644 --- a/clang/test/Analysis/uninit-vals.m +++ b/clang/test/Analysis/uninit-vals.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s typedef unsigned int NSUInteger; -- GitLab From b15a3d5969dda977a0be0a4302d0a83e2c6e380c Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Thu, 22 Jan 2009 23:02:58 +0000 Subject: [PATCH 040/682] Use NonFragileABI as name of new Next abi. More comments for the new meta-data. llvm-svn: 62806 --- clang/Driver/clang.cpp | 6 +- clang/include/clang/Basic/LangOptions.h | 4 +- clang/lib/CodeGen/CGObjCMac.cpp | 174 ++++++++++++++++-------- clang/lib/CodeGen/CGObjCRuntime.h | 2 +- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- 5 files changed, 125 insertions(+), 63 deletions(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 9d28720ce2d1..cf58f34e7c99 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -484,7 +484,7 @@ static llvm::cl::opt EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature")); static llvm::cl::opt -ObjCModernABI("fobjc-modern-abi", llvm::cl::desc("enable objective-c's modern abi")); +ObjCNonFragileABI("fobjc-nonfragile-abi", llvm::cl::desc("enable objective-c's nonfragile abi")); // FIXME: This (and all GCC -f options) really come in -f... and @@ -618,8 +618,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, else if (GNURuntime) Options.NeXTRuntime = 0; - if (ObjCModernABI) - Options.ObjCModernABI = 1; + if (ObjCNonFragileABI) + Options.ObjCNonFragileABI = 1; } static llvm::cl::opt diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index d19db4b4046e..daae904823a7 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -38,7 +38,7 @@ struct LangOptions { unsigned ObjC1 : 1; // Objective-C 1 support enabled. unsigned ObjC2 : 1; // Objective-C 2 support enabled. - unsigned ObjCModernABI : 1; // Objective-C modern abi enabled + unsigned ObjCNonFragileABI : 1; // Objective-C modern abi enabled unsigned PascalStrings : 1; // Allow Pascal strings unsigned Boolean : 1; // Allow bool/true/false @@ -63,7 +63,7 @@ public: Trigraphs = BCPLComment = DollarIdents = AsmPreprocessor = 0; ImplicitInt = Digraphs = 0; HexFloats = 0; - GC = ObjC1 = ObjC2 = ObjCModernABI = 0; + GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0; C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0; CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0; LaxVectorConversions = Exceptions = NeXTRuntime = 0; diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 0a2c3e16a1a7..133c9fd9691d 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -65,6 +65,19 @@ public: /// SuperPtrTy - LLVM type for struct objc_super *. const llvm::Type *SuperPtrTy; + /// PropertyTy - LLVM type for struct objc_property (struct _prop_t + /// in GCC parlance). + const llvm::StructType *PropertyTy; + + /// PropertyListTy - LLVM type for struct objc_property_list + /// (_prop_list_t in GCC parlance). + const llvm::StructType *PropertyListTy; + /// PropertyListPtrTy - LLVM type for struct objc_property_list*. + const llvm::Type *PropertyListPtrTy; + + // MethodTy - LLVM type for struct objc_method. + const llvm::StructType *MethodTy; + llvm::Function *GetPropertyFn, *SetPropertyFn; llvm::Function *EnumerationMutationFn; @@ -124,14 +137,6 @@ public: /// MethodDescriptionListPtrTy - LLVM type for struct /// objc_method_description_list *. const llvm::Type *MethodDescriptionListPtrTy; - /// PropertyTy - LLVM type for struct objc_property (struct _prop_t - /// in GCC parlance). - const llvm::StructType *PropertyTy; - /// PropertyListTy - LLVM type for struct objc_property_list - /// (_prop_list_t in GCC parlance). - const llvm::StructType *PropertyListTy; - /// PropertyListPtrTy - LLVM type for struct objc_property_list*. - const llvm::Type *PropertyListPtrTy; /// ProtocolListTy - LLVM type for struct objc_property_list. const llvm::Type *ProtocolListTy; /// ProtocolListPtrTy - LLVM type for struct objc_property_list*. @@ -156,8 +161,6 @@ public: const llvm::Type *IvarListTy; /// IvarListPtrTy - LLVM type for struct objc_ivar_list *. const llvm::Type *IvarListPtrTy; - // MethodTy - LLVM type for struct objc_method. - const llvm::StructType *MethodTy; /// MethodListTy - LLVM type for struct objc_method_list. const llvm::Type *MethodListTy; /// MethodListPtrTy - LLVM type for struct objc_method_list *. @@ -208,12 +211,12 @@ public: } }; -/// ObjCModernTypesHelper - will have all types needed by objective-c's +/// ObjCNonFragileABITypesHelper - will have all types needed by objective-c's /// modern abi -class ObjCModernTypesHelper : public ObjCCommonTypesHelper { +class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { public: - ObjCModernTypesHelper(CodeGen::CodeGenModule &cgm); - ~ObjCModernTypesHelper(){} + ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); + ~ObjCNonFragileABITypesHelper(){} }; class CGObjCCommonMac : public CodeGen::CGObjCRuntime { @@ -492,11 +495,11 @@ public: llvm::Value *src, llvm::Value *dest); }; -class CGObjCModernMac : public CGObjCCommonMac { +class CGObjCNonFragileABIMac : public CGObjCCommonMac { private: - ObjCModernTypesHelper ObjCTypes; + ObjCNonFragileABITypesHelper ObjCTypes; public: - CGObjCModernMac(CodeGen::CodeGenModule &cgm); + CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); }; } // end anonymous namespace @@ -2256,7 +2259,7 @@ void CGObjCMac::FinishModule() { CGM.getModule().appendModuleInlineAsm(s.str()); } -CGObjCModernMac::CGObjCModernMac(CodeGen::CodeGenModule &cgm) +CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), ObjCTypes(cgm) { @@ -2312,6 +2315,41 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) SuperTy = cast(Types.ConvertType(SuperCTy)); SuperPtrTy = llvm::PointerType::getUnqual(SuperTy); + // struct _prop_t { + // char *name; + // char *attributes; + // } + PropertyTy = llvm::StructType::get(Int8PtrTy, + Int8PtrTy, + NULL); + CGM.getModule().addTypeName("struct._prop_t", + PropertyTy); + + // struct _prop_list_t { + // uint32_t entsize; // sizeof(struct _objc_property) + // uint32_t count_of_properties; + // struct _objc_property prop_list[count_of_properties]; + // } + PropertyListTy = llvm::StructType::get(IntTy, + IntTy, + llvm::ArrayType::get(PropertyTy, 0), + NULL); + CGM.getModule().addTypeName("struct._prop_list_t", + PropertyListTy); + // struct _prop_list_t * + PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); + + // struct _objc_method { + // SEL _cmd; + // char *method_type; + // char *_imp; + // } + MethodTy = llvm::StructType::get(SelectorPtrTy, + Int8PtrTy, + Int8PtrTy, + NULL); + CGM.getModule().addTypeName("struct._objc_method", MethodTy); + // Property manipulation functions. // id objc_getProperty (id, SEL, ptrdiff_t, bool) @@ -2413,30 +2451,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) MethodDescriptionListPtrTy = llvm::PointerType::getUnqual(MethodDescriptionListTy); - // struct _objc_property { - // char *name; - // char *attributes; - // } - PropertyTy = llvm::StructType::get(Int8PtrTy, - Int8PtrTy, - NULL); - CGM.getModule().addTypeName("struct._objc_property", - PropertyTy); - - // struct _objc_property_list { - // uint32_t entsize; // sizeof(struct _objc_property) - // uint32_t count_of_properties; - // struct _objc_property prop_list[count_of_properties]; - // } - PropertyListTy = llvm::StructType::get(IntTy, - IntTy, - llvm::ArrayType::get(PropertyTy, 0), - NULL); - CGM.getModule().addTypeName("struct._objc_property_list", - PropertyListTy); - // struct _objc_property_list * - PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy); - // Protocol description structures // struct _objc_protocol_extension { @@ -2512,17 +2526,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) CGM.getModule().addTypeName("struct._objc_ivar_list", IvarListTy); IvarListPtrTy = llvm::PointerType::getUnqual(IvarListTy); - // struct _objc_method { - // SEL _cmd; - // char *method_type; - // char *_imp; - // } - MethodTy = llvm::StructType::get(SelectorPtrTy, - Int8PtrTy, - Int8PtrTy, - NULL); - CGM.getModule().addTypeName("struct._objc_method", MethodTy); - // struct _objc_method_list * MethodListTy = llvm::OpaqueType::get(); CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy); @@ -2763,9 +2766,68 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) } -ObjCModernTypesHelper::ObjCModernTypesHelper(CodeGen::CodeGenModule &cgm) +ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm) : ObjCCommonTypesHelper(cgm) { + // struct _method_list_t { + // uint32_t entsize; // sizeof(struct _objc_method) + // uint32_t method_count; + // struct _objc_method method_list[method_count]; + // } + + // struct _protocol_t { + // id isa; // NULL + // const char * const protocol_name; + // const struct * _protocol_t const protocol_list; + // const struct method_list_t * const instance_methods; + // const struct method_list_t * const class_methods; + // const struct method_list_t *optionalInstanceMethods; + // const struct method_list_t *optionalClassMethods; + // const struct _prop_list_t * const properties; + // const uint32_t size; // sizeof(struct _protocol_t) + // const uint32_t flags; // = 0 + // } + + // struct _objc_protocol_list { + // long protocol_count; + // struct _protocol_t[protocol_count]; + // } + + // struct _class_t { + // struct _class_t *isa; + // struct _class_t * const superclass; + // void *cache; + // IMP *vtable; + // struct class_ro_t *ro; + // } + + // struct _ivar_t { + // unsigned long int *offset; // pointer to ivar offset location + // char *name; + // char *type; + // uint32_t alignment; + // uint32_t size; + // } + + // struct _ivar_list_t { + // uint32 entsize; // sizeof(struct _ivar_t) + // uint32 count; + // struct _iver_t list[count]; + // } + + // struct class_ro_t { + // uint32_t const flags; + // uint32_t const instanceStart; + // uint32_t const instanceSize; + // uint32_t const reserved; // only when building for 64bit targets + // const uint8_t * const ivarLayout; + // const char *const name; + // const struct _method_list_t * const baseMethods; + // const struct _objc_protocol_list *const baseProtocols; + // const struct _ivar_list_t *const ivars; + // const uint8_t * const weakIvarLayout; + // const struct _prop_list_t * const properties; + // } } /* *** */ @@ -2776,7 +2838,7 @@ CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { } CodeGen::CGObjCRuntime * -CodeGen::CreateMacModernObjCRuntime(CodeGen::CodeGenModule &CGM) { +CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { return 0; - // return new CGObjCModernMac(CGM); + // return new CGObjCNonFragileABIMac(CGM); } diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index 409ae3722115..01543c53e24f 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -161,7 +161,7 @@ public: //TODO: This should include some way of selecting which runtime to target. CGObjCRuntime *CreateGNUObjCRuntime(CodeGenModule &CGM); CGObjCRuntime *CreateMacObjCRuntime(CodeGenModule &CGM); -CGObjCRuntime *CreateMacModernObjCRuntime(CodeGenModule &CGM); +CGObjCRuntime *CreateMacNonFragileABIObjCRuntime(CodeGenModule &CGM); } } #endif diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 79f00dec9771..6e1321f4d6c6 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -39,7 +39,7 @@ CodeGenModule::CodeGenModule(ASTContext &C, const LangOptions &LO, if (Features.ObjC1) { if (Features.NeXTRuntime) { - Runtime = Features.ObjCModernABI ? CreateMacModernObjCRuntime(*this) + Runtime = Features.ObjCNonFragileABI ? CreateMacNonFragileABIObjCRuntime(*this) : CreateMacObjCRuntime(*this); } else { Runtime = CreateGNUObjCRuntime(*this); -- GitLab From 0681693277c8819511667d0509affd06bcbb92bd Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 22 Jan 2009 23:05:37 +0000 Subject: [PATCH 041/682] Handful of fixes to the VC project files. llvm-svn: 62807 --- llvm/win32/CodeGen/CodeGen.vcproj | 16 ++++++++-------- llvm/win32/Transforms/Transforms.vcproj | 12 ++++-------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/llvm/win32/CodeGen/CodeGen.vcproj b/llvm/win32/CodeGen/CodeGen.vcproj index 1e0976bb681a..7707e790278b 100644 --- a/llvm/win32/CodeGen/CodeGen.vcproj +++ b/llvm/win32/CodeGen/CodeGen.vcproj @@ -476,6 +476,14 @@ RelativePath="..\..\lib\CodeGen\RegisterScavenging.cpp" > + + + + @@ -551,14 +559,6 @@ RelativePath="..\..\lib\CodeGen\SelectionDAG\LegalizeVectorTypes.cpp" > - - - - diff --git a/llvm/win32/Transforms/Transforms.vcproj b/llvm/win32/Transforms/Transforms.vcproj index 0bde3d89ffad..2554a4ea3b67 100644 --- a/llvm/win32/Transforms/Transforms.vcproj +++ b/llvm/win32/Transforms/Transforms.vcproj @@ -343,10 +343,6 @@ - - @@ -367,6 +363,10 @@ RelativePath="..\..\lib\Transforms\IPO\ExtractGV.cpp" > + + @@ -609,10 +609,6 @@ RelativePath="..\..\lib\Transforms\Utils\CodeExtractor.cpp" > - - -- GitLab From d8aea2dba8097e43469a4ad80b620884ec397e3a Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Thu, 22 Jan 2009 23:06:24 +0000 Subject: [PATCH 042/682] Disable language extensions for the clang parser. llvm-svn: 62808 --- clang/win32/clangParse/clangParse.vcproj | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/win32/clangParse/clangParse.vcproj b/clang/win32/clangParse/clangParse.vcproj index ba217cb6cf89..1ee5a75de7ec 100644 --- a/clang/win32/clangParse/clangParse.vcproj +++ b/clang/win32/clangParse/clangParse.vcproj @@ -46,6 +46,7 @@ MinimalRebuild="true" BasicRuntimeChecks="3" RuntimeLibrary="3" + DisableLanguageExtensions="true" UsePrecompiledHeader="0" ProgramDataBaseFileName="$(OutDir)\$(ProjectName).pdb" WarningLevel="3" -- GitLab From 2e1cfd02679b8b2d4cdbe75344071389d006c631 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Thu, 22 Jan 2009 23:19:32 +0000 Subject: [PATCH 043/682] ccc: Bug fix, driver logic was allowing child jobs to pipe output when parent wasn't expecting it. llvm-svn: 62811 --- clang/tools/ccc/ccclib/Driver.py | 6 +++--- clang/tools/ccc/test/ccc/universal-hello.c | 3 +++ 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py index 3452ed173b23..2ba1cf6cd80c 100644 --- a/clang/tools/ccc/ccclib/Driver.py +++ b/clang/tools/ccc/ccclib/Driver.py @@ -672,8 +672,8 @@ class Driver(object): inputList = phase.inputs[0].inputs # Only try to use pipes when exactly one input. - canAcceptPipe = len(inputList) == 1 and tool.acceptsPipedInput() - inputs = [createJobs(tc, p, canAcceptPipe, False, + attemptToPipeInput = len(inputList) == 1 and tool.acceptsPipedInput() + inputs = [createJobs(tc, p, attemptToPipeInput, False, arch, tcArgs, linkingOutput) for p in inputList] @@ -694,7 +694,7 @@ class Driver(object): # Figure out where to put the job (pipes). jobList = jobs - if canAcceptPipe and isinstance(inputs[0].source, Jobs.PipedJob): + if isinstance(inputs[0].source, Jobs.PipedJob): jobList = inputs[0].source baseInput = inputs[0].baseInput diff --git a/clang/tools/ccc/test/ccc/universal-hello.c b/clang/tools/ccc/test/ccc/universal-hello.c index 8d4b3e336465..7702b38229c2 100644 --- a/clang/tools/ccc/test/ccc/universal-hello.c +++ b/clang/tools/ccc/test/ccc/universal-hello.c @@ -1,6 +1,9 @@ // RUN: xcc -arch ppc -arch i386 -arch x86_64 %s -o %t && // RUN: %t | grep "Hello, World" && +// RUN: xcc -pipe -arch ppc -arch i386 -arch x86_64 %s -o %t && +// RUN: %t | grep "Hello, World" && + // Check that multiple archs are handled properly. // RUN: xcc -ccc-print-phases -### -arch ppc -arch ppc %s | grep linker- | count 1 -- GitLab From d7fb85e8ad6f006537cd2eb2dfaba38268fb794f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 22 Jan 2009 23:26:18 +0000 Subject: [PATCH 044/682] Reimplement the handling of the "current object" in designator initializers, so that we are within the appropriate subobject after we've processed a multi-designator designation. We're matching GCC and EDG's behavior on all examples I've found thus far. *Huge* thanks to Eli Friedman for pointing out my fundamental misunderstanding of "current object" in the C99 spec. llvm-svn: 62812 --- clang/include/clang/AST/Expr.h | 5 + clang/lib/Sema/Sema.h | 16 +- clang/lib/Sema/SemaInit.cpp | 342 +++++++++++++--------- clang/test/Sema/designated-initializers.c | 38 ++- 4 files changed, 251 insertions(+), 150 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 9d7370735966..a93f0f467b18 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1853,6 +1853,11 @@ public: Field.NameOrField = reinterpret_cast(FD); } + SourceLocation getDotLoc() const { + assert(Kind == FieldDesignator && "Only valid on a field designator"); + return SourceLocation::getFromRawEncoding(Field.DotLoc); + } + SourceLocation getFieldLoc() const { assert(Kind == FieldDesignator && "Only valid on a field designator"); return SourceLocation::getFromRawEncoding(Field.FieldLoc); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 9f1f2a3c3189..128ba8813a1f 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -19,6 +19,7 @@ #include "CXXFieldCollector.h" #include "SemaOverload.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/Expr.h" #include "clang/Parse/Action.h" #include "clang/Basic/Diagnostic.h" #include "llvm/ADT/SmallVector.h" @@ -1838,6 +1839,7 @@ class InitListChecker { unsigned &Index); void CheckListElementTypes(InitListExpr *IList, QualType &DeclType, + bool SubobjectIsDesignatorContext, unsigned &Index); void CheckSubElementType(InitListExpr *IList, QualType ElemType, Expr *expr, unsigned &Index); @@ -1846,11 +1848,17 @@ class InitListChecker { Expr *expr, unsigned &Index); void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index); void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, - unsigned &Index); - void CheckArrayType(InitListExpr *IList, QualType &DeclType, unsigned &Index); + RecordDecl::field_iterator Field, + bool SubobjectIsDesignatorContext, unsigned &Index); + void CheckArrayType(InitListExpr *IList, QualType &DeclType, + llvm::APSInt elementIndex, + bool SubobjectIsDesignatorContext, unsigned &Index); bool CheckDesignatedInitializer(InitListExpr *IList, DesignatedInitExpr *DIE, - QualType DeclType, FieldDecl *&DesignatedField, - llvm::APSInt &DesignatedIndex, unsigned &Index); + DesignatedInitExpr::designators_iterator D, + QualType &CurrentObjectType, + RecordDecl::field_iterator *NextField, + llvm::APSInt *NextElementIndex, + unsigned &Index); int numArrayElements(QualType DeclType); int numStructUnionElements(QualType DeclType); public: diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 163dac94b92b..e855840ea5df 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -74,7 +74,7 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList, // Check the element types *before* we create the implicit init list; // otherwise, we might end up taking the wrong number of elements unsigned NewIndex = Index; - CheckListElementTypes(ParentIList, T, NewIndex); + CheckListElementTypes(ParentIList, T, false, NewIndex); for (int i = 0; i < maxElements; ++i) { // Don't attempt to go past the end of the init list @@ -101,7 +101,7 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T, unsigned &Index) { assert(IList->isExplicit() && "Illegal Implicit InitListExpr"); - CheckListElementTypes(IList, T, Index); + CheckListElementTypes(IList, T, true, Index); IList->setType(T); if (hadError) return; @@ -130,16 +130,22 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T, void InitListChecker::CheckListElementTypes(InitListExpr *IList, QualType &DeclType, + bool SubobjectIsDesignatorContext, unsigned &Index) { if (DeclType->isScalarType()) { CheckScalarType(IList, DeclType, 0, Index); } else if (DeclType->isVectorType()) { CheckVectorType(IList, DeclType, Index); } else if (DeclType->isAggregateType() || DeclType->isUnionType()) { - if (DeclType->isStructureType() || DeclType->isUnionType()) - CheckStructUnionTypes(IList, DeclType, Index); - else if (DeclType->isArrayType()) - CheckArrayType(IList, DeclType, Index); + if (DeclType->isStructureType() || DeclType->isUnionType()) { + RecordDecl *RD = DeclType->getAsRecordType()->getDecl(); + CheckStructUnionTypes(IList, DeclType, RD->field_begin(), + SubobjectIsDesignatorContext, Index); + } else if (DeclType->isArrayType()) { + // FIXME: Is 32 always large enough for array indices? + llvm::APSInt Zero(32, false); + CheckArrayType(IList, DeclType, Zero, SubobjectIsDesignatorContext, Index); + } else assert(0 && "Aggregate that isn't a function or array?!"); } else if (DeclType->isVoidType() || DeclType->isFunctionType()) { @@ -239,6 +245,8 @@ void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType, } void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, + llvm::APSInt elementIndex, + bool SubobjectIsDesignatorContext, unsigned &Index) { // Check for the special-case of initializing an array with a string. if (Index < IList->getNumInits()) { @@ -263,7 +271,6 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, // FIXME: Will 32 bits always be enough? I hope so. const unsigned ArraySizeBits = 32; - llvm::APSInt elementIndex(ArraySizeBits, 0); // We might know the maximum number of elements in advance. llvm::APSInt maxElements(ArraySizeBits, 0); @@ -279,16 +286,25 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, while (Index < IList->getNumInits()) { Expr *Init = IList->getInit(Index); if (DesignatedInitExpr *DIE = dyn_cast(Init)) { - // C99 6.7.8p17: - // [...] In contrast, a designation causes the following - // initializer to begin initialization of the subobject - // described by the designator. - FieldDecl *DesignatedField = 0; - if (CheckDesignatedInitializer(IList, DIE, DeclType, DesignatedField, - elementIndex, Index)) + // If we're not the subobject that matches up with the '{' for + // the designator, we shouldn't be handling the + // designator. Return immediately. + if (!SubobjectIsDesignatorContext) + return; + + // Handle this designated initializer. elementIndex will be + // updated to be the next array element we'll initialize. + if (CheckDesignatedInitializer(IList, DIE, DIE->designators_begin(), + DeclType, 0, &elementIndex, Index)) { hadError = true; + continue; + } + + // If the array is of incomplete type, keep track of the number of + // elements in the initializer. + if (!maxElementsKnown && elementIndex > maxElements) + maxElements = elementIndex; - ++elementIndex; continue; } @@ -324,6 +340,8 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, + RecordDecl::field_iterator Field, + bool SubobjectIsDesignatorContext, unsigned &Index) { RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl(); @@ -338,30 +356,23 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, // because an error should get printed out elsewhere. It might be // worthwhile to skip over the rest of the initializer, though. RecordDecl *RD = DeclType->getAsRecordType()->getDecl(); - RecordDecl::field_iterator Field = RD->field_begin(), - FieldEnd = RD->field_end(); + RecordDecl::field_iterator FieldEnd = RD->field_end(); while (Index < IList->getNumInits()) { Expr *Init = IList->getInit(Index); if (DesignatedInitExpr *DIE = dyn_cast(Init)) { - // C99 6.7.8p17: - // [...] In contrast, a designation causes the following - // initializer to begin initialization of the subobject - // described by the designator. Initialization then continues - // forward in order, beginning with the next subobject after - // that described by the designator. - FieldDecl *DesignatedField = 0; - llvm::APSInt LastElement; - if (CheckDesignatedInitializer(IList, DIE, DeclType, DesignatedField, - LastElement, Index)) { + // If we're not the subobject that matches up with the '{' for + // the designator, we shouldn't be handling the + // designator. Return immediately. + if (!SubobjectIsDesignatorContext) + return; + + // Handle this designated initializer. Field will be updated to + // the next field that we'll be initializing. + if (CheckDesignatedInitializer(IList, DIE, DIE->designators_begin(), + DeclType, &Field, 0, Index)) hadError = true; - continue; - } - Field = RecordDecl::field_iterator( - DeclContext::decl_iterator(DesignatedField), - DeclType->getAsRecordType()->getDecl()->decls_end()); - ++Field; continue; } @@ -411,136 +422,177 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList, /// @param DeclType The type of the "current object" (C99 6.7.8p17), /// into which the designation in @p DIE should refer. /// -/// @param DesignatedField If the first designator in @p DIE is a field, -/// this will be set to the field declaration corresponding to the -/// field named by the designator. +/// @param NextField If non-NULL and the first designator in @p DIE is +/// a field, this will be set to the field declaration corresponding +/// to the field named by the designator. /// -/// @param DesignatedIndex If the first designator in @p DIE is an -/// array designator or GNU array-range designator, this will be set -/// to the last index initialized by this designator. +/// @param NextElementIndex If non-NULL and the first designator in @p +/// DIE is an array designator or GNU array-range designator, this +/// will be set to the last index initialized by this designator. /// /// @param Index Index into @p IList where the designated initializer /// @p DIE occurs. /// /// @returns true if there was an error, false otherwise. -bool InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, - DesignatedInitExpr *DIE, - QualType DeclType, - FieldDecl *&DesignatedField, - llvm::APSInt &DesignatedIndex, - unsigned &Index) { - // DeclType is always the type of the "current object" (C99 6.7.8p17). - - for (DesignatedInitExpr::designators_iterator D = DIE->designators_begin(), - DEnd = DIE->designators_end(); - D != DEnd; ++D) { - if (D->isFieldDesignator()) { - // C99 6.7.8p7: - // - // If a designator has the form - // - // . identifier - // - // then the current object (defined below) shall have - // structure or union type and the identifier shall be the - // name of a member of that type. - const RecordType *RT = DeclType->getAsRecordType(); - if (!RT) { - SemaRef->Diag(DIE->getSourceRange().getBegin(), - diag::err_field_designator_non_aggr) - << SemaRef->getLangOptions().CPlusPlus << DeclType; - ++Index; - return true; - } +bool +InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, + DesignatedInitExpr *DIE, + DesignatedInitExpr::designators_iterator D, + QualType &CurrentObjectType, + RecordDecl::field_iterator *NextField, + llvm::APSInt *NextElementIndex, + unsigned &Index) { + bool IsFirstDesignator = (D == DIE->designators_begin()); - IdentifierInfo *FieldName = D->getFieldName(); - DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName); - FieldDecl *ThisField = 0; - if (Lookup.first == Lookup.second) { - // Lookup did not find anything with this name. - SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_unknown) - << FieldName << DeclType; - } else if (isa(*Lookup.first)) { - // Name lookup found a field. - ThisField = cast(*Lookup.first); - // FIXME: Make sure this isn't a field in an anonymous - // struct/union. - } else { - // Name lookup found something, but it wasn't a field. - SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_nonfield) - << FieldName; - SemaRef->Diag((*Lookup.first)->getLocation(), - diag::note_field_designator_found); - } + if (D == DIE->designators_end()) { + // Check the actual initialization for the designated object type. + bool prevHadError = hadError; + CheckSubElementType(IList, CurrentObjectType, DIE->getInit(), Index); + return hadError && !prevHadError; + } - if (!ThisField) { - ++Index; - return true; - } + if (D->isFieldDesignator()) { + // C99 6.7.8p7: + // + // If a designator has the form + // + // . identifier + // + // then the current object (defined below) shall have + // structure or union type and the identifier shall be the + // name of a member of that type. + const RecordType *RT = CurrentObjectType->getAsRecordType(); + if (!RT) { + SourceLocation Loc = D->getDotLoc(); + if (Loc.isInvalid()) + Loc = D->getFieldLoc(); + SemaRef->Diag(Loc, diag::err_field_designator_non_aggr) + << SemaRef->getLangOptions().CPlusPlus << CurrentObjectType; + ++Index; + return true; + } + + IdentifierInfo *FieldName = D->getFieldName(); + DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName); + FieldDecl *DesignatedField = 0; + if (Lookup.first == Lookup.second) { + // Lookup did not find anything with this name. + SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_unknown) + << FieldName << CurrentObjectType; + } else if (isa(*Lookup.first)) { + // Name lookup found a field. + DesignatedField = cast(*Lookup.first); + // FIXME: Make sure this isn't a field in an anonymous + // struct/union. + } else { + // Name lookup found something, but it wasn't a field. + SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_nonfield) + << FieldName; + SemaRef->Diag((*Lookup.first)->getLocation(), + diag::note_field_designator_found); + } + + if (!DesignatedField) { + ++Index; + return true; + } - // Update the designator with the field declaration. - D->setField(ThisField); + // Update the designator with the field declaration. + D->setField(DesignatedField); - if (D == DIE->designators_begin()) - DesignatedField = ThisField; + // Recurse to check later designated subobjects. + QualType FieldType = DesignatedField->getType(); + if (CheckDesignatedInitializer(IList, DIE, ++D, FieldType, 0, 0, Index)) + return true; + + // Find the position of the next field to be initialized in this + // subobject. + RecordDecl::field_iterator Field(DeclContext::decl_iterator(DesignatedField), + RT->getDecl()->decls_end()); + ++Field; - // The current object is now the type of this field. - DeclType = ThisField->getType(); - } else { - // C99 6.7.8p6: - // - // If a designator has the form - // - // [ constant-expression ] - // - // then the current object (defined below) shall have array - // type and the expression shall be an integer constant - // expression. If the array is of unknown size, any - // nonnegative value is valid. - const ArrayType *AT = SemaRef->Context.getAsArrayType(DeclType); - if (!AT) { - SemaRef->Diag(D->getLBracketLoc(), diag::err_array_designator_non_array) - << DeclType; - ++Index; - return true; - } + // If this the first designator, our caller will continue checking + // the rest of this struct/class/union subobject. + if (IsFirstDesignator) { + if (NextField) + *NextField = Field; + return false; + } - Expr *IndexExpr = 0; - llvm::APSInt ThisIndex; - if (D->isArrayDesignator()) - IndexExpr = DIE->getArrayIndex(*D); - else { - assert(D->isArrayRangeDesignator() && "Need array-range designator"); - IndexExpr = DIE->getArrayRangeEnd(*D); - } + // Check the remaining fields within this class/struct/union subobject. + bool prevHadError = hadError; + CheckStructUnionTypes(IList, CurrentObjectType, Field, false, Index); + return hadError && !prevHadError; + } - bool ConstExpr - = IndexExpr->isIntegerConstantExpr(ThisIndex, SemaRef->Context); - assert(ConstExpr && "Expression must be constant"); (void)ConstExpr; - - if (isa(AT)) { - llvm::APSInt MaxElements(cast(AT)->getSize(), false); - if (ThisIndex >= MaxElements) { - SemaRef->Diag(IndexExpr->getSourceRange().getBegin(), - diag::err_array_designator_too_large) - << ThisIndex.toString(10) << MaxElements.toString(10); - ++Index; - return true; - } - } + // C99 6.7.8p6: + // + // If a designator has the form + // + // [ constant-expression ] + // + // then the current object (defined below) shall have array + // type and the expression shall be an integer constant + // expression. If the array is of unknown size, any + // nonnegative value is valid. + // + // Additionally, cope with the GNU extension that permits + // designators of the form + // + // [ constant-expression ... constant-expression ] + const ArrayType *AT = SemaRef->Context.getAsArrayType(CurrentObjectType); + if (!AT) { + SemaRef->Diag(D->getLBracketLoc(), diag::err_array_designator_non_array) + << CurrentObjectType; + ++Index; + return true; + } - if (D == DIE->designators_begin()) - DesignatedIndex = ThisIndex; + Expr *IndexExpr = 0; + llvm::APSInt DesignatedIndex; + if (D->isArrayDesignator()) + IndexExpr = DIE->getArrayIndex(*D); + else { + assert(D->isArrayRangeDesignator() && "Need array-range designator"); + IndexExpr = DIE->getArrayRangeEnd(*D); + } - // The current object is now the element type of this array. - DeclType = AT->getElementType(); + bool ConstExpr + = IndexExpr->isIntegerConstantExpr(DesignatedIndex, SemaRef->Context); + assert(ConstExpr && "Expression must be constant"); (void)ConstExpr; + + if (isa(AT)) { + llvm::APSInt MaxElements(cast(AT)->getSize(), false); + if (DesignatedIndex >= MaxElements) { + SemaRef->Diag(IndexExpr->getSourceRange().getBegin(), + diag::err_array_designator_too_large) + << DesignatedIndex.toString(10) << MaxElements.toString(10) + << IndexExpr->getSourceRange(); + ++Index; + return true; } } - - // Check the actual initialization for the designated object type. + + // Recurse to check later designated subobjects. + QualType ElementType = AT->getElementType(); + if (CheckDesignatedInitializer(IList, DIE, ++D, ElementType, 0, 0, Index)) + return true; + + // Move to the next index in the array that we'll be initializing. + ++DesignatedIndex; + + // If this the first designator, our caller will continue checking + // the rest of this array subobject. + if (IsFirstDesignator) { + if (NextElementIndex) + *NextElementIndex = DesignatedIndex; + return false; + } + + // Check the remaining elements within this array subobject. bool prevHadError = hadError; - CheckSubElementType(IList, DeclType, DIE->getInit(), Index); - return hadError && !prevHadError; + CheckArrayType(IList, CurrentObjectType, DesignatedIndex, true, Index); + return hadError && !prevHadError; } /// Check that the given Index expression is a valid array designator diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index 5efb4444956b..cc2c3468edc3 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -1,5 +1,9 @@ // RUN: clang -fsyntax-only -verify %s +int complete_array_from_init[] = { 1, 2, [10] = 5, 1, 2, [5] = 2, 6 }; + +int complete_array_from_init_check[((sizeof(complete_array_from_init) / sizeof(int)) == 13)? 1 : -1]; + int iarray[10] = { [0] = 1, [1 ... 5] = 2, @@ -11,6 +15,9 @@ int iarray[10] = { int iarray2[10] = { [10] = 1, // expected-error{{array designator index (10) exceeds array bounds (10)}} +}; + +int iarray3[10] = { [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}} }; @@ -23,7 +30,9 @@ struct point p1 = { .y = 1.0, x: 2.0, .a = 4.0, // expected-error{{field designator 'a' does not refer to any field in type 'struct point'}} +}; +struct point p2 = { [1] = 1.0 // expected-error{{array designator cannot initialize non-array type}} }; @@ -31,9 +40,15 @@ struct point array[10] = { [0].x = 1.0, [1].y = 2.0, [2].z = 3.0, // expected-error{{field designator 'z' does not refer to any field in type 'struct point'}} +}; + +struct point array2[10] = { [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}} [4 ... 5].y = 2.0, - [4 ... 6] = { .x = 3, .y = 4.0 }, + [4 ... 6] = { .x = 3, .y = 4.0 } +}; + +struct point array3[10] = { .x = 5 // expected-error{{field designator cannot initialize a non-struct, non-union type}} }; @@ -76,3 +91,24 @@ struct translator { .wonky = { 0 } }; +int anint; +struct {int x,*y;} z[] = {[0].x = 2, &z[0].x}; + +struct outer { struct inner { int x, *y; } in, *inp; } zz[] = { + [0].in.x = 2, &zz[0].in.x, &zz[0].in, + 0, &anint, &zz[1].in, + [3].in = { .y = &anint, .x = 17 }, + [7].in.y = &anint, &zz[0].in, + [4].in.y = &anint, [5].in.x = 12 +}; + +int zz_sizecheck[sizeof(zz) / sizeof(struct outer) == 8? 1 : -1 ]; + +struct disklabel_ops { + struct {} type; + int labelsize; +}; + +struct disklabel_ops disklabel64_ops = { + .labelsize = sizeof(struct disklabel_ops) +}; -- GitLab From 1f9053a83ca977645ba3e005a60072cba59fcc22 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 23:38:45 +0000 Subject: [PATCH 045/682] do not sign extend characters input to isprint. This improves compatibility with VC++. Patch by Max Burke! llvm-svn: 62813 --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp index 5085fd4bdab5..50cd24ba8227 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -681,7 +681,7 @@ static void printStringChar(raw_ostream &O, char C) { O << "\\\""; } else if (C == '\\') { O << "\\\\"; - } else if (isprint(C)) { + } else if (isprint((unsigned char)C)) { O << C; } else { switch(C) { -- GitLab From fe0f1788cacfd71a9325f578329b8c0734465020 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 23:43:57 +0000 Subject: [PATCH 046/682] Add RegionStore support for the implicit object region that 'self' references. This causes tests 'ObjCProperties.m' and 'refcnt_naming.m' to now pass with RegionStore. llvm-svn: 62814 --- clang/lib/Analysis/RegionStore.cpp | 29 +++++++++++++++++++++++----- clang/test/Analysis/ObjCProperties.m | 4 +++- clang/test/Analysis/refcnt_naming.m | 3 ++- 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 6f0ec1d0b73b..ec801d47f28a 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -110,13 +110,19 @@ class VISIBILITY_HIDDEN RegionStoreManager : public StoreManager { RegionViews::Factory RVFactory; GRStateManager& StateMgr; + const MemRegion* SelfRegion; + const ImplicitParamDecl *SelfDecl; public: RegionStoreManager(GRStateManager& mgr) : StoreManager(mgr.getAllocator()), RBFactory(mgr.getAllocator()), RVFactory(mgr.getAllocator()), - StateMgr(mgr) {} + StateMgr(mgr), SelfRegion(0), SelfDecl(0) { + if (const ObjCMethodDecl* MD = + dyn_cast(&StateMgr.getCodeDecl())) + SelfDecl = MD->getSelfDecl(); + } virtual ~RegionStoreManager() {} @@ -187,8 +193,16 @@ public: /// 'this' object (C++). When used when analyzing a normal function this /// method returns NULL. const MemRegion* getSelfRegion(Store) { - assert (false && "Not implemented."); - return 0; + if (!SelfDecl) + return 0; + + if (!SelfRegion) { + const ObjCMethodDecl *MD = cast(&StateMgr.getCodeDecl()); + SelfRegion = MRMgr.getObjCObjectRegion(MD->getClassInterface(), + MRMgr.getHeapRegion()); + } + + return SelfRegion; } /// RemoveDeadBindings - Scans the RegionStore of 'state' for dead values. @@ -563,9 +577,14 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { // function/method. These are either symbolic values or 'undefined'. // We treat function parameters as symbolic values. - if (const VarRegion* VR = dyn_cast(R)) - if (isa(VR->getDecl())) + if (const VarRegion* VR = dyn_cast(R)) { + const VarDecl *VD = VR->getDecl(); + + if (isa(VD)) return SVal::GetRValueSymbolVal(getSymbolManager(), VR); + else if (VD == SelfDecl) + return loc::MemRegionVal(getSelfRegion(0)); + } if (MRMgr.onStack(R) || MRMgr.onHeap(R)) { // All stack variables are considered to have undefined values diff --git a/clang/test/Analysis/ObjCProperties.m b/clang/test/Analysis/ObjCProperties.m index f2f18b577115..7ce434fbfa13 100644 --- a/clang/test/Analysis/ObjCProperties.m +++ b/clang/test/Analysis/ObjCProperties.m @@ -1,4 +1,6 @@ -// RUN: clang -analyze -checker-simple %s -verify +// RUN: clang -analyze -checker-simple %s -verify && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic %s -verify && +// RUN: clang -analyze -checker-cfref -analyzer-store-region %s -verify // The point of this test cases is to exercise properties in the static // analyzer diff --git a/clang/test/Analysis/refcnt_naming.m b/clang/test/Analysis/refcnt_naming.m index 3c86853b47ee..44ccf27a5662 100644 --- a/clang/test/Analysis/refcnt_naming.m +++ b/clang/test/Analysis/refcnt_naming.m @@ -1,4 +1,5 @@ -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s typedef const struct __CFString * CFStringRef; typedef const struct __CFAllocator * CFAllocatorRef; -- GitLab From 34eab390b97ca0ac10eeffb0134eced897d1a9a6 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Thu, 22 Jan 2009 23:50:07 +0000 Subject: [PATCH 047/682] remove my gross #ifdef's, using portable abstractions now that the 32-bit load is always aligned. I verified that the bswap doesn't occur in the assembly code on x86. llvm-svn: 62815 --- clang/lib/Lex/PTHLexer.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 497e225b4706..51d49cf6e2ce 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -19,10 +19,12 @@ #include "clang/Lex/PTHManager.h" #include "clang/Lex/Token.h" #include "clang/Lex/Preprocessor.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/OwningPtr.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/MathExtras.h" +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/System/Host.h" using namespace clang; #define DISK_TOKEN_SIZE (1+1+2+4+4) @@ -39,16 +41,11 @@ static inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) { } static inline uint32_t ReadLE32(const unsigned char *&Data) { -// Targets that directly support unaligned little-endian 32-bit loads can just -// use them. -#if defined(__i386__) || defined(__x86_64__) + // Hosts that directly support unaligned little-endian 32-bit loads can just + // use them. uint32_t V = *((uint32_t*)Data); -#else - uint32_t V = ((uint32_t)Data[0] << 0) | - ((uint32_t)Data[1] << 8) | - ((uint32_t)Data[2] << 16) | - ((uint32_t)Data[3] << 24); -#endif + if (llvm::sys::isBigEndianHost()) + V = llvm::ByteSwap_32(V); Data += 4; return V; } -- GitLab From 2e1dfe25c5251f2ea39c8492d917e9873b7168e7 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Thu, 22 Jan 2009 23:56:56 +0000 Subject: [PATCH 048/682] For now, return UnknownVal() in RegionStore::getElementsSize() for AnonTypedRegions. It wasn't really doing the right thing and was crashing on rdar-6442306-1.m. This fix causes all path-sensitive test cases to pass with RegionStore. llvm-svn: 62816 --- clang/lib/Analysis/RegionStore.cpp | 10 ++++++++++ clang/test/Analysis/NoReturn.m | 5 +++-- clang/test/Analysis/rdar-6442306-1.m | 4 ++-- 3 files changed, 15 insertions(+), 4 deletions(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index ec801d47f28a..48c11f3bbf1b 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -420,6 +420,12 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, } if (const AnonTypedRegion* ATR = dyn_cast(R)) { +#if 0 + // FIXME: This logic doesn't really work, as we can have all sorts of + // weird cases. For example, this crashes on test case 'rdar-6442306-1.m'. + // The weird cases come in when arbitrary casting comes into play, violating + // any type-safe programming. + GRStateRef state(St, StateMgr); // Get the size of the super region in bytes. @@ -450,6 +456,10 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St, (SSize * getBasicVals().getValue(8, SSize.getBitWidth(), false)) / ESize; return NonLoc::MakeVal(getBasicVals(), S); +#else + ATR = ATR; + return UnknownVal(); +#endif } if (const FieldRegion* FR = dyn_cast(R)) { diff --git a/clang/test/Analysis/NoReturn.m b/clang/test/Analysis/NoReturn.m index 16870f8aa101..2d3bd7c81e07 100644 --- a/clang/test/Analysis/NoReturn.m +++ b/clang/test/Analysis/NoReturn.m @@ -1,5 +1,6 @@ -// RUN: clang -analyze -checker-simple -verify %s && -// RUN: clang -analyze -checker-cfref -verify %s +// RUN: clang -analyze -checker-simple -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s #include diff --git a/clang/test/Analysis/rdar-6442306-1.m b/clang/test/Analysis/rdar-6442306-1.m index ea8d9baf6e65..b3235d9c40d3 100644 --- a/clang/test/Analysis/rdar-6442306-1.m +++ b/clang/test/Analysis/rdar-6442306-1.m @@ -1,5 +1,5 @@ -// RUN: clang -analyze -checker-cfref %s --analyzer-store-basic -verify -// DISABLE: clang -analyze -checker-cfref %s --analyzer-store-region -verify +// RUN: clang -analyze -checker-cfref %s --analyzer-store-basic -verify && +// RUN: clang -analyze -checker-cfref %s --analyzer-store-region -verify typedef int bar_return_t; typedef struct { -- GitLab From ccabd0f01a7b5b9f8dee762b3aa1434cb96f6c5a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 00:04:43 +0000 Subject: [PATCH 049/682] ccc: Fix typo; isn't dynamic typing fun! llvm-svn: 62817 --- clang/tools/ccc/ccclib/Tools.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py index b1087d398385..c1b4e41b6a7c 100644 --- a/clang/tools/ccc/ccclib/Tools.py +++ b/clang/tools/ccc/ccclib/Tools.py @@ -351,7 +351,7 @@ class Darwin_X86_CC1Tool(Tool): return 'cc1',False,False elif type is Types.ObjCType or type is Types.ObjCHeaderType: return 'cc1obj',True,False - elif type is Types.ObjCTypeNoPP or type is Types.ObjCHeaderNoPPTypeP: + elif type is Types.ObjCTypeNoPP or type is Types.ObjCHeaderNoPPType: return 'cc1obj',True,False elif type is Types.CXXType or type is Types.CXXHeaderType: return 'cc1plus',True,True -- GitLab From 94e826df0b8816c2a8e460c4a29de279cdc5ccfc Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 23 Jan 2009 00:11:54 +0000 Subject: [PATCH 050/682] Updated checker build. llvm-svn: 62818 --- clang/www/latest_checker.html.incl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/www/latest_checker.html.incl b/clang/www/latest_checker.html.incl index 0c9ee0518e7c..77b1331898c2 100644 --- a/clang/www/latest_checker.html.incl +++ b/clang/www/latest_checker.html.incl @@ -1 +1 @@ -checker-0.142.tar.bz2 (built January 20, 2009) +checker-0.143.tar.bz2 (built January 22, 2009) -- GitLab From f8ccb4f9e3dc128028e9cd9bf89c212bc84e0733 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 00:13:28 +0000 Subject: [PATCH 051/682] Update comment. llvm-svn: 62819 --- clang/lib/Lex/PTHLexer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 51d49cf6e2ce..b0f06271c4fb 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -41,8 +41,8 @@ static inline uint16_t ReadUnalignedLE16(const unsigned char *&Data) { } static inline uint32_t ReadLE32(const unsigned char *&Data) { - // Hosts that directly support unaligned little-endian 32-bit loads can just - // use them. + // Hosts that directly support little-endian 32-bit loads can just + // use them. Big-endian hosts need a bswap. uint32_t V = *((uint32_t*)Data); if (llvm::sys::isBigEndianHost()) V = llvm::ByteSwap_32(V); -- GitLab From 4bb6a2fcd30a863a5e1720dfab6853ae27681a78 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 00:14:46 +0000 Subject: [PATCH 052/682] ccc: Add support for "alias" options. - Unlike groups (which gather distinct but related options), aliases are for options like '--all-warnings' which are effectively treated like some other option ('-Wall') both in the driver logic and when passing to tools. llvm-svn: 62820 --- clang/tools/ccc/ccclib/Arguments.py | 47 ++++++++++++++++++++++------- 1 file changed, 36 insertions(+), 11 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 2ed0597f896a..87487e0144b9 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -14,18 +14,37 @@ class MissingArgumentError(ValueError): class Option(object): """Option - Root option class.""" - def __init__(self, name, group=None, isLinkerInput=False, noOptAsInput=False): + def __init__(self, name, group=None, alias=None, + isLinkerInput=False, noOptAsInput=False): assert group is None or isinstance(group, OptionGroup) + # Multi-level aliases are not supported, and alias options + # cannot have groups. This just simplifies option tracking, it + # is not an inherent limitation. + assert alias is None or (alias.alias is None and + group is None) + self.name = name self.group = group + self.alias = alias self.isLinkerInput = isLinkerInput self.noOptAsInput = noOptAsInput + def getUnaliasedOption(self): + if self.alias: + return self.alias.getUnaliasedOption() + return self + + def getRenderName(self): + return self.getUnaliasedOption().name + def matches(self, opt): """matches(opt) -> bool Predicate for whether this option is part of the given option (which may be a group).""" + + if self.alias: + return self.alias.matches(opt) if self is opt: return True elif self.group: @@ -183,8 +202,7 @@ class Arg(object): Map the argument into a list of actual program arguments, given the source argument array.""" - assert self.opt - return [self.opt.name] + return [self.opt.getRenderName()] def renderAsInput(self, args): return self.render(args) @@ -215,7 +233,7 @@ class JoinedValueArg(ValueArg): return args.getInputString(self.index)[len(self.opt.name):] def render(self, args): - return [self.opt.name + self.getValue(args)] + return [self.opt.getRenderName() + self.getValue(args)] def renderAsInput(self, args): if self.opt.noOptAsInput: @@ -230,7 +248,7 @@ class SeparateValueArg(ValueArg): return args.getInputString(self.index, offset=1) def render(self, args): - return [self.opt.name, self.getValue(args)] + return [self.opt.getRenderName(), self.getValue(args)] def renderAsInput(self, args): if self.opt.noOptAsInput: @@ -248,7 +266,7 @@ class MultipleValuesArg(Arg): for i in range(self.opt.numArgs)] def render(self, args): - return [self.opt.name] + self.getValues(args) + return [self.opt.getRenderName()] + self.getValues(args) class CommaJoinedValuesArg(Arg): """CommaJoinedValuesArg - An argument with multiple values joined @@ -262,7 +280,7 @@ class CommaJoinedValuesArg(Arg): return args.getInputString(self.index)[len(self.opt.name):].split(',') def render(self, args): - return [self.opt.name + ','.join(self.getValues(args))] + return [self.opt.getRenderName() + ','.join(self.getValues(args))] def renderAsInput(self, args): return self.getValues(args) @@ -280,7 +298,7 @@ class JoinedAndSeparateValuesArg(Arg): return args.getInputString(self.index, offset=1) def render(self, args): - return ([self.opt.name + self.getJoinedValue(args)] + + return ([self.opt.getRenderName() + self.getJoinedValue(args)] + [self.getSeparateValue(args)]) ### @@ -420,9 +438,13 @@ class ArgList(object): def append(self, arg): self.args.append(arg) - self.lastArgs[arg.opt] = arg - if arg.opt.group is not None: - self.lastArgs[arg.opt.group] = arg + + opt = arg.opt + if opt.alias: + opt = opt.alias + self.lastArgs[opt] = arg + if opt.group is not None: + self.lastArgs[opt.group] = arg # Forwarding methods. # @@ -823,6 +845,9 @@ class OptionParser: self.WGroup = OptionGroup('-W') self.ClangWGroup = OptionGroup('-W', self.WGroup) + self.WallOption = self.addOption(FlagOption('-Wall', self.WGroup)) + self.addOption(FlagOption('--all-warnings', alias=self.WallOption)) + self.addOption(FlagOption('-Wunused-macros', self.ClangWGroup)) self.addOption(FlagOption('-Wfloat-equal', self.ClangWGroup)) self.addOption(FlagOption('-Wreadonly-setter-attrs', self.ClangWGroup)) -- GitLab From 48abf2380b7657c57c61524c34aecf5b157e4cd4 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 23 Jan 2009 00:23:32 +0000 Subject: [PATCH 053/682] Add an initial pass at dead spill/restore removal for pre alloc splitting. llvm-svn: 62821 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 60 ++++++++++++++++++++++++-- 1 file changed, 56 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index ca4f7ec6f2d2..f07f0700945d 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -42,6 +42,7 @@ STATISTIC(NumSplits, "Number of intervals split"); STATISTIC(NumRemats, "Number of intervals split by rematerialization"); STATISTIC(NumFolds, "Number of intervals split with spill folding"); STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers"); +STATISTIC(NumDeadSpills, "Number of dead spills removed"); namespace { class VISIBILITY_HIDDEN PreAllocSplitting : public MachineFunctionPass { @@ -152,7 +153,8 @@ namespace { bool SplitRegLiveInterval(LiveInterval*); - bool SplitRegLiveIntervals(const TargetRegisterClass **); + bool SplitRegLiveIntervals(const TargetRegisterClass **, + SmallPtrSet&); void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo, MachineInstr* DefMI, unsigned RestoreIdx); @@ -172,6 +174,7 @@ namespace { SmallPtrSet& RefsInMBB); void RenumberValno(VNInfo* VN); void ReconstructLiveInterval(LiveInterval* LI); + bool removeDeadSpills(SmallPtrSet& split); VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use, MachineBasicBlock* MBB, LiveInterval* LI, @@ -1340,7 +1343,8 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { /// SplitRegLiveIntervals - Split all register live intervals that cross the /// barrier that's being processed. bool -PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs) { +PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs, + SmallPtrSet& Split) { // First find all the virtual registers whose live intervals are intercepted // by the current barrier. SmallVector Intervals; @@ -1369,12 +1373,56 @@ PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs) { Change |= Change; LiveInterval *LI = Intervals.back(); Intervals.pop_back(); - Change |= SplitRegLiveInterval(LI); + bool result = SplitRegLiveInterval(LI); + if (result) Split.insert(LI); + Change |= result; } return Change; } +/// removeDeadSpills - After doing splitting, filter through all intervals we've +/// split, and see if any of the spills are unnecessary. If so, remove them. +bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { + bool changed = false; + + for (SmallPtrSet::iterator LI = split.begin(), + LE = split.end(); LI != LE; ++LI) { + DenseMap VNUseCount; + + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg), + UE = MRI->use_end(); UI != UE; ++UI) { + unsigned index = LIs->getInstructionIndex(&*UI); + index = LiveIntervals::getUseIndex(index); + + const LiveRange* LR = (*LI)->getLiveRangeContaining(index); + VNUseCount[LR->valno]++; + } + + for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(), + VE = (*LI)->vni_end(); VI != VE; ++VI) { + VNInfo* CurrVN = *VI; + if (CurrVN->hasPHIKill) continue; + if (VNUseCount[CurrVN] > 0) continue; + + unsigned DefIdx = CurrVN->def; + if (DefIdx == ~0U || DefIdx == ~1U) continue; + + MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx); + int FrameIndex; + if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue; + + LIs->RemoveMachineInstrFromMaps(DefMI); + (*LI)->removeValNo(CurrVN); + DefMI->eraseFromParent(); + NumDeadSpills++; + changed = true; + } + } + + return changed; +} + bool PreAllocSplitting::createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, MachineBasicBlock* BarrierMBB) { @@ -1457,6 +1505,8 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) { MachineBasicBlock *Entry = MF.begin(); SmallPtrSet Visited; + SmallPtrSet Split; + for (df_ext_iterator > DFI = df_ext_begin(Entry, Visited), E = df_ext_end(Entry, Visited); DFI != E; ++DFI) { @@ -1469,9 +1519,11 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) { if (!BarrierRCs) continue; BarrierIdx = LIs->getInstructionIndex(Barrier); - MadeChange |= SplitRegLiveIntervals(BarrierRCs); + MadeChange |= SplitRegLiveIntervals(BarrierRCs, Split); } } + MadeChange |= removeDeadSpills(Split); + return MadeChange; } -- GitLab From 706d40e66235dafb85557ade0bb6c2209111d878 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 00:27:03 +0000 Subject: [PATCH 054/682] a minor tweak to my previous patch, handle the invalidation case when there are multiple iterations of the loop. This fixes PR3375. llvm-svn: 62822 --- llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index ddfb26eebc16..c84a51fb062f 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -751,9 +751,10 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // cache remains sorted. Sort it now (if needed) so that recursive // invocations of getNonLocalPointerDepFromBB that could reuse the cache // value will only see properly sorted cache arrays. - if (NumSortedEntries != Cache->size()) { + if (Cache && NumSortedEntries != Cache->size()) { std::sort(Cache->begin(), Cache->end()); NumSortedEntries = Cache->size(); + Cache = 0; } // FIXME: it is entirely possible that PHI translating will end up with @@ -767,12 +768,12 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, Result, Visited)) goto PredTranslationFailure; } - + // Refresh the CacheInfo/Cache pointer so that it isn't invalidated. CacheInfo = &NonLocalPointerDeps[CacheKey]; Cache = &CacheInfo->second; NumSortedEntries = Cache->size(); - + // Since we did phi translation, the "Cache" set won't contain all of the // results for the query. This is ok (we can still use it to accelerate // specific block queries) but we can't do the fastpath "return all -- GitLab From f6cd928bf4576811f1aa6ecae84be5b2e048d14c Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 00:36:41 +0000 Subject: [PATCH 055/682] Support arithmetic on pointer-to-function types as a GNU extension. Addresses clang PR/3371. llvm-svn: 62823 --- clang/include/clang/Basic/DiagnosticKinds.def | 6 ++- clang/lib/Sema/SemaExpr.cpp | 43 +++++++++++++++++-- clang/test/Sema/pointer-addition.c | 9 +++- 3 files changed, 51 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 259265c2bfc8..1858f2583bec 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -345,7 +345,9 @@ DIAG(ext_gnu_old_style_field_designator, EXTENSION, "use of GNU old-style field designator extension") DIAG(ext_gnu_case_range, EXTENSION, "use of GNU case range extension") - +DIAG(ext_gnu_ptr_func_arith, EXTENSION, + "arithmetic on pointer to function type %0 is a GNU extension") + // Generic errors. DIAG(err_parse_error, ERROR, "parse error") @@ -1262,6 +1264,8 @@ DIAG(err_typecheck_arithmetic_incomplete_type, ERROR, "arithmetic on pointer to incomplete type %0") DIAG(err_typecheck_pointer_arith_function_type, ERROR, "arithmetic on pointer to function type %0") +DIAG(err_typecheck_pointer_arith_void_type, ERROR, + "arithmetic on pointer to void type") DIAG(err_typecheck_decl_incomplete_type, ERROR, "variable has incomplete type %0") // FIXME: Use %select diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 8cf153e673dd..ab5bd6bd1194 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2656,12 +2656,25 @@ inline QualType Sema::CheckAdditionOperands( // C99 6.5.6 // Check for arithmetic on pointers to incomplete types if (!PTy->getPointeeType()->isObjectType()) { if (PTy->getPointeeType()->isVoidType()) { + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_void_type) + << lex->getSourceRange() << rex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to void Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); } else if (PTy->getPointeeType()->isFunctionType()) { - Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + << lex->getType() << lex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to function + Diag(Loc, diag::ext_gnu_ptr_func_arith) << lex->getType() << lex->getSourceRange(); - return QualType(); } else { DiagnoseIncompleteType(Loc, PTy->getPointeeType(), diag::err_typecheck_arithmetic_incomplete_type, @@ -2701,6 +2714,16 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex, if (lpointee->isVoidType()) { Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); + } else if (lpointee->isFunctionType()) { + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + << lex->getType() << lex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to function + Diag(Loc, diag::ext_gnu_ptr_func_arith) + << lex->getType() << lex->getSourceRange(); } else { Diag(Loc, diag::err_typecheck_sub_ptr_object) << lex->getType() << lex->getSourceRange(); @@ -3174,10 +3197,22 @@ QualType Sema::CheckIncrementDecrementOperand(Expr *Op, SourceLocation OpLoc, if (PT->getPointeeType()->isObjectType()) { // Pointer to object is ok! } else if (PT->getPointeeType()->isVoidType()) { - // Pointer to void is extension. + if (getLangOptions().CPlusPlus) { + Diag(OpLoc, diag::err_typecheck_pointer_arith_void_type) + << Op->getSourceRange(); + return QualType(); + } + + // Pointer to void is a GNU extension in C. Diag(OpLoc, diag::ext_gnu_void_ptr) << Op->getSourceRange(); } else if (PT->getPointeeType()->isFunctionType()) { - Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type) + if (getLangOptions().CPlusPlus) { + Diag(OpLoc, diag::err_typecheck_pointer_arith_function_type) + << Op->getType() << Op->getSourceRange(); + return QualType(); + } + + Diag(OpLoc, diag::ext_gnu_ptr_func_arith) << ResType << Op->getSourceRange(); return QualType(); } else { diff --git a/clang/test/Sema/pointer-addition.c b/clang/test/Sema/pointer-addition.c index 95f364fc676b..81a1dc06c1f2 100644 --- a/clang/test/Sema/pointer-addition.c +++ b/clang/test/Sema/pointer-addition.c @@ -2,13 +2,18 @@ typedef struct S S; // expected-note{{forward declaration of 'struct S'}} void a(S* b, void* c) { + void (*fp)(int) = 0; b++; // expected-error {{arithmetic on pointer to incomplete type}} b += 1; // expected-error {{arithmetic on pointer to incomplete type}} c++; // expected-warning {{use of GNU void* extension}} c += 1; // expected-warning {{use of GNU void* extension}} + c--; // expected-warning {{use of GNU void* extension}} + c -= 1; // expected-warning {{use of GNU void* extension}} b = 1+b; // expected-error {{arithmetic on pointer to incomplete type}} /* The next couple tests are only pedantic warnings in gcc */ void (*d)(S*,void*) = a; - d += 1; // expected-error {{arithmetic on pointer to function type}}} - d++; // expected-error {{arithmetic on pointer to function type}}} + d += 1; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} + d++; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}}} + d--; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} + d -= 1; // expected-warning {{arithmetic on pointer to function type 'void (*)(S *, void *)' is a GNU extension}} } -- GitLab From 58645d02859df3b9fa83c5308cba4e7fd43c7cb4 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 00:39:52 +0000 Subject: [PATCH 056/682] ccc: Darwin/x86/link: Fix a few incompatibilities with gcc (missed forwarding -s to linker, and was only taking last arg in some cases when should have been taking all). llvm-svn: 62824 --- clang/tools/ccc/ccclib/Tools.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py index c1b4e41b6a7c..04d07e226efb 100644 --- a/clang/tools/ccc/ccclib/Tools.py +++ b/clang/tools/ccc/ccclib/Tools.py @@ -989,14 +989,15 @@ class Darwin_X86_LinkTool(Tool): # FIXME: gcc has %{x} in here. How could this ever happen? # Cruft? - arglist.addLastArg(cmd_args, arglist.parser.dGroup) - arglist.addLastArg(cmd_args, arglist.parser.tOption) - arglist.addLastArg(cmd_args, arglist.parser.ZOption) + arglist.addAllArgs(cmd_args, arglist.parser.dOption) + arglist.addAllArgs(cmd_args, arglist.parser.sOption) + arglist.addAllArgs(cmd_args, arglist.parser.tOption) + arglist.addAllArgs(cmd_args, arglist.parser.ZOption) arglist.addAllArgs(cmd_args, arglist.parser.uGroup) - arglist.addLastArg(cmd_args, arglist.parser.AOption) + arglist.addAllArgs(cmd_args, arglist.parser.AOption) arglist.addLastArg(cmd_args, arglist.parser.eOption) - arglist.addLastArg(cmd_args, arglist.parser.mOption) - arglist.addLastArg(cmd_args, arglist.parser.rOption) + arglist.addAllArgs(cmd_args, arglist.parser.mOption) + arglist.addAllArgs(cmd_args, arglist.parser.rOption) cmd_args.extend(arglist.render(output)) -- GitLab From eff67fa33b35162ac64ed421e36e9b025dfab033 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 00:54:03 +0000 Subject: [PATCH 057/682] ccc: Add support for several more aliases (--ansi, --assemble, --assert, --classpath). - Requires providing some option parameters to over-ride rendering in order to match gcc. There may be a cleaner way to do this (probably by introducing a new option type for long JoinedOrSeparate forms). llvm-svn: 62825 --- clang/tools/ccc/ccclib/Arguments.py | 30 +++++++++++++++++++++++++++-- clang/tools/ccc/test/ccc/aliases.c | 13 +++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 clang/tools/ccc/test/ccc/aliases.c diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 87487e0144b9..8b926225d843 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -15,7 +15,9 @@ class Option(object): """Option - Root option class.""" def __init__(self, name, group=None, alias=None, - isLinkerInput=False, noOptAsInput=False): + isLinkerInput=False, noOptAsInput=False, + forceSeparateRender=False, + forceJoinedRender=False): assert group is None or isinstance(group, OptionGroup) # Multi-level aliases are not supported, and alias options # cannot have groups. This just simplifies option tracking, it @@ -28,6 +30,8 @@ class Option(object): self.alias = alias self.isLinkerInput = isLinkerInput self.noOptAsInput = noOptAsInput + self.forceSeparateRender = forceSeparateRender + self.forceJoinedRender = forceJoinedRender def getUnaliasedOption(self): if self.alias: @@ -233,6 +237,9 @@ class JoinedValueArg(ValueArg): return args.getInputString(self.index)[len(self.opt.name):] def render(self, args): + if self.opt.forceSeparateRender: + return [self.opt.getRenderName(), + self.getValue(args)] return [self.opt.getRenderName() + self.getValue(args)] def renderAsInput(self, args): @@ -248,6 +255,8 @@ class SeparateValueArg(ValueArg): return args.getInputString(self.index, offset=1) def render(self, args): + if self.opt.forceJoinedRender: + return [self.opt.getRenderName() + self.getValue(args)] return [self.opt.getRenderName(), self.getValue(args)] def renderAsInput(self, args): @@ -520,7 +529,10 @@ class OptionParser: # Pipeline control self.hashHashHashOption = self.addOption(FlagOption('-###')) self.EOption = self.addOption(FlagOption('-E')) + self.SOption = self.addOption(FlagOption('-S')) + self.addOption(FlagOption('--assemble', alias=self.SOption)) + self.cOption = self.addOption(FlagOption('-c')) self.combineOption = self.addOption(FlagOption('-combine')) self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp')) @@ -568,6 +580,8 @@ class OptionParser: #### # Bring on the random garbage. + self.sOption = self.addOption(FlagOption('-s')) + self.MGroup = OptionGroup('-M') self.MOption = self.addOption(FlagOption('-M', self.MGroup)) self.MDOption = self.addOption(FlagOption('-MD', self.MGroup)) @@ -707,6 +721,10 @@ class OptionParser: # stuff to cc1, but the way the ld spec is constructed it # wants to see -A options but only as a separate arg. self.AOption = self.addOption(JoinedOrSeparateOption('-A')) + self.addOption(JoinedOption('--assert=', alias=self.AOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--assert', alias=self.AOption)) + self.DOption = self.addOption(JoinedOrSeparateOption('-D')) self.FOption = self.addOption(JoinedOrSeparateOption('-F')) self.IOption = self.addOption(JoinedOrSeparateOption('-I')) @@ -737,7 +755,7 @@ class OptionParser: # FIXME: Naming convention. self.dGroup = OptionGroup('-d') self.dAOption = self.addOption(FlagOption('-dA', self.dGroup)) - self.addOption(FlagOption('-d', self.dGroup)) + self.dOption = self.addOption(FlagOption('-d', self.dGroup)) # Use a group for this in anticipation of adding more -d # options explicitly. Note that we don't put many -d things in @@ -766,6 +784,12 @@ class OptionParser: self.fastcpOption = self.addOption(FlagOption('-fastcp', self.fGroup)) self.f_appleKextOption = self.addOption(FlagOption('-fapple-kext', self.fGroup)) + + self.f_classpathOption = self.addOption(JoinedOption('-fclasspath=', self.fGroup)) + self.addOption(JoinedOption('--classpath=', alias=self.f_classpathOption)) + self.addOption(SeparateOption('--classpath', alias=self.f_classpathOption, + forceJoinedRender=True)) + self.f_constantCfstringsOption = self.addOption(FlagOption('-fconstant-cfstrings', self.fGroup)) self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile', self.fGroup)) self.f_debugPassArgumentsOption = self.addOption(FlagOption('-fdebug-pass-arguments', self.fGroup)) @@ -835,6 +859,8 @@ class OptionParser: # FIXME: Why does Darwin send -a* to cc1? self.aGroup = OptionGroup('-a') self.ansiOption = self.addOption(FlagOption('-ansi', self.aGroup)) + self.addOption(FlagOption('--ansi', alias=self.ansiOption)) + self.aOption = self.addOption(JoinedOption('-a', self.aGroup)) self.pedanticGroup = OptionGroup('-pedantic') diff --git a/clang/tools/ccc/test/ccc/aliases.c b/clang/tools/ccc/test/ccc/aliases.c new file mode 100644 index 000000000000..f9b89a14d4b9 --- /dev/null +++ b/clang/tools/ccc/test/ccc/aliases.c @@ -0,0 +1,13 @@ +// RUN: xcc -### -S --all-warnings %s &> %t && +// RUN: grep -- '"-Wall"' %t && + +// RUN: xcc -### -S --ansi %s &> %t && +// RUN: grep -- '"-ansi"' %t && + +// RUN: xcc -### -S --assert foo --assert=foo %s &> %t && +// RUN: grep -- '"-A" "foo" "-A" "foo"' %t && + +// RUN: xcc -### -S --classpath foo --classpath=foo %s &> %t && +// RUN: grep -- '"-fclasspath=foo" "-fclasspath=foo"' %t && + +// RUN: true -- GitLab From a248034f415909402a48f3db6660eec5f1ac48df Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 01:10:18 +0000 Subject: [PATCH 058/682] Make -ast-dump print Objective-C method declarations (and other Objective-C declarations!) again. Fixes llvm-svn: 62826 --- clang/Driver/ASTConsumers.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/Driver/ASTConsumers.cpp b/clang/Driver/ASTConsumers.cpp index 6f66307c4bd4..6fec595e5199 100644 --- a/clang/Driver/ASTConsumers.cpp +++ b/clang/Driver/ASTConsumers.cpp @@ -480,9 +480,6 @@ namespace { } } else if (TypedefDecl *TD = dyn_cast(D)) { PrintTypeDefDecl(TD); - } else if (NamedDecl *ND = dyn_cast(D)) { - Out << "Read top-level variable decl: '" << ND->getNameAsString() - << "'\n"; } else if (ObjCInterfaceDecl *OID = dyn_cast(D)) { Out << "Read objc interface '" << OID->getNameAsString() << "'\n"; } else if (ObjCProtocolDecl *OPD = dyn_cast(D)) { @@ -509,6 +506,9 @@ namespace { Out << "Read objc category implementation decl\n"; } else if (isa(D)) { Out << "Read linkage spec decl\n"; + } else if (NamedDecl *ND = dyn_cast(D)) { + Out << "Read top-level variable decl: '" << ND->getNameAsString() + << "'\n"; } else { assert(0 && "Unknown decl type!"); } -- GitLab From 4c8f55abda4e7e165acd08f7c88e3e6da302db1d Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 23 Jan 2009 01:19:09 +0000 Subject: [PATCH 059/682] Set appropriate tag for the composite type. llvm-svn: 62827 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 4ca5583a6cb6..3057797e7f21 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1747,6 +1747,7 @@ private: const std::string &Name = CTy.getName(); uint64_t Size = CTy.getSizeInBits() >> 3; unsigned Tag = CTy.getTag(); + Buffer.setTag(Tag); switch (Tag) { case DW_TAG_vector_type: case DW_TAG_array_type: -- GitLab From 7d537c23c11c8a8661e7fc7f03167bc3136884e9 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 23 Jan 2009 01:25:58 +0000 Subject: [PATCH 060/682] Code did not follow associated comment. not a good idea. llvm-svn: 62828 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 3057797e7f21..fd59533eeff7 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1578,7 +1578,7 @@ private: void AddSourceLine(DIE *Die, const DIGlobal *G) { unsigned FileID = 0; unsigned Line = G->getLineNumber(); - if (G->getVersion() < LLVMDebugVersion6) { + if (G->getVersion() <= LLVMDebugVersion6) { // Version6 or earlier. Use compile unit info to get file id. CompileUnit *Unit = FindCompileUnit(G->getCompileUnit()); FileID = Unit->getID(); -- GitLab From e2c430b317edc8ba1f56feef4eef1701bb2cf9be Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 01:31:44 +0000 Subject: [PATCH 061/682] ccc: Organize long options together. llvm-svn: 62829 --- clang/tools/ccc/ccclib/Arguments.py | 70 +++++++++++++---------------- 1 file changed, 30 insertions(+), 40 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 8b926225d843..809c3e8e5610 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -499,48 +499,26 @@ class OptionParser: # Misc driver options self.addOption(FlagOption('-pass-exit-codes')) - self.addOption(FlagOption('--help')) - self.addOption(FlagOption('--target-help')) - self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs')) self.dumpversionOption = self.addOption(FlagOption('-dumpversion')) self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine')) self.printSearchDirsOption = self.addOption(FlagOption('-print-search-dirs')) - - self.printLibgccFileNameOption = OptionGroup('-print-libgcc-file-name') - self.addOption(FlagOption('-print-libgcc-file-name', self.printLibgccFileNameOption)) - self.addOption(FlagOption('--print-libgcc-file-name', self.printLibgccFileNameOption)) - - self.printFileNameOption = OptionGroup('-print-file-name=') - self.addOption(JoinedOption('-print-file-name=', self.printFileNameOption)) - self.addOption(JoinedOption('--print-file-name=', self.printFileNameOption)) - - self.printProgNameOption = OptionGroup('-print-prog-name=') - self.addOption(JoinedOption('-print-prog-name=', self.printProgNameOption)) - self.addOption(JoinedOption('--print-prog-name=', self.printProgNameOption)) - + self.printLibgccFileNameOption = self.addOption(FlagOption('-print-libgcc-file-name')) + self.printFileNameOption = self.addOption(JoinedOption('-print-file-name=')) + self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name=')) self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory')) self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib')) self.addOption(FlagOption('-print-multi-os-directory')) - # Hmmm, who really takes this? - self.addOption(FlagOption('--version')) - # Pipeline control self.hashHashHashOption = self.addOption(FlagOption('-###')) self.EOption = self.addOption(FlagOption('-E')) - self.SOption = self.addOption(FlagOption('-S')) - self.addOption(FlagOption('--assemble', alias=self.SOption)) - self.cOption = self.addOption(FlagOption('-c')) self.combineOption = self.addOption(FlagOption('-combine')) self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp')) self.pipeOption = self.addOption(FlagOption('-pipe')) - - self.saveTempsOption = OptionGroup('-save-temps') - self.addOption(FlagOption('-save-temps', self.saveTempsOption)) - self.addOption(FlagOption('--save-temps', self.saveTempsOption)) + self.saveTempsOption = self.addOption(FlagOption('-save-temps')) # FIXME: Error out if this is used. self.addOption(JoinedOption('-specs=')) @@ -721,10 +699,6 @@ class OptionParser: # stuff to cc1, but the way the ld spec is constructed it # wants to see -A options but only as a separate arg. self.AOption = self.addOption(JoinedOrSeparateOption('-A')) - self.addOption(JoinedOption('--assert=', alias=self.AOption, - forceSeparateRender=True)) - self.addOption(SeparateOption('--assert', alias=self.AOption)) - self.DOption = self.addOption(JoinedOrSeparateOption('-D')) self.FOption = self.addOption(JoinedOrSeparateOption('-F')) self.IOption = self.addOption(JoinedOrSeparateOption('-I')) @@ -784,12 +758,7 @@ class OptionParser: self.fastcpOption = self.addOption(FlagOption('-fastcp', self.fGroup)) self.f_appleKextOption = self.addOption(FlagOption('-fapple-kext', self.fGroup)) - - self.f_classpathOption = self.addOption(JoinedOption('-fclasspath=', self.fGroup)) - self.addOption(JoinedOption('--classpath=', alias=self.f_classpathOption)) - self.addOption(SeparateOption('--classpath', alias=self.f_classpathOption, - forceJoinedRender=True)) - + self.f_classpathOption = self.addOption(JoinedOption('-fclasspath=', self.fGroup)) self.f_constantCfstringsOption = self.addOption(FlagOption('-fconstant-cfstrings', self.fGroup)) self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile', self.fGroup)) self.f_debugPassArgumentsOption = self.addOption(FlagOption('-fdebug-pass-arguments', self.fGroup)) @@ -833,7 +802,6 @@ class OptionParser: self.addOption(JoinedOption('-f', self.fGroup)) self.coverageOption = self.addOption(FlagOption('-coverage')) - self.coverageOption2 = self.addOption(FlagOption('--coverage')) self.mGroup = OptionGroup('-m') self.m_32Option = self.addOption(FlagOption('-m32', self.mGroup)) @@ -859,7 +827,6 @@ class OptionParser: # FIXME: Why does Darwin send -a* to cc1? self.aGroup = OptionGroup('-a') self.ansiOption = self.addOption(FlagOption('-ansi', self.aGroup)) - self.addOption(FlagOption('--ansi', alias=self.ansiOption)) self.aOption = self.addOption(JoinedOption('-a', self.aGroup)) @@ -872,8 +839,6 @@ class OptionParser: self.ClangWGroup = OptionGroup('-W', self.WGroup) self.WallOption = self.addOption(FlagOption('-Wall', self.WGroup)) - self.addOption(FlagOption('--all-warnings', alias=self.WallOption)) - self.addOption(FlagOption('-Wunused-macros', self.ClangWGroup)) self.addOption(FlagOption('-Wfloat-equal', self.ClangWGroup)) self.addOption(FlagOption('-Wreadonly-setter-attrs', self.ClangWGroup)) @@ -904,6 +869,31 @@ class OptionParser: # Clang static analyzer options (also see -WA,). self.analyzeOption = self.addOption(FlagOption('--analyze')) + # Long option handling (aliases). + self.addOption(FlagOption('--help')) + self.addOption(FlagOption('--target-help')) + + self.addOption(FlagOption('--all-warnings', alias=self.WallOption)) + self.addOption(FlagOption('--ansi', alias=self.ansiOption)) + self.addOption(FlagOption('--assemble', alias=self.SOption)) + self.addOption(SeparateOption('--assert', alias=self.AOption)) + self.addOption(JoinedOption('--assert=', alias=self.AOption, + forceSeparateRender=True)) + self.addOption(JoinedOption('--classpath=', alias=self.f_classpathOption)) + self.addOption(SeparateOption('--classpath', alias=self.f_classpathOption, + forceJoinedRender=True)) + self.addOption(FlagOption('--coverage', alias=self.coverageOption)) + self.addOption(JoinedOption('--param=', alias=self._paramOption, + forceSeparateRender=True)) + self.addOption(FlagOption('--print-libgcc-file-name', + alias=self.printLibgccFileNameOption)) + self.addOption(JoinedOption('--print-file-name=', alias=self.printFileNameOption)) + self.addOption(SeparateOption('--print-file-name', alias=self.printFileNameOption)) + self.addOption(JoinedOption('--print-prog-name=', alias=self.printProgNameOption)) + self.addOption(SeparateOption('--print-prog-name', alias=self.printProgNameOption)) + self.addOption(FlagOption('--version', alias=self.vOption)) + self.addOption(FlagOption('--save-temps', alias=self.saveTempsOption)) + def addOption(self, opt): self.options.append(opt) return opt -- GitLab From 0232c0569fad1a24c4543de50c3d6b8209152b5d Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 23 Jan 2009 01:46:23 +0000 Subject: [PATCH 062/682] Define LLVM types for nonfragile abi metadata. llvm-svn: 62830 --- clang/lib/CodeGen/CGObjCMac.cpp | 183 +++++++++++++++++++++++++++----- 1 file changed, 158 insertions(+), 25 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 133c9fd9691d..9d106816d02d 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -78,6 +78,11 @@ public: // MethodTy - LLVM type for struct objc_method. const llvm::StructType *MethodTy; + /// CacheTy - LLVM type for struct objc_cache. + const llvm::Type *CacheTy; + /// CachePtrTy - LLVM type for struct objc_cache *. + const llvm::Type *CachePtrTy; + llvm::Function *GetPropertyFn, *SetPropertyFn; llvm::Function *EnumerationMutationFn; @@ -151,10 +156,6 @@ public: const llvm::StructType *ClassExtensionTy; /// ClassExtensionPtrTy - LLVM type for struct objc_class_ext *. const llvm::Type *ClassExtensionPtrTy; - /// CacheTy - LLVM type for struct objc_cache. - const llvm::Type *CacheTy; - /// CachePtrTy - LLVM type for struct objc_cache *. - const llvm::Type *CachePtrTy; // IvarTy - LLVM type for struct objc_ivar. const llvm::StructType *IvarTy; /// IvarListTy - LLVM type for struct objc_ivar_list. @@ -215,6 +216,42 @@ public: /// modern abi class ObjCNonFragileABITypesHelper : public ObjCCommonTypesHelper { public: + // MethodListnfABITy - LLVM for struct _method_list_t + const llvm::StructType *MethodListnfABITy; + + // MethodListnfABIPtrTy - LLVM for struct _method_list_t* + const llvm::Type *MethodListnfABIPtrTy; + + // ProtocolnfABITy = LLVM for struct _protocol_t + const llvm::StructType *ProtocolnfABITy; + + // ProtocolListnfABITy - LLVM for struct _objc_protocol_list + const llvm::StructType *ProtocolListnfABITy; + + // ProtocolListnfABIPtrTy - LLVM for struct _objc_protocol_list* + const llvm::Type *ProtocolListnfABIPtrTy; + + // ClassnfABITy - LLVM for struct _class_t + const llvm::StructType *ClassnfABITy; + + // IvarnfABITy - LLVM for struct _ivar_t + const llvm::StructType *IvarnfABITy; + + // IvarListnfABITy - LLVM for struct _ivar_list_t + const llvm::StructType *IvarListnfABITy; + + // IvarListnfABIPtrTy = LLVM for struct _ivar_list_t* + const llvm::Type *IvarListnfABIPtrTy; + + // ClassRonfABITy - LLVM for struct _class_ro_t + const llvm::StructType *ClassRonfABITy; + + // ImpnfABITy - LLVM for id (*)(id, SEL, ...) + const llvm::Type *ImpnfABITy; + + // CategorynfABITy - LLVM for struct _category_t + const llvm::StructType *CategorynfABITy; + ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm); ~ObjCNonFragileABITypesHelper(){} }; @@ -2326,9 +2363,9 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) PropertyTy); // struct _prop_list_t { - // uint32_t entsize; // sizeof(struct _objc_property) + // uint32_t entsize; // sizeof(struct _prop_t) // uint32_t count_of_properties; - // struct _objc_property prop_list[count_of_properties]; + // struct _prop_t prop_list[count_of_properties]; // } PropertyListTy = llvm::StructType::get(IntTy, IntTy, @@ -2349,6 +2386,11 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm) Int8PtrTy, NULL); CGM.getModule().addTypeName("struct._objc_method", MethodTy); + + // struct _objc_cache * + CacheTy = llvm::OpaqueType::get(); + CGM.getModule().addTypeName("struct._objc_cache", CacheTy); + CachePtrTy = llvm::PointerType::getUnqual(CacheTy); // Property manipulation functions. @@ -2531,11 +2573,6 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm) CGM.getModule().addTypeName("struct._objc_method_list", MethodListTy); MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy); - // struct _objc_cache * - CacheTy = llvm::OpaqueType::get(); - CGM.getModule().addTypeName("struct._objc_cache", CacheTy); - CachePtrTy = llvm::PointerType::getUnqual(CacheTy); - // struct _objc_class_extension * ClassExtensionTy = llvm::StructType::get(IntTy, @@ -2774,32 +2811,63 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // uint32_t method_count; // struct _objc_method method_list[method_count]; // } + MethodListnfABITy = llvm::StructType::get(IntTy, + IntTy, + llvm::ArrayType::get(MethodTy, 0), + NULL); + CGM.getModule().addTypeName("struct.__method_list_t", + MethodListnfABITy); + // struct method_list_t * + MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy); // struct _protocol_t { // id isa; // NULL // const char * const protocol_name; - // const struct * _protocol_t const protocol_list; + // const struct _protocol_list_t * protocol_list; // super protocols // const struct method_list_t * const instance_methods; // const struct method_list_t * const class_methods; // const struct method_list_t *optionalInstanceMethods; // const struct method_list_t *optionalClassMethods; - // const struct _prop_list_t * const properties; + // const struct _prop_list_t * properties; // const uint32_t size; // sizeof(struct _protocol_t) // const uint32_t flags; // = 0 // } + // Holder for struct _protocol_list_t * + llvm::PATypeHolder ProtocolListTyHolder = llvm::OpaqueType::get(); + + ProtocolnfABITy = llvm::StructType::get(ObjectPtrTy, + Int8PtrTy, + llvm::PointerType::getUnqual( + ProtocolListTyHolder), + MethodListnfABIPtrTy, + MethodListnfABIPtrTy, + MethodListnfABIPtrTy, + MethodListnfABIPtrTy, + PropertyListPtrTy, + IntTy, + IntTy, + NULL); + CGM.getModule().addTypeName("struct._protocol_t", + ProtocolnfABITy); + // struct _objc_protocol_list { - // long protocol_count; + // long protocol_count; // Note, this is 32/64 bit // struct _protocol_t[protocol_count]; // } - - // struct _class_t { - // struct _class_t *isa; - // struct _class_t * const superclass; - // void *cache; - // IMP *vtable; - // struct class_ro_t *ro; - // } + ProtocolListnfABITy = llvm::StructType::get(LongTy, + llvm::ArrayType::get( + ProtocolnfABITy, 0), + NULL); + CGM.getModule().addTypeName("struct._objc_protocol_list", + ProtocolListnfABITy); + + // FIXME! Is this doing the right thing? + cast(ProtocolListTyHolder.get())->refineAbstractTypeTo( + ProtocolListnfABITy); + + // struct _objc_protocol_list* + ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); // struct _ivar_t { // unsigned long int *offset; // pointer to ivar offset location @@ -2808,14 +2876,27 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // uint32_t alignment; // uint32_t size; // } - + IvarnfABITy = llvm::StructType::get(llvm::PointerType::getUnqual(LongTy), + Int8PtrTy, + Int8PtrTy, + IntTy, + IntTy, + NULL); + CGM.getModule().addTypeName("struct._ivar_t", IvarnfABITy); + // struct _ivar_list_t { // uint32 entsize; // sizeof(struct _ivar_t) // uint32 count; // struct _iver_t list[count]; // } - - // struct class_ro_t { + IvarListnfABIPtrTy = llvm::StructType::get(IntTy, + IntTy, + llvm::ArrayType::get( + IvarnfABITy, 0), + NULL); + CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABIPtrTy); + + // struct _class_ro_t { // uint32_t const flags; // uint32_t const instanceStart; // uint32_t const instanceSize; @@ -2828,6 +2909,58 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // const uint8_t * const weakIvarLayout; // const struct _prop_list_t * const properties; // } + + // FIXME. Add 'reserved' field in 64bit abi mode! + ClassRonfABITy = llvm::StructType::get(IntTy, + IntTy, + IntTy, + Int8PtrTy, + Int8PtrTy, + MethodListnfABIPtrTy, + ProtocolListnfABIPtrTy, + IvarListnfABIPtrTy, + Int8PtrTy, + PropertyListPtrTy, + NULL); + CGM.getModule().addTypeName("struct._class_ro_t", + ClassRonfABITy); + + // ImpnfABITy - LLVM for id (*)(id, SEL, ...) + std::vector Params; + Params.push_back(ObjectPtrTy); + Params.push_back(SelectorPtrTy); + ImpnfABITy = llvm::PointerType::getUnqual( + llvm::FunctionType::get(ObjectPtrTy, Params, false)); + + // struct _class_t { + // struct _class_t *isa; + // struct _class_t * const superclass; + // void *cache; + // IMP *vtable; + // struct class_ro_t *ro; + // } + + llvm::PATypeHolder ClassTyHolder = llvm::OpaqueType::get(); + ClassnfABITy = llvm::StructType::get(llvm::PointerType::getUnqual(ClassTyHolder), + llvm::PointerType::getUnqual(ClassTyHolder), + CachePtrTy, + llvm::PointerType::getUnqual(ImpnfABITy), + llvm::PointerType::getUnqual( + ClassRonfABITy), + NULL); + CGM.getModule().addTypeName("struct._class_t", ClassnfABITy); + + cast(ClassTyHolder.get())->refineAbstractTypeTo( + ClassnfABITy); + + // struct _category_t { + // const char * const name; + // struct _class_t *const cls; + // const struct _method_list_t * const instance_methods; + // const struct _method_list_t * const class_methods; + // const struct _protocol_list_t * const protocols; + // const struct _prop_list_t * const properties; + // } } /* *** */ -- GitLab From 8fa972a55bab69c1aa2b05e404a8df52d9d2421d Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 02:00:46 +0000 Subject: [PATCH 063/682] ccc: Support long ('--...') flag arguments. - Curiously, a number of the current translations gcc does appear to be useless? llvm-svn: 62831 --- clang/tools/ccc/ccclib/Arguments.py | 61 +++++++++++++++++++++++++---- clang/tools/ccc/ccclib/Driver.py | 1 + clang/tools/ccc/ccclib/Tools.py | 4 +- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 809c3e8e5610..15eaca1ef430 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -498,7 +498,7 @@ class OptionParser: self.archOption = self.addOption(SeparateOption('-arch')) # Misc driver options - self.addOption(FlagOption('-pass-exit-codes')) + self.passExitCodesOption = self.addOption(FlagOption('-pass-exit-codes')) self.dumpspecsOption = self.addOption(FlagOption('-dumpspecs')) self.dumpversionOption = self.addOption(FlagOption('-dumpversion')) self.dumpmachineOption = self.addOption(FlagOption('-dumpmachine')) @@ -507,8 +507,8 @@ class OptionParser: self.printFileNameOption = self.addOption(JoinedOption('-print-file-name=')) self.printProgNameOption = self.addOption(JoinedOption('-print-prog-name=')) self.printMultiDirectoryOption = self.addOption(FlagOption('-print-multi-directory')) + self.printMultiOsDirectoryOption = self.addOption(FlagOption('-print-multi-os-directory')) self.printMultiLibOption = self.addOption(FlagOption('-print-multi-lib')) - self.addOption(FlagOption('-print-multi-os-directory')) # Pipeline control self.hashHashHashOption = self.addOption(FlagOption('-###')) @@ -618,7 +618,7 @@ class OptionParser: self.preloadOption = self.addOption(FlagOption('-preload')) self.staticOption = self.addOption(FlagOption('-static')) self.pagezero_sizeOption = self.addOption(FlagOption('-pagezero_size')) - self.addOption(FlagOption('-shared')) + self.sharedOption = self.addOption(FlagOption('-shared')) self.staticLibgccOption = self.addOption(FlagOption('-static-libgcc')) self.sharedLibgccOption = self.addOption(FlagOption('-shared-libgcc')) self.COption = self.addOption(FlagOption('-C')) @@ -701,7 +701,11 @@ class OptionParser: self.AOption = self.addOption(JoinedOrSeparateOption('-A')) self.DOption = self.addOption(JoinedOrSeparateOption('-D')) self.FOption = self.addOption(JoinedOrSeparateOption('-F')) - self.IOption = self.addOption(JoinedOrSeparateOption('-I')) + + self.IGroup = OptionGroup('-I') + self.I_Option = self.addOption(FlagOption('-I-', self.IGroup)) + self.addOption(JoinedOrSeparateOption('-I', self.IGroup)) + self.LOption = self.addOption(JoinedOrSeparateOption('-L')) self.TOption = self.addOption(JoinedOrSeparateOption('-T')) self.UOption = self.addOption(JoinedOrSeparateOption('-U')) @@ -872,6 +876,8 @@ class OptionParser: # Long option handling (aliases). self.addOption(FlagOption('--help')) self.addOption(FlagOption('--target-help')) + # FIXME: Who handles this? + self.addOption(FlagOption('--version')) self.addOption(FlagOption('--all-warnings', alias=self.WallOption)) self.addOption(FlagOption('--ansi', alias=self.ansiOption)) @@ -882,17 +888,58 @@ class OptionParser: self.addOption(JoinedOption('--classpath=', alias=self.f_classpathOption)) self.addOption(SeparateOption('--classpath', alias=self.f_classpathOption, forceJoinedRender=True)) + self.addOption(FlagOption('--combine', alias=self.combineOption)) + self.addOption(FlagOption('--comments', alias=self.COption)) + self.addOption(FlagOption('--comments-in-macros', alias=self.CCOption)) + self.addOption(FlagOption('--compile', alias=self.cOption)) self.addOption(FlagOption('--coverage', alias=self.coverageOption)) + self.addOption(FlagOption('--dependencies', alias=self.MOption)) + self.addOption(FlagOption('--entry', alias=self.eOption)) + self.addOption(FlagOption('--extra-warnings', alias=self.WOption)) + self.addOption(FlagOption('--coverage', alias=self.coverageOption)) + self.addOption(FlagOption('--include-barrier', alias=self.I_Option)) + self.addOption(FlagOption('--no-integrated-cpp', alias=self.noIntegratedCPPOption)) + self.addOption(FlagOption('--no-line-commands', alias=self.POption)) +# self.addOption(FlagOption('--no-precompiled-includes', alias=self.noprecompOption)) + self.addOption(FlagOption('--no-standard-includes', alias=self.nostdincOption)) + self.addOption(FlagOption('--no-standard-libraries', alias=self.nostdlibOption)) + self.addOption(FlagOption('--no-warnings', alias=self.wOption)) + self.addOption(FlagOption('--pass-exit-codes', alias=self.passExitCodesOption)) + self.addOption(FlagOption('--pedantic', alias=self.pedanticOption)) + self.addOption(FlagOption('--pedantic-errors', alias=self.pedanticErrorsOption)) +# self.addOption(FlagOption('--pie', alias=self.pieOption)) + self.addOption(FlagOption('--pipe', alias=self.pipeOption)) + self.addOption(FlagOption('--preprocess', alias=self.EOption)) self.addOption(JoinedOption('--param=', alias=self._paramOption, forceSeparateRender=True)) - self.addOption(FlagOption('--print-libgcc-file-name', - alias=self.printLibgccFileNameOption)) self.addOption(JoinedOption('--print-file-name=', alias=self.printFileNameOption)) self.addOption(SeparateOption('--print-file-name', alias=self.printFileNameOption)) + self.addOption(FlagOption('--print-libgcc-file-name', + alias=self.printLibgccFileNameOption)) + self.addOption(FlagOption('--print-missing-file-dependencies', alias=self.MGOption)) + self.addOption(FlagOption('--print-multi-lib', alias=self.printMultiLibOption)) + self.addOption(FlagOption('--print-multi-directory', alias=self.printMultiDirectoryOption)) + self.addOption(FlagOption('--print-multi-os-directory', alias=self.printMultiOsDirectoryOption)) self.addOption(JoinedOption('--print-prog-name=', alias=self.printProgNameOption)) self.addOption(SeparateOption('--print-prog-name', alias=self.printProgNameOption)) - self.addOption(FlagOption('--version', alias=self.vOption)) + self.addOption(FlagOption('--print-search-dirs', alias=self.printSearchDirsOption)) + self.addOption(FlagOption('--profile', alias=self.pOption)) + self.addOption(FlagOption('--profile-blocks', alias=self.aOption)) +# self.addOption(FlagOption('--quiet', alias=self.qOption)) +# self.addOption(FlagOption('--shared', alias=self.sharedOption)) +# self.addOption(FlagOption('--silent', alias=self.qOption)) + self.addOption(FlagOption('--static', alias=self.staticOption)) +# self.addOption(FlagOption('--symbolic', alias=self.symbolicOption)) +# self.addOption(FlagOption('--time', alias=self.timeOption)) + self.addOption(FlagOption('--trace-includes', alias=self.HOption)) + self.addOption(FlagOption('--traditional', alias=self.traditionalOption)) + self.addOption(FlagOption('--traditional-cpp', alias=self.traditionalCPPOption)) + self.addOption(FlagOption('--trigraphs', alias=self.trigraphsOption)) + self.addOption(FlagOption('--user-dependencies', alias=self.MMOption)) + self.addOption(FlagOption('--verbose', alias=self.vOption)) self.addOption(FlagOption('--save-temps', alias=self.saveTempsOption)) + self.addOption(FlagOption('--write-dependencies', alias=self.MDOption)) + self.addOption(FlagOption('--write-user-dependencies', alias=self.MMDOption)) def addOption(self, opt): self.options.append(opt) diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py index 2ba1cf6cd80c..9a393f183fa0 100644 --- a/clang/tools/ccc/ccclib/Driver.py +++ b/clang/tools/ccc/ccclib/Driver.py @@ -313,6 +313,7 @@ class Driver(object): arg = (args.getLastArg(self.parser.dumpspecsOption) or args.getLastArg(self.parser.printMultiDirectoryOption) or + args.getLastArg(self.parser.printMultiOsDirectoryOption) or args.getLastArg(self.parser.printMultiLibOption)) if arg: raise Arguments.InvalidArgumentsError('%s unsupported by this driver' % arg.opt.name) diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py index 04d07e226efb..b719b8644205 100644 --- a/clang/tools/ccc/ccclib/Tools.py +++ b/clang/tools/ccc/ccclib/Tools.py @@ -274,7 +274,7 @@ class Clang_CompileTool(Tool): arglist.addAllArgs(cmd_args, arglist.parser.vOption) arglist.addAllArgs2(cmd_args, arglist.parser.DOption, arglist.parser.UOption) - arglist.addAllArgs2(cmd_args, arglist.parser.IOption, arglist.parser.FOption) + arglist.addAllArgs2(cmd_args, arglist.parser.IGroup, arglist.parser.FOption) arglist.addAllArgs(cmd_args, arglist.parser.m_macosxVersionMinOption) # Special case debug options to only pass -g to clang. This is @@ -545,7 +545,7 @@ class Darwin_X86_CC1Tool(Tool): cmd_args.append('-quiet') arglist.addAllArgs(cmd_args, arglist.parser.nostdincOption) arglist.addLastArg(cmd_args, arglist.parser.vOption) - arglist.addAllArgs2(cmd_args, arglist.parser.IOption, arglist.parser.FOption) + arglist.addAllArgs2(cmd_args, arglist.parser.IGroup, arglist.parser.FOption) arglist.addLastArg(cmd_args, arglist.parser.POption) # FIXME: Handle %I properly. -- GitLab From ab7bf14fb4c5948eca47df5713a6df5781210107 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 23 Jan 2009 02:15:19 +0000 Subject: [PATCH 064/682] Cross register class coalescing. Not yet enabled. llvm-svn: 62832 --- llvm/include/llvm/Target/TargetRegisterInfo.h | 6 + llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp | 209 ++++++++++-------- llvm/lib/CodeGen/SimpleRegisterCoalescing.h | 23 +- 3 files changed, 129 insertions(+), 109 deletions(-) diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h index c7b8290335c5..54fc00dd84ce 100644 --- a/llvm/include/llvm/Target/TargetRegisterInfo.h +++ b/llvm/include/llvm/Target/TargetRegisterInfo.h @@ -164,6 +164,12 @@ public: while (*I != NULL) ++I; return I; } + + /// isASubClass - return true if this TargetRegisterClass is a sub-class of at + /// least one other TargetRegisterClass. + bool isASubClass() const { + return SuperClasses[0] != 0; + } /// allocation_order_begin/end - These methods define a range of registers /// which specify the registers in this class that are valid to register diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index 637d74b9a1ab..f0b0d58d1358 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -36,7 +36,7 @@ using namespace llvm; STATISTIC(numJoins , "Number of interval joins performed"); -STATISTIC(numSubJoins , "Number of subclass joins performed"); +STATISTIC(numCrossRCs , "Number of cross class joins performed"); STATISTIC(numCommutes , "Number of instruction commuting performed"); STATISTIC(numExtends , "Number of copies extended"); STATISTIC(NumReMats , "Number of instructions re-materialized"); @@ -55,8 +55,8 @@ NewHeuristic("new-coalescer-heuristic", cl::init(false), cl::Hidden); static cl::opt -CrossClassJoin("join-subclass-copies", - cl::desc("Coalesce copies to sub- register class"), +CrossClassJoin("join-cross-class-copies", + cl::desc("Coalesce cross register class copies"), cl::init(false), cl::Hidden); static RegisterPass @@ -953,38 +953,24 @@ static unsigned getMatchingSuperReg(unsigned Reg, unsigned SubIdx, return 0; } -/// isProfitableToCoalesceToSubRC - Given that register class of DstReg is -/// a subset of the register class of SrcReg, return true if it's profitable -/// to coalesce the two registers. +/// isWinToJoinCrossClass - Return true if it's profitable to coalesce +/// two virtual registers from different register classes. bool -SimpleRegisterCoalescing::isProfitableToCoalesceToSubRC(unsigned SrcReg, - unsigned DstReg, - MachineBasicBlock *MBB){ - if (!CrossClassJoin) - return false; - - // First let's make sure all uses are in the same MBB. - for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(SrcReg), - RE = mri_->reg_end(); RI != RE; ++RI) { - MachineInstr &MI = *RI; - if (MI.getParent() != MBB) - return false; - } - for (MachineRegisterInfo::reg_iterator RI = mri_->reg_begin(DstReg), - RE = mri_->reg_end(); RI != RE; ++RI) { - MachineInstr &MI = *RI; - if (MI.getParent() != MBB) - return false; - } - +SimpleRegisterCoalescing::isWinToJoinCrossClass(unsigned LargeReg, + unsigned SmallReg, + unsigned Threshold) { // Then make sure the intervals are *short*. - LiveInterval &SrcInt = li_->getInterval(SrcReg); - LiveInterval &DstInt = li_->getInterval(DstReg); - unsigned SrcSize = li_->getApproximateInstructionCount(SrcInt); - unsigned DstSize = li_->getApproximateInstructionCount(DstInt); - const TargetRegisterClass *RC = mri_->getRegClass(DstReg); - unsigned Threshold = allocatableRCRegs_[RC].count() * 2; - return (SrcSize + DstSize) <= Threshold; + LiveInterval &LargeInt = li_->getInterval(LargeReg); + LiveInterval &SmallInt = li_->getInterval(SmallReg); + unsigned LargeSize = li_->getApproximateInstructionCount(LargeInt); + unsigned SmallSize = li_->getApproximateInstructionCount(SmallInt); + if (SmallSize > Threshold || LargeSize > Threshold) + if ((float)std::distance(mri_->use_begin(SmallReg), + mri_->use_end()) / SmallSize < + (float)std::distance(mri_->use_begin(LargeReg), + mri_->use_end()) / LargeSize) + return false; + return true; } /// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual @@ -1047,15 +1033,9 @@ SimpleRegisterCoalescing::HasIncompatibleSubRegDefUse(MachineInstr *CopyMI, /// an extract_subreg where dst is a physical register, e.g. /// cl = EXTRACT_SUBREG reg1024, 1 bool -SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(MachineInstr *CopyMI, - unsigned DstReg, unsigned SrcReg, - unsigned SubIdx, unsigned &RealDstReg) { - if (CopyMI->getOperand(1).getSubReg()) { - DOUT << "\tSrc of extract_subreg already coalesced with reg" - << " of a super-class.\n"; - return false; // Not coalescable. - } - +SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(unsigned DstReg, + unsigned SrcReg, unsigned SubIdx, + unsigned &RealDstReg) { const TargetRegisterClass *RC = mri_->getRegClass(SrcReg); RealDstReg = getMatchingSuperReg(DstReg, SubIdx, RC, tri_); assert(RealDstReg && "Invalid extract_subreg instruction!"); @@ -1083,14 +1063,9 @@ SimpleRegisterCoalescing::CanJoinExtractSubRegToPhysReg(MachineInstr *CopyMI, /// an insert_subreg where src is a physical register, e.g. /// reg1024 = INSERT_SUBREG reg1024, c1, 0 bool -SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(MachineInstr *CopyMI, - unsigned DstReg, unsigned SrcReg, - unsigned SubIdx, unsigned &RealSrcReg) { - if (CopyMI->getOperand(1).getSubReg()) { - DOUT << "\tSrc of insert_subreg already coalesced with reg" - << " of a super-class.\n"; - return false; // Not coalescable. - } +SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(unsigned DstReg, + unsigned SrcReg, unsigned SubIdx, + unsigned &RealSrcReg) { const TargetRegisterClass *RC = mri_->getRegClass(DstReg); RealSrcReg = getMatchingSuperReg(SrcReg, SubIdx, RC, tri_); assert(RealSrcReg && "Invalid extract_subreg instruction!"); @@ -1111,7 +1086,6 @@ SimpleRegisterCoalescing::CanJoinInsertSubRegToPhysReg(MachineInstr *CopyMI, return true; } - /// JoinCopy - Attempt to join intervals corresponding to SrcReg/DstReg, /// which are the src/dst of the copy instruction CopyMI. This returns true /// if the copy was successfully coalesced away. If it is not currently @@ -1172,7 +1146,8 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { } // Should be non-null only when coalescing to a sub-register class. - const TargetRegisterClass *SubRC = NULL; + bool CrossRC = false; + const TargetRegisterClass *NewRC = NULL; MachineBasicBlock *CopyMBB = CopyMI->getParent(); unsigned RealDstReg = 0; unsigned RealSrcReg = 0; @@ -1206,13 +1181,17 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { DstReg = tri_->getSubReg(DstReg, SubIdx); SubIdx = 0; } else if ((DstIsPhys && isExtSubReg) || (SrcIsPhys && isInsSubReg)) { + if (CopyMI->getOperand(1).getSubReg()) { + DOUT << "\tSrc of extract_subreg already coalesced with reg" + << " of a super-class.\n"; + return false; // Not coalescable. + } + if (isExtSubReg) { - if (!CanJoinExtractSubRegToPhysReg(CopyMI, DstReg, SrcReg, SubIdx, - RealDstReg)) + if (!CanJoinExtractSubRegToPhysReg(DstReg, SrcReg, SubIdx, RealDstReg)) return false; // Not coalescable } else { - if (!CanJoinInsertSubRegToPhysReg(CopyMI, DstReg, SrcReg, SubIdx, - RealSrcReg)) + if (!CanJoinInsertSubRegToPhysReg(DstReg, SrcReg, SubIdx, RealSrcReg)) return false; // Not coalescable } SubIdx = 0; @@ -1220,8 +1199,7 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { unsigned OldSubIdx = isExtSubReg ? CopyMI->getOperand(0).getSubReg() : CopyMI->getOperand(2).getSubReg(); if (OldSubIdx) { - if (OldSubIdx == SubIdx && - !differingRegisterClasses(SrcReg, DstReg, SubRC)) + if (OldSubIdx == SubIdx && !differingRegisterClasses(SrcReg, DstReg)) // r1024<2> = EXTRACT_SUBREG r1025, 2. Then r1024 has already been // coalesced to a larger register so the subreg indices cancel out. // Also check if the other larger register is of the same register @@ -1235,41 +1213,90 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { if (SubIdx) { unsigned LargeReg = isExtSubReg ? SrcReg : DstReg; unsigned SmallReg = isExtSubReg ? DstReg : SrcReg; - unsigned LargeRegSize = - li_->getApproximateInstructionCount(li_->getInterval(LargeReg)); - unsigned SmallRegSize = - li_->getApproximateInstructionCount(li_->getInterval(SmallReg)); - const TargetRegisterClass *RC = mri_->getRegClass(SmallReg); - unsigned Threshold = allocatableRCRegs_[RC].count(); - // Be conservative. If both sides are virtual registers, do not coalesce - // if this will cause a high use density interval to target a smaller - // set of registers. - if (SmallRegSize > Threshold || LargeRegSize > Threshold) { - if ((float)std::distance(mri_->use_begin(SmallReg), - mri_->use_end()) / SmallRegSize < - (float)std::distance(mri_->use_begin(LargeReg), - mri_->use_end()) / LargeRegSize) { - Again = true; // May be possible to coalesce later. - return false; - } + unsigned Limit= allocatableRCRegs_[mri_->getRegClass(SmallReg)].count(); + if (!isWinToJoinCrossClass(LargeReg, SmallReg, Limit)) { + Again = true; // May be possible to coalesce later. + return false; } } } - } else if (differingRegisterClasses(SrcReg, DstReg, SubRC)) { - // FIXME: What if the resul of a EXTRACT_SUBREG is then coalesced + } else if (differingRegisterClasses(SrcReg, DstReg)) { + if (!CrossClassJoin) + return false; + CrossRC = true; + + // FIXME: What if the result of a EXTRACT_SUBREG is then coalesced // with another? If it's the resulting destination register, then // the subidx must be propagated to uses (but only those defined // by the EXTRACT_SUBREG). If it's being coalesced into another // register, it should be safe because register is assumed to have // the register class of the super-register. - if (!SubRC || !isProfitableToCoalesceToSubRC(SrcReg, DstReg, CopyMBB)) { - // If they are not of the same register class, we cannot join them. + // Process moves where one of the registers have a sub-register index. + MachineOperand *DstMO = CopyMI->findRegisterDefOperand(DstReg); + if (DstMO->getSubReg()) + // FIXME: Can we handle this? + return false; + MachineOperand *SrcMO = CopyMI->findRegisterUseOperand(SrcReg); + SubIdx = SrcMO->getSubReg(); + if (SubIdx) { + // This is not a extract_subreg but it looks like one. + // e.g. %cl = MOV16rr %reg1024:2 + isExtSubReg = true; + if (DstIsPhys) { + if (!CanJoinExtractSubRegToPhysReg(DstReg, SrcReg, SubIdx,RealDstReg)) + return false; // Not coalescable + SubIdx = 0; + } + } + + const TargetRegisterClass *SrcRC= SrcIsPhys ? 0 : mri_->getRegClass(SrcReg); + const TargetRegisterClass *DstRC= DstIsPhys ? 0 : mri_->getRegClass(DstReg); + unsigned LargeReg = SrcReg; + unsigned SmallReg = DstReg; + unsigned Limit = 0; + + // Now determine the register class of the joined register. + if (isExtSubReg) { + if (SubIdx && DstRC && DstRC->isASubClass()) { + // This is a move to a sub-register class. However, the source is a + // sub-register of a larger register class. We don't know what should + // the register class be. FIXME. + Again = true; + return false; + } + Limit = allocatableRCRegs_[DstRC].count(); + } else if (!SrcIsPhys && !SrcIsPhys) { + unsigned SrcSize = SrcRC->getSize(); + unsigned DstSize = DstRC->getSize(); + if (SrcSize < DstSize) + // For example X86::MOVSD2PDrr copies from FR64 to VR128. + NewRC = DstRC; + else if (DstSize > SrcSize) { + NewRC = SrcRC; + std::swap(LargeReg, SmallReg); + } else { + unsigned SrcNumRegs = SrcRC->getNumRegs(); + unsigned DstNumRegs = DstRC->getNumRegs(); + if (DstNumRegs < SrcNumRegs) + // Sub-register class? + NewRC = DstRC; + else if (SrcNumRegs < DstNumRegs) { + NewRC = SrcRC; + std::swap(LargeReg, SmallReg); + } else + // No idea what's the right register class to use. + return false; + } + } + + if (!SrcIsPhys && !DstIsPhys && + !isWinToJoinCrossClass(LargeReg, SmallReg, Limit)) { DOUT << "\tSrc/Dest are different register classes.\n"; // Allow the coalescer to try again in case either side gets coalesced to // a physical register that's compatible with the other side. e.g. // r1024 = MOV32to32_ r1025 - // but later r1024 is assigned EAX then r1025 may be coalesced with EAX. + // But later r1024 is assigned EAX then r1025 may be coalesced with EAX. Again = true; // May be possible to coalesce later. return false; } @@ -1417,9 +1444,10 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { // Coalescing to a virtual register that is of a sub-register class of the // other. Make sure the resulting register is set to the right register class. - if (SubRC) { - mri_->setRegClass(DstReg, SubRC); - ++numSubJoins; + if (CrossRC) { + ++numCrossRCs; + if (NewRC) + mri_->setRegClass(DstReg, NewRC); } if (NewHeuristic) { @@ -2208,14 +2236,10 @@ void SimpleRegisterCoalescing::joinIntervals() { } /// Return true if the two specified registers belong to different register -/// classes. The registers may be either phys or virt regs. In the -/// case where both registers are virtual registers, it would also returns -/// true by reference the RegB register class in SubRC if it is a subset of -/// RegA's register class. +/// classes. The registers may be either phys or virt regs. bool -SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, unsigned RegB, - const TargetRegisterClass *&SubRC) const { - +SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, + unsigned RegB) const { // Get the register classes for the first reg. if (TargetRegisterInfo::isPhysicalRegister(RegA)) { assert(TargetRegisterInfo::isVirtualRegister(RegB) && @@ -2227,10 +2251,7 @@ SimpleRegisterCoalescing::differingRegisterClasses(unsigned RegA, unsigned RegB, const TargetRegisterClass *RegClassA = mri_->getRegClass(RegA); if (TargetRegisterInfo::isVirtualRegister(RegB)) { const TargetRegisterClass *RegClassB = mri_->getRegClass(RegB); - if (RegClassA == RegClassB) - return false; - SubRC = (RegClassA->hasSubClass(RegClassB)) ? RegClassB : NULL; - return true; + return RegClassA != RegClassB; } return !RegClassA->contains(RegB); } diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.h b/llvm/lib/CodeGen/SimpleRegisterCoalescing.h index a4f0fa3f2feb..cce5cebd9e6f 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.h +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.h @@ -173,12 +173,8 @@ namespace llvm { bool SimpleJoin(LiveInterval &LHS, LiveInterval &RHS); /// Return true if the two specified registers belong to different register - /// classes. The registers may be either phys or virt regs. In the - /// case where both registers are virtual registers, it would also returns - /// true by reference the RegB register class in SubRC if it is a subset of - /// RegA's register class. - bool differingRegisterClasses(unsigned RegA, unsigned RegB, - const TargetRegisterClass *&SubRC) const; + /// classes. The registers may be either phys or virt regs. + bool differingRegisterClasses(unsigned RegA, unsigned RegB) const; /// AdjustCopiesBackFrom - We found a non-trivially-coalescable copy. If @@ -219,11 +215,10 @@ namespace llvm { /// identity copies so they will be removed. void RemoveCopiesFromValNo(LiveInterval &li, VNInfo *VNI); - /// isProfitableToCoalesceToSubRC - Given that register class of DstReg is - /// a subset of the register class of SrcReg, return true if it's profitable - /// to coalesce the two registers. - bool isProfitableToCoalesceToSubRC(unsigned SrcReg, unsigned DstReg, - MachineBasicBlock *MBB); + /// isWinToJoinCrossClass - Return true if it's profitable to coalesce + /// two virtual registers from different register classes. + bool isWinToJoinCrossClass(unsigned LargeReg, unsigned SmallReg, + unsigned Threshold); /// HasIncompatibleSubRegDefUse - If we are trying to coalesce a virtual /// register with a physical register, check if any of the virtual register @@ -235,15 +230,13 @@ namespace llvm { /// CanJoinExtractSubRegToPhysReg - Return true if it's possible to coalesce /// an extract_subreg where dst is a physical register, e.g. /// cl = EXTRACT_SUBREG reg1024, 1 - bool CanJoinExtractSubRegToPhysReg(MachineInstr *CopyMI, - unsigned DstReg, unsigned SrcReg, + bool CanJoinExtractSubRegToPhysReg(unsigned DstReg, unsigned SrcReg, unsigned SubIdx, unsigned &RealDstReg); /// CanJoinInsertSubRegToPhysReg - Return true if it's possible to coalesce /// an insert_subreg where src is a physical register, e.g. /// reg1024 = INSERT_SUBREG reg1024, c1, 0 - bool CanJoinInsertSubRegToPhysReg(MachineInstr *CopyMI, - unsigned DstReg, unsigned SrcReg, + bool CanJoinInsertSubRegToPhysReg(unsigned DstReg, unsigned SrcReg, unsigned SubIdx, unsigned &RealDstReg); /// RangeIsDefinedByCopyFromReg - Return true if the specified live range of -- GitLab From a2ca64a39ae9d5b4b926c6fa0fec70a01f8ebff1 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Fri, 23 Jan 2009 03:28:53 +0000 Subject: [PATCH 065/682] Stage two of fixing pre-alloc-splitting's code size issues: filter out restores that are just going to be re-spilled again. This also helps performance. Pre-alloc-splitting now seems to be an overall win on SPEC. llvm-svn: 62834 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 46 +++++++++++++++++++++----- 1 file changed, 37 insertions(+), 9 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index f07f0700945d..8e86213f77c3 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -1388,7 +1388,7 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { for (SmallPtrSet::iterator LI = split.begin(), LE = split.end(); LI != LE; ++LI) { - DenseMap VNUseCount; + DenseMap > VNUseCount; for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg), UE = MRI->use_end(); UI != UE; ++UI) { @@ -1396,27 +1396,55 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { index = LiveIntervals::getUseIndex(index); const LiveRange* LR = (*LI)->getLiveRangeContaining(index); - VNUseCount[LR->valno]++; + VNUseCount[LR->valno].insert(&*UI); } for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(), VE = (*LI)->vni_end(); VI != VE; ++VI) { VNInfo* CurrVN = *VI; if (CurrVN->hasPHIKill) continue; - if (VNUseCount[CurrVN] > 0) continue; unsigned DefIdx = CurrVN->def; if (DefIdx == ~0U || DefIdx == ~1U) continue; - + MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx); int FrameIndex; if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue; - LIs->RemoveMachineInstrFromMaps(DefMI); - (*LI)->removeValNo(CurrVN); - DefMI->eraseFromParent(); - NumDeadSpills++; - changed = true; + if (VNUseCount[CurrVN].size() == 0) { + LIs->RemoveMachineInstrFromMaps(DefMI); + (*LI)->removeValNo(CurrVN); + DefMI->eraseFromParent(); + NumDeadSpills++; + changed = true; + } else { + bool NonRestore = false; + for (SmallPtrSet::iterator UI = + VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); + UI != UI; ++UI) { + int StoreFrameIndex; + unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex); + if (StoreVReg != (*LI)->reg || StoreFrameIndex != FrameIndex) { + NonRestore = false; + break; + } + } + + if (NonRestore) continue; + + for (SmallPtrSet::iterator UI = + VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); + UI != UI; ++UI) { + LIs->RemoveMachineInstrFromMaps(*UI); + (*UI)->eraseFromParent(); + } + + LIs->RemoveMachineInstrFromMaps(DefMI); + (*LI)->removeValNo(CurrVN); + DefMI->eraseFromParent(); + NumDeadSpills++; + changed = true; + } } } -- GitLab From f347c3615bd2909cf37a94f97952fed580db2363 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 23 Jan 2009 05:45:31 +0000 Subject: [PATCH 066/682] Update test to reflect command line option name change. llvm-svn: 62836 --- llvm/test/CodeGen/X86/subclass-coalesce.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/X86/subclass-coalesce.ll b/llvm/test/CodeGen/X86/subclass-coalesce.ll index 26e6256ea0f5..a010f1b29f1d 100644 --- a/llvm/test/CodeGen/X86/subclass-coalesce.ll +++ b/llvm/test/CodeGen/X86/subclass-coalesce.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -join-subclass-copies -stats |& grep {Number of subclass joins performed} +; RUN: llvm-as < %s | llc -march=x86 -join-cross-class-copies -stats |& grep {Number of cross class joins performed} @mem.6 = external global i64 ; [#uses=1] -- GitLab From 9db227999a108f0da1db7cea0c7523908f6599c4 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 23 Jan 2009 05:48:59 +0000 Subject: [PATCH 067/682] Only check if coalescing is worthwhile when the result is targeting a more restrictive register class. llvm-svn: 62837 --- llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp index f0b0d58d1358..f3ffc69cccbe 100644 --- a/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp +++ b/llvm/lib/CodeGen/SimpleRegisterCoalescing.cpp @@ -1290,8 +1290,13 @@ bool SimpleRegisterCoalescing::JoinCopy(CopyRec &TheCopy, bool &Again) { } } + // If we are joining two virtual registers and the resulting register + // class is more restrictive (fewer register, smaller size). Check if it's + // worth doing the merge. if (!SrcIsPhys && !DstIsPhys && - !isWinToJoinCrossClass(LargeReg, SmallReg, Limit)) { + (isExtSubReg || DstRC->isASubClass()) && + !isWinToJoinCrossClass(LargeReg, SmallReg, + allocatableRCRegs_[NewRC].count())) { DOUT << "\tSrc/Dest are different register classes.\n"; // Allow the coalescer to try again in case either side gets coalesced to // a physical register that's compatible with the other side. e.g. -- GitLab From e3ea48c71ea626c4c11bec2ffcdeca3e7042c06a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 06:48:41 +0000 Subject: [PATCH 068/682] Unconditionally reset 'cache' to zero, even if we don't need to resort it. This avoids using a dangling pointer. Reset NumSortedEntries after restoring Cache to avoid extraneous sorts. This fixes the reduced sqlite3 testcase, but apparently not the whole app. llvm-svn: 62838 --- llvm/lib/Analysis/MemoryDependenceAnalysis.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index c84a51fb062f..8670890cdb60 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -751,11 +751,9 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // cache remains sorted. Sort it now (if needed) so that recursive // invocations of getNonLocalPointerDepFromBB that could reuse the cache // value will only see properly sorted cache arrays. - if (Cache && NumSortedEntries != Cache->size()) { + if (Cache && NumSortedEntries != Cache->size()) std::sort(Cache->begin(), Cache->end()); - NumSortedEntries = Cache->size(); - Cache = 0; - } + Cache = 0; // FIXME: it is entirely possible that PHI translating will end up with // the same value. Consider PHI translating something like: @@ -793,7 +791,8 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // Refresh the CacheInfo/Cache pointer so that it isn't invalidated. CacheInfo = &NonLocalPointerDeps[CacheKey]; Cache = &CacheInfo->second; - + NumSortedEntries = Cache->size(); + // Since we did phi translation, the "Cache" set won't contain all of the // results for the query. This is ok (we can still use it to accelerate // specific block queries) but we can't do the fastpath "return all -- GitLab From 3f4591c89f361169b2f66733697c6ac7faafa961 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 07:12:16 +0000 Subject: [PATCH 069/682] fix two more cases where we could let the NLPDI cache get unsorted. With this, sqlite3 now passes. llvm-svn: 62839 --- .../lib/Analysis/MemoryDependenceAnalysis.cpp | 19 +++- .../GVN/2009-01-22-SortInvalidation.ll | 100 ++++++++++++++++++ 2 files changed, 114 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/GVN/2009-01-22-SortInvalidation.ll diff --git a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp index 8670890cdb60..6af365b76a90 100644 --- a/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp +++ b/llvm/lib/Analysis/MemoryDependenceAnalysis.cpp @@ -788,10 +788,15 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, // cerr << "OP:\t\t\t\t" << *PtrInst->getOperand(0); PredTranslationFailure: - // Refresh the CacheInfo/Cache pointer so that it isn't invalidated. - CacheInfo = &NonLocalPointerDeps[CacheKey]; - Cache = &CacheInfo->second; - NumSortedEntries = Cache->size(); + if (Cache == 0) { + // Refresh the CacheInfo/Cache pointer if it got invalidated. + CacheInfo = &NonLocalPointerDeps[CacheKey]; + Cache = &CacheInfo->second; + NumSortedEntries = Cache->size(); + } else if (NumSortedEntries != Cache->size()) { + std::sort(Cache->begin(), Cache->end()); + NumSortedEntries = Cache->size(); + } // Since we did phi translation, the "Cache" set won't contain all of the // results for the query. This is ok (we can still use it to accelerate @@ -821,7 +826,7 @@ getNonLocalPointerDepFromBB(Value *Pointer, uint64_t PointeeSize, break; } } - + // Okay, we're done now. If we added new values to the cache, re-sort it. switch (Cache->size()-NumSortedEntries) { case 0: @@ -1045,6 +1050,10 @@ void MemoryDependenceAnalysis::removeInstruction(Instruction *RemInst) { if (Instruction *NewDirtyInst = NewDirtyVal.getInst()) ReversePtrDepsToAdd.push_back(std::make_pair(NewDirtyInst, P)); } + + // Re-sort the NonLocalDepInfo. Changing the dirty entry to its + // subsequent value may invalidate the sortedness. + std::sort(NLPDI.begin(), NLPDI.end()); } ReverseNonLocalPtrDeps.erase(ReversePtrDepIt); diff --git a/llvm/test/Transforms/GVN/2009-01-22-SortInvalidation.ll b/llvm/test/Transforms/GVN/2009-01-22-SortInvalidation.ll new file mode 100644 index 000000000000..9b7fa0622ab8 --- /dev/null +++ b/llvm/test/Transforms/GVN/2009-01-22-SortInvalidation.ll @@ -0,0 +1,100 @@ +; RUN: llvm-as < %s | opt -gvn | llvm-dis + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + %struct..4sPragmaType = type { i8*, i32 } + %struct.AggInfo = type { i8, i8, i32, %struct.ExprList*, i32, %struct.AggInfo_col*, i32, i32, i32, %struct.AggInfo_func*, i32, i32 } + %struct.AggInfo_col = type { %struct.Table*, i32, i32, i32, i32, %struct.Expr* } + %struct.AggInfo_func = type { %struct.Expr*, %struct.FuncDef*, i32, i32 } + %struct.AuxData = type { i8*, void (i8*)* } + %struct.Bitvec = type { i32, i32, i32, { [125 x i32] } } + %struct.BtCursor = type { %struct.Btree*, %struct.BtShared*, %struct.BtCursor*, %struct.BtCursor*, i32 (i8*, i32, i8*, i32, i8*)*, i8*, i32, %struct.MemPage*, i32, %struct.CellInfo, i8, i8, i8*, i64, i32, i8, i32* } + %struct.BtLock = type { %struct.Btree*, i32, i8, %struct.BtLock* } + %struct.BtShared = type { %struct.Pager*, %struct.sqlite3*, %struct.BtCursor*, %struct.MemPage*, i8, i8, i8, i8, i8, i8, i8, i8, i32, i16, i16, i32, i32, i32, i32, i8, i32, i8*, void (i8*)*, %struct.sqlite3_mutex*, %struct.BusyHandler, i32, %struct.BtShared*, %struct.BtLock*, %struct.Btree* } + %struct.Btree = type { %struct.sqlite3*, %struct.BtShared*, i8, i8, i8, i32, %struct.Btree*, %struct.Btree* } + %struct.BtreeMutexArray = type { i32, [11 x %struct.Btree*] } + %struct.BusyHandler = type { i32 (i8*, i32)*, i8*, i32 } + %struct.CellInfo = type { i8*, i64, i32, i32, i16, i16, i16, i16 } + %struct.CollSeq = type { i8*, i8, i8, i8*, i32 (i8*, i32, i8*, i32, i8*)*, void (i8*)* } + %struct.Column = type { i8*, %struct.Expr*, i8*, i8*, i8, i8, i8, i8 } + %struct.Context = type { i64, i32, %struct.Fifo } + %struct.CountCtx = type { i64 } + %struct.Cursor = type { %struct.BtCursor*, i32, i64, i64, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i64, %struct.Btree*, i32, i8*, i64, i8*, %struct.KeyInfo*, i32, i64, %struct.sqlite3_vtab_cursor*, %struct.sqlite3_module*, i32, i32, i32*, i32*, i8* } + %struct.Db = type { i8*, %struct.Btree*, i8, i8, i8*, void (i8*)*, %struct.Schema* } + %struct.Expr = type { i8, i8, i16, %struct.CollSeq*, %struct.Expr*, %struct.Expr*, %struct.ExprList*, %struct..4sPragmaType, %struct..4sPragmaType, i32, i32, %struct.AggInfo*, i32, i32, %struct.Select*, %struct.Table*, i32 } + %struct.ExprList = type { i32, i32, i32, %struct.ExprList_item* } + %struct.ExprList_item = type { %struct.Expr*, i8*, i8, i8, i8 } + %struct.FKey = type { %struct.Table*, %struct.FKey*, i8*, %struct.FKey*, i32, %struct.sColMap*, i8, i8, i8, i8 } + %struct.Fifo = type { i32, %struct.FifoPage*, %struct.FifoPage* } + %struct.FifoPage = type { i32, i32, i32, %struct.FifoPage*, [1 x i64] } + %struct.FuncDef = type { i16, i8, i8, i8, i8*, %struct.FuncDef*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*)*, [1 x i8] } + %struct.Hash = type { i8, i8, i32, i32, %struct.HashElem*, %struct._ht* } + %struct.HashElem = type { %struct.HashElem*, %struct.HashElem*, i8*, i8*, i32 } + %struct.IdList = type { %struct..4sPragmaType*, i32, i32 } + %struct.Index = type { i8*, i32, i32*, i32*, %struct.Table*, i32, i8, i8, i8*, %struct.Index*, %struct.Schema*, i8*, i8** } + %struct.KeyInfo = type { %struct.sqlite3*, i8, i8, i8, i32, i8*, [1 x %struct.CollSeq*] } + %struct.Mem = type { %struct.CountCtx, double, %struct.sqlite3*, i8*, i32, i16, i8, i8, void (i8*)* } + %struct.MemPage = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i16, i16, i16, i16, i16, i16, [5 x %struct._OvflCell], %struct.BtShared*, i8*, %struct.PgHdr*, i32, %struct.MemPage* } + %struct.Module = type { %struct.sqlite3_module*, i8*, i8*, void (i8*)* } + %struct.Op = type { i8, i8, i8, i8, i32, i32, i32, { i32 } } + %struct.Pager = type { %struct.sqlite3_vfs*, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.Bitvec*, %struct.Bitvec*, i8*, i8*, i8*, i8*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.BusyHandler*, %struct.PagerLruList, %struct.PgHdr*, %struct.PgHdr*, %struct.PgHdr*, i64, i64, i64, i64, i64, i32, void (%struct.PgHdr*, i32)*, void (%struct.PgHdr*, i32)*, i32, %struct.PgHdr**, i8*, [16 x i8] } + %struct.PagerLruLink = type { %struct.PgHdr*, %struct.PgHdr* } + %struct.PagerLruList = type { %struct.PgHdr*, %struct.PgHdr*, %struct.PgHdr* } + %struct.Parse = type { %struct.sqlite3*, i32, i8*, %struct.Vdbe*, i8, i8, i8, i8, i8, i8, i8, [8 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [12 x i32], i32, %struct.TableLock*, i32, i32, i32, i32, i32, %struct.Expr**, i8, %struct..4sPragmaType, %struct..4sPragmaType, %struct..4sPragmaType, i8*, i8*, %struct.Table*, %struct.Trigger*, %struct.TriggerStack*, i8*, %struct..4sPragmaType, i8, %struct.Table*, i32 } + %struct.PgHdr = type { %struct.Pager*, i32, %struct.PgHdr*, %struct.PgHdr*, %struct.PagerLruLink, %struct.PgHdr*, i8, i8, i8, i8, i8, i16, %struct.PgHdr*, %struct.PgHdr*, i8* } + %struct.Schema = type { i32, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Table*, i8, i8, i16, i32, %struct.sqlite3* } + %struct.Select = type { %struct.ExprList*, i8, i8, i8, i8, i8, i8, i8, %struct.SrcList*, %struct.Expr*, %struct.ExprList*, %struct.Expr*, %struct.ExprList*, %struct.Select*, %struct.Select*, %struct.Select*, %struct.Expr*, %struct.Expr*, i32, i32, [3 x i32] } + %struct.SrcList = type { i16, i16, [1 x %struct.SrcList_item] } + %struct.SrcList_item = type { i8*, i8*, i8*, %struct.Table*, %struct.Select*, i8, i8, i32, %struct.Expr*, %struct.IdList*, i64 } + %struct.Table = type { i8*, i32, %struct.Column*, i32, %struct.Index*, i32, %struct.Select*, i32, %struct.Trigger*, %struct.FKey*, i8*, %struct.Expr*, i32, i8, i8, i8, i8, i8, i8, i8, %struct.Module*, %struct.sqlite3_vtab*, i32, i8**, %struct.Schema* } + %struct.TableLock = type { i32, i32, i8, i8* } + %struct.Trigger = type { i8*, i8*, i8, i8, %struct.Expr*, %struct.IdList*, %struct..4sPragmaType, %struct.Schema*, %struct.Schema*, %struct.TriggerStep*, %struct.Trigger* } + %struct.TriggerStack = type { %struct.Table*, i32, i32, i32, i32, i32, i32, %struct.Trigger*, %struct.TriggerStack* } + %struct.TriggerStep = type { i32, i32, %struct.Trigger*, %struct.Select*, %struct..4sPragmaType, %struct.Expr*, %struct.ExprList*, %struct.IdList*, %struct.TriggerStep*, %struct.TriggerStep* } + %struct.Vdbe = type { %struct.sqlite3*, %struct.Vdbe*, %struct.Vdbe*, i32, i32, %struct.Op*, i32, i32, i32*, %struct.Mem**, %struct.Mem*, i32, %struct.Cursor**, i32, %struct.Mem*, i8**, i32, i32, i32, %struct.Mem*, i32, i32, %struct.Fifo, i32, i32, %struct.Context*, i32, i32, i32, i32, i32, [25 x i32], i32, i32, i8**, i8*, %struct.Mem*, i8, i8, i8, i8, i8, i8, i32, i64, i32, %struct.BtreeMutexArray, i32, i8*, i32 } + %struct.VdbeFunc = type { %struct.FuncDef*, i32, [1 x %struct.AuxData] } + %struct._OvflCell = type { i8*, i16 } + %struct._ht = type { i32, %struct.HashElem* } + %struct.anon = type { double } + %struct.sColMap = type { i32, i8* } + %struct.sqlite3 = type { %struct.sqlite3_vfs*, i32, %struct.Db*, i32, i32, i32, i32, i8, i8, i8, i8, i32, %struct.CollSeq*, i64, i64, i32, i32, i32, %struct.sqlite3_mutex*, %struct.sqlite3InitInfo, i32, i8**, %struct.Vdbe*, i32, void (i8*, i8*)*, i8*, void (i8*, i8*, i64)*, i8*, i8*, i32 (i8*)*, i8*, void (i8*)*, i8*, void (i8*, i32, i8*, i8*, i64)*, void (i8*, %struct.sqlite3*, i32, i8*)*, void (i8*, %struct.sqlite3*, i32, i8*)*, i8*, %struct.Mem*, i8*, i8*, %struct.anon, i32 (i8*, i32, i8*, i8*, i8*, i8*)*, i8*, i32 (i8*)*, i8*, i32, %struct.Hash, %struct.Table*, %struct.sqlite3_vtab**, i32, %struct.Hash, %struct.Hash, %struct.BusyHandler, i32, [2 x %struct.Db], i8 } + %struct.sqlite3InitInfo = type { i32, i32, i8 } + %struct.sqlite3_context = type { %struct.FuncDef*, %struct.VdbeFunc*, %struct.Mem, %struct.Mem*, i32, %struct.CollSeq* } + %struct.sqlite3_file = type { %struct.sqlite3_io_methods* } + %struct.sqlite3_index_constraint = type { i32, i8, i8, i32 } + %struct.sqlite3_index_constraint_usage = type { i32, i8 } + %struct.sqlite3_index_info = type { i32, %struct.sqlite3_index_constraint*, i32, %struct.sqlite3_index_constraint_usage*, %struct.sqlite3_index_constraint_usage*, i32, i8*, i32, i32, double } + %struct.sqlite3_io_methods = type { i32, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i64)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i64*)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i32, i8*)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*)* } + %struct.sqlite3_module = type { i32, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_index_info*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_vtab_cursor**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, i32, i8*, i32, %struct.Mem**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, %struct.sqlite3_context*, i32)*, i32 (%struct.sqlite3_vtab_cursor*, i64*)*, i32 (%struct.sqlite3_vtab*, i32, %struct.Mem**, i64*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, i32, i8*, void (%struct.sqlite3_context*, i32, %struct.Mem**)**, i8**)*, i32 (%struct.sqlite3_vtab*, i8*)* } + %struct.sqlite3_mutex = type opaque + %struct.sqlite3_vfs = type { i32, i32, i32, %struct.sqlite3_vfs*, i8*, i8*, i32 (%struct.sqlite3_vfs*, i8*, %struct.sqlite3_file*, i32, i32*)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i8*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*)*, void (%struct.sqlite3_vfs*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*, i8*)*, void (%struct.sqlite3_vfs*, i8*)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i32)*, i32 (%struct.sqlite3_vfs*, double*)* } + %struct.sqlite3_vtab = type { %struct.sqlite3_module*, i32, i8* } + %struct.sqlite3_vtab_cursor = type { %struct.sqlite3_vtab* } + +define fastcc void @sqlite3Insert(%struct.Parse* %pParse, %struct.SrcList* %pTabList, %struct.ExprList* %pList, %struct.Select* %pSelect, %struct.IdList* %pColumn, i32 %onError) nounwind { +entry: + br i1 false, label %bb54, label %bb69.loopexit + +bb54: ; preds = %entry + br label %bb69.loopexit + +bb59: ; preds = %bb63.preheader + %0 = load %struct..4sPragmaType** %3, align 4 ; <%struct..4sPragmaType*> [#uses=0] + br label %bb65 + +bb65: ; preds = %bb63.preheader, %bb59 + %1 = load %struct..4sPragmaType** %4, align 4 ; <%struct..4sPragmaType*> [#uses=0] + br i1 false, label %bb67, label %bb63.preheader + +bb67: ; preds = %bb65 + %2 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=0] + unreachable + +bb69.loopexit: ; preds = %bb54, %entry + %3 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=1] + %4 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=1] + br label %bb63.preheader + +bb63.preheader: ; preds = %bb69.loopexit, %bb65 + br i1 false, label %bb59, label %bb65 +} -- GitLab From 8fb96605f8a2200063cc4aac676d4405bdae9dea Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 08:16:41 +0000 Subject: [PATCH 070/682] ccc: Implement long options which take joined & separate forms. llvm-svn: 62841 --- clang/tools/ccc/ccclib/Arguments.py | 63 +++++++++++++++++++++++++---- 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 15eaca1ef430..50415bf706e7 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -521,7 +521,7 @@ class OptionParser: self.saveTempsOption = self.addOption(FlagOption('-save-temps')) # FIXME: Error out if this is used. - self.addOption(JoinedOption('-specs=')) + self.specsOption = self.addOption(JoinedOption('-specs=')) # FIXME: Implement. self.addOption(FlagOption('-time')) # FIXME: Implement. @@ -704,7 +704,7 @@ class OptionParser: self.IGroup = OptionGroup('-I') self.I_Option = self.addOption(FlagOption('-I-', self.IGroup)) - self.addOption(JoinedOrSeparateOption('-I', self.IGroup)) + self.IOption = self.addOption(JoinedOrSeparateOption('-I', self.IGroup)) self.LOption = self.addOption(JoinedOrSeparateOption('-L')) self.TOption = self.addOption(JoinedOrSeparateOption('-T')) @@ -762,13 +762,17 @@ class OptionParser: self.fastcpOption = self.addOption(FlagOption('-fastcp', self.fGroup)) self.f_appleKextOption = self.addOption(FlagOption('-fapple-kext', self.fGroup)) + self.f_bootclasspathOption = self.addOption(JoinedOption('-fbootclasspath=', self.fGroup)) self.f_classpathOption = self.addOption(JoinedOption('-fclasspath=', self.fGroup)) + self.f_compileResourceOption = self.addOption(JoinedOption('-fcompile-resource=', self.fGroup)) self.f_constantCfstringsOption = self.addOption(FlagOption('-fconstant-cfstrings', self.fGroup)) self.f_createProfileOption = self.addOption(FlagOption('-fcreate-profile', self.fGroup)) self.f_debugPassArgumentsOption = self.addOption(FlagOption('-fdebug-pass-arguments', self.fGroup)) self.f_debugPassStructureOption = self.addOption(FlagOption('-fdebug-pass-structure', self.fGroup)) self.f_eliminateUnusedDebugSymbolsOption = self.addOption(FlagOption('-feliminate-unused-debug-symbols', self.fGroup)) + self.f_encodingOption = self.addOption(JoinedOption('-fencoding=', self.fGroup)) self.f_exceptionsOption = self.addOption(FlagOption('-fexceptions', self.fGroup)) + self.f_extdirsOption = self.addOption(JoinedOption('-fextdirs=', self.fGroup)) self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime', self.fGroup)) self.f_gnuRuntimeOption = self.addOption(FlagOption('-fgnu-runtime', self.fGroup)) self.f_indirectVirtualCallsOption = self.addOption(FlagOption('-findirect-virtual-calls', self.fGroup)) @@ -790,6 +794,7 @@ class OptionParser: self.f_objcOption = self.addOption(FlagOption('-fobjc', self.fGroup)) self.f_omitFramePointerOption = self.addOption(FlagOption('-fomit-frame-pointer', self.fGroup)) self.f_openmpOption = self.addOption(FlagOption('-fopenmp', self.fGroup)) + self.f_outputClassDirOption = self.addOption(JoinedOption('-foutput-class-dir=', self.fGroup)) self.f_pascalStringsOption = self.addOption(FlagOption('-fpascal-strings', self.fGroup)) self.f_pieOption = self.addOption(FlagOption('-fpie', self.fGroup)) self.f_PIEOption = self.addOption(FlagOption('-fPIE', self.fGroup)) @@ -882,12 +887,6 @@ class OptionParser: self.addOption(FlagOption('--all-warnings', alias=self.WallOption)) self.addOption(FlagOption('--ansi', alias=self.ansiOption)) self.addOption(FlagOption('--assemble', alias=self.SOption)) - self.addOption(SeparateOption('--assert', alias=self.AOption)) - self.addOption(JoinedOption('--assert=', alias=self.AOption, - forceSeparateRender=True)) - self.addOption(JoinedOption('--classpath=', alias=self.f_classpathOption)) - self.addOption(SeparateOption('--classpath', alias=self.f_classpathOption, - forceJoinedRender=True)) self.addOption(FlagOption('--combine', alias=self.combineOption)) self.addOption(FlagOption('--comments', alias=self.COption)) self.addOption(FlagOption('--comments-in-macros', alias=self.CCOption)) @@ -941,6 +940,54 @@ class OptionParser: self.addOption(FlagOption('--write-dependencies', alias=self.MDOption)) self.addOption(FlagOption('--write-user-dependencies', alias=self.MMDOption)) + # Long options with joined & separate forms. + + self.addOption(SeparateOption('--assert', alias=self.AOption)) + self.addOption(JoinedOption('--assert=', alias=self.AOption, + forceSeparateRender=True)) + self.addOption(JoinedOption('--bootclasspath=', alias=self.f_bootclasspathOption)) + self.addOption(SeparateOption('--bootclasspath', alias=self.f_bootclasspathOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--CLASSPATH=', alias=self.f_classpathOption)) + self.addOption(SeparateOption('--CLASSPATH', alias=self.f_classpathOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--classpath=', alias=self.f_classpathOption)) + self.addOption(SeparateOption('--classpath', alias=self.f_classpathOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--define-macro=', alias=self.DOption)) + self.addOption(SeparateOption('--define-macro', alias=self.DOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--encoding=', alias=self.f_encodingOption)) + self.addOption(SeparateOption('--encoding', alias=self.f_encodingOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--extdirs=', alias=self.f_extdirsOption)) + self.addOption(SeparateOption('--extdirs', alias=self.f_extdirsOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--include-directory=', alias=self.IOption)) + self.addOption(SeparateOption('--include-directory', alias=self.IOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--machine=', alias=self.mOption)) + self.addOption(SeparateOption('--machine', alias=self.mOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--output-class-directory=', alias=self.f_outputClassDirOption)) + self.addOption(SeparateOption('--output-class-directory', alias=self.f_outputClassDirOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--resource=', alias=self.f_compileResourceOption)) + self.addOption(SeparateOption('--resource', alias=self.f_compileResourceOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--specs=', alias=self.specsOption)) + self.addOption(SeparateOption('--specs', alias=self.specsOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--std=', alias=self.stdOption)) + self.addOption(SeparateOption('--std', alias=self.stdOption, + forceJoinedRender=True)) + self.sysrootOption = self.addOption(JoinedOption('--sysroot=')) + self.addOption(SeparateOption('--sysroot', alias=self.sysrootOption, + forceJoinedRender=True)) + self.addOption(JoinedOption('--undefine-macro=', alias=self.UOption)) + self.addOption(SeparateOption('--undefine-macro', alias=self.UOption, + forceJoinedRender=True)) + def addOption(self, opt): self.options.append(opt) return opt -- GitLab From d4aae43e79251801c6ac9e8c67eefac9dbc185e8 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Fri, 23 Jan 2009 08:42:38 +0000 Subject: [PATCH 071/682] Patch to build llvm with srcdir != objdir from llvm-top. By Michael Schuerig, with some small tweaks to make the "don't configure if already configured" logic work. llvm-svn: 62842 --- llvm/ModuleInfo.txt | 4 ++-- llvm/build-for-llvm-top.sh | 18 ++++++++++++++---- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/llvm/ModuleInfo.txt b/llvm/ModuleInfo.txt index ec9da652cb8f..5a1d8b85ad0b 100644 --- a/llvm/ModuleInfo.txt +++ b/llvm/ModuleInfo.txt @@ -1,4 +1,4 @@ DepModule: BuildCmd: ./build-for-llvm-top.sh -CleanCmd: make clean -InstallCmd: make install +CleanCmd: make clean -C ../build.llvm +InstallCmd: make install -C ../build.llvm diff --git a/llvm/build-for-llvm-top.sh b/llvm/build-for-llvm-top.sh index 2a68c79965b8..78e3ed87f092 100755 --- a/llvm/build-for-llvm-top.sh +++ b/llvm/build-for-llvm-top.sh @@ -9,9 +9,16 @@ # variables. process_arguments "$@" +# First, see if the build directory is there. If not, create it. +build_dir="$LLVM_TOP/build.llvm" +if test ! -d "$build_dir" ; then + mkdir -p "$build_dir" +fi + # See if we have previously been configured by sensing the presence # of the config.status scripts -if test ! -x "config.status" ; then +config_status="$build_dir/config.status" +if test ! -f "$config_status" -o "$config_status" -ot "$0" ; then # We must configure so build a list of configure options config_options="--prefix=$PREFIX --with-llvmgccdir=$PREFIX" if test "$OPTIMIZED" -eq 1 ; then @@ -45,12 +52,15 @@ if test ! -x "config.status" ; then config_options="$config_options --disable-threads" fi config_options="$config_options $OPTIONS_DASH $OPTIONS_DASH_DASH" + src_dir=`pwd` + cd "$build_dir" msg 0 Configuring $module with: - msg 0 " ./configure" $config_options - $LLVM_TOP/llvm/configure $config_options || \ - die $? "Configuring llvm module failed" + msg 0 " $src_dir/configure" $config_options + $src_dir/configure $config_options || \ + die $? "Configuring $module module failed" else msg 0 Module $module already configured, ignoring configure options. + cd "$build_dir" fi msg 0 Building $module with: -- GitLab From 570e088e4bd3479e4c10f1bd977e1600ae37f2ff Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 23 Jan 2009 10:19:29 +0000 Subject: [PATCH 072/682] When getting the element region type, we should get the rvalue type of the super region. Otherwise we would get an extra level of pointer type. llvm-svn: 62844 --- clang/lib/Analysis/MemRegion.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp index 72b1e0b4f7f2..2724ed0ada22 100644 --- a/clang/lib/Analysis/MemRegion.cpp +++ b/clang/lib/Analysis/MemRegion.cpp @@ -108,8 +108,8 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { } QualType ElementRegion::getRValueType(ASTContext& C) const { - QualType T = getArrayRegion()->getLValueType(C); - // FIXME: Should ArrayType be considered an LValue or RValue type? + QualType T = getArrayRegion()->getRValueType(C); + if (isa(T.getTypePtr())) { ArrayType* AT = cast(T.getTypePtr()); return AT->getElementType(); -- GitLab From b8365bd890f2c8e19d3623b7369e9816baa8e3d1 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 23 Jan 2009 10:23:13 +0000 Subject: [PATCH 073/682] Add a test case for init expr of array and struct type. llvm-svn: 62845 --- clang/test/Analysis/array-struct.c | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/test/Analysis/array-struct.c b/clang/test/Analysis/array-struct.c index 4257220f9bd6..326c2888a0b9 100644 --- a/clang/test/Analysis/array-struct.c +++ b/clang/test/Analysis/array-struct.c @@ -44,6 +44,7 @@ void f3() { void f4() { int a[] = { 1, 2, 3}; int b[3] = { 1, 2 }; + struct s c[] = {{1,{1}}}; } // Struct variable in lvalue context. -- GitLab From 804f26a60a79ceb4b92fca44c519effb0b7956f4 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 23 Jan 2009 10:42:17 +0000 Subject: [PATCH 074/682] Now this comment should be resolved. See the comments for the KillSet. llvm-svn: 62846 --- clang/lib/Analysis/RegionStore.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 48c11f3bbf1b..2e82cc665ccd 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -572,12 +572,6 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { GRStateRef state(St, StateMgr); - // FIXME: Do we even need a killset? If 'Unknown' is explicitly - // bound to to a region won't this be enough? (that's basically - // what a killset is). RemoveDeadBindings should only remove - // bindings that are no longer accessible, which means that won't - // ever be read. - // Check if the region is in killset. if (state.contains(R)) return UnknownVal(); -- GitLab From e37f9afb2ea832ecbabf2513da899bf38273e6f2 Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 23 Jan 2009 11:22:12 +0000 Subject: [PATCH 075/682] Implement retrieval of the default value of element and field regions. llvm-svn: 62847 --- clang/lib/Analysis/RegionStore.cpp | 9 +++++++++ clang/test/Analysis/array-struct.c | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index 2e82cc665ccd..f519d4d1cd1b 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -576,6 +576,15 @@ SVal RegionStoreManager::Retrieve(const GRState* St, Loc L, QualType T) { if (state.contains(R)) return UnknownVal(); + // If the region is an element of field, it may have a default value. + if (isa(R) || isa(R)) { + const MemRegion* SuperR = cast(R)->getSuperRegion(); + GRStateTrait::lookup_type D = + state.get(SuperR); + if (D) + return *D; + } + // The location does not have a bound value. This means that it has // the value it had upon its creation and/or entry to the analyzed // function/method. These are either symbolic values or 'undefined'. diff --git a/clang/test/Analysis/array-struct.c b/clang/test/Analysis/array-struct.c index 326c2888a0b9..a8de8245cd0a 100644 --- a/clang/test/Analysis/array-struct.c +++ b/clang/test/Analysis/array-struct.c @@ -87,3 +87,11 @@ void f10() { char a1[4] = "abc"; char a3[6] = "abc"; } + +// Retrieve the default value of element/field region. +void f11() { + struct s a; + g(&a); + if (a.data == 0) // no-warning + a.data = 1; +} -- GitLab From 9aa8904a467c709c5b002dc41b7a3bf55e38b18f Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 16:23:13 +0000 Subject: [PATCH 076/682] Handle any undeclared parameters in a K&R-style function with a special action, inside function prototype scope. This avoids confusion when we try to inject these parameters into the scope of the function body before the function itself has been added to the surrounding scope. Fixes . llvm-svn: 62849 --- clang/include/clang/Parse/Action.h | 7 +++++++ clang/lib/Parse/Parser.cpp | 1 + clang/lib/Sema/Sema.h | 1 + clang/lib/Sema/SemaDecl.cpp | 16 ++++++++++++---- clang/test/Sema/function.c | 4 ++++ clang/test/Sema/redefinition.c | 5 +++++ 6 files changed, 30 insertions(+), 4 deletions(-) diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 5d87b1722105..0f0d88acc84e 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -223,6 +223,13 @@ public: return Group; } + /// @brief Indicates that all K&R-style parameter declarations have + /// been parsed prior to a function definition. + /// @param S The function prototype scope. + /// @param D The function declarator. + virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D) { + } + /// ActOnStartOfFunctionDef - This is called at the start of a function /// definition, instead of calling ActOnDeclarator. The Declarator includes /// information about formal arguments that are part of this function. diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 6ae3bf038ffa..7e1cef950fdc 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -674,6 +674,7 @@ void Parser::ParseKNRParamDeclarations(Declarator &D) { } // The actions module must verify that all arguments were declared. + Actions.ActOnFinishKNRParamDeclarations(CurScope, D); } diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 128ba8813a1f..40cfe8f1938a 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -311,6 +311,7 @@ public: void ActOnUninitializedDecl(DeclTy *dcl); virtual DeclTy *FinalizeDeclaratorGroup(Scope *S, DeclTy *Group); + virtual void ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D); virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, Declarator &D); virtual DeclTy *ActOnStartOfFunctionDef(Scope *S, DeclTy *D); virtual void ObjCActOnStartOfMethodDef(Scope *S, DeclTy *D); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 276f2e24e85d..e766ca06a5e1 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2633,8 +2633,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) { } -Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { - assert(getCurFunctionDecl() == 0 && "Function parsing confused"); +void Sema::ActOnFinishKNRParamDeclarations(Scope *S, Declarator &D) { assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && "Not a function declarator!"); DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun; @@ -2654,10 +2653,19 @@ Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { PrevSpec); Declarator ParamD(DS, Declarator::KNRTypeListContext); ParamD.SetIdentifier(FTI.ArgInfo[i].Ident, FTI.ArgInfo[i].IdentLoc); - FTI.ArgInfo[i].Param = ActOnParamDeclarator(FnBodyScope, ParamD); + FTI.ArgInfo[i].Param = ActOnParamDeclarator(S, ParamD); } } - } else { + } +} + +Sema::DeclTy *Sema::ActOnStartOfFunctionDef(Scope *FnBodyScope, Declarator &D) { + assert(getCurFunctionDecl() == 0 && "Function parsing confused"); + assert(D.getTypeObject(0).Kind == DeclaratorChunk::Function && + "Not a function declarator!"); + DeclaratorChunk::FunctionTypeInfo &FTI = D.getTypeObject(0).Fun; + + if (FTI.hasPrototype) { // FIXME: Diagnose arguments without names in C. } diff --git a/clang/test/Sema/function.c b/clang/test/Sema/function.c index de970a09b352..677f6a3f0e29 100644 --- a/clang/test/Sema/function.c +++ b/clang/test/Sema/function.c @@ -39,3 +39,7 @@ void t13() { int t14() { return; // expected-warning {{non-void function 't14' should return a value}} } + +// +y(y) { return y; } // expected-warning{{parameter 'y' was not declared, defaulting to type 'int'}} \ + // expected-warning{{type specifier missing, defaults to 'int'}} diff --git a/clang/test/Sema/redefinition.c b/clang/test/Sema/redefinition.c index 5e7907062311..97e047314803 100644 --- a/clang/test/Sema/redefinition.c +++ b/clang/test/Sema/redefinition.c @@ -3,3 +3,8 @@ int f(int a) { } // expected-note {{previous definition is here}} int f(int); int f(int a) { } // expected-error {{redefinition of 'f'}} +// +int foo(x) { + return 0; +} +int x = 1; -- GitLab From 033d1257ca0f6ca3d5095c139d4d34ad34f4cf91 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 16:54:12 +0000 Subject: [PATCH 077/682] Properly manage the bit-widths of APInts/APSInts in array initialization. Fixes PR clang/3377 llvm-svn: 62851 --- clang/lib/Sema/SemaInit.cpp | 19 ++++++++++++------- clang/test/Sema/designated-initializers.c | 3 +++ clang/test/Sema/init.c | 4 +++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index e855840ea5df..ba8312b7b52d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -142,8 +142,9 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList, CheckStructUnionTypes(IList, DeclType, RD->field_begin(), SubobjectIsDesignatorContext, Index); } else if (DeclType->isArrayType()) { - // FIXME: Is 32 always large enough for array indices? - llvm::APSInt Zero(32, false); + llvm::APSInt Zero( + SemaRef->Context.getTypeSize(SemaRef->Context.getSizeType()), + false); CheckArrayType(IList, DeclType, Zero, SubobjectIsDesignatorContext, Index); } else @@ -269,15 +270,13 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, return; } - // FIXME: Will 32 bits always be enough? I hope so. - const unsigned ArraySizeBits = 32; - // We might know the maximum number of elements in advance. - llvm::APSInt maxElements(ArraySizeBits, 0); + llvm::APSInt maxElements(elementIndex.getBitWidth(), 0); bool maxElementsKnown = false; if (const ConstantArrayType *CAT = SemaRef->Context.getAsConstantArrayType(DeclType)) { maxElements = CAT->getSize(); + elementIndex.extOrTrunc(maxElements.getBitWidth()); maxElementsKnown = true; } @@ -300,6 +299,11 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, continue; } + if (elementIndex.getBitWidth() > maxElements.getBitWidth()) + maxElements.extend(elementIndex.getBitWidth()); + else if (elementIndex.getBitWidth() < maxElements.getBitWidth()) + elementIndex.extend(maxElements.getBitWidth()); + // If the array is of incomplete type, keep track of the number of // elements in the initializer. if (!maxElementsKnown && elementIndex > maxElements) @@ -325,7 +329,7 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, if (DeclType->isIncompleteArrayType()) { // If this is an incomplete array type, the actual type needs to // be calculated here. - llvm::APInt Zero(ArraySizeBits, 0); + llvm::APInt Zero(maxElements.getBitWidth(), 0); if (maxElements == Zero) { // Sizing an array implicitly to zero is not allowed by ISO C, // but is supported by GNU. @@ -563,6 +567,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, if (isa(AT)) { llvm::APSInt MaxElements(cast(AT)->getSize(), false); + DesignatedIndex.extOrTrunc(MaxElements.getBitWidth()); if (DesignatedIndex >= MaxElements) { SemaRef->Diag(IndexExpr->getSourceRange().getBegin(), diag::err_array_designator_too_large) diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index cc2c3468edc3..8e5bd43b6c6a 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -112,3 +112,6 @@ struct disklabel_ops { struct disklabel_ops disklabel64_ops = { .labelsize = sizeof(struct disklabel_ops) }; + +// PR clang/3377 +int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 }; diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index abfab37b439f..edaaf64b8be3 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -2,7 +2,9 @@ typedef void (* fp)(void); void foo(void); -fp a[1] = { foo }; + +// PR clang/3377 +fp a[(short int)1] = { foo }; int myArray[5] = {1, 2, 3, 4, 5}; int *myPointer2 = myArray; -- GitLab From 5a63e4cd53330f605e678df608e1af016587883c Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 23 Jan 2009 17:41:22 +0000 Subject: [PATCH 078/682] Another missing LLVM type for objc2's new abi defined. llvm-svn: 62852 --- clang/lib/CodeGen/CGObjCMac.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 9d106816d02d..eb811abd3497 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2960,7 +2960,17 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // const struct _method_list_t * const class_methods; // const struct _protocol_list_t * const protocols; // const struct _prop_list_t * const properties; - // } + // } + CategorynfABITy = llvm::StructType::get(Int8PtrTy, + llvm::PointerType::getUnqual( + ClassnfABITy), + MethodListnfABIPtrTy, + MethodListnfABIPtrTy, + ProtocolListnfABIPtrTy, + PropertyListPtrTy, + NULL); + CGM.getModule().addTypeName("struct._category_t", CategorynfABITy); + } /* *** */ @@ -2972,6 +2982,5 @@ CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { CodeGen::CGObjCRuntime * CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { - return 0; - // return new CGObjCNonFragileABIMac(CGM); + return new CGObjCNonFragileABIMac(CGM); } -- GitLab From 7fa50496f6566b463b70b9f00a244ae6ad15acf1 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 23 Jan 2009 17:48:29 +0000 Subject: [PATCH 079/682] Checked in an oops! llvm-svn: 62853 --- clang/lib/CodeGen/CGObjCMac.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index eb811abd3497..fbd9b3645b0a 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2982,5 +2982,6 @@ CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { CodeGen::CGObjCRuntime * CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { - return new CGObjCNonFragileABIMac(CGM); + return 0; + // return new CGObjCNonFragileABIMac(CGM); } -- GitLab From 9db60a38e9be06f1cef1522028ece1af64e945a1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 18:00:48 +0000 Subject: [PATCH 080/682] Preprocessor doesn't require and IdentifierInfoLookup object. Patch by Axel Naumann! llvm-svn: 62854 --- clang/include/clang/Lex/Preprocessor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 3956725ffa69..2954c676e8db 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -192,7 +192,7 @@ private: // Cached tokens state. public: Preprocessor(Diagnostic &diags, const LangOptions &opts, TargetInfo &target, SourceManager &SM, HeaderSearch &Headers, - IdentifierInfoLookup* IILookup); + IdentifierInfoLookup* IILookup = 0); ~Preprocessor(); -- GitLab From 1f6c7fe6a87583eecb49b00b02fbb529f45bac90 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 18:35:48 +0000 Subject: [PATCH 081/682] This is a follow-up to r62675: Refactor how the preprocessor changes a token from being an tok::identifier to a keyword (e.g. tok::kw_for). Instead of doing this in HandleIdentifier, hoist this common case out into the caller, so that every keyword doesn't have to go through HandleIdentifier. This drops time in HandleIdentifier from 1.25ms to .62ms, and speeds up clang -Eonly with PTH by about 1%. llvm-svn: 62855 --- clang/include/clang/Basic/IdentifierTable.h | 11 ++--------- clang/lib/Lex/Lexer.cpp | 4 ++++ clang/lib/Lex/PTHLexer.cpp | 6 ++++++ clang/lib/Lex/Preprocessor.cpp | 4 ---- clang/lib/Lex/TokenLexer.cpp | 11 ++++++++--- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h index a06e9b10807b..56a6f4184852 100644 --- a/clang/include/clang/Basic/IdentifierTable.h +++ b/clang/include/clang/Basic/IdentifierTable.h @@ -122,14 +122,7 @@ public: /// can be used to cause the lexer to map identifiers to source-language /// tokens. tok::TokenKind getTokenID() const { return (tok::TokenKind)TokenID; } - void setTokenID(tok::TokenKind ID) { - TokenID = ID; - - if (ID != tok::identifier) - NeedsHandleIdentifier = 1; - else - RecomputeNeedsHandleIdentifier(); - } + void setTokenID(tok::TokenKind ID) { TokenID = ID; } /// getPPKeywordID - Return the preprocessor keyword ID for this identifier. /// For example, "define" will return tok::pp_define. @@ -225,7 +218,7 @@ private: void RecomputeNeedsHandleIdentifier() { NeedsHandleIdentifier = (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() | - isExtensionToken()) || getTokenID() != tok::identifier; + isExtensionToken()); } }; diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index fca8fd4eb165..3174a0591745 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -558,6 +558,10 @@ FinishIdentifier: // identifier table. IdentifierInfo *II = PP->LookUpIdentifierInfo(Result, IdStart); + // Change the kind of this identifier to the appropriate token kind, e.g. + // turning "for" into a keyword. + Result.setKind(II->getTokenID()); + // Finally, now that we know we have an identifier, pass this off to the // preprocessor, which may macro expand it or something. if (II->isHandleIdentifierCase()) diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index b0f06271c4fb..ec76a299845b 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -101,7 +101,13 @@ LexNextToken: if (IdentifierID) { MIOpt.ReadToken(); IdentifierInfo *II = PTHMgr.GetIdentifierInfo(IdentifierID-1); + Tok.setIdentifierInfo(II); + + // Change the kind of this identifier to the appropriate token kind, e.g. + // turning "for" into a keyword. + Tok.setKind(II->getTokenID()); + if (II->isHandleIdentifierCase()) PP->HandleIdentifier(Tok); return; diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index e53c392c388b..d0a15e45c414 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -759,10 +759,6 @@ void Preprocessor::HandleIdentifier(Token &Identifier) { if (II.isCPlusPlusOperatorKeyword()) Identifier.setIdentifierInfo(0); - // Change the kind of this identifier to the appropriate token kind, e.g. - // turning "for" into a keyword. - Identifier.setKind(II.getTokenID()); - // If this is an extension token, diagnose its use. // We avoid diagnosing tokens that originate from macro definitions. if (II.isExtensionToken() && Features.C99 && !DisableMacroExpansion) diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index c945843459f4..dd5352c1b616 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -326,9 +326,14 @@ void TokenLexer::Lex(Token &Tok) { } // Handle recursive expansion! - if (Tok.getIdentifierInfo() && !DisableMacroExpansion && - Tok.getIdentifierInfo()->isHandleIdentifierCase()) - PP.HandleIdentifier(Tok); + if (IdentifierInfo *II = Tok.getIdentifierInfo()) { + // Change the kind of this identifier to the appropriate token kind, e.g. + // turning "for" into a keyword. + Tok.setKind(II->getTokenID()); + + if (!DisableMacroExpansion && II->isHandleIdentifierCase()) + PP.HandleIdentifier(Tok); + } // Otherwise, return a normal token. } -- GitLab From 42a8cd37b23e6482f7a6f4c5264d0d39d680142e Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 18:51:09 +0000 Subject: [PATCH 082/682] Handle pointer arithmetic on function pointers. - Clang-generated bitcode crashes LLVM while compiling function pointer addition expression llvm-svn: 62857 --- clang/lib/CodeGen/CGExprScalar.cpp | 33 +++++++++++++++++++++---- clang/test/CodeGen/pointer-arithmetic.c | 21 +++++++++++++--- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index f21373a53831..fc87726a2115 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -872,11 +872,14 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) { // FIXME: What about a pointer to a VLA? Value *Ptr, *Idx; Expr *IdxExp; - if (isa(Ops.LHS->getType())) { // pointer + int + const PointerType *PT; + if ((PT = Ops.E->getLHS()->getType()->getAsPointerType())) { Ptr = Ops.LHS; Idx = Ops.RHS; IdxExp = Ops.E->getRHS(); } else { // int + pointer + PT = Ops.E->getRHS()->getType()->getAsPointerType(); + assert(PT && "Invalid add expr"); Ptr = Ops.RHS; Idx = Ops.LHS; IdxExp = Ops.E->getLHS(); @@ -892,6 +895,17 @@ Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &Ops) { else Idx = Builder.CreateZExt(Idx, IdxType, "idx.ext"); } + + // Explicitly handle GNU void* and function pointer arithmetic + // extensions. The GNU void* casts amount to no-ops since our void* + // type is i8*, but this is future proof. + const QualType ElementType = PT->getPointeeType(); + if (ElementType->isVoidType() || ElementType->isFunctionType()) { + const llvm::Type *i8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + Value *Casted = Builder.CreateBitCast(Ptr, i8Ty); + Value *Res = Builder.CreateGEP(Casted, Idx, "sub.ptr"); + return Builder.CreateBitCast(Res, Ptr->getType()); + } return Builder.CreateGEP(Ptr, Idx, "add.ptr"); } @@ -900,6 +914,8 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { if (!isa(Ops.LHS->getType())) return Builder.CreateSub(Ops.LHS, Ops.RHS, "sub"); + const QualType LHSType = Ops.E->getLHS()->getType(); + const QualType LHSElementType = LHSType->getAsPointerType()->getPointeeType(); if (!isa(Ops.RHS->getType())) { // pointer - int Value *Idx = Ops.RHS; @@ -916,16 +932,23 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &Ops) { Idx = Builder.CreateNeg(Idx, "sub.ptr.neg"); // FIXME: The pointer could point to a VLA. - // The GNU void* - int case is automatically handled here because - // our LLVM type for void* is i8*. + + // Explicitly handle GNU void* and function pointer arithmetic + // extensions. The GNU void* casts amount to no-ops since our + // void* type is i8*, but this is future proof. + if (LHSElementType->isVoidType() || LHSElementType->isFunctionType()) { + const llvm::Type *i8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); + Value *LHSCasted = Builder.CreateBitCast(Ops.LHS, i8Ty); + Value *Res = Builder.CreateGEP(LHSCasted, Idx, "sub.ptr"); + return Builder.CreateBitCast(Res, Ops.LHS->getType()); + } + return Builder.CreateGEP(Ops.LHS, Idx, "sub.ptr"); } else { // pointer - pointer Value *LHS = Ops.LHS; Value *RHS = Ops.RHS; - const QualType LHSType = Ops.E->getLHS()->getType(); - const QualType LHSElementType = LHSType->getAsPointerType()->getPointeeType(); uint64_t ElementSize; // Handle GCC extension for pointer arithmetic on void* types. diff --git a/clang/test/CodeGen/pointer-arithmetic.c b/clang/test/CodeGen/pointer-arithmetic.c index 3133c9effe4e..23a6ab41a1c6 100644 --- a/clang/test/CodeGen/pointer-arithmetic.c +++ b/clang/test/CodeGen/pointer-arithmetic.c @@ -1,7 +1,22 @@ -// RUN: clang -emit-llvm %s -o %t +// RUN: clang -S %s -o %t typedef int Int; -int test1(int *a, Int *b) { return a - b; } +int f0(int *a, Int *b) { return a - b; } -int test2(const char *a, char *b) { return b - a; } +int f1(const char *a, char *b) { return b - a; } + +// GNU extensions +typedef void (*FP)(void); +void *f2(void *a, int b) { return a + b; } +void *f2_1(void *a, int b) { return (a += b); } +void *f3(int a, void *b) { return a + b; } +void *f3_1(int a, void *b) { return (a += b); } +void *f4(void *a, int b) { return a - b; } +void *f4_1(void *a, int b) { return (a -= b); } +FP f5(FP a, int b) { return a + b; } +FP f5_1(FP a, int b) { return (a += b); } +FP f6(int a, FP b) { return a + b; } +FP f6_1(int a, FP b) { return (a += b); } +FP f7(FP a, int b) { return a - b; } +FP f7_1(FP a, int b) { return (a -= b); } -- GitLab From 583cf0ac574d74b2fd05f2ee87ca3785e7406e8d Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 18:58:42 +0000 Subject: [PATCH 083/682] Make sure all of the isUnsigned flags line up when comparing initializer values, to really really fix PR clang/3377 llvm-svn: 62858 --- clang/lib/Sema/SemaInit.cpp | 10 +++++++--- clang/test/Sema/designated-initializers.c | 1 + 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index ba8312b7b52d..aff46ef61d50 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -271,12 +271,13 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, } // We might know the maximum number of elements in advance. - llvm::APSInt maxElements(elementIndex.getBitWidth(), 0); + llvm::APSInt maxElements(elementIndex.getBitWidth(), elementIndex.isUnsigned()); bool maxElementsKnown = false; if (const ConstantArrayType *CAT = SemaRef->Context.getAsConstantArrayType(DeclType)) { maxElements = CAT->getSize(); elementIndex.extOrTrunc(maxElements.getBitWidth()); + elementIndex.setIsUnsigned(maxElements.isUnsigned()); maxElementsKnown = true; } @@ -303,6 +304,7 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, maxElements.extend(elementIndex.getBitWidth()); else if (elementIndex.getBitWidth() < maxElements.getBitWidth()) elementIndex.extend(maxElements.getBitWidth()); + elementIndex.setIsUnsigned(maxElements.isUnsigned()); // If the array is of incomplete type, keep track of the number of // elements in the initializer. @@ -329,7 +331,7 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, if (DeclType->isIncompleteArrayType()) { // If this is an incomplete array type, the actual type needs to // be calculated here. - llvm::APInt Zero(maxElements.getBitWidth(), 0); + llvm::APSInt Zero(maxElements.getBitWidth(), maxElements.isUnsigned()); if (maxElements == Zero) { // Sizing an array implicitly to zero is not allowed by ISO C, // but is supported by GNU. @@ -568,6 +570,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList, if (isa(AT)) { llvm::APSInt MaxElements(cast(AT)->getSize(), false); DesignatedIndex.extOrTrunc(MaxElements.getBitWidth()); + DesignatedIndex.setIsUnsigned(MaxElements.isUnsigned()); if (DesignatedIndex >= MaxElements) { SemaRef->Diag(IndexExpr->getSourceRange().getBegin(), diag::err_array_designator_too_large) @@ -617,7 +620,8 @@ CheckArrayDesignatorExpr(Sema &Self, Expr *Index, llvm::APSInt &Value) { << Index->getSourceRange(); // Make sure this constant expression is non-negative. - llvm::APSInt Zero(llvm::APSInt::getNullValue(Value.getBitWidth()), false); + llvm::APSInt Zero(llvm::APSInt::getNullValue(Value.getBitWidth()), + Value.isUnsigned()); if (Value < Zero) return Self.Diag(Loc, diag::err_array_designator_negative) << Value.toString(10) << Index->getSourceRange(); diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index 8e5bd43b6c6a..3fe5f8484c2d 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -115,3 +115,4 @@ struct disklabel_ops disklabel64_ops = { // PR clang/3377 int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 }; +int a[]= { [sizeof(int)] = 0 }; -- GitLab From 5da47ad57b8e899736015c01823cbb1a10518c30 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 19:03:35 +0000 Subject: [PATCH 084/682] Allow subtraction of function pointer types in C, as a GNU extension. Fixes rdar://problem/6520707 llvm-svn: 62859 --- clang/lib/Sema/SemaExpr.cpp | 11 +++++++++++ clang/test/Sema/pointer-subtract-compat.c | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ab5bd6bd1194..6ec4d4a61f34 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2746,6 +2746,17 @@ QualType Sema::CheckSubtractionOperands(Expr *&lex, Expr *&rex, if (!lpointee->isVoidType()) Diag(Loc, diag::ext_gnu_void_ptr) << lex->getSourceRange() << rex->getSourceRange(); + } else if (rpointee->isFunctionType()) { + if (getLangOptions().CPlusPlus) { + Diag(Loc, diag::err_typecheck_pointer_arith_function_type) + << rex->getType() << rex->getSourceRange(); + return QualType(); + } + + // GNU extension: arithmetic on pointer to function + if (!lpointee->isFunctionType()) + Diag(Loc, diag::ext_gnu_ptr_func_arith) + << lex->getType() << lex->getSourceRange(); } else { Diag(Loc, diag::err_typecheck_sub_ptr_object) << rex->getType() << rex->getSourceRange(); diff --git a/clang/test/Sema/pointer-subtract-compat.c b/clang/test/Sema/pointer-subtract-compat.c index 4ed6abf8af71..9aebe9cdcebb 100644 --- a/clang/test/Sema/pointer-subtract-compat.c +++ b/clang/test/Sema/pointer-subtract-compat.c @@ -4,3 +4,8 @@ typedef const char rchar; int a(char* a, rchar* b) { return a-b; } + +// +void f0(void (*fp)(void)) { + int x = fp - fp; // expected-warning{{arithmetic on pointer to function type 'void (*)(void)' is a GNU extension}} +} -- GitLab From 1275e28dede2fda98c46c1c85892f893af451d01 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 23 Jan 2009 19:10:37 +0000 Subject: [PATCH 085/682] Fold x-0 to x in unsafe-fp-math mode. This comes up in the testcase from PR3376, and in fact is sufficient to completely avoid the problem in that testcase. There's an underlying problem though; TLI.isOperationLegal considers Custom to be Legal, which might be ok in some cases, but that's what DAGCombiner is using in many places to test if something is legal when LegalOperations is true. When DAGCombiner is running after legalize, this isn't sufficient. I'll address this in a separate commit. llvm-svn: 62860 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 3 +++ .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 25 ++++++++++++------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 7e8e46fba50f..e4b24f1aaff6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3853,6 +3853,9 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { // fold (fsub c1, c2) -> c1-c2 if (N0CFP && N1CFP && VT != MVT::ppcf128) return DAG.getNode(ISD::FSUB, VT, N0, N1); + // fold (A-0) -> A + if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) + return N0; // fold (0-B) -> -B if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) { if (isNegatibleForFree(N1, LegalOperations)) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 29744862089d..6d1fdd23407d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2402,15 +2402,22 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, case ISD::FMUL: case ISD::FDIV: case ISD::FREM: - if (UnsafeFPMath && Opcode == ISD::FADD) { - // 0+x --> x - if (ConstantFPSDNode *CFP = dyn_cast(N1)) - if (CFP->getValueAPF().isZero()) - return N2; - // x+0 --> x - if (ConstantFPSDNode *CFP = dyn_cast(N2)) - if (CFP->getValueAPF().isZero()) - return N1; + if (UnsafeFPMath) { + if (Opcode == ISD::FADD) { + // 0+x --> x + if (ConstantFPSDNode *CFP = dyn_cast(N1)) + if (CFP->getValueAPF().isZero()) + return N2; + // x+0 --> x + if (ConstantFPSDNode *CFP = dyn_cast(N2)) + if (CFP->getValueAPF().isZero()) + return N1; + } else if (Opcode == ISD::FSUB) { + // x-0 --> x + if (ConstantFPSDNode *CFP = dyn_cast(N2)) + if (CFP->getValueAPF().isZero()) + return N1; + } } assert(N1.getValueType() == N2.getValueType() && N1.getValueType() == VT && "Binary operator types must match!"); -- GitLab From dd7aa3789576b484e3ae7e5fd0ba53984b5ce000 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 23 Jan 2009 19:13:31 +0000 Subject: [PATCH 086/682] Empty DIType represents void. In this case no need to construct any type DIE. llvm-svn: 62861 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index fd59533eeff7..6bbb5bb9b769 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1662,10 +1662,8 @@ private: /// AddType - Add a new type attribute to the specified entity. void AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) { - if (Ty.isNull()) { - AddBasicType(Entity, DW_Unit, "", DW_ATE_signed, sizeof(int32_t)); + if (Ty.isNull()) return; - } // Check for pre-existence. DIEntry *&Slot = DW_Unit->getDIEntrySlotFor(Ty.getGV()); -- GitLab From 617001d84279f075a09e236f7002d58572c1192b Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Fri, 23 Jan 2009 19:27:28 +0000 Subject: [PATCH 087/682] Add support for deleting a module provider from a JIT in such a way that it does not cause the owned module to be fully materialized. llvm-svn: 62864 --- .../llvm/ExecutionEngine/ExecutionEngine.h | 8 +++++++- llvm/lib/ExecutionEngine/ExecutionEngine.cpp | 20 ++++++++++++++++++- llvm/lib/ExecutionEngine/JIT/JIT.cpp | 13 ++++++++++++ llvm/lib/ExecutionEngine/JIT/JIT.h | 9 +++++++++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h index a26c755ee76a..3559ede31c34 100644 --- a/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h +++ b/llvm/include/llvm/ExecutionEngine/ExecutionEngine.h @@ -143,10 +143,16 @@ public: /// removeModuleProvider - Remove a ModuleProvider from the list of modules. - /// Release module from ModuleProvider. + /// Relases the Module from the ModuleProvider, materializing it in the + /// process, and returns the materialized Module. virtual Module* removeModuleProvider(ModuleProvider *P, std::string *ErrInfo = 0); + /// deleteModuleProvider - Remove a ModuleProvider from the list of modules, + /// and deletes the ModuleProvider and owned Module. Avoids materializing + /// the underlying module. + virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0); + /// FindFunctionNamed - Search all of the active modules to find the one that /// defines FnName. This is very slow operation and shouldn't be used for /// general code. diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index d1a406c99607..9fea1f5753f8 100644 --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -59,7 +59,8 @@ char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) { } /// removeModuleProvider - Remove a ModuleProvider from the list of modules. -/// Release module from ModuleProvider. +/// Relases the Module from the ModuleProvider, materializing it in the +/// process, and returns the materialized Module. Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P, std::string *ErrInfo) { for(SmallVector::iterator I = Modules.begin(), @@ -74,6 +75,23 @@ Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P, return NULL; } +/// deleteModuleProvider - Remove a ModuleProvider from the list of modules, +/// and deletes the ModuleProvider and owned Module. Avoids materializing +/// the underlying module. +void ExecutionEngine::deleteModuleProvider(ModuleProvider *P, + std::string *ErrInfo) { + for(SmallVector::iterator I = Modules.begin(), + E = Modules.end(); I != E; ++I) { + ModuleProvider *MP = *I; + if (MP == P) { + Modules.erase(I); + clearGlobalMappingsFromModule(MP->getModule()); + delete MP; + return; + } + } +} + /// FindFunctionNamed - Search all of the active modules to find the one that /// defines FnName. This is very slow operation and shouldn't be used for /// general code. diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/llvm/lib/ExecutionEngine/JIT/JIT.cpp index fd69e69c44d5..7fc7b2fdceb4 100644 --- a/llvm/lib/ExecutionEngine/JIT/JIT.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -297,6 +297,19 @@ Module *JIT::removeModuleProvider(ModuleProvider *MP, std::string *E) { return result; } +/// deleteModuleProvider - Remove a ModuleProvider from the list of modules, +/// and deletes the ModuleProvider and owned Module. Avoids materializing +/// the underlying module. +void JIT::deleteModuleProvider(ModuleProvider *MP, std::string *E) { + ExecutionEngine::deleteModuleProvider(MP, E); + + MutexGuard locked(lock); + if (Modules.empty()) { + delete jitstate; + jitstate = 0; + } +} + /// run - Start execution with the specified function and arguments. /// GenericValue JIT::runFunction(Function *F, diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.h b/llvm/lib/ExecutionEngine/JIT/JIT.h index b92999960331..7c085e360e20 100644 --- a/llvm/lib/ExecutionEngine/JIT/JIT.h +++ b/llvm/lib/ExecutionEngine/JIT/JIT.h @@ -77,9 +77,18 @@ public: } virtual void addModuleProvider(ModuleProvider *MP); + + /// removeModuleProvider - Remove a ModuleProvider from the list of modules. + /// Relases the Module from the ModuleProvider, materializing it in the + /// process, and returns the materialized Module. virtual Module *removeModuleProvider(ModuleProvider *MP, std::string *ErrInfo = 0); + /// deleteModuleProvider - Remove a ModuleProvider from the list of modules, + /// and deletes the ModuleProvider and owned Module. Avoids materializing + /// the underlying module. + virtual void deleteModuleProvider(ModuleProvider *P,std::string *ErrInfo = 0); + /// runFunction - Start execution with the specified function and arguments. /// virtual GenericValue runFunction(Function *F, -- GitLab From eb61fcf2a1f949b70264c6a86ea7559f7ac3ed76 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Fri, 23 Jan 2009 19:40:15 +0000 Subject: [PATCH 088/682] Simplify the logic of getting hold of a PHI predecessor block. There is now a direct way from value-use-iterator to incoming block in PHINode's API. This way we avoid the iterator->index->iterator trip, and especially the costly getOperandNo() invocation. Additionally there is now an assertion that the iterator really refers to one of the PHI's Uses. llvm-svn: 62869 --- llvm/include/llvm/Analysis/LoopInfo.h | 3 +-- llvm/include/llvm/Instructions.h | 8 ++++++++ llvm/lib/Transforms/IPO/GlobalOpt.cpp | 3 +-- llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp | 3 +-- llvm/lib/Transforms/Utils/LCSSA.cpp | 6 ++---- llvm/lib/VMCore/Instruction.cpp | 3 +-- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/llvm/include/llvm/Analysis/LoopInfo.h b/llvm/include/llvm/Analysis/LoopInfo.h index 7aa325a9d1d8..a1bac6639077 100644 --- a/llvm/include/llvm/Analysis/LoopInfo.h +++ b/llvm/include/llvm/Analysis/LoopInfo.h @@ -482,8 +482,7 @@ public: ++UI) { BlockT *UserBB = cast(*UI)->getParent(); if (PHINode *P = dyn_cast(*UI)) { - unsigned OperandNo = UI.getOperandNo(); - UserBB = P->getIncomingBlock(OperandNo/2); + UserBB = P->getIncomingBlock(UI); } // Check the current block, as a fast-path. Most values are used in diff --git a/llvm/include/llvm/Instructions.h b/llvm/include/llvm/Instructions.h index 841cf9cff27f..fbf376afd5d4 100644 --- a/llvm/include/llvm/Instructions.h +++ b/llvm/include/llvm/Instructions.h @@ -1943,6 +1943,14 @@ public: return i*2; } + /// getIncomingBlock - Return incoming basic block corresponding + /// to value use iterator + /// + template + BasicBlock *getIncomingBlock(value_use_iterator I) const { + assert(this == *I && "Iterator doesn't point to PHI's Uses?"); + return static_cast((&I.getUse() + 1)->get()); + } /// getIncomingBlock - Return incoming basic block number x /// BasicBlock *getIncomingBlock(unsigned i) const { diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 99fc7317b1fa..7f636c927015 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -988,8 +988,7 @@ static void ReplaceUsesOfMallocWithGlobal(Instruction *Alloc, } else if (PHINode *PN = dyn_cast(U)) { // Insert the load in the corresponding predecessor, not right before the // PHI. - unsigned PredNo = Alloc->use_begin().getOperandNo()/2; - InsertPt = PN->getIncomingBlock(PredNo)->getTerminator(); + InsertPt = PN->getIncomingBlock(Alloc->use_begin())->getTerminator(); } else if (isa(U)) { // Must be bitcast between the malloc and store to initialize the global. ReplaceUsesOfMallocWithGlobal(U, GV); diff --git a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp index 59c6586532c0..0a1c641e2bf4 100644 --- a/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp +++ b/llvm/lib/Transforms/Scalar/CodeGenPrepare.cpp @@ -459,8 +459,7 @@ static bool OptimizeNoopCopyExpression(CastInst *CI, const TargetLowering &TLI){ // appropriate predecessor block. BasicBlock *UserBB = User->getParent(); if (PHINode *PN = dyn_cast(User)) { - unsigned OpVal = UI.getOperandNo()/2; - UserBB = PN->getIncomingBlock(OpVal); + UserBB = PN->getIncomingBlock(UI); } // Preincrement use iterator so we don't invalidate it. diff --git a/llvm/lib/Transforms/Utils/LCSSA.cpp b/llvm/lib/Transforms/Utils/LCSSA.cpp index 385588861154..9cd7e69557ad 100644 --- a/llvm/lib/Transforms/Utils/LCSSA.cpp +++ b/llvm/lib/Transforms/Utils/LCSSA.cpp @@ -175,8 +175,7 @@ void LCSSA::ProcessInstruction(Instruction *Instr, UI != E;) { BasicBlock *UserBB = cast(*UI)->getParent(); if (PHINode *P = dyn_cast(*UI)) { - unsigned OperandNo = UI.getOperandNo(); - UserBB = P->getIncomingBlock(OperandNo/2); + UserBB = P->getIncomingBlock(UI); } // If the user is in the loop, don't rewrite it! @@ -212,8 +211,7 @@ void LCSSA::getLoopValuesUsedOutsideLoop(Loop *L, ++UI) { BasicBlock *UserBB = cast(*UI)->getParent(); if (PHINode* p = dyn_cast(*UI)) { - unsigned OperandNo = UI.getOperandNo(); - UserBB = p->getIncomingBlock(OperandNo/2); + UserBB = p->getIncomingBlock(UI); } if (*BB != UserBB && !inLoop(UserBB)) { diff --git a/llvm/lib/VMCore/Instruction.cpp b/llvm/lib/VMCore/Instruction.cpp index b09ab93aa11d..f33c1a23f238 100644 --- a/llvm/lib/VMCore/Instruction.cpp +++ b/llvm/lib/VMCore/Instruction.cpp @@ -278,8 +278,7 @@ bool Instruction::isUsedOutsideOfBlock(const BasicBlock *BB) const { continue; } - unsigned UseOperand = UI.getOperandNo(); - if (PN->getIncomingBlock(UseOperand/2) != BB) + if (PN->getIncomingBlock(UI) != BB) return true; } return false; -- GitLab From 505f751451ef2615daf8be3345e14f78b3e9f9a0 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 19:40:54 +0000 Subject: [PATCH 089/682] ccc: Another batch of long argument translations. - Again turned up a few which don't do anything sensible. llvm-svn: 62870 --- clang/tools/ccc/ccclib/Arguments.py | 74 +++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 5 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 50415bf706e7..6637f73b7c45 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -553,7 +553,9 @@ class OptionParser: self.XpreprocessorOption = self.addOption(SeparateOption('-Xpreprocessor')) self.addOption(CommaJoinedOption('-Wl,', isLinkerInput=True)) - self.addOption(SeparateOption('-Xlinker', isLinkerInput=True, noOptAsInput=True)) + self.XlinkerOption = self.addOption(SeparateOption('-Xlinker', + isLinkerInput=True, + noOptAsInput=True)) #### # Bring on the random garbage. @@ -587,7 +589,11 @@ class OptionParser: self.dylinkerOption = self.addOption(FlagOption('-dylinker')) self.iGroup = OptionGroup('-i') - self.addOption(JoinedOrSeparateOption('-idirafter', self.iGroup)) + self.idirafterOption = self.addOption(JoinedOrSeparateOption('-idirafter', self.iGroup)) + self.imacrosOption = self.addOption(JoinedOrSeparateOption('-imacros', self.iGroup)) + self.iprefixOption = self.addOption(JoinedOrSeparateOption('-iprefix', self.iGroup)) + self.iwithprefixOption = self.addOption(JoinedOrSeparateOption('-iwithprefix', self.iGroup)) + self.iwithprefixbeforeOption = self.addOption(JoinedOrSeparateOption('-iwithprefixbefore', self.iGroup)) self.addOption(JoinedOrSeparateOption('-iquote', self.iGroup)) self.isysrootOption = self.addOption(JoinedOrSeparateOption('-isysroot', self.iGroup)) self.includeOption = self.addOption(JoinedOrSeparateOption('-include', self.iGroup)) @@ -870,8 +876,9 @@ class OptionParser: self.pthreadOption = self.addOption(FlagOption('-pthread')) self.addOption(FlagOption('-pthreads')) - # Version control - self.addOption(JoinedOrSeparateOption('-B')) + # Version control. + # FIXME: Figure out what to do about these. + self.BOption = self.addOption(JoinedOrSeparateOption('-B')) self.addOption(JoinedOrSeparateOption('-V')) self.addOption(JoinedOrSeparateOption('-b')) @@ -940,7 +947,8 @@ class OptionParser: self.addOption(FlagOption('--write-dependencies', alias=self.MDOption)) self.addOption(FlagOption('--write-user-dependencies', alias=self.MMDOption)) - # Long options with joined & separate forms. + # Long options with joined & separate forms (coercing to + # joined form). self.addOption(SeparateOption('--assert', alias=self.AOption)) self.addOption(JoinedOption('--assert=', alias=self.AOption, @@ -988,6 +996,62 @@ class OptionParser: self.addOption(SeparateOption('--undefine-macro', alias=self.UOption, forceJoinedRender=True)) + # Long options with joined & separate forms (coercing to + # separate form). + +# self.addOption(JoinedOption('--dump=', alias=self.dOption, +# forceSeparateRender=True)) +# self.addOption(SeparateOption('--dump', alias=self.dOption)) +# self.addOption(JoinedOption('--dumpbase=', alias=self.dumpbaseOption, +# forceSeparateRender=True)) +# self.addOption(SeparateOption('--dumpbase', alias=self.dumpbaseOption)) +# self.addOption(JoinedOption('--for-assembler=', alias=self.WaOption, +# forceSeparateRender=True)) +# self.addOption(SeparateOption('--for-assembler', alias=self.WaOption)) + self.addOption(JoinedOption('--for-linker=', alias=self.XlinkerOption, + forceSeparateRender=True, + isLinkerInput=True, + noOptAsInput=True)) + self.addOption(SeparateOption('--for-linker', alias=self.XlinkerOption, + isLinkerInput=True, + noOptAsInput=True)) + self.addOption(JoinedOption('--force-link=', alias=self.uOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--force-link', alias=self.uOption)) + self.addOption(JoinedOption('--imacros=', alias=self.imacrosOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--imacros', alias=self.imacrosOption)) + self.addOption(JoinedOption('--include=', alias=self.includeOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--include', alias=self.includeOption)) + self.addOption(JoinedOption('--include-directory-after=', alias=self.idirafterOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--include-directory-after', alias=self.idirafterOption)) + self.addOption(JoinedOption('--include-prefix=', alias=self.iprefixOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--include-prefix', alias=self.iprefixOption)) + self.addOption(JoinedOption('--include-with-prefix=', alias=self.iwithprefixOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--include-with-prefix', alias=self.iwithprefixOption)) + self.addOption(JoinedOption('--include-with-prefix-before=', alias=self.iwithprefixbeforeOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--include-with-prefix-before', alias=self.iwithprefixbeforeOption)) + self.addOption(JoinedOption('--include-with-prefix-after=', alias=self.iwithprefixOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--include-with-prefix-after', alias=self.iwithprefixOption)) + self.addOption(JoinedOption('--language=', alias=self.xOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--language', alias=self.xOption)) + self.addOption(JoinedOption('--library-directory=', alias=self.LOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--library-directory', alias=self.LOption)) + self.addOption(JoinedOption('--output=', alias=self.oOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--output', alias=self.oOption)) + self.addOption(JoinedOption('--prefix=', alias=self.BOption, + forceSeparateRender=True)) + self.addOption(SeparateOption('--prefix', alias=self.BOption)) + def addOption(self, opt): self.options.append(opt) return opt -- GitLab From 099243aa9e421579401c0a4b369c64c204225ea2 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 23 Jan 2009 20:06:20 +0000 Subject: [PATCH 090/682] When using -analyzer-output-plist always output a plist file even if it contains no error reports. llvm-svn: 62871 --- clang/Driver/Analyses.def | 6 +++--- clang/Driver/AnalysisConsumer.cpp | 11 ++++++++++- clang/Driver/AnalysisConsumer.h | 2 +- clang/Driver/clang.cpp | 2 +- clang/lib/Driver/PlistDiagnostics.cpp | 25 ++++++++++++++----------- 5 files changed, 29 insertions(+), 17 deletions(-) diff --git a/clang/Driver/Analyses.def b/clang/Driver/Analyses.def index 1f702cc0e9c2..3beaa73bcb73 100644 --- a/clang/Driver/Analyses.def +++ b/clang/Driver/Analyses.def @@ -56,11 +56,11 @@ ANALYSIS_STORE(BasicStore, "basic", "Use basic analyzer store") ANALYSIS_STORE(RegionStore, "region", "Use region-based analyzer store") #ifndef ANALYSIS_DIAGNOSTICS -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN) +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE) #endif -ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", CreateHTMLDiagnosticClient) -ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient) +ANALYSIS_DIAGNOSTICS(HTML, "html", "Output analysis results using HTML", CreateHTMLDiagnosticClient, false) +ANALYSIS_DIAGNOSTICS(PLIST, "plist", "Output analysis results using Plists", CreatePlistDiagnosticClient, true) #undef ANALYSIS #undef ANALYSIS_STORE diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp index 1ada515c10e0..236cc1d865dc 100644 --- a/clang/Driver/AnalysisConsumer.cpp +++ b/clang/Driver/AnalysisConsumer.cpp @@ -207,7 +207,7 @@ namespace { if (C.PD.get() == 0 && !C.HTMLDir.empty()) { switch (C.DC) { default: -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN)\ +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\ case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break; #include "Analyses.def" } @@ -288,6 +288,15 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break; CreateConstraintMgr = ManagerRegistry::ConstraintMgrCreator; else CreateConstraintMgr = CreateBasicConstraintManager; + + // Some DiagnosticClients should be created all the time instead of + // lazily. Create those now. + switch (C.DC) { + default: break; +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATEFN, AUTOCREATE)\ +case PD_##NAME: if (AUTOCREATE) getPathDiagnosticClient(); break; +#include "Analyses.def" + } } }; diff --git a/clang/Driver/AnalysisConsumer.h b/clang/Driver/AnalysisConsumer.h index 27c8e6e07ab0..1e0824022062 100644 --- a/clang/Driver/AnalysisConsumer.h +++ b/clang/Driver/AnalysisConsumer.h @@ -29,7 +29,7 @@ NumStores }; enum AnalysisDiagClients { -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN) PD_##NAME, +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREAT) PD_##NAME, #include "Analyses.def" NUM_ANALYSIS_DIAG_CLIENTS }; diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index cf58f34e7c99..cc3788b5f3f7 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -239,7 +239,7 @@ static llvm::cl::opt AnalysisDiagOpt(llvm::cl::desc("SCA Output Options:"), llvm::cl::init(PD_HTML), llvm::cl::values( -#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN)\ +#define ANALYSIS_DIAGNOSTICS(NAME, CMDFLAG, DESC, CREATFN, AUTOCREATE)\ clEnumValN(PD_##NAME, "analyzer-output-" CMDFLAG, DESC), #include "Analyses.def" clEnumValEnd)); diff --git a/clang/lib/Driver/PlistDiagnostics.cpp b/clang/lib/Driver/PlistDiagnostics.cpp index ab5b5a394ab6..72d64ed1a88f 100644 --- a/clang/lib/Driver/PlistDiagnostics.cpp +++ b/clang/lib/Driver/PlistDiagnostics.cpp @@ -50,17 +50,17 @@ clang::CreatePlistDiagnosticClient(const std::string& s, } static void AddFID(FIDMap &FIDs, llvm::SmallVectorImpl &V, - SourceManager& SM, SourceLocation L) { + SourceManager* SM, SourceLocation L) { - FileID FID = SM.getFileID(SM.getInstantiationLoc(L)); + FileID FID = SM->getFileID(SM->getInstantiationLoc(L)); FIDMap::iterator I = FIDs.find(FID); if (I != FIDs.end()) return; FIDs[FID] = V.size(); V.push_back(FID); } -static unsigned GetFID(const FIDMap& FIDs, SourceManager& SM, SourceLocation L){ - FileID FID = SM.getFileID(SM.getInstantiationLoc(L)); +static unsigned GetFID(const FIDMap& FIDs, SourceManager* SM, SourceLocation L){ + FileID FID = SM->getFileID(SM->getInstantiationLoc(L)); FIDMap::const_iterator I = FIDs.find(FID); assert(I != FIDs.end()); return I->second; @@ -72,21 +72,21 @@ static llvm::raw_ostream& Indent(llvm::raw_ostream& o, const unsigned indent) { return o; } -static void EmitLocation(llvm::raw_ostream& o, SourceManager& SM, +static void EmitLocation(llvm::raw_ostream& o, SourceManager* SM, SourceLocation L, const FIDMap& FM, const unsigned indent) { Indent(o, indent) << "\n"; Indent(o, indent) << " line" - << SM.getInstantiationLineNumber(L) << "\n"; + << SM->getInstantiationLineNumber(L) << "\n"; Indent(o, indent) << " col" - << SM.getInstantiationColumnNumber(L) << "\n"; + << SM->getInstantiationColumnNumber(L) << "\n"; Indent(o, indent) << " file" << GetFID(FM, SM, L) << "\n"; Indent(o, indent) << "\n"; } -static void EmitRange(llvm::raw_ostream& o, SourceManager& SM, SourceRange R, +static void EmitRange(llvm::raw_ostream& o, SourceManager* SM, SourceRange R, const FIDMap& FM, const unsigned indent) { Indent(o, indent) << "\n"; @@ -96,7 +96,7 @@ static void EmitRange(llvm::raw_ostream& o, SourceManager& SM, SourceRange R, } static void ReportDiag(llvm::raw_ostream& o, const PathDiagnosticPiece& P, - const FIDMap& FM, SourceManager& SM) { + const FIDMap& FM, SourceManager* SM) { unsigned indent = 2; Indent(o, indent) << "\n"; @@ -154,7 +154,10 @@ PlistDiagnostics::~PlistDiagnostics() { // ranges of the diagnostics. FIDMap FM; llvm::SmallVector Fids; - SourceManager& SM = (*BatchedDiags.begin())->begin()->getLocation().getManager(); + SourceManager* SM = 0; + + if (!BatchedDiags.empty()) + SM = &(*BatchedDiags.begin())->begin()->getLocation().getManager(); for (std::vector::iterator DI = BatchedDiags.begin(), DE = BatchedDiags.end(); DI != DE; ++DI) { @@ -195,7 +198,7 @@ PlistDiagnostics::~PlistDiagnostics() { for (llvm::SmallVectorImpl::iterator I=Fids.begin(), E=Fids.end(); I!=E; ++I) - o << " " << SM.getFileEntryForID(*I)->getName() << "\n"; + o << " " << SM->getFileEntryForID(*I)->getName() << "\n"; o << " \n" " diagnostics\n" -- GitLab From 3d5d14ea15eee48eb846c079d7efee296f53048c Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 23 Jan 2009 20:08:16 +0000 Subject: [PATCH 091/682] ccc: Finish definition of long argument translations. - However, these last ones do not actually work; the issue is that they translate to batches of options and need to be reparsed. For now we just give an unsupported error on them. llvm-svn: 62872 --- clang/tools/ccc/ccclib/Arguments.py | 48 ++++++++++++++++++++++++----- clang/tools/ccc/ccclib/Tools.py | 2 +- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 6637f73b7c45..8f3e282967e1 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -17,7 +17,8 @@ class Option(object): def __init__(self, name, group=None, alias=None, isLinkerInput=False, noOptAsInput=False, forceSeparateRender=False, - forceJoinedRender=False): + forceJoinedRender=False, + unsupported=False): assert group is None or isinstance(group, OptionGroup) # Multi-level aliases are not supported, and alias options # cannot have groups. This just simplifies option tracking, it @@ -32,6 +33,7 @@ class Option(object): self.noOptAsInput = noOptAsInput self.forceSeparateRender = forceSeparateRender self.forceJoinedRender = forceJoinedRender + self.unsupported = unsupported def getUnaliasedOption(self): if self.alias: @@ -446,6 +448,9 @@ class ArgList(object): return iter(self.args) def append(self, arg): + if arg.opt.unsupported: + raise InvalidArgumentsError('option %r is unsupported' % arg.opt.name) + self.args.append(arg) opt = arg.opt @@ -814,7 +819,7 @@ class OptionParser: self.f_unwindTablesOption = self.addOption(FlagOption('-funwind-tables', self.fGroup)) self.f_writableStringsOption = self.addOption(FlagOption('-fwritable-strings', self.fGroup)) self.f_zeroInitializedInBssOption = self.addOption(FlagOption('-fzero-initialized-in-bss', self.fGroup)) - self.addOption(JoinedOption('-f', self.fGroup)) + self.fOption = self.addOption(JoinedOption('-f', self.fGroup)) self.coverageOption = self.addOption(FlagOption('-coverage')) @@ -835,9 +840,9 @@ class OptionParser: # Ugh. Need to disambiguate our naming convetion. -m x goes to # the linker sometimes, wheres -mxxxx is used for a variety of - # other things. - self.mOption = self.addOption(SeparateOption('-m')) - self.addOption(JoinedOption('-m', self.mGroup)) + # other things. + self.mSeparate = self.addOption(SeparateOption('-m', self.mGroup)) + self.mJoined = self.addOption(JoinedOption('-m', self.mGroup)) # FIXME: Why does Darwin send -a* to cc1? self.aGroup = OptionGroup('-a') @@ -974,8 +979,8 @@ class OptionParser: self.addOption(JoinedOption('--include-directory=', alias=self.IOption)) self.addOption(SeparateOption('--include-directory', alias=self.IOption, forceJoinedRender=True)) - self.addOption(JoinedOption('--machine=', alias=self.mOption)) - self.addOption(SeparateOption('--machine', alias=self.mOption, + self.addOption(JoinedOption('--machine=', alias=self.mJoined)) + self.addOption(SeparateOption('--machine', alias=self.mJoined, forceJoinedRender=True)) self.addOption(JoinedOption('--output-class-directory=', alias=self.f_outputClassDirOption)) self.addOption(SeparateOption('--output-class-directory', alias=self.f_outputClassDirOption, @@ -1052,6 +1057,35 @@ class OptionParser: forceSeparateRender=True)) self.addOption(SeparateOption('--prefix', alias=self.BOption)) + # Long options with joined forms. gcc's handling of '=' for + # long forms makes these a bit odd. + # + # FIXME: We do not currently support these options. The + # problem is that they need to be reparsed in their translated + # form; they need to map to the correct option and we have to + # find a way to do so without replicating all the declared + # names. + self.addOption(JoinedOption('--debug=', alias=self.gOption, + unsupported=True)) + self.addOption(FlagOption('--debug', alias=self.gOption, + unsupported=True)) + self.addOption(JoinedOption('--machine-=', alias=self.mJoined, + unsupported=True)) + self.addOption(JoinedOption('--machine-', alias=self.mJoined, + unsupported=True)) + self.addOption(JoinedOption('--optimize=', alias=self.OOption, + unsupported=True)) + self.addOption(FlagOption('--optimize', alias=self.OOption, + unsupported=True)) + self.addOption(JoinedOption('--warn-=', alias=self.WOption, + unsupported=True)) + self.addOption(JoinedOption('--warn-', alias=self.WOption, + unsupported=True)) + + # Ugh. + self.addOption(JoinedOption('--', alias=self.fOption, + unsupported=True)) + def addOption(self, opt): self.options.append(opt) return opt diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py index b719b8644205..8b3ee744bb57 100644 --- a/clang/tools/ccc/ccclib/Tools.py +++ b/clang/tools/ccc/ccclib/Tools.py @@ -996,7 +996,7 @@ class Darwin_X86_LinkTool(Tool): arglist.addAllArgs(cmd_args, arglist.parser.uGroup) arglist.addAllArgs(cmd_args, arglist.parser.AOption) arglist.addLastArg(cmd_args, arglist.parser.eOption) - arglist.addAllArgs(cmd_args, arglist.parser.mOption) + arglist.addAllArgs(cmd_args, arglist.parser.mSeparate) arglist.addAllArgs(cmd_args, arglist.parser.rOption) cmd_args.extend(arglist.render(output)) -- GitLab From ea06ec1cade1d256a0f2b15e0aebd8ab0fbcbe33 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 23 Jan 2009 20:28:53 +0000 Subject: [PATCH 092/682] Added virtual method DiagnosticClient::IncludeInDiagnosticCounts(). This is used by Diagnostics to determine if a diagnostic sent to a given DiagnosticClient should be included in the count of diagnostics. The default implementation of this method returns 'true'. Implemented DiagCollector::IncludeInDiagnosticCounts() to return 'false' so that the batching of diagnostics for use with BugReporter doesn't mess up the count of real diagnostics. llvm-svn: 62873 --- .../Analysis/PathSensitive/BugReporter.h | 46 ++----------------- clang/include/clang/Basic/Diagnostic.h | 6 +++ clang/lib/Analysis/BugReporter.cpp | 42 +++++++++++++++++ clang/lib/Basic/Diagnostic.cpp | 8 +++- 4 files changed, 59 insertions(+), 43 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h index 5613ad839bea..ba6f25396388 100644 --- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/clang/include/clang/Analysis/PathSensitive/BugReporter.h @@ -305,50 +305,12 @@ public: virtual ~DiagCollector() {} - virtual void HandleDiagnostic(Diagnostic::Level DiagLevel, - const DiagnosticInfo &Info) { - - // FIXME: Use a map from diag::kind to BugType, instead of having just - // one BugType. - const char *Desc = Info.getDiags()->getDescription(Info.getID()); - Reports.push_back(DiagBugReport(Desc, D, Info.getLocation())); - DiagBugReport& R = Reports.back(); - - for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) - R.addRange(Info.getRange(i)); - - // FIXME: This is losing/ignoring formatting. - for (unsigned i = 0, e = Info.getNumArgs(); i != e; ++i) { - switch (Info.getArgKind(i)) { - case Diagnostic::ak_std_string: - R.addString(Info.getArgStdStr(i)); - break; - case Diagnostic::ak_c_string: - R.addString(Info.getArgCStr(i)); - break; - case Diagnostic::ak_sint: - R.addString(llvm::itostr(Info.getArgSInt(i))); - break; - case Diagnostic::ak_uint: - R.addString(llvm::utostr_32(Info.getArgUInt(i))); - break; - case Diagnostic::ak_identifierinfo: - R.addString(Info.getArgIdentifier(i)->getName()); - break; - case Diagnostic::ak_qualtype: - case Diagnostic::ak_declarationname: { - llvm::SmallString<64> Str; - Info.getDiags()->ConvertArgToString(Info.getArgKind(i), - Info.getRawArg(i), 0, 0, 0, 0, Str); - R.addString(std::string(Str.begin(), Str.end())); - break; - } - } - } - } + bool IncludeInDiagnosticCounts() const { return false; } - // Iterators. + void HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info); + // Iterators. typedef std::list::iterator iterator; iterator begin() { return Reports.begin(); } iterator end() { return Reports.end(); } diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index 15883941903b..a78f73331574 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -484,6 +484,12 @@ public: class DiagnosticClient { public: virtual ~DiagnosticClient(); + + /// IncludeInDiagnosticCounts - This method (whose default implementation + /// returns true) indicates whether the diagnostics handled by this + /// DiagnosticClient should be included in the number of diagnostics + /// reported by Diagnostic. + virtual bool IncludeInDiagnosticCounts() const; /// HandleDiagnostic - Handle this diagnostic, reporting it to the user or /// capturing it to a log as needed. diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index adb3325f53dc..e3735670cf63 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -823,4 +823,46 @@ void BugReporter::EmitBasicReport(const char* name, const char* category, for (DiagCollector::iterator I = C.begin(), E = C.end(); I != E; ++I) EmitWarning(*I); } + +void DiagCollector::HandleDiagnostic(Diagnostic::Level DiagLevel, + const DiagnosticInfo &Info) { + + // FIXME: Use a map from diag::kind to BugType, instead of having just + // one BugType. + const char *Desc = Info.getDiags()->getDescription(Info.getID()); + Reports.push_back(DiagBugReport(Desc, D, Info.getLocation())); + DiagBugReport& R = Reports.back(); + + for (unsigned i = 0, e = Info.getNumRanges(); i != e; ++i) + R.addRange(Info.getRange(i)); + + // FIXME: This is losing/ignoring formatting. + for (unsigned i = 0, e = Info.getNumArgs(); i != e; ++i) { + switch (Info.getArgKind(i)) { + case Diagnostic::ak_std_string: + R.addString(Info.getArgStdStr(i)); + break; + case Diagnostic::ak_c_string: + R.addString(Info.getArgCStr(i)); + break; + case Diagnostic::ak_sint: + R.addString(llvm::itostr(Info.getArgSInt(i))); + break; + case Diagnostic::ak_uint: + R.addString(llvm::utostr_32(Info.getArgUInt(i))); + break; + case Diagnostic::ak_identifierinfo: + R.addString(Info.getArgIdentifier(i)->getName()); + break; + case Diagnostic::ak_qualtype: + case Diagnostic::ak_declarationname: { + llvm::SmallString<64> Str; + Info.getDiags()->ConvertArgToString(Info.getArgKind(i), + Info.getRawArg(i), 0, 0, 0, 0, Str); + R.addString(std::string(Str.begin(), Str.end())); + break; + } + } + } +} diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 340ef28846c7..2271095b5963 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -255,7 +255,7 @@ void Diagnostic::ProcessDiag() { // Finally, report it. Client->HandleDiagnostic(DiagLevel, Info); - ++NumDiagnostics; + if (Client->IncludeInDiagnosticCounts()) ++NumDiagnostics; } @@ -551,3 +551,9 @@ FormatDiagnostic(llvm::SmallVectorImpl &OutStr) const { } } } + +/// IncludeInDiagnosticCounts - This method (whose default implementation +/// returns true) indicates whether the diagnostics handled by this +/// DiagnosticClient should be included in the number of diagnostics +/// reported by Diagnostic. +bool DiagnosticClient::IncludeInDiagnosticCounts() const { return true; } -- GitLab From ec2839108404dae5222251ebecddab3c19cbca41 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 23 Jan 2009 20:52:26 +0000 Subject: [PATCH 093/682] Added clang option '--analyzer-display-progress' to indicate that the analyzer should output 'ANALYZE:' messages to display its progress on a source file. llvm-svn: 62875 --- clang/Driver/AnalysisConsumer.cpp | 28 ++++++++++++++++++---------- clang/Driver/AnalysisConsumer.h | 3 ++- clang/Driver/clang.cpp | 7 ++++++- clang/utils/ccc-analyzer | 1 + 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp index 236cc1d865dc..4dab9c7b4bc1 100644 --- a/clang/Driver/AnalysisConsumer.cpp +++ b/clang/Driver/AnalysisConsumer.cpp @@ -86,6 +86,7 @@ namespace { bool AnalyzeAll; AnalysisStores SM; AnalysisDiagClients DC; + const bool DisplayProgress; AnalysisConsumer(Diagnostic &diags, Preprocessor* pp, PreprocessorFactory* ppf, @@ -93,13 +94,15 @@ namespace { const std::string& fname, const std::string& htmldir, AnalysisStores sm, AnalysisDiagClients dc, - bool visgraphviz, bool visubi, bool trim, bool analyzeAll) + bool visgraphviz, bool visubi, bool trim, bool analyzeAll, + bool displayProgress) : VisGraphviz(visgraphviz), VisUbigraph(visubi), TrimGraph(trim), LOpts(lopts), Diags(diags), Ctx(0), PP(pp), PPF(ppf), HTMLDir(htmldir), FName(fname), - AnalyzeAll(analyzeAll), SM(sm), DC(dc) {} + AnalyzeAll(analyzeAll), SM(sm), DC(dc), + DisplayProgress(displayProgress) {} void addCodeAction(CodeAction action) { FunctionActions.push_back(action); @@ -143,13 +146,16 @@ namespace { ConstraintManagerCreator CreateConstraintMgr; public: - AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b) - : D(d), Body(b), TU(0), AScope(ScopeDecl), C(c), DisplayedFunction(false){ + AnalysisManager(AnalysisConsumer& c, Decl* d, Stmt* b, bool displayProgress) + : D(d), Body(b), TU(0), AScope(ScopeDecl), C(c), + DisplayedFunction(!displayProgress) { setManagerCreators(); } - AnalysisManager(AnalysisConsumer& c, TranslationUnit* tu) - : D(0), Body(0), TU(tu), AScope(ScopeTU), C(c), DisplayedFunction(false) { + AnalysisManager(AnalysisConsumer& c, TranslationUnit* tu, + bool displayProgress) + : D(0), Body(0), TU(tu), AScope(ScopeTU), C(c), + DisplayedFunction(!displayProgress) { setManagerCreators(); } @@ -347,7 +353,7 @@ void AnalysisConsumer::HandleTopLevelDecl(Decl *D) { void AnalysisConsumer::HandleTranslationUnit(TranslationUnit& TU) { if(!TranslationUnitActions.empty()) { - AnalysisManager mgr(*this, &TU); + AnalysisManager mgr(*this, &TU, DisplayProgress); for (Actions::iterator I = TranslationUnitActions.begin(), E = TranslationUnitActions.end(); I != E; ++I) (*I)(mgr); @@ -382,7 +388,7 @@ void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) { // Create an AnalysisManager that will manage the state for analyzing // this method/function. - AnalysisManager mgr(*this, D, Body); + AnalysisManager mgr(*this, D, Body, DisplayProgress); // Dispatch on the actions. for (Actions::iterator I = actions.begin(), E = actions.end(); I != E; ++I) @@ -544,11 +550,13 @@ ASTConsumer* clang::CreateAnalysisConsumer(Analyses* Beg, Analyses* End, const std::string& htmldir, bool VisGraphviz, bool VisUbi, bool trim, - bool analyzeAll) { + bool analyzeAll, + bool displayProgress) { llvm::OwningPtr C(new AnalysisConsumer(diags, pp, ppf, lopts, fname, htmldir, SM, DC, - VisGraphviz, VisUbi, trim, analyzeAll)); + VisGraphviz, VisUbi, trim, analyzeAll, + displayProgress)); for ( ; Beg != End ; ++Beg) switch (*Beg) { diff --git a/clang/Driver/AnalysisConsumer.h b/clang/Driver/AnalysisConsumer.h index 1e0824022062..eb349be24053 100644 --- a/clang/Driver/AnalysisConsumer.h +++ b/clang/Driver/AnalysisConsumer.h @@ -44,7 +44,8 @@ ASTConsumer* CreateAnalysisConsumer(Analyses* Beg, Analyses* End, bool VisualizeGraphViz, bool VisualizeUbi, bool VizTrimGraph, - bool AnalyzeAll); + bool AnalyzeAll, + bool DisplayProgress); } // end clang namespace #endif diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index cc3788b5f3f7..d7c8beb1d39f 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -218,6 +218,10 @@ AnalyzeAll("analyzer-opt-analyze-headers", llvm::cl::desc("Force the static analyzer to analyze " "functions defined in header files")); +static llvm::cl::opt +AnalyzerDisplayProgress("analyzer-display-progress", + llvm::cl::desc("Emit verbose output about the analyzer's progress.")); + static llvm::cl::list AnalysisList(llvm::cl::desc("SCA Checks/Analyses:"), llvm::cl::values( @@ -1313,7 +1317,8 @@ static ASTConsumer* CreateASTConsumer(const std::string& InFile, Diag, PP, PPF, LangOpts, AnalyzeSpecificFunction, OutputFile, VisualizeEGDot, VisualizeEGUbi, - TrimGraph, AnalyzeAll); + TrimGraph, AnalyzeAll, + AnalyzerDisplayProgress); } } diff --git a/clang/utils/ccc-analyzer b/clang/utils/ccc-analyzer index 68df56a38eae..6c5e700ae4f6 100755 --- a/clang/utils/ccc-analyzer +++ b/clang/utils/ccc-analyzer @@ -100,6 +100,7 @@ sub Analyze { push @CmdArgs,@$Args; @CmdArgsSansAnalyses = @CmdArgs; push @CmdArgs,'--analyze'; + push @CmdArgs,"--analyzer-display-progress"; push @CmdArgs,(split /\s/,$Analyses); $RunAnalyzer = 1; } -- GitLab From 51650d380b29a1fbd58dfe3103942f7a7ade98ab Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 21:04:18 +0000 Subject: [PATCH 094/682] Hopefully the last of the APSInt signedness issues with initializers. Fixes PR clang/3378 llvm-svn: 62876 --- clang/lib/Sema/SemaInit.cpp | 1 + clang/test/Sema/designated-initializers.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index aff46ef61d50..15e2d5d13f2f 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -626,6 +626,7 @@ CheckArrayDesignatorExpr(Sema &Self, Expr *Index, llvm::APSInt &Value) { return Self.Diag(Loc, diag::err_array_designator_negative) << Value.toString(10) << Index->getSourceRange(); + Value.setIsUnsigned(true); return false; } diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index 3fe5f8484c2d..8f7eb8cda928 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -113,6 +113,7 @@ struct disklabel_ops disklabel64_ops = { .labelsize = sizeof(struct disklabel_ops) }; -// PR clang/3377 +// PR clang/3378 int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 }; int a[]= { [sizeof(int)] = 0 }; +int a2[]= { [0 ... sizeof(int)] = 0 }; -- GitLab From 59c431347fe129a735bdd7da227fd359be0f1371 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Fri, 23 Jan 2009 21:17:04 +0000 Subject: [PATCH 095/682] use CallSite::isCalle instead of slow getOperandNo llvm-svn: 62877 --- llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp index 9d7980c0b2b9..dd5fce69fe15 100644 --- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -182,7 +182,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { if (!TheCall) return false; // Not a direct call site? // The addr of this function is passed to the call. - if (I.getOperandNo() != 0) return false; + if (!CS.isCallee(I)) return false; } // Okay, we know we can transform this function if safe. Scan its body @@ -438,13 +438,13 @@ void DAE::SurveyFunction(Function &F) { for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) { // If the function is PASSED IN as an argument, its address has been // taken. - if (I.getOperandNo() != 0) { + CallSite CS = CallSite::get(*I); + if (!CS.getInstruction() || !CS.isCallee(I)) { MarkLive(F); return; } // If this use is anything other than a call site, the function is alive. - CallSite CS = CallSite::get(*I); Instruction *TheCall = CS.getInstruction(); if (!TheCall) { // Not a direct call site? MarkLive(F); -- GitLab From b6b9961fdd0a9428ce695d076e418e2244a8931e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 21:30:56 +0000 Subject: [PATCH 096/682] Make sure that all NamedDecls have an identifier namespace. Make sure that we know a call is invalid if we dropped arguments. llvm-svn: 62882 --- clang/include/clang/AST/DeclBase.h | 19 ++++++++++++------- clang/lib/Sema/SemaExpr.cpp | 6 ++++-- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 64792e94684e..86992b5dd51f 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -257,19 +257,24 @@ public: if (DeclKind >= FunctionFirst && DeclKind <= FunctionLast) return IDNS_Ordinary; assert(0 && "Unknown decl kind!"); - case ImplicitParam: + case OverloadedFunction: case Typedef: + case TemplateTypeParm: + case EnumConstant: case Var: + case CXXClassVar: + case ImplicitParam: case ParmVar: case OriginalParmVar: - case EnumConstant: case NonTypeTemplateParm: + case ObjCMethod: + case ObjCContainer: + case ObjCCategory: + case ObjCProtocol: case ObjCInterface: + case ObjCCategoryImpl: + case ObjCProperty: case ObjCCompatibleAlias: - case OverloadedFunction: - case CXXMethod: - case CXXConversion: - case CXXClassVar: return IDNS_Ordinary; case Field: @@ -279,9 +284,9 @@ public: case Record: case CXXRecord: - case TemplateTypeParm: case Enum: return IDNS_Tag; + case Namespace: return IdentifierNamespace(IDNS_Tag | IDNS_Ordinary); } diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 6ec4d4a61f34..202f07b4bf5e 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1684,7 +1684,8 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, // assignment, to the types of the corresponding parameter, ... unsigned NumArgsInProto = Proto->getNumArgs(); unsigned NumArgsToCheck = NumArgs; - + bool Invalid = false; + // If too few arguments are available (and we don't have default // arguments for the remaining parameters), don't make the call. if (NumArgs < NumArgsInProto) { @@ -1707,6 +1708,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, Args[NumArgs-1]->getLocEnd()); // This deletes the extra arguments. Call->setNumArgs(NumArgsInProto); + Invalid = true; } NumArgsToCheck = NumArgsInProto; } @@ -1746,7 +1748,7 @@ Sema::ConvertArgumentsForCall(CallExpr *Call, Expr *Fn, } } - return false; + return Invalid; } /// ActOnCallExpr - Handle a call to Fn with the specified array of arguments. -- GitLab From 486d309b34daddae8774a2035833aed0d8083002 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 23 Jan 2009 21:54:18 +0000 Subject: [PATCH 097/682] Fix test case. Use valid file name and directory in global variable's debug info entry. llvm-svn: 62883 --- llvm/test/DebugInfo/2009-01-15-member.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/DebugInfo/2009-01-15-member.ll b/llvm/test/DebugInfo/2009-01-15-member.ll index ae598d6a6e35..7eb81f8f3dd8 100644 --- a/llvm/test/DebugInfo/2009-01-15-member.ll +++ b/llvm/test/DebugInfo/2009-01-15-member.ll @@ -27,4 +27,4 @@ @llvm.dbg.composite11 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, i64 64, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] @llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] @.str12 = internal constant [3 x i8] c"s2\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] -@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { i32 458804, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([3 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 6, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*), i1 false, i1 true, { }* bitcast (%struct.s* @s2 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0] +@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { i32 458804, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([3 x i8]* @.str12, i32 0, i32 0), i8* getelementptr ([3 x i8]* @.str12, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 6, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*), i1 false, i1 true, { }* bitcast (%struct.s* @s2 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([6 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0] \ No newline at end of file -- GitLab From 7a95b08fcebd553ee54183f43d84daaf3e931732 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 22:22:29 +0000 Subject: [PATCH 098/682] More APSInt appeasement llvm-svn: 62884 --- clang/lib/Sema/SemaInit.cpp | 32 ++++++++++++++--------- clang/test/Sema/designated-initializers.c | 2 +- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 15e2d5d13f2f..55d11b439854 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -671,18 +671,26 @@ Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig, if (CheckArrayDesignatorExpr(*this, StartIndex, StartValue) || CheckArrayDesignatorExpr(*this, EndIndex, EndValue)) Invalid = true; - else if (EndValue < StartValue) { - Diag(D.getEllipsisLoc(), diag::err_array_designator_empty_range) - << StartValue.toString(10) << EndValue.toString(10) - << StartIndex->getSourceRange() << EndIndex->getSourceRange(); - Invalid = true; - } else { - Designators.push_back(ASTDesignator(InitExpressions.size(), - D.getLBracketLoc(), - D.getEllipsisLoc(), - D.getRBracketLoc())); - InitExpressions.push_back(StartIndex); - InitExpressions.push_back(EndIndex); + else { + // Make sure we're comparing values with the same bit width. + if (StartValue.getBitWidth() > EndValue.getBitWidth()) + EndValue.extend(StartValue.getBitWidth()); + else if (StartValue.getBitWidth() < EndValue.getBitWidth()) + StartValue.extend(EndValue.getBitWidth()); + + if (EndValue < StartValue) { + Diag(D.getEllipsisLoc(), diag::err_array_designator_empty_range) + << StartValue.toString(10) << EndValue.toString(10) + << StartIndex->getSourceRange() << EndIndex->getSourceRange(); + Invalid = true; + } else { + Designators.push_back(ASTDesignator(InitExpressions.size(), + D.getLBracketLoc(), + D.getEllipsisLoc(), + D.getRBracketLoc())); + InitExpressions.push_back(StartIndex); + InitExpressions.push_back(EndIndex); + } } break; } diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c index 8f7eb8cda928..fd4873193cfd 100644 --- a/clang/test/Sema/designated-initializers.c +++ b/clang/test/Sema/designated-initializers.c @@ -1,4 +1,4 @@ -// RUN: clang -fsyntax-only -verify %s +// RUN: clang -fsyntax-only -verify -arch x86_64 %s int complete_array_from_init[] = { 1, 2, [10] = 5, 1, 2, [5] = 2, 6 }; -- GitLab From 864ead2076dce0dcd4c6abf4d6b390505bdf2066 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 23 Jan 2009 22:22:49 +0000 Subject: [PATCH 099/682] Output summary diagnostic for each bug report. llvm-svn: 62885 --- clang/lib/Analysis/BugReporter.cpp | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index e3735670cf63..9d4d059341b5 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -738,19 +738,20 @@ void BugReporter::EmitWarning(BugReport& R) { PathDiagnosticClient* PD = getPathDiagnosticClient(); if (PD && !D->empty()) { - PD->HandlePathDiagnostic(D.take()); - return; + PD->HandlePathDiagnostic(D.take()); + // Output a diagnostic summarizing the report. + Diagnostic& Diag = getDiagnostic(); + Diag.Report(R.getLocation(getSourceManager()), + Diag.getCustomDiagID(Diagnostic::Warning,R.getDescription())); + return; } - // We don't have a PathDiagnosticClient, but we can still emit a single + // This isn't a bug with a path, but we can still emit a single // line diagnostic. Determine the location. - FullSourceLoc L = D->empty() ? R.getLocation(getSourceManager()) : D->back()->getLocation(); - - // Determine the range. - + // Determine the range. const SourceRange *Beg, *End; if (!D->empty()) { @@ -768,6 +769,10 @@ void BugReporter::EmitWarning(BugReport& R) { D->push_back(piece); PD->HandlePathDiagnostic(D.take()); + + // Output a diagnostic summarizing the report. + Diagnostic& Diag = getDiagnostic(); + Diag.Report(L,Diag.getCustomDiagID(Diagnostic::Warning,R.getDescription())); return; } else { -- GitLab From 18d30c23427354888698b760ea7269d156940706 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 23 Jan 2009 22:28:29 +0000 Subject: [PATCH 100/682] Fix a small regression in warning about template type parameter redeclarations. llvm-svn: 62886 --- clang/include/clang/AST/DeclBase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 86992b5dd51f..8d203cc2c2c6 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -259,7 +259,6 @@ public: assert(0 && "Unknown decl kind!"); case OverloadedFunction: case Typedef: - case TemplateTypeParm: case EnumConstant: case Var: case CXXClassVar: @@ -285,6 +284,7 @@ public: case Record: case CXXRecord: case Enum: + case TemplateTypeParm: return IDNS_Tag; case Namespace: -- GitLab From 832959536a6471eef3bee0bd4774b49ac76d46eb Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 23 Jan 2009 22:33:40 +0000 Subject: [PATCH 101/682] hopefully address PR3379 by making the P modifier work in x86 inline asm. llvm-svn: 62887 --- llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp index df0b107f9d84..e09411a51764 100644 --- a/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp +++ b/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp @@ -709,6 +709,9 @@ bool X86ATTAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, case 'q': // Print SImode register // These only apply to registers, ignore on mem. break; + case 'P': // Don't print @PLT, but do print as memory. + printOperand(MI, OpNo, "mem"); + return false; } } printMemReference(MI, OpNo); -- GitLab From ccfacfff9a707e283e208a3d5295557cc060ac36 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Fri, 23 Jan 2009 22:33:47 +0000 Subject: [PATCH 102/682] Introduce two DWARF attribute extentions DW_AT_APPLE_optimized, DW_AT_APPLE_flags. DW_AT_APPLE_optimized flag is set when a compile_unit is optimized. The debugger takes advantage of this information some way. DW_AT_APPLE_flags encodes command line options when certain env. variable is set. This is used by build engineers to track various gcc command lines used by by a project, irrespective of whether the project used makefile, Xcode or something else. llvm-gcc patch is next. llvm-svn: 62888 --- llvm/include/llvm/Analysis/DebugInfo.h | 6 +++++- llvm/include/llvm/Support/Dwarf.h | 6 +++++- llvm/lib/Analysis/DebugInfo.cpp | 8 ++++++-- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 5 +++++ llvm/lib/Support/Dwarf.cpp | 2 ++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/Analysis/DebugInfo.h b/llvm/include/llvm/Analysis/DebugInfo.h index 63206ea6fca5..c80a11d3b32c 100644 --- a/llvm/include/llvm/Analysis/DebugInfo.h +++ b/llvm/include/llvm/Analysis/DebugInfo.h @@ -109,6 +109,8 @@ namespace llvm { std::string getFilename() const { return getStringField(3); } std::string getDirectory() const { return getStringField(4); } std::string getProducer() const { return getStringField(5); } + bool isOptimized() const { return getUnsignedField(6); } + std::string getFlags() const { return getStringField(7); } /// Verify - Verify that a compile unit is well formed. bool Verify() const; @@ -372,7 +374,9 @@ namespace llvm { DICompileUnit CreateCompileUnit(unsigned LangID, const std::string &Filename, const std::string &Directory, - const std::string &Producer); + const std::string &Producer, + bool isOptimized = false, + const char *Flags = ""); /// CreateEnumerator - Create a single enumerator value. DIEnumerator CreateEnumerator(const std::string &Name, uint64_t Val); diff --git a/llvm/include/llvm/Support/Dwarf.h b/llvm/include/llvm/Support/Dwarf.h index 23ab9bf29e57..c24274354cf6 100644 --- a/llvm/include/llvm/Support/Dwarf.h +++ b/llvm/include/llvm/Support/Dwarf.h @@ -221,7 +221,11 @@ enum dwarf_constants { DW_AT_GNU_vector = 0x2107, DW_AT_lo_user = 0x2000, DW_AT_hi_user = 0x3fff, - + + // Apple extensions. + DW_AT_APPLE_optimized = 0x3fe1, + DW_AT_APPLE_flags = 0x3fe2, + // Attribute form encodings DW_FORM_addr = 0x01, DW_FORM_block2 = 0x03, diff --git a/llvm/lib/Analysis/DebugInfo.cpp b/llvm/lib/Analysis/DebugInfo.cpp index 34ccd0a97cf9..2f336572a1df 100644 --- a/llvm/lib/Analysis/DebugInfo.cpp +++ b/llvm/lib/Analysis/DebugInfo.cpp @@ -440,14 +440,18 @@ DISubrange DIFactory::GetOrCreateSubrange(int64_t Lo, int64_t Hi) { DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID, const std::string &Filename, const std::string &Directory, - const std::string &Producer) { + const std::string &Producer, + bool isOptimized, + const char *Flags) { Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_compile_unit), getCastToEmpty(GetOrCreateCompileUnitAnchor()), ConstantInt::get(Type::Int32Ty, LangID), GetStringConstant(Filename), GetStringConstant(Directory), - GetStringConstant(Producer) + GetStringConstant(Producer), + ConstantInt::get(Type::Int1Ty, isOptimized), + GetStringConstant(Flags) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 6bbb5bb9b769..4b19d06c924e 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -2781,6 +2781,11 @@ private: AddString(Die, DW_AT_name, DW_FORM_string, DIUnit.getFilename()); if (!DIUnit.getDirectory().empty()) AddString(Die, DW_AT_comp_dir, DW_FORM_string, DIUnit.getDirectory()); + if (DIUnit.isOptimized()) + AddUInt(Die, DW_AT_APPLE_optimized, DW_FORM_flag, 1); + const std::string &Flags = DIUnit.getFlags(); + if (!Flags.empty()) + AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags); CompileUnit *Unit = new CompileUnit(ID, Die); DW_CUs[DIUnit.getGV()] = Unit; diff --git a/llvm/lib/Support/Dwarf.cpp b/llvm/lib/Support/Dwarf.cpp index b7cf3b977abd..10a2c3c64f8d 100644 --- a/llvm/lib/Support/Dwarf.cpp +++ b/llvm/lib/Support/Dwarf.cpp @@ -198,6 +198,8 @@ const char *AttributeString(unsigned Attribute) { case DW_AT_GNU_vector: return "DW_AT_GNU_vector"; case DW_AT_lo_user: return "DW_AT_lo_user"; case DW_AT_hi_user: return "DW_AT_hi_user"; + case DW_AT_APPLE_optimized: return "DW_AT_APPLE_optimized"; + case DW_AT_APPLE_flags: return "DW_AT_APPLE_flags"; } assert(0 && "Unknown Dwarf Attribute"); return ""; -- GitLab From 6d8970695b0f8f1b533f6aabb8d93c68ca30168d Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Fri, 23 Jan 2009 23:27:33 +0000 Subject: [PATCH 103/682] Refactor code. No functionality change. llvm-svn: 62893 --- .../lib/CodeGen/TwoAddressInstructionPass.cpp | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index 1d97f6798228..071b39954c09 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -69,6 +69,11 @@ namespace { MachineInstr *MI, MachineInstr *DefMI, MachineBasicBlock *MBB, unsigned Loc, DenseMap &DistanceMap); + + bool CommuteInstruction(MachineBasicBlock::iterator &mi, + MachineFunction::iterator &mbbi, + unsigned RegC, unsigned Dist, + DenseMap &DistanceMap); public: static char ID; // Pass identification, replacement for typeid TwoAddressInstructionPass() : MachineFunctionPass(&ID) {} @@ -250,6 +255,38 @@ TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg, return MBB == DefMI->getParent(); } +/// CommuteInstruction - Commute a two-address instruction and update the basic +/// block, distance map, and live variables if needed. Return true if it is +/// successful. +bool +TwoAddressInstructionPass::CommuteInstruction(MachineBasicBlock::iterator &mi, + MachineFunction::iterator &mbbi, + unsigned RegC, unsigned Dist, + DenseMap &DistanceMap) { + MachineInstr *MI = mi; + DOUT << "2addr: COMMUTING : " << *MI; + MachineInstr *NewMI = TII->commuteInstruction(MI); + + if (NewMI == 0) { + DOUT << "2addr: COMMUTING FAILED!\n"; + return false; + } + + DOUT << "2addr: COMMUTED TO: " << *NewMI; + // If the instruction changed to commute it, update livevar. + if (NewMI != MI) { + if (LV) + // Update live variables + LV->replaceKillInstruction(RegC, MI, NewMI); + + mbbi->insert(mi, NewMI); // Insert the new inst + mbbi->erase(mi); // Nuke the old inst. + mi = NewMI; + DistanceMap.insert(std::make_pair(NewMI, Dist)); + } + return true; +} + /// runOnMachineFunction - Reduce two-address instructions to two operands. /// bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { @@ -337,27 +374,8 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { assert(mi->getOperand(3-si).isReg() && "Not a proper commutative instruction!"); unsigned regC = mi->getOperand(3-si).getReg(); - if (mi->killsRegister(regC)) { - DOUT << "2addr: COMMUTING : " << *mi; - MachineInstr *NewMI = TII->commuteInstruction(mi); - - if (NewMI == 0) { - DOUT << "2addr: COMMUTING FAILED!\n"; - } else { - DOUT << "2addr: COMMUTED TO: " << *NewMI; - // If the instruction changed to commute it, update livevar. - if (NewMI != mi) { - if (LV) - // Update live variables - LV->replaceKillInstruction(regC, mi, NewMI); - - mbbi->insert(mi, NewMI); // Insert the new inst - mbbi->erase(mi); // Nuke the old inst. - mi = NewMI; - DistanceMap.insert(std::make_pair(NewMI, Dist)); - } - + if (CommuteInstruction(mi, mbbi, regC, Dist, DistanceMap)) { ++NumCommuted; regB = regC; goto InstructionRearranged; -- GitLab From 71394045e486e4bf7dc2e46ab515efea329dc916 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 23 Jan 2009 23:53:38 +0000 Subject: [PATCH 104/682] Some very early work for new objc's meta-data generation. llvm-svn: 62894 --- clang/lib/CodeGen/CGObjCMac.cpp | 219 ++++++++++++++++++++++++++++++-- 1 file changed, 208 insertions(+), 11 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index fbd9b3645b0a..1b0027a96be0 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -234,6 +234,9 @@ public: // ClassnfABITy - LLVM for struct _class_t const llvm::StructType *ClassnfABITy; + // ClassnfABIPtrTy - LLVM for struct _class_t* + const llvm::Type *ClassnfABIPtrTy; + // IvarnfABITy - LLVM for struct _ivar_t const llvm::StructType *IvarnfABITy; @@ -344,6 +347,8 @@ protected: public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { } + + virtual llvm::Constant *GenerateConstantString(const std::string &String); }; class CGObjCMac : public CGObjCCommonMac { @@ -476,8 +481,9 @@ private: public: CGObjCMac(CodeGen::CodeGenModule &cgm); - virtual llvm::Constant *GenerateConstantString(const std::string &String); + virtual llvm::Function *ModuleInitFunction(); + virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, QualType ResultType, Selector Sel, @@ -511,7 +517,6 @@ public: virtual void GenerateProtocol(const ObjCProtocolDecl *PD); - virtual llvm::Function *ModuleInitFunction(); virtual llvm::Function *GetPropertyGetFunction(); virtual llvm::Function *GetPropertySetFunction(); virtual llvm::Function *EnumerationMutationFunction(); @@ -535,8 +540,83 @@ public: class CGObjCNonFragileABIMac : public CGObjCCommonMac { private: ObjCNonFragileABITypesHelper ObjCTypes; + llvm::GlobalVariable* ObjCEmptyCacheVar; + llvm::GlobalVariable* ObjCEmptyVtableVar; + + /// FinishNonFragileABIModule - Write out global data structures at the end of + /// processing a translation unit. + void FinishNonFragileABIModule(); + public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); + // FIXME. All stubs for now! + virtual llvm::Function *ModuleInitFunction(); + + virtual CodeGen::RValue GenerateMessageSend(CodeGen::CodeGenFunction &CGF, + QualType ResultType, + Selector Sel, + llvm::Value *Receiver, + bool IsClassMessage, + const CallArgList &CallArgs) + {return RValue::get(0);} + + virtual CodeGen::RValue + GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, + QualType ResultType, + Selector Sel, + const ObjCInterfaceDecl *Class, + llvm::Value *Receiver, + bool IsClassMessage, + const CallArgList &CallArgs){ return RValue::get(0);} + + virtual llvm::Value *GetClass(CGBuilderTy &Builder, + const ObjCInterfaceDecl *ID){ return 0; } + + virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel) + { return 0; } + + virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, + const ObjCContainerDecl *CD=0) + { return 0; } + + virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD) + { return; } + + virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); + + virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, + const ObjCProtocolDecl *PD) + { return 0; } + + virtual void GenerateProtocol(const ObjCProtocolDecl *PD){ return; } + + virtual llvm::Function *GetPropertyGetFunction(){ return 0; } + virtual llvm::Function *GetPropertySetFunction() + { return 0; } + virtual llvm::Function *EnumerationMutationFunction() + { return 0; } + + virtual void EmitTryOrSynchronizedStmt(CodeGen::CodeGenFunction &CGF, + const Stmt &S) + { return; } + virtual void EmitThrowStmt(CodeGen::CodeGenFunction &CGF, + const ObjCAtThrowStmt &S) + { return; } + virtual llvm::Value * EmitObjCWeakRead(CodeGen::CodeGenFunction &CGF, + llvm::Value *AddrWeakObj) + { return 0; } + virtual void EmitObjCWeakAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dst) + { return; } + virtual void EmitObjCGlobalAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dest) + { return; } + virtual void EmitObjCIvarAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dest) + { return; } + virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, + llvm::Value *src, llvm::Value *dest) + { return; } }; } // end anonymous namespace @@ -585,7 +665,8 @@ llvm::Value *CGObjCMac::GetSelector(CGBuilderTy &Builder, Selector Sel) { }; */ -llvm::Constant *CGObjCMac::GenerateConstantString(const std::string &String) { +llvm::Constant *CGObjCCommonMac::GenerateConstantString( + const std::string &String) { return CGM.GetAddrOfConstantCFString(String); } @@ -2300,6 +2381,7 @@ CGObjCNonFragileABIMac::CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm) : CGObjCCommonMac(cgm), ObjCTypes(cgm) { + ObjCEmptyCacheVar = ObjCEmptyVtableVar = NULL; ObjCABI = 2; } @@ -2862,13 +2944,13 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul CGM.getModule().addTypeName("struct._objc_protocol_list", ProtocolListnfABITy); - // FIXME! Is this doing the right thing? - cast(ProtocolListTyHolder.get())->refineAbstractTypeTo( - ProtocolListnfABITy); - // struct _objc_protocol_list* ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy); + // FIXME! Is this doing the right thing? + cast(ProtocolListTyHolder.get())->refineAbstractTypeTo( + ProtocolListnfABIPtrTy); + // struct _ivar_t { // unsigned long int *offset; // pointer to ivar offset location // char *name; @@ -2953,6 +3035,9 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul cast(ClassTyHolder.get())->refineAbstractTypeTo( ClassnfABITy); + // LLVM for struct _class_t * + ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy); + // struct _category_t { // const char * const name; // struct _class_t *const cls; @@ -2962,8 +3047,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // const struct _prop_list_t * const properties; // } CategorynfABITy = llvm::StructType::get(Int8PtrTy, - llvm::PointerType::getUnqual( - ClassnfABITy), + ClassnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, @@ -2973,6 +3057,120 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul } +llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { + FinishNonFragileABIModule(); + + return NULL; +} + +void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { + // nonfragile abi has no module definition. + std::vector Used; + for (std::vector::iterator i = UsedGlobals.begin(), + e = UsedGlobals.end(); i != e; ++i) { + Used.push_back(llvm::ConstantExpr::getBitCast(*i, ObjCTypes.Int8PtrTy)); + } + + llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.Int8PtrTy, Used.size()); + llvm::GlobalValue *GV = + new llvm::GlobalVariable(AT, false, + llvm::GlobalValue::AppendingLinkage, + llvm::ConstantArray::get(AT, Used), + "llvm.used", + &CGM.getModule()); + + GV->setSection("llvm.metadata"); + +} + +void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { + std::string ClassName = ID->getNameAsString(); + if (!ObjCEmptyCacheVar) { + ObjCEmptyCacheVar = new llvm::GlobalVariable( + ObjCTypes.CachePtrTy, + false, + llvm::GlobalValue::ExternalLinkage, + 0, + "\01_objc_empty_cache", + &CGM.getModule()); + UsedGlobals.push_back(ObjCEmptyCacheVar); + + ObjCEmptyVtableVar = new llvm::GlobalVariable( + llvm::PointerType::getUnqual( + ObjCTypes.ImpnfABITy), + false, + llvm::GlobalValue::ExternalLinkage, + 0, + "\01_objc_empty_vtable", + &CGM.getModule()); + UsedGlobals.push_back(ObjCEmptyVtableVar); + } + + std::vector Values(11); // 11 for 64bit targets! + // Generate following meta-data: + // struct _class_ro_t { + // uint32_t const flags; + // uint32_t const instanceStart; + // uint32_t const instanceSize; + // uint32_t const reserved; // only when building for 64bit targets + // const uint8_t * const ivarLayout; + // const char *const name; + // const struct _method_list_t * const baseMethods; + // const struct _objc_protocol_list *const baseProtocols; + // const struct _ivar_list_t *const ivars; + // const uint8_t * const weakIvarLayout; + // const struct _prop_list_t * const properties; + // } + Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); + Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); + Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); + Values[ 3] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); + // FIXME. For 64bit targets add 0 here. + Values[ 4] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + Values[ 5] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); + Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); + Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + Values[10] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, + Values); + llvm::GlobalVariable *CLASS_RO_GV = + new llvm::GlobalVariable(ObjCTypes.ClassRonfABITy, false, + llvm::GlobalValue::InternalLinkage, + Init, + std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, + &CGM.getModule()); + CLASS_RO_GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + UsedGlobals.push_back(CLASS_RO_GV); + + // Generate following meta-data: + // struct _class_t { + // struct _class_t *isa; + // struct _class_t * const superclass; + // void *cache; + // IMP *vtable; + // struct class_ro_t *ro; + // } + Values.resize(5); + Values[0] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); + Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); + Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar + Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar + Values[4] = CLASS_RO_GV; // &CLASS_RO_GV + Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, Values); + llvm::GlobalVariable *GV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + Init, + std::string("\01_OBJC_CLASS_$_")+ClassName, + &CGM.getModule()); + GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + UsedGlobals.push_back(GV); + // FIXME! why? + GV->setAlignment(32); +} + /* *** */ CodeGen::CGObjCRuntime * @@ -2982,6 +3180,5 @@ CodeGen::CreateMacObjCRuntime(CodeGen::CodeGenModule &CGM) { CodeGen::CGObjCRuntime * CodeGen::CreateMacNonFragileABIObjCRuntime(CodeGen::CodeGenModule &CGM) { - return 0; - // return new CGObjCNonFragileABIMac(CGM); + return new CGObjCNonFragileABIMac(CGM); } -- GitLab From 82221d62a98511e71b5a98bd8f2a05106c045936 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Sat, 24 Jan 2009 00:00:41 +0000 Subject: [PATCH 105/682] Perform optional clang building. llvm-svn: 62895 --- llvm/Makefile.rules | 7 +++++++ llvm/tools/Makefile | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/llvm/Makefile.rules b/llvm/Makefile.rules index 0d4a0c8aedf2..5bddff8e8a22 100644 --- a/llvm/Makefile.rules +++ b/llvm/Makefile.rules @@ -612,6 +612,13 @@ $(RecursiveTargets):: done endif +#----------------------------------------------------------- +# Handle the OPTIONAL_PARALLEL_DIRS options for optional parallel construction +#----------------------------------------------------------- +ifdef OPTIONAL_PARALLEL_DIRS + PARALLEL_DIRS += $(foreach T,$(OPTIONAL_PARALLEL_DIRS),$(shell test -d $(PROJ_SRC_DIR)/$(T) && echo "$(T)")) +endif + #----------------------------------------------------------- # Handle the PARALLEL_DIRS options for parallel construction #----------------------------------------------------------- diff --git a/llvm/tools/Makefile b/llvm/tools/Makefile index 2726c1f3e43e..519717ad98de 100644 --- a/llvm/tools/Makefile +++ b/llvm/tools/Makefile @@ -8,6 +8,10 @@ ##===----------------------------------------------------------------------===## LEVEL := .. + +# Build clang if present. +OPTIONAL_PARALLEL_DIRS := clang + # NOTE: The tools are organized into five groups of four consisting of one # large and three small executables. This is done to minimize memory load # in parallel builds. Please retain this ordering. -- GitLab From f08ac278ed1ac4c00cb28434b0a22b48b75ddb2c Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 24 Jan 2009 00:55:43 +0000 Subject: [PATCH 106/682] More hacking on static analyzer diagnostics. When emitting summary diagnostics the code paths for diagnostics involving paths or single locations are now unified. This patch also constifies many arguments/methods that are touched by this logic, leading to a nice overall code cleanup. llvm-svn: 62903 --- .../Analysis/PathSensitive/BugReporter.h | 14 +- .../Analysis/PathSensitive/ExplodedGraph.h | 17 +- clang/lib/Analysis/BugReporter.cpp | 184 ++++++++---------- clang/lib/Analysis/CFRefCount.cpp | 48 +++-- clang/lib/Analysis/ExplodedGraph.cpp | 25 ++- clang/test/Analysis/NSString.m | 2 +- clang/test/Analysis/retain-release.m | 4 +- 7 files changed, 130 insertions(+), 164 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/BugReporter.h b/clang/include/clang/Analysis/PathSensitive/BugReporter.h index ba6f25396388..bcc28bdc5cbd 100644 --- a/clang/include/clang/Analysis/PathSensitive/BugReporter.h +++ b/clang/include/clang/Analysis/PathSensitive/BugReporter.h @@ -70,16 +70,16 @@ public: class BugReport { BugType& Desc; - ExplodedNode *EndNode; + const ExplodedNode *EndNode; SourceRange R; public: - BugReport(BugType& D, ExplodedNode *n) : Desc(D), EndNode(n) {} + BugReport(BugType& D, const ExplodedNode *n) : Desc(D), EndNode(n) {} virtual ~BugReport(); const BugType& getBugType() const { return Desc; } BugType& getBugType() { return Desc; } - ExplodedNode* getEndNode() const { return EndNode; } + const ExplodedNode* getEndNode() const { return EndNode; } Stmt* getStmt(BugReporter& BR) const; @@ -98,16 +98,16 @@ public: } virtual PathDiagnosticPiece* getEndPath(BugReporter& BR, - ExplodedNode* N); + const ExplodedNode* N); virtual FullSourceLoc getLocation(SourceManager& Mgr); virtual void getRanges(BugReporter& BR,const SourceRange*& beg, const SourceRange*& end); - virtual PathDiagnosticPiece* VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, + virtual PathDiagnosticPiece* VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, BugReporter& BR); }; diff --git a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h b/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h index 3406d178dd7d..954b096b8eaa 100644 --- a/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h +++ b/clang/include/clang/Analysis/PathSensitive/ExplodedGraph.h @@ -179,9 +179,9 @@ public: // Iterators over successor and predecessor vertices. typedef ExplodedNode** succ_iterator; - typedef const ExplodedNode** const_succ_iterator; + typedef const ExplodedNode* const * const_succ_iterator; typedef ExplodedNode** pred_iterator; - typedef const ExplodedNode** const_pred_iterator; + typedef const ExplodedNode* const * const_pred_iterator; pred_iterator pred_begin() { return (ExplodedNode**) Preds.begin(); } pred_iterator pred_end() { return (ExplodedNode**) Preds.end(); } @@ -289,8 +289,8 @@ public: return llvm::dyn_cast(&CodeDecl); } - ExplodedGraphImpl* Trim(ExplodedNodeImpl** NBeg, - ExplodedNodeImpl** NEnd) const; + ExplodedGraphImpl* Trim(const ExplodedNodeImpl* const * NBeg, + const ExplodedNodeImpl* const * NEnd) const; }; @@ -411,15 +411,18 @@ public: // Utility. - ExplodedGraph* Trim(NodeTy** NBeg, NodeTy** NEnd) const { + ExplodedGraph* + Trim(const NodeTy* const* NBeg, const NodeTy* const* NEnd) const { if (NBeg == NEnd) return NULL; assert (NBeg < NEnd); - ExplodedNodeImpl** NBegImpl = (ExplodedNodeImpl**) NBeg; - ExplodedNodeImpl** NEndImpl = (ExplodedNodeImpl**) NEnd; + const ExplodedNodeImpl* const* NBegImpl = + (const ExplodedNodeImpl* const*) NBeg; + const ExplodedNodeImpl* const* NEndImpl = + (const ExplodedNodeImpl* const*) NEnd; return static_cast(ExplodedGraphImpl::Trim(NBegImpl, NEndImpl)); diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 9d4d059341b5..b08f5cb793e3 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -64,27 +64,30 @@ static inline Stmt* GetStmt(const CFGBlock* B) { return (*B)[0]; } -static inline ExplodedNode* -GetNextNode(ExplodedNode* N) { +static inline const ExplodedNode* +GetNextNode(const ExplodedNode* N) { return N->pred_empty() ? NULL : *(N->pred_begin()); } -static Stmt* GetLastStmt(ExplodedNode* N) { +static Stmt* GetLastStmt(const ExplodedNode* N) { assert (isa(N->getLocation())); for (N = GetNextNode(N); N; N = GetNextNode(N)) { - ProgramPoint P = N->getLocation(); - - if (PostStmt* PS = dyn_cast(&P)) - return PS->getStmt(); + if (PostStmt* PS = dyn_cast(&P)) return PS->getStmt(); } return NULL; } +static inline Stmt* GetStmt(const ExplodedNode* N) { + ProgramPoint ProgP = N->getLocation(); + return isa(ProgP) ? GetLastStmt(N) : GetStmt(ProgP); +} + + static void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr, - Stmt* S) { + const Stmt* S) { if (!S) return; @@ -100,7 +103,7 @@ static void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr, static inline void ExecutionContinues(std::ostringstream& os, SourceManager& SMgr, - ExplodedNode* N) { + const ExplodedNode* N) { ExecutionContinues(os, SMgr, GetStmt(N->getLocation())); } @@ -129,7 +132,7 @@ Stmt* BugReport::getStmt(BugReporter& BR) const { PathDiagnosticPiece* BugReport::getEndPath(BugReporter& BR, - ExplodedNode* EndPathNode) { + const ExplodedNode* EndPathNode) { Stmt* S = getStmt(BR); @@ -165,7 +168,7 @@ FullSourceLoc BugReport::getLocation(SourceManager& Mgr) { if (!EndNode) return FullSourceLoc(); - Stmt* S = GetStmt(EndNode->getLocation()); + Stmt* S = GetStmt(EndNode); if (!S) return FullSourceLoc(); @@ -173,21 +176,22 @@ FullSourceLoc BugReport::getLocation(SourceManager& Mgr) { return FullSourceLoc(S->getLocStart(), Mgr); } -PathDiagnosticPiece* BugReport::VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, +PathDiagnosticPiece* BugReport::VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, BugReporter& BR) { return NULL; } static std::pair*, ExplodedNode*> -MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { +MakeReportGraph(const ExplodedGraph* G, + const ExplodedNode* N) { - llvm::OwningPtr > GTrim(G->Trim(&N, &N+1)); + llvm::OwningPtr< ExplodedGraph > GTrim(G->Trim(&N, &N+1)); // Find the error node in the trimmed graph. - ExplodedNode* NOld = N; + const ExplodedNode* NOld = N; N = 0; for (ExplodedGraph::node_iterator @@ -203,21 +207,21 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { assert(N); // Create a new graph with a single path. - - G = new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(), - GTrim->getContext()); + ExplodedGraph *GNew = + new ExplodedGraph(GTrim->getCFG(), GTrim->getCodeDecl(), + GTrim->getContext()); // Sometimes TrimGraph can contain a cycle. Perform a reverse DFS // to the root node, and then construct a new graph that contains only // a single path. - llvm::DenseMap Visited; - llvm::SmallVector*, 10> WS; + llvm::DenseMap Visited; + llvm::SmallVector*, 10> WS; WS.push_back(N); unsigned cnt = 0; - ExplodedNode* Root = 0; + const ExplodedNode* Root = 0; while (!WS.empty()) { - ExplodedNode* Node = WS.back(); + const ExplodedNode* Node = WS.back(); WS.pop_back(); if (Visited.find(Node) != Visited.end()) @@ -230,7 +234,7 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { break; } - for (ExplodedNode::pred_iterator I=Node->pred_begin(), + for (ExplodedNode::const_pred_iterator I=Node->pred_begin(), E=Node->pred_end(); I!=E; ++I) WS.push_back(*I); } @@ -242,15 +246,14 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { ExplodedNode *Last = 0, *First = 0; for ( N = Root ;;) { - // Lookup the number associated with the current node. - llvm::DenseMap::iterator I=Visited.find(N); + llvm::DenseMap::iterator I = Visited.find(N); assert (I != Visited.end()); // Create the equivalent node in the new graph with the same state // and location. ExplodedNode* NewN = - G->getNode(N->getLocation(), N->getState()); + GNew->getNode(N->getLocation(), N->getState()); // Link up the new node with the previous node. if (Last) @@ -266,8 +269,8 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { // Find the next successor node. We choose the node that is marked // with the lowest DFS number. - ExplodedNode::succ_iterator SI = N->succ_begin(); - ExplodedNode::succ_iterator SE = N->succ_end(); + ExplodedNode::const_succ_iterator SI = N->succ_begin(); + ExplodedNode::const_succ_iterator SE = N->succ_end(); N = 0; for (unsigned MinVal = 0; SI != SE; ++SI) { @@ -287,12 +290,12 @@ MakeReportGraph(ExplodedGraph* G, ExplodedNode* N) { } assert (First); - return std::make_pair(G, First); + return std::make_pair(GNew, First); } -static VarDecl* GetMostRecentVarDeclBinding(ExplodedNode* N, - GRStateManager& VMgr, - SVal X) { +static const VarDecl* +GetMostRecentVarDeclBinding(const ExplodedNode* N, + GRStateManager& VMgr, SVal X) { for ( ; N ; N = N->pred_empty() ? 0 : *N->pred_begin()) { @@ -328,16 +331,16 @@ class VISIBILITY_HIDDEN NotableSymbolHandler SymbolRef Sym; const GRState* PrevSt; - Stmt* S; + const Stmt* S; GRStateManager& VMgr; - ExplodedNode* Pred; + const ExplodedNode* Pred; PathDiagnostic& PD; BugReporter& BR; public: - NotableSymbolHandler(SymbolRef sym, const GRState* prevst, Stmt* s, - GRStateManager& vmgr, ExplodedNode* pred, + NotableSymbolHandler(SymbolRef sym, const GRState* prevst, const Stmt* s, + GRStateManager& vmgr, const ExplodedNode* pred, PathDiagnostic& pd, BugReporter& br) : Sym(sym), PrevSt(prevst), S(s), VMgr(vmgr), Pred(pred), PD(pd), BR(br) {} @@ -367,7 +370,7 @@ public: VarDecl *VD = 0; - if (BinaryOperator* B = dyn_cast(S)) { + if (const BinaryOperator* B = dyn_cast(S)) { if (!B->isAssignmentOp()) return true; @@ -379,7 +382,7 @@ public: VD = dyn_cast(DR->getDecl()); } - else if (DeclStmt* DS = dyn_cast(S)) { + else if (const DeclStmt* DS = dyn_cast(S)) { // FIXME: Eventually CFGs won't have DeclStmts. Right now we // assume that each DeclStmt has a single Decl. This invariant // holds by contruction in the CFG. @@ -390,7 +393,7 @@ public: return true; // What is the most recently referenced variable with this binding? - VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V); + const VarDecl* MostRecent = GetMostRecentVarDeclBinding(Pred, VMgr, V); if (!MostRecent) return true; @@ -411,11 +414,12 @@ public: }; } -static void HandleNotableSymbol(ExplodedNode* N, Stmt* S, +static void HandleNotableSymbol(const ExplodedNode* N, + const Stmt* S, SymbolRef Sym, BugReporter& BR, PathDiagnostic& PD) { - ExplodedNode* Pred = N->pred_empty() ? 0 : *N->pred_begin(); + const ExplodedNode* Pred = N->pred_empty() ? 0 : *N->pred_begin(); const GRState* PrevSt = Pred ? Pred->getState() : 0; if (!PrevSt) @@ -433,13 +437,13 @@ class VISIBILITY_HIDDEN ScanNotableSymbols : public StoreManager::BindingsHandler { llvm::SmallSet AlreadyProcessed; - ExplodedNode* N; + const ExplodedNode* N; Stmt* S; GRBugReporter& BR; PathDiagnostic& PD; public: - ScanNotableSymbols(ExplodedNode* n, Stmt* s, GRBugReporter& br, + ScanNotableSymbols(const ExplodedNode* n, Stmt* s, GRBugReporter& br, PathDiagnostic& pd) : N(n), S(s), BR(br), PD(pd) {} @@ -472,14 +476,14 @@ public: void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, BugReport& R) { - ExplodedNode* N = R.getEndNode(); + const ExplodedNode* N = R.getEndNode(); if (!N) return; // Construct a new graph that contains only a single path from the error // node to a root. - const std::pair*,ExplodedNode*> + const std::pair*, ExplodedNode*> GPair = MakeReportGraph(&getGraph(), N); llvm::OwningPtr > ReportGraph(GPair.first); @@ -493,15 +497,15 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, else return; - ExplodedNode* NextNode = N->pred_empty() - ? NULL : *(N->pred_begin()); + const ExplodedNode* NextNode = N->pred_empty() + ? NULL : *(N->pred_begin()); ASTContext& Ctx = getContext(); SourceManager& SMgr = Ctx.getSourceManager(); while (NextNode) { - ExplodedNode* LastNode = N; + const ExplodedNode* LastNode = N; N = NextNode; NextNode = GetNextNode(N); @@ -697,7 +701,7 @@ void GRBugReporter::GeneratePathDiagnostic(PathDiagnostic& PD, bool BugTypeCacheLocation::isCached(BugReport& R) { - ExplodedNode* N = R.getEndNode(); + const ExplodedNode* N = R.getEndNode(); if (!N) return false; @@ -727,73 +731,37 @@ void BugReporter::EmitWarning(BugReport& R) { GeneratePathDiagnostic(*D.get(), R); // Get the meta data. - std::pair Meta = R.getExtraDescriptiveText(); - - for (const char** s = Meta.first; s != Meta.second; ++s) - D->addMeta(*s); + for (const char** s = Meta.first; s != Meta.second; ++s) D->addMeta(*s); - // Emit a full diagnostic for the path if we have a PathDiagnosticClient. - + // Emit a summary diagnostic to the regular Diagnostics engine. PathDiagnosticClient* PD = getPathDiagnosticClient(); - - if (PD && !D->empty()) { - PD->HandlePathDiagnostic(D.take()); - // Output a diagnostic summarizing the report. - Diagnostic& Diag = getDiagnostic(); - Diag.Report(R.getLocation(getSourceManager()), - Diag.getCustomDiagID(Diagnostic::Warning,R.getDescription())); - return; - } - - // This isn't a bug with a path, but we can still emit a single - // line diagnostic. Determine the location. - FullSourceLoc L = D->empty() ? R.getLocation(getSourceManager()) - : D->back()->getLocation(); - - // Determine the range. - const SourceRange *Beg, *End; - - if (!D->empty()) { - Beg = D->back()->ranges_begin(); - End = D->back()->ranges_end(); - } - else - R.getRanges(*this, Beg, End); - - if (PD) { - PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription()); - - for ( ; Beg != End; ++Beg) - piece->addRange(*Beg); - - D->push_back(piece); - PD->HandlePathDiagnostic(D.take()); - - // Output a diagnostic summarizing the report. - Diagnostic& Diag = getDiagnostic(); - Diag.Report(L,Diag.getCustomDiagID(Diagnostic::Warning,R.getDescription())); - return; - } - else { - std::string str; - - if (D->empty()) - str = R.getDescription(); - else - str = D->back()->getString(); - - Diagnostic& Diag = getDiagnostic(); - unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, str.c_str()); + const SourceRange *Beg = 0, *End = 0; + R.getRanges(*this, Beg, End); + Diagnostic& Diag = getDiagnostic(); + FullSourceLoc L = R.getLocation(getSourceManager()); + const char *msg = PD ? R.getBugType().getName() : R.getDescription(); + unsigned ErrorDiag = Diag.getCustomDiagID(Diagnostic::Warning, msg); - switch (End-Beg) { + switch (End-Beg) { default: assert(0 && "Don't handle this many ranges yet!"); case 0: Diag.Report(L, ErrorDiag); break; case 1: Diag.Report(L, ErrorDiag) << Beg[0]; break; case 2: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1]; break; case 3: Diag.Report(L, ErrorDiag) << Beg[0] << Beg[1] << Beg[2]; break; - } } + + // Emit a full diagnostic for the path if we have a PathDiagnosticClient. + if (!PD) + return; + + if (D->empty()) { + PathDiagnosticPiece* piece = new PathDiagnosticPiece(L, R.getDescription()); + for ( ; Beg != End; ++Beg) piece->addRange(*Beg); + D->push_back(piece); + } + + PD->HandlePathDiagnostic(D.take()); } void BugReporter::EmitBasicReport(const char* name, const char* str, diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp index 4731921731fa..bfc9d9058b3c 100644 --- a/clang/lib/Analysis/CFRefCount.cpp +++ b/clang/lib/Analysis/CFRefCount.cpp @@ -2215,11 +2215,7 @@ namespace { return "[naming convention] leak of returned object"; } } - - virtual const char* getDescription() const { - return "Object leaked"; - } - + virtual void EmitWarnings(BugReporter& BR); virtual void GetErrorNodes(std::vector*>& Nodes); virtual bool isLeak() const { return true; } @@ -2256,15 +2252,15 @@ namespace { SymbolRef getSymbol() const { return Sym; } - virtual PathDiagnosticPiece* getEndPath(BugReporter& BR, - ExplodedNode* N); + PathDiagnosticPiece* getEndPath(BugReporter& BR, + const ExplodedNode* N); - virtual std::pair getExtraDescriptiveText(); + std::pair getExtraDescriptiveText(); - virtual PathDiagnosticPiece* VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, - BugReporter& BR); + PathDiagnosticPiece* VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, + BugReporter& BR); }; @@ -2313,9 +2309,9 @@ std::pair CFRefReport::getExtraDescriptiveText() { } } -PathDiagnosticPiece* CFRefReport::VisitNode(ExplodedNode* N, - ExplodedNode* PrevN, - ExplodedGraph& G, +PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N, + const ExplodedNode* PrevN, + const ExplodedGraph& G, BugReporter& BR) { // Check if the type state has changed. @@ -2486,14 +2482,14 @@ class VISIBILITY_HIDDEN FindUniqueBinding : }; } -static std::pair*,MemRegion*> -GetAllocationSite(GRStateManager* StateMgr, ExplodedNode* N, +static std::pair*,const MemRegion*> +GetAllocationSite(GRStateManager* StateMgr, const ExplodedNode* N, SymbolRef Sym) { // Find both first node that referred to the tracked symbol and the // memory location that value was store to. - ExplodedNode* Last = N; - MemRegion* FirstBinding = 0; + const ExplodedNode* Last = N; + const MemRegion* FirstBinding = 0; while (N) { const GRState* St = N->getState(); @@ -2515,8 +2511,8 @@ GetAllocationSite(GRStateManager* StateMgr, ExplodedNode* N, return std::make_pair(Last, FirstBinding); } -PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br, - ExplodedNode* EndN) { +PathDiagnosticPiece* +CFRefReport::getEndPath(BugReporter& br, const ExplodedNode* EndN) { GRBugReporter& BR = cast(br); @@ -2530,8 +2526,8 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br, // We are a leak. Walk up the graph to get to the first node where the // symbol appeared, and also get the first VarDecl that tracked object // is stored to. - ExplodedNode* AllocNode = 0; - MemRegion* FirstBinding = 0; + const ExplodedNode* AllocNode = 0; + const MemRegion* FirstBinding = 0; llvm::tie(AllocNode, FirstBinding) = GetAllocationSite(&BR.getStateManager(), EndN, Sym); @@ -2566,7 +2562,7 @@ PathDiagnosticPiece* CFRefReport::getEndPath(BugReporter& br, PathDiagnosticPiece::DisplayHint Hint = PathDiagnosticPiece::Above; assert (!EndN->pred_empty()); // Not possible to have 0 predecessors. - ExplodedNode *Pred = *(EndN->pred_begin()); + const ExplodedNode *Pred = *(EndN->pred_begin()); ProgramPoint PredPos = Pred->getLocation(); if (PostStmt* PredPS = dyn_cast(&PredPos)) { @@ -2664,8 +2660,8 @@ bool Leak::isCached(BugReport& R) { SymbolRef Sym = static_cast(R).getSymbol(); - ExplodedNode* AllocNode = - GetAllocationSite(0, R.getEndNode(), Sym).first; + const ExplodedNode* AllocNode = + GetAllocationSite(0, R.getEndNode(), Sym).first; if (!AllocNode) return false; diff --git a/clang/lib/Analysis/ExplodedGraph.cpp b/clang/lib/Analysis/ExplodedGraph.cpp index 945416b1b56e..4e41b60da377 100644 --- a/clang/lib/Analysis/ExplodedGraph.cpp +++ b/clang/lib/Analysis/ExplodedGraph.cpp @@ -120,36 +120,35 @@ ExplodedNodeImpl::NodeGroup::~NodeGroup() { if (getKind() == SizeOther) delete &getVector(getPtr()); } -ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, - ExplodedNodeImpl** EndSources) const{ +ExplodedGraphImpl* +ExplodedGraphImpl::Trim(const ExplodedNodeImpl* const* BeginSources, + const ExplodedNodeImpl* const* EndSources) const{ - typedef llvm::DenseMap Pass1Ty; - typedef llvm::DenseMap Pass2Ty; + typedef llvm::DenseMap Pass1Ty; + typedef llvm::DenseMap Pass2Ty; Pass1Ty Pass1; Pass2Ty Pass2; - llvm::SmallVector WL2; + llvm::SmallVector WL2; { // ===- Pass 1 (reverse BFS) -=== // Enqueue the source nodes to the first worklist. - std::list > WL1; - std::list > WL1_Loops; + std::list > WL1, WL1_Loops; - for (ExplodedNodeImpl** I = BeginSources; I != EndSources; ++I) + for (const ExplodedNodeImpl* const* I = BeginSources; I != EndSources; ++I) WL1.push_back(std::make_pair(*I, *I)); // Process the worklist. while (! (WL1.empty() && WL1_Loops.empty())) { - - ExplodedNodeImpl *N, *Src; - // Only dequeue from the "loops" worklist if WL1 has no items. // Thus we prioritize for paths that don't span loop boundaries. - + const ExplodedNodeImpl *N, *Src; + if (WL1.empty()) { N = WL1_Loops.back().first; Src = WL1_Loops.back().second; @@ -227,7 +226,7 @@ ExplodedGraphImpl* ExplodedGraphImpl::Trim(ExplodedNodeImpl** BeginSources, while (!WL2.empty()) { - ExplodedNodeImpl* N = WL2.back(); + const ExplodedNodeImpl* N = WL2.back(); WL2.pop_back(); // Skip this node if we have already processed it. diff --git a/clang/test/Analysis/NSString.m b/clang/test/Analysis/NSString.m index e01c994d313d..b123d62337c5 100644 --- a/clang/test/Analysis/NSString.m +++ b/clang/test/Analysis/NSString.m @@ -194,7 +194,7 @@ void f12() { } - (id)notShared { - return [[SharedClass alloc] _init]; // expected-warning{{This violates the naming convention rules}} + return [[SharedClass alloc] _init]; // expected-warning{{[naming convention] leak of returned object}} } + (id)sharedInstance { diff --git a/clang/test/Analysis/retain-release.m b/clang/test/Analysis/retain-release.m index 2b16ae8ad86c..0ce283ff24d2 100644 --- a/clang/test/Analysis/retain-release.m +++ b/clang/test/Analysis/retain-release.m @@ -149,8 +149,8 @@ CFDateRef f6(int x) { CFDateRef f7() { CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); - CFRetain(date); //expected-warning{{leak}} - date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); + CFRetain(date); + date = CFDateCreate(0, CFAbsoluteTimeGetCurrent()); //expected-warning{{leak}} return date; } -- GitLab From 72cd68fe64333b0e1005179fdbefacfa2db2e063 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 01:00:13 +0000 Subject: [PATCH 107/682] Make InstCombineStoreToCast handle aggregates more aggressively, handling the case in Transforms/InstCombine/cast-store-gep.ll, which is a heavily reduced testcase from Clang on x86-64. llvm-svn: 62904 --- .../Scalar/InstructionCombining.cpp | 66 ++++++++++++++----- .../Transforms/InstCombine/cast-store-gep.ll | 17 +++++ 2 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/cast-store-gep.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 8b20453a0e4b..dd55d65e1638 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7700,12 +7700,12 @@ Instruction *InstCombiner::commonCastTransforms(CastInst &CI) { /// FindElementAtOffset - Given a type and a constant offset, determine whether /// or not there is a sequence of GEP indices into the type that will land us at -/// the specified offset. If so, fill them into NewIndices and return true, -/// otherwise return false. -static bool FindElementAtOffset(const Type *Ty, int64_t Offset, - SmallVectorImpl &NewIndices, - const TargetData *TD) { - if (!Ty->isSized()) return false; +/// the specified offset. If so, fill them into NewIndices and return the +/// resultant element type, otherwise return null. +static const Type *FindElementAtOffset(const Type *Ty, int64_t Offset, + SmallVectorImpl &NewIndices, + const TargetData *TD) { + if (!Ty->isSized()) return 0; // Start with the index over the outer type. Note that the type size // might be zero (even if the offset isn't zero) if the indexed type @@ -7731,7 +7731,7 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset, while (Offset) { // Indexing into tail padding between struct/array elements. if (uint64_t(Offset*8) >= TD->getTypeSizeInBits(Ty)) - return false; + return 0; if (const StructType *STy = dyn_cast(Ty)) { const StructLayout *SL = TD->getStructLayout(STy); @@ -7751,11 +7751,11 @@ static bool FindElementAtOffset(const Type *Ty, int64_t Offset, Ty = AT->getElementType(); } else { // Otherwise, we can't index into the middle of this atomic type, bail. - return false; + return 0; } } - return true; + return Ty; } /// @brief Implement the transforms for cast of pointer (bitcast/ptrtoint) @@ -11139,7 +11139,8 @@ Instruction *InstCombiner::visitLoadInst(LoadInst &LI) { } /// InstCombineStoreToCast - Fold store V, (cast P) -> store (cast V), P -/// when possible. +/// when possible. This makes it generally easy to do alias analysis and/or +/// SROA/mem2reg of the memory object. static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { User *CI = cast(SI.getOperand(1)); Value *CastOp = CI->getOperand(0); @@ -11153,18 +11154,34 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { if (!DestPTy->isInteger() && !isa(DestPTy)) return 0; + /// NewGEPIndices - If SrcPTy is an aggregate type, we can emit a "noop gep" + /// to its first element. This allows us to handle things like: + /// store i32 xxx, (bitcast {foo*, float}* %P to i32*) + /// on 32-bit hosts. + SmallVector NewGEPIndices; + // If the source is an array, the code below will not succeed. Check to // see if a trivial 'gep P, 0, 0' will help matters. Only do this for // constants. - if (const ArrayType *ASrcTy = dyn_cast(SrcPTy)) - if (Constant *CSrc = dyn_cast(CastOp)) - if (ASrcTy->getNumElements() != 0) { - Value* Idxs[2]; - Idxs[0] = Idxs[1] = Constant::getNullValue(Type::Int32Ty); - CastOp = ConstantExpr::getGetElementPtr(CSrc, Idxs, 2); - SrcTy = cast(CastOp->getType()); - SrcPTy = SrcTy->getElementType(); + if (isa(SrcPTy) || isa(SrcPTy)) { + // Index through pointer. + Constant *Zero = Constant::getNullValue(Type::Int32Ty); + NewGEPIndices.push_back(Zero); + + while (1) { + if (const StructType *STy = dyn_cast(SrcPTy)) { + NewGEPIndices.push_back(Zero); + SrcPTy = STy->getElementType(0); + } else if (const ArrayType *ATy = dyn_cast(SrcPTy)) { + NewGEPIndices.push_back(Zero); + SrcPTy = ATy->getElementType(); + } else { + break; } + } + + SrcTy = PointerType::get(SrcPTy, SrcTy->getAddressSpace()); + } if (!SrcPTy->isInteger() && !isa(SrcPTy)) return 0; @@ -11192,6 +11209,19 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { if (isa(SIOp0->getType())) opcode = Instruction::PtrToInt; } + + // SIOp0 is a pointer to aggregate and this is a store to the first field, + // emit a GEP to index into its first field. + if (!NewGEPIndices.empty()) { + if (Constant *C = dyn_cast(CastOp)) + CastOp = ConstantExpr::getGetElementPtr(C, &NewGEPIndices[0], + NewGEPIndices.size()); + else + CastOp = IC.InsertNewInstBefore( + GetElementPtrInst::Create(CastOp, NewGEPIndices.begin(), + NewGEPIndices.end()), SI); + } + if (Constant *C = dyn_cast(SIOp0)) NewCast = ConstantExpr::getCast(opcode, C, CastDstTy); else diff --git a/llvm/test/Transforms/InstCombine/cast-store-gep.ll b/llvm/test/Transforms/InstCombine/cast-store-gep.ll new file mode 100644 index 000000000000..95a069d60b75 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/cast-store-gep.ll @@ -0,0 +1,17 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep inttoptr +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep alloca + +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-apple-darwin10.0" + %T = type { i8*, i8 } + +define i8* @test(i8* %Val, i64 %V) nounwind { +entry: + %A = alloca %T, align 8 + %mrv_gep = bitcast %T* %A to i64* ; [#uses=1] + %B = getelementptr %T* %A, i64 0, i32 0 ; [#uses=1] + + store i64 %V, i64* %mrv_gep + %C = load i8** %B, align 8 ; [#uses=1] + ret i8* %C +} -- GitLab From 899ecdbbba5af65d84f85f25430c966a8d332187 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 24 Jan 2009 01:27:33 +0000 Subject: [PATCH 108/682] Improve the inlining cost function a bit. Little practical effect. llvm-svn: 62908 --- llvm/lib/Transforms/Utils/InlineCost.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Utils/InlineCost.cpp b/llvm/lib/Transforms/Utils/InlineCost.cpp index 80516723d0ca..37d2c0352ace 100644 --- a/llvm/lib/Transforms/Utils/InlineCost.cpp +++ b/llvm/lib/Transforms/Utils/InlineCost.cpp @@ -121,9 +121,12 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) { } // Calls often compile into many machine instructions. Bump up their - // cost to reflect this. - if (!isa(II)) - NumInsts += 5; + // cost to reflect this. Allow an extra instruction per parameter. + if (!isa(II)) { + for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); + I != E; ++I) + NumInsts ++; + } } if (const AllocaInst *AI = dyn_cast(II)) { -- GitLab From b3fcaa7a7714a902bf2953ff7c1dc6c1a4c7858b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 24 Jan 2009 06:11:36 +0000 Subject: [PATCH 109/682] Fix crash ElementRegion::getRValueType() when the RvalueType of the ArrayRegion is a typedef and not (directly) a pointer. llvm-svn: 62909 --- clang/lib/Analysis/MemRegion.cpp | 15 ++++++--------- clang/test/Analysis/exercise-ps.c | 14 +++++++++++++- 2 files changed, 19 insertions(+), 10 deletions(-) diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp index 2724ed0ada22..55c6935b8e85 100644 --- a/clang/lib/Analysis/MemRegion.cpp +++ b/clang/lib/Analysis/MemRegion.cpp @@ -108,17 +108,14 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { } QualType ElementRegion::getRValueType(ASTContext& C) const { - QualType T = getArrayRegion()->getRValueType(C); + // Strip off typedefs from the ArrayRegion's RvalueType. + QualType T = getArrayRegion()->getRValueType(C)->getDesugaredType(); - if (isa(T.getTypePtr())) { - ArrayType* AT = cast(T.getTypePtr()); + if (ArrayType* AT = dyn_cast(T.getTypePtr())) return AT->getElementType(); - } - else { - PointerType* PtrT = cast(T.getTypePtr()); - QualType PTy = PtrT->getPointeeType(); - return C.getCanonicalType(PTy); - } + + PointerType* PtrT = cast(T.getTypePtr()); + return C.getCanonicalType(PtrT->getPointeeType()); } //===----------------------------------------------------------------------===// diff --git a/clang/test/Analysis/exercise-ps.c b/clang/test/Analysis/exercise-ps.c index 6d58e92c31f2..4aaba8e8dd05 100644 --- a/clang/test/Analysis/exercise-ps.c +++ b/clang/test/Analysis/exercise-ps.c @@ -2,7 +2,8 @@ // RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s && // RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s // -// Just exercise the analyzer (no assertions). +// Just exercise the analyzer on code that has at one point caused issues +// (i.e., no assertions or crashes). static const char * f1(const char *x, char *y) { @@ -10,3 +11,14 @@ static const char * f1(const char *x, char *y) { *y++ = *x++; } } + +// This following case checks that we properly handle typedefs when getting +// the RvalueType of an ElementRegion. +typedef struct F12_struct {} F12_typedef; +typedef void* void_typedef; +void_typedef f2_helper(); +static void f2(void *buf) { + F12_typedef* x; + x = f2_helper(); + memcpy((&x[1]), (buf), 1); +} -- GitLab From b239341ec43a951be107844189ae622dbe22b0a6 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 24 Jan 2009 08:11:59 +0000 Subject: [PATCH 110/682] Updated checker build. llvm-svn: 62914 --- clang/www/latest_checker.html.incl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/www/latest_checker.html.incl b/clang/www/latest_checker.html.incl index 77b1331898c2..56439ef56696 100644 --- a/clang/www/latest_checker.html.incl +++ b/clang/www/latest_checker.html.incl @@ -1 +1 @@ -checker-0.143.tar.bz2 (built January 22, 2009) +checker-0.144.tar.bz2 (built January 24, 2009) -- GitLab From 3334a44501a869ed011cc82f3d151fc86f6ba613 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 24 Jan 2009 08:32:22 +0000 Subject: [PATCH 111/682] Start filling in x86_64 ABI implementation. - No functionality change, moved behind -use-x86_64-abi option until it becomes non-experimental. llvm-svn: 62915 --- clang/lib/CodeGen/CGCall.cpp | 172 ++++++++++++++++++++++++++++++++--- 1 file changed, 159 insertions(+), 13 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index ac0eb1878f0d..cf0d4cc79bc5 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -21,9 +21,15 @@ #include "clang/AST/DeclObjC.h" #include "llvm/ADT/StringExtras.h" #include "llvm/Attributes.h" +#include "llvm/Support/CommandLine.h" using namespace clang; using namespace CodeGen; +static llvm::cl::opt +UseX86_64ABI("use-x86_64-abi", + llvm::cl::desc("Enable use of experimental x86_64 ABI."), + llvm::cl::init(false)); + /***/ // FIXME: Use iterator and sidestep silly type array creation. @@ -303,17 +309,6 @@ public: virtual ABIArgInfo classifyArgumentType(QualType RetTy, ASTContext &Context) const; }; - - -/// X86_32ABIInfo - The X86_64 ABI information. -class X86_64ABIInfo : public ABIInfo { -public: - virtual ABIArgInfo classifyReturnType(QualType RetTy, - ASTContext &Context) const; - - virtual ABIArgInfo classifyArgumentType(QualType RetTy, - ASTContext &Context) const; -}; } ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy, @@ -389,9 +384,159 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, } } +namespace { +/// X86_32ABIInfo - The X86_64 ABI information. +class X86_64ABIInfo : public ABIInfo { + enum Class { + Integer = 0, + SSE, + SSEUp, + X87, + X87Up, + ComplexX87, + NoClass, + Memory + }; + + /// classify - Determine the x86_64 register classes in which the + /// given type T should be passed. + /// + /// \param Lo - The classification for the low word of the type. + /// \param Hi - The classification for the high word of the type. + /// + /// If a word is unused its result will be NoClass; if a type should + /// be passed in Memory then at least the classification of \arg Lo + /// will be Memory. + /// + /// The \arg Lo class will be NoClass iff the argument is ignored. + /// + /// If the \arg Lo class is ComplexX87, then the \arg Hi class will + /// be NoClass. + void classify(QualType T, ASTContext &Context, + Class &Lo, Class &Hi) const; + +public: + virtual ABIArgInfo classifyReturnType(QualType RetTy, + ASTContext &Context) const; + + virtual ABIArgInfo classifyArgumentType(QualType RetTy, + ASTContext &Context) const; +}; +} + +void X86_64ABIInfo::classify(QualType Ty, + ASTContext &Context, + Class &Lo, Class &Hi) const { + Lo = Memory; + Hi = NoClass; + if (const BuiltinType *BT = Ty->getAsBuiltinType()) { + BuiltinType::Kind k = BT->getKind(); + + if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { + Lo = Integer; + } else if (k == BuiltinType::Float || k == BuiltinType::Double) { + Lo = SSE; + } else if (k == BuiltinType::LongDouble) { + Lo = X87; + Hi = X87Up; + } + // FIXME: _Decimal32, _Decimal64, and __m64 are SSE. + // FIXME: _float128, _Decimal128, and __m128 are (SSE, SSEUp). + // FIXME: __int128 is (Integer, Integer). + } else if (Ty->isPointerLikeType() || Ty->isBlockPointerType() || + Ty->isObjCQualifiedInterfaceType()) { + Lo = Integer; + } else if (const ComplexType *CT = Ty->getAsComplexType()) { + QualType ET = CT->getElementType(); + + if (ET == Context.FloatTy) + Lo = SSE; + else if (ET == Context.DoubleTy) + Lo = Hi = SSE; + else if (ET == Context.LongDoubleTy) + Lo = ComplexX87; + } +} + ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy, ASTContext &Context) const { - return ABIArgInfo::getDefault(); + // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the + // classification algorithm. + X86_64ABIInfo::Class Lo, Hi; + classify(RetTy, Context, Lo, Hi); + + const llvm::Type *ResType = 0; + switch (Lo) { + case NoClass: + assert(0 && "FIXME: Handle ignored return values."); + + case SSEUp: + case X87Up: + assert(0 && "Invalid classification for lo word."); + + // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via + // hidden argument, i.e. structret. + case Memory: + return ABIArgInfo::getStructRet(); + + // AMD64-ABI 3.2.3p4: Rule 3. If the class is INTEGER, the next + // available register of the sequence %rax, %rdx is used. + case Integer: + ResType = llvm::Type::Int64Ty; break; + + // AMD64-ABI 3.2.3p4: Rule 4. If the class is SSE, the next + // available SSE register of the sequence %xmm0, %xmm1 is used. + case SSE: + ResType = llvm::Type::DoubleTy; break; + + // AMD64-ABI 3.2.3p4: Rule 6. If the class is X87, the value is + // returned on the X87 stack in %st0 as 80-bit x87 number. + case X87: + ResType = llvm::Type::X86_FP80Ty; break; + + // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real + // part of the value is returned in %st0 and the imaginary part in + // %st1. + case ComplexX87: + assert(Hi == NoClass && "Unexpected ComplexX87 classification."); + ResType = llvm::VectorType::get(llvm::Type::X86_FP80Ty, 2); + break; + } + + switch (Hi) { + // Memory was handled previously, and ComplexX87 and X87 should + // never occur as hi classes. + case Memory: + case X87: + case ComplexX87: + assert(0 && "Invalid classification for hi word."); + + case NoClass: break; + case Integer: + assert(0 && "FIXME: Implement MRV"); break; + case SSE: + assert(0 && "FIXME: Implement MRV"); break; + + // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte + // is passed in the upper half of the last used SSE register. + // + // SSEUP should always be preceeded by SSE, just widen. + case SSEUp: + assert(Lo == SSE && "Unexpected SSEUp classification."); + ResType = llvm::VectorType::get(llvm::Type::DoubleTy, 2); + break; + + // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is + // returned together with the previos X87 value in %st0. + // + // X87UP should always be preceeded by X87, so we don't need to do + // anything here. + case X87Up: + assert(Lo == X87 && "Unexpected X87Up classification."); + break; + } + + return ABIArgInfo::getCoerce(ResType); } ABIArgInfo X86_64ABIInfo::classifyArgumentType(QualType Ty, @@ -421,7 +566,8 @@ const ABIInfo &CodeGenTypes::getABIInfo() const { case 32: return *(TheABIInfo = new X86_32ABIInfo()); case 64: - return *(TheABIInfo = new X86_64ABIInfo()); + if (UseX86_64ABI) + return *(TheABIInfo = new X86_64ABIInfo()); } } -- GitLab From ed4361ecbbdf3119c657bfc42cc0e7077b09d00a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 24 Jan 2009 08:43:22 +0000 Subject: [PATCH 112/682] Add simple make based harness for running ABI tests. llvm-svn: 62916 --- clang/utils/ABITest/TypeGen.py | 4 + clang/utils/ABITest/return-types/Makefile | 124 ++++++++++++++++++++++ 2 files changed, 128 insertions(+) create mode 100644 clang/utils/ABITest/return-types/Makefile diff --git a/clang/utils/ABITest/TypeGen.py b/clang/utils/ABITest/TypeGen.py index ce34a25e6428..3074a5627338 100644 --- a/clang/utils/ABITest/TypeGen.py +++ b/clang/utils/ABITest/TypeGen.py @@ -6,6 +6,10 @@ from Enumeration import * # - struct improvements (bitfields, flexible arrays, packed & # unpacked, alignment) +# - objective-c qualified id +# - anonymous / transparent unions +# - VLAs +# - block types ### # Actual type types diff --git a/clang/utils/ABITest/return-types/Makefile b/clang/utils/ABITest/return-types/Makefile new file mode 100644 index 000000000000..1a993b741be9 --- /dev/null +++ b/clang/utils/ABITest/return-types/Makefile @@ -0,0 +1,124 @@ +# Usage: make test.N.report +# +# COUNT can be over-ridden to change the number of tests generated per +# file, and TESTARGS is used to change the type generation. Make sure +# to 'make clean' after changing either of these parameters. + +ABITESTGEN := ../ABITestGen.py +TESTARGS := --max-args 0 --no-vector --no-complex --no-union +COUNT := 100 + +CFLAGS := -std=gnu99 + +X_COMPILER := llvm-gcc +X_LL_CFLAGS := -emit-llvm -S +Y_COMPILER := clang +Y_LL_CFLAGS := -emit-llvm +CC := gcc + +X_CFLAGS := -m32 +Y_CFLAGS := -arch i386 +CC_CFLAGS := -m32 + +.PHONY: test.%.report +test.%.report: test.%.xx.diff test.%.xy.diff test.%.yx.diff test.%.yy.diff + @for t in $^; do \ + if [ -s $$t ]; then \ + echo "TEST $*: $$t failed"; \ + fi; \ + done + +.PHONY: test.%.build +test.%.build: test.%.ref test.%.xx test.%.xy test.%.yx test.%.yy test.%.x.defs test.%.y.defs + @true + +### + +.PRECIOUS: test.%.xx.diff +test.%.xx.diff: test.%.ref.out test.%.xx.out + -diff $^ > $@ +.PRECIOUS: test.%.xy.diff +test.%.xy.diff: test.%.ref.out test.%.xy.out + -diff $^ > $@ +.PRECIOUS: test.%.yx.diff +test.%.yx.diff: test.%.ref.out test.%.yx.out + -diff $^ > $@ +.PRECIOUS: test.%.yy.diff +test.%.yy.diff: test.%.ref.out test.%.yy.out + -diff $^ > $@ +.PRECIOUS: test.%.defs.diff +test.%.defs.diff: test.%.x.defs test.%.y.defs + zipdifflines \ + --replace "%struct.T[0-9]+" "%struct.s" \ + --replace "byval align [0-9]+" "byval" \ + $^ > $@ + +.PRECIOUS: test.%.out +test.%.out: test.% + -./$< > $@ + +.PRECIOUS: test.%.ref +test.%.ref: test.%.driver.ref.o test.%.a.ref.o test.%.b.ref.o + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.xx +test.%.xx: test.%.driver.ref.o test.%.a.x.o test.%.b.x.o + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.xy +test.%.xy: test.%.driver.ref.o test.%.a.x.o test.%.b.y.o + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.yx +test.%.yx: test.%.driver.ref.o test.%.a.y.o test.%.b.x.o + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.yy +test.%.yy: test.%.driver.ref.o test.%.a.y.o test.%.b.y.o + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ + +.PRECIOUS: test.%.ref.o +test.%.ref.o: test.%.c + $(CC) -c $(CFLAGS) $(CC_CFLAGS) -o $@ $< +.PRECIOUS: test.%.x.o +test.%.x.o: test.%.c + $(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $< +.PRECIOUS: test.%.y.o +test.%.y.o: test.%.c + $(Y_COMPILER) -S $(CFLAGS) $(Y_CFLAGS) -o $@.s $< + as $(Y_CFLAGS) -o $@ $@.s + +.PRECIOUS: test.%.x.defs +test.%.x.defs: test.%.a.x.ll + grep '^define ' $< > $@ +.PRECIOUS: test.%.y.defs +test.%.y.defs: test.%.a.y.ll + grep '^define ' $< > $@ + +.PRECIOUS: test.%.a.x.ll +test.%.a.x.ll: test.%.a.c + $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $< +.PRECIOUS: test.%.b.x.ll +test.%.b.x.ll: test.%.b.c + $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $< +.PRECIOUS: test.%.a.y.ll +test.%.a.y.ll: test.%.a.c + $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $< +.PRECIOUS: test.%.b.y.ll +test.%.b.y.ll: test.%.b.c + $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $< + +.PHONY: test.%.top +test.%.top: test.%.a.c test.%.b.c test.%.driver.c + @true + +.PRECIOUS: test.%.a.c test.%.b.c test.%.driver.c +test.%.a.c: test.%.generate + @true +test.%.b.c: test.%.generate + @true +test.%.driver.c: test.%.generate + @true + +.PHONY: test.%.generate +test.%.generate: $(ABITESTGEN) + $(ABITESTGEN) $(TESTARGS) -o test.$*.a.c -T test.$*.b.c -D test.$*.driver.c --min=$(shell expr $* '*' $(COUNT)) --count=$(COUNT) + +clean: + rm -f test.* *~ -- GitLab From ee34b8f1791515cfacd4b5eec1e222b5636e1f14 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sat, 24 Jan 2009 10:07:43 +0000 Subject: [PATCH 113/682] Some cleanups. No functional changes. llvm-svn: 62917 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 60 +++++++++++++++----------- 1 file changed, 34 insertions(+), 26 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 8e86213f77c3..e99c70c16428 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -175,6 +175,8 @@ namespace { void RenumberValno(VNInfo* VN); void ReconstructLiveInterval(LiveInterval* LI); bool removeDeadSpills(SmallPtrSet& split); + unsigned getNumberOfSpills(SmallPtrSet& MIs, + unsigned Reg, int FrameIndex); VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use, MachineBasicBlock* MBB, LiveInterval* LI, @@ -1381,6 +1383,21 @@ PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs, return Change; } +unsigned PreAllocSplitting::getNumberOfSpills( + SmallPtrSet& MIs, + unsigned Reg, int FrameIndex) { + unsigned Spills = 0; + for (SmallPtrSet::iterator UI = MIs.begin(), UE = MIs.end(); + UI != UI; ++UI) { + int StoreFrameIndex; + unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex); + if (StoreVReg == Reg && StoreFrameIndex == FrameIndex) + Spills++; + } + + return Spills; +} + /// removeDeadSpills - After doing splitting, filter through all intervals we've /// split, and see if any of the spills are unnecessary. If so, remove them. bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { @@ -1417,34 +1434,25 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) { DefMI->eraseFromParent(); NumDeadSpills++; changed = true; - } else { - bool NonRestore = false; - for (SmallPtrSet::iterator UI = - VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); - UI != UI; ++UI) { - int StoreFrameIndex; - unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex); - if (StoreVReg != (*LI)->reg || StoreFrameIndex != FrameIndex) { - NonRestore = false; - break; - } - } - - if (NonRestore) continue; - - for (SmallPtrSet::iterator UI = - VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); - UI != UI; ++UI) { - LIs->RemoveMachineInstrFromMaps(*UI); - (*UI)->eraseFromParent(); - } + continue; + } + + unsigned SpillCount = getNumberOfSpills(VNUseCount[CurrVN], + (*LI)->reg, FrameIndex); + if (SpillCount != VNUseCount[CurrVN].size()) continue; - LIs->RemoveMachineInstrFromMaps(DefMI); - (*LI)->removeValNo(CurrVN); - DefMI->eraseFromParent(); - NumDeadSpills++; - changed = true; + for (SmallPtrSet::iterator UI = + VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end(); + UI != UI; ++UI) { + LIs->RemoveMachineInstrFromMaps(*UI); + (*UI)->eraseFromParent(); } + + LIs->RemoveMachineInstrFromMaps(DefMI); + (*LI)->removeValNo(CurrVN); + DefMI->eraseFromParent(); + NumDeadSpills++; + changed = true; } } -- GitLab From 73ff92272ffa6b343b541832cc2e39d72a98629f Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sat, 24 Jan 2009 11:30:49 +0000 Subject: [PATCH 114/682] void* is represented as pointer to empty struct {}. Thus we need to check whether the struct is empty before trying to index into it. This fixes PR3381. llvm-svn: 62918 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index dd55d65e1638..aed086709327 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -11170,6 +11170,8 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { while (1) { if (const StructType *STy = dyn_cast(SrcPTy)) { + if (!STy->getNumElements()) /* Void is represented as {} */ + break; NewGEPIndices.push_back(Zero); SrcPTy = STy->getElementType(0); } else if (const ArrayType *ATy = dyn_cast(SrcPTy)) { -- GitLab From 142ccc0e157e287b9b8434bf4f61b0cbc3ea1293 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 24 Jan 2009 15:58:40 +0000 Subject: [PATCH 115/682] Add more documentation mentioning the limitations due to PR2660. llvm-svn: 62919 --- llvm/docs/LangRef.html | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/llvm/docs/LangRef.html b/llvm/docs/LangRef.html index f2d7d8d1680c..35f83b48d4f5 100644 --- a/llvm/docs/LangRef.html +++ b/llvm/docs/LangRef.html @@ -1344,6 +1344,13 @@ value.

+ +

Note that the code generator does not yet support large integer types +to be used as function return types. The specific limit on how large a +return type the code generator can currently handle is target-dependent; +currently it's often 64 bits for 32-bit targets and 128 bits for 64-bit +targets.

+ @@ -1404,6 +1411,11 @@ As a special case, however, zero length arrays are recognized to be variable length. This allows implementation of 'pascal style arrays' with the LLVM type "{ i32, [0 x float]}", for example.

+

Note that the code generator does not yet support large aggregate types +to be used as function return types. The specific limit on how large an +aggregate return type the code generator can currently handle is +target-dependent, and also dependent on the aggregate element types.

+ @@ -1489,6 +1501,12 @@ instruction.

an i32. + +

Note that the code generator does not yet support large aggregate types +to be used as function return types. The specific limit on how large an +aggregate return type the code generator can currently handle is +target-dependent, and also dependent on the aggregate element types.

+ @@ -1593,6 +1611,12 @@ be any integer or floating point type.

Vector of 2 64-bit integer values. + +

Note that the code generator does not yet support large vector types +to be used as function return types. The specific limit on how large a +vector return type codegen can currently handle is target-dependent; +currently it's often a few times longer than a hardware vector register.

+ @@ -2042,8 +2066,13 @@ return value.

ret { i32, i8 } { i32 4, i8 2 } ; Return an aggregate of values 4 and 2 -

Note that the code generator does not yet fully support larger - aggregate return values.

+

Note that the code generator does not yet fully support large + return values. The specific sizes that are currently supported are + dependent on the target. For integers, on 32-bit targets the limit + is often 64 bits, and on 64-bit targets the limit is often 128 bits. + For aggregate types, the current limits are dependent on the element + types; for example targets are often limited to 2 total integer + elements and 2 total floating-point elements.

-- GitLab From f4395ea97a7d1ab5191ba1b6e916c26328e7b20a Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sat, 24 Jan 2009 17:16:04 +0000 Subject: [PATCH 116/682] testcase for PR3381. Also it was an empty struct, not a void after all. llvm-svn: 62920 --- .../Transforms/Scalar/InstructionCombining.cpp | 2 +- .../InstCombine/2009-01-24-EmptyStruct.ll | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index aed086709327..40289eaf6bfd 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -11170,7 +11170,7 @@ static Instruction *InstCombineStoreToCast(InstCombiner &IC, StoreInst &SI) { while (1) { if (const StructType *STy = dyn_cast(SrcPTy)) { - if (!STy->getNumElements()) /* Void is represented as {} */ + if (!STy->getNumElements()) /* Struct can be empty {} */ break; NewGEPIndices.push_back(Zero); SrcPTy = STy->getElementType(0); diff --git a/llvm/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll b/llvm/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll new file mode 100644 index 000000000000..313e76d028d0 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2009-01-24-EmptyStruct.ll @@ -0,0 +1,18 @@ +; RUN: llvm-as < %s | opt -instcombine +; PR3381 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.atomic_t = type { i32 } + %struct.inode = type { i32, %struct.mutex } + %struct.list_head = type { %struct.list_head*, %struct.list_head* } + %struct.lock_class_key = type { } + %struct.mutex = type { %struct.atomic_t, %struct.rwlock_t, %struct.list_head } + %struct.rwlock_t = type { %struct.lock_class_key } + +define void @handle_event(%struct.inode* %bar) nounwind { +entry: + %0 = getelementptr %struct.inode* %bar, i64 -1, i32 1, i32 1 ; <%struct.rwlock_t*> [#uses=1] + %1 = bitcast %struct.rwlock_t* %0 to i32* ; [#uses=1] + store i32 1, i32* %1, align 4 + ret void +} -- GitLab From 73fd5a56513325016d7cf309710ad412fd8e472b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sat, 24 Jan 2009 17:32:54 +0000 Subject: [PATCH 117/682] Add a PR comment to this test. llvm-svn: 62921 --- llvm/test/CodeGen/X86/pr3018.ll | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/CodeGen/X86/pr3018.ll b/llvm/test/CodeGen/X86/pr3018.ll index 7d335ee2f6de..ba84711c03eb 100644 --- a/llvm/test/CodeGen/X86/pr3018.ll +++ b/llvm/test/CodeGen/X86/pr3018.ll @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep {orl \$1} +; PR3018 define i32 @test(i32 %A) nounwind { %B = or i32 %A, 1 -- GitLab From b66a312f93d8ec3d1aa3584228fe45abed5b1667 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 24 Jan 2009 17:47:50 +0000 Subject: [PATCH 118/682] Ignore parens when determining if an expr is a string literal. Fixes PR3382. llvm-svn: 62922 --- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/test/Sema/init.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index e766ca06a5e1..0fb939e23abc 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1031,7 +1031,7 @@ bool Sema::CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT) { StringLiteral *Sema::IsStringLiteralInit(Expr *Init, QualType DeclType) { const ArrayType *AT = Context.getAsArrayType(DeclType); if (AT && AT->getElementType()->isCharType()) { - return dyn_cast(Init); + return dyn_cast(Init->IgnoreParens()); } return 0; } diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index edaaf64b8be3..9f0867869a98 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -78,3 +78,5 @@ struct s1 s2 = { .b = bogus // expected-error {{use of undeclared identifier 'bogus'}} } +// PR3382 +char t[] = ("Hello"); -- GitLab From a0b892113a9977575b3ca647339225c0302cfeee Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 24 Jan 2009 18:03:09 +0000 Subject: [PATCH 119/682] Handle the 'e' constraint. Fixes PR3385 llvm-svn: 62923 --- clang/lib/Basic/Targets.cpp | 6 ++++-- clang/test/Sema/asm.c | 6 ++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 4128946493ee..026641c7c7db 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -505,8 +505,10 @@ X86TargetInfo::validateAsmConstraint(char c, case 'y': // Any MMX register. case 'x': // Any SSE register. case 'Q': // Any register accessible as [r]h: a, b, c, and d. - case 'Z': // 32-bit integer constant for use with zero-extending x86_64 - // instructions. + case 'e': // 32-bit signed integer constant for use with zero-extending + // x86_64 instructions. + case 'Z': // 32-bit unsigned integer constant for use with zero-extending + // x86_64 instructions. case 'N': // unsigned 8-bit integer constant for use with in and out // instructions. info = (TargetInfo::ConstraintInfo)(info|TargetInfo::CI_AllowsRegister); diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c index 4093b1abeb94..fa9b125b6dd4 100644 --- a/clang/test/Sema/asm.c +++ b/clang/test/Sema/asm.c @@ -54,3 +54,9 @@ void test5() { asm("nop" : : "X" (8)); } + +// PR3385 +void test6(long i) +{ + asm("nop" : : "er"(i)); +} \ No newline at end of file -- GitLab From 134a02586e25f60811096c038492f4c8e17917da Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 24 Jan 2009 19:08:01 +0000 Subject: [PATCH 120/682] Fix invalid evaluation of _Complex float (real & imaginary parts had mismatched semantics). - Enforce this in APValue. llvm-svn: 62924 --- clang/include/clang/AST/APValue.h | 4 ++++ clang/lib/AST/ExprConstant.cpp | 10 ++++++++-- clang/test/Sema/const-eval.c | 3 +++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h index d88757de1a3d..5d5abfe011d4 100644 --- a/clang/include/clang/AST/APValue.h +++ b/clang/include/clang/AST/APValue.h @@ -188,11 +188,15 @@ public: ((Vec*)(void*)Data)->Elts[i] = E[i]; } void setComplexInt(const APSInt &R, const APSInt &I) { + assert(R.getBitWidth() == I.getBitWidth() && + "Invalid complex int (type mismatch)."); assert(isComplexInt() && "Invalid accessor"); ((ComplexAPSInt*)(void*)Data)->Real = R; ((ComplexAPSInt*)(void*)Data)->Imag = I; } void setComplexFloat(const APFloat &R, const APFloat &I) { + assert(&R.getSemantics() == &I.getSemantics() && + "Invalid complex float (type mismatch)."); assert(isComplexFloat() && "Invalid accessor"); ((ComplexAPFloat*)(void*)Data)->Real = R; ((ComplexAPFloat*)(void*)Data)->Imag = I; diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index f45bd787b569..16c6e89c3293 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -1194,7 +1194,8 @@ public: if (!EvaluateFloat(E->getSubExpr(), Result, Info)) return APValue(); - return APValue(APFloat(0.0), Result); + return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), + Result); } APValue VisitCastExpr(CastExpr *E) { @@ -1206,7 +1207,8 @@ public: if (!EvaluateFloat(SubExpr, Result, Info)) return APValue(); - return APValue(Result, APFloat(0.0)); + return APValue(Result, + APFloat(Result.getSemantics(), APFloat::fcZero)); } // FIXME: Handle more casts. @@ -1221,6 +1223,10 @@ public: static bool EvaluateComplexFloat(const Expr *E, APValue &Result, EvalInfo &Info) { Result = ComplexFloatExprEvaluator(Info).Visit(const_cast(E)); + if (Result.isComplexFloat()) + assert(&Result.getComplexFloatReal().getSemantics() == + &Result.getComplexFloatImag().getSemantics() && + "Invalid complex evaluation."); return Result.isComplexFloat(); } diff --git a/clang/test/Sema/const-eval.c b/clang/test/Sema/const-eval.c index e3d63ca94fb3..71f76228d1b9 100644 --- a/clang/test/Sema/const-eval.c +++ b/clang/test/Sema/const-eval.c @@ -26,3 +26,6 @@ void f() int a; EVAL_EXPR(15, (_Bool)&a); // expected-error {{fields must have a constant size}} } + +// FIXME: Turn into EVAL_EXPR test once we have more folding. +_Complex float g16 = (1.0f + 1.0fi); -- GitLab From 3cedd4dc643b548da418a77609329d2922aafcb3 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sat, 24 Jan 2009 19:30:25 +0000 Subject: [PATCH 121/682] add note about possible GEP improvement with fields of size 0. llvm-svn: 62925 --- llvm/lib/Target/README.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/llvm/lib/Target/README.txt b/llvm/lib/Target/README.txt index c679fd83c0da..78dcb12581c6 100644 --- a/llvm/lib/Target/README.txt +++ b/llvm/lib/Target/README.txt @@ -1683,3 +1683,9 @@ Always foldable for odd constants, what is the rule for even? //===---------------------------------------------------------------------===// +PR 3381: GEP to field of size 0 inside a struct could be turned into GEP +for next field in struct (which is at same address). + +For example: store of float into { {{}}, float } could be turned into a store to +the float directly. + -- GitLab From b1355b1545e7d32d504e8aa06cdc09bac13c549b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 19:46:37 +0000 Subject: [PATCH 122/682] minor formatting changes, no functionality change. llvm-svn: 62926 --- clang/lib/Sema/SemaExpr.cpp | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 202f07b4bf5e..9a4977d09b9a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1016,19 +1016,23 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, const SourceRange &ExprRange, bool isSizeof) { // C99 6.5.3.4p1: - if (isa(exprType) && isSizeof) + if (isa(exprType)) { // alignof(function) is allowed. - Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange; - else if (exprType->isVoidType()) + if (isSizeof) + Diag(OpLoc, diag::ext_sizeof_function_type) << ExprRange; + return false; + } + + if (exprType->isVoidType()) { Diag(OpLoc, diag::ext_sizeof_void_type) << (isSizeof ? "sizeof" : "__alignof") << ExprRange; - else - return DiagnoseIncompleteType(OpLoc, exprType, - isSizeof ? diag::err_sizeof_incomplete_type : - diag::err_alignof_incomplete_type, - ExprRange); + return false; + } - return false; + return DiagnoseIncompleteType(OpLoc, exprType, + isSizeof ? diag::err_sizeof_incomplete_type : + diag::err_alignof_incomplete_type, + ExprRange); } /// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and @@ -1059,8 +1063,8 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. return Owned(new (Context) SizeOfAlignOfExpr(isSizeof, isType, TyOrEx, - Context.getSizeType(), OpLoc, - Range.getEnd())); + Context.getSizeType(), OpLoc, + Range.getEnd())); } QualType Sema::CheckRealImagOperand(Expr *&V, SourceLocation Loc) { -- GitLab From 619393762b88650d6df0ffa833e12d50b2f81cd0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 19:49:13 +0000 Subject: [PATCH 123/682] fix a fixme, don't leak the expr on error. llvm-svn: 62927 --- clang/lib/Sema/SemaExpr.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9a4977d09b9a..fa4c9d620af4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1049,18 +1049,23 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, if (isType) { ArgTy = QualType::getFromOpaquePtr(TyOrEx); Range = ArgRange; + + // Verify that the operand is valid. + if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof)) + return ExprError(); } else { // Get the end location. Expr *ArgEx = (Expr *)TyOrEx; Range = ArgEx->getSourceRange(); ArgTy = ArgEx->getType(); + + // Verify that the operand is valid. + if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof)) { + DeleteExpr(ArgEx); + return ExprError(); + } } - // Verify that the operand is valid. - // FIXME: This might leak the expression. - if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof)) - return ExprError(); - // C99 6.5.3.4p4: the type (an unsigned integer type) is size_t. return Owned(new (Context) SizeOfAlignOfExpr(isSizeof, isType, TyOrEx, Context.getSizeType(), OpLoc, -- GitLab From 8dff0176955d9e28e58bfa6f1bafcdb33fb93032 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 20:17:12 +0000 Subject: [PATCH 124/682] Fix PR3386 by handling GCC's rules for alignof, which are substantially different than those for sizeof. Reject alignof(bitfield) like gcc does. llvm-svn: 62928 --- clang/include/clang/Basic/DiagnosticKinds.def | 2 ++ clang/lib/Sema/Sema.h | 1 + clang/lib/Sema/SemaExpr.cpp | 29 ++++++++++++++++++- clang/test/Sema/exprs.c | 9 ++++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 1858f2583bec..5cb71fc9bfb1 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -1188,6 +1188,8 @@ DIAG(err_sizeof_incomplete_type, ERROR, "invalid application of 'sizeof' to an incomplete type %0") DIAG(err_alignof_incomplete_type, ERROR, "invalid application of '__alignof' to an incomplete type %0") +DIAG(err_alignof_bitfield, ERROR, + "invalid application of '__alignof' to bitfield") DIAG(err_offsetof_record_type, ERROR, "offsetof requires struct, union, or class type, %0 invalid") DIAG(err_offsetof_array_type, ERROR, diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 40cfe8f1938a..a993ebe2cbd9 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1003,6 +1003,7 @@ public: ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, void *TyOrEx, const SourceRange &ArgRange); + bool CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, const SourceRange &R); bool CheckSizeOfAlignOfOperand(QualType type, SourceLocation OpLoc, const SourceRange &R, bool isSizeof); diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index fa4c9d620af4..56ad4b5f2617 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1035,6 +1035,27 @@ bool Sema::CheckSizeOfAlignOfOperand(QualType exprType, ExprRange); } +bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, + const SourceRange &ExprRange) { + E = E->IgnoreParens(); + + // alignof decl is always ok. + if (isa(E)) + return false; + + if (MemberExpr *ME = dyn_cast(E)) { + if (FieldDecl *FD = dyn_cast(ME->getMemberDecl())) { + if (FD->isBitField()) { + Diag(OpLoc, diag::err_alignof_bitfield) << ExprRange; + return true; + } + // Other fields are ok. + return false; + } + } + return CheckSizeOfAlignOfOperand(E->getType(), OpLoc, ExprRange, false); +} + /// ActOnSizeOfAlignOfExpr - Handle @c sizeof(type) and @c sizeof @c expr and /// the same for @c alignof and @c __alignof /// Note that the ArgRange is invalid if isType is false. @@ -1060,7 +1081,13 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, ArgTy = ArgEx->getType(); // Verify that the operand is valid. - if (CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, isSizeof)) { + bool isInvalid; + if (isSizeof) + isInvalid = CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, true); + else + isInvalid = CheckAlignOfExpr(ArgEx, OpLoc, Range); + + if (isInvalid) { DeleteExpr(ArgEx); return ExprError(); } diff --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c index 73d73ebe7b1b..5413757df79a 100644 --- a/clang/test/Sema/exprs.c +++ b/clang/test/Sema/exprs.c @@ -45,3 +45,12 @@ int test8(void) { __builtin_choose_expr (0, 42, i) = 10; // expected-warning {{extension used}} return i; } + + +// PR3386 +struct f { int x : 4; float y[]; }; +int test9(struct f *P) { + return __alignof(P->x) + // expected-error {{invalid application of '__alignof' to bitfield}} expected-warning {{extension used}} + __alignof(P->y); // ok. expected-warning {{extension used}} +} + -- GitLab From 9e3ad5220d7ede24c9266d0540f483766df50784 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 24 Jan 2009 20:21:50 +0000 Subject: [PATCH 125/682] This patch builds the meta-class object for each implemented class in objc2's nonfrigile abi. llvm-svn: 62929 --- clang/lib/CodeGen/CGObjCMac.cpp | 246 ++++++++++++++++++++++---------- 1 file changed, 171 insertions(+), 75 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 1b0027a96be0..a7c6aee56207 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -344,6 +344,10 @@ protected: llvm::Constant *GetPropertyTypeString(const ObjCPropertyDecl *PD, const Decl *Container); + /// GetClassName - Return a unique constant for the given selector's + /// name. The return value has type char *. + llvm::Constant *GetClassName(IdentifierInfo *Ident); + public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { } @@ -475,10 +479,6 @@ private: /// defined. The return value has type ProtocolPtrTy. llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); - /// GetClassName - Return a unique constant for the given selector's - /// name. The return value has type char *. - llvm::Constant *GetClassName(IdentifierInfo *Ident); - public: CGObjCMac(CodeGen::CodeGenModule &cgm); @@ -547,6 +547,16 @@ private: /// processing a translation unit. void FinishNonFragileABIModule(); + llvm::GlobalVariable * BuildClassRoTInitializer(unsigned flags, + unsigned InstanceStart, + unsigned InstanceSize, + const ObjCImplementationDecl *ID); + void BuildClassMetaData(std::string &ClassName, + llvm::Constant *IsAGV, llvm::Constant *SuperClassGV, + llvm::Constant *ClassRoGV); + + + public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); // FIXME. All stubs for now! @@ -2207,7 +2217,7 @@ llvm::Value *CGObjCMac::EmitSelector(CGBuilderTy &Builder, Selector Sel) { return Builder.CreateLoad(Entry, false, "tmp"); } -llvm::Constant *CGObjCMac::GetClassName(IdentifierInfo *Ident) { +llvm::Constant *CGObjCCommonMac::GetClassName(IdentifierInfo *Ident) { llvm::GlobalVariable *&Entry = ClassNames[Ident]; if (!Entry) { @@ -2971,12 +2981,14 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul // uint32 count; // struct _iver_t list[count]; // } - IvarListnfABIPtrTy = llvm::StructType::get(IntTy, - IntTy, - llvm::ArrayType::get( - IvarnfABITy, 0), - NULL); - CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABIPtrTy); + IvarListnfABITy = llvm::StructType::get(IntTy, + IntTy, + llvm::ArrayType::get( + IvarnfABITy, 0), + NULL); + CGM.getModule().addTypeName("struct._ivar_list_t", IvarListnfABITy); + + IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy); // struct _class_ro_t { // uint32_t const flags; @@ -3083,6 +3095,101 @@ void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { } +// Metadata flags +enum MetaDataDlags { + CLS = 0x0, + CLS_META = 0x1, + CLS_ROOT = 0x2, + CLS_HIDDEN = 0x10, + CLS_EXCEPTION = 0x20 +}; +/// BuildClassRoTInitializer - generate meta-data for: +/// struct _class_ro_t { +/// uint32_t const flags; +/// uint32_t const instanceStart; +/// uint32_t const instanceSize; +/// uint32_t const reserved; // only when building for 64bit targets +/// const uint8_t * const ivarLayout; +/// const char *const name; +/// const struct _method_list_t * const baseMethods; +/// const struct _objc_protocol_list *const baseProtocols; +/// const struct _ivar_list_t *const ivars; +/// const uint8_t * const weakIvarLayout; +/// const struct _prop_list_t * const properties; +/// } +/// +llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( + unsigned flags, + unsigned InstanceStart, + unsigned InstanceSize, + const ObjCImplementationDecl *ID) { + std::string ClassName = ID->getNameAsString(); + std::vector Values(10); // 11 for 64bit targets! + Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, flags); + Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart); + Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize); + // FIXME. For 64bit targets add 0 here. + Values[ 3] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + Values[ 4] = GetClassName(ID->getIdentifier()); + Values[ 5] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); + Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); + Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, + Values); + llvm::GlobalVariable *CLASS_RO_GV = + new llvm::GlobalVariable(ObjCTypes.ClassRonfABITy, false, + llvm::GlobalValue::InternalLinkage, + Init, + (flags & CLS_META) ? + std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : + std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, + &CGM.getModule()); + CLASS_RO_GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + UsedGlobals.push_back(CLASS_RO_GV); + return CLASS_RO_GV; +} + +/// BuildClassMetaData - This routine defines that to-level meta-data +/// for the given ClassName for: +/// struct _class_t { +/// struct _class_t *isa; +/// struct _class_t * const superclass; +/// void *cache; +/// IMP *vtable; +/// struct class_ro_t *ro; +/// } +/// +void CGObjCNonFragileABIMac::BuildClassMetaData(std::string &ClassName, + llvm::Constant *IsAGV, + llvm::Constant *SuperClassGV, + llvm::Constant *ClassRoGV) { + std::vector Values(5); + Values[0] = IsAGV; + Values[1] = SuperClassGV; + Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar + Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar + Values[4] = ClassRoGV; // &CLASS_RO_GV + llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, + Values); + llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(ClassName); + if (GV) + GV->setInitializer(Init); + else + GV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + Init, + ClassName, + &CGM.getModule()); + GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + UsedGlobals.push_back(GV); + // FIXME! why? + GV->setAlignment(32); + +} + void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { std::string ClassName = ID->getNameAsString(); if (!ObjCEmptyCacheVar) { @@ -3105,70 +3212,59 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { &CGM.getModule()); UsedGlobals.push_back(ObjCEmptyVtableVar); } - - std::vector Values(11); // 11 for 64bit targets! - // Generate following meta-data: - // struct _class_ro_t { - // uint32_t const flags; - // uint32_t const instanceStart; - // uint32_t const instanceSize; - // uint32_t const reserved; // only when building for 64bit targets - // const uint8_t * const ivarLayout; - // const char *const name; - // const struct _method_list_t * const baseMethods; - // const struct _objc_protocol_list *const baseProtocols; - // const struct _ivar_list_t *const ivars; - // const uint8_t * const weakIvarLayout; - // const struct _prop_list_t * const properties; - // } - Values[ 0] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); - Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); - Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); - Values[ 3] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); - // FIXME. For 64bit targets add 0 here. - Values[ 4] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); - Values[ 5] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); - Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); - Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); - Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); - Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); - Values[10] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); - llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, - Values); - llvm::GlobalVariable *CLASS_RO_GV = - new llvm::GlobalVariable(ObjCTypes.ClassRonfABITy, false, - llvm::GlobalValue::InternalLinkage, - Init, - std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, - &CGM.getModule()); - CLASS_RO_GV->setSection(".section __DATA,__data,regular,no_dead_strip"); - UsedGlobals.push_back(CLASS_RO_GV); - - // Generate following meta-data: - // struct _class_t { - // struct _class_t *isa; - // struct _class_t * const superclass; - // void *cache; - // IMP *vtable; - // struct class_ro_t *ro; - // } - Values.resize(5); - Values[0] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); - Values[1] = llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); - Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar - Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar - Values[4] = CLASS_RO_GV; // &CLASS_RO_GV - Init = llvm::ConstantStruct::get(ObjCTypes.ClassnfABITy, Values); - llvm::GlobalVariable *GV = - new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, - llvm::GlobalValue::ExternalLinkage, - Init, - std::string("\01_OBJC_CLASS_$_")+ClassName, - &CGM.getModule()); - GV->setSection(".section __DATA,__data,regular,no_dead_strip"); - UsedGlobals.push_back(GV); - // FIXME! why? - GV->setAlignment(32); + uint32_t InstanceStart = + CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassnfABITy); + uint32_t InstanceSize = InstanceStart; + uint32_t flags = CLS_META; + std::string ObjCMetaClassName("\01_OBJC_METACLASS_$_"); + std::string ObjCClassName("\01_OBJC_CLASS_$_"); + + llvm::GlobalVariable *SuperClassGV, *IsAGV; + + if (ID->getClassInterface() && !ID->getClassInterface()->getSuperClass()) { + // class is root + flags |= CLS_ROOT; + std::string SuperClassName = ObjCClassName + ClassName; + SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName); + if (!SuperClassGV) + SuperClassGV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + 0, + SuperClassName, + &CGM.getModule()); + UsedGlobals.push_back(SuperClassGV); + std::string IsAClassName = ObjCMetaClassName + ClassName; + IsAGV = CGM.getModule().getGlobalVariable(IsAClassName); + if (!IsAGV) + IsAGV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + 0, + IsAClassName, + &CGM.getModule()); + UsedGlobals.push_back(IsAGV); + } else { + // Not a root. + std::string RootClassName = + ID->getClassInterface()->getSuperClass()->getNameAsString(); + std::string SuperClassName = ObjCMetaClassName + RootClassName; + SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName); + if (!SuperClassGV) + SuperClassGV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + 0, + SuperClassName, + &CGM.getModule()); + UsedGlobals.push_back(SuperClassGV); + IsAGV = SuperClassGV; + } + llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, + InstanceStart, + InstanceSize,ID); + std::string MetaClassName = ObjCMetaClassName + ClassName; + BuildClassMetaData(MetaClassName, IsAGV, SuperClassGV, CLASS_RO_GV); } /* *** */ -- GitLab From 096d3ecb5196ebae3bcc35949a6212ee59730ac5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 20:24:49 +0000 Subject: [PATCH 126/682] remove dead code. llvm-svn: 62930 --- clang/lib/CodeGen/CGExprConstant.cpp | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index b7c4f7fd39f8..9d709d3a509d 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -517,21 +517,6 @@ public: else return llvm::ConstantExpr::getFPExtend(Src, DstTy); } - - llvm::Constant *EmitSizeAlignOf(QualType TypeToSize, - QualType RetType, bool isSizeOf) { - std::pair Info = - CGM.getContext().getTypeInfo(TypeToSize); - - uint64_t Val = isSizeOf ? Info.first : Info.second; - Val /= 8; // Return size in bytes, not bits. - - assert(RetType->isIntegerType() && "Result type must be an integer!"); - - uint32_t ResultWidth = - static_cast(CGM.getContext().getTypeSize(RetType)); - return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); - } public: llvm::Constant *EmitLValue(Expr *E) { -- GitLab From 7bf46469f388a9d50ef29aa8759458978f43b07d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 21:08:33 +0000 Subject: [PATCH 127/682] fix some const-correctness issues. llvm-svn: 62931 --- clang/include/clang/AST/Expr.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a93f0f467b18..19cd5d5786bc 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -647,10 +647,14 @@ public: assert(isArgumentType() && "calling getArgumentType() when arg is expr"); return QualType::getFromOpaquePtr(Argument.Ty); } - Expr* getArgumentExpr() const { + Expr *getArgumentExpr() { assert(!isArgumentType() && "calling getArgumentExpr() when arg is type"); return static_cast(Argument.Ex); } + const Expr *getArgumentExpr() const { + return const_cast(this)->getArgumentExpr(); + } + /// Gets the argument type, or the type of the argument expression, whichever /// is appropriate. QualType getTypeOfArgument() const { -- GitLab From 24aeeab05c259ab46911da59057e12ea05fd8484 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 21:09:06 +0000 Subject: [PATCH 128/682] Improve handling of alignof. alignof(VLA) now works properly for example. llvm-svn: 62932 --- clang/lib/AST/ExprConstant.cpp | 63 +++++++++++++++++++++++++++------- 1 file changed, 50 insertions(+), 13 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 16c6e89c3293..6d1d150c1c16 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -508,6 +508,8 @@ public: private: bool HandleCast(CastExpr* E); + uint64_t GetAlignOfExpr(const Expr *E); + uint64_t GetAlignOfType(QualType T); }; } // end anonymous namespace @@ -842,6 +844,41 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr()); } +uint64_t IntExprEvaluator::GetAlignOfType(QualType T) { + const Type *Ty = Info.Ctx.getCanonicalType(T).getTypePtr(); + + // __alignof__(void) = 1 as a gcc extension. + if (Ty->isVoidType()) + return 1; + + // GCC extension: alignof(function) = 4. + // FIXME: AlignOf shouldn't be unconditionally 4! It should listen to the + // attribute(align) directive. + if (Ty->isFunctionType()) + return 4; + + if (const ASQualType *ASQT = dyn_cast(Ty)) + return GetAlignOfType(QualType(ASQT->getBaseType(), 0)); + + // alignof VLA/incomplete array. + if (const ArrayType *VAT = dyn_cast(Ty)) + return GetAlignOfType(VAT->getElementType()); + + // sizeof (objc class)? + if (isa(Ty)) + return 1; // FIXME: This probably isn't right. + + // Get information about the alignment. + unsigned CharSize = Info.Ctx.Target.getCharWidth(); + return Info.Ctx.getTypeAlign(Ty) / CharSize; +} + +uint64_t IntExprEvaluator::GetAlignOfExpr(const Expr *E) { + + return GetAlignOfType(E->getType()); +} + + /// VisitSizeAlignOfExpr - Evaluate a sizeof or alignof with a result as the /// expression's type. bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { @@ -850,6 +887,15 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { Result.zextOrTrunc(getIntTypeSizeInBits(DstTy)); Result.setIsUnsigned(DstTy->isUnsignedIntegerType()); + // Handle alignof separately. + if (!E->isSizeOf()) { + if (E->isArgumentType()) + Result = GetAlignOfType(E->getArgumentType()); + else + Result = GetAlignOfExpr(E->getArgumentExpr()); + return true; + } + QualType SrcTy = E->getTypeOfArgument(); // sizeof(void) and __alignof__(void) = 1 as a gcc extension. @@ -859,31 +905,22 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { } // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. - // FIXME: But alignof(vla) is! - if (!SrcTy->isConstantSizeType()) { - // FIXME: Should we attempt to evaluate this? + if (!SrcTy->isConstantSizeType()) return false; - } // sizeof (objc class) ? if (SrcTy->isObjCInterfaceType()) return false; - bool isSizeOf = E->isSizeOf(); - // GCC extension: sizeof(function) = 1. if (SrcTy->isFunctionType()) { - // FIXME: AlignOf shouldn't be unconditionally 4! - Result = isSizeOf ? 1 : 4; + Result = 1; return true; } - // Get information about the size or align. + // Get information about the size. unsigned CharSize = Info.Ctx.Target.getCharWidth(); - if (isSizeOf) - Result = Info.Ctx.getTypeSize(SrcTy) / CharSize; - else - Result = Info.Ctx.getTypeAlign(SrcTy) / CharSize; + Result = Info.Ctx.getTypeSize(SrcTy) / CharSize; return true; } -- GitLab From 04964bbebe2f70f8d839b2e55236d522896c5199 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 21:09:45 +0000 Subject: [PATCH 129/682] remove a bunch of alignment handling code out of CGExprScalar, since alignment must always be a constant. Just let the constant folder do it. llvm-svn: 62933 --- clang/lib/CodeGen/CGExprScalar.cpp | 38 ++++++++++++++---------------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index fc87726a2115..b1150cb2d10b 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -673,45 +673,43 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { /// argument of the sizeof expression as an integer. Value * ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { + // Handle alignof with the constant folding logic. alignof always produces a + // constant. + if (!E->isSizeOf()) { + Expr::EvalResult Result; + E->Evaluate(Result, CGF.getContext()); + return llvm::ConstantInt::get(Result.Val.getInt()); + } + QualType RetType = E->getType(); assert(RetType->isIntegerType() && "Result type must be an integer!"); uint32_t ResultWidth = static_cast(CGF.getContext().getTypeSize(RetType)); - + + // sizeof(void) and sizeof(function) = 1 as a strange gcc extension. QualType TypeToSize = E->getTypeOfArgument(); - // sizeof(void) and __alignof__(void) = 1 as a gcc extension. Also - // for function types. - // FIXME: what is alignof a function type in gcc? if (TypeToSize->isVoidType() || TypeToSize->isFunctionType()) return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1)); if (const VariableArrayType *VAT = CGF.getContext().getAsVariableArrayType(TypeToSize)) { - if (E->isSizeOf()) { - if (E->isArgumentType()) { - // sizeof(type) - make sure to emit the VLA size. - CGF.EmitVLASize(TypeToSize); - } - return CGF.GetVLASize(VAT); + if (E->isArgumentType()) { + // sizeof(type) - make sure to emit the VLA size. + CGF.EmitVLASize(TypeToSize); } - - // alignof - QualType BaseType = CGF.getContext().getBaseElementType(VAT); - uint64_t Align = CGF.getContext().getTypeAlign(BaseType); - - Align /= 8; // Return alignment in bytes, not bits. - return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Align)); + return CGF.GetVLASize(VAT); } + if (TypeToSize->isObjCInterfaceType()) { ObjCInterfaceDecl *OI = TypeToSize->getAsObjCInterfaceType()->getDecl(); RecordDecl *RD = const_cast( CGF.getContext().addRecordToClass(OI)); TypeToSize = CGF.getContext().getTagDeclType(static_cast(RD)); } - std::pair Info = CGF.getContext().getTypeInfo(TypeToSize); - uint64_t Val = E->isSizeOf() ? Info.first : Info.second; - Val /= 8; // Return size in bytes, not bits. + uint64_t Val = CGF.getContext().getTypeSize(TypeToSize); + // Return size in bytes, not bits. + Val /= CGF.getContext().Target.getCharWidth(); return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); } -- GitLab From 9ed6efdd751653ae46c264d1c653ef6bce2afa2c Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sat, 24 Jan 2009 21:16:55 +0000 Subject: [PATCH 130/682] Add support for declaring pointers to members. Add serialization support for ReferenceType. llvm-svn: 62934 --- clang/include/clang/AST/ASTContext.h | 10 ++- clang/include/clang/AST/Type.h | 70 ++++++++++++++-- clang/include/clang/Basic/DiagnosticKinds.def | 4 + clang/include/clang/Parse/DeclSpec.h | 80 ++++++++++++++----- clang/include/clang/Parse/Ownership.h | 2 +- clang/lib/AST/ASTContext.cpp | 51 +++++++++++- clang/lib/AST/Type.cpp | 42 +++++++++- clang/lib/AST/TypeSerialization.cpp | 51 ++++++++++-- clang/lib/Parse/ParseDecl.cpp | 52 +++++++++--- clang/lib/Sema/SemaCXXScopeSpec.cpp | 1 + clang/lib/Sema/SemaType.cpp | 57 +++++++++++-- clang/test/SemaCXX/member-pointer.cpp | 14 ++++ 12 files changed, 378 insertions(+), 56 deletions(-) create mode 100644 clang/test/SemaCXX/member-pointer.cpp diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 12f89c3fb96d..9ac6027570f3 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -60,6 +60,7 @@ class ASTContext { llvm::FoldingSet PointerTypes; llvm::FoldingSet BlockPointerTypes; llvm::FoldingSet ReferenceTypes; + llvm::FoldingSet MemberPointerTypes; llvm::FoldingSet ConstantArrayTypes; llvm::FoldingSet IncompleteArrayTypes; std::vector VariableArrayTypes; @@ -185,11 +186,16 @@ public: /// getBlockPointerType - Return the uniqued reference to the type for a block /// of the specified type. QualType getBlockPointerType(QualType T); - + /// getReferenceType - Return the uniqued reference to the type for a /// reference to the specified type. QualType getReferenceType(QualType T); - + + /// getMemberPointerType - Return the uniqued reference to the type for a + /// member pointer to the specified type in the specified class. The class + /// is a Type because it could be a dependent name. + QualType getMemberPointerType(QualType T, const Type *Cls); + /// getVariableArrayType - Returns a non-unique reference to the type for a /// variable array of the specified element type. QualType getVariableArrayType(QualType EltTy, Expr *NumElts, diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 29e829c190c6..baa2016f553b 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -46,6 +46,7 @@ namespace clang { class PointerType; class BlockPointerType; class ReferenceType; + class MemberPointerType; class VectorType; class ArrayType; class ConstantArrayType; @@ -66,7 +67,7 @@ namespace clang { class ObjCQualifiedIdType; class ObjCQualifiedInterfaceType; class StmtIteratorBase; - + /// QualType - For efficiency, we don't store CVR-qualified types as nodes on /// their own: instead each reference to a type stores the qualifiers. This /// greatly reduces the number of nodes we need to allocate for types (for @@ -237,7 +238,7 @@ namespace clang { class Type { public: enum TypeClass { - Builtin, Complex, Pointer, Reference, + Builtin, Complex, Pointer, Reference, MemberPointer, ConstantArray, VariableArray, IncompleteArray, DependentSizedArray, Vector, ExtVector, FunctionNoProto, FunctionProto, @@ -337,6 +338,8 @@ public: bool isBlockPointerType() const; bool isReferenceType() const; bool isFunctionPointerType() const; + bool isMemberPointerType() const; + bool isMemberFunctionPointerType() const; bool isArrayType() const; bool isConstantArrayType() const; bool isIncompleteArrayType() const; @@ -363,13 +366,14 @@ public: // Type Checking Functions: Check to see if this type is structurally the // specified type, ignoring typedefs and qualifiers, and return a pointer to // the best type we can. - const BuiltinType *getAsBuiltinType() const; - const FunctionType *getAsFunctionType() const; - const FunctionTypeProto *getAsFunctionTypeProto() const; + const BuiltinType *getAsBuiltinType() const; + const FunctionType *getAsFunctionType() const; + const FunctionTypeProto *getAsFunctionTypeProto() const; const PointerLikeType *getAsPointerLikeType() const; // Pointer or Reference. const PointerType *getAsPointerType() const; const BlockPointerType *getAsBlockPointerType() const; const ReferenceType *getAsReferenceType() const; + const MemberPointerType *getAsMemberPointerType() const; const RecordType *getAsRecordType() const; const RecordType *getAsStructureType() const; /// NOTE: getAs*ArrayType are methods on ASTContext. @@ -665,6 +669,53 @@ public: static bool classof(const Type *T) { return T->getTypeClass() == Reference; } static bool classof(const ReferenceType *) { return true; } + +protected: + virtual void EmitImpl(llvm::Serializer& S) const; + static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D); + friend class Type; +}; + +/// MemberPointerType - C++ 8.3.3 - Pointers to members +/// +class MemberPointerType : public Type, public llvm::FoldingSetNode { + QualType PointeeType; + /// The class of which the pointee is a member. Must ultimately be a + /// RecordType, but could be a typedef or a template parameter too. + const Type *Class; + + MemberPointerType(QualType Pointee, const Type *Cls, QualType CanonicalPtr) : + Type(MemberPointer, CanonicalPtr, + Cls->isDependentType() || Pointee->isDependentType()), + PointeeType(Pointee), Class(Cls) { + } + friend class ASTContext; // ASTContext creates these. +public: + + QualType getPointeeType() const { return PointeeType; } + + const Type *getClass() const { return Class; } + + virtual void getAsStringInternal(std::string &InnerString) const; + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getPointeeType(), getClass()); + } + static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee, + const Type *Class) { + ID.AddPointer(Pointee.getAsOpaquePtr()); + ID.AddPointer(Class); + } + + static bool classof(const Type *T) { + return T->getTypeClass() == MemberPointer; + } + static bool classof(const MemberPointerType *) { return true; } + +protected: + virtual void EmitImpl(llvm::Serializer& S) const; + static Type* CreateImpl(ASTContext& Context, llvm::Deserializer& D); + friend class Type; }; /// ArrayType - C99 6.7.5.2 - Array Declarators. @@ -1576,6 +1627,15 @@ inline bool Type::isFunctionPointerType() const { else return false; } +inline bool Type::isMemberPointerType() const { + return isa(CanonicalType.getUnqualifiedType()); +} +inline bool Type::isMemberFunctionPointerType() const { + if (const MemberPointerType* T = getAsMemberPointerType()) + return T->getPointeeType()->isFunctionType(); + else + return false; +} inline bool Type::isArrayType() const { return isa(CanonicalType.getUnqualifiedType()); } diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 5cb71fc9bfb1..a2a1ca4c9fa5 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -1161,6 +1161,10 @@ DIAG(err_illegal_decl_array_of_references, ERROR, "'%0' declared as array of references") DIAG(err_illegal_decl_pointer_to_reference, ERROR, "'%0' declared as a pointer to a reference") +DIAG(err_illegal_decl_mempointer_to_void, ERROR, + "'%0' declared as a member pointer to void") +DIAG(err_illegal_decl_mempointer_in_nonclass, ERROR, + "'%0' does not point into a class") DIAG(err_illegal_decl_reference_to_reference, ERROR, "%0 declared as a reference to a reference") DIAG(err_invalid_reference_qualifier_application, ERROR, diff --git a/clang/include/clang/Parse/DeclSpec.h b/clang/include/clang/Parse/DeclSpec.h index d4ac25a25092..d4d363b0104f 100644 --- a/clang/include/clang/Parse/DeclSpec.h +++ b/clang/include/clang/Parse/DeclSpec.h @@ -429,9 +429,9 @@ typedef llvm::SmallVector CachedTokens; /// This is intended to be a small value object. struct DeclaratorChunk { enum { - Pointer, Reference, Array, Function, BlockPointer + Pointer, Reference, Array, Function, BlockPointer, MemberPointer } Kind; - + /// Loc - The place where this type was defined. SourceLocation Loc; @@ -544,39 +544,64 @@ struct DeclaratorChunk { void destroy() {} }; + struct MemberPointerTypeInfo { + /// The type qualifiers: const/volatile/restrict. + unsigned TypeQuals : 3; + AttributeList *AttrList; + // CXXScopeSpec has a constructor, so it can't be a direct member. + // So we need some pointer-aligned storage and a bit of trickery. + union { + void *Aligner; + char Mem[sizeof(CXXScopeSpec)]; + } ScopeMem; + CXXScopeSpec &Scope() { + return *reinterpret_cast(ScopeMem.Mem); + } + const CXXScopeSpec &Scope() const { + return *reinterpret_cast(ScopeMem.Mem); + } + void destroy() { + delete AttrList; + Scope().~CXXScopeSpec(); + } + }; + union { - PointerTypeInfo Ptr; - ReferenceTypeInfo Ref; - ArrayTypeInfo Arr; - FunctionTypeInfo Fun; - BlockPointerTypeInfo Cls; + PointerTypeInfo Ptr; + ReferenceTypeInfo Ref; + ArrayTypeInfo Arr; + FunctionTypeInfo Fun; + BlockPointerTypeInfo Cls; + MemberPointerTypeInfo Mem; }; - + void destroy() { switch (Kind) { default: assert(0 && "Unknown decl type!"); - case DeclaratorChunk::Function: return Fun.destroy(); - case DeclaratorChunk::Pointer: return Ptr.destroy(); - case DeclaratorChunk::BlockPointer: return Cls.destroy(); - case DeclaratorChunk::Reference: return Ref.destroy(); - case DeclaratorChunk::Array: return Arr.destroy(); + case DeclaratorChunk::Function: return Fun.destroy(); + case DeclaratorChunk::Pointer: return Ptr.destroy(); + case DeclaratorChunk::BlockPointer: return Cls.destroy(); + case DeclaratorChunk::Reference: return Ref.destroy(); + case DeclaratorChunk::Array: return Arr.destroy(); + case DeclaratorChunk::MemberPointer: return Mem.destroy(); } } - + /// getAttrs - If there are attributes applied to this declaratorchunk, return /// them. const AttributeList *getAttrs() const { switch (Kind) { default: assert(0 && "Unknown declarator kind!"); - case Pointer: return Ptr.AttrList; - case Reference: return Ref.AttrList; - case Array: return 0; - case Function: return 0; - case BlockPointer: return 0; // FIXME: Do blocks have attr list? + case Pointer: return Ptr.AttrList; + case Reference: return Ref.AttrList; + case MemberPointer: return Mem.AttrList; + case Array: return 0; + case Function: return 0; + case BlockPointer: return 0; // FIXME: Do blocks have attr list? } } - - + + /// getPointer - Return a DeclaratorChunk for a pointer. /// static DeclaratorChunk getPointer(unsigned TypeQuals, SourceLocation Loc, @@ -633,6 +658,19 @@ struct DeclaratorChunk { I.Cls.TypeQuals = TypeQuals; return I; } + + static DeclaratorChunk getMemberPointer(const CXXScopeSpec &SS, + unsigned TypeQuals, + SourceLocation Loc, + AttributeList *AL) { + DeclaratorChunk I; + I.Kind = MemberPointer; + I.Loc = Loc; + I.Mem.TypeQuals = TypeQuals; + I.Mem.AttrList = AL; + new (I.Mem.ScopeMem.Mem) CXXScopeSpec(SS); + return I; + } }; /// Declarator - Information about one declarator, including the parsed type diff --git a/clang/include/clang/Parse/Ownership.h b/clang/include/clang/Parse/Ownership.h index 2144481c3d1d..14c4bbf067f1 100644 --- a/clang/include/clang/Parse/Ownership.h +++ b/clang/include/clang/Parse/Ownership.h @@ -103,7 +103,7 @@ // conversions. // Flip this switch to measure performance impact of the smart pointers. -//#define DISABLE_SMART_POINTERS +#define DISABLE_SMART_POINTERS namespace clang { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d20387dd95ee..f3243c25ae71 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -85,6 +85,7 @@ void ASTContext::PrintStats() const { unsigned NumBuiltin = 0, NumPointer = 0, NumArray = 0, NumFunctionP = 0; unsigned NumVector = 0, NumComplex = 0, NumBlockPointer = 0; unsigned NumFunctionNP = 0, NumTypeName = 0, NumTagged = 0, NumReference = 0; + unsigned NumMemberPointer = 0; unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0; unsigned NumObjCInterfaces = 0, NumObjCQualifiedInterfaces = 0; @@ -101,6 +102,8 @@ void ASTContext::PrintStats() const { ++NumBlockPointer; else if (isa(T)) ++NumReference; + else if (isa(T)) + ++NumMemberPointer; else if (isa(T)) ++NumComplex; else if (isa(T)) @@ -142,6 +145,7 @@ void ASTContext::PrintStats() const { fprintf(stderr, " %d pointer types\n", NumPointer); fprintf(stderr, " %d block pointer types\n", NumBlockPointer); fprintf(stderr, " %d reference types\n", NumReference); + fprintf(stderr, " %d member pointer types\n", NumMemberPointer); fprintf(stderr, " %d complex types\n", NumComplex); fprintf(stderr, " %d array types\n", NumArray); fprintf(stderr, " %d vector types\n", NumVector); @@ -164,6 +168,7 @@ void ASTContext::PrintStats() const { fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+ NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+ NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+ + NumMemberPointer*sizeof(MemberPointerType)+ NumFunctionP*sizeof(FunctionTypeProto)+ NumFunctionNP*sizeof(FunctionTypeNoProto)+ NumTypeName*sizeof(TypedefType)+NumTagged*sizeof(TagType)+ @@ -374,7 +379,19 @@ ASTContext::getTypeInfo(const Type *T) { // FIXME: This is wrong for struct layout: a reference in a struct has // pointer size. return getTypeInfo(cast(T)->getPointeeType()); - + case Type::MemberPointer: { + // Note that this is not only platform- but also ABI-dependent. We follow + // the GCC ABI, where pointers to data are one pointer large, pointers to + // functions two pointers. But if we want to support ABI compatibility with + // other compilers too, we need to delegate this completely to TargetInfo. + QualType Pointee = cast(T)->getPointeeType(); + unsigned AS = Pointee.getAddressSpace(); + Width = Target.getPointerWidth(AS); + if (Pointee->isFunctionType()) + Width *= 2; + Align = Target.getPointerAlign(AS); + // GCC aligns at single pointer width. + } case Type::Complex: { // Complex types have the same alignment as their elements, but twice the // size. @@ -808,6 +825,38 @@ QualType ASTContext::getReferenceType(QualType T) { return QualType(New, 0); } +/// getMemberPointerType - Return the uniqued reference to the type for a +/// member pointer to the specified type, in the specified class. +QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) +{ + // Unique pointers, to guarantee there is only one pointer of a particular + // structure. + llvm::FoldingSetNodeID ID; + MemberPointerType::Profile(ID, T, Cls); + + void *InsertPos = 0; + if (MemberPointerType *PT = + MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos)) + return QualType(PT, 0); + + // If the pointee or class type isn't canonical, this won't be a canonical + // type either, so fill in the canonical type field. + QualType Canonical; + if (!T->isCanonical()) { + Canonical = getMemberPointerType(getCanonicalType(T),getCanonicalType(Cls)); + + // Get the new insert position for the node we care about. + MemberPointerType *NewIP = + MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos); + assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; + } + void *Mem = Allocator.Allocate(sizeof(MemberPointerType), 8); + MemberPointerType *New = new (Mem) MemberPointerType(T, Cls, Canonical); + Types.push_back(New); + MemberPointerTypes.InsertNode(New, InsertPos); + return QualType(New, 0); +} + /// getConstantArrayType - Return the unique reference to the type for an /// array of the specified element type. QualType ASTContext::getConstantArrayType(QualType EltTy, diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 94968920391d..ebaa01135555 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -288,6 +288,24 @@ const ReferenceType *Type::getAsReferenceType() const { return getDesugaredType()->getAsReferenceType(); } +const MemberPointerType *Type::getAsMemberPointerType() const { + // If this is directly a member pointer type, return it. + if (const MemberPointerType *MTy = dyn_cast(this)) + return MTy; + + // If the canonical form of this type isn't the right kind, reject it. + if (!isa(CanonicalType)) { + // Look through type qualifiers + if (isa(CanonicalType.getUnqualifiedType())) + return CanonicalType.getUnqualifiedType()->getAsMemberPointerType(); + return 0; + } + + // If this is a typedef for a member pointer type, strip the typedef off + // without losing all typedef information. + return getDesugaredType()->getAsMemberPointerType(); +} + /// isVariablyModifiedType (C99 6.7.5p3) - Return true for variable length /// array types and types that contain variable array types in their /// declarator @@ -300,8 +318,11 @@ bool Type::isVariablyModifiedType() const { if (const Type *T = getArrayElementTypeNoTypeQual()) return T->isVariablyModifiedType(); - // A pointer can point to a variably modified type - if (const PointerType *PT = getAsPointerType()) + // A pointer can point to a variably modified type. + // Also, C++ references and member pointers can point to a variably modified + // type, where VLAs appear as an extension to C++, and should be treated + // correctly. + if (const PointerLikeType *PT = getAsPointerLikeType()) return PT->getPointeeType()->isVariablyModifiedType(); // A function can return a variably modified type @@ -633,6 +654,7 @@ bool Type::isScalarType() const { return ASQT->getBaseType()->isScalarType(); return isa(CanonicalType) || isa(CanonicalType) || + isa(CanonicalType) || isa(CanonicalType) || isa(CanonicalType); } @@ -702,9 +724,9 @@ bool Type::isPODType() const { case Builtin: case Complex: case Pointer: + case MemberPointer: case Vector: case ExtVector: - // FIXME: pointer-to-member return true; case Tagged: @@ -951,6 +973,20 @@ void ReferenceType::getAsStringInternal(std::string &S) const { getPointeeType().getAsStringInternal(S); } +void MemberPointerType::getAsStringInternal(std::string &S) const { + std::string C; + Class->getAsStringInternal(C); + C += "::*"; + S = C + S; + + // Handle things like 'int (&A)[4];' correctly. + // FIXME: this should include vectors, but vectors use attributes I guess. + if (isa(getPointeeType())) + S = '(' + S + ')'; + + getPointeeType().getAsStringInternal(S); +} + void ConstantArrayType::getAsStringInternal(std::string &S) const { S += '['; S += llvm::utostr(getSize().getZExtValue()); diff --git a/clang/lib/AST/TypeSerialization.cpp b/clang/lib/AST/TypeSerialization.cpp index 4f3eeca28c69..12c3d03c1214 100644 --- a/clang/lib/AST/TypeSerialization.cpp +++ b/clang/lib/AST/TypeSerialization.cpp @@ -93,21 +93,29 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) { case Type::IncompleteArray: D.RegisterPtr(PtrID,IncompleteArrayType::CreateImpl(Context,D)); break; - + + case Type::MemberPointer: + D.RegisterPtr(PtrID, MemberPointerType::CreateImpl(Context, D)); + break; + case Type::Pointer: - D.RegisterPtr(PtrID,PointerType::CreateImpl(Context,D)); + D.RegisterPtr(PtrID, PointerType::CreateImpl(Context, D)); break; case Type::BlockPointer: - D.RegisterPtr(PtrID,BlockPointerType::CreateImpl(Context,D)); + D.RegisterPtr(PtrID, BlockPointerType::CreateImpl(Context, D)); break; - + + case Type::Reference: + D.RegisterPtr(PtrID, ReferenceType::CreateImpl(Context, D)); + break; + case Type::Tagged: - D.RegisterPtr(PtrID,TagType::CreateImpl(Context,D)); + D.RegisterPtr(PtrID, TagType::CreateImpl(Context, D)); break; - + case Type::TypeName: - D.RegisterPtr(PtrID,TypedefType::CreateImpl(Context,D)); + D.RegisterPtr(PtrID, TypedefType::CreateImpl(Context, D)); break; case Type::TypeOfExp: @@ -123,7 +131,7 @@ void Type::Create(ASTContext& Context, unsigned i, Deserializer& D) { break; case Type::VariableArray: - D.RegisterPtr(PtrID,VariableArrayType::CreateImpl(Context,D)); + D.RegisterPtr(PtrID, VariableArrayType::CreateImpl(Context, D)); break; } } @@ -242,6 +250,33 @@ Type* PointerType::CreateImpl(ASTContext& Context, Deserializer& D) { return Context.getPointerType(QualType::ReadVal(D)).getTypePtr(); } +//===----------------------------------------------------------------------===// +// ReferenceType +//===----------------------------------------------------------------------===// + +void ReferenceType::EmitImpl(Serializer& S) const { + S.Emit(getPointeeType()); +} + +Type* ReferenceType::CreateImpl(ASTContext& Context, Deserializer& D) { + return Context.getReferenceType(QualType::ReadVal(D)).getTypePtr(); +} + +//===----------------------------------------------------------------------===// +// MemberPointerType +//===----------------------------------------------------------------------===// + +void MemberPointerType::EmitImpl(Serializer& S) const { + S.Emit(getPointeeType()); + S.Emit(QualType(Class, 0)); +} + +Type* MemberPointerType::CreateImpl(ASTContext& Context, Deserializer& D) { + QualType Pointee = QualType::ReadVal(D); + QualType Class = QualType::ReadVal(D); + return Context.getMemberPointerType(Pointee, Class.getTypePtr()).getTypePtr(); +} + //===----------------------------------------------------------------------===// // TagType //===----------------------------------------------------------------------===// diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 7f5c0988ed6b..0ac9e0898229 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1550,10 +1550,10 @@ void Parser::ParseDeclarator(Declarator &D) { /// isn't parsed at all, making this function effectively parse the C++ /// ptr-operator production. /// -/// declarator: [C99 6.7.5] -/// pointer[opt] direct-declarator -/// [C++] '&' declarator [C++ 8p4, dcl.decl] -/// [GNU] '&' restrict[opt] attributes[opt] declarator +/// declarator: [C99 6.7.5] [C++ 8p4, dcl.decl] +/// [C] pointer[opt] direct-declarator +/// [C++] direct-declarator +/// [C++] ptr-operator declarator /// /// pointer: [C99 6.7.5] /// '*' type-qualifier-list[opt] @@ -1563,11 +1563,41 @@ void Parser::ParseDeclarator(Declarator &D) { /// '*' cv-qualifier-seq[opt] /// '&' /// [GNU] '&' restrict[opt] attributes[opt] -/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] [TODO] +/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] void Parser::ParseDeclaratorInternal(Declarator &D, DirectDeclParseFunction DirectDeclParser) { - tok::TokenKind Kind = Tok.getKind(); + // C++ member pointers start with a '::' or a nested-name. + // Member pointers get special handling, since there's no place for the + // scope spec in the generic path below. + if ((Tok.is(tok::coloncolon) || Tok.is(tok::identifier) || + Tok.is(tok::annot_cxxscope)) && getLang().CPlusPlus) { + CXXScopeSpec SS; + if (ParseOptionalCXXScopeSpecifier(SS)) { + if(Tok.isNot(tok::star)) { + // The scope spec really belongs to the direct-declarator. + D.getCXXScopeSpec() = SS; + if (DirectDeclParser) + (this->*DirectDeclParser)(D); + return; + } + + SourceLocation Loc = ConsumeToken(); + DeclSpec DS; + ParseTypeQualifierListOpt(DS); + + // Recurse to parse whatever is left. + ParseDeclaratorInternal(D, DirectDeclParser); + + // Sema will have to catch (syntactically invalid) pointers into global + // scope. It has to catch pointers into namespace scope anyway. + D.AddTypeInfo(DeclaratorChunk::getMemberPointer(SS,DS.getTypeQualifiers(), + Loc,DS.TakeAttributes())); + return; + } + } + + tok::TokenKind Kind = Tok.getKind(); // Not a pointer, C++ reference, or block. if (Kind != tok::star && (Kind != tok::amp || !getLang().CPlusPlus) && (Kind != tok::caret || !getLang().Blocks)) { @@ -1575,16 +1605,16 @@ void Parser::ParseDeclaratorInternal(Declarator &D, (this->*DirectDeclParser)(D); return; } - + // Otherwise, '*' -> pointer, '^' -> block, '&' -> reference. SourceLocation Loc = ConsumeToken(); // Eat the * or &. if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) { // Is a pointer. DeclSpec DS; - + ParseTypeQualifierListOpt(DS); - + // Recursively parse the declarator. ParseDeclaratorInternal(D, DirectDeclParser); if (Kind == tok::star) @@ -1680,7 +1710,9 @@ void Parser::ParseDirectDeclarator(Declarator &D) { if (getLang().CPlusPlus) { if (D.mayHaveIdentifier()) { - bool afterCXXScope = ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec()); + // ParseDeclaratorInternal might already have parsed the scope. + bool afterCXXScope = D.getCXXScopeSpec().isSet() || + ParseOptionalCXXScopeSpecifier(D.getCXXScopeSpec()); if (afterCXXScope) { // Change the declaration context for name lookup, until this function // is exited (and the declarator has been parsed). diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 0c0fa35a5e76..699f8908079c 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -50,6 +50,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S, return cast(SD); } + // FIXME: Template parameters and dependent types. // FIXME: C++0x scoped enums // Fall through to produce an error: we found something that isn't diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index ecae79320dd4..21db14a2ae9b 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -287,9 +287,9 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { !T->isIncompleteOrObjectType()) { Diag(DeclType.Loc, diag::err_typecheck_invalid_restrict_invalid_pointee) << T; - DeclType.Ptr.TypeQuals &= QualType::Restrict; - } - + DeclType.Ptr.TypeQuals &= ~QualType::Restrict; + } + // Apply the pointer typequals to the pointer object. T = Context.getPointerType(T).getQualifiedType(DeclType.Ptr.TypeQuals); break; @@ -424,7 +424,7 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { } break; } - case DeclaratorChunk::Function: + case DeclaratorChunk::Function: { // If the function declarator has a prototype (i.e. it is not () and // does not have a K&R-style identifier list), then the arguments are part // of the type, otherwise the argument list is (). @@ -518,7 +518,54 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { } break; } - + case DeclaratorChunk::MemberPointer: + // The scope spec must refer to a class, or be dependent. + DeclContext *DC = static_cast( + DeclType.Mem.Scope().getScopeRep()); + QualType ClsType; + // FIXME: Extend for dependent types when it's actually supported. + // See ActOnCXXNestedNameSpecifier. + if (CXXRecordDecl *RD = dyn_cast_or_null(DC)) { + ClsType = Context.getTagDeclType(RD); + } else { + if (DC) { + Diag(DeclType.Mem.Scope().getBeginLoc(), + diag::err_illegal_decl_mempointer_in_nonclass) + << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name") + << DeclType.Mem.Scope().getRange(); + } + D.setInvalidType(true); + ClsType = Context.IntTy; + } + + // C++ 8.3.3p3: A pointer to member shall not pointer to ... a member + // with reference type, or "cv void." + if (T->isReferenceType()) { + Diag(DeclType.Loc, diag::err_illegal_decl_pointer_to_reference) + << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name"); + D.setInvalidType(true); + T = Context.IntTy; + } + if (T->isVoidType()) { + Diag(DeclType.Loc, diag::err_illegal_decl_mempointer_to_void) + << (D.getIdentifier() ? D.getIdentifier()->getName() : "type name"); + T = Context.IntTy; + } + + // Enforce C99 6.7.3p2: "Types other than pointer types derived from + // object or incomplete types shall not be restrict-qualified." + if ((DeclType.Mem.TypeQuals & QualType::Restrict) && + !T->isIncompleteOrObjectType()) { + Diag(DeclType.Loc, diag::err_typecheck_invalid_restrict_invalid_pointee) + << T; + DeclType.Mem.TypeQuals &= ~QualType::Restrict; + } + + T = Context.getMemberPointerType(T, ClsType.getTypePtr()); + + break; + } + // See if there are any attributes on this declarator chunk. if (const AttributeList *AL = DeclType.getAttrs()) ProcessTypeAttributeList(T, AL); diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp new file mode 100644 index 000000000000..dcf70b2681e7 --- /dev/null +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -0,0 +1,14 @@ +// RUN: clang -fsyntax-only -verify %s + +struct A {}; +enum B { Dummy }; +namespace C {} + +int A::*pdi1; +int (::A::*pdi2); +int (A::*pfi)(int); + +int B::*pbi; // expected-error {{expected a class or namespace}} +int C::*pci; // expected-error {{'pci' does not point into a class}} +void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}} +int& A::*pdr; // expected-error {{'pdr' declared as a pointer to a reference}} -- GitLab From 4723fb70a97f97ad0341c110add829687052c86f Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 24 Jan 2009 21:21:53 +0000 Subject: [PATCH 131/682] Patch to build class meta-data for each implementation of class in objc2's nonfragile abi. llvm-svn: 62935 --- clang/lib/CodeGen/CGObjCMac.cpp | 53 +++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 9 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index a7c6aee56207..be3a0bdd009d 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -551,9 +551,10 @@ private: unsigned InstanceStart, unsigned InstanceSize, const ObjCImplementationDecl *ID); - void BuildClassMetaData(std::string &ClassName, - llvm::Constant *IsAGV, llvm::Constant *SuperClassGV, - llvm::Constant *ClassRoGV); + llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, + llvm::Constant *IsAGV, + llvm::Constant *SuperClassGV, + llvm::Constant *ClassRoGV); @@ -3161,13 +3162,16 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( /// struct class_ro_t *ro; /// } /// -void CGObjCNonFragileABIMac::BuildClassMetaData(std::string &ClassName, +llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( + std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV) { std::vector Values(5); Values[0] = IsAGV; - Values[1] = SuperClassGV; + Values[1] = SuperClassGV + ? SuperClassGV + : llvm::Constant::getNullValue(ObjCTypes.ClassnfABIPtrTy); Values[2] = ObjCEmptyCacheVar; // &ObjCEmptyCacheVar Values[3] = ObjCEmptyVtableVar; // &ObjCEmptyVtableVar Values[4] = ClassRoGV; // &CLASS_RO_GV @@ -3187,7 +3191,7 @@ void CGObjCNonFragileABIMac::BuildClassMetaData(std::string &ClassName, UsedGlobals.push_back(GV); // FIXME! why? GV->setAlignment(32); - + return GV; } void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { @@ -3245,7 +3249,7 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { &CGM.getModule()); UsedGlobals.push_back(IsAGV); } else { - // Not a root. + // Has a root. Current class is not a root. std::string RootClassName = ID->getClassInterface()->getSuperClass()->getNameAsString(); std::string SuperClassName = ObjCMetaClassName + RootClassName; @@ -3263,8 +3267,39 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *CLASS_RO_GV = BuildClassRoTInitializer(flags, InstanceStart, InstanceSize,ID); - std::string MetaClassName = ObjCMetaClassName + ClassName; - BuildClassMetaData(MetaClassName, IsAGV, SuperClassGV, CLASS_RO_GV); + std::string TClassName = ObjCMetaClassName + ClassName; + llvm::GlobalVariable *MetaTClass = + BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV); + + // Metadata for the class + flags = CLS; + if (ID->getClassInterface() && !ID->getClassInterface()->getSuperClass()) { + flags |= CLS_ROOT; + SuperClassGV = 0; + } + else { + // Has a root. Current class is not a root. + std::string RootClassName = + ID->getClassInterface()->getSuperClass()->getNameAsString(); + std::string SuperClassName = ObjCClassName + RootClassName; + SuperClassGV = CGM.getModule().getGlobalVariable(SuperClassName); + if (!SuperClassGV) + SuperClassGV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + 0, + SuperClassName, + &CGM.getModule()); + UsedGlobals.push_back(SuperClassGV); + + } + + CLASS_RO_GV = BuildClassRoTInitializer(flags, + 0, + 0,ID); + + TClassName = ObjCClassName + ClassName; + BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); } /* *** */ -- GitLab From 5eca6ada3a0c70d3d844c11e48fab3856baa1d88 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 21:29:22 +0000 Subject: [PATCH 132/682] Implement C99 6.5.3.4p1, rejecting sizeof(bitfield) llvm-svn: 62936 --- clang/include/clang/Basic/DiagnosticKinds.def | 4 ++-- clang/lib/Sema/SemaExpr.cpp | 12 ++++++++---- clang/test/Sema/exprs.c | 7 +++++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index a2a1ca4c9fa5..13f540374511 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -1192,8 +1192,8 @@ DIAG(err_sizeof_incomplete_type, ERROR, "invalid application of 'sizeof' to an incomplete type %0") DIAG(err_alignof_incomplete_type, ERROR, "invalid application of '__alignof' to an incomplete type %0") -DIAG(err_alignof_bitfield, ERROR, - "invalid application of '__alignof' to bitfield") +DIAG(err_sizeof_alignof_bitfield, ERROR, + "invalid application of '%select{sizeof|__alignof}0' to bitfield") DIAG(err_offsetof_record_type, ERROR, "offsetof requires struct, union, or class type, %0 invalid") DIAG(err_offsetof_array_type, ERROR, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 56ad4b5f2617..d4babb4baa4f 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1046,7 +1046,7 @@ bool Sema::CheckAlignOfExpr(Expr *E, SourceLocation OpLoc, if (MemberExpr *ME = dyn_cast(E)) { if (FieldDecl *FD = dyn_cast(ME->getMemberDecl())) { if (FD->isBitField()) { - Diag(OpLoc, diag::err_alignof_bitfield) << ExprRange; + Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 1 << ExprRange; return true; } // Other fields are ok. @@ -1082,10 +1082,14 @@ Sema::ActOnSizeOfAlignOfExpr(SourceLocation OpLoc, bool isSizeof, bool isType, // Verify that the operand is valid. bool isInvalid; - if (isSizeof) - isInvalid = CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, true); - else + if (!isSizeof) { isInvalid = CheckAlignOfExpr(ArgEx, OpLoc, Range); + } else if (ArgEx->isBitField()) { // C99 6.5.3.4p1. + Diag(OpLoc, diag::err_sizeof_alignof_bitfield) << 0; + isInvalid = true; + } else { + isInvalid = CheckSizeOfAlignOfOperand(ArgTy, OpLoc, Range, true); + } if (isInvalid) { DeleteExpr(ArgEx); diff --git a/clang/test/Sema/exprs.c b/clang/test/Sema/exprs.c index 5413757df79a..db2daf1f7ca8 100644 --- a/clang/test/Sema/exprs.c +++ b/clang/test/Sema/exprs.c @@ -50,7 +50,10 @@ int test8(void) { // PR3386 struct f { int x : 4; float y[]; }; int test9(struct f *P) { - return __alignof(P->x) + // expected-error {{invalid application of '__alignof' to bitfield}} expected-warning {{extension used}} - __alignof(P->y); // ok. expected-warning {{extension used}} + int R; + R = __alignof(P->x); // expected-error {{invalid application of '__alignof' to bitfield}} expected-warning {{extension used}} + R = __alignof(P->y); // ok. expected-warning {{extension used}} + R = sizeof(P->x); // expected-error {{invalid application of 'sizeof' to bitfield}} + return R; } -- GitLab From 887ce84b2b22cc6c1ffb0990f91640152e76ae42 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sat, 24 Jan 2009 21:36:33 +0000 Subject: [PATCH 133/682] Undo accidental disabling of smart pointers. llvm-svn: 62937 --- clang/include/clang/Parse/Ownership.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/Parse/Ownership.h b/clang/include/clang/Parse/Ownership.h index 14c4bbf067f1..2144481c3d1d 100644 --- a/clang/include/clang/Parse/Ownership.h +++ b/clang/include/clang/Parse/Ownership.h @@ -103,7 +103,7 @@ // conversions. // Flip this switch to measure performance impact of the smart pointers. -#define DISABLE_SMART_POINTERS +//#define DISABLE_SMART_POINTERS namespace clang { -- GitLab From 2b3389a626efcf3758c14698bb0caea68edf8e27 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 24 Jan 2009 21:49:34 +0000 Subject: [PATCH 134/682] Revert previous change; even this mild and clearly more accurate change loses more than it gains on benchmarks. llvm-svn: 62938 --- llvm/lib/Transforms/Utils/InlineCost.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Transforms/Utils/InlineCost.cpp b/llvm/lib/Transforms/Utils/InlineCost.cpp index 37d2c0352ace..69cd9343f8c7 100644 --- a/llvm/lib/Transforms/Utils/InlineCost.cpp +++ b/llvm/lib/Transforms/Utils/InlineCost.cpp @@ -119,14 +119,11 @@ void InlineCostAnalyzer::FunctionInfo::analyzeFunction(Function *F) { NeverInline = true; return; } - + // Calls often compile into many machine instructions. Bump up their - // cost to reflect this. Allow an extra instruction per parameter. - if (!isa(II)) { - for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end(); - I != E; ++I) - NumInsts ++; - } + // cost to reflect this. + if (!isa(II)) + NumInsts += 5; } if (const AllocaInst *AI = dyn_cast(II)) { -- GitLab From 6806131c6b23a389ac75681e9b396316e097e31f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 24 Jan 2009 21:53:27 +0000 Subject: [PATCH 135/682] add initial support for the gcc "alignof(decl) is the alignment of the decl not the type" semantics. This can definitely be improved, but is better than what we had. llvm-svn: 62939 --- clang/include/clang/AST/ASTContext.h | 5 +++++ clang/lib/AST/ASTContext.cpp | 20 ++++++++++++++++++++ clang/lib/AST/ExprConstant.cpp | 19 ++++++++++++++----- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 9ac6027570f3..927d65b99f52 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -403,6 +403,11 @@ public: return getTypeInfo(T).second; } + /// getDeclAlign - Return a conservative estimate of the alignment of the + /// specified decl. Note that bitfields do not have a valid alignment, so + /// this method will assert on them. + unsigned getDeclAlign(const Decl *D); + /// getASTRecordLayout - Get or compute information about the layout of the /// specified record (struct/union/class), which indicates its size and field /// position information. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index f3243c25ae71..63e4ccc24157 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -260,6 +260,26 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const { } } +/// getDeclAlign - Return a conservative estimate of the alignment of the +/// specified decl. Note that bitfields do not have a valid alignment, so +/// this method will assert on them. +unsigned ASTContext::getDeclAlign(const Decl *D) { + // FIXME: If attribute(align) is specified on the decl, round up to it. + + if (const ValueDecl *VD = dyn_cast(D)) { + QualType T = VD->getType(); + // Incomplete or function types default to 1. + if (T->isIncompleteType() || T->isFunctionType()) + return 1; + + while (isa(T) || isa(T)) + T = cast(T)->getElementType(); + + return getTypeAlign(T); + } + + return 1; +} /// getTypeSize - Return the size of the specified type, in bits. This method /// does not work on incomplete types. diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 6d1d150c1c16..49cc3201db97 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -508,8 +508,8 @@ public: private: bool HandleCast(CastExpr* E); - uint64_t GetAlignOfExpr(const Expr *E); - uint64_t GetAlignOfType(QualType T); + unsigned GetAlignOfExpr(const Expr *E); + unsigned GetAlignOfType(QualType T); }; } // end anonymous namespace @@ -844,7 +844,7 @@ bool IntExprEvaluator::VisitConditionalOperator(const ConditionalOperator *E) { return Visit(Cond ? E->getTrueExpr() : E->getFalseExpr()); } -uint64_t IntExprEvaluator::GetAlignOfType(QualType T) { +unsigned IntExprEvaluator::GetAlignOfType(QualType T) { const Type *Ty = Info.Ctx.getCanonicalType(T).getTypePtr(); // __alignof__(void) = 1 as a gcc extension. @@ -873,8 +873,17 @@ uint64_t IntExprEvaluator::GetAlignOfType(QualType T) { return Info.Ctx.getTypeAlign(Ty) / CharSize; } -uint64_t IntExprEvaluator::GetAlignOfExpr(const Expr *E) { - +unsigned IntExprEvaluator::GetAlignOfExpr(const Expr *E) { + E = E->IgnoreParens(); + + // alignof decl is always accepted, even if it doesn't make sense: we default + // to 1 in those cases. + if (const DeclRefExpr *DRE = dyn_cast(E)) + return Info.Ctx.getDeclAlign(DRE->getDecl()); + + if (const MemberExpr *ME = dyn_cast(E)) + return Info.Ctx.getDeclAlign(ME->getMemberDecl()); + return GetAlignOfType(E->getType()); } -- GitLab From b09b0242ca34a184f6caa2699d7c938ad3c3832e Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Sat, 24 Jan 2009 22:12:48 +0000 Subject: [PATCH 136/682] Fix an indent and a typo. llvm-svn: 62940 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 +- llvm/lib/Target/X86/X86ISelLowering.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 10baccbdf997..723c512c92ed 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3287,7 +3287,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::MUL: if (VT == MVT::i32) LC = RTLIB::MUL_I32; - else if (VT == MVT::i64) + else if (VT == MVT::i64) LC = RTLIB::MUL_I64; break; case ISD::FPOW: diff --git a/llvm/lib/Target/X86/X86ISelLowering.h b/llvm/lib/Target/X86/X86ISelLowering.h index 558b119954be..c8dc30a4f9cb 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.h +++ b/llvm/lib/Target/X86/X86ISelLowering.h @@ -185,7 +185,7 @@ namespace llvm { /// in order to obtain suitable precision. FRSQRT, FRCP, - // TLSADDR, THREAThread - Thread Local Storage. + // TLSADDR, THREAD_POINTER - Thread Local Storage. TLSADDR, THREAD_POINTER, // EH_RETURN - Exception Handling helpers. -- GitLab From 2aa38fea3545e31642c048ebac0f7362b4831946 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 24 Jan 2009 22:19:05 +0000 Subject: [PATCH 137/682] Refactor sizeof handling to use constant folding logic for constant sizeof expressions. llvm-svn: 62941 --- clang/lib/AST/ExprConstant.cpp | 15 ++++++--- clang/lib/CodeGen/CGExprScalar.cpp | 50 +++++++++--------------------- 2 files changed, 24 insertions(+), 41 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 49cc3201db97..4c242059b528 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -916,17 +916,22 @@ bool IntExprEvaluator::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { // sizeof(vla) is not a constantexpr: C99 6.5.3.4p2. if (!SrcTy->isConstantSizeType()) return false; - - // sizeof (objc class) ? - if (SrcTy->isObjCInterfaceType()) - return false; // GCC extension: sizeof(function) = 1. if (SrcTy->isFunctionType()) { Result = 1; return true; } - + + if (SrcTy->isObjCInterfaceType()) { + // Slightly unusual case: the size of an ObjC interface type is the + // size of the class. This code intentionally falls through to the normal + // case. + ObjCInterfaceDecl *OI = SrcTy->getAsObjCInterfaceType()->getDecl(); + RecordDecl *RD = const_cast(Info.Ctx.addRecordToClass(OI)); + SrcTy = Info.Ctx.getTagDeclType(static_cast(RD)); + } + // Get information about the size. unsigned CharSize = Info.Ctx.Target.getCharWidth(); Result = Info.Ctx.getTypeSize(SrcTy) / CharSize; diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index b1150cb2d10b..766721e96b44 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -673,45 +673,23 @@ Value *ScalarExprEmitter::VisitUnaryLNot(const UnaryOperator *E) { /// argument of the sizeof expression as an integer. Value * ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) { - // Handle alignof with the constant folding logic. alignof always produces a - // constant. - if (!E->isSizeOf()) { - Expr::EvalResult Result; - E->Evaluate(Result, CGF.getContext()); - return llvm::ConstantInt::get(Result.Val.getInt()); - } - - QualType RetType = E->getType(); - assert(RetType->isIntegerType() && "Result type must be an integer!"); - uint32_t ResultWidth = - static_cast(CGF.getContext().getTypeSize(RetType)); - - // sizeof(void) and sizeof(function) = 1 as a strange gcc extension. QualType TypeToSize = E->getTypeOfArgument(); - if (TypeToSize->isVoidType() || TypeToSize->isFunctionType()) - return llvm::ConstantInt::get(llvm::APInt(ResultWidth, 1)); - - if (const VariableArrayType *VAT = - CGF.getContext().getAsVariableArrayType(TypeToSize)) { - if (E->isArgumentType()) { - // sizeof(type) - make sure to emit the VLA size. - CGF.EmitVLASize(TypeToSize); + if (E->isSizeOf()) { + if (const VariableArrayType *VAT = + CGF.getContext().getAsVariableArrayType(TypeToSize)) { + if (E->isArgumentType()) { + // sizeof(type) - make sure to emit the VLA size. + CGF.EmitVLASize(TypeToSize); + } + return CGF.GetVLASize(VAT); } - return CGF.GetVLASize(VAT); } - - if (TypeToSize->isObjCInterfaceType()) { - ObjCInterfaceDecl *OI = TypeToSize->getAsObjCInterfaceType()->getDecl(); - RecordDecl *RD = const_cast( - CGF.getContext().addRecordToClass(OI)); - TypeToSize = CGF.getContext().getTagDeclType(static_cast(RD)); - } - - uint64_t Val = CGF.getContext().getTypeSize(TypeToSize); - // Return size in bytes, not bits. - Val /= CGF.getContext().Target.getCharWidth(); - - return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); + + // If this isn't sizeof(vla), the result must be constant; use the + // constant folding logic so we don't have to duplicate it here. + Expr::EvalResult Result; + E->Evaluate(Result, CGF.getContext()); + return llvm::ConstantInt::get(Result.Val.getInt()); } Value *ScalarExprEmitter::VisitUnaryReal(const UnaryOperator *E) { -- GitLab From 8549e5dcc868f1c6c75ecd11bd8762a018af9f1d Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 24 Jan 2009 22:38:55 +0000 Subject: [PATCH 138/682] Fix for PR2910: implement CodeGen for non-constant offsetof. Note that there are still other issues in this area; see PR3396. llvm-svn: 62942 --- clang/lib/CodeGen/CGExprScalar.cpp | 49 +++++++++++++++++++++++++----- clang/test/CodeGen/offsetof.c | 12 ++++++++ 2 files changed, 54 insertions(+), 7 deletions(-) create mode 100644 clang/test/CodeGen/offsetof.c diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp index 766721e96b44..33c5a6124bdc 100644 --- a/clang/lib/CodeGen/CGExprScalar.cpp +++ b/clang/lib/CodeGen/CGExprScalar.cpp @@ -15,6 +15,7 @@ #include "CodeGenModule.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" +#include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" #include "clang/Basic/TargetInfo.h" #include "llvm/Constants.h" @@ -711,13 +712,47 @@ Value *ScalarExprEmitter::VisitUnaryImag(const UnaryOperator *E) { Value *ScalarExprEmitter::VisitUnaryOffsetOf(const UnaryOperator *E) { - int64_t Val = E->evaluateOffsetOf(CGF.getContext()); - - assert(E->getType()->isIntegerType() && "Result type must be an integer!"); - - uint32_t ResultWidth = - static_cast(CGF.getContext().getTypeSize(E->getType())); - return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); + const Expr* SubExpr = E->getSubExpr(); + const llvm::Type* ResultType = ConvertType(E->getType()); + llvm::Value* Result = llvm::Constant::getNullValue(ResultType); + while (!isa(SubExpr)) { + if (const MemberExpr *ME = dyn_cast(SubExpr)) { + SubExpr = ME->getBase(); + QualType Ty = SubExpr->getType(); + + RecordDecl *RD = Ty->getAsRecordType()->getDecl(); + const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD); + FieldDecl *FD = cast(ME->getMemberDecl()); + + // FIXME: This is linear time. And the fact that we're indexing + // into the layout by position in the record means that we're + // either stuck numbering the fields in the AST or we have to keep + // the linear search (yuck and yuck). + unsigned i = 0; + for (RecordDecl::field_iterator Field = RD->field_begin(), + FieldEnd = RD->field_end(); + Field != FieldEnd; (void)++Field, ++i) { + if (*Field == FD) + break; + } + + llvm::Value* Offset = + llvm::ConstantInt::get(ResultType, RL.getFieldOffset(i) / 8); + Result = Builder.CreateAdd(Result, Offset); + } else if (const ArraySubscriptExpr *ASE = dyn_cast(SubExpr)) { + SubExpr = ASE->getBase(); + int64_t size = CGF.getContext().getTypeSize(ASE->getType()) / 8; + llvm::Value* ElemSize = llvm::ConstantInt::get(ResultType, size); + llvm::Value* ElemIndex = CGF.EmitScalarExpr(ASE->getIdx()); + bool IndexSigned = ASE->getIdx()->getType()->isSignedIntegerType(); + ElemIndex = Builder.CreateIntCast(ElemIndex, ResultType, IndexSigned); + llvm::Value* Offset = Builder.CreateMul(ElemSize, ElemIndex); + Result = Builder.CreateAdd(Result, Offset); + } else { + assert(0 && "This should be impossible!"); + } + } + return Result; } //===----------------------------------------------------------------------===// diff --git a/clang/test/CodeGen/offsetof.c b/clang/test/CodeGen/offsetof.c new file mode 100644 index 000000000000..7b6f5039f8c6 --- /dev/null +++ b/clang/test/CodeGen/offsetof.c @@ -0,0 +1,12 @@ +// RUN: clang %s -emit-llvm -o %t + +// PR2910 +struct sockaddr_un { + unsigned char sun_len; + char sun_path[104]; +}; + +int test(int len) { + return __builtin_offsetof(struct sockaddr_un, sun_path[len+1]); +} + -- GitLab From 52cc016f2199922f10d7eb9e9bc0229843ab8051 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 24 Jan 2009 23:09:00 +0000 Subject: [PATCH 139/682] PR3062: statement expressions should be illegal at file scope. I don't think this has any significant effects at the moment, but it could matter if we start constant-folding statement expressions like gcc does. llvm-svn: 62943 --- clang/include/clang/Basic/DiagnosticKinds.def | 2 ++ clang/lib/Sema/SemaExpr.cpp | 5 +++++ clang/test/Sema/stmt_exprs.c | 2 ++ 3 files changed, 9 insertions(+) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 13f540374511..93b023e56099 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -1301,6 +1301,8 @@ DIAG(ext_typecheck_comparison_of_distinct_pointers, WARNING, "comparison of distinct pointer types (%0 and %1)") DIAG(err_typecheck_assign_const, ERROR, "read-only variable is not assignable") +DIAG(err_stmtexpr_file_scope, ERROR, + "statement expression not allowed at file scope") DIAG(err_invalid_this_use, ERROR, "invalid use of 'this' outside of a nonstatic member function") diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index d4babb4baa4f..1d55ed7c3aa4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3940,6 +3940,11 @@ Sema::ExprResult Sema::ActOnStmtExpr(SourceLocation LPLoc, StmtTy *substmt, assert(SubStmt && isa(SubStmt) && "Invalid action invocation!"); CompoundStmt *Compound = cast(SubStmt); + bool isFileScope = getCurFunctionOrMethodDecl() == 0; + if (isFileScope) { + return Diag(LPLoc, diag::err_stmtexpr_file_scope); + } + // FIXME: there are a variety of strange constraints to enforce here, for // example, it is not possible to goto into a stmt expression apparently. // More semantic analysis is needed. diff --git a/clang/test/Sema/stmt_exprs.c b/clang/test/Sema/stmt_exprs.c index ee835a355dc7..0d6fe8585f51 100644 --- a/clang/test/Sema/stmt_exprs.c +++ b/clang/test/Sema/stmt_exprs.c @@ -20,3 +20,5 @@ int test5() { return ({L1: L2: L3: 5;}); } int test6() { return ({5;}); } void test7() { ({5;}); } // expected-warning {{expression result unused}} +// PR3062 +int x[({10;})]; // expected-error {{illegal statement expression}} -- GitLab From c6d52f5dfb2b6c309dcb33f560e300c4e8eb42e2 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sat, 24 Jan 2009 23:29:36 +0000 Subject: [PATCH 140/682] Make tentative parsing of pointer-to-member decls work, and fix other stuff pointed out by Doug. llvm-svn: 62944 --- clang/lib/AST/ASTContext.cpp | 5 +++-- clang/lib/AST/Type.cpp | 2 ++ clang/lib/Parse/ParseTentative.cpp | 10 +++++++--- clang/test/SemaCXX/member-pointer.cpp | 5 +++++ 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 63e4ccc24157..2662860af2fe 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -400,10 +400,11 @@ ASTContext::getTypeInfo(const Type *T) { // pointer size. return getTypeInfo(cast(T)->getPointeeType()); case Type::MemberPointer: { - // Note that this is not only platform- but also ABI-dependent. We follow + // FIXME: This is not only platform- but also ABI-dependent. We follow // the GCC ABI, where pointers to data are one pointer large, pointers to // functions two pointers. But if we want to support ABI compatibility with - // other compilers too, we need to delegate this completely to TargetInfo. + // other compilers too, we need to delegate this completely to TargetInfo + // or some ABI abstraction layer. QualType Pointee = cast(T)->getPointeeType(); unsigned AS = Pointee.getAddressSpace(); Width = Target.getPointerWidth(AS); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index ebaa01135555..7d9be2d72c70 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -324,6 +324,8 @@ bool Type::isVariablyModifiedType() const { // correctly. if (const PointerLikeType *PT = getAsPointerLikeType()) return PT->getPointeeType()->isVariablyModifiedType(); + if (const MemberPointerType *PT = getAsMemberPointerType()) + return PT->getPointeeType()->isVariablyModifiedType(); // A function can return a variably modified type // This one isn't completely obvious, but it follows from the diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index a7c3e389319e..e7914cccea06 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -357,7 +357,7 @@ bool Parser::isCXXTypeIdInParens() { /// '*' cv-qualifier-seq[opt] /// '&' /// [C++0x] '&&' [TODO] -/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] [TODO] +/// '::'[opt] nested-name-specifier '*' cv-qualifier-seq[opt] /// /// cv-qualifier-seq: /// cv-qualifier cv-qualifier-seq[opt] @@ -387,8 +387,12 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, // ptr-operator declarator while (1) { - if (Tok.is(tok::star) || Tok.is(tok::amp) || - (Tok.is(tok::caret) && getLang().Blocks)) { + if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) + TryAnnotateCXXScopeToken(); + + if (Tok.is(tok::star) || Tok.is(tok::amp) || + (Tok.is(tok::caret) && getLang().Blocks) || + (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { // ptr-operator ConsumeToken(); while (Tok.is(tok::kw_const) || diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index dcf70b2681e7..2568cb59d8b7 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -12,3 +12,8 @@ int B::*pbi; // expected-error {{expected a class or namespace}} int C::*pci; // expected-error {{'pci' does not point into a class}} void A::*pdv; // expected-error {{'pdv' declared as a member pointer to void}} int& A::*pdr; // expected-error {{'pdr' declared as a pointer to a reference}} + +void f() { + // This requires tentative parsing. + int (A::*pf)(int, int); +} -- GitLab From a887e63434ed3567a9bf146aa3cf0e96061b4201 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 24 Jan 2009 23:43:01 +0000 Subject: [PATCH 141/682] Compute instaceStart/instanceSize fields of the class_ro_t meta-data for objc2's non-fragile abi. llvm-svn: 62945 --- clang/lib/CodeGen/CGObjCMac.cpp | 43 +++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index be3a0bdd009d..f677782ec3e8 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3294,9 +3294,48 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { } + InstanceStart = InstanceSize = 0; + if (ObjCInterfaceDecl *OID = + const_cast(ID->getClassInterface())) { + // FIXME. Share this with the one in EmitIvarList. + int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); + const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); + RecordDecl::field_iterator firstField = RD->field_begin(); + RecordDecl::field_iterator lastField = RD->field_end(); + + while (countSuperClassIvars-- > 0) { + lastField = firstField; + ++firstField; + } + + for (RecordDecl::field_iterator e = RD->field_end(), + ifield = firstField; ifield != e; ++ifield) + lastField = ifield; + + const llvm::Type *InterfaceTy = + CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID)); + const llvm::StructLayout *Layout = + CGM.getTargetData().getStructLayout(cast(InterfaceTy)); + + if (lastField != RD->field_end()) { + FieldDecl *Field = *lastField; + const llvm::Type *FieldTy = + CGM.getTypes().ConvertTypeForMem(Field->getType()); + unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy); + InstanceSize = Layout->getElementOffset( + CGM.getTypes().getLLVMFieldNo(Field)) + + Size; + if (firstField == RD->field_end()) + InstanceStart = InstanceSize; + else + InstanceStart = Layout->getElementOffset(CGM.getTypes(). + getLLVMFieldNo(*firstField)); + } + } CLASS_RO_GV = BuildClassRoTInitializer(flags, - 0, - 0,ID); + InstanceStart, + InstanceSize, + ID); TClassName = ObjCClassName + ClassName; BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); -- GitLab From 588395702f004f14cd67dad2a62366274391cb09 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 24 Jan 2009 23:44:26 +0000 Subject: [PATCH 142/682] Correct test; sorry for any inconvenience. llvm-svn: 62946 --- clang/test/Sema/stmt_exprs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Sema/stmt_exprs.c b/clang/test/Sema/stmt_exprs.c index 0d6fe8585f51..10b9e47214ac 100644 --- a/clang/test/Sema/stmt_exprs.c +++ b/clang/test/Sema/stmt_exprs.c @@ -21,4 +21,4 @@ int test6() { return ({5;}); } void test7() { ({5;}); } // expected-warning {{expression result unused}} // PR3062 -int x[({10;})]; // expected-error {{illegal statement expression}} +int x[({10;})]; // expected-error {{statement expression not allowed at file scope}} -- GitLab From 8b7c52658bd5966c65a74d1404fa2fa96adc9edc Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sat, 24 Jan 2009 23:49:55 +0000 Subject: [PATCH 143/682] Fix for PR2100: merge types for variables. llvm-svn: 62947 --- clang/lib/Sema/SemaDecl.cpp | 8 ++++---- clang/test/Sema/decl-type-merging.c | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 clang/test/Sema/decl-type-merging.c diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 0fb939e23abc..9f308842d9ec 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -658,15 +658,15 @@ VarDecl *Sema::MergeVarDecl(VarDecl *New, Decl *OldD) { MergeAttributes(New, Old); - // Verify the types match. - QualType OldCType = Context.getCanonicalType(Old->getType()); - QualType NewCType = Context.getCanonicalType(New->getType()); - if (OldCType != NewCType && !Context.typesAreCompatible(OldCType, NewCType)) { + // Merge the types + QualType MergedT = Context.mergeTypes(New->getType(), Old->getType()); + if (MergedT.isNull()) { Diag(New->getLocation(), diag::err_redefinition_different_type) << New->getDeclName(); Diag(Old->getLocation(), diag::note_previous_definition); return New; } + New->setType(MergedT); // C99 6.2.2p4: Check if we have a static decl followed by a non-static. if (New->getStorageClass() == VarDecl::Static && (Old->getStorageClass() == VarDecl::None || diff --git a/clang/test/Sema/decl-type-merging.c b/clang/test/Sema/decl-type-merging.c new file mode 100644 index 000000000000..89bc49447508 --- /dev/null +++ b/clang/test/Sema/decl-type-merging.c @@ -0,0 +1,16 @@ +// RUN: clang -fsyntax-only -std=c99 -verify -pedantic %s + +int x[10]; +int x[] = {1,2,3}; +int testx[(sizeof(x) == sizeof(int) * 10) ? 1 : -1]; + +int (*a)(int (*x)[10], int (*y)[]); +int (*a)(int (*x)[], int (*y)[5]); +int b() { +int x[10], y[5]; +a(&x, &y); +a(&y, &y); // expected-warning {{incompatible pointer}} +a(&x, &x); // expected-warning {{incompatible pointer}} +} + + -- GitLab From 529a99bcf4d2ac42d2ddff4909e3e7e61edf14b2 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 25 Jan 2009 01:21:06 +0000 Subject: [PATCH 144/682] Fix the address of a label to be properly considered and emitted as a constant. llvm-svn: 62948 --- clang/lib/AST/ExprConstant.cpp | 2 ++ clang/lib/CodeGen/CGExprConstant.cpp | 6 ++++++ clang/test/CodeGen/const-label-addr.c | 4 ++++ 3 files changed, 12 insertions(+) create mode 100644 clang/test/CodeGen/const-label-addr.c diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 4c242059b528..76bdaa2c8f83 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -215,6 +215,8 @@ public: APValue VisitUnaryOperator(const UnaryOperator *E); APValue VisitObjCStringLiteral(ObjCStringLiteral *E) { return APValue(E, 0); } + APValue VisitAddrLabelExpr(AddrLabelExpr *E) + { return APValue(E, 0); } APValue VisitConditionalOperator(ConditionalOperator *E); }; } // end anonymous namespace diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 9d709d3a509d..0e31cacd1b03 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -619,6 +619,12 @@ public: return CGM.GetAddrOfConstantCString(Str, ".tmp"); } + case Expr::AddrLabelExprClass: { + assert(CGF && "Invalid address of label expression outside function."); + unsigned id = CGF->GetIDForAddrOfLabel(cast(E)->getLabel()); + llvm::Constant *C = llvm::ConstantInt::get(llvm::Type::Int32Ty, id); + return llvm::ConstantExpr::getIntToPtr(C, ConvertType(E->getType())); + } } CGM.ErrorUnsupported(E, "constant l-value expression"); llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType())); diff --git a/clang/test/CodeGen/const-label-addr.c b/clang/test/CodeGen/const-label-addr.c new file mode 100644 index 000000000000..1ae74e5ad064 --- /dev/null +++ b/clang/test/CodeGen/const-label-addr.c @@ -0,0 +1,4 @@ +// RUN: clang %s -emit-llvm -o %t +int a() { +A:;static void* a = &&A; +} -- GitLab From c69d454d5aa427279c73d9e8e157f246159ce683 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 25 Jan 2009 01:54:01 +0000 Subject: [PATCH 145/682] Make the constant folder aware of __builtin___CFStringMakeConstantString. (We get into trouble in GenerateStaticBlockVarDecl if the constant folder isn't accurate.) llvm-svn: 62949 --- clang/lib/AST/ExprConstant.cpp | 7 +++++++ clang/lib/CodeGen/CGBuiltin.cpp | 4 ++-- clang/lib/CodeGen/CGExprConstant.cpp | 9 +++++++++ clang/test/CodeGen/cfstring.c | 4 +++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 76bdaa2c8f83..43b45612b940 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -217,6 +217,7 @@ public: { return APValue(E, 0); } APValue VisitAddrLabelExpr(AddrLabelExpr *E) { return APValue(E, 0); } + APValue VisitCallExpr(CallExpr *E); APValue VisitConditionalOperator(ConditionalOperator *E); }; } // end anonymous namespace @@ -306,6 +307,12 @@ APValue PointerExprEvaluator::VisitCastExpr(const CastExpr* E) { return APValue(); } +APValue PointerExprEvaluator::VisitCallExpr(CallExpr *E) { + if (E->isBuiltinCall() == Builtin::BI__builtin___CFStringMakeConstantString) + return APValue(E, 0); + return APValue(); +} + APValue PointerExprEvaluator::VisitConditionalOperator(ConditionalOperator *E) { bool BoolResult; if (!HandleConversionToBool(E->getCond(), BoolResult, Info)) diff --git a/clang/lib/CodeGen/CGBuiltin.cpp b/clang/lib/CodeGen/CGBuiltin.cpp index 30f8c34c5876..9260b11ed34a 100644 --- a/clang/lib/CodeGen/CGBuiltin.cpp +++ b/clang/lib/CodeGen/CGBuiltin.cpp @@ -42,8 +42,8 @@ RValue CodeGenFunction::EmitBuiltinExpr(unsigned BuiltinID, const CallExpr *E) { if (E->Evaluate(Result, CGM.getContext())) { if (Result.Val.isInt()) return RValue::get(llvm::ConstantInt::get(Result.Val.getInt())); - assert(Result.Val.isFloat() && "Unsupported constant type"); - return RValue::get(llvm::ConstantFP::get(Result.Val.getFloat())); + else if (Result.Val.isFloat()) + return RValue::get(llvm::ConstantFP::get(Result.Val.getFloat())); } switch (BuiltinID) { diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 0e31cacd1b03..716e295f3e0c 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -625,6 +625,15 @@ public: llvm::Constant *C = llvm::ConstantInt::get(llvm::Type::Int32Ty, id); return llvm::ConstantExpr::getIntToPtr(C, ConvertType(E->getType())); } + case Expr::CallExprClass: { + CallExpr* CE = cast(E); + if (CE->isBuiltinCall() != Builtin::BI__builtin___CFStringMakeConstantString) + break; + const Expr *Arg = CE->getArg(0)->IgnoreParenCasts(); + const StringLiteral *Literal = cast(Arg); + std::string S(Literal->getStrData(), Literal->getByteLength()); + return CGM.GetAddrOfConstantCFString(S); + } } CGM.ErrorUnsupported(E, "constant l-value expression"); llvm::Type *Ty = llvm::PointerType::getUnqual(ConvertType(E->getType())); diff --git a/clang/test/CodeGen/cfstring.c b/clang/test/CodeGen/cfstring.c index 7d7edeca3cb3..3bd1a2d18344 100644 --- a/clang/test/CodeGen/cfstring.c +++ b/clang/test/CodeGen/cfstring.c @@ -8,4 +8,6 @@ void f() { // rdar://6248329 void *G = CFSTR("yo joe"); - +void h() { + static void* h = CFSTR("Goodbye, World!"); +} -- GitLab From cf2b7ba4a762ae463ef45ee3f004ef6e309e5124 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 25 Jan 2009 02:10:46 +0000 Subject: [PATCH 146/682] Get rid of some code that should be unnecessary. llvm-svn: 62950 --- clang/lib/CodeGen/CGExprConstant.cpp | 52 ---------------------------- 1 file changed, 52 deletions(-) diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 716e295f3e0c..32d126e5903e 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -48,13 +48,6 @@ public: llvm::Constant *VisitParenExpr(ParenExpr *PE) { return Visit(PE->getSubExpr()); } - - llvm::Constant *VisitObjCStringLiteral(const ObjCStringLiteral *E) { - std::string S(E->getString()->getStrData(), - E->getString()->getByteLength()); - llvm::Constant *C = CGM.getObjCRuntime().GenerateConstantString(S); - return llvm::ConstantExpr::getBitCast(C, ConvertType(E->getType())); - } llvm::Constant *VisitCompoundLiteralExpr(CompoundLiteralExpr *E) { return Visit(E->getInitializer()); @@ -371,54 +364,9 @@ public: return llvm::ConstantArray::get(CGM.GetStringForStringLiteral(E), false); } - llvm::Constant *VisitAddrLabelExpr(const AddrLabelExpr *E) { - assert(CGF && "Invalid address of label expression outside function."); - llvm::Constant *C = - llvm::ConstantInt::get(llvm::Type::Int32Ty, - CGF->GetIDForAddrOfLabel(E->getLabel())); - return llvm::ConstantExpr::getIntToPtr(C, ConvertType(E->getType())); - } - - llvm::Constant *VisitUnaryAddrOf(const UnaryOperator *E) { - return EmitLValue(E->getSubExpr()); - } - llvm::Constant *VisitUnaryOffsetOf(const UnaryOperator *E) { - int64_t Val = E->evaluateOffsetOf(CGM.getContext()); - - assert(E->getType()->isIntegerType() && "Result type must be an integer!"); - - uint32_t ResultWidth = - static_cast(CGM.getContext().getTypeSize(E->getType())); - return llvm::ConstantInt::get(llvm::APInt(ResultWidth, Val)); - } - llvm::Constant *VisitUnaryExtension(const UnaryOperator *E) { return Visit(E->getSubExpr()); } - - // Binary operators - - llvm::Constant *VisitCallExpr(const CallExpr *E) { - Expr::EvalResult Result; - if (E->Evaluate(Result, CGM.getContext())) { - if (Result.Val.isInt()) - return llvm::ConstantInt::get(Result.Val.getInt()); - if (Result.Val.isFloat()) - return llvm::ConstantFP::get(Result.Val.getFloat()); - } - - // Handle __builtin___CFStringMakeConstantString. - if (E->isBuiltinCall() ==Builtin::BI__builtin___CFStringMakeConstantString){ - const Expr *Arg = E->getArg(0)->IgnoreParenCasts(); - - const StringLiteral *Literal = cast(Arg); - std::string S(Literal->getStrData(), Literal->getByteLength()); - return CGM.GetAddrOfConstantCFString(S); - } - - CGM.ErrorUnsupported(E, "constant call expression"); - return llvm::Constant::getNullValue(ConvertType(E->getType())); - } // Utility methods const llvm::Type *ConvertType(QualType T) { -- GitLab From 7139af42ce181d285e9c5aa1301403c2eaec665c Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 25 Jan 2009 02:32:41 +0000 Subject: [PATCH 147/682] Rename Expr::isConstantExpr to Expr::isConstantInitializer; this more accurately states what the function is trying to do and how it is different from Expr::isEvaluatable. Also get rid of a parameter that is both unused and inaccurate. llvm-svn: 62951 --- clang/include/clang/AST/Expr.h | 5 +++-- clang/lib/AST/Expr.cpp | 7 +++---- clang/lib/Analysis/CheckDeadStores.cpp | 2 +- clang/lib/CodeGen/CGDecl.cpp | 2 +- clang/lib/CodeGen/CGExprAgg.cpp | 2 +- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 19cd5d5786bc..5d768cd9dba3 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -181,8 +181,9 @@ public: llvm::APSInt X; return isIntegerConstantExpr(X, Ctx, Loc); } - /// isConstantExpr - Return true if this expression is a valid constant expr. - bool isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const; + /// isConstantInitializer - Returns true if this expression is a constant + /// initializer, which can be emitted at compile-time. + bool isConstantInitializer(ASTContext &Ctx) const; /// EvalResult is a struct with detailed info about an evaluated expression. struct EvalResult { diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 70b63fea1bd6..86f1cd9fdbad 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -692,11 +692,10 @@ bool Expr::hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs) { return false; } -bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { +bool Expr::isConstantInitializer(ASTContext &Ctx) const { switch (getStmtClass()) { default: if (!isEvaluatable(Ctx)) { - if (Loc) *Loc = getLocStart(); return false; } break; @@ -704,13 +703,13 @@ bool Expr::isConstantExpr(ASTContext &Ctx, SourceLocation *Loc) const { return true; case CompoundLiteralExprClass: { const Expr *Exp = cast(this)->getInitializer(); - return Exp->isConstantExpr(Ctx, Loc); + return Exp->isConstantInitializer(Ctx); } case InitListExprClass: { const InitListExpr *Exp = cast(this); unsigned numInits = Exp->getNumInits(); for (unsigned i = 0; i < numInits; i++) { - if (!Exp->getInit(i)->isConstantExpr(Ctx, Loc)) + if (!Exp->getInit(i)->isConstantInitializer(Ctx)) return false; } } diff --git a/clang/lib/Analysis/CheckDeadStores.cpp b/clang/lib/Analysis/CheckDeadStores.cpp index 4f51cd8d9ae7..d5e5f4c9b2a2 100644 --- a/clang/lib/Analysis/CheckDeadStores.cpp +++ b/clang/lib/Analysis/CheckDeadStores.cpp @@ -195,7 +195,7 @@ public: // If x is EVER assigned a new value later, don't issue // a warning. This is because such initialization can be // due to defensive programming. - if (!E->isConstantExpr(Ctx,NULL)) + if (!E->isConstantInitializer(Ctx)) Report(V, DeadInit, V->getLocation(), E->getSourceRange()); } } diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp index 1acebaed4b93..6774f33337ae 100644 --- a/clang/lib/CodeGen/CGDecl.cpp +++ b/clang/lib/CodeGen/CGDecl.cpp @@ -86,7 +86,7 @@ CodeGenFunction::GenerateStaticBlockVarDecl(const VarDecl &D, if ((D.getInit() == 0) || NoInit) { Init = llvm::Constant::getNullValue(LTy); } else { - if (D.getInit()->isConstantExpr(getContext(), 0)) + if (D.getInit()->isConstantInitializer(getContext())) Init = CGM.EmitConstantExpr(D.getInit(), this); else { assert(getContext().getLangOptions().CPlusPlus && diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 5e36751fb769..058b561f95b3 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -394,7 +394,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) { // FIXME: Should we really be doing this? Should we try to avoid // cases where we emit a global with a lot of zeros? Should // we try to avoid short globals? - if (E->isConstantExpr(CGF.getContext(), 0)) { + if (E->isConstantInitializer(CGF.getContext(), 0)) { llvm::Constant* C = CGF.CGM.EmitConstantExpr(E, &CGF); llvm::GlobalVariable* GV = new llvm::GlobalVariable(C->getType(), true, -- GitLab From 384da271319eb58cb97a23079c80953b9d7196cd Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 25 Jan 2009 03:12:18 +0000 Subject: [PATCH 148/682] Enhancements to Expr::isConstantInitializer to deal with a few cases it couldn't deal with before. llvm-svn: 62952 --- clang/lib/AST/Expr.cpp | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 86f1cd9fdbad..1bb404ffeac0 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -693,12 +693,14 @@ bool Expr::hasAnyValueDependentArguments(Expr** Exprs, unsigned NumExprs) { } bool Expr::isConstantInitializer(ASTContext &Ctx) const { + // This function is attempting whether an expression is an initializer + // which can be evaluated at compile-time. isEvaluatable handles most + // of the cases, but it can't deal with some initializer-specific + // expressions, and it can't deal with aggregates; we deal with those here, + // and fall back to isEvaluatable for the other cases. + switch (getStmtClass()) { - default: - if (!isEvaluatable(Ctx)) { - return false; - } - break; + default: break; case StringLiteralClass: return true; case CompoundLiteralExprClass: { @@ -712,10 +714,27 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const { if (!Exp->getInit(i)->isConstantInitializer(Ctx)) return false; } + return true; } + case ParenExprClass: { + return cast(this)->getSubExpr()->isConstantInitializer(Ctx); + } + case UnaryOperatorClass: { + const UnaryOperator* Exp = cast(this); + if (Exp->getOpcode() == UnaryOperator::Extension) + return Exp->getSubExpr()->isConstantInitializer(Ctx); + break; + } + case CStyleCastExprClass: + // Handle casts with a destination that's a struct or union; this + // deals with both the gcc no-op struct cast extension and the + // cast-to-union extension. + if (getType()->isRecordType()) + return cast(this)->getSubExpr()->isConstantInitializer(Ctx); + break; } - return true; + return isEvaluatable(Ctx); } /// isIntegerConstantExpr - this recursive routine will test if an expression is -- GitLab From 8bad1c59031f218d523346a67d94ab0625a08023 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 25 Jan 2009 03:27:40 +0000 Subject: [PATCH 149/682] One more case for Expr::isConstantInitializer; I think this covers everything that we aren't intending to implement in Expr::Evaluate. llvm-svn: 62953 --- clang/lib/AST/Expr.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 1bb404ffeac0..defb0c3e91c3 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -732,6 +732,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const { if (getType()->isRecordType()) return cast(this)->getSubExpr()->isConstantInitializer(Ctx); break; + case DesignatedInitExprClass: + return cast(Init)->getInit()->isConstantInitializer(Ctx); } return isEvaluatable(Ctx); -- GitLab From abda665f5f6b3f569ef28dba660234eee00a5168 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sun, 25 Jan 2009 03:53:59 +0000 Subject: [PATCH 150/682] Teach 2addr pass to be do more commuting. If both uses of a two-address instruction are killed, but the first operand has a use before and after the def, commute if the second operand does not suffer from the same issue. %reg1028 = EXTRACT_SUBREG %reg1027, 1 %reg1029 = MOV8rr %reg1028 %reg1029 = SHR8ri %reg1029, 7, %EFLAGS insert => %reg1030 = MOV8rr %reg1028 %reg1030 = ADD8rr %reg1028, %reg1029, %EFLAGS In this case, it might not be possible to coalesce the second MOV8rr instruction if the first one is coalesced. So it would be profitable to commute it: %reg1028 = EXTRACT_SUBREG %reg1027, 1 %reg1029 = MOV8rr %reg1028 %reg1029 = SHR8ri %reg1029, 7, %EFLAGS insert => %reg1030 = MOV8rr %reg1029 %reg1030 = ADD8rr %reg1029, %reg1028, %EFLAGS llvm-svn: 62954 --- .../lib/CodeGen/TwoAddressInstructionPass.cpp | 110 +++++++++++++++++- llvm/test/CodeGen/X86/2008-02-22-ReMatBug.ll | 2 +- .../CodeGen/X86/2008-07-19-movups-spills.ll | 2 +- llvm/test/CodeGen/X86/pmul.ll | 2 +- llvm/test/CodeGen/X86/twoaddr-coalesce.ll | 25 ++++ 5 files changed, 132 insertions(+), 9 deletions(-) create mode 100644 llvm/test/CodeGen/X86/twoaddr-coalesce.ll diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp index 071b39954c09..5cf2ffd3771b 100644 --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp @@ -49,6 +49,7 @@ using namespace llvm; STATISTIC(NumTwoAddressInstrs, "Number of two-address instructions"); STATISTIC(NumCommuted , "Number of instructions commuted to coalesce"); +STATISTIC(NumAggrCommuted , "Number of instructions aggressively commuted"); STATISTIC(NumConvertedTo3Addr, "Number of instructions promoted to 3-address"); STATISTIC(Num3AddrSunk, "Number of 3-address instructions sunk"); STATISTIC(NumReMats, "Number of instructions re-materialized"); @@ -70,6 +71,15 @@ namespace { MachineBasicBlock *MBB, unsigned Loc, DenseMap &DistanceMap); + bool NoUseAfterLastDef(unsigned Reg, MachineBasicBlock *MBB, unsigned Dist, + DenseMap &DistanceMap, + unsigned &LastDef); + + bool isProfitableToCommute(unsigned regB, unsigned regC, + MachineInstr *MI, MachineBasicBlock *MBB, + unsigned Dist, + DenseMap &DistanceMap); + bool CommuteInstruction(MachineBasicBlock::iterator &mi, MachineFunction::iterator &mbbi, unsigned RegC, unsigned Dist, @@ -230,8 +240,6 @@ TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg, for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(Reg), UE = MRI->use_end(); UI != UE; ++UI) { MachineOperand &UseMO = UI.getOperand(); - if (!UseMO.isUse()) - continue; MachineInstr *UseMI = UseMO.getParent(); MachineBasicBlock *UseMBB = UseMI->getParent(); if (UseMBB == MBB) { @@ -255,6 +263,82 @@ TwoAddressInstructionPass::isProfitableToReMat(unsigned Reg, return MBB == DefMI->getParent(); } +/// NoUseAfterLastDef - Return true if there are no intervening uses between the +/// last instruction in the MBB that defines the specified register and the +/// two-address instruction which is being processed. It also returns the last +/// def location by reference +bool TwoAddressInstructionPass::NoUseAfterLastDef(unsigned Reg, + MachineBasicBlock *MBB, unsigned Dist, + DenseMap &DistanceMap, + unsigned &LastDef) { + LastDef = 0; + unsigned LastUse = Dist; + for (MachineRegisterInfo::reg_iterator I = MRI->reg_begin(Reg), + E = MRI->reg_end(); I != E; ++I) { + MachineOperand &MO = I.getOperand(); + MachineInstr *MI = MO.getParent(); + if (MI->getParent() != MBB) + continue; + DenseMap::iterator DI = DistanceMap.find(MI); + if (DI == DistanceMap.end()) + continue; + if (MO.isUse() && DI->second < LastUse) + LastUse = DI->second; + if (MO.isDef() && DI->second > LastDef) + LastDef = DI->second; + } + + return !(LastUse > LastDef && LastUse < Dist); +} + +/// isProfitableToReMat - Return true if it's potentially profitable to commute +/// the two-address instruction that's being processed. +bool +TwoAddressInstructionPass::isProfitableToCommute(unsigned regB, unsigned regC, + MachineInstr *MI, MachineBasicBlock *MBB, + unsigned Dist, DenseMap &DistanceMap) { + // Determine if it's profitable to commute this two address instruction. In + // general, we want no uses between this instruction and the definition of + // the two-address register. + // e.g. + // %reg1028 = EXTRACT_SUBREG %reg1027, 1 + // %reg1029 = MOV8rr %reg1028 + // %reg1029 = SHR8ri %reg1029, 7, %EFLAGS + // insert => %reg1030 = MOV8rr %reg1028 + // %reg1030 = ADD8rr %reg1028, %reg1029, %EFLAGS + // In this case, it might not be possible to coalesce the second MOV8rr + // instruction if the first one is coalesced. So it would be profitable to + // commute it: + // %reg1028 = EXTRACT_SUBREG %reg1027, 1 + // %reg1029 = MOV8rr %reg1028 + // %reg1029 = SHR8ri %reg1029, 7, %EFLAGS + // insert => %reg1030 = MOV8rr %reg1029 + // %reg1030 = ADD8rr %reg1029, %reg1028, %EFLAGS + + if (!MI->killsRegister(regC)) + return false; + + // Ok, we have something like: + // %reg1030 = ADD8rr %reg1028, %reg1029, %EFLAGS + // let's see if it's worth commuting it. + + // If there is a use of regC between its last def (could be livein) and this + // instruction, then bail. + unsigned LastDefC = 0; + if (!NoUseAfterLastDef(regC, MBB, Dist, DistanceMap, LastDefC)) + return false; + + // If there is a use of regB between its last def (could be livein) and this + // instruction, then go ahead and make this transformation. + unsigned LastDefB = 0; + if (!NoUseAfterLastDef(regB, MBB, Dist, DistanceMap, LastDefB)) + return true; + + // Since there are no intervening uses for both registers, then commute + // if the def of regC is closer. Its live interval is shorter. + return LastDefB && LastDefC && LastDefC > LastDefB; +} + /// CommuteInstruction - Commute a two-address instruction and update the basic /// block, distance map, and live variables if needed. Return true if it is /// successful. @@ -419,6 +503,17 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { } } + // If it's profitable to commute the instruction, do so. + if (TID.isCommutable() && mi->getNumOperands() >= 3) { + unsigned regC = mi->getOperand(3-si).getReg(); + if (isProfitableToCommute(regB, regC, mi, mbbi, Dist, DistanceMap)) + if (CommuteInstruction(mi, mbbi, regC, Dist, DistanceMap)) { + ++NumAggrCommuted; + ++NumCommuted; + regB = regC; + } + } + InstructionRearranged: const TargetRegisterClass* rc = MRI->getRegClass(regA); MachineInstr *DefMI = MRI->getVRegDef(regB); @@ -436,7 +531,10 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { TII->copyRegToReg(*mbbi, mi, regA, regB, rc, rc); } - MachineBasicBlock::iterator prevMi = prior(mi); + MachineBasicBlock::iterator prevMI = prior(mi); + // Update DistanceMap. + DistanceMap.insert(std::make_pair(prevMI, Dist)); + DistanceMap[mi] = ++Dist; // Update live variables for regB. if (LV) { @@ -446,13 +544,13 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) { varInfoB.UsedBlocks[mbbi->getNumber()] = true; if (LV->removeVirtualRegisterKilled(regB, mi)) - LV->addVirtualRegisterKilled(regB, prevMi); + LV->addVirtualRegisterKilled(regB, prevMI); if (LV->removeVirtualRegisterDead(regB, mi)) - LV->addVirtualRegisterDead(regB, prevMi); + LV->addVirtualRegisterDead(regB, prevMI); } - DOUT << "\t\tprepend:\t"; DEBUG(prevMi->print(*cerr.stream(), &TM)); + DOUT << "\t\tprepend:\t"; DEBUG(prevMI->print(*cerr.stream(), &TM)); // Replace all occurences of regB with regA. for (unsigned i = 0, e = mi->getNumOperands(); i != e; ++i) { diff --git a/llvm/test/CodeGen/X86/2008-02-22-ReMatBug.ll b/llvm/test/CodeGen/X86/2008-02-22-ReMatBug.ll index f78d52651ded..539fc15fcba5 100644 --- a/llvm/test/CodeGen/X86/2008-02-22-ReMatBug.ll +++ b/llvm/test/CodeGen/X86/2008-02-22-ReMatBug.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of re-materialization} | grep 3 +; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of re-materialization} | grep 4 ; RUN: llvm-as < %s | llc -march=x86 -stats |& grep {Number of dead spill slots removed} ; rdar://5761454 diff --git a/llvm/test/CodeGen/X86/2008-07-19-movups-spills.ll b/llvm/test/CodeGen/X86/2008-07-19-movups-spills.ll index ef5c7c50f66e..880035715f83 100644 --- a/llvm/test/CodeGen/X86/2008-07-19-movups-spills.ll +++ b/llvm/test/CodeGen/X86/2008-07-19-movups-spills.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux -realign-stack=1 -mattr=sse2 | grep movaps | count 76 +; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux -realign-stack=1 -mattr=sse2 | grep movaps | count 75 ; RUN: llvm-as < %s | llc -mtriple=i686-pc-linux -realign-stack=0 -mattr=sse2 | grep movaps | count 1 ; PR2539 diff --git a/llvm/test/CodeGen/X86/pmul.ll b/llvm/test/CodeGen/X86/pmul.ll index 5ee09326dd1f..b619411eaff2 100644 --- a/llvm/test/CodeGen/X86/pmul.ll +++ b/llvm/test/CodeGen/X86/pmul.ll @@ -1,6 +1,6 @@ ; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -stack-alignment=16 > %t ; RUN: grep pmul %t | count 12 -; RUN: grep mov %t | count 19 +; RUN: grep mov %t | count 15 define <4 x i32> @a(<4 x i32> %i) nounwind { %A = mul <4 x i32> %i, < i32 117, i32 117, i32 117, i32 117 > diff --git a/llvm/test/CodeGen/X86/twoaddr-coalesce.ll b/llvm/test/CodeGen/X86/twoaddr-coalesce.ll new file mode 100644 index 000000000000..c369d91f56ae --- /dev/null +++ b/llvm/test/CodeGen/X86/twoaddr-coalesce.ll @@ -0,0 +1,25 @@ +; RUN: llvm-as < %s | llc -march=x86 -join-cross-class-copies -stats |& \ +; RUN: grep {twoaddrinstr} | grep {Number of instructions aggressively commuted} +; rdar://6523745 + +@"\01LC" = internal constant [4 x i8] c"%d\0A\00" ; <[4 x i8]*> [#uses=1] + +define i32 @main() nounwind { +bb1.thread: + br label %bb1 + +bb1: ; preds = %bb1, %bb1.thread + %i.0.reg2mem.0 = phi i32 [ 0, %bb1.thread ], [ %indvar.next, %bb1 ] ; [#uses=2] + %0 = trunc i32 %i.0.reg2mem.0 to i8 ; [#uses=1] + %1 = sdiv i8 %0, 2 ; [#uses=1] + %2 = sext i8 %1 to i32 ; [#uses=1] + %3 = tail call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @"\01LC", i32 0, i32 0), i32 %2) nounwind ; [#uses=0] + %indvar.next = add i32 %i.0.reg2mem.0, 1 ; [#uses=2] + %exitcond = icmp eq i32 %indvar.next, 258 ; [#uses=1] + br i1 %exitcond, label %bb2, label %bb1 + +bb2: ; preds = %bb1 + ret i32 0 +} + +declare i32 @printf(i8*, ...) nounwind -- GitLab From 1c7c019229c28c0319d00f1322cf82a9b087fe73 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sun, 25 Jan 2009 06:32:01 +0000 Subject: [PATCH 151/682] Private linkage support for PPC / Darwin. llvm-svn: 62955 --- llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp | 2 ++ llvm/test/CodeGen/PowerPC/private.ll | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp index 362e8d19da6c..5fe77be04000 100644 --- a/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp +++ b/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp @@ -776,6 +776,7 @@ bool PPCDarwinAsmPrinter::runOnMachineFunction(MachineFunction &MF) { switch (F->getLinkage()) { default: assert(0 && "Unknown linkage type!"); + case Function::PrivateLinkage: case Function::InternalLinkage: // Symbols default to internal. break; case Function::ExternalLinkage: @@ -959,6 +960,7 @@ void PPCDarwinAsmPrinter::printModuleLevelGV(const GlobalVariable* GVar) { O << "\t.globl " << name << '\n'; // FALL THROUGH case GlobalValue::InternalLinkage: + case GlobalValue::PrivateLinkage: break; default: cerr << "Unknown linkage type!"; diff --git a/llvm/test/CodeGen/PowerPC/private.ll b/llvm/test/CodeGen/PowerPC/private.ll index e25d2936b71e..0f0d13492a08 100644 --- a/llvm/test/CodeGen/PowerPC/private.ll +++ b/llvm/test/CodeGen/PowerPC/private.ll @@ -5,6 +5,11 @@ ; RUN: grep bl.*\.Lfoo %t ; RUN: grep .Lbaz: %t ; RUN: grep lis.*\.Lbaz %t +; RUN: llvm-as < %s | llc -mtriple=powerpc-apple-darwin > %t +; RUN: grep L_foo: %t +; RUN: grep bl.*\L_foo %t +; RUN: grep L_baz: %t +; RUN: grep lis.*\L_baz %t declare void @foo() -- GitLab From 5647c5d1a4d7b77c2b97e3ed355b05ef5b2f6de8 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sun, 25 Jan 2009 07:59:57 +0000 Subject: [PATCH 152/682] The function that does nothing but call malloc is noalias return. llvm-svn: 62956 --- llvm/lib/Transforms/IPO/IndMemRemoval.cpp | 11 ++++++----- llvm/test/Transforms/IndMemRem/2009-01-24-Noalias.ll | 11 +++++++++++ 2 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/IndMemRem/2009-01-24-Noalias.ll diff --git a/llvm/lib/Transforms/IPO/IndMemRemoval.cpp b/llvm/lib/Transforms/IPO/IndMemRemoval.cpp index b251ab4b09c1..6b1f969e440e 100644 --- a/llvm/lib/Transforms/IPO/IndMemRemoval.cpp +++ b/llvm/lib/Transforms/IPO/IndMemRemoval.cpp @@ -44,11 +44,11 @@ static RegisterPass X("indmemrem","Indirect Malloc and Free Removal"); bool IndMemRemPass::runOnModule(Module &M) { - //in Theory, all direct calls of malloc and free should be promoted - //to intrinsics. Therefor, this goes through and finds where the - //address of free or malloc are taken and replaces those with bounce - //functions, ensuring that all malloc and free that might happen - //happen through intrinsics. + // In theory, all direct calls of malloc and free should be promoted + // to intrinsics. Therefore, this goes through and finds where the + // address of free or malloc are taken and replaces those with bounce + // functions, ensuring that all malloc and free that might happen + // happen through intrinsics. bool changed = false; if (Function* F = M.getFunction("free")) { if (F->isDeclaration() && F->arg_size() == 1 && !F->use_empty()) { @@ -69,6 +69,7 @@ bool IndMemRemPass::runOnModule(Module &M) { Function* FN = Function::Create(F->getFunctionType(), GlobalValue::LinkOnceLinkage, "malloc_llvm_bounce", &M); + FN->setDoesNotAlias(0); BasicBlock* bb = BasicBlock::Create("entry",FN); Instruction* c = CastInst::CreateIntegerCast( FN->arg_begin(), Type::Int32Ty, false, "c", bb); diff --git a/llvm/test/Transforms/IndMemRem/2009-01-24-Noalias.ll b/llvm/test/Transforms/IndMemRem/2009-01-24-Noalias.ll new file mode 100644 index 000000000000..bc3d0bfe5e3f --- /dev/null +++ b/llvm/test/Transforms/IndMemRem/2009-01-24-Noalias.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | opt -indmemrem | llvm-dis | grep bounce | grep noalias + +declare i8* @malloc(i32) + +@g = external global i8* + +define void @test() { + %A = bitcast i8* (i32) * @malloc to i8* + store i8* %A, i8** @g + ret void +} -- GitLab From cb7a10ab63c92273161105d55b55d4073f55e7d9 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sun, 25 Jan 2009 08:05:07 +0000 Subject: [PATCH 153/682] Actually run the test in this directory. llvm-svn: 62957 --- llvm/test/Transforms/IndMemRem/dg.exp | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 llvm/test/Transforms/IndMemRem/dg.exp diff --git a/llvm/test/Transforms/IndMemRem/dg.exp b/llvm/test/Transforms/IndMemRem/dg.exp new file mode 100644 index 000000000000..f2005891a59a --- /dev/null +++ b/llvm/test/Transforms/IndMemRem/dg.exp @@ -0,0 +1,3 @@ +load_lib llvm.exp + +RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]] -- GitLab From 21add8f9835a74d187e4d3f75b4d64dfb8fac264 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sun, 25 Jan 2009 08:16:27 +0000 Subject: [PATCH 154/682] Start generating arbitrary precision integer SCEVs. This removes the temporary code that rounded up and capped the size. llvm-svn: 62958 --- llvm/lib/Analysis/ScalarEvolution.cpp | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp index ca16a755dcab..c05ba8d0ef27 100644 --- a/llvm/lib/Analysis/ScalarEvolution.cpp +++ b/llvm/lib/Analysis/ScalarEvolution.cpp @@ -585,17 +585,7 @@ static SCEVHandle BinomialCoefficient(SCEVHandle It, unsigned K, } // We need at least W + T bits for the multiplication step - // FIXME: A temporary hack; we round up the bitwidths - // to the nearest power of 2 to be nice to the code generator. - unsigned CalculationBits = 1U << Log2_32_Ceil(W + T); - // FIXME: Temporary hack to avoid generating integers that are too wide. - // Although, it's not completely clear how to determine how much - // widening is safe; for example, on X86, we can't really widen - // beyond 64 because we need to be able to do multiplication - // that's CalculationBits wide, but on X86-64, we can safely widen up to - // 128 bits. - if (CalculationBits > 64) - return new SCEVCouldNotCompute(); + unsigned CalculationBits = W + T; // Calcuate 2^T, at width T+W. APInt DivFactor = APInt(CalculationBits, 1).shl(T); -- GitLab From a865ade730d47e4b2184256f48a48bd0757f41f0 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sun, 25 Jan 2009 13:34:47 +0000 Subject: [PATCH 155/682] Fix compile error from r62953. llvm-svn: 62959 --- clang/lib/AST/Expr.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index defb0c3e91c3..63484d1b87dc 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -733,7 +733,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const { return cast(this)->getSubExpr()->isConstantInitializer(Ctx); break; case DesignatedInitExprClass: - return cast(Init)->getInit()->isConstantInitializer(Ctx); + return cast(this)-> + getInit()->isConstantInitializer(Ctx); } return isEvaluatable(Ctx); -- GitLab From 8b2540439f0f8377111caaae7e76a61f0c223f7d Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sun, 25 Jan 2009 13:35:30 +0000 Subject: [PATCH 156/682] Introduce an explicit case for member pointers in CodeGenTypes. However, it simply asserts. llvm-svn: 62960 --- clang/lib/CodeGen/CodeGenTypes.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index 9e57aafa02a3..aac6e8d64406 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -312,6 +312,13 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { return llvm::PointerType::get(ConvertTypeRecursive(FTy), FTy.getAddressSpace()); } + + case Type::MemberPointer: + // FIXME: Implement C++ pointer-to-member. The GCC representation is + // documented here: + // http://gcc.gnu.org/onlinedocs/gccint/Type-Layout.html#Type-Layout + assert(0 && "FIXME: We can't handle member pointers yet."); + return llvm::OpaqueType::get(); } // FIXME: implement. -- GitLab From e3f2278de157de78c9e80cfaeef90101883d6d9b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 25 Jan 2009 16:04:50 +0000 Subject: [PATCH 157/682] Reality-check the FAQ entry for "Can I use LLVM to convert C++ to C?" llvm-svn: 62961 --- llvm/docs/FAQ.html | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/llvm/docs/FAQ.html b/llvm/docs/FAQ.html index 753331269f51..ad08f10cfa29 100644 --- a/llvm/docs/FAQ.html +++ b/llvm/docs/FAQ.html @@ -564,9 +564,8 @@ code that you desire. Note that the generated C code will be very low level (all loops are lowered to gotos, etc) and not very pretty (comments are stripped, original source formatting is totally lost, variables are renamed, expressions are regrouped), -so this may not be what you're looking for. However, this is a good way to add -C++ support for a processor that does not otherwise have a C++ compiler. -

+so this may not be what you're looking for. Also, there are several +limitations noted below.

Use commands like this:

@@ -603,20 +602,31 @@ C++ support for a processor that does not otherwise have a C++ compiler. -

Note that, by default, the C backend does not support exception handling. If -you want/need it for a certain program, you can enable it by passing -"-enable-correct-eh-support" to the llc program. The resultant code will use -setjmp/longjmp to implement exception support that is correct but relatively -slow.

+

Using LLVM does not eliminate the need for C++ library support. +If you use the llvm-g++ front-end, the generated code will depend on +g++'s C++ support libraries in the same way that code generated from +g++ would. If you use another C++ front-end, the generated code will +depend on whatever library that front-end would normally require.

-

Also note: this specific sequence of commands won't work if you use a -function defined in the C++ runtime library (or any other C++ library). To -access an external C++ library, you must manually compile libstdc++ to LLVM +

If you are working on a platform that does not provide any C++ +libraries, you may be able to manually compile libstdc++ to LLVM bitcode, statically link it into your program, then use the commands above to -convert the whole result into C code. Alternatively, you can compile the +convert the whole result into C code. Alternatively, you might compile the libraries and your application into two different chunks of C code and link them.

+

Note that, by default, the C back end does not support exception handling. If +you want/need it for a certain program, you can enable it by passing +"-enable-correct-eh-support" to the llc program. The resultant code will use +setjmp/longjmp to implement exception support that is relatively slow, and +not C++-ABI-conforming on most platforms, but otherwise correct.

+ +

Also, there are a number of other limitations of the C backend that +cause it to produce code that does not fully conform to the C++ ABI on +most platforms. Some of the C++ programs in LLVM's test suite are known +to fail when compiled with the C back end because of ABI incompatiblities +with standard C++ libraries.

+ -- GitLab From e7b0dde2ee8f8b6681a97b2cbe49e51d840ec69b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 25 Jan 2009 16:20:37 +0000 Subject: [PATCH 158/682] Move the N->use_empty() assert from DeleteNode to DeleteNodeNotInCSEMaps, since DeleteNode just calls DeleteNodeNotInCSEMaps. llvm-svn: 62962 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 6d1fdd23407d..ecdbf2156ca6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -568,8 +568,6 @@ void SelectionDAG::RemoveDeadNode(SDNode *N, DAGUpdateListener *UpdateListener){ } void SelectionDAG::DeleteNode(SDNode *N) { - assert(N->use_empty() && "Cannot delete a node that is not dead!"); - // First take this out of the appropriate CSE map. RemoveNodeFromCSEMaps(N); @@ -579,7 +577,8 @@ void SelectionDAG::DeleteNode(SDNode *N) { } void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { - assert(N != AllNodes.begin()); + assert(N != AllNodes.begin() && "Cannot delete the entry node!"); + assert(N->use_empty() && "Cannot delete a node that is not dead!"); // Drop all of the operands and decrement used node's use counts. for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) -- GitLab From 3a113ec468c1099778089d8b28fd7f116328608e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 25 Jan 2009 16:21:38 +0000 Subject: [PATCH 159/682] Whitespace tidiments. llvm-svn: 62963 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ecdbf2156ca6..920441012217 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -952,7 +952,7 @@ SDValue SelectionDAG::getGlobalAddress(const GlobalValue *GV, ID.AddInteger(Offset); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) - return SDValue(E, 0); + return SDValue(E, 0); SDNode *N = NodeAllocator.Allocate(); new (N) GlobalAddressSDNode(isTargetGA, GV, VT, Offset); CSEMap.InsertNode(N, IP); @@ -4398,7 +4398,6 @@ SDNode *SelectionDAG::getNodeIfExists(unsigned Opcode, SDVTList VTList, return NULL; } - /// ReplaceAllUsesWith - Modify anything using 'From' to use 'To' instead. /// This can cause recursive merging of nodes in the DAG. /// -- GitLab From f1d38be265f49b09bc3c9dec620aabd2ad3269a7 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Sun, 25 Jan 2009 16:29:12 +0000 Subject: [PATCH 160/682] Eliminate the loop that searches through each of the operands of each use in the SelectionDAG ReplaceAllUses* functions. Thanks to Chris for spotting this opportunity. Also, factor out code from all 5 of the ReplaceAllUses* functions into AddNonLeafNodeToCSEMaps, which is now renamed AddModifiedNodeToCSEMaps to more accurately reflect its purpose. llvm-svn: 62964 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 2 +- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 373 +++++++++--------- 2 files changed, 179 insertions(+), 196 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 8f41b5c208c9..209fedb1e96c 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -800,7 +800,7 @@ public: private: bool RemoveNodeFromCSEMaps(SDNode *N); - SDNode *AddNonLeafNodeToCSEMaps(SDNode *N); + void AddModifiedNodeToCSEMaps(SDNode *N, DAGUpdateListener *UpdateListener); SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op, void *&InsertPos); SDNode *FindModifiedNodeSlot(SDNode *N, SDValue Op1, SDValue Op2, void *&InsertPos); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 920441012217..ab222c4f2faa 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -651,20 +651,36 @@ bool SelectionDAG::RemoveNodeFromCSEMaps(SDNode *N) { return Erased; } -/// AddNonLeafNodeToCSEMaps - Add the specified node back to the CSE maps. It -/// has been taken out and modified in some way. If the specified node already -/// exists in the CSE maps, do not modify the maps, but return the existing node -/// instead. If it doesn't exist, add it and return null. +/// AddModifiedNodeToCSEMaps - The specified node has been removed from the CSE +/// maps and modified in place. Add it back to the CSE maps, unless an identical +/// node already exists, in which case transfer all its users to the existing +/// node. This transfer can potentially trigger recursive merging. /// -SDNode *SelectionDAG::AddNonLeafNodeToCSEMaps(SDNode *N) { - assert(N->getNumOperands() && "This is a leaf node!"); - - if (doNotCSE(N)) - return 0; +void +SelectionDAG::AddModifiedNodeToCSEMaps(SDNode *N, + DAGUpdateListener *UpdateListener) { + // For node types that aren't CSE'd, just act as if no identical node + // already exists. + if (!doNotCSE(N)) { + SDNode *Existing = CSEMap.GetOrInsertNode(N); + if (Existing != N) { + // If there was already an existing matching node, use ReplaceAllUsesWith + // to replace the dead one with the existing one. This can cause + // recursive merging of other unrelated nodes down the line. + ReplaceAllUsesWith(N, Existing, UpdateListener); + + // N is now dead. Inform the listener if it exists and delete it. + if (UpdateListener) + UpdateListener->NodeDeleted(N, Existing); + DeleteNodeNotInCSEMaps(N); + return; + } + } - SDNode *New = CSEMap.GetOrInsertNode(N); - if (New != N) return New; // Node already existed. - return 0; + // If the node doesn't already exist, we updated it. Inform a listener if + // it exists. + if (UpdateListener) + UpdateListener->NodeUpdated(N); } /// FindModifiedNodeSlot - Find a slot for the specified node if its operands @@ -3900,8 +3916,7 @@ SDValue SelectionDAG::UpdateNodeOperands(SDValue InN, SDValue Op) { // Now we update the operands. N->OperandList[0].getVal()->removeUser(0, N); - N->OperandList[0] = Op; - N->OperandList[0].setUser(N); + N->OperandList[0].getSDValue() = Op; Op.getNode()->addUser(0, N); // If this gets put into a CSE map, add it. @@ -3931,14 +3946,12 @@ UpdateNodeOperands(SDValue InN, SDValue Op1, SDValue Op2) { // Now we update the operands. if (N->OperandList[0] != Op1) { N->OperandList[0].getVal()->removeUser(0, N); - N->OperandList[0] = Op1; - N->OperandList[0].setUser(N); + N->OperandList[0].getSDValue() = Op1; Op1.getNode()->addUser(0, N); } if (N->OperandList[1] != Op2) { N->OperandList[1].getVal()->removeUser(1, N); - N->OperandList[1] = Op2; - N->OperandList[1].setUser(N); + N->OperandList[1].getSDValue() = Op2; Op2.getNode()->addUser(1, N); } @@ -3999,8 +4012,7 @@ UpdateNodeOperands(SDValue InN, const SDValue *Ops, unsigned NumOps) { for (unsigned i = 0; i != NumOps; ++i) { if (N->OperandList[i] != Ops[i]) { N->OperandList[i].getVal()->removeUser(i, N); - N->OperandList[i] = Ops[i]; - N->OperandList[i].setUser(N); + N->OperandList[i].getSDValue() = Ops[i]; Ops[i].getNode()->addUser(i, N); } } @@ -4272,7 +4284,7 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, // Assign the new operands. N->NumOperands = NumOps; for (unsigned i = 0, e = NumOps; i != e; ++i) { - N->OperandList[i] = Ops[i]; + N->OperandList[i].getSDValue() = Ops[i]; N->OperandList[i].setUser(N); SDNode *ToUse = N->OperandList[i].getVal(); ToUse->addUser(i, N); @@ -4410,43 +4422,35 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To, "Cannot replace with this method!"); assert(From != To.getNode() && "Cannot replace uses of with self"); - // Iterate over all the existing uses of From. This specifically avoids - // visiting any new uses of From that arise while the replacement is - // happening, because any such uses would be the result of CSE: If an - // existing node looks like From after one of its operands is replaced - // by To, we don't want to replace of all its users with To too. - // See PR3018 for more info. + // Iterate over all the existing uses of From. New uses will be added + // to the beginning of the use list, which we avoid visiting. + // This specifically avoids visiting uses of From that arise while the + // replacement is happening, because any such uses would be the result + // of CSE: If an existing node looks like From after one of its operands + // is replaced by To, we don't want to replace of all its users with To + // too. See PR3018 for more info. SDNode::use_iterator UI = From->use_begin(), UE = From->use_end(); while (UI != UE) { - SDNode *U = *UI; - do ++UI; while (UI != UE && *UI == U); + SDNode *User = *UI; // This node is about to morph, remove its old self from the CSE maps. - RemoveNodeFromCSEMaps(U); - int operandNum = 0; - for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); - I != E; ++I, ++operandNum) - if (I->getVal() == From) { - From->removeUser(operandNum, U); - *I = To; - I->setUser(U); - To.getNode()->addUser(operandNum, U); - } - - // Now that we have modified U, add it back to the CSE maps. If it already - // exists there, recursively merge the results together. - if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { - ReplaceAllUsesWith(U, Existing, UpdateListener); - // U is now dead. Inform the listener if it exists and delete it. - if (UpdateListener) - UpdateListener->NodeDeleted(U, Existing); - DeleteNodeNotInCSEMaps(U); - } else { - // If the node doesn't already exist, we updated it. Inform a listener if - // it exists. - if (UpdateListener) - UpdateListener->NodeUpdated(U); - } + RemoveNodeFromCSEMaps(User); + + // A user can appear in a use list multiple times, and when this + // happens the uses are usually next to each other in the list. + // To help reduce the number of CSE recomputations, process all + // the uses of this user that we can find this way. + do { + unsigned operandNum = UI.getOperandNo(); + ++UI; + From->removeUser(operandNum, User); + User->OperandList[operandNum].getSDValue() = To; + To.getNode()->addUser(operandNum, User); + } while (UI != UE && *UI == User); + + // Now that we have modified User, add it back to the CSE maps. If it + // already exists there, recursively merge the results together. + AddModifiedNodeToCSEMaps(User, UpdateListener); } } @@ -4470,34 +4474,26 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, // the ReplaceAllUsesWith above. SDNode::use_iterator UI = From->use_begin(), UE = From->use_end(); while (UI != UE) { - SDNode *U = *UI; - do ++UI; while (UI != UE && *UI == U); + SDNode *User = *UI; // This node is about to morph, remove its old self from the CSE maps. - RemoveNodeFromCSEMaps(U); - int operandNum = 0; - for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); - I != E; ++I, ++operandNum) - if (I->getVal() == From) { - From->removeUser(operandNum, U); - I->getSDValue().setNode(To); - To->addUser(operandNum, U); - } + RemoveNodeFromCSEMaps(User); - // Now that we have modified U, add it back to the CSE maps. If it already - // exists there, recursively merge the results together. - if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { - ReplaceAllUsesWith(U, Existing, UpdateListener); - // U is now dead. Inform the listener if it exists and delete it. - if (UpdateListener) - UpdateListener->NodeDeleted(U, Existing); - DeleteNodeNotInCSEMaps(U); - } else { - // If the node doesn't already exist, we updated it. Inform a listener if - // it exists. - if (UpdateListener) - UpdateListener->NodeUpdated(U); - } + // A user can appear in a use list multiple times, and when this + // happens the uses are usually next to each other in the list. + // To help reduce the number of CSE recomputations, process all + // the uses of this user that we can find this way. + do { + unsigned operandNum = UI.getOperandNo(); + ++UI; + From->removeUser(operandNum, User); + User->OperandList[operandNum].getSDValue().setNode(To); + To->addUser(operandNum, User); + } while (UI != UE && *UI == User); + + // Now that we have modified User, add it back to the CSE maps. If it + // already exists there, recursively merge the results together. + AddModifiedNodeToCSEMaps(User, UpdateListener); } } @@ -4516,36 +4512,28 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, // the ReplaceAllUsesWith above. SDNode::use_iterator UI = From->use_begin(), UE = From->use_end(); while (UI != UE) { - SDNode *U = *UI; - do ++UI; while (UI != UE && *UI == U); + SDNode *User = *UI; // This node is about to morph, remove its old self from the CSE maps. - RemoveNodeFromCSEMaps(U); - int operandNum = 0; - for (SDNode::op_iterator I = U->op_begin(), E = U->op_end(); - I != E; ++I, ++operandNum) - if (I->getVal() == From) { - const SDValue &ToOp = To[I->getSDValue().getResNo()]; - From->removeUser(operandNum, U); - *I = ToOp; - I->setUser(U); - ToOp.getNode()->addUser(operandNum, U); - } + RemoveNodeFromCSEMaps(User); - // Now that we have modified U, add it back to the CSE maps. If it already - // exists there, recursively merge the results together. - if (SDNode *Existing = AddNonLeafNodeToCSEMaps(U)) { - ReplaceAllUsesWith(U, Existing, UpdateListener); - // U is now dead. Inform the listener if it exists and delete it. - if (UpdateListener) - UpdateListener->NodeDeleted(U, Existing); - DeleteNodeNotInCSEMaps(U); - } else { - // If the node doesn't already exist, we updated it. Inform a listener if - // it exists. - if (UpdateListener) - UpdateListener->NodeUpdated(U); - } + // A user can appear in a use list multiple times, and when this + // happens the uses are usually next to each other in the list. + // To help reduce the number of CSE recomputations, process all + // the uses of this user that we can find this way. + do { + unsigned operandNum = UI.getOperandNo(); + const SDValue &ToOp = + To[User->OperandList[operandNum].getSDValue().getResNo()]; + ++UI; + From->removeUser(operandNum, User); + User->OperandList[operandNum].getSDValue() = ToOp; + ToOp.getNode()->addUser(operandNum, User); + } while (UI != UE && *UI == User); + + // Now that we have modified User, add it back to the CSE maps. If it + // already exists there, recursively merge the results together. + AddModifiedNodeToCSEMaps(User, UpdateListener); } } @@ -4563,57 +4551,62 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To, return; } - // Get all of the users of From.getNode(). We want these in a nice, - // deterministically ordered and uniqued set, so we use a SmallSetVector. - SmallSetVector Users(From.getNode()->use_begin(), From.getNode()->use_end()); + // Iterate over just the existing users of From. See the comments in + // the ReplaceAllUsesWith above. + SDNode::use_iterator UI = From.getNode()->use_begin(), + UE = From.getNode()->use_end(); + while (UI != UE) { + SDNode *User = *UI; + bool UserRemovedFromCSEMaps = false; + + // A user can appear in a use list multiple times, and when this + // happens the uses are usually next to each other in the list. + // To help reduce the number of CSE recomputations, process all + // the uses of this user that we can find this way. + do { + unsigned operandNum = UI.getOperandNo(); + + // Skip uses of different values from the same node. + if (User->OperandList[operandNum].getSDValue().getResNo() != + From.getResNo()) { + ++UI; + continue; + } - while (!Users.empty()) { - // We know that this user uses some value of From. If it is the right - // value, update it. - SDNode *User = Users.back(); - Users.pop_back(); - - // Scan for an operand that matches From. - SDNode::op_iterator Op = User->op_begin(), E = User->op_end(); - for (; Op != E; ++Op) - if (*Op == From) break; - - // If there are no matches, the user must use some other result of From. - if (Op == E) continue; - - // Okay, we know this user needs to be updated. Remove its old self - // from the CSE maps. - RemoveNodeFromCSEMaps(User); - - // Update all operands that match "From" in case there are multiple uses. - for (; Op != E; ++Op) { - if (*Op == From) { - From.getNode()->removeUser(Op-User->op_begin(), User); - *Op = To; - Op->setUser(User); - To.getNode()->addUser(Op-User->op_begin(), User); + // If this node hasn't been modified yet, it's still in the CSE maps, + // so remove its old self from the CSE maps. + if (!UserRemovedFromCSEMaps) { + RemoveNodeFromCSEMaps(User); + UserRemovedFromCSEMaps = true; } - } - + + ++UI; + From.getNode()->removeUser(operandNum, User); + User->OperandList[operandNum].getSDValue() = To; + To.getNode()->addUser(operandNum, User); + } while (UI != UE && *UI == User); + + // We are iterating over all uses of the From node, so if a use + // doesn't use the specific value, no changes are made. + if (!UserRemovedFromCSEMaps) + continue; + // Now that we have modified User, add it back to the CSE maps. If it // already exists there, recursively merge the results together. - SDNode *Existing = AddNonLeafNodeToCSEMaps(User); - if (!Existing) { - if (UpdateListener) UpdateListener->NodeUpdated(User); - continue; // Continue on to next user. - } - - // If there was already an existing matching node, use ReplaceAllUsesWith - // to replace the dead one with the existing one. This can cause - // recursive merging of other unrelated nodes down the line. - ReplaceAllUsesWith(User, Existing, UpdateListener); - - // User is now dead. Notify a listener if present. - if (UpdateListener) UpdateListener->NodeDeleted(User, Existing); - DeleteNodeNotInCSEMaps(User); + AddModifiedNodeToCSEMaps(User, UpdateListener); } } +namespace { + /// UseMemo - This class is used by SelectionDAG::ReplaceAllUsesOfValuesWith + /// to record information about a use. + struct UseMemo { + SDNode *User; + unsigned Index; + unsigned operandNum; + }; +} + /// ReplaceAllUsesOfValuesWith - Replace any uses of From with To, leaving /// uses of other values produced by From.getVal() alone. The same value may /// appear in both the From and To list. The Deleted vector is @@ -4626,57 +4619,47 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From, if (Num == 1) return ReplaceAllUsesOfValueWith(*From, *To, UpdateListener); - SmallVector, 16> Users; - for (unsigned i = 0; i != Num; ++i) - for (SDNode::use_iterator UI = From[i].getNode()->use_begin(), - E = From[i].getNode()->use_end(); UI != E; ++UI) - Users.push_back(std::make_pair(*UI, i)); + // Read up all the uses and make records of them. This helps + // processing new uses that are introduced during the + // replacement process. + SmallVector Uses; + for (unsigned i = 0; i != Num; ++i) { + unsigned FromResNo = From[i].getResNo(); + SDNode *FromNode = From[i].getNode(); + for (SDNode::use_iterator UI = FromNode->use_begin(), + E = FromNode->use_end(); UI != E; ++UI) + if (UI.getUse().getSDValue().getResNo() == FromResNo) { + UseMemo Memo = { *UI, i, UI.getOperandNo() }; + Uses.push_back(Memo); + } + } - while (!Users.empty()) { + for (unsigned UseIndex = 0, UseIndexEnd = Uses.size(); + UseIndex != UseIndexEnd; ) { // We know that this user uses some value of From. If it is the right // value, update it. - SDNode *User = Users.back().first; - unsigned i = Users.back().second; - Users.pop_back(); - - // Scan for an operand that matches From. - SDNode::op_iterator Op = User->op_begin(), E = User->op_end(); - for (; Op != E; ++Op) - if (*Op == From[i]) break; - - // If there are no matches, the user must use some other result of From. - if (Op == E) continue; - - // Okay, we know this user needs to be updated. Remove its old self - // from the CSE maps. + SDNode *User = Uses[UseIndex].User; + + // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(User); - - // Update all operands that match "From" in case there are multiple uses. - for (; Op != E; ++Op) { - if (*Op == From[i]) { - From[i].getNode()->removeUser(Op-User->op_begin(), User); - *Op = To[i]; - Op->setUser(User); - To[i].getNode()->addUser(Op-User->op_begin(), User); - } - } - + + // A user can appear in a use list multiple times, and when this + // happens the uses are usually next to each other in the list. + // To help reduce the number of CSE recomputations, process all + // the uses of this user that we can find this way. + do { + unsigned i = Uses[UseIndex].Index; + unsigned operandNum = Uses[UseIndex].operandNum; + ++UseIndex; + + From[i].getNode()->removeUser(operandNum, User); + User->OperandList[operandNum].getSDValue() = To[i]; + To[i].getNode()->addUser(operandNum, User); + } while (UseIndex != UseIndexEnd && Uses[UseIndex].User == User); + // Now that we have modified User, add it back to the CSE maps. If it // already exists there, recursively merge the results together. - SDNode *Existing = AddNonLeafNodeToCSEMaps(User); - if (!Existing) { - if (UpdateListener) UpdateListener->NodeUpdated(User); - continue; // Continue on to next user. - } - - // If there was already an existing matching node, use ReplaceAllUsesWith - // to replace the dead one with the existing one. This can cause - // recursive merging of other unrelated nodes down the line. - ReplaceAllUsesWith(User, Existing, UpdateListener); - - // User is now dead. Notify a listener if present. - if (UpdateListener) UpdateListener->NodeDeleted(User, Existing); - DeleteNodeNotInCSEMaps(User); + AddModifiedNodeToCSEMaps(User, UpdateListener); } } -- GitLab From a23c73bbdc7198f457c6d39b446b589dc5cab22b Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sun, 25 Jan 2009 17:58:56 +0000 Subject: [PATCH 161/682] If user explicitly asks not to use SSE, don't force it. This fixes LLVM part of PR3402. llvm-svn: 62967 --- llvm/lib/Target/X86/X86Subtarget.cpp | 2 -- llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 5dc5103727d5..99708e04cf9c 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -331,8 +331,6 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // are enabled. These are available on all x86-64 CPUs. if (Is64Bit) { HasX86_64 = true; - if (X86SSELevel < SSE2) - X86SSELevel = SSE2; } DOUT << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel diff --git a/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll b/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll new file mode 100644 index 000000000000..b12e4137dbd5 --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | llc -march=x86-64 -mattr=-sse,-sse2 | not grep xmm +; PR3402 +target datalayout = +"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.ktermios = type { i32, i32, i32, i32, i8, [19 x i8], i32, i32 } + +define void @foo() nounwind { +entry: + %termios = alloca %struct.ktermios, align 8 + %termios1 = bitcast %struct.ktermios* %termios to i8* + call void @llvm.memset.i64(i8* %termios1, i8 0, i64 44, i32 8) + call void @bar(%struct.ktermios* %termios) nounwind + ret void +} + +declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind + +declare void @bar(%struct.ktermios*) + -- GitLab From 3cc194000323e58f4d16e6c5324bb1fa9468db23 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sun, 25 Jan 2009 18:00:06 +0000 Subject: [PATCH 162/682] testcase for llvm-gcc part of PR3402. llvm-svn: 62969 --- llvm/test/FrontendC/2009-01-25-NoSSE.c | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 llvm/test/FrontendC/2009-01-25-NoSSE.c diff --git a/llvm/test/FrontendC/2009-01-25-NoSSE.c b/llvm/test/FrontendC/2009-01-25-NoSSE.c new file mode 100644 index 000000000000..1585f4b007b4 --- /dev/null +++ b/llvm/test/FrontendC/2009-01-25-NoSSE.c @@ -0,0 +1,30 @@ +// RUN: $llvmgcc -m64 -O1 -march=core2 -mno-sse %s -S -o - | not grep xmm +// PR3402 +// This is a test for x86/x86-64, add your target below if it FAILs. +// XFAIL: alpha|ia64|arm|powerpc|sparc +typedef unsigned long __kernel_size_t; +typedef __kernel_size_t size_t; +void *memset(void *s, int c, size_t n); + +typedef unsigned char cc_t; +typedef unsigned int speed_t; +typedef unsigned int tcflag_t; + +struct ktermios { + tcflag_t c_iflag; + tcflag_t c_oflag; + tcflag_t c_cflag; + tcflag_t c_lflag; + cc_t c_line; + cc_t c_cc[19]; + speed_t c_ispeed; + speed_t c_ospeed; +}; +void bar(struct ktermios*); +void foo() +{ + struct ktermios termios; + memset(&termios, 0, sizeof(termios)); + bar(&termios); +} + -- GitLab From 72b597d6b6ae7106889b3ff6916d64963477fb45 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Sun, 25 Jan 2009 19:43:20 +0000 Subject: [PATCH 163/682] Implement implicit conversions for pointers-to-member. llvm-svn: 62971 --- clang/include/clang/Basic/DiagnosticKinds.def | 6 + clang/lib/Sema/Sema.h | 3 + clang/lib/Sema/SemaExprCXX.cpp | 5 +- clang/lib/Sema/SemaOverload.cpp | 107 +++++++++++++++++- clang/lib/Sema/SemaType.cpp | 11 +- clang/test/SemaCXX/member-pointer.cpp | 13 +++ .../test/SemaCXX/qualification-conversion.cpp | 12 ++ 7 files changed, 147 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 93b023e56099..e9dbad94b676 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -1590,6 +1590,12 @@ DIAG(err_duplicate_base_class, ERROR, // FIXME: better way to display derivation? Pass entire thing into diagclient? DIAG(err_ambiguous_derived_to_base_conv, ERROR, "ambiguous conversion from derived class %0 to base class %1:%2") +DIAG(err_ambiguous_base_to_derived_memptr_conv, ERROR, + "ambiguous conversion from pointer to member of base class %0 " + "to pointer to member of derived class %1:%2") +DIAG(err_memptr_conv_via_virtual, ERROR, + "conversion from pointer to member of class %0 to pointer to member " + "of class %1 via virtual base %2 is not allowed") // C++ member name lookup DIAG(err_ambiguous_member_multiple_subobjects, ERROR, diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index a993ebe2cbd9..51d2e38c938b 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -428,6 +428,9 @@ public: bool isObjCPointerConversion(QualType FromType, QualType ToType, QualType& ConvertedType, bool &IncompatibleObjC); bool CheckPointerConversion(Expr *From, QualType ToType); + bool IsMemberPointerConversion(Expr *From, QualType FromType, QualType ToType, + QualType &ConvertedType); + bool CheckMemberPointerConversion(Expr *From, QualType ToType); bool IsQualificationConversion(QualType FromType, QualType ToType); bool IsUserDefinedConversion(Expr *From, QualType ToType, UserDefinedConversionSequence& User, diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 1266d32d3f8a..04e37d1ebf43 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -832,8 +832,9 @@ Sema::PerformImplicitConversion(Expr *&From, QualType ToType, break; case ICK_Pointer_Member: - // FIXME: Implement pointer-to-member conversions. - assert(false && "Pointer-to-member conversions are unsupported"); + if (CheckMemberPointerConversion(From, ToType)) + return true; + ImpCastExprToType(From, ToType); break; case ICK_Boolean_Conversion: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 9441ea5f166b..b2ae90b4b875 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -544,14 +544,17 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, SCS.Second = ICK_Pointer_Conversion; SCS.IncompatibleObjC = IncompatibleObjC; } - // FIXME: Pointer to member conversions (4.11). + // Pointer to member conversions (4.11). + else if (IsMemberPointerConversion(From, FromType, ToType, FromType)) { + SCS.Second = ICK_Pointer_Member; + } // Boolean conversions (C++ 4.12). - // FIXME: pointer-to-member type else if (ToType->isBooleanType() && (FromType->isArithmeticType() || FromType->isEnumeralType() || FromType->isPointerType() || - FromType->isBlockPointerType())) { + FromType->isBlockPointerType() || + FromType->isMemberPointerType())) { SCS.Second = ICK_Boolean_Conversion; FromType = Context.BoolTy; } else { @@ -999,7 +1002,7 @@ bool Sema::isObjCPointerConversion(QualType FromType, QualType ToType, } } - return false; + return false; } /// CheckPointerConversion - Check the pointer conversion from the @@ -1013,8 +1016,6 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType) { if (const PointerType *FromPtrType = FromType->getAsPointerType()) if (const PointerType *ToPtrType = ToType->getAsPointerType()) { - BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, - /*DetectVirtual=*/false); QualType FromPointeeType = FromPtrType->getPointeeType(), ToPointeeType = ToPtrType->getPointeeType(); @@ -1040,6 +1041,100 @@ bool Sema::CheckPointerConversion(Expr *From, QualType ToType) { return false; } +/// IsMemberPointerConversion - Determines whether the conversion of the +/// expression From, which has the (possibly adjusted) type FromType, can be +/// converted to the type ToType via a member pointer conversion (C++ 4.11). +/// If so, returns true and places the converted type (that might differ from +/// ToType in its cv-qualifiers at some level) into ConvertedType. +bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, + QualType ToType, QualType &ConvertedType) +{ + const MemberPointerType *ToTypePtr = ToType->getAsMemberPointerType(); + if (!ToTypePtr) + return false; + + // A null pointer constant can be converted to a member pointer (C++ 4.11p1) + if (From->isNullPointerConstant(Context)) { + ConvertedType = ToType; + return true; + } + + // Otherwise, both types have to be member pointers. + const MemberPointerType *FromTypePtr = FromType->getAsMemberPointerType(); + if (!FromTypePtr) + return false; + + // A pointer to member of B can be converted to a pointer to member of D, + // where D is derived from B (C++ 4.11p2). + QualType FromClass(FromTypePtr->getClass(), 0); + QualType ToClass(ToTypePtr->getClass(), 0); + // FIXME: What happens when these are dependent? Is this function even called? + + if (IsDerivedFrom(ToClass, FromClass)) { + ConvertedType = Context.getMemberPointerType(FromTypePtr->getPointeeType(), + ToClass.getTypePtr()); + return true; + } + + return false; +} + +/// CheckMemberPointerConversion - Check the member pointer conversion from the +/// expression From to the type ToType. This routine checks for ambiguous or +/// virtual (FIXME: or inaccessible) base-to-derived member pointer conversions +/// for which IsMemberPointerConversion has already returned true. It returns +/// true and produces a diagnostic if there was an error, or returns false +/// otherwise. +bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) { + QualType FromType = From->getType(); + + if (const MemberPointerType *FromPtrType = + FromType->getAsMemberPointerType()) { + if (const MemberPointerType *ToPtrType = + ToType->getAsMemberPointerType()) { + QualType FromClass = QualType(FromPtrType->getClass(), 0); + QualType ToClass = QualType(ToPtrType->getClass(), 0); + + // FIXME: What about dependent types? + assert(FromClass->isRecordType() && "Pointer into non-class."); + assert(ToClass->isRecordType() && "Pointer into non-class."); + + BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, + /*DetectVirtual=*/true); + bool DerivationOkay = IsDerivedFrom(ToClass, FromClass, Paths); + assert(DerivationOkay && + "Should not have been called if derivation isn't OK."); + if (!DerivationOkay) + return true; + + if (Paths.isAmbiguous(Context.getCanonicalType(FromClass). + getUnqualifiedType())) { + // Derivation is ambiguous. Redo the check to find the exact paths. + Paths.clear(); + Paths.setRecordingPaths(true); + bool StillOkay = IsDerivedFrom(ToClass, FromClass, Paths); + assert(StillOkay && "Derivation changed due to quantum fluctuation."); + if (!StillOkay) + return true; + + std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); + Diag(From->getExprLoc(), + diag::err_ambiguous_base_to_derived_memptr_conv) + << FromClass << ToClass << PathDisplayStr << From->getSourceRange(); + return true; + } + + if (const CXXRecordType *VBase = Paths.getDetectedVirtual()) { + Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual) + << FromClass << ToClass << QualType(VBase, 0) + << From->getSourceRange(); + return true; + } + } + } + return false; +} + /// IsQualificationConversion - Determines whether the conversion from /// an rvalue of type FromType to ToType is a qualification conversion /// (C++ 4.4). diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 21db14a2ae9b..d62e767a1c11 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -561,7 +561,8 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { DeclType.Mem.TypeQuals &= ~QualType::Restrict; } - T = Context.getMemberPointerType(T, ClsType.getTypePtr()); + T = Context.getMemberPointerType(T, ClsType.getTypePtr()). + getQualifiedType(DeclType.Mem.TypeQuals); break; } @@ -660,7 +661,13 @@ bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) return true; } - // FIXME: pointer-to-member types + const MemberPointerType *T1MPType = T1->getAsMemberPointerType(), + *T2MPType = T2->getAsMemberPointerType(); + if (T1MPType && T2MPType) { + T1 = T1MPType->getPointeeType(); + T2 = T2MPType->getPointeeType(); + return true; + } return false; } diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index 2568cb59d8b7..4aa309846101 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -3,6 +3,7 @@ struct A {}; enum B { Dummy }; namespace C {} +struct D : A {}; int A::*pdi1; int (::A::*pdi2); @@ -16,4 +17,16 @@ int& A::*pdr; // expected-error {{'pdr' declared as a pointer to a reference}} void f() { // This requires tentative parsing. int (A::*pf)(int, int); + + // Implicit conversion to bool. + bool b = pdi1; + b = pfi; + + // Conversion from null pointer constant. + pf = 0; + pf = __null; + + // Conversion to member of derived. + int D::*pdid = pdi1; + pdid = pdi2; } diff --git a/clang/test/SemaCXX/qualification-conversion.cpp b/clang/test/SemaCXX/qualification-conversion.cpp index d467d3101c44..1b818c33927c 100644 --- a/clang/test/SemaCXX/qualification-conversion.cpp +++ b/clang/test/SemaCXX/qualification-conversion.cpp @@ -9,3 +9,15 @@ void test_quals(int * p, int * * pp, int * * * ppp) { quals2(pp); quals3(ppp); // expected-error {{ incompatible type passing 'int ***', expected 'int const **const *' }} } + +struct A {}; +void mquals1(int const A::*p); +void mquals2(int const A::* const A::*pp); +void mquals3(int const A::* A::* const A::*ppp); + +void test_mquals(int A::*p, int A::* A::*pp, int A::* A::* A::*ppp) { + int const A::* const A::* pp2 = pp; + mquals1(p); + mquals2(pp); + mquals3(ppp); // expected-error {{ incompatible type passing 'int struct A::*struct A::*struct A::*', expected 'int const struct A::*struct A::*const struct A::*' }} +} -- GitLab From 97be2f5840f8e0d208b29a65adaeb51e5206e71e Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sun, 25 Jan 2009 20:21:24 +0000 Subject: [PATCH 164/682] revert this patch for now, because Codegen does still want to generate SSE code, for example in the case of va-args. XFAIL associated tests. llvm-svn: 62972 --- llvm/lib/Target/X86/X86Subtarget.cpp | 4 ++++ llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll | 2 ++ llvm/test/FrontendC/2009-01-25-NoSSE.c | 2 ++ 3 files changed, 8 insertions(+) diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 99708e04cf9c..f74008d45889 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -331,6 +331,10 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // are enabled. These are available on all x86-64 CPUs. if (Is64Bit) { HasX86_64 = true; ++#if 1 + if (X86SSELevel < SSE2) + X86SSELevel = SSE2; ++#endif } DOUT << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel diff --git a/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll b/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll index b12e4137dbd5..99826dd7159a 100644 --- a/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll +++ b/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll @@ -1,5 +1,7 @@ ; RUN: llvm-as < %s | llc -march=x86-64 -mattr=-sse,-sse2 | not grep xmm ; PR3402 +; reverted +; XFAIL: * target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/FrontendC/2009-01-25-NoSSE.c b/llvm/test/FrontendC/2009-01-25-NoSSE.c index 1585f4b007b4..92612cd4587b 100644 --- a/llvm/test/FrontendC/2009-01-25-NoSSE.c +++ b/llvm/test/FrontendC/2009-01-25-NoSSE.c @@ -2,6 +2,8 @@ // PR3402 // This is a test for x86/x86-64, add your target below if it FAILs. // XFAIL: alpha|ia64|arm|powerpc|sparc +// reverted +// XFAIL: * typedef unsigned long __kernel_size_t; typedef __kernel_size_t size_t; void *memset(void *s, int c, size_t n); -- GitLab From 692ed0f67d64786f3d3108359298a79ad706e4a1 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sun, 25 Jan 2009 20:29:34 +0000 Subject: [PATCH 165/682] should have removed the + when manually applying a patch! llvm-svn: 62973 --- llvm/lib/Target/X86/X86Subtarget.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index f74008d45889..7034c555ccc3 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -331,10 +331,10 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // are enabled. These are available on all x86-64 CPUs. if (Is64Bit) { HasX86_64 = true; -+#if 1 +#if 1 if (X86SSELevel < SSE2) X86SSELevel = SSE2; -+#endif +#endif } DOUT << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel -- GitLab From 4f765fb1983ca5fc662dc4f58d9425eca657f58b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 25 Jan 2009 22:02:19 +0000 Subject: [PATCH 166/682] use simpler method llvm-svn: 62974 --- clang/Driver/RewriteBlocks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/Driver/RewriteBlocks.cpp b/clang/Driver/RewriteBlocks.cpp index 706eef891820..75aa3c863a19 100644 --- a/clang/Driver/RewriteBlocks.cpp +++ b/clang/Driver/RewriteBlocks.cpp @@ -354,7 +354,7 @@ void RewriteBlocks::HandleTopLevelDecl(Decl *D) { RewriteProtocolDecl(PD); // If we have a decl in the main file, see if we should rewrite it. - if (SM->getDecomposedFileLoc(Loc).first == MainFileID) + if (SM->isFromMainFile(Loc)) HandleDeclInMainFile(D); return; } -- GitLab From 3138e816216f9ecc27a8fe646a26337a5f2ea609 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 25 Jan 2009 23:06:38 +0000 Subject: [PATCH 167/682] improve ASTContext::getDeclAlign comment, as suggested by Eli. llvm-svn: 62975 --- clang/include/clang/AST/ASTContext.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 927d65b99f52..684feb24025d 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -403,9 +403,9 @@ public: return getTypeInfo(T).second; } - /// getDeclAlign - Return a conservative estimate of the alignment of the - /// specified decl. Note that bitfields do not have a valid alignment, so - /// this method will assert on them. + /// getDeclAlign - Return the alignment of the specified decl that should be + /// returned by __alignof(). Note that bitfields do not have a valid + /// alignment, so this method will assert on them. unsigned getDeclAlign(const Decl *D); /// getASTRecordLayout - Get or compute information about the layout of the -- GitLab From 80b283c1cd36c23e23b539dcfb6f0428f39d44fd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sun, 25 Jan 2009 23:08:00 +0000 Subject: [PATCH 168/682] silence a warning when assertions are disabled. llvm-svn: 62976 --- llvm/lib/Target/ARM/ARMISelLowering.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index eda6ff4266db..79ae745d4db6 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -399,9 +399,9 @@ SDValue ARMTargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { CallSDNode *TheCall = cast(Op.getNode()); MVT RetVT = TheCall->getRetValType(0); SDValue Chain = TheCall->getChain(); - unsigned CallConv = TheCall->getCallingConv(); - assert((CallConv == CallingConv::C || - CallConv == CallingConv::Fast) && "unknown calling convention"); + assert((TheCall->getCallingConv() == CallingConv::C || + TheCall->getCallingConv() == CallingConv::Fast) && + "unknown calling convention"); SDValue Callee = TheCall->getCallee(); unsigned NumOps = TheCall->getNumArgs(); unsigned ArgOffset = 0; // Frame mechanisms handle retaddr slot -- GitLab From cf8e1fa58e25fbc49b2358994e5f83498aff5dd3 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 26 Jan 2009 00:11:25 +0000 Subject: [PATCH 169/682] Update C++ status table with new member pointer conversion capabilities. llvm-svn: 62977 --- clang/www/cxx_status.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index fed62884acf0..664e452987e3 100644 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -419,9 +419,9 @@ welcome!

  4.4 [conv.qual] ✓ ✓ - + ✓ + - Missing pointer-to-member conversions.   4.5 [conv.prom] @@ -474,18 +474,18 @@ welcome!

  4.11 [conv.mem] ✓ - - + ✓ + ✓ + - No support for pointer-to-members.   4.12 [conv.bool] ✓ ✓ - + ✓ + - Missing pointer-to-member conversions. 5 [expr] -- GitLab From 4fa23625abb476ac89b84d06ee2a45ef822eaf15 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 00:43:02 +0000 Subject: [PATCH 170/682] Check in the long promised SourceLocation rewrite. This lays the ground work for implementing #line, and fixes the "out of macro ID's" problem. There is nothing particularly tricky about the code, other than the very performance sensitive SourceManager::getFileID() method. llvm-svn: 62978 --- clang/include/clang/Basic/SourceLocation.h | 109 +----- clang/include/clang/Basic/SourceManager.h | 399 ++++++++++++--------- clang/include/clang/Lex/Lexer.h | 7 +- clang/lib/Basic/SourceManager.cpp | 375 +++++++++++-------- clang/lib/Lex/Lexer.cpp | 25 +- clang/lib/Lex/PPMacroExpansion.cpp | 11 +- clang/lib/Lex/PTHLexer.cpp | 5 +- clang/lib/Lex/ScratchBuffer.cpp | 2 +- clang/lib/Lex/TokenLexer.cpp | 7 +- clang/lib/Rewrite/HTMLRewrite.cpp | 3 +- clang/lib/Rewrite/Rewriter.cpp | 2 +- 11 files changed, 516 insertions(+), 429 deletions(-) diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index 8def5c5c1a5b..6da9a87ee3ac 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -45,12 +45,12 @@ public: bool operator>(const FileID &RHS) const { return RHS < *this; } bool operator>=(const FileID &RHS) const { return RHS <= *this; } - static FileID getSentinel() { return Create(~0U); } + static FileID getSentinel() { return get(~0U); } unsigned getHashValue() const { return ID; } private: friend class SourceManager; - static FileID Create(unsigned V) { + static FileID get(unsigned V) { FileID F; F.ID = V; return F; @@ -66,33 +66,14 @@ class SourceLocation { unsigned ID; friend class SourceManager; enum { - // FileID Layout: - // bit 31: 0 -> FileID, 1 -> MacroID (invalid for FileID) - // 30...17 -> ChunkID of location, index into SourceManager table. - ChunkIDBits = 14, - // 0...16 -> Index into the chunk of the specified ChunkID. - FilePosBits = 32-1-ChunkIDBits, - - // MacroID Layout: - // bit 31: 1 -> MacroID, 0 -> FileID (invalid for MacroID) - - // bit 29,30: unused. - - // bits 28...9 -> MacroID number. - MacroIDBits = 20, - // bits 8...0 -> Macro spelling offset - MacroSpellingOffsBits = 9, - - - // Useful constants. - ChunkSize = (1 << FilePosBits) + MacroIDBit = 1U << 31 }; public: SourceLocation() : ID(0) {} // 0 is an invalid FileID. - bool isFileID() const { return (ID >> 31) == 0; } - bool isMacroID() const { return (ID >> 31) != 0; } + bool isFileID() const { return (ID & MacroIDBit) == 0; } + bool isMacroID() const { return (ID & MacroIDBit) != 0; } /// isValid - Return true if this is a valid SourceLocation object. Invalid /// SourceLocations are often used when events have no corresponding location @@ -102,86 +83,34 @@ public: bool isInvalid() const { return ID == 0; } private: - /// getChunkID - Return the chunk identifier for this SourceLocation. This - /// ChunkID can be used with the SourceManager object to obtain an entire - /// include stack for a file position reference. - unsigned getChunkID() const { - assert(isFileID() && "can't get the file id of a non-file sloc!"); - return ID >> FilePosBits; + /// getOffset - Return the index for SourceManager's SLocEntryTable table, + /// note that this is not an index *into* it though. + unsigned getOffset() const { + return ID & ~MacroIDBit; } - unsigned getMacroID() const { - assert(isMacroID() && "Is not a macro id!"); - return (ID >> MacroSpellingOffsBits) & ((1 << MacroIDBits)-1); - } - - static SourceLocation getFileLoc(unsigned ChunkID, unsigned FilePos) { + static SourceLocation getFileLoc(unsigned ID) { + assert((ID & MacroIDBit) == 0 && "Ran out of source locations!"); SourceLocation L; - // If a FilePos is larger than (1<= ChunkSize) { - ChunkID += FilePos >> FilePosBits; - FilePos &= ChunkSize-1; - } - - // FIXME: Find a way to handle out of ChunkID bits! Maybe MaxFileID is an - // escape of some sort? - assert(ChunkID < (1 << ChunkIDBits) && "Out of ChunkID's"); - - L.ID = (ChunkID << FilePosBits) | FilePos; + L.ID = ID; return L; } - static bool isValidMacroSpellingOffs(int Val) { - if (Val >= 0) - return Val < (1 << (MacroSpellingOffsBits-1)); - return -Val <= (1 << (MacroSpellingOffsBits-1)); - } - - static SourceLocation getMacroLoc(unsigned MacroID, int SpellingOffs) { - assert(MacroID < (1 << MacroIDBits) && "Too many macros!"); - assert(isValidMacroSpellingOffs(SpellingOffs) &&"spelling offs too large!"); - - // Mask off sign bits. - SpellingOffs &= (1 << MacroSpellingOffsBits)-1; - + static SourceLocation getMacroLoc(unsigned ID) { + assert((ID & MacroIDBit) == 0 && "Ran out of source locations!"); SourceLocation L; - L.ID = (1 << 31) | - (MacroID << MacroSpellingOffsBits) | - SpellingOffs; + L.ID = MacroIDBit | ID; return L; } - - /// getRawFilePos - Return the byte offset from the start of the file-chunk - /// referred to by ChunkID. This method should not be used to get the offset - /// from the start of the file, instead you should use - /// SourceManager::getDecomposedFileLoc. This method will be - // incorrect for large files. - unsigned getRawFilePos() const { - assert(isFileID() && "can't get the file id of a non-file sloc!"); - return ID & (ChunkSize-1); - } - - int getMacroSpellingOffs() const { - assert(isMacroID() && "Is not a macro id!"); - int Val = ID & ((1 << MacroSpellingOffsBits)-1); - // Sign extend it properly. - unsigned ShAmt = sizeof(int)*8 - MacroSpellingOffsBits; - return (Val << ShAmt) >> ShAmt; - } public: /// getFileLocWithOffset - Return a source location with the specified offset /// from this file SourceLocation. SourceLocation getFileLocWithOffset(int Offset) const { - unsigned ChunkID = getChunkID(); - Offset += getRawFilePos(); - // Handle negative offsets correctly. - while (Offset < 0) { - --ChunkID; - Offset += ChunkSize; - } - return getFileLoc(ChunkID, Offset); + assert(((getOffset()+Offset) & MacroIDBit) == 0 && "invalid location"); + SourceLocation L; + L.ID = ID+Offset; + return L; } /// getRawEncoding - When a SourceLocation itself cannot be used, this returns diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index c8362d890e57..17c39f8016e3 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -116,99 +116,113 @@ namespace SrcMgr { ContentCache &operator=(const ContentCache& RHS); }; - /// FileIDInfo - Information about a FileID, basically just the logical file - /// that it represents and include stack information. A File SourceLocation - /// is a byte offset from the start of this. + /// FileInfo - Information about a FileID, basically just the logical file + /// that it represents and include stack information. /// - /// FileID's are used to compute the location of a character in memory as well - /// as the instantiation source location, which can be differ from the - /// spelling location. It is different when #line's are active or when macros - /// have been expanded. + /// Each FileInfo has include stack information, indicating where it came + /// from. This information encodes the #include chain that a token was + /// instantiated from. The main include file has an invalid IncludeLoc. /// - /// Each FileID has include stack information, indicating where it came from. - /// For the primary translation unit, it comes from SourceLocation() aka 0. - /// This information encodes the #include chain that a token was instantiated - /// from. + /// FileInfos contain a "ContentCache *", with the contents of the file. /// - /// FileIDInfos contain a "ContentCache *", describing the source file, - /// and a Chunk number, which allows a SourceLocation to index into very - /// large files (those which there are not enough FilePosBits to address). - /// - struct FileIDInfo { - private: + class FileInfo { /// IncludeLoc - The location of the #include that brought in this file. - /// This SourceLocation object has an invalid SLOC for the main file. - SourceLocation IncludeLoc; - - /// ChunkNo - Really large buffers are broken up into chunks that are - /// each (1 << SourceLocation::FilePosBits) in size. This specifies the - /// chunk number of this FileID. - unsigned ChunkNo : 30; - - /// FileCharacteristic - This is an instance of CharacteristicKind, - /// indicating whether this is a system header dir or not. - unsigned FileCharacteristic : 2; + /// This is an invalid SLOC for the main file (top of the #include chain). + unsigned IncludeLoc; // Really a SourceLocation /// Content - Information about the source buffer itself. const ContentCache *Content; + /// FileCharacteristic - This is an instance of CharacteristicKind, + /// indicating whether this is a system header dir or not. + unsigned FileCharacteristic : 2; public: - /// get - Return a FileIDInfo object. - static FileIDInfo get(SourceLocation IL, unsigned CN, - const ContentCache *Con, - CharacteristicKind FileCharacter) { - FileIDInfo X; - X.IncludeLoc = IL; - X.ChunkNo = CN; + /// get - Return a FileInfo object. + static FileInfo get(SourceLocation IL, const ContentCache *Con, + CharacteristicKind FileCharacter) { + FileInfo X; + X.IncludeLoc = IL.getRawEncoding(); X.Content = Con; X.FileCharacteristic = FileCharacter; return X; } - SourceLocation getIncludeLoc() const { return IncludeLoc; } - unsigned getChunkNo() const { return ChunkNo; } + SourceLocation getIncludeLoc() const { + return SourceLocation::getFromRawEncoding(IncludeLoc); + } const ContentCache* getContentCache() const { return Content; } - + /// getCharacteristic - Return whether this is a system header or not. CharacteristicKind getFileCharacteristic() const { return (CharacteristicKind)FileCharacteristic; } - - /// Emit - Emit this FileIDInfo to Bitcode. - void Emit(llvm::Serializer& S) const; - - /// ReadVal - Reconstitute a FileIDInfo from Bitcode. - static FileIDInfo ReadVal(llvm::Deserializer& S); }; - /// MacroIDInfo - Macro SourceLocations refer to these records by their ID. - /// Each MacroIDInfo encodes the Instantiation location - where the macro was - /// instantiated, and the SpellingLoc - where the actual character data for - /// the token came from. An actual macro SourceLocation stores deltas from - /// these positions. - class MacroIDInfo { - SourceLocation InstantiationLoc, SpellingLoc; + /// InstantiationInfo - Each InstantiationInfo encodes the Instantiation + /// location - where the token was ultimately instantiated, and the + /// SpellingLoc - where the actual character data for the token came from. + class InstantiationInfo { + unsigned InstantiationLoc, SpellingLoc; // Really these are SourceLocations. public: - SourceLocation getInstantiationLoc() const { return InstantiationLoc; } - SourceLocation getSpellingLoc() const { return SpellingLoc; } + SourceLocation getInstantiationLoc() const { + return SourceLocation::getFromRawEncoding(InstantiationLoc); + } + SourceLocation getSpellingLoc() const { + return SourceLocation::getFromRawEncoding(SpellingLoc); + } - /// get - Return a MacroID for a macro expansion. VL specifies + /// get - Return a InstantiationInfo for an expansion. VL specifies /// the instantiation location (where the macro is expanded), and SL /// specifies the spelling location (where the characters from the token /// come from). Both VL and PL refer to normal File SLocs. - static MacroIDInfo get(SourceLocation VL, SourceLocation SL) { - MacroIDInfo X; - X.InstantiationLoc = VL; - X.SpellingLoc = SL; + static InstantiationInfo get(SourceLocation IL, SourceLocation SL) { + InstantiationInfo X; + X.InstantiationLoc = IL.getRawEncoding(); + X.SpellingLoc = SL.getRawEncoding(); return X; } + }; + + /// SLocEntry - This is a discriminated union of FileInfo and + /// InstantiationInfo. SourceManager keeps an array of these objects, and + /// they are uniquely identified by the FileID datatype. + class SLocEntry { + unsigned Offset; // low bit is set for instantiation info. + union { + FileInfo File; + InstantiationInfo Instantiation; + }; + public: + unsigned getOffset() const { return Offset >> 1; } - /// Emit - Emit this MacroIDInfo to Bitcode. - void Emit(llvm::Serializer& S) const; + bool isInstantiation() const { return Offset & 1; } + bool isFile() const { return !isInstantiation(); } + + const FileInfo &getFile() const { + assert(isFile() && "Not a file SLocEntry!"); + return File; + } + + const InstantiationInfo &getInstantiation() const { + assert(isInstantiation() && "Not an instantiation SLocEntry!"); + return Instantiation; + } - /// ReadVal - Reconstitute a MacroIDInfo from Bitcode. - static MacroIDInfo ReadVal(llvm::Deserializer& S); + static SLocEntry get(unsigned Offset, const FileInfo &FI) { + SLocEntry E; + E.Offset = Offset << 1; + E.File = FI; + return E; + } + + static SLocEntry get(unsigned Offset, const InstantiationInfo &II) { + SLocEntry E; + E.Offset = (Offset << 1) | 1; + E.Instantiation = II; + return E; + } }; + } // end SrcMgr namespace. } // end clang namespace @@ -247,12 +261,17 @@ class SourceManager { /// stored ContentCache objects are NULL, as they do not refer to a file. std::list MemBufferInfos; - /// FileIDs - Information about each FileID. FileID #0 is not valid, so all - /// entries are off by one. - std::vector FileIDs; + /// SLocEntryTable - This is an array of SLocEntry's that we have created. + /// FileID is an index into this vector. This array is sorted by the offset. + std::vector SLocEntryTable; + /// NextOffset - This is the next available offset that a new SLocEntry can + /// start at. It is SLocEntryTable.back().getOffset()+size of back() entry. + unsigned NextOffset; - /// MacroIDs - Information about each MacroID. - std::vector MacroIDs; + /// LastFileIDLookup - This is a one-entry cache to speed up getFileID. + /// LastFileIDLookup records the last FileID looked up or created, because it + /// is very common to look up many tokens from the same file. + mutable FileID LastFileIDLookup; /// LastLineNo - These ivars serve as a cache used in the getLineNumber /// method which is used to speedup getLineNumber calls to nearby locations. @@ -264,19 +283,28 @@ class SourceManager { /// MainFileID - The file ID for the main source file of the translation unit. FileID MainFileID; + // Statistics for -print-stats. + mutable unsigned NumLinearScans, NumBinaryProbes; + // SourceManager doesn't support copy construction. explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); public: - SourceManager() {} + SourceManager() : NumLinearScans(0), NumBinaryProbes(0) { + clearIDTables(); + } ~SourceManager() {} void clearIDTables() { MainFileID = FileID(); - FileIDs.clear(); - MacroIDs.clear(); + SLocEntryTable.clear(); LastLineNoFileIDQuery = FileID(); LastLineNoContentCache = 0; + LastFileIDLookup = FileID(); + + // Use up FileID #0 as an invalid instantiation. + NextOffset = 0; + createInstantiationLoc(SourceLocation(), SourceLocation(), 1); } //===--------------------------------------------------------------------===// @@ -295,7 +323,7 @@ public: } //===--------------------------------------------------------------------===// - // Methods to create new FileID's. + // Methods to create new FileID's and instantiations. //===--------------------------------------------------------------------===// /// createFileID - Create a new FileID that represents the specified file @@ -303,7 +331,7 @@ public: /// error and translates NULL into standard input. FileID createFileID(const FileEntry *SourceFile, SourceLocation IncludePos, SrcMgr::CharacteristicKind FileCharacter) { - const SrcMgr::ContentCache *IR = getContentCache(SourceFile); + const SrcMgr::ContentCache *IR = getOrCreateContentCache(SourceFile); if (IR == 0) return FileID(); // Error opening file? return createFileID(IR, IncludePos, FileCharacter); } @@ -325,6 +353,13 @@ public: return MainFileID; } + /// createInstantiationLoc - Return a new SourceLocation that encodes the fact + /// that a token at Loc should actually be referenced from InstantiationLoc. + /// TokLength is the length of the token being instantiated. + SourceLocation createInstantiationLoc(SourceLocation Loc, + SourceLocation InstantiationLoc, + unsigned TokLength); + //===--------------------------------------------------------------------===// // FileID manipulation methods. //===--------------------------------------------------------------------===// @@ -332,12 +367,12 @@ public: /// getBuffer - Return the buffer for the specified FileID. /// const llvm::MemoryBuffer *getBuffer(FileID FID) const { - return getContentCache(FID)->getBuffer(); + return getSLocEntry(FID).getFile().getContentCache()->getBuffer(); } /// getFileEntryForID - Returns the FileEntry record for the provided FileID. const FileEntry *getFileEntryForID(FileID FID) const { - return getContentCache(FID)->Entry; + return getSLocEntry(FID).getFile().getContentCache()->Entry; } /// getBufferData - Return a pointer to the start and end of the source buffer @@ -349,26 +384,112 @@ public: // SourceLocation manipulation methods. //===--------------------------------------------------------------------===// + /// getFileIDSlow - Return the FileID for a SourceLocation. This is a very + /// hot method that is used for all SourceManager queries that start with a + /// SourceLocation object. It is responsible for finding the entry in + /// SLocEntryTable which contains the specified location. + /// + FileID getFileID(SourceLocation SpellingLoc) const { + unsigned SLocOffset = SpellingLoc.getOffset(); + + // If our one-entry cache covers this offset, just return it. + if (isOffsetInFileID(LastFileIDLookup, SLocOffset)) + return LastFileIDLookup; + + return getFileIDSlow(SLocOffset); + } + /// getLocForStartOfFile - Return the source location corresponding to the /// first byte of the specified file. SourceLocation getLocForStartOfFile(FileID FID) const { - return SourceLocation::getFileLoc(FID.ID, 0); + assert(FID.ID < SLocEntryTable.size() && SLocEntryTable[FID.ID].isFile()); + unsigned FileOffset = SLocEntryTable[FID.ID].getOffset(); + return SourceLocation::getFileLoc(FileOffset); } - /// getInstantiationLoc - Return a new SourceLocation that encodes the fact - /// that a token at Loc should actually be referenced from InstantiationLoc. - SourceLocation getInstantiationLoc(SourceLocation Loc, - SourceLocation InstantiationLoc); - - /// getIncludeLoc - Return the location of the #include for the specified + /// getIncludeLoc - Return the location of the #include for the specified /// SourceLocation. If this is a macro expansion, this transparently figures /// out which file includes the file being expanded into. SourceLocation getIncludeLoc(SourceLocation ID) const { - return getFIDInfo(getInstantiationLoc(ID).getChunkID())->getIncludeLoc(); + return getSLocEntry(getFileID(getInstantiationLoc(ID))) + .getFile().getIncludeLoc(); + } + + /// Given a SourceLocation object, return the instantiation location + /// referenced by the ID. + SourceLocation getInstantiationLoc(SourceLocation Loc) const { + // File locations work! + if (Loc.isFileID()) return Loc; + + std::pair LocInfo = getDecomposedLoc(Loc); + Loc = getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc(); + return Loc.getFileLocWithOffset(LocInfo.second); + } + + /// getSpellingLoc - Given a SourceLocation object, return the spelling + /// location referenced by the ID. This is the place where the characters + /// that make up the lexed token can be found. + SourceLocation getSpellingLoc(SourceLocation Loc) const { + // File locations work! + if (Loc.isFileID()) return Loc; + + std::pair LocInfo = getDecomposedLoc(Loc); + Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc(); + return Loc.getFileLocWithOffset(LocInfo.second); + } + + /// getDecomposedLoc - Decompose the specified location into a raw FileID + + /// Offset pair. The first element is the FileID, the second is the + /// offset from the start of the buffer of the location. + std::pair getDecomposedLoc(SourceLocation Loc) const { + FileID FID = getFileID(Loc); + return std::make_pair(FID, Loc.getOffset()-getSLocEntry(FID).getOffset()); + } + + /// getDecomposedInstantiationLoc - Decompose the specified location into a + /// raw FileID + Offset pair. If the location is an instantiation record, + /// walk through it until we find the final location instantiated. + std::pair + getDecomposedInstantiationLoc(SourceLocation Loc) const { + FileID FID = getFileID(Loc); + const SrcMgr::SLocEntry *E = &getSLocEntry(FID); + + unsigned Offset = Loc.getOffset()-E->getOffset(); + if (Loc.isFileID()) + return std::make_pair(FID, Offset); + + return getDecomposedInstantiationLocSlowCase(E, Offset); + } + + /// getDecomposedSpellingLoc - Decompose the specified location into a raw + /// FileID + Offset pair. If the location is an instantiation record, walk + /// through it until we find its spelling record. + std::pair + getDecomposedSpellingLoc(SourceLocation Loc) const { + FileID FID = getFileID(Loc); + const SrcMgr::SLocEntry *E = &getSLocEntry(FID); + + unsigned Offset = Loc.getOffset()-E->getOffset(); + if (Loc.isFileID()) + return std::make_pair(FID, Offset); + return getDecomposedSpellingLocSlowCase(E, Offset); + } + + /// getFullFilePos - This (efficient) method returns the offset from the start + /// of the file that the specified spelling SourceLocation represents. This + /// returns the location of the actual character data, not the instantiation + /// position. + unsigned getFullFilePos(SourceLocation SpellingLoc) const { + return getDecomposedLoc(SpellingLoc).second; } + + //===--------------------------------------------------------------------===// + // Queries about the code at a SourceLocation. + //===--------------------------------------------------------------------===// + /// getCharacterData - Return a pointer to the start of the specified location - /// in the appropriate MemoryBuffer. + /// in the appropriate spelling MemoryBuffer. const char *getCharacterData(SourceLocation SL) const; /// getColumnNumber - Return the column # for the specified file position. @@ -391,7 +512,7 @@ public: /// line offsets for the MemoryBuffer, so this is not cheap: use only when /// about to emit a diagnostic. unsigned getLineNumber(SourceLocation Loc) const; - + unsigned getInstantiationLineNumber(SourceLocation Loc) const { return getLineNumber(getInstantiationLoc(Loc)); } @@ -399,65 +520,18 @@ public: return getLineNumber(getSpellingLoc(Loc)); } + // FIXME: This should handle #line. + SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const { + FileID FID = getFileID(getSpellingLoc(Loc)); + return getSLocEntry(FID).getFile().getFileCharacteristic(); + } + /// getSourceName - This method returns the name of the file or buffer that /// the SourceLocation specifies. This can be modified with #line directives, /// etc. const char *getSourceName(SourceLocation Loc) const; - - /// Given a SourceLocation object, return the instantiation location - /// referenced by the ID. - SourceLocation getInstantiationLoc(SourceLocation Loc) const { - // File locations work. - if (Loc.isFileID()) return Loc; - - return MacroIDs[Loc.getMacroID()].getInstantiationLoc(); - } - /// getSpellingLoc - Given a SourceLocation object, return the spelling - /// location referenced by the ID. This is the place where the characters - /// that make up the lexed token can be found. - SourceLocation getSpellingLoc(SourceLocation Loc) const { - // File locations work! - if (Loc.isFileID()) return Loc; - - // Look up the macro token's spelling location. - SourceLocation PLoc = MacroIDs[Loc.getMacroID()].getSpellingLoc(); - return PLoc.getFileLocWithOffset(Loc.getMacroSpellingOffs()); - } - - /// getDecomposedFileLoc - Decompose the specified file location into a raw - /// FileID + Offset pair. The first element is the FileID, the second is the - /// offset from the start of the buffer of the location. - std::pair getDecomposedFileLoc(SourceLocation Loc) const { - assert(Loc.isFileID() && "Isn't a File SourceLocation"); - - // TODO: Add a flag "is first chunk" to SLOC. - const SrcMgr::FileIDInfo *FIDInfo = getFIDInfo(Loc.getChunkID()); - - // If this file has been split up into chunks, factor in the chunk number - // that the FileID references. - unsigned ChunkNo = FIDInfo->getChunkNo(); - unsigned Offset = Loc.getRawFilePos(); - Offset += (ChunkNo << SourceLocation::FilePosBits); - - assert(Loc.getChunkID() >= ChunkNo && "Unexpected offset"); - - return std::make_pair(FileID::Create(Loc.getChunkID()-ChunkNo), Offset); - } - /// getFileID - Return the FileID for a SourceLocation. - /// - FileID getFileID(SourceLocation SpellingLoc) const { - return getDecomposedFileLoc(SpellingLoc).first; - } - - /// getFullFilePos - This (efficient) method returns the offset from the start - /// of the file that the specified spelling SourceLocation represents. This - /// returns the location of the actual character data, not the instantiation - /// position. - unsigned getFullFilePos(SourceLocation SpellingLoc) const { - return getDecomposedFileLoc(SpellingLoc).second; - } /// isFromSameFile - Returns true if both SourceLocations correspond to /// the same file. @@ -470,15 +544,11 @@ public: bool isFromMainFile(SourceLocation Loc) const { return getFileID(Loc) == getMainFileID(); } - + /// isInSystemHeader - Returns if a SourceLocation is in a system header. bool isInSystemHeader(SourceLocation Loc) const { return getFileCharacteristic(Loc) != SrcMgr::C_User; } - SrcMgr::CharacteristicKind getFileCharacteristic(SourceLocation Loc) const { - return getFIDInfo(getSpellingLoc(Loc).getChunkID()) - ->getFileCharacteristic(); - } //===--------------------------------------------------------------------===// // Other miscellaneous methods. @@ -503,6 +573,19 @@ public: private: friend struct SrcMgr::ContentCache; // Used for deserialization. + /// isOffsetInFileID - Return true if the specified FileID contains the + /// specified SourceLocation offset. This is a very hot method. + inline bool isOffsetInFileID(FileID FID, unsigned SLocOffset) const { + const SrcMgr::SLocEntry &Entry = getSLocEntry(FID); + // If the entry is after the offset, it can't contain it. + if (SLocOffset < Entry.getOffset()) return false; + + // If this is the last entry than it does. Otherwise, the entry after it + // has to not include it. + if (FID.ID+1 == SLocEntryTable.size()) return true; + return SLocOffset < SLocEntryTable[FID.ID+1].getOffset(); + } + /// createFileID - Create a new fileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. @@ -510,33 +593,27 @@ private: SourceLocation IncludePos, SrcMgr::CharacteristicKind DirCharacter); - /// getContentCache - Create or return a cached ContentCache for the specified - /// file. This returns null on failure. - const SrcMgr::ContentCache* getContentCache(const FileEntry *SourceFile); + const SrcMgr::ContentCache * + getOrCreateContentCache(const FileEntry *SourceFile); /// createMemBufferContentCache - Create a new ContentCache for the specified /// memory buffer. const SrcMgr::ContentCache* createMemBufferContentCache(const llvm::MemoryBuffer *Buf); - const SrcMgr::FileIDInfo *getFIDInfo(unsigned FID) const { - assert(FID-1 < FileIDs.size() && "Invalid FileID!"); - return &FileIDs[FID-1]; - } - const SrcMgr::FileIDInfo *getFIDInfo(FileID FID) const { - return getFIDInfo(FID.ID); + const SrcMgr::SLocEntry &getSLocEntry(FileID FID) const { + assert(FID.ID < SLocEntryTable.size() && "Invalid id"); + return SLocEntryTable[FID.ID]; } - const SrcMgr::ContentCache *getContentCache(FileID FID) const { - return getContentCache(getFIDInfo(FID.ID)); - } - - /// Return the ContentCache structure for the specified FileID. - /// This is always the physical reference for the ID. - const SrcMgr::ContentCache* - getContentCache(const SrcMgr::FileIDInfo* FIDInfo) const { - return FIDInfo->getContentCache(); - } + FileID getFileIDSlow(unsigned SLocOffset) const; + + std::pair + getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, + unsigned Offset) const; + std::pair + getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, + unsigned Offset) const; }; diff --git a/clang/include/clang/Lex/Lexer.h b/clang/include/clang/Lex/Lexer.h index 42cdd9170a8b..296fca11151c 100644 --- a/clang/include/clang/Lex/Lexer.h +++ b/clang/include/clang/Lex/Lexer.h @@ -190,7 +190,7 @@ public: /// getSourceLocation - Return a source location identifier for the specified /// offset in the current file. - SourceLocation getSourceLocation(const char *Loc) const; + SourceLocation getSourceLocation(const char *Loc, unsigned TokLen = 1) const; /// getSourceLocation - Return a source location for the next character in /// the current file. @@ -228,8 +228,9 @@ private: /// TokEnd. void FormTokenWithChars(Token &Result, const char *TokEnd, tok::TokenKind Kind) { - Result.setLocation(getSourceLocation(BufferPtr)); - Result.setLength(TokEnd-BufferPtr); + unsigned TokLen = TokEnd-BufferPtr; + Result.setLength(TokLen); + Result.setLocation(getSourceLocation(BufferPtr, TokLen)); Result.setKind(Kind); BufferPtr = TokEnd; } diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 35c350ebbac0..e30e2a81315d 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -24,6 +24,10 @@ using namespace clang; using namespace SrcMgr; using llvm::MemoryBuffer; +//===--------------------------------------------------------------------===// +// SourceManager Helper Classes +//===--------------------------------------------------------------------===// + // This (temporary) directive toggles between lazy and eager creation of // MemBuffers. This directive is not permanent, and is here to test a few // potential optimizations in PTH. Once it is clear whether eager or lazy @@ -62,12 +66,16 @@ const llvm::MemoryBuffer* ContentCache::getBuffer() const { return Buffer; } +//===--------------------------------------------------------------------===// +// Private 'Create' methods. +//===--------------------------------------------------------------------===// -/// getFileInfo - Create or return a cached FileInfo for the specified file. -/// -const ContentCache* SourceManager::getContentCache(const FileEntry *FileEnt) { - +/// getOrCreateContentCache - Create or return a cached ContentCache for the +/// specified file. +const ContentCache * +SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { assert(FileEnt && "Didn't specify a file entry to use?"); + // Do we already have information about this file? std::set::iterator I = FileInfos.lower_bound(ContentCache(FileEnt)); @@ -107,47 +115,34 @@ SourceManager::createMemBufferContentCache(const MemoryBuffer *Buffer) { return &Entry; } +//===----------------------------------------------------------------------===// +// Methods to create new FileID's and instantiations. +//===----------------------------------------------------------------------===// /// createFileID - Create a new fileID for the specified ContentCache and /// include position. This works regardless of whether the ContentCache /// corresponds to a file or some other input source. FileID SourceManager::createFileID(const ContentCache *File, - SourceLocation IncludePos, - SrcMgr::CharacteristicKind FileCharacter) { - // If FileEnt is really large (e.g. it's a large .i file), we may not be able - // to fit an arbitrary position in the file in the FilePos field. To handle - // this, we create one FileID for each chunk of the file that fits in a - // FilePos field. + SourceLocation IncludePos, + SrcMgr::CharacteristicKind FileCharacter) { + SLocEntryTable.push_back(SLocEntry::get(NextOffset, + FileInfo::get(IncludePos, File, + FileCharacter))); unsigned FileSize = File->getSize(); - if (FileSize+1 < (1 << SourceLocation::FilePosBits)) { - FileIDs.push_back(FileIDInfo::get(IncludePos, 0, File, FileCharacter)); - assert(FileIDs.size() < (1 << SourceLocation::ChunkIDBits) && - "Ran out of file ID's!"); - return FileID::Create(FileIDs.size()); - } + assert(NextOffset+FileSize+1 > NextOffset && "Ran out of source locations!"); + NextOffset += FileSize+1; - // Create one FileID for each chunk of the file. - unsigned Result = FileIDs.size()+1; - - unsigned ChunkNo = 0; - while (1) { - FileIDs.push_back(FileIDInfo::get(IncludePos, ChunkNo++, File, - FileCharacter)); - - if (FileSize+1 < (1 << SourceLocation::FilePosBits)) break; - FileSize -= (1 << SourceLocation::FilePosBits); - } - - assert(FileIDs.size() < (1 << SourceLocation::ChunkIDBits) && - "Ran out of file ID's!"); - return FileID::Create(Result); + // Set LastFileIDLookup to the newly created file. The next getFileID call is + // almost guaranteed to be from that file. + return LastFileIDLookup = FileID::get(SLocEntryTable.size()-1); } -/// getInstantiationLoc - Return a new SourceLocation that encodes the fact +/// createInstantiationLoc - Return a new SourceLocation that encodes the fact /// that a token from SpellingLoc should actually be referenced from /// InstantiationLoc. -SourceLocation SourceManager::getInstantiationLoc(SourceLocation SpellingLoc, - SourceLocation InstantLoc) { +SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc, + SourceLocation InstantLoc, + unsigned TokLength) { // The specified source location may be a mapped location, due to a macro // instantiation or #line directive. Strip off this information to find out // where the characters are actually located. @@ -155,29 +150,13 @@ SourceLocation SourceManager::getInstantiationLoc(SourceLocation SpellingLoc, // Resolve InstantLoc down to a real instantiation location. InstantLoc = getInstantiationLoc(InstantLoc); - - - // If the last macro id is close to the currently requested location, try to - // reuse it. This implements a small cache. - for (int i = MacroIDs.size()-1, e = MacroIDs.size()-6; i >= 0 && i != e; --i){ - MacroIDInfo &LastOne = MacroIDs[i]; - - // The instanitation point and source SpellingLoc have to exactly match to - // reuse (for now). We could allow "nearby" instantiations in the future. - if (LastOne.getInstantiationLoc() != InstantLoc || - LastOne.getSpellingLoc().getChunkID() != SpellingLoc.getChunkID()) - continue; - - // Check to see if the spellloc of the token came from near enough to reuse. - int SpellDelta = SpellingLoc.getRawFilePos() - - LastOne.getSpellingLoc().getRawFilePos(); - if (SourceLocation::isValidMacroSpellingOffs(SpellDelta)) - return SourceLocation::getMacroLoc(i, SpellDelta); - } - - - MacroIDs.push_back(MacroIDInfo::get(InstantLoc, SpellingLoc)); - return SourceLocation::getMacroLoc(MacroIDs.size()-1, 0); + + SLocEntryTable.push_back(SLocEntry::get(NextOffset, + InstantiationInfo::get(InstantLoc, + SpellingLoc))); + assert(NextOffset+TokLength+1 > NextOffset && "Ran out of source locations!"); + NextOffset += TokLength+1; + return SourceLocation::getMacroLoc(NextOffset-(TokLength+1)); } /// getBufferData - Return a pointer to the start and end of the source buffer @@ -189,19 +168,153 @@ SourceManager::getBufferData(FileID FID) const { } +//===--------------------------------------------------------------------===// +// SourceLocation manipulation methods. +//===--------------------------------------------------------------------===// + +/// getFileIDSlow - Return the FileID for a SourceLocation. This is a very hot +/// method that is used for all SourceManager queries that start with a +/// SourceLocation object. It is responsible for finding the entry in +/// SLocEntryTable which contains the specified location. +/// +FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { + assert(SLocOffset && "Invalid FileID"); + + // After the first and second level caches, I see two common sorts of + // behavior: 1) a lot of searched FileID's are "near" the cached file location + // or are "near" the cached instantiation location. 2) others are just + // completely random and may be a very long way away. + // + // To handle this, we do a linear search for up to 8 steps to catch #1 quickly + // then we fall back to a less cache efficient, but more scalable, binary + // search to find the location. + + // See if this is near the file point - worst case we start scanning from the + // most newly created FileID. + std::vector::const_iterator I; + + if (SLocEntryTable[LastFileIDLookup.ID].getOffset() < SLocOffset) { + // Neither loc prunes our search. + I = SLocEntryTable.end(); + } else { + // Perhaps it is near the file point. + I = SLocEntryTable.begin()+LastFileIDLookup.ID; + } + + // Find the FileID that contains this. "I" is an iterator that points to a + // FileID whose offset is known to be larger than SLocOffset. + unsigned NumProbes = 0; + while (1) { + --I; + if (I->getOffset() <= SLocOffset) { +#if 0 + printf("lin %d -> %d [%s] %d %d\n", SLocOffset, + I-SLocEntryTable.begin(), + I->isInstantiation() ? "inst" : "file", + LastFileIDLookup.ID, int(SLocEntryTable.end()-I)); +#endif + FileID Res = FileID::get(I-SLocEntryTable.begin()); + + // If this isn't an instantiation, remember it. We have good locality + // across FileID lookups. + if (!I->isInstantiation()) + LastFileIDLookup = Res; + NumLinearScans += NumProbes+1; + return Res; + } + if (++NumProbes == 8) + break; + } + + // Convert "I" back into an index. We know that it is an entry whose index is + // larger than the offset we are looking for. + unsigned GreaterIndex = I-SLocEntryTable.begin(); + // LessIndex - This is the lower bound of the range that we're searching. + // We know that the offset corresponding to the FileID is is less than + // SLocOffset. + unsigned LessIndex = 0; + NumProbes = 0; + while (1) { + unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; + unsigned MidOffset = SLocEntryTable[MiddleIndex].getOffset(); + + ++NumProbes; + + // If the offset of the midpoint is too large, chop the high side of the + // range to the midpoint. + if (MidOffset > SLocOffset) { + GreaterIndex = MiddleIndex; + continue; + } + + // If the middle index contains the value, succeed and return. + if (isOffsetInFileID(FileID::get(MiddleIndex), SLocOffset)) { +#if 0 + printf("bin %d -> %d [%s] %d %d\n", SLocOffset, + I-SLocEntryTable.begin(), + I->isInstantiation() ? "inst" : "file", + LastFileIDLookup.ID, int(SLocEntryTable.end()-I)); +#endif + FileID Res = FileID::get(MiddleIndex); + + // If this isn't an instantiation, remember it. We have good locality + // across FileID lookups. + if (!I->isInstantiation()) + LastFileIDLookup = Res; + NumBinaryProbes += NumProbes; + return Res; + } + + // Otherwise, move the low-side up to the middle index. + LessIndex = MiddleIndex; + } +} + +std::pair +SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, + unsigned Offset) const { + // If this is an instantiation record, walk through all the instantiation + // points. + FileID FID; + SourceLocation Loc; + do { + Loc = E->getInstantiation().getInstantiationLoc(); + + FID = getFileID(Loc); + E = &getSLocEntry(FID); + Offset += Loc.getOffset()-E->getOffset(); + } while (Loc.isFileID()); + + return std::make_pair(FID, Offset); +} + +std::pair +SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, + unsigned Offset) const { + // If this is an instantiation record, get and return the spelling. + SourceLocation Loc = E->getInstantiation().getSpellingLoc(); + FileID FID = getFileID(Loc); + E = &getSLocEntry(FID); + Offset += Loc.getOffset()-E->getOffset(); + assert(Loc.isFileID() && "Should only have one spelling link"); + return std::make_pair(FID, Offset); +} + + +//===----------------------------------------------------------------------===// +// Queries about the code at a SourceLocation. +//===----------------------------------------------------------------------===// /// getCharacterData - Return a pointer to the start of the specified location /// in the appropriate MemoryBuffer. const char *SourceManager::getCharacterData(SourceLocation SL) const { // Note that this is a hot function in the getSpelling() path, which is // heavily used by -E mode. - SL = getSpellingLoc(SL); - - std::pair LocInfo = getDecomposedFileLoc(SL); + std::pair LocInfo = getDecomposedSpellingLoc(SL); // Note that calling 'getBuffer()' may lazily page in a source file. - return getContentCache(LocInfo.first)->getBuffer()->getBufferStart() + - LocInfo.second; + return getSLocEntry(LocInfo.first).getFile().getContentCache() + ->getBuffer()->getBufferStart() + LocInfo.second; } @@ -209,9 +322,10 @@ const char *SourceManager::getCharacterData(SourceLocation SL) const { /// this is significantly cheaper to compute than the line number. This returns /// zero if the column number isn't known. unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { - if (Loc.getChunkID() == 0) return 0; + if (Loc.isInvalid()) return 0; + assert(Loc.isFileID() && "Don't know what part of instantiation loc to get"); - std::pair LocInfo = getDecomposedFileLoc(Loc); + std::pair LocInfo = getDecomposedLoc(Loc); unsigned FilePos = LocInfo.second; const char *Buf = getBuffer(LocInfo.first)->getBufferStart(); @@ -222,21 +336,6 @@ unsigned SourceManager::getColumnNumber(SourceLocation Loc) const { return FilePos-LineStart+1; } -/// getSourceName - This method returns the name of the file or buffer that -/// the SourceLocation specifies. This can be modified with #line directives, -/// etc. -const char *SourceManager::getSourceName(SourceLocation Loc) const { - if (Loc.getChunkID() == 0) return ""; - - Loc = getSpellingLoc(Loc); - unsigned ChunkID = Loc.getChunkID(); - const SrcMgr::ContentCache *C = getFIDInfo(ChunkID)->getContentCache(); - - // To get the source name, first consult the FileEntry (if one exists) before - // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. - return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); -} - static void ComputeLineNumbers(ContentCache* FI) DISABLE_INLINE; static void ComputeLineNumbers(ContentCache* FI) { // Note that calling 'getBuffer()' may lazily page in the file. @@ -287,16 +386,17 @@ static void ComputeLineNumbers(ContentCache* FI) { /// line offsets for the MemoryBuffer, so this is not cheap: use only when /// about to emit a diagnostic. unsigned SourceManager::getLineNumber(SourceLocation Loc) const { - if (Loc.getChunkID() == 0) return 0; + if (Loc.isInvalid()) return 0; + assert(Loc.isFileID() && "Don't know what part of instantiation loc to get"); - ContentCache *Content; - - std::pair LocInfo = getDecomposedFileLoc(Loc); + std::pair LocInfo = getDecomposedLoc(Loc); + ContentCache *Content; if (LastLineNoFileIDQuery == LocInfo.first) Content = LastLineNoContentCache; else - Content = const_cast(getContentCache(LocInfo.first)); + Content = const_cast(getSLocEntry(LocInfo.first) + .getFile().getContentCache()); // If this is the first use of line information for this buffer, compute the /// SourceLineCache for it on demand. @@ -375,15 +475,32 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const { return LineNo; } +/// getSourceName - This method returns the name of the file or buffer that +/// the SourceLocation specifies. This can be modified with #line directives, +/// etc. +const char *SourceManager::getSourceName(SourceLocation Loc) const { + if (Loc.isInvalid()) return ""; + + const SrcMgr::ContentCache *C = + getSLocEntry(getFileID(getSpellingLoc(Loc))).getFile().getContentCache(); + + // To get the source name, first consult the FileEntry (if one exists) before + // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. + return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); +} + +//===----------------------------------------------------------------------===// +// Other miscellaneous methods. +//===----------------------------------------------------------------------===// + + /// PrintStats - Print statistics to stderr. /// void SourceManager::PrintStats() const { llvm::cerr << "\n*** Source Manager Stats:\n"; llvm::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size() - << " mem buffers mapped, " << FileIDs.size() - << " file ID's allocated.\n"; - llvm::cerr << " " << FileIDs.size() << " normal buffer FileID's, " - << MacroIDs.size() << " macro expansion FileID's.\n"; + << " mem buffers mapped, " << SLocEntryTable.size() + << " SLocEntry's allocated.\n"; unsigned NumLineNumsComputed = 0; unsigned NumFileBytesMapped = 0; @@ -395,6 +512,8 @@ void SourceManager::PrintStats() const { llvm::cerr << NumFileBytesMapped << " bytes of files mapped, " << NumLineNumsComputed << " files with line #'s computed.\n"; + llvm::cerr << "FileID scans: " << NumLinearScans << " linear, " + << NumBinaryProbes << " binary.\n"; } //===----------------------------------------------------------------------===// @@ -450,49 +569,23 @@ void ContentCache::ReadToSourceManager(llvm::Deserializer& D, D.RegisterPtr(PtrID,NULL); else // Get the ContextCache object and register it with the deserializer. - D.RegisterPtr(PtrID,SMgr.getContentCache(E)); + D.RegisterPtr(PtrID, SMgr.getOrCreateContentCache(E)); + return; } - else { - // Register the ContextCache object with the deserializer. - SMgr.MemBufferInfos.push_back(ContentCache()); - ContentCache& Entry = const_cast(SMgr.MemBufferInfos.back()); - D.RegisterPtr(&Entry); - - // Create the buffer. - unsigned Size = D.ReadInt(); - Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size); - - // Read the contents of the buffer. - char* p = const_cast(Entry.Buffer->getBufferStart()); - for (unsigned i = 0; i < Size ; ++i) - p[i] = D.ReadInt(); - } -} - -void FileIDInfo::Emit(llvm::Serializer& S) const { - S.Emit(IncludeLoc); - S.EmitInt(ChunkNo); - S.EmitPtr(Content); -} - -FileIDInfo FileIDInfo::ReadVal(llvm::Deserializer& D) { - FileIDInfo I; - I.IncludeLoc = SourceLocation::ReadVal(D); - I.ChunkNo = D.ReadInt(); - D.ReadPtr(I.Content,false); - return I; -} - -void MacroIDInfo::Emit(llvm::Serializer& S) const { - S.Emit(InstantiationLoc); - S.Emit(SpellingLoc); -} - -MacroIDInfo MacroIDInfo::ReadVal(llvm::Deserializer& D) { - MacroIDInfo I; - I.InstantiationLoc = SourceLocation::ReadVal(D); - I.SpellingLoc = SourceLocation::ReadVal(D); - return I; + + // Register the ContextCache object with the deserializer. + SMgr.MemBufferInfos.push_back(ContentCache()); + ContentCache& Entry = const_cast(SMgr.MemBufferInfos.back()); + D.RegisterPtr(&Entry); + + // Create the buffer. + unsigned Size = D.ReadInt(); + Entry.Buffer = MemoryBuffer::getNewUninitMemBuffer(Size); + + // Read the contents of the buffer. + char* p = const_cast(Entry.Buffer->getBufferStart()); + for (unsigned i = 0; i < Size ; ++i) + p[i] = D.ReadInt(); } void SourceManager::Emit(llvm::Serializer& S) const { @@ -516,13 +609,7 @@ void SourceManager::Emit(llvm::Serializer& S) const { S.ExitBlock(); - // Emit: FileIDs - S.EmitInt(FileIDs.size()); - std::for_each(FileIDs.begin(), FileIDs.end(), S.MakeEmitter()); - - // Emit: MacroIDs - S.EmitInt(MacroIDs.size()); - std::for_each(MacroIDs.begin(), MacroIDs.end(), S.MakeEmitter()); + // FIXME: Emit SLocEntryTable. S.ExitBlock(); } @@ -533,7 +620,7 @@ SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){ D.RegisterPtr(M); // Read: the FileID of the main source file of the translation unit. - M->MainFileID = FileID::Create(D.ReadInt()); + M->MainFileID = FileID::get(D.ReadInt()); std::vector Buf; @@ -549,17 +636,7 @@ SourceManager::CreateAndRegister(llvm::Deserializer& D, FileManager& FMgr){ ContentCache::ReadToSourceManager(D,*M,NULL,Buf); } - // Read: FileIDs. - unsigned Size = D.ReadInt(); - M->FileIDs.reserve(Size); - for (; Size > 0 ; --Size) - M->FileIDs.push_back(FileIDInfo::ReadVal(D)); - - // Read: MacroIDs. - Size = D.ReadInt(); - M->MacroIDs.reserve(Size); - for (; Size > 0 ; --Size) - M->MacroIDs.push_back(MacroIDInfo::ReadVal(D)); + // FIXME: Read SLocEntryTable. return M; } diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 3174a0591745..9e8d1aa74076 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -169,8 +169,8 @@ Lexer *Lexer::Create_PragmaLexer(SourceLocation SpellingLoc, // Set the SourceLocation with the remapping information. This ensures that // GetMappedTokenLoc will remap the tokens as they are lexed. - L->FileLoc = SM.getInstantiationLoc(SM.getLocForStartOfFile(SpellingFID), - InstantiationLoc); + L->FileLoc = SM.createInstantiationLoc(SM.getLocForStartOfFile(SpellingFID), + InstantiationLoc, TokLen); // Ensure that the lexer thinks it is inside a directive, so that end \n will // return an EOM token. @@ -214,16 +214,15 @@ void Lexer::Stringify(llvm::SmallVectorImpl &Str) { /// that are part of that. unsigned Lexer::MeasureTokenLength(SourceLocation Loc, const SourceManager &SM) { - // If this comes from a macro expansion, we really do want the macro name, not - // the token this macro expanded to. - Loc = SM.getInstantiationLoc(Loc); - // TODO: this could be special cased for common tokens like identifiers, ')', // etc to make this faster, if it mattered. Just look at StrData[0] to handle // all obviously single-char tokens. This could use // Lexer::isObviouslySimpleCharacter for example to handle identifiers or // something. - std::pair LocInfo = SM.getDecomposedFileLoc(Loc); + + // If this comes from a macro expansion, we really do want the macro name, not + // the token this macro expanded to. + std::pair LocInfo = SM.getDecomposedInstantiationLoc(Loc); std::pair Buffer = SM.getBufferData(LocInfo.first); const char *StrData = Buffer.first+LocInfo.second; @@ -310,10 +309,11 @@ static inline bool isNumberBody(unsigned char c) { /// path of the hot getSourceLocation method. Do not allow it to be inlined. static SourceLocation GetMappedTokenLoc(Preprocessor &PP, SourceLocation FileLoc, - unsigned CharNo) DISABLE_INLINE; + unsigned CharNo, + unsigned TokLen) DISABLE_INLINE; static SourceLocation GetMappedTokenLoc(Preprocessor &PP, SourceLocation FileLoc, - unsigned CharNo) { + unsigned CharNo, unsigned TokLen) { // Otherwise, we're lexing "mapped tokens". This is used for things like // _Pragma handling. Combine the instantiation location of FileLoc with the // spelling location. @@ -324,12 +324,13 @@ static SourceLocation GetMappedTokenLoc(Preprocessor &PP, SourceLocation InstLoc = SourceMgr.getInstantiationLoc(FileLoc); SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(FileLoc); SpellingLoc = SpellingLoc.getFileLocWithOffset(CharNo); - return SourceMgr.getInstantiationLoc(SpellingLoc, InstLoc); + return SourceMgr.createInstantiationLoc(SpellingLoc, InstLoc, TokLen); } /// getSourceLocation - Return a source location identifier for the specified /// offset in the current file. -SourceLocation Lexer::getSourceLocation(const char *Loc) const { +SourceLocation Lexer::getSourceLocation(const char *Loc, + unsigned TokLen) const { assert(Loc >= BufferStart && Loc <= BufferEnd && "Location out of range for this buffer!"); @@ -342,7 +343,7 @@ SourceLocation Lexer::getSourceLocation(const char *Loc) const { // Otherwise, this is the _Pragma lexer case, which pretends that all of the // tokens are lexed from where the _Pragma was defined. assert(PP && "This doesn't work on raw lexers"); - return GetMappedTokenLoc(*PP, FileLoc, CharNo); + return GetMappedTokenLoc(*PP, FileLoc, CharNo, TokLen); } /// Diag - Forwarding function for diagnostics. This translate a source diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 6c4096de6cc7..63caafaf5048 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -221,7 +221,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, } else if (MI->getNumTokens() == 1 && isTrivialSingleTokenExpansion(MI, Identifier.getIdentifierInfo(), - *this)){ + *this)) { // Otherwise, if this macro expands into a single trivially-expanded // token: expand it now. This handles common cases like // "#define VAL 42". @@ -247,7 +247,8 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier, // Update the tokens location to include both its instantiation and physical // locations. SourceLocation Loc = - SourceMgr.getInstantiationLoc(Identifier.getLocation(), InstantiateLoc); + SourceMgr.createInstantiationLoc(Identifier.getLocation(), InstantiateLoc, + Identifier.getLength()); Identifier.setLocation(Loc); // If this is #define X X, we must mark the result as unexpandible. @@ -480,13 +481,15 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { ComputeDATE_TIME(DATELoc, TIMELoc, *this); Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"Mmm dd yyyy\"")); - Tok.setLocation(SourceMgr.getInstantiationLoc(DATELoc, Tok.getLocation())); + Tok.setLocation(SourceMgr.createInstantiationLoc(DATELoc, Tok.getLocation(), + Tok.getLength())); } else if (II == Ident__TIME__) { if (!TIMELoc.isValid()) ComputeDATE_TIME(DATELoc, TIMELoc, *this); Tok.setKind(tok::string_literal); Tok.setLength(strlen("\"hh:mm:ss\"")); - Tok.setLocation(SourceMgr.getInstantiationLoc(TIMELoc, Tok.getLocation())); + Tok.setLocation(SourceMgr.createInstantiationLoc(TIMELoc, Tok.getLocation(), + Tok.getLength())); } else if (II == Ident__INCLUDE_LEVEL__) { Diag(Tok, diag::ext_pp_include_level); diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index ec76a299845b..f6994e0976d2 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -321,7 +321,7 @@ unsigned PTHManager::getSpelling(FileID FID, unsigned FPos, unsigned PTHManager::getSpelling(SourceLocation Loc, const char *&Buffer) { SourceManager &SM = PP->getSourceManager(); Loc = SM.getSpellingLoc(Loc); - std::pair LocInfo = SM.getDecomposedFileLoc(Loc); + std::pair LocInfo = SM.getDecomposedLoc(Loc); return getSpelling(LocInfo.first, LocInfo.second, Buffer); } @@ -407,8 +407,7 @@ unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned FPos, unsigned PTHLexer::getSpelling(SourceLocation Loc, const char *&Buffer) { SourceManager &SM = PP->getSourceManager(); - Loc = SM.getSpellingLoc(Loc); - std::pair LocInfo = SM.getDecomposedFileLoc(Loc); + std::pair LocInfo = SM.getDecomposedSpellingLoc(Loc); FileID FID = LocInfo.first; unsigned FPos = LocInfo.second; diff --git a/clang/lib/Lex/ScratchBuffer.cpp b/clang/lib/Lex/ScratchBuffer.cpp index bef81caac719..695a5365faf7 100644 --- a/clang/lib/Lex/ScratchBuffer.cpp +++ b/clang/lib/Lex/ScratchBuffer.cpp @@ -50,7 +50,7 @@ SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len) { SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, SourceLocation SourceLoc) { // Map the physloc to the specified sourceloc. - return SourceMgr.getInstantiationLoc(getToken(Buf, Len), SourceLoc); + return SourceMgr.createInstantiationLoc(getToken(Buf, Len), SourceLoc, Len); } void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index dd5352c1b616..ea4ce669d1d9 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -314,8 +314,9 @@ void TokenLexer::Lex(Token &Tok) { // that captures all of this. if (InstantiateLoc.isValid()) { // Don't do this for token streams. SourceManager &SrcMgr = PP.getSourceManager(); - Tok.setLocation(SrcMgr.getInstantiationLoc(Tok.getLocation(), - InstantiateLoc)); + Tok.setLocation(SrcMgr.createInstantiationLoc(Tok.getLocation(), + InstantiateLoc, + Tok.getLength())); } // If this is the first token, set the lexical properties of the token to @@ -398,7 +399,7 @@ bool TokenLexer::PasteTokens(Token &Tok) { "Should be a raw location into scratch buffer"); SourceManager &SourceMgr = PP.getSourceManager(); std::pair LocInfo = - SourceMgr.getDecomposedFileLoc(ResultTokLoc); + SourceMgr.getDecomposedLoc(ResultTokLoc); const char *ScratchBufStart =SourceMgr.getBufferData(LocInfo.first).first; diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp index 040146620d21..b5f0fc395118 100644 --- a/clang/lib/Rewrite/HTMLRewrite.cpp +++ b/clang/lib/Rewrite/HTMLRewrite.cpp @@ -441,8 +441,7 @@ void html::HighlightMacros(Rewriter &R, FileID FID, Preprocessor& PP) { // Ignore tokens whose instantiation location was not the main file. SourceLocation LLoc = SourceMgr.getInstantiationLoc(Tok.getLocation()); - std::pair LLocInfo = - SourceMgr.getDecomposedFileLoc(LLoc); + std::pair LLocInfo = SourceMgr.getDecomposedLoc(LLoc); if (LLocInfo.first != FID) { PP.Lex(Tok); diff --git a/clang/lib/Rewrite/Rewriter.cpp b/clang/lib/Rewrite/Rewriter.cpp index e92bd7d329d2..551fa1d4910c 100644 --- a/clang/lib/Rewrite/Rewriter.cpp +++ b/clang/lib/Rewrite/Rewriter.cpp @@ -151,7 +151,7 @@ std::string Rewriter::getRewritenText(SourceRange Range) const { unsigned Rewriter::getLocationOffsetAndFileID(SourceLocation Loc, FileID &FID) const { assert(Loc.isValid() && "Invalid location"); - std::pair V = SourceMgr->getDecomposedFileLoc(Loc); + std::pair V = SourceMgr->getDecomposedLoc(Loc); FID = V.first; return V.second; } -- GitLab From 8a51d8c8f77d39a283cd090191dc9827e5546851 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Mon, 26 Jan 2009 00:52:55 +0000 Subject: [PATCH 171/682] Support pattern matching various x86 sse shifts. llvm-svn: 62979 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 93 +++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index a2ae6095f504..8edd5a4df6c6 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -806,6 +806,9 @@ X86TargetLowering::X86TargetLowering(X86TargetMachine &TM) setTargetDAGCombine(ISD::VECTOR_SHUFFLE); setTargetDAGCombine(ISD::BUILD_VECTOR); setTargetDAGCombine(ISD::SELECT); + setTargetDAGCombine(ISD::SHL); + setTargetDAGCombine(ISD::SRA); + setTargetDAGCombine(ISD::SRL); setTargetDAGCombine(ISD::STORE); computeRegisterProperties(); @@ -7654,6 +7657,93 @@ static SDValue PerformSELECTCombine(SDNode *N, SelectionDAG &DAG, return SDValue(); } +/// PerformShiftCombine - Transforms vector shift nodes to use vector shifts +/// when possible. +static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG, + const X86Subtarget *Subtarget) { + // On X86 with SSE2 support, we can transform this to a vector shift if + // all elements are shifted by the same amount. We can't do this in legalize + // because the a constant vector is typically transformed to a constant pool + // so we have no knowledge of the shift amount. + MVT VT = N->getValueType(0); + if (Subtarget->hasSSE2() && + (VT == MVT::v2i64 || VT == MVT::v4i32 || VT == MVT::v8i16)) { + SDValue ValOp = N->getOperand(0); + SDValue ShAmtOp = N->getOperand(1); + unsigned NumElts = VT.getVectorNumElements(); + + if (ShAmtOp.getOpcode() == ISD::BUILD_VECTOR) { + unsigned i = 0; + SDValue BaseShAmt; + for (; i != NumElts; ++i) { + SDValue Arg = ShAmtOp.getOperand(i); + if (Arg.getOpcode() == ISD::UNDEF) continue; + BaseShAmt = Arg; + break; + } + for (; i != NumElts; ++i) { + SDValue Arg = ShAmtOp.getOperand(i); + if (Arg.getOpcode() == ISD::UNDEF) continue; + if (Arg != BaseShAmt) { + return SDValue(); + } + } + + MVT EltVT = VT.getVectorElementType(); + if (EltVT.bitsGT(MVT::i32)) + BaseShAmt = DAG.getNode(ISD::TRUNCATE, MVT::i32, BaseShAmt); + else if (EltVT.bitsLT(MVT::i32)) + BaseShAmt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BaseShAmt); + + // The shift amount is identical so we can do a vector shift. + switch (N->getOpcode()) { + default: + assert(0 && "Unknown shift opcode!"); + break; + case ISD::SHL: + if (VT == MVT::v2i64) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_pslli_q, MVT::i32), + ValOp, BaseShAmt); + else if (VT == MVT::v4i32) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_pslli_d, MVT::i32), + ValOp, BaseShAmt); + else if (VT == MVT::v8i16) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32), + ValOp, BaseShAmt); + break; + case ISD::SRA: + if (VT == MVT::v4i32) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_psrai_d, MVT::i32), + ValOp, BaseShAmt); + else if (VT == MVT::v8i16) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_psrai_w, MVT::i32), + ValOp, BaseShAmt); + break; + case ISD::SRL: + if (VT == MVT::v2i64) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_psrli_q, MVT::i32), + ValOp, BaseShAmt); + else if (VT == MVT::v4i32) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_psrli_d, MVT::i32), + ValOp, BaseShAmt); + else if (VT == MVT::v8i16) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + DAG.getConstant(Intrinsic::x86_sse2_psrli_w, MVT::i32), + ValOp, BaseShAmt); + break; + } + } + } + return SDValue(); +} + /// PerformSTORECombine - Do target-specific dag combines on STORE nodes. static SDValue PerformSTORECombine(SDNode *N, SelectionDAG &DAG, const X86Subtarget *Subtarget) { @@ -7782,6 +7872,9 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N, case ISD::BUILD_VECTOR: return PerformBuildVectorCombine(N, DAG, Subtarget, *this); case ISD::SELECT: return PerformSELECTCombine(N, DAG, Subtarget); + case ISD::SHL: + case ISD::SRA: + case ISD::SRL: return PerformShiftCombine(N, DAG, Subtarget); case ISD::STORE: return PerformSTORECombine(N, DAG, Subtarget); case X86ISD::FXOR: case X86ISD::FOR: return PerformFORCombine(N, DAG); -- GitLab From 5eca265519e2c1545d9542b16bd484988dbc19d3 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Mon, 26 Jan 2009 01:24:32 +0000 Subject: [PATCH 172/682] Map address space 256 to gs; similar mappings could be supported for the other x86 segments. address space 0 is stack/default, 1-255 are reserved for client use. llvm-svn: 62980 --- llvm/lib/Target/X86/X86Instr64bit.td | 5 +++++ llvm/lib/Target/X86/X86InstrInfo.td | 15 +++++++++++++++ llvm/test/CodeGen/X86/movgs.ll | 8 ++++++++ 3 files changed, 28 insertions(+) create mode 100644 llvm/test/CodeGen/X86/movgs.ll diff --git a/llvm/lib/Target/X86/X86Instr64bit.td b/llvm/lib/Target/X86/X86Instr64bit.td index 123062c6d059..774da61ba941 100644 --- a/llvm/lib/Target/X86/X86Instr64bit.td +++ b/llvm/lib/Target/X86/X86Instr64bit.td @@ -1242,6 +1242,11 @@ def TLS_addr64 : I<0, Pseudo, (outs GR64:$dst), (ins i64imm:$sym), ".byte\t0x66; leaq\t${sym:mem}(%rip), $dst; .word\t0x6666; rex64", [(set GR64:$dst, (X86tlsaddr tglobaltlsaddr:$sym))]>; +let AddedComplexity = 5 in +def MOV64GSrm : RI<0x8B, MRMSrcMem, (outs GR64:$dst), (ins i64mem:$src), + "movq\t%gs:$src, $dst", + [(set GR64:$dst, (gsload addr:$src))]>, SegGS; + //===----------------------------------------------------------------------===// // Atomic Instructions //===----------------------------------------------------------------------===// diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index fbe03299e07a..9649c234de45 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -308,6 +308,16 @@ def nvloadi32 : PatFrag<(ops node:$ptr), (i32 (unindexedload node:$ptr)), [{ return false; }]>; +def gsload : PatFrag<(ops node:$ptr), (load node:$ptr), [{ + LoadSDNode *LD = cast(N); + const Value *Src = LD->getSrcValue(); + if (!Src) + return false; + if (const PointerType *PT = dyn_cast(Src->getType())) + return PT->getAddressSpace() == 256; + return false; +}]>; + def loadi8 : PatFrag<(ops node:$ptr), (i8 (load node:$ptr))>; def loadi64 : PatFrag<(ops node:$ptr), (i64 (load node:$ptr))>; @@ -2852,6 +2862,11 @@ def TLS_tp : I<0x8B, Pseudo, (outs GR32:$dst), (ins), "movl\t%gs:0, $dst", [(set GR32:$dst, X86TLStp)]>, SegGS; +let AddedComplexity = 5 in +def GS_MOV32rm : I<0x8B, MRMSrcMem, (outs GR32:$dst), (ins i32mem:$src), + "movl\t%gs:$src, $dst", + [(set GR32:$dst, (gsload addr:$src))]>, SegGS; + //===----------------------------------------------------------------------===// // DWARF Pseudo Instructions // diff --git a/llvm/test/CodeGen/X86/movgs.ll b/llvm/test/CodeGen/X86/movgs.ll new file mode 100644 index 000000000000..f621849e5b06 --- /dev/null +++ b/llvm/test/CodeGen/X86/movgs.ll @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep gs + +define i32 @foo() nounwind readonly { +entry: + %tmp = load i32* addrspace(256)* getelementptr (i32* addrspace(256)* inttoptr (i32 72 to i32* addrspace(256)*), i32 31) ; [#uses=1] + %tmp1 = load i32* %tmp ; [#uses=1] + ret i32 %tmp1 +} -- GitLab From 16c88df1a0dc5cc4a42bbd82c9ed63cd6fb090eb Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Mon, 26 Jan 2009 01:33:06 +0000 Subject: [PATCH 173/682] PR3269: create an empty InitListExpr as a child for the CompoundLiteralExpr so that there aren't any null pointers in the AST. llvm-svn: 62981 --- clang/lib/Sema/SemaExpr.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 1d55ed7c3aa4..9b91ec6ee5f4 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -3987,9 +3987,13 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S, // Otherwise, create a compound literal expression as the base, and // iteratively process the offsetof designators. - Expr *Res = new (Context) CompoundLiteralExpr(SourceLocation(), ArgTy, 0, - false); - + InitListExpr *IList = + new (Context) InitListExpr(SourceLocation(), 0, 0, + SourceLocation(), false); + IList->setType(ArgTy); + Expr *Res = + new (Context) CompoundLiteralExpr(SourceLocation(), ArgTy, IList, false); + // offsetof with non-identifier designators (e.g. "offsetof(x, a.b[c])") are a // GCC extension, diagnose them. if (NumComponents != 1) -- GitLab From d67aaa6560314742833d9f08fd7229e13d351676 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 01:38:24 +0000 Subject: [PATCH 174/682] tidy asserts llvm-svn: 62982 --- llvm/lib/Transforms/Scalar/LoopRotation.cpp | 35 ++++++++++----------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp index e8df49b6e4e5..857d32658ee3 100644 --- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp +++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp @@ -139,8 +139,8 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { if (L->getBlocks().size() == 1) return false; - assert (OrigHeader && OrigLatch && OrigPreHeader && - "Loop is not in canonical form"); + assert(OrigHeader && OrigLatch && OrigPreHeader && + "Loop is not in canonical form"); // If loop header is not one of the loop exit block then // either this loop is already rotated or it is not @@ -151,7 +151,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { BranchInst *BI = dyn_cast(OrigHeader->getTerminator()); if (!BI) return false; - assert (BI->isConditional() && "Branch Instruction is not conditional"); + assert(BI->isConditional() && "Branch Instruction is not conditional"); // Updating PHInodes in loops with multiple exits adds complexity. // Keep it simple, and restrict loop rotation to loops with one exit only. @@ -176,7 +176,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { NewHeader = BI->getSuccessor(1); if (L->contains(Exit)) std::swap(Exit, NewHeader); - assert (NewHeader && "Unable to determine new loop header"); + assert(NewHeader && "Unable to determine new loop header"); assert(L->contains(NewHeader) && !L->contains(Exit) && "Unable to determine loop header and exit blocks"); @@ -221,7 +221,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { for (; I != E; ++I) { Instruction *In = I; - assert (!isa(In) && "PHINode is not expected here"); + assert(!isa(In) && "PHINode is not expected here"); // This is not a PHI instruction. Insert its clone into original pre-header. // If this instruction is using a value from same basic block then // update it to use value from cloned instruction. @@ -325,7 +325,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // Used inside Exit Block. Since we are in LCSSA form, U must be PHINode. if (U->getParent() == Exit) { - assert (isa(U) && "Use in Exit Block that is not PHINode"); + assert(isa(U) && "Use in Exit Block that is not PHINode"); PHINode *UPhi = cast(U); // UPhi already has one incoming argument from original header. @@ -457,8 +457,8 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { if (OrigPH_BI->getSuccessor(0) == NewHeader) OrigPH_BI->setSuccessor(0, NewPreHeader); else { - assert (OrigPH_BI->getSuccessor(1) == NewHeader && - "Unexpected original pre-header terminator"); + assert(OrigPH_BI->getSuccessor(1) == NewHeader && + "Unexpected original pre-header terminator"); OrigPH_BI->setSuccessor(1, NewPreHeader); } @@ -470,10 +470,10 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { break; int index = PN->getBasicBlockIndex(OrigPreHeader); - assert (index != -1 && "Expected incoming value from Original PreHeader"); + assert(index != -1 && "Expected incoming value from Original PreHeader"); PN->setIncomingBlock(index, NewPreHeader); - assert (PN->getBasicBlockIndex(OrigPreHeader) == -1 && - "Expected only one incoming value from Original PreHeader"); + assert(PN->getBasicBlockIndex(OrigPreHeader) == -1 && + "Expected only one incoming value from Original PreHeader"); } if (DominatorTree *DT = getAnalysisToUpdate()) { @@ -571,11 +571,10 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { } } - assert (NewHeader && L->getHeader() == NewHeader - && "Invalid loop header after loop rotation"); - assert (NewPreHeader && L->getLoopPreheader() == NewPreHeader - && "Invalid loop preheader after loop rotation"); - assert (L->getLoopLatch() - && "Invalid loop latch after loop rotation"); - + assert(NewHeader && L->getHeader() == NewHeader && + "Invalid loop header after loop rotation"); + assert(NewPreHeader && L->getLoopPreheader() == NewPreHeader && + "Invalid loop preheader after loop rotation"); + assert(L->getLoopLatch() && + "Invalid loop latch after loop rotation"); } -- GitLab From 57cb472b56d75dce518bf6f1730e0dc855c79d25 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 01:57:01 +0000 Subject: [PATCH 175/682] More cleanups and simplifications, no functionality change. llvm-svn: 62983 --- llvm/lib/Transforms/Scalar/LoopRotation.cpp | 70 +++++++-------------- 1 file changed, 23 insertions(+), 47 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp index 857d32658ee3..1118ed559187 100644 --- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp +++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp @@ -128,7 +128,6 @@ bool LoopRotate::runOnLoop(Loop *Lp, LPPassManager &LPM) { /// Rotate loop LP. Return true if the loop is rotated. bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { - L = Lp; OrigHeader = L->getHeader(); @@ -170,8 +169,8 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // Now, this loop is suitable for rotation. // Find new Loop header. NewHeader is a Header's one and only successor - // that is inside loop. Header's other successor is out side the - // loop. Otherwise loop is not suitable for rotation. + // that is inside loop. Header's other successor is outside the + // loop. Otherwise loop is not suitable for rotation. Exit = BI->getSuccessor(0); NewHeader = BI->getSuccessor(1); if (L->contains(Exit)) @@ -197,31 +196,29 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // receive a clone of original header terminator as a new terminator. OrigPreHeader->getInstList().pop_back(); BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end(); - PHINode *PN = NULL; + PHINode *PN = 0; for (; (PN = dyn_cast(I)); ++I) { - Instruction *In = I; - // PHI nodes are not copied into original pre-header. Instead their values // are directly propagated. - Value * NPV = PN->getIncomingValueForBlock(OrigPreHeader); + Value *NPV = PN->getIncomingValueForBlock(OrigPreHeader); // Create new PHI node with two incoming values for NewHeader. // One incoming value is from OrigLatch (through OrigHeader) and // second incoming value is from original pre-header. - PHINode *NH = PHINode::Create(In->getType(), In->getName(), + PHINode *NH = PHINode::Create(PN->getType(), PN->getName(), NewHeader->begin()); NH->addIncoming(PN->getIncomingValueForBlock(OrigLatch), OrigHeader); NH->addIncoming(NPV, OrigPreHeader); // "In" can be replaced by NH at various places. - LoopHeaderInfo.push_back(RenameData(In, NPV, NH)); + LoopHeaderInfo.push_back(RenameData(PN, NPV, NH)); } // Now, handle non-phi instructions. for (; I != E; ++I) { Instruction *In = I; - assert(!isa(In) && "PHINode is not expected here"); + // This is not a PHI instruction. Insert its clone into original pre-header. // If this instruction is using a value from same basic block then // update it to use value from cloned instruction. @@ -230,21 +227,12 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { OrigPreHeader->getInstList().push_back(C); for (unsigned opi = 0, e = In->getNumOperands(); opi != e; ++opi) { - if (Instruction *OpPhi = dyn_cast(In->getOperand(opi))) { - if (const RenameData *D = findReplacementData(OpPhi)) { - // This is using values from original header PHI node. - // Here, directly used incoming value from original pre-header. - C->setOperand(opi, D->PreHeader); - } - } - else if (Instruction *OpInsn = - dyn_cast(In->getOperand(opi))) { - if (const RenameData *D = findReplacementData(OpInsn)) - C->setOperand(opi, D->PreHeader); - } + Instruction *OpInsn = dyn_cast(In->getOperand(opi)); + if (!OpInsn) continue; // Ignore non-instruction values. + if (const RenameData *D = findReplacementData(OpInsn)) + C->setOperand(opi, D->PreHeader); } - // If this instruction is used outside this basic block then // create new PHINode for this instruction. Instruction *NewHeaderReplacement = NULL; @@ -276,7 +264,7 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // 2) Inside loop but not in original header // // Replace this use to reflect definition from new header. - for(unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) { + for (unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) { const RenameData &ILoopHeaderInfo = LoopHeaderInfo[LHI]; if (!ILoopHeaderInfo.Header) @@ -289,10 +277,8 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // not invalidated. SmallVector AllUses; for (Value::use_iterator UI = OldPhi->use_begin(), UE = OldPhi->use_end(); - UI != UE; ++UI) { - Instruction *U = cast(UI); - AllUses.push_back(U); - } + UI != UE; ++UI) + AllUses.push_back(cast(UI)); for (SmallVector::iterator UI = AllUses.begin(), UE = AllUses.end(); UI != UE; ++UI) { @@ -351,14 +337,9 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { // Removing incoming branch from loop preheader to original header. // Now original header is inside the loop. for (BasicBlock::iterator I = OrigHeader->begin(), E = OrigHeader->end(); - I != E; ++I) { - Instruction *In = I; - PHINode *PN = dyn_cast(In); - if (!PN) - break; - - PN->removeIncomingValue(OrigPreHeader); - } + I != E; ++I) + if (PHINode *PN = dyn_cast(I)) + PN->removeIncomingValue(OrigPreHeader); // Make NewHeader as the new header for the loop. L->moveToHeader(NewHeader); @@ -411,14 +392,11 @@ void LoopRotate::initialize() { /// Return true if this instruction is used by any instructions in the loop that /// aren't in original header. bool LoopRotate::usedOutsideOriginalHeader(Instruction *In) { - for (Value::use_iterator UI = In->use_begin(), UE = In->use_end(); UI != UE; ++UI) { - Instruction *U = cast(UI); - if (U->getParent() != OrigHeader) { - if (L->contains(U->getParent())) - return true; - } + BasicBlock *UserBB = cast(UI)->getParent(); + if (UserBB != OrigHeader && L->contains(UserBB)) + return true; } return false; @@ -429,7 +407,7 @@ bool LoopRotate::usedOutsideOriginalHeader(Instruction *In) { const RenameData *LoopRotate::findReplacementData(Instruction *In) { // Since LoopHeaderInfo is small, linear walk is OK. - for(unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) { + for (unsigned LHI = 0, LHI_E = LoopHeaderInfo.size(); LHI != LHI_E; ++LHI) { const RenameData &ILoopHeaderInfo = LoopHeaderInfo[LHI]; if (ILoopHeaderInfo.Original == In) return &ILoopHeaderInfo; @@ -464,8 +442,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { for (BasicBlock::iterator I = NewHeader->begin(), E = NewHeader->end(); I != E; ++I) { - Instruction *In = I; - PHINode *PN = dyn_cast(In); + PHINode *PN = dyn_cast(I); if (!PN) break; @@ -492,8 +469,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) { DT->changeImmediateDominator(OrigHeader, OrigLatch); } - if(DominanceFrontier *DF = getAnalysisToUpdate()) { - + if (DominanceFrontier *DF = getAnalysisToUpdate()) { // New Preheader's dominance frontier is Exit block. DominanceFrontier::DomSetType NewPHSet; NewPHSet.insert(Exit); -- GitLab From 7b6647c17893a74dcc9e54cf28ea764292c751b0 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 02:11:30 +0000 Subject: [PATCH 176/682] Fix PR3408 by making a non-obvious assumption very obvious, and handling the flaw inherent in that assumption. :) llvm-svn: 62984 --- llvm/lib/Transforms/Scalar/LoopRotation.cpp | 8 +++++-- .../LoopRotate/2009-01-25-SingleEntryPhi.ll | 21 +++++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp index 1118ed559187..aed84e2df87f 100644 --- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp +++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #define DEBUG_TYPE "loop-rotate" - #include "llvm/Transforms/Scalar.h" #include "llvm/Function.h" #include "llvm/Instructions.h" @@ -26,7 +25,6 @@ #include "llvm/Support/Debug.h" #include "llvm/ADT/Statistic.h" #include "llvm/ADT/SmallVector.h" - using namespace llvm; #define MAX_HEADER_SIZE 16 @@ -178,6 +176,12 @@ bool LoopRotate::rotateLoop(Loop *Lp, LPPassManager &LPM) { assert(NewHeader && "Unable to determine new loop header"); assert(L->contains(NewHeader) && !L->contains(Exit) && "Unable to determine loop header and exit blocks"); + + // This code assumes that new header has exactly one predecessor. Remove any + // single entry PHI nodes in it. + assert(NewHeader->getSinglePredecessor() && + "New header doesn't have one pred!"); + FoldSingleEntryPHINodes(NewHeader); // Copy PHI nodes and other instructions from original header // into original pre-header. Unlike original header, original pre-header is diff --git a/llvm/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll b/llvm/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll new file mode 100644 index 000000000000..7cc3951b3cd1 --- /dev/null +++ b/llvm/test/Transforms/LoopRotate/2009-01-25-SingleEntryPhi.ll @@ -0,0 +1,21 @@ +; RUN: llvm-as < %s | opt -loop-rotate | llvm-dis +; PR3408 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.Cls = type { i32, i8, [2 x %struct.Cls*], [2 x %struct.Lit*] } + %struct.Lit = type { i8 } + +define void @picosat_main_bb13.i.i71.outer_bb132.i.i.i.outer(%struct.Cls**, %struct.Cls**, i32 %collect.i.i.i.1.lcssa, i32 %lcollect.i.i.i.2.lcssa, %struct.Cls*** %rhead.tmp.0236.out, i32* %collect.i.i.i.2.out, i32* %lcollect.i.i.i.3.ph.ph.ph.out) nounwind { +newFuncRoot: + br label %codeRepl + +bb133.i.i.i.exitStub: ; preds = %codeRepl + ret void + +bb130.i.i.i: ; preds = %codeRepl + %rhead.tmp.0236.lcssa82 = phi %struct.Cls** [ null, %codeRepl ] ; <%struct.Cls**> [#uses=0] + br label %codeRepl + +codeRepl: ; preds = %bb130.i.i.i, %newFuncRoot + br i1 false, label %bb130.i.i.i, label %bb133.i.i.i.exitStub +} -- GitLab From 9449991c4f53cfb3efc2207af2ba585439078191 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 02:18:20 +0000 Subject: [PATCH 177/682] Handle single-entry phi nodes gracefully in condprop. llvm-svn: 62985 --- llvm/lib/Transforms/Scalar/CondPropagate.cpp | 8 ++++ .../CondProp/2009-01-25-SingleEntryPHI.ll | 37 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 llvm/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll diff --git a/llvm/lib/Transforms/Scalar/CondPropagate.cpp b/llvm/lib/Transforms/Scalar/CondPropagate.cpp index 2e899432909e..f68fb292e4a9 100644 --- a/llvm/lib/Transforms/Scalar/CondPropagate.cpp +++ b/llvm/lib/Transforms/Scalar/CondPropagate.cpp @@ -126,6 +126,14 @@ void CondProp::SimplifyPredecessors(BranchInst *BI) { // one use (the branch), and is the only instruction besides the branch in the // block. PHINode *PN = cast(BI->getCondition()); + + if (PN->getNumIncomingValues() == 1) { + // Eliminate single-entry PHI nodes. + FoldSingleEntryPHINodes(PN->getParent()); + return; + } + + if (!PN->hasOneUse()) return; BasicBlock *BB = BI->getParent(); diff --git a/llvm/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll b/llvm/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll new file mode 100644 index 000000000000..d14ce38f3df2 --- /dev/null +++ b/llvm/test/Transforms/CondProp/2009-01-25-SingleEntryPHI.ll @@ -0,0 +1,37 @@ +; RUN: llvm-as < %s | opt -condprop | llvm-dis +; PR3405 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + br label %bb2 + +bb2: ; preds = %bb.bb2_crit_edge, %entry + br i1 false, label %bb5.thread2, label %bb + +bb: ; preds = %bb2 + br i1 false, label %bb3, label %bb.bb2_crit_edge + +bb.bb2_crit_edge: ; preds = %bb + br label %bb2 + +bb3: ; preds = %bb + %.lcssa4 = phi i1 [ false, %bb ] ; [#uses=1] + br i1 %.lcssa4, label %bb5.thread, label %bb6 + +bb5.thread: ; preds = %bb3 + br label %bb7 + +bb7: ; preds = %bb5.thread2, %bb5.thread + br label %UnifiedReturnBlock + +bb6: ; preds = %bb3 + br label %UnifiedReturnBlock + +bb5.thread2: ; preds = %bb2 + br label %bb7 + +UnifiedReturnBlock: ; preds = %bb6, %bb7 + ret i32 0 +} -- GitLab From 7ea4e861ca34905995b9ed9a31c9a0b1ebb1bfe8 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Mon, 26 Jan 2009 02:54:45 +0000 Subject: [PATCH 178/682] Add some documentation for address-space-based access to the segment registers. llvm-svn: 62986 --- llvm/docs/CodeGenerator.html | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/llvm/docs/CodeGenerator.html b/llvm/docs/CodeGenerator.html index 009ecd676788..66d793dfa03c 100644 --- a/llvm/docs/CodeGenerator.html +++ b/llvm/docs/CodeGenerator.html @@ -1718,7 +1718,7 @@ processors, and includes support for ISA extensions such as MMX and SSE.
@@ -1789,6 +1789,27 @@ same way and in the same order.

+ + + +
+ +

x86 has the ability to perform loads and stores to different address spaces +via the x86 segment registers. A segment override prefix byte on an instruction +causes the instruction's memory access to go to the specified segment. LLVM +address space 0 is the default address space, which includes the stack, and +any unqualified memory accesses in a program. Address spaces 1-255 are +currently reserved for user-defined code. The GS-segment is represented by +address space 256. Other x86 segments have yet to be allocated address space +numbers. + +

Some operating systems use the GS-segment to implement TLS, so care should be +taken when reading and writing to address space 256 on these platforms. + +

+
Instruction naming -- GitLab From 5c8fc9d549746e190838428da22c533398e381d2 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Mon, 26 Jan 2009 03:04:57 +0000 Subject: [PATCH 179/682] Build libLTO on any platform so long as PIC is enabled. llvm-svn: 62987 --- llvm/tools/Makefile | 3 +-- llvm/tools/lto/Makefile | 8 ++------ 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/llvm/tools/Makefile b/llvm/tools/Makefile index 519717ad98de..909a54843b5d 100644 --- a/llvm/tools/Makefile +++ b/llvm/tools/Makefile @@ -25,8 +25,7 @@ PARALLEL_DIRS := llvm-config \ include $(LEVEL)/Makefile.config -# only build new lto project on Darwin for now -ifeq ($(OS),Darwin) +ifeq ($(ENABLE_PIC),1) PARALLEL_DIRS += lto endif diff --git a/llvm/tools/lto/Makefile b/llvm/tools/lto/Makefile index 69014d781ff1..f0f6da7191a2 100644 --- a/llvm/tools/lto/Makefile +++ b/llvm/tools/lto/Makefile @@ -16,12 +16,8 @@ LIBRARYNAME = LTO include $(LEVEL)/Makefile.config LINK_LIBS_IN_SHARED = 1 -ifeq ($(OS),Darwin) - SHARED_LIBRARY = 1 - DONT_BUILD_RELINKED = 1 -else - BUILD_ARCHIVE = 1 -endif +SHARED_LIBRARY = 1 +DONT_BUILD_RELINKED = 1 LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter -- GitLab From a2550a8e96bdebaa491de9716aaaae07b6897b68 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Mon, 26 Jan 2009 03:15:31 +0000 Subject: [PATCH 180/682] De-identifying per sabre review llvm-svn: 62988 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 115 ++++++++++++------------ 1 file changed, 59 insertions(+), 56 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 8edd5a4df6c6..205a141623ab 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -7665,81 +7665,84 @@ static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG, // all elements are shifted by the same amount. We can't do this in legalize // because the a constant vector is typically transformed to a constant pool // so we have no knowledge of the shift amount. + if (!Subtarget->hasSSE2()) + return SDValue(); + MVT VT = N->getValueType(0); - if (Subtarget->hasSSE2() && - (VT == MVT::v2i64 || VT == MVT::v4i32 || VT == MVT::v8i16)) { - SDValue ValOp = N->getOperand(0); - SDValue ShAmtOp = N->getOperand(1); - unsigned NumElts = VT.getVectorNumElements(); - - if (ShAmtOp.getOpcode() == ISD::BUILD_VECTOR) { - unsigned i = 0; - SDValue BaseShAmt; - for (; i != NumElts; ++i) { - SDValue Arg = ShAmtOp.getOperand(i); - if (Arg.getOpcode() == ISD::UNDEF) continue; - BaseShAmt = Arg; - break; - } - for (; i != NumElts; ++i) { - SDValue Arg = ShAmtOp.getOperand(i); - if (Arg.getOpcode() == ISD::UNDEF) continue; - if (Arg != BaseShAmt) { - return SDValue(); - } - } + if (VT != MVT::v2i64 && VT != MVT::v4i32 && VT != MVT::v8i16) + return SDValue(); + + SDValue ShAmtOp = N->getOperand(1); + if (ShAmtOp.getOpcode() != ISD::BUILD_VECTOR) + return SDValue(); - MVT EltVT = VT.getVectorElementType(); - if (EltVT.bitsGT(MVT::i32)) - BaseShAmt = DAG.getNode(ISD::TRUNCATE, MVT::i32, BaseShAmt); - else if (EltVT.bitsLT(MVT::i32)) - BaseShAmt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BaseShAmt); + unsigned NumElts = VT.getVectorNumElements(); + unsigned i = 0; + SDValue BaseShAmt; + for (; i != NumElts; ++i) { + SDValue Arg = ShAmtOp.getOperand(i); + if (Arg.getOpcode() == ISD::UNDEF) continue; + BaseShAmt = Arg; + break; + } + for (; i != NumElts; ++i) { + SDValue Arg = ShAmtOp.getOperand(i); + if (Arg.getOpcode() == ISD::UNDEF) continue; + if (Arg != BaseShAmt) { + return SDValue(); + } + } - // The shift amount is identical so we can do a vector shift. - switch (N->getOpcode()) { - default: - assert(0 && "Unknown shift opcode!"); - break; - case ISD::SHL: - if (VT == MVT::v2i64) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + MVT EltVT = VT.getVectorElementType(); + if (EltVT.bitsGT(MVT::i32)) + BaseShAmt = DAG.getNode(ISD::TRUNCATE, MVT::i32, BaseShAmt); + else if (EltVT.bitsLT(MVT::i32)) + BaseShAmt = DAG.getNode(ISD::ANY_EXTEND, MVT::i32, BaseShAmt); + + // The shift amount is identical so we can do a vector shift. + SDValue ValOp = N->getOperand(0); + switch (N->getOpcode()) { + default: + assert(0 && "Unknown shift opcode!"); + break; + case ISD::SHL: + if (VT == MVT::v2i64) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_pslli_q, MVT::i32), ValOp, BaseShAmt); - else if (VT == MVT::v4i32) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + if (VT == MVT::v4i32) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_pslli_d, MVT::i32), ValOp, BaseShAmt); - else if (VT == MVT::v8i16) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + if (VT == MVT::v8i16) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_pslli_w, MVT::i32), ValOp, BaseShAmt); - break; - case ISD::SRA: - if (VT == MVT::v4i32) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + break; + case ISD::SRA: + if (VT == MVT::v4i32) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_psrai_d, MVT::i32), ValOp, BaseShAmt); - else if (VT == MVT::v8i16) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + if (VT == MVT::v8i16) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_psrai_w, MVT::i32), ValOp, BaseShAmt); - break; - case ISD::SRL: - if (VT == MVT::v2i64) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + break; + case ISD::SRL: + if (VT == MVT::v2i64) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_psrli_q, MVT::i32), ValOp, BaseShAmt); - else if (VT == MVT::v4i32) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + if (VT == MVT::v4i32) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_psrli_d, MVT::i32), ValOp, BaseShAmt); - else if (VT == MVT::v8i16) - return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, + if (VT == MVT::v8i16) + return DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VT, DAG.getConstant(Intrinsic::x86_sse2_psrli_w, MVT::i32), ValOp, BaseShAmt); - break; - } - } + break; } return SDValue(); } -- GitLab From 624801e87e06c9f4436a2c3ad41289d5d3a82505 Mon Sep 17 00:00:00 2001 From: Nate Begeman Date: Mon, 26 Jan 2009 03:15:54 +0000 Subject: [PATCH 181/682] Fix a typo llvm-svn: 62989 --- llvm/lib/Target/Mips/MipsISelLowering.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/Mips/MipsISelLowering.cpp b/llvm/lib/Target/Mips/MipsISelLowering.cpp index f2786dc12027..5af38bf4ab47 100644 --- a/llvm/lib/Target/Mips/MipsISelLowering.cpp +++ b/llvm/lib/Target/Mips/MipsISelLowering.cpp @@ -573,9 +573,8 @@ LowerConstantPool(SDValue Op, SelectionDAG &DAG) // CALL Calling Convention Implementation //===----------------------------------------------------------------------===// -/// LowerCCCCallTo - functions arguments are copied from virtual -/// regs to (physical regs)/(stack frame), CALLSEQ_START and -/// CALLSEQ_END are emitted. +/// LowerCALL - functions arguments are copied from virtual regs to +/// (physical regs)/(stack frame), CALLSEQ_START and CALLSEQ_END are emitted. /// TODO: isVarArg, isTailCall. SDValue MipsTargetLowering:: LowerCALL(SDValue Op, SelectionDAG &DAG) -- GitLab From 9e3e4a9219dcb07ecbf0897cbd9d9b39d1cd9630 Mon Sep 17 00:00:00 2001 From: Scott Michel Date: Mon, 26 Jan 2009 03:31:40 +0000 Subject: [PATCH 182/682] CellSPU: - Rename fcmp.ll test to fcmp32.ll, start adding new double tests to fcmp64.ll - Fix select_bits.ll test - Capitulate to the DAGCombiner and move i64 constant loads to instruction selection (SPUISelDAGtoDAG.cpp). DAGCombiner will insert all kinds of 64-bit optimizations after operation legalization occurs and now we have to do most of the work that instruction selection should be doing twice (once to determine if v2i64 build_vector can be handled by SelectCode(), which then runs all of the predicates a second time to select the necessary instructions.) But, CellSPU is a good citizen. llvm-svn: 62990 --- llvm/lib/Target/CellSPU/SPU64InstrInfo.td | 4 +- llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 173 +++++-- llvm/lib/Target/CellSPU/SPUISelLowering.cpp | 484 +++++++++++------- llvm/lib/Target/CellSPU/SPUISelLowering.h | 4 +- llvm/lib/Target/CellSPU/SPUInstrInfo.cpp | 4 +- llvm/lib/Target/CellSPU/SPUInstrInfo.td | 30 +- .../CodeGen/CellSPU/{fcmp.ll => fcmp32.ll} | 15 +- llvm/test/CodeGen/CellSPU/fcmp64.ll | 7 + llvm/test/CodeGen/CellSPU/fneg-fabs.ll | 11 +- llvm/test/CodeGen/CellSPU/select_bits.ll | 114 ++--- llvm/test/CodeGen/CellSPU/shift_ops.ll | 6 + 11 files changed, 552 insertions(+), 300 deletions(-) rename llvm/test/CodeGen/CellSPU/{fcmp.ll => fcmp32.ll} (56%) create mode 100644 llvm/test/CodeGen/CellSPU/fcmp64.ll diff --git a/llvm/lib/Target/CellSPU/SPU64InstrInfo.td b/llvm/lib/Target/CellSPU/SPU64InstrInfo.td index 33298946c521..06eb1496def7 100644 --- a/llvm/lib/Target/CellSPU/SPU64InstrInfo.td +++ b/llvm/lib/Target/CellSPU/SPU64InstrInfo.td @@ -30,8 +30,8 @@ // selb instruction definition for i64. Note that the selection mask is // a vector, produced by various forms of FSM: def SELBr64_cond: - SELBInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB, VECREG:$rC), - [/* no pattern */]>; + SELBInst<(outs R64C:$rT), (ins R64C:$rA, R64C:$rB, VECREG:$rC), + [/* no pattern */]>; // The generic i64 select pattern, which assumes that the comparison result // is in a 32-bit register that contains a select mask pattern (i.e., gather diff --git a/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index 0fc7aec9906e..6d7f40d5d751 100644 --- a/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -254,26 +254,56 @@ public: /// getSmallIPtrImm - Return a target constant of pointer type. inline SDValue getSmallIPtrImm(unsigned Imm) { return CurDAG->getTargetConstant(Imm, SPUtli.getPointerTy()); - } + } SDNode *emitBuildVector(SDValue build_vec) { + MVT vecVT = build_vec.getValueType(); + SDNode *bvNode = build_vec.getNode(); + bool canBeSelected = false; + + // Check to see if this vector can be represented as a CellSPU immediate + // constant. + if (vecVT == MVT::v8i16) { + if (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0) { + canBeSelected = true; + } + } else if (vecVT == MVT::v4i32) { + if ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) + || (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) + || (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) + || (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0)) { + canBeSelected = true; + } + } else if (vecVT == MVT::v2i64) { + if ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) + || (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) + || (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)) { + canBeSelected = true; + } + } + + if (canBeSelected) { + return Select(build_vec); + } + + // No, need to emit a constant pool spill: std::vector CV; for (size_t i = 0; i < build_vec.getNumOperands(); ++i) { - ConstantSDNode *V = dyn_cast(build_vec.getOperand(i)); - CV.push_back(const_cast(V->getConstantIntValue())); + ConstantSDNode *V = dyn_cast (build_vec.getOperand(i)); + CV.push_back(const_cast (V->getConstantIntValue())); } Constant *CP = ConstantVector::get(CV); SDValue CPIdx = CurDAG->getConstantPool(CP, SPUtli.getPointerTy()); - unsigned Alignment = 1 << cast(CPIdx)->getAlignment(); + unsigned Alignment = 1 << cast (CPIdx)->getAlignment(); SDValue CGPoolOffset = SPU::LowerConstantPool(CPIdx, *CurDAG, SPUtli.getSPUTargetMachine()); return SelectCode(CurDAG->getLoad(build_vec.getValueType(), - CurDAG->getEntryNode(), CGPoolOffset, - PseudoSourceValue::getConstantPool(), 0, - false, Alignment)); + CurDAG->getEntryNode(), CGPoolOffset, + PseudoSourceValue::getConstantPool(), 0, + false, Alignment)); } /// Select - Convert the specified operand from a target-independent to a @@ -289,6 +319,9 @@ public: //! Emit the instruction sequence for i64 sra SDNode *SelectSRAi64(SDValue &Op, MVT OpVT); + //! Emit the necessary sequence for loading i64 constants: + SDNode *SelectI64Constant(SDValue &Op, MVT OpVT); + //! Returns true if the address N is an A-form (local store) address bool SelectAFormAddr(SDValue Op, SDValue N, SDValue &Base, SDValue &Index); @@ -652,7 +685,9 @@ SPUDAGToDAGISel::Select(SDValue Op) { if (N->isMachineOpcode()) { return NULL; // Already selected. - } else if (Opc == ISD::FrameIndex) { + } + + if (Opc == ISD::FrameIndex) { int FI = cast(N)->getIndex(); SDValue TFI = CurDAG->getTargetFrameIndex(FI, Op.getValueType()); SDValue Imm0 = CurDAG->getTargetConstant(0, Op.getValueType()); @@ -669,6 +704,11 @@ SPUDAGToDAGISel::Select(SDValue Op) { TFI, Imm0), 0); n_ops = 2; } + } else if (Opc == ISD::Constant && OpVT == MVT::i64) { + // Catch the i64 constants that end up here. Note: The backend doesn't + // attempt to legalize the constant (it's useless because DAGCombiner + // will insert 64-bit constants and we can't stop it). + return SelectI64Constant(Op, OpVT); } else if ((Opc == ISD::ZERO_EXTEND || Opc == ISD::ANY_EXTEND) && OpVT == MVT::i64) { SDValue Op0 = Op.getOperand(0); @@ -745,27 +785,38 @@ SPUDAGToDAGISel::Select(SDValue Op) { return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, OpVT, Op.getOperand(0), Op.getOperand(1), SDValue(CGLoad, 0))); - } else if (Opc == ISD::ADD && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { - SDNode *CGLoad = - emitBuildVector(SPU::getCarryGenerateShufMask(*CurDAG)); - - return SelectCode(CurDAG->getNode(SPUISD::ADD64_MARKER, OpVT, - Op.getOperand(0), Op.getOperand(1), - SDValue(CGLoad, 0))); - } else if (Opc == ISD::SUB && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { - SDNode *CGLoad = - emitBuildVector(SPU::getBorrowGenerateShufMask(*CurDAG)); - - return SelectCode(CurDAG->getNode(SPUISD::SUB64_MARKER, OpVT, - Op.getOperand(0), Op.getOperand(1), - SDValue(CGLoad, 0))); - } else if (Opc == ISD::MUL && (OpVT == MVT::i64 || OpVT == MVT::v2i64)) { - SDNode *CGLoad = - emitBuildVector(SPU::getCarryGenerateShufMask(*CurDAG)); - - return SelectCode(CurDAG->getNode(SPUISD::MUL64_MARKER, OpVT, - Op.getOperand(0), Op.getOperand(1), - SDValue(CGLoad, 0))); + } else if (Opc == ISD::TRUNCATE) { + SDValue Op0 = Op.getOperand(0); + if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) + && OpVT == MVT::i32 + && Op0.getValueType() == MVT::i64) { + // Catch the (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 to + // take advantage of the fact that the upper 32 bits are in the + // i32 preferred slot and avoid all kinds of other shuffle gymnastics: + ConstantSDNode *CN = dyn_cast(Op0.getOperand(1)); + if (CN != 0) { + unsigned shift_amt = unsigned(CN->getZExtValue()); + + if (shift_amt >= 32) { + SDNode *hi32 = + CurDAG->getTargetNode(SPU::ORr32_r64, OpVT, Op0.getOperand(0)); + + shift_amt -= 32; + if (shift_amt > 0) { + // Take care of the additional shift, if present: + SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); + unsigned Opc = SPU::ROTMAIr32_i32; + + if (Op0.getOpcode() == ISD::SRL) + Opc = SPU::ROTMr32; + + hi32 = CurDAG->getTargetNode(Opc, OpVT, SDValue(hi32, 0), shift); + } + + return hi32; + } + } + } } else if (Opc == ISD::SHL) { if (OpVT == MVT::i64) { return SelectSHLi64(Op, OpVT); @@ -1046,6 +1097,70 @@ SPUDAGToDAGISel::SelectSRAi64(SDValue &Op, MVT OpVT) { return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(Shift, 0)); } +/*! + Do the necessary magic necessary to load a i64 constant + */ +SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) { + ConstantSDNode *CN = cast(Op.getNode()); + MVT OpVecVT = MVT::getVectorVT(OpVT, 2); + SDValue i64vec = + SPU::LowerSplat_v2i64(OpVecVT, *CurDAG, CN->getZExtValue()); + + // Here's where it gets interesting, because we have to parse out the + // subtree handed back in i64vec: + + if (i64vec.getOpcode() == ISD::BIT_CONVERT) { + // The degenerate case where the upper and lower bits in the splat are + // identical: + SDValue Op0 = i64vec.getOperand(0); + ReplaceUses(i64vec, Op0); + + return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, + SDValue(emitBuildVector(Op0), 0)); + } else if (i64vec.getOpcode() == SPUISD::SHUFB) { + SDValue lhs = i64vec.getOperand(0); + SDValue rhs = i64vec.getOperand(1); + SDValue shufmask = i64vec.getOperand(2); + + if (lhs.getOpcode() == ISD::BIT_CONVERT) { + ReplaceUses(lhs, lhs.getOperand(0)); + lhs = lhs.getOperand(0); + } + + SDNode *lhsNode = (lhs.getNode()->isMachineOpcode() + ? lhs.getNode() + : emitBuildVector(lhs)); + + if (rhs.getOpcode() == ISD::BIT_CONVERT) { + ReplaceUses(rhs, rhs.getOperand(0)); + rhs = rhs.getOperand(0); + } + + SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() + ? rhs.getNode() + : emitBuildVector(rhs)); + + if (shufmask.getOpcode() == ISD::BIT_CONVERT) { + ReplaceUses(shufmask, shufmask.getOperand(0)); + shufmask = shufmask.getOperand(0); + } + + SDNode *shufMaskNode = (shufmask.getNode()->isMachineOpcode() + ? shufmask.getNode() + : emitBuildVector(shufmask)); + + SDNode *shufNode = + Select(CurDAG->getNode(SPUISD::SHUFB, OpVecVT, + SDValue(lhsNode, 0), SDValue(rhsNode, 0), + SDValue(shufMaskNode, 0))); + + return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(shufNode, 0)); + } else { + cerr << "SPUDAGToDAGISel::SelectI64Constant: Unhandled i64vec condition\n"; + abort(); + } +} + /// createSPUISelDag - This pass converts a legalized DAG into a /// SPU-specific DAG, ready for instruction scheduling. /// diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp index 124f1a7536b6..6bb76d805e3f 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp @@ -17,6 +17,7 @@ #include "SPUFrameInfo.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/VectorExtras.h" +#include "llvm/CallingConv.h" #include "llvm/CodeGen/CallingConvLower.h" #include "llvm/CodeGen/MachineFrameInfo.h" #include "llvm/CodeGen/MachineFunction.h" @@ -79,6 +80,43 @@ namespace { return retval; } + //! Expand a library call into an actual call DAG node + /*! + \note + This code is taken from SelectionDAGLegalize, since it is not exposed as + part of the LLVM SelectionDAG API. + */ + + SDValue + ExpandLibCall(RTLIB::Libcall LC, SDValue Op, SelectionDAG &DAG, + bool isSigned, SDValue &Hi, SPUTargetLowering &TLI) { + // The input chain to this libcall is the entry node of the function. + // Legalizing the call will automatically add the previous call to the + // dependence. + SDValue InChain = DAG.getEntryNode(); + + TargetLowering::ArgListTy Args; + TargetLowering::ArgListEntry Entry; + for (unsigned i = 0, e = Op.getNumOperands(); i != e; ++i) { + MVT ArgVT = Op.getOperand(i).getValueType(); + const Type *ArgTy = ArgVT.getTypeForMVT(); + Entry.Node = Op.getOperand(i); + Entry.Ty = ArgTy; + Entry.isSExt = isSigned; + Entry.isZExt = !isSigned; + Args.push_back(Entry); + } + SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), + TLI.getPointerTy()); + + // Splice the libcall in wherever FindInputOutputChains tells us to. + const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT(); + std::pair CallInfo = + TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, + CallingConv::C, false, Callee, Args, DAG); + + return CallInfo.first; + } } SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) @@ -113,7 +151,6 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) setLoadExtAction(ISD::EXTLOAD, MVT::f64, Expand); // SPU constant load actions are custom lowered: - setOperationAction(ISD::Constant, MVT::i64, Custom); setOperationAction(ISD::ConstantFP, MVT::f32, Legal); setOperationAction(ISD::ConstantFP, MVT::f64, Custom); @@ -128,10 +165,6 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) setLoadExtAction(ISD::ZEXTLOAD, VT, Custom); setLoadExtAction(ISD::SEXTLOAD, VT, Custom); - // SMUL_LOHI, UMUL_LOHI are not legal for Cell: - setOperationAction(ISD::SMUL_LOHI, VT, Expand); - setOperationAction(ISD::UMUL_LOHI, VT, Expand); - for (unsigned stype = sctype - 1; stype >= (unsigned) MVT::i8; --stype) { MVT StoreVT = (MVT::SimpleValueType) stype; setTruncStoreAction(VT, StoreVT, Expand); @@ -179,16 +212,14 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) setOperationAction(ISD::FCOS , MVT::f32, Expand); setOperationAction(ISD::FREM , MVT::f32, Expand); - // If we're enabling GP optimizations, use hardware square root + // Expand fsqrt to the appropriate libcall (NOTE: should use h/w fsqrt + // for f32!) setOperationAction(ISD::FSQRT, MVT::f64, Expand); setOperationAction(ISD::FSQRT, MVT::f32, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); - // Make sure that DAGCombine doesn't insert illegal 64-bit constants - setOperationAction(ISD::FABS, MVT::f64, Custom); - // SPU can do rotate right and left, so legalize it... but customize for i8 // because instructions don't exist. @@ -254,22 +285,21 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) // Custom lower i128 -> i64 truncates setOperationAction(ISD::TRUNCATE, MVT::i64, Custom); - // SPU has a legal FP -> signed INT instruction - setOperationAction(ISD::FP_TO_SINT, MVT::i32, Legal); - setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); - setOperationAction(ISD::FP_TO_UINT, MVT::i32, Legal); - setOperationAction(ISD::FP_TO_UINT, MVT::i64, Custom); + // SPU has a legal FP -> signed INT instruction for f32, but for f64, need + // to expand to a libcall, hence the custom lowering: + setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); + setOperationAction(ISD::FP_TO_UINT, MVT::i32, Custom); // FDIV on SPU requires custom lowering - setOperationAction(ISD::FDIV, MVT::f64, Expand); // libcall + setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall // SPU has [U|S]INT_TO_FP - setOperationAction(ISD::SINT_TO_FP, MVT::i32, Legal); + setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); - setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote); - setOperationAction(ISD::UINT_TO_FP, MVT::i32, Legal); + setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote); + setOperationAction(ISD::UINT_TO_FP, MVT::i32, Custom); setOperationAction(ISD::UINT_TO_FP, MVT::i16, Promote); - setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote); + setOperationAction(ISD::UINT_TO_FP, MVT::i8, Promote); setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); setOperationAction(ISD::UINT_TO_FP, MVT::i64, Custom); @@ -338,24 +368,23 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) MVT VT = (MVT::SimpleValueType)i; // add/sub are legal for all supported vector VT's. - setOperationAction(ISD::ADD , VT, Legal); - setOperationAction(ISD::SUB , VT, Legal); + setOperationAction(ISD::ADD, VT, Legal); + setOperationAction(ISD::SUB, VT, Legal); // mul has to be custom lowered. - // TODO: v2i64 vector multiply - setOperationAction(ISD::MUL , VT, Legal); + setOperationAction(ISD::MUL, VT, Legal); - setOperationAction(ISD::AND , VT, Legal); - setOperationAction(ISD::OR , VT, Legal); - setOperationAction(ISD::XOR , VT, Legal); - setOperationAction(ISD::LOAD , VT, Legal); - setOperationAction(ISD::SELECT, VT, Legal); - setOperationAction(ISD::STORE, VT, Legal); + setOperationAction(ISD::AND, VT, Legal); + setOperationAction(ISD::OR, VT, Legal); + setOperationAction(ISD::XOR, VT, Legal); + setOperationAction(ISD::LOAD, VT, Legal); + setOperationAction(ISD::SELECT, VT, Legal); + setOperationAction(ISD::STORE, VT, Legal); // These operations need to be expanded: - setOperationAction(ISD::SDIV, VT, Expand); - setOperationAction(ISD::SREM, VT, Expand); - setOperationAction(ISD::UDIV, VT, Expand); - setOperationAction(ISD::UREM, VT, Expand); + setOperationAction(ISD::SDIV, VT, Expand); + setOperationAction(ISD::SREM, VT, Expand); + setOperationAction(ISD::UDIV, VT, Expand); + setOperationAction(ISD::UREM, VT, Expand); // Custom lower build_vector, constant pool spills, insert and // extract vector elements: @@ -866,31 +895,6 @@ LowerGlobalAddress(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { return SDValue(); } -//! Custom lower i64 integer constants -/*! - This code inserts all of the necessary juggling that needs to occur to load - a 64-bit constant into a register. - */ -static SDValue -LowerConstant(SDValue Op, SelectionDAG &DAG) { - MVT VT = Op.getValueType(); - - if (VT == MVT::i64) { - ConstantSDNode *CN = cast(Op.getNode()); - SDValue T = DAG.getConstant(CN->getZExtValue(), VT); - return DAG.getNode(SPUISD::VEC2PREFSLOT, VT, - DAG.getNode(ISD::BUILD_VECTOR, MVT::v2i64, T, T)); - } else { - cerr << "LowerConstant: unhandled constant type " - << VT.getMVTString() - << "\n"; - abort(); - /*NOTREACHED*/ - } - - return SDValue(); -} - //! Custom lower double precision floating point constants static SDValue LowerConstantFP(SDValue Op, SelectionDAG &DAG) { @@ -1564,7 +1568,7 @@ static bool isConstantSplat(const uint64_t Bits128[2], //! Lower a BUILD_VECTOR instruction creatively: SDValue -SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { +LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { MVT VT = Op.getValueType(); // If this is a vector of constants or undefs, get the bits. A bit in // UndefBits is set if the corresponding element of the vector is an @@ -1588,7 +1592,7 @@ SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { abort(); /*NOTREACHED*/ case MVT::v4f32: { - uint32_t Value32 = SplatBits; + uint32_t Value32 = uint32_t(SplatBits); assert(SplatSize == 4 && "LowerBUILD_VECTOR: Unexpected floating point vector element."); // NOTE: pretend the constant is an integer. LLVM won't load FP constants @@ -1598,7 +1602,7 @@ SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { break; } case MVT::v2f64: { - uint64_t f64val = SplatBits; + uint64_t f64val = uint64_t(SplatBits); assert(SplatSize == 8 && "LowerBUILD_VECTOR: 64-bit float vector size > 8 bytes."); // NOTE: pretend the constant is an integer. LLVM won't load FP constants @@ -1638,93 +1642,99 @@ SPU::LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG) { return DAG.getNode(ISD::BUILD_VECTOR, VT, T, T); } case MVT::v2i64: { - uint64_t val = SplatBits; - uint32_t upper = uint32_t(val >> 32); - uint32_t lower = uint32_t(val); - - if (upper == lower) { - // Magic constant that can be matched by IL, ILA, et. al. - SDValue Val = DAG.getTargetConstant(val, MVT::i64); - return DAG.getNode(ISD::BUILD_VECTOR, VT, Val, Val); - } else { - SDValue LO32; - SDValue HI32; - SmallVector ShufBytes; - SDValue Result; - bool upper_special, lower_special; - - // NOTE: This code creates common-case shuffle masks that can be easily - // detected as common expressions. It is not attempting to create highly - // specialized masks to replace any and all 0's, 0xff's and 0x80's. - - // Detect if the upper or lower half is a special shuffle mask pattern: - upper_special = (upper == 0||upper == 0xffffffff||upper == 0x80000000); - lower_special = (lower == 0||lower == 0xffffffff||lower == 0x80000000); - - // Create lower vector if not a special pattern - if (!lower_special) { - SDValue LO32C = DAG.getConstant(lower, MVT::i32); - LO32 = DAG.getNode(ISD::BIT_CONVERT, VT, - DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, - LO32C, LO32C, LO32C, LO32C)); - } + return SPU::LowerSplat_v2i64(VT, DAG, SplatBits); + } + } - // Create upper vector if not a special pattern - if (!upper_special) { - SDValue HI32C = DAG.getConstant(upper, MVT::i32); - HI32 = DAG.getNode(ISD::BIT_CONVERT, VT, - DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, - HI32C, HI32C, HI32C, HI32C)); - } + return SDValue(); +} - // If either upper or lower are special, then the two input operands are - // the same (basically, one of them is a "don't care") - if (lower_special) - LO32 = HI32; - if (upper_special) - HI32 = LO32; - if (lower_special && upper_special) { - // Unhappy situation... both upper and lower are special, so punt with - // a target constant: - SDValue Zero = DAG.getConstant(0, MVT::i32); - HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero, - Zero, Zero); - } +SDValue +SPU::LowerSplat_v2i64(MVT OpVT, SelectionDAG& DAG, uint64_t SplatVal) { + uint32_t upper = uint32_t(SplatVal >> 32); + uint32_t lower = uint32_t(SplatVal); + + if (upper == lower) { + // Magic constant that can be matched by IL, ILA, et. al. + SDValue Val = DAG.getTargetConstant(upper, MVT::i32); + return DAG.getNode(ISD::BIT_CONVERT, OpVT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + Val, Val, Val, Val)); + } else { + SDValue LO32; + SDValue HI32; + SmallVector ShufBytes; + SDValue Result; + bool upper_special, lower_special; + + // NOTE: This code creates common-case shuffle masks that can be easily + // detected as common expressions. It is not attempting to create highly + // specialized masks to replace any and all 0's, 0xff's and 0x80's. + + // Detect if the upper or lower half is a special shuffle mask pattern: + upper_special = (upper == 0 || upper == 0xffffffff || upper == 0x80000000); + lower_special = (lower == 0 || lower == 0xffffffff || lower == 0x80000000); + + // Create lower vector if not a special pattern + if (!lower_special) { + SDValue LO32C = DAG.getConstant(lower, MVT::i32); + LO32 = DAG.getNode(ISD::BIT_CONVERT, OpVT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + LO32C, LO32C, LO32C, LO32C)); + } - for (int i = 0; i < 4; ++i) { - uint64_t val = 0; - for (int j = 0; j < 4; ++j) { - SDValue V; - bool process_upper, process_lower; - val <<= 8; - process_upper = (upper_special && (i & 1) == 0); - process_lower = (lower_special && (i & 1) == 1); - - if (process_upper || process_lower) { - if ((process_upper && upper == 0) - || (process_lower && lower == 0)) - val |= 0x80; - else if ((process_upper && upper == 0xffffffff) - || (process_lower && lower == 0xffffffff)) - val |= 0xc0; - else if ((process_upper && upper == 0x80000000) - || (process_lower && lower == 0x80000000)) - val |= (j == 0 ? 0xe0 : 0x80); - } else - val |= i * 4 + j + ((i & 1) * 16); - } + // Create upper vector if not a special pattern + if (!upper_special) { + SDValue HI32C = DAG.getConstant(upper, MVT::i32); + HI32 = DAG.getNode(ISD::BIT_CONVERT, OpVT, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + HI32C, HI32C, HI32C, HI32C)); + } - ShufBytes.push_back(DAG.getConstant(val, MVT::i32)); + // If either upper or lower are special, then the two input operands are + // the same (basically, one of them is a "don't care") + if (lower_special) + LO32 = HI32; + if (upper_special) + HI32 = LO32; + if (lower_special && upper_special) { + // Unhappy situation... both upper and lower are special, so punt with + // a target constant: + SDValue Zero = DAG.getConstant(0, MVT::i32); + HI32 = LO32 = DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, Zero, Zero, + Zero, Zero); + } + + for (int i = 0; i < 4; ++i) { + uint64_t val = 0; + for (int j = 0; j < 4; ++j) { + SDValue V; + bool process_upper, process_lower; + val <<= 8; + process_upper = (upper_special && (i & 1) == 0); + process_lower = (lower_special && (i & 1) == 1); + + if (process_upper || process_lower) { + if ((process_upper && upper == 0) + || (process_lower && lower == 0)) + val |= 0x80; + else if ((process_upper && upper == 0xffffffff) + || (process_lower && lower == 0xffffffff)) + val |= 0xc0; + else if ((process_upper && upper == 0x80000000) + || (process_lower && lower == 0x80000000)) + val |= (j == 0 ? 0xe0 : 0x80); + } else + val |= i * 4 + j + ((i & 1) * 16); } - return DAG.getNode(SPUISD::SHUFB, VT, HI32, LO32, - DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, - &ShufBytes[0], ShufBytes.size())); + ShufBytes.push_back(DAG.getConstant(val, MVT::i32)); } - } - } - return SDValue(); + return DAG.getNode(SPUISD::SHUFB, OpVT, HI32, LO32, + DAG.getNode(ISD::BUILD_VECTOR, MVT::v4i32, + &ShufBytes[0], ShufBytes.size())); + } } /// LowerVECTOR_SHUFFLE - Lower a vector shuffle (V1, V2, V3) to something on @@ -2384,81 +2394,180 @@ static SDValue LowerCTPOP(SDValue Op, SelectionDAG &DAG) { return SDValue(); } -//! Lower ISD::FABS +//! Lower ISD::FP_TO_SINT, ISD::FP_TO_UINT for i32 /*! - DAGCombine does the same basic reduction: convert the double to i64 and mask - off the sign bit. Unfortunately, DAGCombine inserts the i64 constant, which - CellSPU has to legalize. Hence, the custom lowering. + f32->i32 passes through unchanged, whereas f64->i32 expands to a libcall. + All conversions to i64 are expanded to a libcall. */ - -static SDValue LowerFABS(SDValue Op, SelectionDAG &DAG) { +static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, + SPUTargetLowering &TLI) { MVT OpVT = Op.getValueType(); - MVT IntVT(MVT::i64); SDValue Op0 = Op.getOperand(0); + MVT Op0VT = Op0.getValueType(); + + if ((OpVT == MVT::i32 && Op0VT == MVT::f64) + || OpVT == MVT::i64) { + // Convert f32 / f64 to i32 / i64 via libcall. + RTLIB::Libcall LC = + (Op.getOpcode() == ISD::FP_TO_SINT) + ? RTLIB::getFPTOSINT(Op0VT, OpVT) + : RTLIB::getFPTOUINT(Op0VT, OpVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd fp-to-int conversion!"); + SDValue Dummy; + return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI); + } + + return SDValue(); +} - assert(OpVT == MVT::f64 && "LowerFABS: expecting MVT::f64!\n"); +//! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32 +/*! + i32->f32 passes through unchanged, whereas i32->f64 is expanded to a libcall. + All conversions from i64 are expanded to a libcall. + */ +static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG, + SPUTargetLowering &TLI) { + MVT OpVT = Op.getValueType(); + SDValue Op0 = Op.getOperand(0); + MVT Op0VT = Op0.getValueType(); - SDValue iABS = - DAG.getNode(ISD::AND, IntVT, - DAG.getNode(ISD::BIT_CONVERT, IntVT, Op0), - DAG.getConstant(~IntVT.getIntegerVTSignBit(), IntVT)); + if ((OpVT == MVT::f64 && Op0VT == MVT::i32) + || Op0VT == MVT::i64) { + // Convert i32, i64 to f64 via libcall: + RTLIB::Libcall LC = + (Op.getOpcode() == ISD::SINT_TO_FP) + ? RTLIB::getSINTTOFP(Op0VT, OpVT) + : RTLIB::getUINTTOFP(Op0VT, OpVT); + assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpectd int-to-fp conversion!"); + SDValue Dummy; + return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI); + } - return DAG.getNode(ISD::BIT_CONVERT, MVT::f64, iABS); + return SDValue(); } //! Lower ISD::SETCC /*! This handles MVT::f64 (double floating point) condition lowering */ - static SDValue LowerSETCC(SDValue Op, SelectionDAG &DAG, const TargetLowering &TLI) { + CondCodeSDNode *CC = dyn_cast(Op.getOperand(2)); + assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n"); + SDValue lhs = Op.getOperand(0); SDValue rhs = Op.getOperand(1); - CondCodeSDNode *CC = dyn_cast (Op.getOperand(2)); MVT lhsVT = lhs.getValueType(); - SDValue posNaN = DAG.getConstant(0x7ff0000000000001ULL, MVT::i64); - - assert(CC != 0 && "LowerSETCC: CondCodeSDNode should not be null here!\n"); assert(lhsVT == MVT::f64 && "LowerSETCC: type other than MVT::64\n"); - switch (CC->get()) { - case ISD::SETOEQ: - case ISD::SETOGT: - case ISD::SETOGE: - case ISD::SETOLT: - case ISD::SETOLE: - case ISD::SETONE: - cerr << "CellSPU ISel Select: unimplemented f64 condition\n"; - abort(); - break; - case ISD::SETO: { - SDValue lhsfabs = DAG.getNode(ISD::FABS, MVT::f64, lhs); - SDValue i64lhs = - DAG.getNode(ISD::BIT_CONVERT, MVT::i64, lhsfabs); + MVT ccResultVT = TLI.getSetCCResultType(lhs.getValueType()); + APInt ccResultOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits()); + MVT IntVT(MVT::i64); - return DAG.getSetCC(MVT::i32, i64lhs, posNaN, ISD::SETLT); - } - case ISD::SETUO: { - SDValue lhsfabs = DAG.getNode(ISD::FABS, MVT::f64, lhs); - SDValue i64lhs = - DAG.getNode(ISD::BIT_CONVERT, MVT::i64, lhsfabs); + // Take advantage of the fact that (truncate (sra arg, 32)) is efficiently + // selected to a NOP: + SDValue i64lhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, lhs); + SDValue lhsHi32 = + DAG.getNode(ISD::TRUNCATE, MVT::i32, + DAG.getNode(ISD::SRL, IntVT, + i64lhs, DAG.getConstant(32, MVT::i32))); + SDValue lhsHi32abs = + DAG.getNode(ISD::AND, MVT::i32, + lhsHi32, DAG.getConstant(0x7fffffff, MVT::i32)); + SDValue lhsLo32 = + DAG.getNode(ISD::TRUNCATE, MVT::i32, i64lhs); + + // SETO and SETUO only use the lhs operand: + if (CC->get() == ISD::SETO) { + // Evaluates to true if Op0 is not [SQ]NaN - lowers to the inverse of + // SETUO + APInt ccResultAllOnes = APInt::getAllOnesValue(ccResultVT.getSizeInBits()); + return DAG.getNode(ISD::XOR, ccResultVT, + DAG.getSetCC(ccResultVT, + lhs, DAG.getConstantFP(0.0, lhsVT), + ISD::SETUO), + DAG.getConstant(ccResultAllOnes, ccResultVT)); + } else if (CC->get() == ISD::SETUO) { + // Evaluates to true if Op0 is [SQ]NaN + return DAG.getNode(ISD::AND, ccResultVT, + DAG.getSetCC(ccResultVT, + lhsHi32abs, + DAG.getConstant(0x7ff00000, MVT::i32), + ISD::SETGE), + DAG.getSetCC(ccResultVT, + lhsLo32, + DAG.getConstant(0, MVT::i32), + ISD::SETGT)); + } + + SDValue i64rhs = DAG.getNode(ISD::BIT_CONVERT, IntVT, rhs); + SDValue rhsHi32 = + DAG.getNode(ISD::TRUNCATE, MVT::i32, + DAG.getNode(ISD::SRL, IntVT, + i64rhs, DAG.getConstant(32, MVT::i32))); + + // If a value is negative, subtract from the sign magnitude constant: + SDValue signMag2TC = DAG.getConstant(0x8000000000000000ULL, IntVT); + + // Convert the sign-magnitude representation into 2's complement: + SDValue lhsSelectMask = DAG.getNode(ISD::SRA, ccResultVT, + lhsHi32, DAG.getConstant(31, MVT::i32)); + SDValue lhsSignMag2TC = DAG.getNode(ISD::SUB, IntVT, signMag2TC, i64lhs); + SDValue lhsSelect = + DAG.getNode(ISD::SELECT, IntVT, + lhsSelectMask, lhsSignMag2TC, i64lhs); + + SDValue rhsSelectMask = DAG.getNode(ISD::SRA, ccResultVT, + rhsHi32, DAG.getConstant(31, MVT::i32)); + SDValue rhsSignMag2TC = DAG.getNode(ISD::SUB, IntVT, signMag2TC, i64rhs); + SDValue rhsSelect = + DAG.getNode(ISD::SELECT, IntVT, + rhsSelectMask, rhsSignMag2TC, i64rhs); + + unsigned compareOp; - return DAG.getSetCC(MVT::i32, i64lhs, posNaN, ISD::SETGE); - } + switch (CC->get()) { + case ISD::SETOEQ: case ISD::SETUEQ: + compareOp = ISD::SETEQ; break; + case ISD::SETOGT: case ISD::SETUGT: + compareOp = ISD::SETGT; break; + case ISD::SETOGE: case ISD::SETUGE: + compareOp = ISD::SETGE; break; + case ISD::SETOLT: case ISD::SETULT: + compareOp = ISD::SETLT; break; + case ISD::SETOLE: case ISD::SETULE: + compareOp = ISD::SETLE; break; case ISD::SETUNE: + case ISD::SETONE: + compareOp = ISD::SETNE; break; default: cerr << "CellSPU ISel Select: unimplemented f64 condition\n"; abort(); break; } - return SDValue(); + SDValue result = + DAG.getSetCC(ccResultVT, lhsSelect, rhsSelect, (ISD::CondCode) compareOp); + + if ((CC->get() & 0x8) == 0) { + // Ordered comparison: + SDValue lhsNaN = DAG.getSetCC(ccResultVT, + lhs, DAG.getConstantFP(0.0, MVT::f64), + ISD::SETO); + SDValue rhsNaN = DAG.getSetCC(ccResultVT, + rhs, DAG.getConstantFP(0.0, MVT::f64), + ISD::SETO); + SDValue ordered = DAG.getNode(ISD::AND, ccResultVT, lhsNaN, rhsNaN); + + result = DAG.getNode(ISD::AND, ccResultVT, ordered, result); + } + + return result; } //! Lower ISD::SELECT_CC @@ -2566,8 +2675,6 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) return LowerGlobalAddress(Op, DAG, SPUTM.getSubtargetImpl()); case ISD::JumpTable: return LowerJumpTable(Op, DAG, SPUTM.getSubtargetImpl()); - case ISD::Constant: - return LowerConstant(Op, DAG); case ISD::ConstantFP: return LowerConstantFP(Op, DAG); case ISD::FORMAL_ARGUMENTS: @@ -2590,12 +2697,17 @@ SPUTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) break; } - case ISD::FABS: - return LowerFABS(Op, DAG); + case ISD::FP_TO_SINT: + case ISD::FP_TO_UINT: + return LowerFP_TO_INT(Op, DAG, *this); + + case ISD::SINT_TO_FP: + case ISD::UINT_TO_FP: + return LowerINT_TO_FP(Op, DAG, *this); // Vector-related lowering. case ISD::BUILD_VECTOR: - return SPU::LowerBUILD_VECTOR(Op, DAG); + return LowerBUILD_VECTOR(Op, DAG); case ISD::SCALAR_TO_VECTOR: return LowerSCALAR_TO_VECTOR(Op, DAG); case ISD::VECTOR_SHUFFLE: diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.h b/llvm/lib/Target/CellSPU/SPUISelLowering.h index 079f3ba69efa..24c2803fe65f 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.h +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.h @@ -61,7 +61,7 @@ namespace llvm { }; } - //! Utility functions specific to CellSPU-only: + //! Utility functions specific to CellSPU: namespace SPU { SDValue get_vec_u18imm(SDNode *N, SelectionDAG &DAG, MVT ValueType); @@ -78,7 +78,7 @@ namespace llvm { SDValue LowerConstantPool(SDValue Op, SelectionDAG &DAG, const SPUTargetMachine &TM); - SDValue LowerBUILD_VECTOR(SDValue Op, SelectionDAG &DAG); + SDValue LowerSplat_v2i64(MVT OpVT, SelectionDAG &DAG, uint64_t splat); SDValue getBorrowGenerateShufMask(SelectionDAG &DAG); SDValue getCarryGenerateShufMask(SelectionDAG &DAG); diff --git a/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp b/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp index 91d52facada8..f35a42d71a9c 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp +++ b/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp @@ -155,13 +155,13 @@ SPUInstrInfo::isMoveInstr(const MachineInstr& MI, case SPU::ORr8_r32: case SPU::ORr32_r16: case SPU::ORr32_r8: - case SPU::ORr32_r64: case SPU::ORr16_r64: case SPU::ORr8_r64: - case SPU::ORr64_r32: case SPU::ORr64_r16: case SPU::ORr64_r8: */ + case SPU::ORr64_r32: + case SPU::ORr32_r64: case SPU::ORf32_r32: case SPU::ORr32_f32: case SPU::ORf64_r64: diff --git a/llvm/lib/Target/CellSPU/SPUInstrInfo.td b/llvm/lib/Target/CellSPU/SPUInstrInfo.td index 2834a1eb8d9c..8db2fa7fced3 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrInfo.td +++ b/llvm/lib/Target/CellSPU/SPUInstrInfo.td @@ -1259,6 +1259,9 @@ multiclass BitwiseAnd def fabs32: ANDInst<(outs R32FP:$rT), (ins R32FP:$rA, R32C:$rB), [/* Intentionally does not match a pattern */]>; + def fabs64: ANDInst<(outs R64FP:$rT), (ins R64FP:$rA, VECREG:$rB), + [/* Intentionally does not match a pattern */]>; + // Could use v4i32, but won't for clarity def fabsvec: ANDInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB), [/* Intentionally does not match a pattern */]>; @@ -1525,17 +1528,17 @@ multiclass BitwiseOr // Conversion from R32C to register def r32_r16: ORCvtFormR32Reg; def r32_r8: ORCvtFormR32Reg; +*/ - // Conversion from register to R64C: + // Conversion to register from R64C: def r32_r64: ORCvtFormR64Reg; - def r16_r64: ORCvtFormR64Reg; - def r8_r64: ORCvtFormR64Reg; + // def r16_r64: ORCvtFormR64Reg; + // def r8_r64: ORCvtFormR64Reg; - // Conversion from R64C to register + // Conversion to R64C from register def r64_r32: ORCvtFormRegR64; - def r64_r16: ORCvtFormRegR64; - def r64_r8: ORCvtFormRegR64; -*/ + // def r64_r16: ORCvtFormRegR64; + // def r64_r8: ORCvtFormRegR64; // bitconvert patterns: def r32_f32: ORCvtFormR32Reg pattern>: RRRForm<0b1000, OOL, IOL, "selb\t$rT, $rA, $rB, $rC", IntegerOp, pattern>; -class SELBVecInst: +class SELBVecInst: SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), [(set (vectype VECREG:$rT), (or (and (vectype VECREG:$rC), (vectype VECREG:$rB)), - (and (vnot (vectype VECREG:$rC)), + (and (vnot_frag (vectype VECREG:$rC)), (vectype VECREG:$rA))))]>; class SELBVecVCondInst: @@ -1947,7 +1950,7 @@ multiclass SelectBits def v16i8: SELBVecInst; def v8i16: SELBVecInst; def v4i32: SELBVecInst; - def v2i64: SELBVecInst; + def v2i64: SELBVecInst; def r128: SELBRegInst; def r64: SELBRegInst; @@ -4321,6 +4324,13 @@ def : Pat<(fabs (v4f32 VECREG:$rA)), (ANDfabsvec (v4f32 VECREG:$rA), (v4f32 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>; +def : Pat<(fabs R64FP:$rA), + (ANDfabs64 R64FP:$rA, (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f))>; + +def : Pat<(fabs (v2f64 VECREG:$rA)), + (ANDfabsvec (v2f64 VECREG:$rA), + (v2f64 (ANDBIv16i8 (FSMBIv16i8 0xffff), 0x7f)))>; + //===----------------------------------------------------------------------===// // Hint for branch instructions: //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/CellSPU/fcmp.ll b/llvm/test/CodeGen/CellSPU/fcmp32.ll similarity index 56% rename from llvm/test/CodeGen/CellSPU/fcmp.ll rename to llvm/test/CodeGen/CellSPU/fcmp32.ll index aad77175d163..27a659e82930 100644 --- a/llvm/test/CodeGen/CellSPU/fcmp.ll +++ b/llvm/test/CodeGen/CellSPU/fcmp32.ll @@ -1,22 +1,23 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s ; RUN: grep fceq %t1.s | count 1 ; RUN: grep fcmeq %t1.s | count 1 -; -; This file includes standard floating point arithmetic instructions + target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" +; Exercise the floating point comparison operators for f32: + declare double @fabs(double) declare float @fabsf(float) define i1 @fcmp_eq(float %arg1, float %arg2) { - %A = fcmp oeq float %arg1, %arg2 ; [#uses=1] + %A = fcmp oeq float %arg1, %arg2 ret i1 %A } define i1 @fcmp_mag_eq(float %arg1, float %arg2) { - %A = call float @fabsf(float %arg1) ; [#uses=1] - %B = call float @fabsf(float %arg2) ; [#uses=1] - %C = fcmp oeq float %A, %B ; [#uses=1] - ret i1 %C + %1 = call float @fabsf(float %arg1) + %2 = call float @fabsf(float %arg2) + %3 = fcmp oeq float %1, %2 + ret i1 %3 } diff --git a/llvm/test/CodeGen/CellSPU/fcmp64.ll b/llvm/test/CodeGen/CellSPU/fcmp64.ll new file mode 100644 index 000000000000..1906bfe7ddaa --- /dev/null +++ b/llvm/test/CodeGen/CellSPU/fcmp64.ll @@ -0,0 +1,7 @@ +; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s + +define i1 @fcmp_eq_setcc_f64(double %arg1, double %arg2) nounwind { +entry: + %A = fcmp oeq double %arg1, %arg2 + ret i1 %A +} diff --git a/llvm/test/CodeGen/CellSPU/fneg-fabs.ll b/llvm/test/CodeGen/CellSPU/fneg-fabs.ll index 70220a563d94..b6eca10803ec 100644 --- a/llvm/test/CodeGen/CellSPU/fneg-fabs.ll +++ b/llvm/test/CodeGen/CellSPU/fneg-fabs.ll @@ -1,9 +1,10 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s -; RUN: grep fsmbi %t1.s | count 2 +; RUN: grep fsmbi %t1.s | count 3 ; RUN: grep 32768 %t1.s | count 2 ; RUN: grep xor %t1.s | count 4 -; RUN: grep and %t1.s | count 4 -; RUN: grep andbi %t1.s | count 2 +; RUN: grep and %t1.s | count 5 +; RUN: grep andbi %t1.s | count 3 + target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" @@ -33,11 +34,11 @@ declare double @fabs(double) declare float @fabsf(float) define double @fabs_dp(double %X) { - %Y = call double @fabs( double %X ) ; [#uses=1] + %Y = call double @fabs( double %X ) ret double %Y } define float @fabs_sp(float %X) { - %Y = call float @fabsf( float %X ) ; [#uses=1] + %Y = call float @fabsf( float %X ) ret float %Y } diff --git a/llvm/test/CodeGen/CellSPU/select_bits.ll b/llvm/test/CodeGen/CellSPU/select_bits.ll index 3a7334d808cf..e83e47606c28 100644 --- a/llvm/test/CodeGen/CellSPU/select_bits.ll +++ b/llvm/test/CodeGen/CellSPU/select_bits.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s -; RUN: grep selb %t1.s | count 280 +; RUN: grep selb %t1.s | count 56 target datalayout = "E-p:32:32:128-f64:64:128-f32:32:128-i64:32:128-i32:32:128-i16:16:128-i8:8:128-i1:8:128-a0:0:128-v128:128:128-s0:128:128" target triple = "spu" @@ -9,7 +9,7 @@ target triple = "spu" ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define <2 x i64> @selb_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %C = and <2 x i64> %rC, %rB %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %A, %rA @@ -18,7 +18,7 @@ define <2 x i64> @selb_v2i64_01(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define <2 x i64> @selb_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %C = and <2 x i64> %rB, %rC %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %A, %rA @@ -27,7 +27,7 @@ define <2 x i64> @selb_v2i64_02(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define <2 x i64> @selb_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %A, %rA %C = and <2 x i64> %rB, %rC @@ -36,7 +36,7 @@ define <2 x i64> @selb_v2i64_03(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define <2 x i64> @selb_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %A, %rA %C = and <2 x i64> %rC, %rB @@ -45,7 +45,7 @@ define <2 x i64> @selb_v2i64_04(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define <2 x i64> @selb_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %C = and <2 x i64> %rC, %rB %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %rA, %A @@ -54,7 +54,7 @@ define <2 x i64> @selb_v2i64_05(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define <2 x i64> @selb_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %C = and <2 x i64> %rB, %rC %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %rA, %A @@ -63,7 +63,7 @@ define <2 x i64> @selb_v2i64_06(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define <2 x i64> @selb_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %rA, %A %C = and <2 x i64> %rB, %rC @@ -72,7 +72,7 @@ define <2 x i64> @selb_v2i64_07(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define <2 x i64> @selb_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { +define <2 x i64> @selectbits_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { %A = xor <2 x i64> %rC, < i64 -1, i64 -1 > %B = and <2 x i64> %rA, %A %C = and <2 x i64> %rC, %rB @@ -85,7 +85,7 @@ define <2 x i64> @selb_v2i64_08(<2 x i64> %rA, <2 x i64> %rB, <2 x i64> %rC) { ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define <4 x i32> @selb_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %C = and <4 x i32> %rC, %rB %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 > %B = and <4 x i32> %A, %rA @@ -94,7 +94,7 @@ define <4 x i32> @selb_v4i32_01(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define <4 x i32> @selb_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %C = and <4 x i32> %rB, %rC %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 > %B = and <4 x i32> %A, %rA @@ -103,7 +103,7 @@ define <4 x i32> @selb_v4i32_02(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define <4 x i32> @selb_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1 > %B = and <4 x i32> %A, %rA %C = and <4 x i32> %rB, %rC @@ -112,7 +112,7 @@ define <4 x i32> @selb_v4i32_03(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define <4 x i32> @selb_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1> %B = and <4 x i32> %A, %rA %C = and <4 x i32> %rC, %rB @@ -121,7 +121,7 @@ define <4 x i32> @selb_v4i32_04(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define <4 x i32> @selb_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %C = and <4 x i32> %rC, %rB %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1> %B = and <4 x i32> %rA, %A @@ -130,7 +130,7 @@ define <4 x i32> @selb_v4i32_05(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define <4 x i32> @selb_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %C = and <4 x i32> %rB, %rC %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1> %B = and <4 x i32> %rA, %A @@ -139,7 +139,7 @@ define <4 x i32> @selb_v4i32_06(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define <4 x i32> @selb_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1> %B = and <4 x i32> %rA, %A %C = and <4 x i32> %rB, %rC @@ -148,7 +148,7 @@ define <4 x i32> @selb_v4i32_07(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define <4 x i32> @selb_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { +define <4 x i32> @selectbits_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { %A = xor <4 x i32> %rC, < i32 -1, i32 -1, i32 -1, i32 -1> %B = and <4 x i32> %rA, %A %C = and <4 x i32> %rC, %rB @@ -161,7 +161,7 @@ define <4 x i32> @selb_v4i32_08(<4 x i32> %rA, <4 x i32> %rB, <4 x i32> %rC) { ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define <8 x i16> @selb_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %C = and <8 x i16> %rC, %rB %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > @@ -171,7 +171,7 @@ define <8 x i16> @selb_v8i16_01(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define <8 x i16> @selb_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %C = and <8 x i16> %rB, %rC %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > @@ -181,7 +181,7 @@ define <8 x i16> @selb_v8i16_02(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define <8 x i16> @selb_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > %B = and <8 x i16> %A, %rA @@ -191,7 +191,7 @@ define <8 x i16> @selb_v8i16_03(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define <8 x i16> @selb_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > %B = and <8 x i16> %A, %rA @@ -201,7 +201,7 @@ define <8 x i16> @selb_v8i16_04(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define <8 x i16> @selb_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %C = and <8 x i16> %rC, %rB %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > @@ -211,7 +211,7 @@ define <8 x i16> @selb_v8i16_05(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define <8 x i16> @selb_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %C = and <8 x i16> %rB, %rC %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > @@ -221,7 +221,7 @@ define <8 x i16> @selb_v8i16_06(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define <8 x i16> @selb_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > %B = and <8 x i16> %rA, %A @@ -231,7 +231,7 @@ define <8 x i16> @selb_v8i16_07(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define <8 x i16> @selb_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { +define <8 x i16> @selectbits_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { %A = xor <8 x i16> %rC, < i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1, i16 -1 > %B = and <8 x i16> %rA, %A @@ -245,7 +245,7 @@ define <8 x i16> @selb_v8i16_08(<8 x i16> %rA, <8 x i16> %rB, <8 x i16> %rC) { ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define <16 x i8> @selb_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %C = and <16 x i8> %rC, %rB %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -257,7 +257,7 @@ define <16 x i8> @selb_v16i8_01(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define <16 x i8> @selb_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %C = and <16 x i8> %rB, %rC %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -269,7 +269,7 @@ define <16 x i8> @selb_v16i8_02(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define <16 x i8> @selb_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -281,7 +281,7 @@ define <16 x i8> @selb_v16i8_03(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define <16 x i8> @selb_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -293,7 +293,7 @@ define <16 x i8> @selb_v16i8_04(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define <16 x i8> @selb_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %C = and <16 x i8> %rC, %rB %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -305,7 +305,7 @@ define <16 x i8> @selb_v16i8_05(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define <16 x i8> @selb_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %C = and <16 x i8> %rB, %rC %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -317,7 +317,7 @@ define <16 x i8> @selb_v16i8_06(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define <16 x i8> @selb_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -329,7 +329,7 @@ define <16 x i8> @selb_v16i8_07(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define <16 x i8> @selb_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { +define <16 x i8> @selectbits_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { %A = xor <16 x i8> %rC, < i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, i8 -1, @@ -345,7 +345,7 @@ define <16 x i8> @selb_v16i8_08(<16 x i8> %rA, <16 x i8> %rB, <16 x i8> %rC) { ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define i32 @selb_i32_01(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_01(i32 %rA, i32 %rB, i32 %rC) { %C = and i32 %rC, %rB %A = xor i32 %rC, -1 %B = and i32 %A, %rA @@ -354,7 +354,7 @@ define i32 @selb_i32_01(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define i32 @selb_i32_02(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_02(i32 %rA, i32 %rB, i32 %rC) { %C = and i32 %rB, %rC %A = xor i32 %rC, -1 %B = and i32 %A, %rA @@ -363,7 +363,7 @@ define i32 @selb_i32_02(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define i32 @selb_i32_03(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_03(i32 %rA, i32 %rB, i32 %rC) { %A = xor i32 %rC, -1 %B = and i32 %A, %rA %C = and i32 %rB, %rC @@ -372,7 +372,7 @@ define i32 @selb_i32_03(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define i32 @selb_i32_04(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_04(i32 %rA, i32 %rB, i32 %rC) { %A = xor i32 %rC, -1 %B = and i32 %A, %rA %C = and i32 %rC, %rB @@ -381,7 +381,7 @@ define i32 @selb_i32_04(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define i32 @selb_i32_05(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_05(i32 %rA, i32 %rB, i32 %rC) { %C = and i32 %rC, %rB %A = xor i32 %rC, -1 %B = and i32 %rA, %A @@ -390,7 +390,7 @@ define i32 @selb_i32_05(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define i32 @selb_i32_06(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_06(i32 %rA, i32 %rB, i32 %rC) { %C = and i32 %rB, %rC %A = xor i32 %rC, -1 %B = and i32 %rA, %A @@ -399,7 +399,7 @@ define i32 @selb_i32_06(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define i32 @selb_i32_07(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_07(i32 %rA, i32 %rB, i32 %rC) { %A = xor i32 %rC, -1 %B = and i32 %rA, %A %C = and i32 %rB, %rC @@ -408,7 +408,7 @@ define i32 @selb_i32_07(i32 %rA, i32 %rB, i32 %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define i32 @selb_i32_08(i32 %rA, i32 %rB, i32 %rC) { +define i32 @selectbits_i32_08(i32 %rA, i32 %rB, i32 %rC) { %A = xor i32 %rC, -1 %B = and i32 %rA, %A %C = and i32 %rC, %rB @@ -421,7 +421,7 @@ define i32 @selb_i32_08(i32 %rA, i32 %rB, i32 %rC) { ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define i16 @selb_i16_01(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_01(i16 %rA, i16 %rB, i16 %rC) { %C = and i16 %rC, %rB %A = xor i16 %rC, -1 %B = and i16 %A, %rA @@ -430,7 +430,7 @@ define i16 @selb_i16_01(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define i16 @selb_i16_02(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_02(i16 %rA, i16 %rB, i16 %rC) { %C = and i16 %rB, %rC %A = xor i16 %rC, -1 %B = and i16 %A, %rA @@ -439,7 +439,7 @@ define i16 @selb_i16_02(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define i16 @selb_i16_03(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_03(i16 %rA, i16 %rB, i16 %rC) { %A = xor i16 %rC, -1 %B = and i16 %A, %rA %C = and i16 %rB, %rC @@ -448,7 +448,7 @@ define i16 @selb_i16_03(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define i16 @selb_i16_04(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_04(i16 %rA, i16 %rB, i16 %rC) { %A = xor i16 %rC, -1 %B = and i16 %A, %rA %C = and i16 %rC, %rB @@ -457,7 +457,7 @@ define i16 @selb_i16_04(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define i16 @selb_i16_05(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_05(i16 %rA, i16 %rB, i16 %rC) { %C = and i16 %rC, %rB %A = xor i16 %rC, -1 %B = and i16 %rA, %A @@ -466,7 +466,7 @@ define i16 @selb_i16_05(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define i16 @selb_i16_06(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_06(i16 %rA, i16 %rB, i16 %rC) { %C = and i16 %rB, %rC %A = xor i16 %rC, -1 %B = and i16 %rA, %A @@ -475,7 +475,7 @@ define i16 @selb_i16_06(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define i16 @selb_i16_07(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_07(i16 %rA, i16 %rB, i16 %rC) { %A = xor i16 %rC, -1 %B = and i16 %rA, %A %C = and i16 %rB, %rC @@ -484,7 +484,7 @@ define i16 @selb_i16_07(i16 %rA, i16 %rB, i16 %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define i16 @selb_i16_08(i16 %rA, i16 %rB, i16 %rC) { +define i16 @selectbits_i16_08(i16 %rA, i16 %rB, i16 %rC) { %A = xor i16 %rC, -1 %B = and i16 %rA, %A %C = and i16 %rC, %rB @@ -497,7 +497,7 @@ define i16 @selb_i16_08(i16 %rA, i16 %rB, i16 %rC) { ;-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~-~ ; (or (and rC, rB), (and (not rC), rA)) -define i8 @selb_i8_01(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_01(i8 %rA, i8 %rB, i8 %rC) { %C = and i8 %rC, %rB %A = xor i8 %rC, -1 %B = and i8 %A, %rA @@ -506,7 +506,7 @@ define i8 @selb_i8_01(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and rB, rC), (and (not rC), rA)) -define i8 @selb_i8_02(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_02(i8 %rA, i8 %rB, i8 %rC) { %C = and i8 %rB, %rC %A = xor i8 %rC, -1 %B = and i8 %A, %rA @@ -515,7 +515,7 @@ define i8 @selb_i8_02(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and (not rC), rA), (and rB, rC)) -define i8 @selb_i8_03(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_03(i8 %rA, i8 %rB, i8 %rC) { %A = xor i8 %rC, -1 %B = and i8 %A, %rA %C = and i8 %rB, %rC @@ -524,7 +524,7 @@ define i8 @selb_i8_03(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and (not rC), rA), (and rC, rB)) -define i8 @selb_i8_04(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_04(i8 %rA, i8 %rB, i8 %rC) { %A = xor i8 %rC, -1 %B = and i8 %A, %rA %C = and i8 %rC, %rB @@ -533,7 +533,7 @@ define i8 @selb_i8_04(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and rC, rB), (and rA, (not rC))) -define i8 @selb_i8_05(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_05(i8 %rA, i8 %rB, i8 %rC) { %C = and i8 %rC, %rB %A = xor i8 %rC, -1 %B = and i8 %rA, %A @@ -542,7 +542,7 @@ define i8 @selb_i8_05(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and rB, rC), (and rA, (not rC))) -define i8 @selb_i8_06(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_06(i8 %rA, i8 %rB, i8 %rC) { %C = and i8 %rB, %rC %A = xor i8 %rC, -1 %B = and i8 %rA, %A @@ -551,7 +551,7 @@ define i8 @selb_i8_06(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and rA, (not rC)), (and rB, rC)) -define i8 @selb_i8_07(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_07(i8 %rA, i8 %rB, i8 %rC) { %A = xor i8 %rC, -1 %B = and i8 %rA, %A %C = and i8 %rB, %rC @@ -560,7 +560,7 @@ define i8 @selb_i8_07(i8 %rA, i8 %rB, i8 %rC) { } ; (or (and rA, (not rC)), (and rC, rB)) -define i8 @selb_i8_08(i8 %rA, i8 %rB, i8 %rC) { +define i8 @selectbits_i8_08(i8 %rA, i8 %rB, i8 %rC) { %A = xor i8 %rC, -1 %B = and i8 %rA, %A %C = and i8 %rC, %rB diff --git a/llvm/test/CodeGen/CellSPU/shift_ops.ll b/llvm/test/CodeGen/CellSPU/shift_ops.ll index 2df2f96435d3..3c26baa7c7ab 100644 --- a/llvm/test/CodeGen/CellSPU/shift_ops.ll +++ b/llvm/test/CodeGen/CellSPU/shift_ops.ll @@ -275,3 +275,9 @@ define i64 @ashr_i64_3(i64 %arg1, i32 %shift) { %2 = ashr i64 %arg1, %1 ret i64 %2 } + +define i32 @hi32_i64(i64 %arg) { + %1 = lshr i64 %arg, 32 + %2 = trunc i64 %1 to i32 + ret i32 %2 +} -- GitLab From 95b2a206ee4388f58cfdc28ec768e6c7998c80ed Mon Sep 17 00:00:00 2001 From: Scott Michel Date: Mon, 26 Jan 2009 03:37:41 +0000 Subject: [PATCH 183/682] Untabify code. llvm-svn: 62991 --- llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 4 +-- llvm/lib/Target/CellSPU/SPUISelLowering.cpp | 10 ++++---- llvm/lib/Target/CellSPU/SPUInstrInfo.cpp | 24 +++++++++--------- llvm/lib/Target/CellSPU/SPUInstrInfo.h | 8 +++--- llvm/lib/Target/CellSPU/SPUInstrInfo.td | 24 +++++++++--------- llvm/lib/Target/CellSPU/SPUMathInstr.td | 28 ++++++++++----------- 6 files changed, 49 insertions(+), 49 deletions(-) diff --git a/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index 6d7f40d5d751..63fbb6d3beea 100644 --- a/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -633,9 +633,9 @@ SPUDAGToDAGISel::DFormAddressPredicate(SDValue Op, SDValue N, SDValue &Base, } else { /* If otherwise unadorned, default to D-form address with 0 offset: */ if (Opc == ISD::CopyFromReg) { - Index = N.getOperand(1); + Index = N.getOperand(1); } else { - Index = N; + Index = N; } Base = CurDAG->getTargetConstant(0, Index.getValueType()); diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp index 6bb76d805e3f..3a399c139bd2 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp @@ -608,7 +608,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { // specified by the operand: MVT vecVT = MVT::getVectorVT(InVT, (128 / InVT.getSizeInBits())); result = DAG.getNode(SPUISD::VEC2PREFSLOT, InVT, - DAG.getNode(ISD::BIT_CONVERT, vecVT, result)); + DAG.getNode(ISD::BIT_CONVERT, vecVT, result)); // Handle extending loads by extending the scalar result: if (ExtType == ISD::SEXTLOAD) { @@ -619,7 +619,7 @@ LowerLOAD(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { unsigned NewOpc = ISD::ANY_EXTEND; if (OutVT.isFloatingPoint()) - NewOpc = ISD::FP_EXTEND; + NewOpc = ISD::FP_EXTEND; result = DAG.getNode(NewOpc, OutVT, result); } @@ -775,8 +775,8 @@ LowerSTORE(SDValue Op, SelectionDAG &DAG, const SPUSubtarget *ST) { DAG.getNode(ISD::SCALAR_TO_VECTOR, vecVT, theValue); result = DAG.getNode(SPUISD::SHUFB, vecVT, - vectorizeOp, alignLoadVec, - DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp)); + vectorizeOp, alignLoadVec, + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, insertEltOp)); result = DAG.getStore(the_chain, result, basePtr, LN->getSrcValue(), LN->getSrcValueOffset(), @@ -2094,7 +2094,7 @@ static SDValue LowerINSERT_VECTOR_ELT(SDValue Op, SelectionDAG &DAG) { DAG.getNode(SPUISD::SHUFB, VT, DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, ValOp), VecOp, - DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask)); + DAG.getNode(ISD::BIT_CONVERT, MVT::v4i32, ShufMask)); return result; } diff --git a/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp b/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp index f35a42d71a9c..46e63893ee27 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp +++ b/llvm/lib/Target/CellSPU/SPUInstrInfo.cpp @@ -28,8 +28,8 @@ namespace { unsigned opc = I->getOpcode(); return (opc == SPU::BR - || opc == SPU::BRA - || opc == SPU::BI); + || opc == SPU::BRA + || opc == SPU::BI); } //! Predicate for a conditional branch instruction @@ -38,12 +38,12 @@ namespace { return (opc == SPU::BRNZr32 || opc == SPU::BRNZv4i32 - || opc == SPU::BRZr32 - || opc == SPU::BRZv4i32 - || opc == SPU::BRHNZr16 - || opc == SPU::BRHNZv8i16 - || opc == SPU::BRHZr16 - || opc == SPU::BRHZv8i16); + || opc == SPU::BRZr32 + || opc == SPU::BRZv4i32 + || opc == SPU::BRHNZr16 + || opc == SPU::BRHNZv8i16 + || opc == SPU::BRHZr16 + || opc == SPU::BRHZv8i16); } } @@ -531,8 +531,8 @@ SPUInstrInfo::foldMemoryOperandImpl(MachineFunction &MF, */ bool SPUInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, - MachineBasicBlock *&FBB, - SmallVectorImpl &Cond) const { + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond) const { // If the block has no terminators, it just falls into the block after it. MachineBasicBlock::iterator I = MBB.end(); if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) @@ -621,8 +621,8 @@ SPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { unsigned SPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl &Cond) const { + MachineBasicBlock *FBB, + const SmallVectorImpl &Cond) const { // Shouldn't be a fall through. assert(TBB && "InsertBranch must not be told to insert a fallthrough"); assert((Cond.size() == 2 || Cond.size() == 0) && diff --git a/llvm/lib/Target/CellSPU/SPUInstrInfo.h b/llvm/lib/Target/CellSPU/SPUInstrInfo.h index 7bbdfada12c7..0ec3b5ffa13b 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrInfo.h +++ b/llvm/lib/Target/CellSPU/SPUInstrInfo.h @@ -103,14 +103,14 @@ namespace llvm { bool ReverseBranchCondition(SmallVectorImpl &Cond) const; virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, - MachineBasicBlock *&FBB, - SmallVectorImpl &Cond) const; + MachineBasicBlock *&FBB, + SmallVectorImpl &Cond) const; virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const; virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, - MachineBasicBlock *FBB, - const SmallVectorImpl &Cond) const; + MachineBasicBlock *FBB, + const SmallVectorImpl &Cond) const; }; } diff --git a/llvm/lib/Target/CellSPU/SPUInstrInfo.td b/llvm/lib/Target/CellSPU/SPUInstrInfo.td index 8db2fa7fced3..05b31bbc21eb 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrInfo.td +++ b/llvm/lib/Target/CellSPU/SPUInstrInfo.td @@ -624,25 +624,25 @@ defm A : AddInstruction; class AIInst pattern>: RI10Form<0b00111000, OOL, IOL, - "ai\t$rT, $rA, $val", IntegerOp, - pattern>; + "ai\t$rT, $rA, $val", IntegerOp, + pattern>; class AIVecInst: AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>; + [(set (vectype VECREG:$rT), (add (vectype VECREG:$rA), immpred:$val))]>; class AIFPVecInst: AIInst<(outs VECREG:$rT), (ins VECREG:$rA, s10imm:$val), - [/* no pattern */]>; + [/* no pattern */]>; class AIRegInst: AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val), - [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>; + [(set rclass:$rT, (add rclass:$rA, immpred:$val))]>; // This is used to add epsilons to floating point numbers in the f32 fdiv code: class AIFPInst: AIInst<(outs rclass:$rT), (ins rclass:$rA, s10imm_i32:$val), - [/* no pattern */]>; + [/* no pattern */]>; multiclass AddImmediate { def v4i32: AIVecInst; @@ -1969,11 +1969,11 @@ multiclass SelectBits def v2i64_vcond: SELBVecCondInst; def v4f32_cond: - SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), - [(set (v4f32 VECREG:$rT), - (select (v4i32 VECREG:$rC), - (v4f32 VECREG:$rB), - (v4f32 VECREG:$rA)))]>; + SELBInst<(outs VECREG:$rT), (ins VECREG:$rA, VECREG:$rB, VECREG:$rC), + [(set (v4f32 VECREG:$rT), + (select (v4i32 VECREG:$rC), + (v4f32 VECREG:$rB), + (v4f32 VECREG:$rA)))]>; // SELBr64_cond is defined in SPU64InstrInfo.td def r32_cond: SELBRegCondInst; @@ -3260,7 +3260,7 @@ multiclass CmpGtrWordImm (v4i32 v4i32SExt16Imm:$val)))]>; def f32: CGTIInst<(outs R32C:$rT), (ins R32FP:$rA, s10imm_i32:$val), - [/* no pattern */]>; + [/* no pattern */]>; } class CLGTBInst pattern> : diff --git a/llvm/lib/Target/CellSPU/SPUMathInstr.td b/llvm/lib/Target/CellSPU/SPUMathInstr.td index 64548fd8c087..80ebde3ef259 100644 --- a/llvm/lib/Target/CellSPU/SPUMathInstr.td +++ b/llvm/lib/Target/CellSPU/SPUMathInstr.td @@ -66,15 +66,15 @@ def Interpf32: CodeFrag<(FIf32 R32FP:$rB, (FRESTf32 R32FP:$rB))>; def DivEstf32: CodeFrag<(FMf32 R32FP:$rA, Interpf32.Fragment)>; // Newton-Raphson iteration def NRaphf32: CodeFrag<(FMAf32 (FNMSf32 DivEstf32.Fragment, R32FP:$rB, R32FP:$rA), - Interpf32.Fragment, - DivEstf32.Fragment)>; + Interpf32.Fragment, + DivEstf32.Fragment)>; // Epsilon addition def Epsilonf32: CodeFrag<(AIf32 NRaphf32.Fragment, 1)>; def : Pat<(fdiv R32FP:$rA, R32FP:$rB), - (SELBf32_cond NRaphf32.Fragment, - Epsilonf32.Fragment, - (CGTIf32 (FNMSf32 R32FP:$rB, Epsilonf32.Fragment, R32FP:$rA), -1))>; + (SELBf32_cond NRaphf32.Fragment, + Epsilonf32.Fragment, + (CGTIf32 (FNMSf32 R32FP:$rB, Epsilonf32.Fragment, R32FP:$rA), -1))>; // Reciprocal estimate and interpolation def Interpv4f32: CodeFrag<(FIv4f32 (v4f32 VECREG:$rB), (FRESTv4f32 (v4f32 VECREG:$rB)))>; @@ -82,16 +82,16 @@ def Interpv4f32: CodeFrag<(FIv4f32 (v4f32 VECREG:$rB), (FRESTv4f32 (v4f32 VECREG def DivEstv4f32: CodeFrag<(FMv4f32 (v4f32 VECREG:$rA), Interpv4f32.Fragment)>; // Newton-Raphson iteration def NRaphv4f32: CodeFrag<(FMAv4f32 (FNMSv4f32 DivEstv4f32.Fragment, - (v4f32 VECREG:$rB), - (v4f32 VECREG:$rA)), - Interpv4f32.Fragment, - DivEstv4f32.Fragment)>; + (v4f32 VECREG:$rB), + (v4f32 VECREG:$rA)), + Interpv4f32.Fragment, + DivEstv4f32.Fragment)>; // Epsilon addition def Epsilonv4f32: CodeFrag<(AIv4f32 NRaphv4f32.Fragment, 1)>; def : Pat<(fdiv (v4f32 VECREG:$rA), (v4f32 VECREG:$rB)), - (SELBv4f32_cond NRaphv4f32.Fragment, - Epsilonv4f32.Fragment, - (CGTIv4f32 (FNMSv4f32 (v4f32 VECREG:$rB), - Epsilonv4f32.Fragment, - (v4f32 VECREG:$rA)), -1))>; + (SELBv4f32_cond NRaphv4f32.Fragment, + Epsilonv4f32.Fragment, + (CGTIv4f32 (FNMSv4f32 (v4f32 VECREG:$rB), + Epsilonv4f32.Fragment, + (v4f32 VECREG:$rA)), -1))>; -- GitLab From dd9babc79a82804010381912d879eafbf4d8fe1a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 03:46:22 +0000 Subject: [PATCH 184/682] Only resolve a macro's instantiation loc once per macro, instead of once per token lexed from it. This speeds up clang on c99-intconst-1.c from the GCC testsuite from 3.64s to 2.66s (36%). This reduces the number of binary search FileID lookups from 251570522 to 114175649 on this testcase. llvm-svn: 62992 --- clang/lib/Lex/TokenLexer.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index ea4ce669d1d9..3707ef1ed6f0 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -31,7 +31,14 @@ void TokenLexer::Init(Token &Tok, MacroArgs *Actuals) { Macro = PP.getMacroInfo(Tok.getIdentifierInfo()); ActualArgs = Actuals; CurToken = 0; + InstantiateLoc = Tok.getLocation(); + + // If the instantiation loc is not already a FileID, resolve it here. If we + // don't do this, we end up doing it once per token lexed. + if (!InstantiateLoc.isFileID()) + InstantiateLoc = PP.getSourceManager().getInstantiationLoc(InstantiateLoc); + AtStartOfLine = Tok.isAtStartOfLine(); HasLeadingSpace = Tok.hasLeadingSpace(); Tokens = &*Macro->tokens_begin(); -- GitLab From 5a5d67101b71577a89a1a3ee89f1b85994d83304 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 04:06:48 +0000 Subject: [PATCH 185/682] Eagerly resolve the spelling location of the tokens in a definition of a macro. Since these tokens may themselves be from macro expansions, we need to resolve down to the spelling loc when the macro ends up being instantiated. Instead of resolving this for each token expanded from the macro definition, just do it once when the macro is defined. This speeds up clang on c99-intconst-1.c from 2.66s to 2.43s (9.5%), reducing the FileID lookups from 407244 linear and 114175649 binary to 2529040 linear and 64771121 binary. llvm-svn: 62993 --- clang/lib/Lex/PPDirectives.cpp | 12 ++++++++++++ clang/lib/Lex/PPMacroExpansion.cpp | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index ef26aeb79a6c..ec5b67fb788e 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -991,6 +991,12 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { if (MI->isObjectLike()) { // Object-like macros are very simple, just read their body. while (Tok.isNot(tok::eom)) { + // If this token has a virtual location, resolve it down to its spelling + // location. This is not strictly needed, but avoids extra resolutions + // for macros that are expanded frequently. + if (!Tok.getLocation().isFileID()) + Tok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); + MI->AddTokenToBody(Tok); // Get the next token of the macro. LexUnexpandedToken(Tok); @@ -1000,6 +1006,12 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { // Otherwise, read the body of a function-like macro. This has to validate // the # (stringize) operator. while (Tok.isNot(tok::eom)) { + // If this token has a virtual location, resolve it down to its spelling + // location. This is not strictly needed, but avoids extra resolutions + // for macros that are expanded frequently. + if (!Tok.getLocation().isFileID()) + Tok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); + MI->AddTokenToBody(Tok); // Check C99 6.10.3.2p1: ensure that # operators are followed by macro diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 63caafaf5048..518c84e8c38a 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -340,6 +340,12 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, if (!MI->isEnabled()) Tok.setFlag(Token::DisableExpand); } + + // If this token has instantiation location, resolve it down to its + // spelling location. This is not strictly needed, but avoids extra + // resolutions for macros that are expanded frequently. + if (!Tok.getLocation().isFileID()) + Tok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); ArgTokens.push_back(Tok); } -- GitLab From ad13cf4e7a3ca27f2303156ee15c6eb06430cbde Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 04:33:10 +0000 Subject: [PATCH 186/682] eagerly resolve the spelling locations of macro argument preexpansions. This reduces fsyntax-only time on c99-intconst-1.c from 2.43s down to 2.01s (20%), reducing the number of fileid lookups from 2529040 linear and 64771121 binary to 5625902 linear and 4151182 binary. This knocks getFileID down to only 4.6% of compile time on this testcase. At this point, malloc/free is over 35% of compile time, primarily allocating MacroArgs objects and their argument preexpansion vectors. I don't feel like malloc avoiding right now, so I'm just going to call this good. llvm-svn: 62994 --- clang/lib/Lex/MacroArgs.cpp | 11 +++++++++-- clang/lib/Lex/PPMacroExpansion.cpp | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp index b634f6a62cb7..77c96e0ab33f 100644 --- a/clang/lib/Lex/MacroArgs.cpp +++ b/clang/lib/Lex/MacroArgs.cpp @@ -23,7 +23,7 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI, unsigned NumToks, bool VarargsElided) { assert(MI->isFunctionLike() && "Can't have args for an object-like macro!"); - + // Allocate memory for the MacroArgs object with the lexer tokens at the end. MacroArgs *Result = (MacroArgs*)malloc(sizeof(MacroArgs) + NumToks*sizeof(Token)); @@ -118,7 +118,14 @@ MacroArgs::getPreExpArgument(unsigned Arg, Preprocessor &PP) { // Lex all of the macro-expanded tokens into Result. do { Result.push_back(Token()); - PP.Lex(Result.back()); + Token &Tok = Result.back(); + PP.Lex(Tok); + + // Eagerly resolve instantiation ID's to their spelling location. This + // makes it so we only have to get the spelling loc once per macro argument + // preexpansion instead of once per each time the token is expanded. + if (!Tok.getLocation().isFileID()) + Tok.setLocation(PP.getSourceManager().getSpellingLoc(Tok.getLocation())); } while (Result.back().isNot(tok::eof)); // Pop the token stream off the top of the stack. We know that the internal diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 518c84e8c38a..b14df735ad1c 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -359,7 +359,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, Token EOFTok; EOFTok.startToken(); EOFTok.setKind(tok::eof); - EOFTok.setLocation(Tok.getLocation()); + EOFTok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); EOFTok.setLength(0); ArgTokens.push_back(EOFTok); ++NumActuals; -- GitLab From 8e4ac9b71ab2bd9149b9d27b4f76b9065f957786 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 26 Jan 2009 04:35:06 +0000 Subject: [PATCH 187/682] Take the next steps in making SDUse more consistent with LLVM Use, and tidy up SDUse and related code. - Replace the operator= member functions with a set method, like LLVM Use has, and variants setInitial and setNode, which take care up updating use lists, like LLVM Use's does. This simplifies code that calls these functions. - getSDValue() is renamed to get(), as in LLVM Use, though most places can either use the implicit conversion to SDValue or the convenience functions instead. - Fix some more node vs. value terminology issues. Also, eliminate the one remaining use of SDOperandPtr, and SDOperandPtr itself. llvm-svn: 62995 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 339 +++++++++--------- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 2 +- .../CodeGen/SelectionDAG/LegalizeTypes.cpp | 2 +- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 143 ++++---- llvm/lib/Target/X86/X86ISelLowering.cpp | 18 +- 5 files changed, 238 insertions(+), 266 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index a429855a9d21..7a5cd3b43eed 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -955,63 +955,77 @@ template<> struct simplify_type { } }; -/// SDUse - Represents a use of the SDNode referred by -/// the SDValue. +/// SDUse - Represents a use of a SDNode. This class holds an SDValue, +/// which records the SDNode being used and the result number, a +/// pointer to the SDNode using the value, and Next and Prev pointers, +/// which link together all the uses of an SDNode. +/// class SDUse { - SDValue Operand; - /// User - Parent node of this operand. - SDNode *User; - /// Prev, next - Pointers to the uses list of the SDNode referred by + /// Val - The value being used. + SDValue Val; + /// User - The user of this value. + SDNode *User; + /// Prev, Next - Pointers to the uses list of the SDNode referred by /// this operand. SDUse **Prev, *Next; -public: - friend class SDNode; - SDUse(): Operand(), User(NULL), Prev(NULL), Next(NULL) {} - SDUse(SDNode *val, unsigned resno) : - Operand(val,resno), User(NULL), Prev(NULL), Next(NULL) {} - - SDUse& operator= (const SDValue& Op) { - Operand = Op; - Next = NULL; - Prev = NULL; - return *this; - } + SDUse(const SDUse &U); // Do not implement + void operator=(const SDUse &U); // Do not implement - SDUse& operator= (const SDUse& Op) { - Operand = Op; - Next = NULL; - Prev = NULL; - return *this; - } +public: + SDUse() : Val(), User(NULL), Prev(NULL), Next(NULL) {} - SDUse *getNext() { return Next; } + /// Normally SDUse will just implicitly convert to an SDValue that it holds. + operator const SDValue&() const { return Val; } + /// If implicit conversion to SDValue doesn't work, the get() method returns + /// the SDValue. + const SDValue &get() const { return Val; } + + /// getUser - This returns the SDNode that contains this Use. SDNode *getUser() { return User; } - void setUser(SDNode *p) { User = p; } - - operator SDValue() const { return Operand; } + /// getNext - Get the next SDUse in the use list. + SDUse *getNext() const { return Next; } - const SDValue& getSDValue() const { return Operand; } + /// getNode - Convenience function for get().getNode(). + SDNode *getNode() const { return Val.getNode(); } + /// getResNo - Convenience function for get().getResNo(). + unsigned getResNo() const { return Val.getResNo(); } + /// getValueType - Convenience function for get().getValueType(). + MVT getValueType() const { return Val.getValueType(); } - SDValue &getSDValue() { return Operand; } - SDNode *getVal() { return Operand.getNode(); } - SDNode *getVal() const { return Operand.getNode(); } // FIXME: const correct? - - bool operator==(const SDValue &O) const { - return Operand == O; + /// operator== - Convenience function for get().operator== + bool operator==(const SDValue &V) const { + return Val == V; } - - bool operator!=(const SDValue &O) const { - return !(Operand == O); + + /// operator!= - Convenience function for get().operator!= + bool operator!=(const SDValue &V) const { + return Val != V; } - bool operator<(const SDValue &O) const { - return Operand < O; + /// operator< - Convenience function for get().operator< + bool operator<(const SDValue &V) const { + return Val < V; } -protected: +private: + friend class SelectionDAG; + friend class SDNode; + + void setUser(SDNode *p) { User = p; } + + /// set - Remove this use from its existing use list, assign it the + /// given value, and add it to the new value's node's use list. + inline void set(const SDValue &V); + /// setInitial - like set, but only supports initializing a newly-allocated + /// SDUse with a non-null value. + inline void setInitial(const SDValue &V); + /// setNode - like set, but only sets the Node portion of the value, + /// leaving the ResNo portion unmodified. + inline void setNode(SDNode *N); + void addToList(SDUse **List) { Next = *List; if (Next) Next->Prev = &Next; @@ -1025,61 +1039,22 @@ protected: } }; - /// simplify_type specializations - Allow casting operators to work directly on /// SDValues as if they were SDNode*'s. template<> struct simplify_type { typedef SDNode* SimpleType; static SimpleType getSimplifiedValue(const SDUse &Val) { - return static_cast(Val.getVal()); + return static_cast(Val.getNode()); } }; template<> struct simplify_type { typedef SDNode* SimpleType; static SimpleType getSimplifiedValue(const SDUse &Val) { - return static_cast(Val.getVal()); + return static_cast(Val.getNode()); } }; -/// SDOperandPtr - A helper SDValue pointer class, that can handle -/// arrays of SDUse and arrays of SDValue objects. This is required -/// in many places inside the SelectionDAG. -/// -class SDOperandPtr { - const SDValue *ptr; // The pointer to the SDValue object - int object_size; // The size of the object containg the SDValue -public: - SDOperandPtr() : ptr(0), object_size(0) {} - - SDOperandPtr(SDUse * use_ptr) { - ptr = &use_ptr->getSDValue(); - object_size = (int)sizeof(SDUse); - } - - SDOperandPtr(const SDValue * op_ptr) { - ptr = op_ptr; - object_size = (int)sizeof(SDValue); - } - - const SDValue operator *() { return *ptr; } - const SDValue *operator ->() { return ptr; } - SDOperandPtr operator ++ () { - ptr = (SDValue*)((char *)ptr + object_size); - return *this; - } - - SDOperandPtr operator ++ (int) { - SDOperandPtr tmp = *this; - ptr = (SDValue*)((char *)ptr + object_size); - return tmp; - } - - SDValue operator[] (int idx) const { - return *(SDValue*)((char*) ptr + object_size * idx); - } -}; - /// SDNode - Represents one node in the SelectionDAG. /// class SDNode : public FoldingSetNode, public ilist_node { @@ -1113,11 +1088,14 @@ private: /// NumOperands/NumValues - The number of entries in the Operand/Value list. unsigned short NumOperands, NumValues; - /// Uses - List of uses for this SDNode. - SDUse *Uses; + /// UseList - List of uses for this SDNode. + SDUse *UseList; - /// addUse - add SDUse to the list of uses. - void addUse(SDUse &U) { U.addToList(&Uses); } + /// getValueTypeList - Return a pointer to the specified value type. + static const MVT *getValueTypeList(MVT VT); + + friend class SelectionDAG; + friend struct ilist_traits; public: //===--------------------------------------------------------------------===// @@ -1148,7 +1126,7 @@ public: /// use_empty - Return true if there are no uses of this node. /// - bool use_empty() const { return Uses == NULL; } + bool use_empty() const { return UseList == NULL; } /// hasOneUse - Return true if there is exactly one use of this node. /// @@ -1226,7 +1204,7 @@ public: /// of an SDNode. use_iterator use_begin() const { - return use_iterator(Uses); + return use_iterator(UseList); } static use_iterator use_end() { return use_iterator(0); } @@ -1265,14 +1243,13 @@ public: const SDValue &getOperand(unsigned Num) const { assert(Num < NumOperands && "Invalid child # of SDNode!"); - return OperandList[Num].getSDValue(); + return OperandList[Num]; } typedef SDUse* op_iterator; op_iterator op_begin() const { return OperandList; } op_iterator op_end() const { return OperandList+NumOperands; } - SDVTList getVTList() const { SDVTList X = { ValueList, NumValues }; return X; @@ -1339,13 +1316,11 @@ public: /// void Profile(FoldingSetNodeID &ID) const; -protected: - friend class SelectionDAG; - friend struct ilist_traits; - - /// getValueTypeList - Return a pointer to the specified value type. + /// addUse - This method should only be used by the SDUse class. /// - static const MVT *getValueTypeList(MVT VT); + void addUse(SDUse &U) { U.addToList(&UseList); } + +protected: static SDVTList getSDVTList(MVT VT) { SDVTList Ret = { getValueTypeList(VT), 1 }; return Ret; @@ -1353,77 +1328,84 @@ protected: SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), Uses(NULL) { - NumOperands = NumOps; - OperandList = NumOps ? new SDUse[NumOperands] : 0; - + NodeId(-1), + OperandList(NumOps ? new SDUse[NumOps] : 0), + ValueList(VTs.VTs), + NumOperands(NumOps), NumValues(VTs.NumVTs), + UseList(NULL) { for (unsigned i = 0; i != NumOps; ++i) { - OperandList[i] = Ops[i]; OperandList[i].setUser(this); - Ops[i].getNode()->addUse(OperandList[i]); + OperandList[i].setInitial(Ops[i]); } - - ValueList = VTs.VTs; - NumValues = VTs.NumVTs; - } - - SDNode(unsigned Opc, SDVTList VTs, const SDUse *Ops, unsigned NumOps) - : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), Uses(NULL) { - OperandsNeedDelete = true; - NumOperands = NumOps; - OperandList = NumOps ? new SDUse[NumOperands] : 0; - - for (unsigned i = 0; i != NumOps; ++i) { - OperandList[i] = Ops[i]; - OperandList[i].setUser(this); - Ops[i].getVal()->addUse(OperandList[i]); - } - - ValueList = VTs.VTs; - NumValues = VTs.NumVTs; } /// This constructor adds no operands itself; operands can be /// set later with InitOperands. SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), - NodeId(-1), Uses(NULL) { - NumOperands = 0; - OperandList = 0; - ValueList = VTs.VTs; - NumValues = VTs.NumVTs; - } + NodeId(-1), OperandList(0), ValueList(VTs.VTs), + NumOperands(0), NumValues(VTs.NumVTs), + UseList(NULL) {} - /// InitOperands - Initialize the operands list of this node with the - /// specified values, which are part of the node (thus they don't need to be - /// copied in or allocated). - void InitOperands(SDUse *Ops, unsigned NumOps) { - assert(OperandList == 0 && "Operands already set!"); - NumOperands = NumOps; + /// InitOperands - Initialize the operands list of this with 1 operand. + void InitOperands(SDUse *Ops, const SDValue &Op0) { + Ops[0].setUser(this); + Ops[0].setInitial(Op0); + NumOperands = 1; OperandList = Ops; - Uses = NULL; - - for (unsigned i = 0; i != NumOps; ++i) { - OperandList[i].setUser(this); - Ops[i].getVal()->addUse(OperandList[i]); + } + + /// InitOperands - Initialize the operands list of this with 2 operands. + void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1) { + Ops[0].setUser(this); + Ops[0].setInitial(Op0); + Ops[1].setUser(this); + Ops[1].setInitial(Op1); + NumOperands = 2; + OperandList = Ops; + } + + /// InitOperands - Initialize the operands list of this with 3 operands. + void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1, + const SDValue &Op2) { + Ops[0].setUser(this); + Ops[0].setInitial(Op0); + Ops[1].setUser(this); + Ops[1].setInitial(Op1); + Ops[2].setUser(this); + Ops[2].setInitial(Op2); + NumOperands = 3; + OperandList = Ops; + } + + /// InitOperands - Initialize the operands list of this with 4 operands. + void InitOperands(SDUse *Ops, const SDValue &Op0, const SDValue &Op1, + const SDValue &Op2, const SDValue &Op3) { + Ops[0].setUser(this); + Ops[0].setInitial(Op0); + Ops[1].setUser(this); + Ops[1].setInitial(Op1); + Ops[2].setUser(this); + Ops[2].setInitial(Op2); + Ops[3].setUser(this); + Ops[3].setInitial(Op3); + NumOperands = 4; + OperandList = Ops; + } + + /// InitOperands - Initialize the operands list of this with N operands. + void InitOperands(SDUse *Ops, const SDValue *Vals, unsigned N) { + for (unsigned i = 0; i != N; ++i) { + Ops[i].setUser(this); + Ops[i].setInitial(Vals[i]); } + NumOperands = N; + OperandList = Ops; } /// DropOperands - Release the operands and set this node to have /// zero operands. void DropOperands(); - - void addUser(unsigned i, SDNode *User) { - assert(User->OperandList[i].getUser() && "Node without parent"); - addUse(User->OperandList[i]); - } - - void removeUser(unsigned i, SDNode *User) { - assert(User->OperandList[i].getUser() && "Node without parent"); - SDUse &Op = User->OperandList[i]; - Op.removeFromList(); - } }; @@ -1460,6 +1442,25 @@ inline bool SDValue::hasOneUse() const { return Node->hasNUsesOfValue(1, ResNo); } +// Define inline functions from the SDUse class. + +inline void SDUse::set(const SDValue &V) { + if (Val.getNode()) removeFromList(); + Val = V; + if (V.getNode()) V.getNode()->addUse(*this); +} + +inline void SDUse::setInitial(const SDValue &V) { + Val = V; + V.getNode()->addUse(*this); +} + +inline void SDUse::setNode(SDNode *N) { + if (Val.getNode()) removeFromList(); + Val.setNode(N); + if (N) N->addUse(*this); +} + /// UnarySDNode - This class is used for single-operand SDNodes. This is solely /// to allow co-allocation of node operands with the node itself. class UnarySDNode : public SDNode { @@ -1467,8 +1468,7 @@ class UnarySDNode : public SDNode { public: UnarySDNode(unsigned Opc, SDVTList VTs, SDValue X) : SDNode(Opc, VTs) { - Op = X; - InitOperands(&Op, 1); + InitOperands(&Op, X); } }; @@ -1479,9 +1479,7 @@ class BinarySDNode : public SDNode { public: BinarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y) : SDNode(Opc, VTs) { - Ops[0] = X; - Ops[1] = Y; - InitOperands(Ops, 2); + InitOperands(Ops, X, Y); } }; @@ -1493,10 +1491,7 @@ public: TernarySDNode(unsigned Opc, SDVTList VTs, SDValue X, SDValue Y, SDValue Z) : SDNode(Opc, VTs) { - Ops[0] = X; - Ops[1] = Y; - Ops[2] = Z; - InitOperands(Ops, 3); + InitOperands(Ops, X, Y, Z); } }; @@ -1516,11 +1511,10 @@ public: explicit HandleSDNode(SDValue X) #endif : SDNode(ISD::HANDLENODE, getSDVTList(MVT::Other)) { - Op = X; - InitOperands(&Op, 1); + InitOperands(&Op, X); } ~HandleSDNode(); - const SDValue &getValue() const { return Op.getSDValue(); } + const SDValue &getValue() const { return Op; } }; /// Abstact virtual class for operations for memory operations @@ -1617,21 +1611,14 @@ public: unsigned Align=0) : MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0, Align, /*isVolatile=*/true) { - Ops[0] = Chain; - Ops[1] = Ptr; - Ops[2] = Cmp; - Ops[3] = Swp; - InitOperands(Ops, 4); + InitOperands(Ops, Chain, Ptr, Cmp, Swp); } AtomicSDNode(unsigned Opc, SDVTList VTL, MVT MemVT, SDValue Chain, SDValue Ptr, SDValue Val, const Value* SrcVal, unsigned Align=0) : MemSDNode(Opc, VTL, MemVT, SrcVal, /*SVOffset=*/0, Align, /*isVolatile=*/true) { - Ops[0] = Chain; - Ops[1] = Ptr; - Ops[2] = Val; - InitOperands(Ops, 3); + InitOperands(Ops, Chain, Ptr, Val); } const SDValue &getBasePtr() const { return getOperand(1); } @@ -1979,8 +1966,7 @@ protected: Value *cu) : SDNode(ISD::DBG_STOPPOINT, getSDVTList(MVT::Other)), Line(l), Column(c), CU(cu) { - Chain = ch; - InitOperands(&Chain, 1); + InitOperands(&Chain, ch); } public: unsigned getLine() const { return Line; } @@ -2000,8 +1986,7 @@ protected: friend class SelectionDAG; LabelSDNode(unsigned NodeTy, SDValue ch, unsigned id) : SDNode(NodeTy, getSDVTList(MVT::Other)), LabelID(id) { - Chain = ch; - InitOperands(&Chain, 1); + InitOperands(&Chain, ch); } public: unsigned getLabelID() const { return LabelID; } @@ -2256,9 +2241,7 @@ public: const Value *SV, int SVO, unsigned Align, bool Vol) : MemSDNode(NodeTy, VTs, VT, SV, SVO, Align, Vol) { SubclassData = AM; - for (unsigned i = 0; i != numOperands; ++i) - Ops[i] = Operands[i]; - InitOperands(Ops, numOperands); + InitOperands(Ops, Operands, numOperands); assert(Align != 0 && "Loads and stores should have non-zero aligment"); assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) && "Only indexed loads and stores have a non-undef offset operand"); diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e4b24f1aaff6..d1759c1ab0e3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4138,7 +4138,7 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) { // If this is fp_round(fpextend), don't fold it, allow ourselves to be folded. if (N->hasOneUse() && - N->use_begin().getUse().getSDValue().getOpcode() == ISD::FP_ROUND) + N->use_begin()->getOpcode() == ISD::FP_ROUND) return SDValue(); // fold (fp_extend c1fp) -> c1fp diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index a4f3917b18a6..4c5dd030c7a1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -81,7 +81,7 @@ void DAGTypeLegalizer::PerformExpensiveChecks() { // Check that remapped values are only used by nodes marked NewNode. for (SDNode::use_iterator UI = I->use_begin(), UE = I->use_end(); UI != UE; ++UI) - if (UI.getUse().getSDValue().getResNo() == i) + if (UI.getUse().getResNo() == i) assert(UI->getNodeId() == NewNode && "Remapped value has non-trivial use!"); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index ab222c4f2faa..7fd50aca401d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -342,8 +342,8 @@ static void AddNodeIDOperands(FoldingSetNodeID &ID, static void AddNodeIDOperands(FoldingSetNodeID &ID, const SDUse *Ops, unsigned NumOps) { for (; NumOps; --NumOps, ++Ops) { - ID.AddPointer(Ops->getVal()); - ID.AddInteger(Ops->getSDValue().getResNo()); + ID.AddPointer(Ops->getNode()); + ID.AddInteger(Ops->getResNo()); } } @@ -538,8 +538,7 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl &DeadNodes, // Process the worklist, deleting the nodes and adding their uses to the // worklist. while (!DeadNodes.empty()) { - SDNode *N = DeadNodes.back(); - DeadNodes.pop_back(); + SDNode *N = DeadNodes.pop_back_val(); if (UpdateListener) UpdateListener->NodeDeleted(N, 0); @@ -549,10 +548,11 @@ void SelectionDAG::RemoveDeadNodes(SmallVectorImpl &DeadNodes, // Next, brutally remove the operand list. This is safe to do, as there are // no cycles in the graph. - for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) { - SDNode *Operand = I->getVal(); - Operand->removeUser(std::distance(N->op_begin(), I), N); - + for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) { + SDUse &Use = *I++; + SDNode *Operand = Use.getNode(); + Use.set(SDValue()); + // Now that we removed this operand, see if there are no uses of it left. if (Operand->use_empty()) DeadNodes.push_back(Operand); @@ -581,8 +581,7 @@ void SelectionDAG::DeleteNodeNotInCSEMaps(SDNode *N) { assert(N->use_empty() && "Cannot delete a node that is not dead!"); // Drop all of the operands and decrement used node's use counts. - for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) - I->getVal()->removeUser(std::distance(N->op_begin(), I), N); + N->DropOperands(); DeallocateNode(N); } @@ -763,7 +762,7 @@ void SelectionDAG::VerifyNode(SDNode *N) { // following checks at least makes it possible to legalize most of the time. // MVT EltVT = N->getValueType(0).getVectorElementType(); // for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ++I) -// assert(I->getSDValue().getValueType() == EltVT && +// assert(I->getValueType() == EltVT && // "Wrong operand type!"); break; } @@ -819,7 +818,7 @@ void SelectionDAG::clear() { std::fill(ValueTypeNodes.begin(), ValueTypeNodes.end(), static_cast(0)); - EntryNode.Uses = 0; + EntryNode.UseList = 0; AllNodes.push_back(&EntryNode); Root = getEntryNode(); } @@ -3915,9 +3914,7 @@ SDValue SelectionDAG::UpdateNodeOperands(SDValue InN, SDValue Op) { InsertPos = 0; // Now we update the operands. - N->OperandList[0].getVal()->removeUser(0, N); - N->OperandList[0].getSDValue() = Op; - Op.getNode()->addUser(0, N); + N->OperandList[0].set(Op); // If this gets put into a CSE map, add it. if (InsertPos) CSEMap.InsertNode(N, InsertPos); @@ -3944,16 +3941,10 @@ UpdateNodeOperands(SDValue InN, SDValue Op1, SDValue Op2) { InsertPos = 0; // Now we update the operands. - if (N->OperandList[0] != Op1) { - N->OperandList[0].getVal()->removeUser(0, N); - N->OperandList[0].getSDValue() = Op1; - Op1.getNode()->addUser(0, N); - } - if (N->OperandList[1] != Op2) { - N->OperandList[1].getVal()->removeUser(1, N); - N->OperandList[1].getSDValue() = Op2; - Op2.getNode()->addUser(1, N); - } + if (N->OperandList[0] != Op1) + N->OperandList[0].set(Op1); + if (N->OperandList[1] != Op2) + N->OperandList[1].set(Op2); // If this gets put into a CSE map, add it. if (InsertPos) CSEMap.InsertNode(N, InsertPos); @@ -4009,13 +4000,9 @@ UpdateNodeOperands(SDValue InN, const SDValue *Ops, unsigned NumOps) { InsertPos = 0; // Now we update the operands. - for (unsigned i = 0; i != NumOps; ++i) { - if (N->OperandList[i] != Ops[i]) { - N->OperandList[i].getVal()->removeUser(i, N); - N->OperandList[i].getSDValue() = Ops[i]; - Ops[i].getNode()->addUser(i, N); - } - } + for (unsigned i = 0; i != NumOps; ++i) + if (N->OperandList[i] != Ops[i]) + N->OperandList[i].set(Ops[i]); // If this gets put into a CSE map, add it. if (InsertPos) CSEMap.InsertNode(N, InsertPos); @@ -4027,10 +4014,10 @@ UpdateNodeOperands(SDValue InN, const SDValue *Ops, unsigned NumOps) { void SDNode::DropOperands() { // Unlike the code in MorphNodeTo that does this, we don't need to // watch for dead nodes here. - for (op_iterator I = op_begin(), E = op_end(); I != E; ++I) - I->getVal()->removeUser(std::distance(op_begin(), I), this); - - NumOperands = 0; + for (op_iterator I = op_begin(), E = op_end(); I != E; ) { + SDUse &Use = *I++; + Use.set(SDValue()); + } } /// SelectNodeTo - These are wrappers around MorphNodeTo that accept a @@ -4255,10 +4242,10 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, // Clear the operands list, updating used nodes to remove this from their // use list. Keep track of any operands that become dead as a result. SmallPtrSet DeadNodeSet; - for (SDNode::op_iterator B = N->op_begin(), I = B, E = N->op_end(); - I != E; ++I) { - SDNode *Used = I->getVal(); - Used->removeUser(std::distance(B, I), N); + for (SDNode::op_iterator I = N->op_begin(), E = N->op_end(); I != E; ) { + SDUse &Use = *I++; + SDNode *Used = Use.getNode(); + Use.set(SDValue()); if (Used->use_empty()) DeadNodeSet.insert(Used); } @@ -4284,10 +4271,8 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc, // Assign the new operands. N->NumOperands = NumOps; for (unsigned i = 0, e = NumOps; i != e; ++i) { - N->OperandList[i].getSDValue() = Ops[i]; N->OperandList[i].setUser(N); - SDNode *ToUse = N->OperandList[i].getVal(); - ToUse->addUser(i, N); + N->OperandList[i].setInitial(Ops[i]); } // Delete any nodes that are still dead after adding the uses for the @@ -4441,11 +4426,9 @@ void SelectionDAG::ReplaceAllUsesWith(SDValue FromN, SDValue To, // To help reduce the number of CSE recomputations, process all // the uses of this user that we can find this way. do { - unsigned operandNum = UI.getOperandNo(); + SDUse &Use = UI.getUse(); ++UI; - From->removeUser(operandNum, User); - User->OperandList[operandNum].getSDValue() = To; - To.getNode()->addUser(operandNum, User); + Use.set(To); } while (UI != UE && *UI == User); // Now that we have modified User, add it back to the CSE maps. If it @@ -4484,11 +4467,9 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, SDNode *To, // To help reduce the number of CSE recomputations, process all // the uses of this user that we can find this way. do { - unsigned operandNum = UI.getOperandNo(); + SDUse &Use = UI.getUse(); ++UI; - From->removeUser(operandNum, User); - User->OperandList[operandNum].getSDValue().setNode(To); - To->addUser(operandNum, User); + Use.setNode(To); } while (UI != UE && *UI == User); // Now that we have modified User, add it back to the CSE maps. If it @@ -4522,13 +4503,10 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, // To help reduce the number of CSE recomputations, process all // the uses of this user that we can find this way. do { - unsigned operandNum = UI.getOperandNo(); - const SDValue &ToOp = - To[User->OperandList[operandNum].getSDValue().getResNo()]; + SDUse &Use = UI.getUse(); + const SDValue &ToOp = To[Use.getResNo()]; ++UI; - From->removeUser(operandNum, User); - User->OperandList[operandNum].getSDValue() = ToOp; - ToOp.getNode()->addUser(operandNum, User); + Use.set(ToOp); } while (UI != UE && *UI == User); // Now that we have modified User, add it back to the CSE maps. If it @@ -4538,8 +4516,8 @@ void SelectionDAG::ReplaceAllUsesWith(SDNode *From, } /// ReplaceAllUsesOfValueWith - Replace any uses of From with To, leaving -/// uses of other values produced by From.getVal() alone. The Deleted vector is -/// handled the same way as for ReplaceAllUsesWith. +/// uses of other values produced by From.getNode() alone. The Deleted +/// vector is handled the same way as for ReplaceAllUsesWith. void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To, DAGUpdateListener *UpdateListener){ // Handle the really simple, really trivial case efficiently. @@ -4564,11 +4542,10 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To, // To help reduce the number of CSE recomputations, process all // the uses of this user that we can find this way. do { - unsigned operandNum = UI.getOperandNo(); + SDUse &Use = UI.getUse(); // Skip uses of different values from the same node. - if (User->OperandList[operandNum].getSDValue().getResNo() != - From.getResNo()) { + if (Use.getResNo() != From.getResNo()) { ++UI; continue; } @@ -4581,9 +4558,7 @@ void SelectionDAG::ReplaceAllUsesOfValueWith(SDValue From, SDValue To, } ++UI; - From.getNode()->removeUser(operandNum, User); - User->OperandList[operandNum].getSDValue() = To; - To.getNode()->addUser(operandNum, User); + Use.set(To); } while (UI != UE && *UI == User); // We are iterating over all uses of the From node, so if a use @@ -4603,13 +4578,18 @@ namespace { struct UseMemo { SDNode *User; unsigned Index; - unsigned operandNum; + SDUse *Use; }; + + /// operator< - Sort Memos by User. + bool operator<(const UseMemo &L, const UseMemo &R) { + return (intptr_t)L.User < (intptr_t)R.User; + } } /// ReplaceAllUsesOfValuesWith - Replace any uses of From with To, leaving -/// uses of other values produced by From.getVal() alone. The same value may -/// appear in both the From and To list. The Deleted vector is +/// uses of other values produced by From.getNode() alone. The same value +/// may appear in both the From and To list. The Deleted vector is /// handled the same way as for ReplaceAllUsesWith. void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From, const SDValue *To, @@ -4627,13 +4607,18 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From, unsigned FromResNo = From[i].getResNo(); SDNode *FromNode = From[i].getNode(); for (SDNode::use_iterator UI = FromNode->use_begin(), - E = FromNode->use_end(); UI != E; ++UI) - if (UI.getUse().getSDValue().getResNo() == FromResNo) { - UseMemo Memo = { *UI, i, UI.getOperandNo() }; + E = FromNode->use_end(); UI != E; ++UI) { + SDUse &Use = UI.getUse(); + if (Use.getResNo() == FromResNo) { + UseMemo Memo = { *UI, i, &Use }; Uses.push_back(Memo); } + } } + // Sort the uses, so that all the uses from a given User are together. + std::sort(Uses.begin(), Uses.end()); + for (unsigned UseIndex = 0, UseIndexEnd = Uses.size(); UseIndex != UseIndexEnd; ) { // We know that this user uses some value of From. If it is the right @@ -4643,18 +4628,16 @@ void SelectionDAG::ReplaceAllUsesOfValuesWith(const SDValue *From, // This node is about to morph, remove its old self from the CSE maps. RemoveNodeFromCSEMaps(User); - // A user can appear in a use list multiple times, and when this - // happens the uses are usually next to each other in the list. + // The Uses array is sorted, so all the uses for a given User + // are next to each other in the list. // To help reduce the number of CSE recomputations, process all // the uses of this user that we can find this way. do { unsigned i = Uses[UseIndex].Index; - unsigned operandNum = Uses[UseIndex].operandNum; + SDUse &Use = *Uses[UseIndex].Use; ++UseIndex; - From[i].getNode()->removeUser(operandNum, User); - User->OperandList[operandNum].getSDValue() = To[i]; - To[i].getNode()->addUser(operandNum, User); + Use.set(To[i]); } while (UseIndex != UseIndexEnd && Uses[UseIndex].User == User); // Now that we have modified User, add it back to the CSE maps. If it @@ -4839,7 +4822,7 @@ bool SDNode::hasNUsesOfValue(unsigned NUses, unsigned Value) const { // TODO: Only iterate over uses of a given value of the node for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) { - if (UI.getUse().getSDValue().getResNo() == Value) { + if (UI.getUse().getResNo() == Value) { if (NUses == 0) return false; --NUses; @@ -4857,7 +4840,7 @@ bool SDNode::hasAnyUseOfValue(unsigned Value) const { assert(Value < getNumValues() && "Bad value!"); for (SDNode::use_iterator UI = use_begin(), E = use_end(); UI != E; ++UI) - if (UI.getUse().getSDValue().getResNo() == Value) + if (UI.getUse().getResNo() == Value) return true; return false; @@ -4890,7 +4873,7 @@ bool SDValue::isOperandOf(SDNode *N) const { bool SDNode::isOperandOf(SDNode *N) const { for (unsigned i = 0, e = N->NumOperands; i != e; ++i) - if (this == N->OperandList[i].getVal()) + if (this == N->OperandList[i].getNode()) return true; return false; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 205a141623ab..406b2370b1c0 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -2160,7 +2160,8 @@ bool X86::isPSHUFLWMask(SDNode *N) { /// isSHUFPMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to SHUFP*. -static bool isSHUFPMask(SDOperandPtr Elems, unsigned NumElems) { +template +static bool isSHUFPMask(SDOperand *Elems, unsigned NumElems) { if (NumElems != 2 && NumElems != 4) return false; unsigned Half = NumElems / 2; @@ -2183,7 +2184,8 @@ bool X86::isSHUFPMask(SDNode *N) { /// the reverse of what x86 shuffles want. x86 shuffles requires the lower /// half elements to come from vector 1 (which would equal the dest.) and /// the upper half to come from vector 2. -static bool isCommutedSHUFP(SDOperandPtr Ops, unsigned NumOps) { +template +static bool isCommutedSHUFP(SDOperand *Ops, unsigned NumOps) { if (NumOps != 2 && NumOps != 4) return false; unsigned Half = NumOps / 2; @@ -2277,7 +2279,8 @@ bool X86::isMOVHPMask(SDNode *N) { /// isUNPCKLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to UNPCKL. -bool static isUNPCKLMask(SDOperandPtr Elts, unsigned NumElts, +template +bool static isUNPCKLMask(SDOperand *Elts, unsigned NumElts, bool V2IsSplat = false) { if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16) return false; @@ -2306,7 +2309,8 @@ bool X86::isUNPCKLMask(SDNode *N, bool V2IsSplat) { /// isUNPCKHMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to UNPCKH. -bool static isUNPCKHMask(SDOperandPtr Elts, unsigned NumElts, +template +bool static isUNPCKHMask(SDOperand *Elts, unsigned NumElts, bool V2IsSplat = false) { if (NumElts != 2 && NumElts != 4 && NumElts != 8 && NumElts != 16) return false; @@ -2382,7 +2386,8 @@ bool X86::isUNPCKH_v_undef_Mask(SDNode *N) { /// isMOVLMask - Return true if the specified VECTOR_SHUFFLE operand /// specifies a shuffle of elements that is suitable for input to MOVSS, /// MOVSD, and MOVD, i.e. setting the lowest element. -static bool isMOVLMask(SDOperandPtr Elts, unsigned NumElts) { +template +static bool isMOVLMask(SDOperand *Elts, unsigned NumElts) { if (NumElts != 2 && NumElts != 4) return false; @@ -2405,7 +2410,8 @@ bool X86::isMOVLMask(SDNode *N) { /// isCommutedMOVL - Returns true if the shuffle mask is except the reverse /// of what x86 movss want. X86 movs requires the lowest element to be lowest /// element of vector 2 and the other elements to come from vector 1 in order. -static bool isCommutedMOVL(SDOperandPtr Ops, unsigned NumOps, +template +static bool isCommutedMOVL(SDOperand *Ops, unsigned NumOps, bool V2IsSplat = false, bool V2IsUndef = false) { if (NumOps != 2 && NumOps != 4 && NumOps != 8 && NumOps != 16) -- GitLab From 5fe12615c2f0db19ce9205bd7b928b1b26cf5db2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 04:36:10 +0000 Subject: [PATCH 188/682] an insane macro testcase. llvm-svn: 62996 --- clang/c99-intconst-1.c | 639 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 639 insertions(+) create mode 100644 clang/c99-intconst-1.c diff --git a/clang/c99-intconst-1.c b/clang/c99-intconst-1.c new file mode 100644 index 000000000000..629b0bcac205 --- /dev/null +++ b/clang/c99-intconst-1.c @@ -0,0 +1,639 @@ +/* Test for integer constant types. */ + +/* Origin: Joseph Myers . */ +/* { dg-do compile } */ +/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */ + +#include + +/* Assertion that constant C is of type T. */ +#define ASSERT_CONST_TYPE(C, T) \ + do { \ + typedef T type; \ + typedef type **typepp; \ + typedef __typeof__((C)) ctype; \ + typedef ctype **ctypepp; \ + typepp x = 0; \ + ctypepp y = 0; \ + x = y; \ + y = x; \ + } while (0) + +/* (T *) if E is zero, (void *) otherwise. */ +#define type_if_not(T, E) __typeof__(0 ? (T *)0 : (void *)(E)) + +/* (T *) if E is nonzero, (void *) otherwise. */ +#define type_if(T, E) type_if_not(T, !(E)) + +/* Combine pointer types, all but one (void *). */ +#define type_comb2(T1, T2) __typeof__(0 ? (T1)0 : (T2)0) +#define type_comb3(T1, T2, T3) type_comb2(T1, type_comb2(T2, T3)) +#define type_comb4(T1, T2, T3, T4) \ + type_comb2(T1, type_comb2(T2, type_comb2(T3, T4))) +#define type_comb6(T1, T2, T3, T4, T5, T6) \ + type_comb2(T1, \ + type_comb2(T2, \ + type_comb2(T3, \ + type_comb2(T4, \ + type_comb2(T5, T6))))) + +/* (T1 *) if E1, otherwise (T2 *) if E2. */ +#define first_of2p(T1, E1, T2, E2) type_comb2(type_if(T1, (E1)), \ + type_if(T2, (!(E1) && (E2)))) +/* (T1 *) if E1, otherwise (T2 *) if E2, otherwise (T3 *) if E3. */ +#define first_of3p(T1, E1, T2, E2, T3, E3) \ + type_comb3(type_if(T1, (E1)), \ + type_if(T2, (!(E1) && (E2))), \ + type_if(T3, (!(E1) && !(E2) && (E3)))) +/* (T1 *) if E1, otherwise (T2 *) if E2, otherwise (T3 *) if E3, otherwise + (T4 *) if E4. */ +#define first_of4p(T1, E1, T2, E2, T3, E3, T4, E4) \ + type_comb4(type_if(T1, (E1)), \ + type_if(T2, (!(E1) && (E2))), \ + type_if(T3, (!(E1) && !(E2) && (E3))), \ + type_if(T4, (!(E1) && !(E2) && !(E3) && (E4)))) +/* (T1 *) if E1, otherwise (T2 *) if E2, otherwise (T3 *) if E3, otherwise + (T4 *) if E4, otherwise (T5 *) if E5, otherwise (T6 *) if E6. */ +#define first_of6p(T1, E1, T2, E2, T3, E3, T4, E4, T5, E5, T6, E6) \ + type_comb6(type_if(T1, (E1)), \ + type_if(T2, (!(E1) && (E2))), \ + type_if(T3, (!(E1) && !(E2) && (E3))), \ + type_if(T4, (!(E1) && !(E2) && !(E3) && (E4))), \ + type_if(T5, (!(E1) && !(E2) && !(E3) && !(E4) && (E5))), \ + type_if(T6, (!(E1) && !(E2) && !(E3) \ + && !(E4) && !(E5) && (E6)))) + +/* Likewise, but return the original type rather than a pointer type. */ +#define first_of2(T1, E1, T2, E2) \ + __typeof__(*((first_of2p(T1, (E1), T2, (E2)))0)) +#define first_of3(T1, E1, T2, E2, T3, E3) \ + __typeof__(*((first_of3p(T1, (E1), T2, (E2), T3, (E3)))0)) +#define first_of4(T1, E1, T2, E2, T3, E3, T4, E4) \ + __typeof__(*((first_of4p(T1, (E1), T2, (E2), T3, (E3), T4, (E4)))0)) +#define first_of6(T1, E1, T2, E2, T3, E3, T4, E4, T5, E5, T6, E6) \ + __typeof__(*((first_of6p(T1, (E1), T2, (E2), T3, (E3), \ + T4, (E4), T5, (E5), T6, (E6)))0)) + +/* Types of constants according to the C99 rules. */ +#define C99_UNSUF_DEC_TYPE(C) \ + first_of3(int, (C) <= INT_MAX, \ + long int, (C) <= LONG_MAX, \ + long long int, (C) <= LLONG_MAX) +#define C99_UNSUF_OCTHEX_TYPE(C) \ + first_of6(int, (C) <= INT_MAX, \ + unsigned int, (C) <= UINT_MAX, \ + long int, (C) <= LONG_MAX, \ + unsigned long int, (C) <= ULONG_MAX, \ + long long int, (C) <= LLONG_MAX, \ + unsigned long long int, (C) <= ULLONG_MAX) +#define C99_SUFu_TYPE(C) \ + first_of3(unsigned int, (C) <= UINT_MAX, \ + unsigned long int, (C) <= ULONG_MAX, \ + unsigned long long int, (C) <= ULLONG_MAX) +#define C99_SUFl_DEC_TYPE(C) \ + first_of2(long int, (C) <= LONG_MAX, \ + long long int, (C) <= LLONG_MAX) +#define C99_SUFl_OCTHEX_TYPE(C) \ + first_of4(long int, (C) <= LONG_MAX, \ + unsigned long int, (C) <= ULONG_MAX, \ + long long int, (C) <= LLONG_MAX, \ + unsigned long long int, (C) <= ULLONG_MAX) +#define C99_SUFul_TYPE(C) \ + first_of2(unsigned long int, (C) <= ULONG_MAX, \ + unsigned long long int, (C) <= ULLONG_MAX) +#define C99_SUFll_OCTHEX_TYPE(C) \ + first_of2(long long int, (C) <= LLONG_MAX, \ + unsigned long long int, (C) <= ULLONG_MAX) + +/* Checks that constants have correct type. */ +#define CHECK_UNSUF_DEC_TYPE(C) ASSERT_CONST_TYPE((C), C99_UNSUF_DEC_TYPE((C))) +#define CHECK_UNSUF_OCTHEX_TYPE(C) \ + ASSERT_CONST_TYPE((C), C99_UNSUF_OCTHEX_TYPE((C))) +#define CHECK_SUFu_TYPE(C) ASSERT_CONST_TYPE((C), C99_SUFu_TYPE((C))) +#define CHECK_SUFl_DEC_TYPE(C) ASSERT_CONST_TYPE((C), C99_SUFl_DEC_TYPE((C))) +#define CHECK_SUFl_OCTHEX_TYPE(C) \ + ASSERT_CONST_TYPE((C), C99_SUFl_OCTHEX_TYPE((C))) +#define CHECK_SUFul_TYPE(C) ASSERT_CONST_TYPE((C), C99_SUFul_TYPE((C))) +#define CHECK_SUFll_DEC_TYPE(C) ASSERT_CONST_TYPE((C), long long int) +#define CHECK_SUFll_OCTHEX_TYPE(C) \ + ASSERT_CONST_TYPE((C), C99_SUFll_OCTHEX_TYPE((C))) +#define CHECK_SUFull_TYPE(C) ASSERT_CONST_TYPE((C), unsigned long long int) + +/* Check a decimal value, with all suffixes. */ +#define CHECK_DEC_CONST(C) \ + CHECK_UNSUF_DEC_TYPE(C); \ + CHECK_SUFu_TYPE(C##u); \ + CHECK_SUFu_TYPE(C##U); \ + CHECK_SUFl_DEC_TYPE(C##l); \ + CHECK_SUFl_DEC_TYPE(C##L); \ + CHECK_SUFul_TYPE(C##ul); \ + CHECK_SUFul_TYPE(C##uL); \ + CHECK_SUFul_TYPE(C##Ul); \ + CHECK_SUFul_TYPE(C##UL); \ + CHECK_SUFll_DEC_TYPE(C##ll); \ + CHECK_SUFll_DEC_TYPE(C##LL); \ + CHECK_SUFull_TYPE(C##ull); \ + CHECK_SUFull_TYPE(C##uLL); \ + CHECK_SUFull_TYPE(C##Ull); \ + CHECK_SUFull_TYPE(C##ULL); + +/* Check an octal or hexadecimal value, with all suffixes. */ +#define CHECK_OCTHEX_CONST(C) \ + CHECK_UNSUF_OCTHEX_TYPE(C); \ + CHECK_SUFu_TYPE(C##u); \ + CHECK_SUFu_TYPE(C##U); \ + CHECK_SUFl_OCTHEX_TYPE(C##l); \ + CHECK_SUFl_OCTHEX_TYPE(C##L); \ + CHECK_SUFul_TYPE(C##ul); \ + CHECK_SUFul_TYPE(C##uL); \ + CHECK_SUFul_TYPE(C##Ul); \ + CHECK_SUFul_TYPE(C##UL); \ + CHECK_SUFll_OCTHEX_TYPE(C##ll); \ + CHECK_SUFll_OCTHEX_TYPE(C##LL); \ + CHECK_SUFull_TYPE(C##ull); \ + CHECK_SUFull_TYPE(C##uLL); \ + CHECK_SUFull_TYPE(C##Ull); \ + CHECK_SUFull_TYPE(C##ULL); + +#define CHECK_OCT_CONST(C) CHECK_OCTHEX_CONST(C) +#define CHECK_HEX_CONST(C) \ + CHECK_OCTHEX_CONST(0x##C); \ + CHECK_OCTHEX_CONST(0X##C); + +/* True iff "long long" is at least B bits. This presumes that (B-2)/3 is at + most 63. */ +#define LLONG_AT_LEAST(B) \ + (LLONG_MAX >> ((B)-2)/3 >> ((B)-2)/3 \ + >> ((B)-2 - ((B)-2)/3 - ((B)-2)/3)) + +#define LLONG_HAS_BITS(B) (LLONG_AT_LEAST((B)) && !LLONG_AT_LEAST((B) + 1)) + +void +foo (void) +{ + /* Decimal. */ + /* Check all 2^n and 2^n - 1 up to 2^71 - 1. */ + CHECK_DEC_CONST(1); + CHECK_DEC_CONST(2); + CHECK_DEC_CONST(3); + CHECK_DEC_CONST(4); + CHECK_DEC_CONST(7); + CHECK_DEC_CONST(8); + CHECK_DEC_CONST(15); + CHECK_DEC_CONST(16); + CHECK_DEC_CONST(31); + CHECK_DEC_CONST(32); + CHECK_DEC_CONST(63); + CHECK_DEC_CONST(64); + CHECK_DEC_CONST(127); + CHECK_DEC_CONST(128); + CHECK_DEC_CONST(255); + CHECK_DEC_CONST(256); + CHECK_DEC_CONST(511); + CHECK_DEC_CONST(512); + CHECK_DEC_CONST(1023); + CHECK_DEC_CONST(1024); + CHECK_DEC_CONST(2047); + CHECK_DEC_CONST(2048); + CHECK_DEC_CONST(4095); + CHECK_DEC_CONST(4096); + CHECK_DEC_CONST(8191); + CHECK_DEC_CONST(8192); + CHECK_DEC_CONST(16383); + CHECK_DEC_CONST(16384); + CHECK_DEC_CONST(32767); + CHECK_DEC_CONST(32768); + CHECK_DEC_CONST(65535); + CHECK_DEC_CONST(65536); + CHECK_DEC_CONST(131071); + CHECK_DEC_CONST(131072); + CHECK_DEC_CONST(262143); + CHECK_DEC_CONST(262144); + CHECK_DEC_CONST(524287); + CHECK_DEC_CONST(524288); + CHECK_DEC_CONST(1048575); + CHECK_DEC_CONST(1048576); + CHECK_DEC_CONST(2097151); + CHECK_DEC_CONST(2097152); + CHECK_DEC_CONST(4194303); + CHECK_DEC_CONST(4194304); + CHECK_DEC_CONST(8388607); + CHECK_DEC_CONST(8388608); + CHECK_DEC_CONST(16777215); + CHECK_DEC_CONST(16777216); + CHECK_DEC_CONST(33554431); + CHECK_DEC_CONST(33554432); + CHECK_DEC_CONST(67108863); + CHECK_DEC_CONST(67108864); + CHECK_DEC_CONST(134217727); + CHECK_DEC_CONST(134217728); + CHECK_DEC_CONST(268435455); + CHECK_DEC_CONST(268435456); + CHECK_DEC_CONST(536870911); + CHECK_DEC_CONST(536870912); + CHECK_DEC_CONST(1073741823); + CHECK_DEC_CONST(1073741824); + CHECK_DEC_CONST(2147483647); + CHECK_DEC_CONST(2147483648); + CHECK_DEC_CONST(4294967295); + CHECK_DEC_CONST(4294967296); + CHECK_DEC_CONST(8589934591); + CHECK_DEC_CONST(8589934592); + CHECK_DEC_CONST(17179869183); + CHECK_DEC_CONST(17179869184); + CHECK_DEC_CONST(34359738367); + CHECK_DEC_CONST(34359738368); + CHECK_DEC_CONST(68719476735); + CHECK_DEC_CONST(68719476736); + CHECK_DEC_CONST(137438953471); + CHECK_DEC_CONST(137438953472); + CHECK_DEC_CONST(274877906943); + CHECK_DEC_CONST(274877906944); + CHECK_DEC_CONST(549755813887); + CHECK_DEC_CONST(549755813888); + CHECK_DEC_CONST(1099511627775); + CHECK_DEC_CONST(1099511627776); + CHECK_DEC_CONST(2199023255551); + CHECK_DEC_CONST(2199023255552); + CHECK_DEC_CONST(4398046511103); + CHECK_DEC_CONST(4398046511104); + CHECK_DEC_CONST(8796093022207); + CHECK_DEC_CONST(8796093022208); + CHECK_DEC_CONST(17592186044415); + CHECK_DEC_CONST(17592186044416); + CHECK_DEC_CONST(35184372088831); + CHECK_DEC_CONST(35184372088832); + CHECK_DEC_CONST(70368744177663); + CHECK_DEC_CONST(70368744177664); + CHECK_DEC_CONST(140737488355327); + CHECK_DEC_CONST(140737488355328); + CHECK_DEC_CONST(281474976710655); + CHECK_DEC_CONST(281474976710656); + CHECK_DEC_CONST(562949953421311); + CHECK_DEC_CONST(562949953421312); + CHECK_DEC_CONST(1125899906842623); + CHECK_DEC_CONST(1125899906842624); + CHECK_DEC_CONST(2251799813685247); + CHECK_DEC_CONST(2251799813685248); + CHECK_DEC_CONST(4503599627370495); + CHECK_DEC_CONST(4503599627370496); + CHECK_DEC_CONST(9007199254740991); + CHECK_DEC_CONST(9007199254740992); + CHECK_DEC_CONST(18014398509481983); + CHECK_DEC_CONST(18014398509481984); + CHECK_DEC_CONST(36028797018963967); + CHECK_DEC_CONST(36028797018963968); + CHECK_DEC_CONST(72057594037927935); + CHECK_DEC_CONST(72057594037927936); + CHECK_DEC_CONST(144115188075855871); + CHECK_DEC_CONST(144115188075855872); + CHECK_DEC_CONST(288230376151711743); + CHECK_DEC_CONST(288230376151711744); + CHECK_DEC_CONST(576460752303423487); + CHECK_DEC_CONST(576460752303423488); + CHECK_DEC_CONST(1152921504606846975); + CHECK_DEC_CONST(1152921504606846976); + CHECK_DEC_CONST(2305843009213693951); + CHECK_DEC_CONST(2305843009213693952); + CHECK_DEC_CONST(4611686018427387903); + CHECK_DEC_CONST(4611686018427387904); + CHECK_DEC_CONST(9223372036854775807); +#if LLONG_AT_LEAST(65) + CHECK_DEC_CONST(9223372036854775808); + CHECK_DEC_CONST(18446744073709551615); +#endif +#if LLONG_AT_LEAST(66) + CHECK_DEC_CONST(18446744073709551616); + CHECK_DEC_CONST(36893488147419103231); +#endif +#if LLONG_AT_LEAST(67) + CHECK_DEC_CONST(36893488147419103232); + CHECK_DEC_CONST(73786976294838206463); +#endif +#if LLONG_AT_LEAST(68) + CHECK_DEC_CONST(73786976294838206464); + CHECK_DEC_CONST(147573952589676412927); +#endif +#if LLONG_AT_LEAST(69) + CHECK_DEC_CONST(147573952589676412928); + CHECK_DEC_CONST(295147905179352825855); +#endif +#if LLONG_AT_LEAST(70) + CHECK_DEC_CONST(295147905179352825856); + CHECK_DEC_CONST(590295810358705651711); +#endif +#if LLONG_AT_LEAST(71) + CHECK_DEC_CONST(590295810358705651712); + CHECK_DEC_CONST(1180591620717411303423); +#endif +#if LLONG_AT_LEAST(72) + CHECK_DEC_CONST(1180591620717411303424); + CHECK_DEC_CONST(2361183241434822606847); +#endif + /* Octal and hexadecimal. */ + /* Check all 2^n and 2^n - 1 up to 2^72 - 1. */ + CHECK_OCT_CONST(0); + CHECK_HEX_CONST(0); + CHECK_OCT_CONST(01); + CHECK_HEX_CONST(1); + CHECK_OCT_CONST(02); + CHECK_HEX_CONST(2); + CHECK_OCT_CONST(03); + CHECK_HEX_CONST(3); + CHECK_OCT_CONST(04); + CHECK_HEX_CONST(4); + CHECK_OCT_CONST(07); + CHECK_HEX_CONST(7); + CHECK_OCT_CONST(010); + CHECK_HEX_CONST(8); + CHECK_OCT_CONST(017); + CHECK_HEX_CONST(f); + CHECK_OCT_CONST(020); + CHECK_HEX_CONST(10); + CHECK_OCT_CONST(037); + CHECK_HEX_CONST(1f); + CHECK_OCT_CONST(040); + CHECK_HEX_CONST(20); + CHECK_OCT_CONST(077); + CHECK_HEX_CONST(3f); + CHECK_OCT_CONST(0100); + CHECK_HEX_CONST(40); + CHECK_OCT_CONST(0177); + CHECK_HEX_CONST(7f); + CHECK_OCT_CONST(0200); + CHECK_HEX_CONST(80); + CHECK_OCT_CONST(0377); + CHECK_HEX_CONST(ff); + CHECK_OCT_CONST(0400); + CHECK_HEX_CONST(100); + CHECK_OCT_CONST(0777); + CHECK_HEX_CONST(1ff); + CHECK_OCT_CONST(01000); + CHECK_HEX_CONST(200); + CHECK_OCT_CONST(01777); + CHECK_HEX_CONST(3ff); + CHECK_OCT_CONST(02000); + CHECK_HEX_CONST(400); + CHECK_OCT_CONST(03777); + CHECK_HEX_CONST(7ff); + CHECK_OCT_CONST(04000); + CHECK_HEX_CONST(800); + CHECK_OCT_CONST(07777); + CHECK_HEX_CONST(fff); + CHECK_OCT_CONST(010000); + CHECK_HEX_CONST(1000); + CHECK_OCT_CONST(017777); + CHECK_HEX_CONST(1fff); + CHECK_OCT_CONST(020000); + CHECK_HEX_CONST(2000); + CHECK_OCT_CONST(037777); + CHECK_HEX_CONST(3fff); + CHECK_OCT_CONST(040000); + CHECK_HEX_CONST(4000); + CHECK_OCT_CONST(077777); + CHECK_HEX_CONST(7fff); + CHECK_OCT_CONST(0100000); + CHECK_HEX_CONST(8000); + CHECK_OCT_CONST(0177777); + CHECK_HEX_CONST(ffff); + CHECK_OCT_CONST(0200000); + CHECK_HEX_CONST(10000); + CHECK_OCT_CONST(0377777); + CHECK_HEX_CONST(1ffff); + CHECK_OCT_CONST(0400000); + CHECK_HEX_CONST(20000); + CHECK_OCT_CONST(0777777); + CHECK_HEX_CONST(3ffff); + CHECK_OCT_CONST(01000000); + CHECK_HEX_CONST(40000); + CHECK_OCT_CONST(01777777); + CHECK_HEX_CONST(7ffff); + CHECK_OCT_CONST(02000000); + CHECK_HEX_CONST(80000); + CHECK_OCT_CONST(03777777); + CHECK_HEX_CONST(fffff); + CHECK_OCT_CONST(04000000); + CHECK_HEX_CONST(100000); + CHECK_OCT_CONST(07777777); + CHECK_HEX_CONST(1fffff); + CHECK_OCT_CONST(010000000); + CHECK_HEX_CONST(200000); + CHECK_OCT_CONST(017777777); + CHECK_HEX_CONST(3fffff); + CHECK_OCT_CONST(020000000); + CHECK_HEX_CONST(400000); + CHECK_OCT_CONST(037777777); + CHECK_HEX_CONST(7fffff); + CHECK_OCT_CONST(040000000); + CHECK_HEX_CONST(800000); + CHECK_OCT_CONST(077777777); + CHECK_HEX_CONST(ffffff); + CHECK_OCT_CONST(0100000000); + CHECK_HEX_CONST(1000000); + CHECK_OCT_CONST(0177777777); + CHECK_HEX_CONST(1ffffff); + CHECK_OCT_CONST(0200000000); + CHECK_HEX_CONST(2000000); + CHECK_OCT_CONST(0377777777); + CHECK_HEX_CONST(3ffffff); + CHECK_OCT_CONST(0400000000); + CHECK_HEX_CONST(4000000); + CHECK_OCT_CONST(0777777777); + CHECK_HEX_CONST(7ffffff); + CHECK_OCT_CONST(01000000000); + CHECK_HEX_CONST(8000000); + CHECK_OCT_CONST(01777777777); + CHECK_HEX_CONST(fffffff); + CHECK_OCT_CONST(02000000000); + CHECK_HEX_CONST(10000000); + CHECK_OCT_CONST(03777777777); + CHECK_HEX_CONST(1fffffff); + CHECK_OCT_CONST(04000000000); + CHECK_HEX_CONST(20000000); + CHECK_OCT_CONST(07777777777); + CHECK_HEX_CONST(3fffffff); + CHECK_OCT_CONST(010000000000); + CHECK_HEX_CONST(40000000); + CHECK_OCT_CONST(017777777777); + CHECK_HEX_CONST(7fffffff); + CHECK_OCT_CONST(020000000000); + CHECK_HEX_CONST(80000000); + CHECK_OCT_CONST(037777777777); + CHECK_HEX_CONST(ffffffff); + CHECK_OCT_CONST(040000000000); + CHECK_HEX_CONST(100000000); + CHECK_OCT_CONST(077777777777); + CHECK_HEX_CONST(1ffffffff); + CHECK_OCT_CONST(0100000000000); + CHECK_HEX_CONST(200000000); + CHECK_OCT_CONST(0177777777777); + CHECK_HEX_CONST(3ffffffff); + CHECK_OCT_CONST(0200000000000); + CHECK_HEX_CONST(400000000); + CHECK_OCT_CONST(0377777777777); + CHECK_HEX_CONST(7ffffffff); + CHECK_OCT_CONST(0400000000000); + CHECK_HEX_CONST(800000000); + CHECK_OCT_CONST(0777777777777); + CHECK_HEX_CONST(fffffffff); + CHECK_OCT_CONST(01000000000000); + CHECK_HEX_CONST(1000000000); + CHECK_OCT_CONST(01777777777777); + CHECK_HEX_CONST(1fffffffff); + CHECK_OCT_CONST(02000000000000); + CHECK_HEX_CONST(2000000000); + CHECK_OCT_CONST(03777777777777); + CHECK_HEX_CONST(3fffffffff); + CHECK_OCT_CONST(04000000000000); + CHECK_HEX_CONST(4000000000); + CHECK_OCT_CONST(07777777777777); + CHECK_HEX_CONST(7fffffffff); + CHECK_OCT_CONST(010000000000000); + CHECK_HEX_CONST(8000000000); + CHECK_OCT_CONST(017777777777777); + CHECK_HEX_CONST(ffffffffff); + CHECK_OCT_CONST(020000000000000); + CHECK_HEX_CONST(10000000000); + CHECK_OCT_CONST(037777777777777); + CHECK_HEX_CONST(1ffffffffff); + CHECK_OCT_CONST(040000000000000); + CHECK_HEX_CONST(20000000000); + CHECK_OCT_CONST(077777777777777); + CHECK_HEX_CONST(3ffffffffff); + CHECK_OCT_CONST(0100000000000000); + CHECK_HEX_CONST(40000000000); + CHECK_OCT_CONST(0177777777777777); + CHECK_HEX_CONST(7ffffffffff); + CHECK_OCT_CONST(0200000000000000); + CHECK_HEX_CONST(80000000000); + CHECK_OCT_CONST(0377777777777777); + CHECK_HEX_CONST(fffffffffff); + CHECK_OCT_CONST(0400000000000000); + CHECK_HEX_CONST(100000000000); + CHECK_OCT_CONST(0777777777777777); + CHECK_HEX_CONST(1fffffffffff); + CHECK_OCT_CONST(01000000000000000); + CHECK_HEX_CONST(200000000000); + CHECK_OCT_CONST(01777777777777777); + CHECK_HEX_CONST(3fffffffffff); + CHECK_OCT_CONST(02000000000000000); + CHECK_HEX_CONST(400000000000); + CHECK_OCT_CONST(03777777777777777); + CHECK_HEX_CONST(7fffffffffff); + CHECK_OCT_CONST(04000000000000000); + CHECK_HEX_CONST(800000000000); + CHECK_OCT_CONST(07777777777777777); + CHECK_HEX_CONST(ffffffffffff); + CHECK_OCT_CONST(010000000000000000); + CHECK_HEX_CONST(1000000000000); + CHECK_OCT_CONST(017777777777777777); + CHECK_HEX_CONST(1ffffffffffff); + CHECK_OCT_CONST(020000000000000000); + CHECK_HEX_CONST(2000000000000); + CHECK_OCT_CONST(037777777777777777); + CHECK_HEX_CONST(3ffffffffffff); + CHECK_OCT_CONST(040000000000000000); + CHECK_HEX_CONST(4000000000000); + CHECK_OCT_CONST(077777777777777777); + CHECK_HEX_CONST(7ffffffffffff); + CHECK_OCT_CONST(0100000000000000000); + CHECK_HEX_CONST(8000000000000); + CHECK_OCT_CONST(0177777777777777777); + CHECK_HEX_CONST(fffffffffffff); + CHECK_OCT_CONST(0200000000000000000); + CHECK_HEX_CONST(10000000000000); + CHECK_OCT_CONST(0377777777777777777); + CHECK_HEX_CONST(1fffffffffffff); + CHECK_OCT_CONST(0400000000000000000); + CHECK_HEX_CONST(20000000000000); + CHECK_OCT_CONST(0777777777777777777); + CHECK_HEX_CONST(3fffffffffffff); + CHECK_OCT_CONST(01000000000000000000); + CHECK_HEX_CONST(40000000000000); + CHECK_OCT_CONST(01777777777777777777); + CHECK_HEX_CONST(7fffffffffffff); + CHECK_OCT_CONST(02000000000000000000); + CHECK_HEX_CONST(80000000000000); + CHECK_OCT_CONST(03777777777777777777); + CHECK_HEX_CONST(ffffffffffffff); + CHECK_OCT_CONST(04000000000000000000); + CHECK_HEX_CONST(100000000000000); + CHECK_OCT_CONST(07777777777777777777); + CHECK_HEX_CONST(1ffffffffffffff); + CHECK_OCT_CONST(010000000000000000000); + CHECK_HEX_CONST(200000000000000); + CHECK_OCT_CONST(017777777777777777777); + CHECK_HEX_CONST(3ffffffffffffff); + CHECK_OCT_CONST(020000000000000000000); + CHECK_HEX_CONST(400000000000000); + CHECK_OCT_CONST(037777777777777777777); + CHECK_HEX_CONST(7ffffffffffffff); + CHECK_OCT_CONST(040000000000000000000); + CHECK_HEX_CONST(800000000000000); + CHECK_OCT_CONST(077777777777777777777); + CHECK_HEX_CONST(fffffffffffffff); + CHECK_OCT_CONST(0100000000000000000000); + CHECK_HEX_CONST(1000000000000000); + CHECK_OCT_CONST(0177777777777777777777); + CHECK_HEX_CONST(1fffffffffffffff); + CHECK_OCT_CONST(0200000000000000000000); + CHECK_HEX_CONST(2000000000000000); + CHECK_OCT_CONST(0377777777777777777777); + CHECK_HEX_CONST(3fffffffffffffff); + CHECK_OCT_CONST(0400000000000000000000); + CHECK_HEX_CONST(4000000000000000); + CHECK_OCT_CONST(0777777777777777777777); + CHECK_HEX_CONST(7fffffffffffffff); + CHECK_OCT_CONST(01000000000000000000000); + CHECK_HEX_CONST(8000000000000000); + CHECK_OCT_CONST(01777777777777777777777); + CHECK_HEX_CONST(ffffffffffffffff); +#if LLONG_AT_LEAST(65) + CHECK_OCT_CONST(02000000000000000000000); + CHECK_HEX_CONST(10000000000000000); + CHECK_OCT_CONST(03777777777777777777777); + CHECK_HEX_CONST(1ffffffffffffffff); +#endif +#if LLONG_AT_LEAST(66) + CHECK_OCT_CONST(04000000000000000000000); + CHECK_HEX_CONST(20000000000000000); + CHECK_OCT_CONST(07777777777777777777777); + CHECK_HEX_CONST(3ffffffffffffffff); +#endif +#if LLONG_AT_LEAST(67) + CHECK_OCT_CONST(010000000000000000000000); + CHECK_HEX_CONST(40000000000000000); + CHECK_OCT_CONST(017777777777777777777777); + CHECK_HEX_CONST(7ffffffffffffffff); +#endif +#if LLONG_AT_LEAST(68) + CHECK_OCT_CONST(020000000000000000000000); + CHECK_HEX_CONST(80000000000000000); + CHECK_OCT_CONST(037777777777777777777777); + CHECK_HEX_CONST(fffffffffffffffff); +#endif +#if LLONG_AT_LEAST(69) + CHECK_OCT_CONST(040000000000000000000000); + CHECK_HEX_CONST(100000000000000000); + CHECK_OCT_CONST(077777777777777777777777); + CHECK_HEX_CONST(1fffffffffffffffff); +#endif +#if LLONG_AT_LEAST(70) + CHECK_OCT_CONST(0100000000000000000000000); + CHECK_HEX_CONST(200000000000000000); + CHECK_OCT_CONST(0177777777777777777777777); + CHECK_HEX_CONST(3fffffffffffffffff); +#endif +#if LLONG_AT_LEAST(71) + CHECK_OCT_CONST(0200000000000000000000000); + CHECK_HEX_CONST(400000000000000000); + CHECK_OCT_CONST(0377777777777777777777777); + CHECK_HEX_CONST(7fffffffffffffffff); +#endif +#if LLONG_AT_LEAST(72) + CHECK_OCT_CONST(0400000000000000000000000); + CHECK_HEX_CONST(800000000000000000); + CHECK_OCT_CONST(0777777777777777777777777); + CHECK_HEX_CONST(ffffffffffffffffff); +#endif +} -- GitLab From d6d0619fb408e4211161adef4819490f25948e16 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 04:36:31 +0000 Subject: [PATCH 189/682] added to wrong directory llvm-svn: 62997 --- clang/{ => INPUTS}/c99-intconst-1.c | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename clang/{ => INPUTS}/c99-intconst-1.c (100%) diff --git a/clang/c99-intconst-1.c b/clang/INPUTS/c99-intconst-1.c similarity index 100% rename from clang/c99-intconst-1.c rename to clang/INPUTS/c99-intconst-1.c -- GitLab From 3537a627046fdb324419800dd72987db9138d475 Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Mon, 26 Jan 2009 04:39:00 +0000 Subject: [PATCH 190/682] Fixed optimization of combining two shuffles where the first shuffle inputs has a different number of elements than the output. llvm-svn: 62998 --- .../Scalar/InstructionCombining.cpp | 4 +++- .../Transforms/InstCombine/vec_shuffle2.ll | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/InstCombine/vec_shuffle2.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 40289eaf6bfd..7f7592840a4d 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -12179,9 +12179,11 @@ Instruction *InstCombiner::visitShuffleVectorInst(ShuffleVectorInst &SVI) { // If the result mask is equal to the src shuffle or this shuffle mask, do // the replacement. if (NewMask == LHSMask || NewMask == Mask) { + unsigned LHSInNElts = + cast(LHSSVI->getOperand(0)->getType())->getNumElements(); std::vector Elts; for (unsigned i = 0, e = NewMask.size(); i != e; ++i) { - if (NewMask[i] >= e*2) { + if (NewMask[i] >= LHSInNElts*2) { Elts.push_back(UndefValue::get(Type::Int32Ty)); } else { Elts.push_back(ConstantInt::get(Type::Int32Ty, NewMask[i])); diff --git a/llvm/test/Transforms/InstCombine/vec_shuffle2.ll b/llvm/test/Transforms/InstCombine/vec_shuffle2.ll new file mode 100644 index 000000000000..3bd8924903f8 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/vec_shuffle2.ll @@ -0,0 +1,19 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep undef | count 1 +; END. + +; Test fold of two shuffles where the first shuffle vectors inputs are a +; different length then the second. + +define void @test_cl(<4 x i8> addrspace(1)* %dest, <16 x i8> addrspace(1)* %old) nounwind { +entry: + %arrayidx = getelementptr <4 x i8> addrspace(1)* %dest, i32 0 ; <<4 x i8> addrspace(1)*> [#uses=1] + %arrayidx5 = getelementptr <16 x i8> addrspace(1)* %old, i32 0 ; <<16 x i8> addrspace(1)*> [#uses=1] + %tmp6 = load <16 x i8> addrspace(1)* %arrayidx5 ; <<16 x i8>> [#uses=1] + %tmp7 = shufflevector <16 x i8> %tmp6, <16 x i8> undef, <4 x i32> < i32 13, i32 9, i32 4, i32 13 > ; <<4 x i8>> [#uses=1] + %tmp9 = shufflevector <4 x i8> %tmp7, <4 x i8> undef, <4 x i32> < i32 3, i32 1, i32 2, i32 0 > ; <<4 x i8>> [#uses=1] + store <4 x i8> %tmp9, <4 x i8> addrspace(1)* %arrayidx + ret void + +return: ; preds = %entry + ret void +} \ No newline at end of file -- GitLab From 100c65e8109e1ef9fc7fc24f27597947e60decb4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 05:29:08 +0000 Subject: [PATCH 191/682] parse and enforce required constraints on #line directives. Right now we just discard them. llvm-svn: 62999 --- clang/include/clang/Basic/DiagnosticKinds.def | 7 ++ clang/include/clang/Lex/Preprocessor.h | 1 + clang/lib/Lex/PPDirectives.cpp | 100 +++++++++++++++--- clang/test/Preprocessor/line-directive.c | 10 ++ 4 files changed, 104 insertions(+), 14 deletions(-) create mode 100644 clang/test/Preprocessor/line-directive.c diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index e9dbad94b676..09b24ad81841 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -200,6 +200,13 @@ DIAG(err_pp_duplicate_name_in_arg_list, ERROR, "duplicate macro parameter name %0") DIAG(err_pp_stringize_not_parameter, ERROR, "'#' is not followed by a macro parameter") +DIAG(err_pp_line_requires_integer, ERROR, + "#line directive requires a positive integer argument") +DIAG(err_pp_line_invalid_filename, ERROR, + "invalid filename for #line directive") +DIAG(ext_pp_line_too_big, EXTENSION, + "C requires #line number to be less than %0, allowed as extension") + DIAG(err_pp_malformed_ident, ERROR, "invalid #ident directive") DIAG(err_pp_unterminated_conditional, ERROR, diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 2954c676e8db..8081759e9655 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -691,6 +691,7 @@ private: /// should side-effect the current preprocessor object so that the next call /// to Lex() will return the appropriate token next. + void HandleLineDirective(Token &Tok); void HandleUserDiagnosticDirective(Token &Tok, bool isWarning); void HandleIdentSCCSDirective(Token &Tok); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index ec5b67fb788e..4ab293b9b724 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -12,10 +12,12 @@ //===----------------------------------------------------------------------===// #include "clang/Lex/Preprocessor.h" +#include "clang/Lex/LiteralSupport.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" +#include "llvm/ADT/APInt.h" using namespace clang; //===----------------------------------------------------------------------===// @@ -478,8 +480,7 @@ TryAgain: case tok::numeric_constant: // FIXME: implement # 7 line numbers! - DiscardUntilEndOfDirective(); - return; + return DiscardUntilEndOfDirective(); default: IdentifierInfo *II = Result.getIdentifierInfo(); if (II == 0) break; // Not an identifier. @@ -513,9 +514,7 @@ TryAgain: // C99 6.10.4 - Line Control. case tok::pp_line: - // FIXME: implement #line - DiscardUntilEndOfDirective(); - return; + return HandleLineDirective(Result); // C99 6.10.5 - Error Directive. case tok::pp_error: @@ -557,22 +556,95 @@ TryAgain: // Okay, we're done parsing the directive. } +/// HandleLineDirective - Handle #line directive: C99 6.10.4. The two +/// acceptable forms are: +/// # line digit-sequence +/// # line digit-sequence "s-char-sequence" +void Preprocessor::HandleLineDirective(Token &Tok) { + // Read the line # and string argument. Per C99 6.10.4p5, these tokens are + // expanded. + Token DigitTok; + Lex(DigitTok); + + // Verify that we get a number. + if (DigitTok.isNot(tok::numeric_constant)) { + Diag(DigitTok, diag::err_pp_line_requires_integer); + if (DigitTok.isNot(tok::eom)) + DiscardUntilEndOfDirective(); + return; + } + + // Validate the number and convert it to an unsigned. + llvm::SmallString<64> IntegerBuffer; + IntegerBuffer.resize(DigitTok.getLength()); + const char *DigitTokBegin = &IntegerBuffer[0]; + unsigned ActualLength = getSpelling(DigitTok, DigitTokBegin); + NumericLiteralParser Literal(DigitTokBegin, DigitTokBegin+ActualLength, + DigitTok.getLocation(), *this); + if (Literal.hadError) + return DiscardUntilEndOfDirective(); // a diagnostic was already reported. + + if (Literal.isFloatingLiteral() || Literal.isImaginary) { + Diag(DigitTok, diag::err_pp_line_requires_integer); + return; + } + + // Parse the integer literal into Result. + llvm::APInt Val(32, 0); + if (Literal.GetIntegerValue(Val)) { + // Overflow parsing integer literal. + Diag(DigitTok, diag::err_pp_line_requires_integer); + return DiscardUntilEndOfDirective(); + } + + // Enforce C99 6.10.4p3: The digit sequence shall not specify zero, nor a + // number greater than 2147483647. + unsigned LineNo = Val.getZExtValue(); + if (LineNo == 0) { + Diag(DigitTok, diag::err_pp_line_requires_integer); + return DiscardUntilEndOfDirective(); + } + + // C90 requires that the line # be less than 32767, and C99 ups the limit. + unsigned LineLimit = Features.C99 ? 2147483648U : 32768U; + if (LineNo >= LineLimit) + Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit; + + Token StrTok; + Lex(StrTok); + + // If the StrTok is "eom", then it wasn't present. Otherwise, it must be a + // string followed by eom. + if (StrTok.is(tok::eom)) + ; // ok + else if (StrTok.isNot(tok::string_literal)) { + Diag(StrTok, diag::err_pp_line_invalid_filename); + DiscardUntilEndOfDirective(); + return; + } else { + // Verify that there is nothing after the string, other than EOM. + CheckEndOfDirective("#line"); + } + + // FIXME: do something with the #line info. +} + + void Preprocessor::HandleUserDiagnosticDirective(Token &Tok, bool isWarning) { + if (!CurLexer) + return CurPTHLexer->DiscardToEndOfLine(); + // Read the rest of the line raw. We do this because we don't want macros // to be expanded and we don't require that the tokens be valid preprocessing // tokens. For example, this is allowed: "#warning ` 'foo". GCC does // collapse multiple consequtive white space between tokens, but this isn't // specified by the standard. - - if (CurLexer) { - std::string Message = CurLexer->ReadToEndOfLine(); - unsigned DiagID = isWarning ? diag::pp_hash_warning : diag::err_pp_hash_error; - Diag(Tok, DiagID) << Message; - } - else { - CurPTHLexer->DiscardToEndOfLine(); - } + std::string Message = CurLexer->ReadToEndOfLine(); + if (isWarning) + Diag(Tok, diag::pp_hash_warning) << Message; + else + Diag(Tok, diag::err_pp_hash_error) << Message; } /// HandleIdentSCCSDirective - Handle a #ident/#sccs directive. diff --git a/clang/test/Preprocessor/line-directive.c b/clang/test/Preprocessor/line-directive.c new file mode 100644 index 000000000000..9b7950633b21 --- /dev/null +++ b/clang/test/Preprocessor/line-directive.c @@ -0,0 +1,10 @@ +// RUN: clang -fsyntax-only -verify -pedantic %s + +#line 'a' // expected-error {{#line directive requires a positive integer argument}} +#line 0 // expected-error {{#line directive requires a positive integer argument}} +#line 2147483648 // expected-warning {{C requires #line number to be less than 2147483648, allowed as extension}} +#line 42 // ok +#line 42 'a' // expected-error {{nvalid filename for #line directive}} +#line 42 "foo/bar/baz.h" // ok + + -- GitLab From 38d7fd252a6de1aa6ea25e4f747e6711990833dd Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 05:30:54 +0000 Subject: [PATCH 192/682] a few minor cleanups llvm-svn: 63000 --- clang/lib/Lex/PPDirectives.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 4ab293b9b724..1c8f7f1f3a33 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -629,10 +629,12 @@ void Preprocessor::HandleLineDirective(Token &Tok) { // FIXME: do something with the #line info. } - +/// HandleUserDiagnosticDirective - Handle a #warning or #error directive. +/// void Preprocessor::HandleUserDiagnosticDirective(Token &Tok, bool isWarning) { - if (!CurLexer) + // PTH doesn't emit #warning or #error directives. + if (CurPTHLexer) return CurPTHLexer->DiscardToEndOfLine(); // Read the rest of the line raw. We do this because we don't want macros @@ -661,6 +663,8 @@ void Preprocessor::HandleIdentSCCSDirective(Token &Tok) { if (StrTok.isNot(tok::string_literal) && StrTok.isNot(tok::wide_string_literal)) { Diag(StrTok, diag::err_pp_malformed_ident); + if (StrTok.isNot(tok::eom)) + DiscardUntilEndOfDirective(); return; } -- GitLab From 5a8057bc18be32b10672e5e31be7138ed9a8fd6a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 05:44:13 +0000 Subject: [PATCH 193/682] add another sanity test. llvm-svn: 63001 --- clang/test/Preprocessor/line-directive.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/test/Preprocessor/line-directive.c b/clang/test/Preprocessor/line-directive.c index 9b7950633b21..e1adc6116df3 100644 --- a/clang/test/Preprocessor/line-directive.c +++ b/clang/test/Preprocessor/line-directive.c @@ -8,3 +8,7 @@ #line 42 "foo/bar/baz.h" // ok +// #line directives expand macros. +#define A 42 "foo" +#line A + -- GitLab From e9193283c69c0a861cac726da121acde568bd238 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 26 Jan 2009 06:04:53 +0000 Subject: [PATCH 194/682] Use tag classes instead of typedefs for GDM entries 'ConstNotEq' and 'ConstEq'. This avoids collisions in the GDM. llvm-svn: 63002 --- clang/lib/Analysis/BasicConstraintManager.cpp | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp index c875691167a5..7496c5f5aac2 100644 --- a/clang/lib/Analysis/BasicConstraintManager.cpp +++ b/clang/lib/Analysis/BasicConstraintManager.cpp @@ -21,11 +21,29 @@ using namespace clang; -namespace { + +namespace { class VISIBILITY_HIDDEN ConstNotEq {}; } +namespace { class VISIBILITY_HIDDEN ConstEq {}; } typedef llvm::ImmutableMap ConstNotEqTy; typedef llvm::ImmutableMap ConstEqTy; + +static int ConstEqIndex = 0; +static int ConstNotEqIndex = 0; +namespace clang { +template<> +struct GRStateTrait : public GRStatePartialTrait { + static inline void* GDMIndex() { return &ConstNotEqIndex; } +}; + +template<> +struct GRStateTrait : public GRStatePartialTrait { + static inline void* GDMIndex() { return &ConstEqIndex; } +}; +} + +namespace { // BasicConstraintManager only tracks equality and inequality constraints of // constants and integer variables. class VISIBILITY_HIDDEN BasicConstraintManager : public ConstraintManager { @@ -437,26 +455,12 @@ BasicConstraintManager::AssumeInBound(const GRState* St, SVal Idx, return St; } -static int ConstEqTyIndex = 0; -static int ConstNotEqTyIndex = 0; - -namespace clang { - template<> - struct GRStateTrait : public GRStatePartialTrait { - static inline void* GDMIndex() { return &ConstNotEqTyIndex; } - }; - - template<> - struct GRStateTrait : public GRStatePartialTrait { - static inline void* GDMIndex() { return &ConstEqTyIndex; } - }; -} const GRState* BasicConstraintManager::AddEQ(const GRState* St, SymbolRef sym, const llvm::APSInt& V) { // Create a new state with the old binding replaced. GRStateRef state(St, StateMgr); - return state.set(sym, &V); + return state.set(sym, &V); } const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym, @@ -465,7 +469,7 @@ const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym, GRStateRef state(St, StateMgr); // First, retrieve the NE-set associated with the given symbol. - ConstNotEqTy::data_type* T = state.get(sym); + ConstNotEqTy::data_type* T = state.get(sym); GRState::IntSetTy S = T ? *T : ISetFactory.GetEmptySet(); @@ -473,12 +477,12 @@ const GRState* BasicConstraintManager::AddNE(const GRState* St, SymbolRef sym, S = ISetFactory.Add(S, &V); // Create a new state with the old binding replaced. - return state.set(sym, S); + return state.set(sym, S); } const llvm::APSInt* BasicConstraintManager::getSymVal(const GRState* St, SymbolRef sym) { - const ConstEqTy::data_type* T = St->get(sym); + const ConstEqTy::data_type* T = St->get(sym); return T ? *T : NULL; } @@ -486,7 +490,7 @@ bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const { // Retrieve the NE-set associated with the given symbol. - const ConstNotEqTy::data_type* T = St->get(sym); + const ConstNotEqTy::data_type* T = St->get(sym); // See if V is present in the NE-set. return T ? T->contains(&V) : false; @@ -495,7 +499,7 @@ bool BasicConstraintManager::isNotEqual(const GRState* St, SymbolRef sym, bool BasicConstraintManager::isEqual(const GRState* St, SymbolRef sym, const llvm::APSInt& V) const { // Retrieve the EQ-set associated with the given symbol. - const ConstEqTy::data_type* T = St->get(sym); + const ConstEqTy::data_type* T = St->get(sym); // See if V is present in the EQ-set. return T ? **T == V : false; } @@ -507,31 +511,31 @@ BasicConstraintManager::RemoveDeadBindings(const GRState* St, SymbolReaper& SymReaper) { GRStateRef state(St, StateMgr); - ConstEqTy CE = state.get(); - ConstEqTy::Factory& CEFactory = state.get_context(); + ConstEqTy CE = state.get(); + ConstEqTy::Factory& CEFactory = state.get_context(); for (ConstEqTy::iterator I = CE.begin(), E = CE.end(); I!=E; ++I) { SymbolRef sym = I.getKey(); if (SymReaper.maybeDead(sym)) CE = CEFactory.Remove(CE, sym); } - state = state.set(CE); + state = state.set(CE); - ConstNotEqTy CNE = state.get(); - ConstNotEqTy::Factory& CNEFactory = state.get_context(); + ConstNotEqTy CNE = state.get(); + ConstNotEqTy::Factory& CNEFactory = state.get_context(); for (ConstNotEqTy::iterator I = CNE.begin(), E = CNE.end(); I != E; ++I) { SymbolRef sym = I.getKey(); if (SymReaper.maybeDead(sym)) CNE = CNEFactory.Remove(CNE, sym); } - return state.set(CNE); + return state.set(CNE); } void BasicConstraintManager::print(const GRState* St, std::ostream& Out, const char* nl, const char *sep) { // Print equality constraints. - ConstEqTy CE = St->get(); + ConstEqTy CE = St->get(); if (!CE.isEmpty()) { Out << nl << sep << "'==' constraints:"; @@ -545,7 +549,7 @@ void BasicConstraintManager::print(const GRState* St, std::ostream& Out, // Print != constraints. - ConstNotEqTy CNE = St->get(); + ConstNotEqTy CNE = St->get(); if (!CNE.isEmpty()) { Out << nl << sep << "'!=' constraints:"; -- GitLab From 76e689636be099136805a940c0d15ec2e8896313 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 06:19:46 +0000 Subject: [PATCH 195/682] add parsing and constraint enforcement for GNU line marker directives. llvm-svn: 63003 --- clang/include/clang/Basic/DiagnosticKinds.def | 6 + clang/include/clang/Lex/Preprocessor.h | 11 +- clang/lib/Lex/PPDirectives.cpp | 183 ++++++++++++++---- clang/test/Preprocessor/line-directive.c | 13 ++ 4 files changed, 173 insertions(+), 40 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 09b24ad81841..5ff6728283c0 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -204,6 +204,12 @@ DIAG(err_pp_line_requires_integer, ERROR, "#line directive requires a positive integer argument") DIAG(err_pp_line_invalid_filename, ERROR, "invalid filename for #line directive") +DIAG(err_pp_linemarker_requires_integer, ERROR, + "line marker directive requires a positive integer argument") +DIAG(err_pp_linemarker_invalid_filename, ERROR, + "invalid filename for line marker directive") +DIAG(err_pp_linemarker_invalid_flag, ERROR, + "invalid flag line marker directive") DIAG(ext_pp_line_too_big, EXTENSION, "C requires #line number to be less than %0, allowed as extension") diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 8081759e9655..bf47bab29529 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -532,6 +532,11 @@ public: /// CheckEndOfDirective - Ensure that the next token is a tok::eom token. If /// not, emit a diagnostic and consume up until the eom. void CheckEndOfDirective(const char *Directive); + + /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the + /// current line until the tok::eom token is found. + void DiscardUntilEndOfDirective(); + private: void PushIncludeMacroStack() { @@ -566,10 +571,6 @@ private: /// #include. bool isInPrimaryFile() const; - /// DiscardUntilEndOfDirective - Read and discard all tokens remaining on the - /// current line until the tok::eom token is found. - void DiscardUntilEndOfDirective(); - /// ReadMacroName - Lex and validate a macro name, which occurs after a /// #define or #undef. This emits a diagnostic, sets the token kind to eom, /// and discards the rest of the macro line if the macro name is invalid. @@ -690,8 +691,8 @@ private: /// Handle*Directive - implement the various preprocessor directives. These /// should side-effect the current preprocessor object so that the next call /// to Lex() will return the appropriate token next. - void HandleLineDirective(Token &Tok); + void HandleDigitDirective(Token &Tok); void HandleUserDiagnosticDirective(Token &Tok, bool isWarning); void HandleIdentSCCSDirective(Token &Tok); diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 1c8f7f1f3a33..5b45ddd35e9a 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -478,9 +478,8 @@ TryAgain: LexUnexpandedToken(Result); goto TryAgain; - case tok::numeric_constant: - // FIXME: implement # 7 line numbers! - return DiscardUntilEndOfDirective(); + case tok::numeric_constant: // # 7 GNU line marker directive. + return HandleDigitDirective(Result); default: IdentifierInfo *II = Result.getIdentifierInfo(); if (II == 0) break; // Not an identifier. @@ -556,56 +555,68 @@ TryAgain: // Okay, we're done parsing the directive. } -/// HandleLineDirective - Handle #line directive: C99 6.10.4. The two -/// acceptable forms are: -/// # line digit-sequence -/// # line digit-sequence "s-char-sequence" -void Preprocessor::HandleLineDirective(Token &Tok) { - // Read the line # and string argument. Per C99 6.10.4p5, these tokens are - // expanded. - Token DigitTok; - Lex(DigitTok); - - // Verify that we get a number. +/// GetLineValue - Convert a numeric token into an unsigned value, emitting +/// Diagnostic DiagID if it is invalid, and returning the value in Val. +static bool GetLineValue(Token &DigitTok, unsigned &Val, + unsigned DiagID, Preprocessor &PP) { if (DigitTok.isNot(tok::numeric_constant)) { - Diag(DigitTok, diag::err_pp_line_requires_integer); + PP.Diag(DigitTok, DiagID); + if (DigitTok.isNot(tok::eom)) - DiscardUntilEndOfDirective(); - return; + PP.DiscardUntilEndOfDirective(); + return true; } - // Validate the number and convert it to an unsigned. llvm::SmallString<64> IntegerBuffer; IntegerBuffer.resize(DigitTok.getLength()); const char *DigitTokBegin = &IntegerBuffer[0]; - unsigned ActualLength = getSpelling(DigitTok, DigitTokBegin); + unsigned ActualLength = PP.getSpelling(DigitTok, DigitTokBegin); NumericLiteralParser Literal(DigitTokBegin, DigitTokBegin+ActualLength, - DigitTok.getLocation(), *this); + DigitTok.getLocation(), PP); if (Literal.hadError) - return DiscardUntilEndOfDirective(); // a diagnostic was already reported. + return true; // Error already emitted. if (Literal.isFloatingLiteral() || Literal.isImaginary) { - Diag(DigitTok, diag::err_pp_line_requires_integer); - return; + PP.Diag(DigitTok, DiagID); + return true; } // Parse the integer literal into Result. - llvm::APInt Val(32, 0); - if (Literal.GetIntegerValue(Val)) { + llvm::APInt APVal(32, 0); + if (Literal.GetIntegerValue(APVal)) { // Overflow parsing integer literal. - Diag(DigitTok, diag::err_pp_line_requires_integer); - return DiscardUntilEndOfDirective(); + PP.Diag(DigitTok, DiagID); + return true; } - - // Enforce C99 6.10.4p3: The digit sequence shall not specify zero, nor a - // number greater than 2147483647. - unsigned LineNo = Val.getZExtValue(); - if (LineNo == 0) { - Diag(DigitTok, diag::err_pp_line_requires_integer); - return DiscardUntilEndOfDirective(); + Val = APVal.getZExtValue(); + + // Reject 0, this is needed both by #line numbers and flags. + if (Val == 0) { + PP.Diag(DigitTok, DiagID); + PP.DiscardUntilEndOfDirective(); + return true; } - // C90 requires that the line # be less than 32767, and C99 ups the limit. + return false; +} + +/// HandleLineDirective - Handle #line directive: C99 6.10.4. The two +/// acceptable forms are: +/// # line digit-sequence +/// # line digit-sequence "s-char-sequence" +void Preprocessor::HandleLineDirective(Token &Tok) { + // Read the line # and string argument. Per C99 6.10.4p5, these tokens are + // expanded. + Token DigitTok; + Lex(DigitTok); + + // Validate the number and convert it to an unsigned. + unsigned LineNo; + if (GetLineValue(DigitTok, LineNo, diag::err_pp_line_requires_integer, *this)) + return; + + // Enforce C99 6.10.4p3: "The digit sequence shall not specify ... a + // number greater than 2147483647". C90 requires that the line # be <= 32767. unsigned LineLimit = Features.C99 ? 2147483648U : 32768U; if (LineNo >= LineLimit) Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit; @@ -629,6 +640,108 @@ void Preprocessor::HandleLineDirective(Token &Tok) { // FIXME: do something with the #line info. } +/// ReadLineMarkerFlags - Parse and validate any flags at the end of a GNU line +/// marker directive. +static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, + bool &IsSystemHeader, bool &IsExternCHeader, + Preprocessor &PP) { + unsigned FlagVal; + Token FlagTok; + PP.Lex(FlagTok); + if (FlagTok.is(tok::eom)) return false; + if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag, PP)) + return true; + + if (FlagVal == 1) { + IsFileEntry = true; + + PP.Lex(FlagTok); + if (FlagTok.is(tok::eom)) return false; + if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP)) + return true; + } else if (FlagVal == 2) { + IsFileExit = true; + + PP.Lex(FlagTok); + if (FlagTok.is(tok::eom)) return false; + if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP)) + return true; + } + + // We must have 3 if there are still flags. + if (FlagVal != 3) { + PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag); + return true; + } + + IsSystemHeader = true; + + PP.Lex(FlagTok); + if (FlagTok.is(tok::eom)) return false; + if (GetLineValue(FlagTok, FlagVal, diag::err_pp_linemarker_invalid_flag,PP)) + return true; + + // We must have 4 if there is yet another flag. + if (FlagVal != 4) { + PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag); + return true; + } + + IsExternCHeader = true; + + PP.Lex(FlagTok); + if (FlagTok.is(tok::eom)) return false; + + // There are no more valid flags here. + PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag); + return true; +} + +/// HandleDigitDirective - Handle a GNU line marker directive, whose syntax is +/// one of the following forms: +/// +/// # 42 +/// # 42 "file" ('1' | '2')? +/// # 42 "file" ('1' | '2')? '3' '4'? +/// +void Preprocessor::HandleDigitDirective(Token &DigitTok) { + // Validate the number and convert it to an unsigned. GNU does not have a + // line # limit other than it fit in 32-bits. + unsigned LineNo; + if (GetLineValue(DigitTok, LineNo, diag::err_pp_linemarker_requires_integer, + *this)) + return; + + Token StrTok; + Lex(StrTok); + + bool IsFileEntry = false, IsFileExit = false; + bool IsSystemHeader = false, IsExternCHeader = false; + + // If the StrTok is "eom", then it wasn't present. Otherwise, it must be a + // string followed by eom. + if (StrTok.is(tok::eom)) + ; // ok + else if (StrTok.isNot(tok::string_literal)) { + Diag(StrTok, diag::err_pp_linemarker_invalid_filename); + DiscardUntilEndOfDirective(); + return; + } else { + // If a filename was present, read any flags that are present. + if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, + IsSystemHeader, IsExternCHeader, *this)) { + DiscardUntilEndOfDirective(); + return; + } + } + + // FIXME: do something with the #line info. + + + +} + + /// HandleUserDiagnosticDirective - Handle a #warning or #error directive. /// void Preprocessor::HandleUserDiagnosticDirective(Token &Tok, diff --git a/clang/test/Preprocessor/line-directive.c b/clang/test/Preprocessor/line-directive.c index e1adc6116df3..3faac15c2720 100644 --- a/clang/test/Preprocessor/line-directive.c +++ b/clang/test/Preprocessor/line-directive.c @@ -12,3 +12,16 @@ #define A 42 "foo" #line A +# 42 +# 42 "foo" +# 42 "foo" 1 3 +# 42 "foo" 2 3 +# 42 "foo" 2 3 4 +# 42 "foo" 3 4 + +# 'a' // expected-error {{invalid preprocessing directive}} +# 42 'f' // expected-error {{invalid filename for line marker directive}} +# 42 1 3 // expected-error {{invalid filename for line marker directive}} +# 42 "foo" 3 1 // expected-error {{invalid flag line marker directive}} +# 42 "foo" 42 // expected-error {{invalid flag line marker directive}} +# 42 "foo" 1 2 // expected-error {{invalid flag line marker directive}} -- GitLab From 273fc663dfc6431cd7bc85b62fab3ebd50c8fb12 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 06:49:09 +0000 Subject: [PATCH 196/682] Bitmangle file characteristic bits into the low bits of the content cache pointer. This saves 105876 bytes on cocoa.h because it shrinks the SLocEntry union, which we have a big array of. It would be nice to use PointerIntPair here, but we can't because it is in a union. llvm-svn: 63004 --- clang/include/clang/Basic/SourceManager.h | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index 17c39f8016e3..a58662443d14 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -130,31 +130,33 @@ namespace SrcMgr { /// This is an invalid SLOC for the main file (top of the #include chain). unsigned IncludeLoc; // Really a SourceLocation - /// Content - Information about the source buffer itself. - const ContentCache *Content; - - /// FileCharacteristic - This is an instance of CharacteristicKind, - /// indicating whether this is a system header dir or not. - unsigned FileCharacteristic : 2; + /// Data - This contains the ContentCache* and the bits indicating the + /// characteristic of the file and whether it has #line info, all bitmangled + /// together. + uintptr_t Data; public: /// get - Return a FileInfo object. static FileInfo get(SourceLocation IL, const ContentCache *Con, CharacteristicKind FileCharacter) { FileInfo X; X.IncludeLoc = IL.getRawEncoding(); - X.Content = Con; - X.FileCharacteristic = FileCharacter; + X.Data = (uintptr_t)Con; + assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); + assert((unsigned)FileCharacter < 4 && "invalid file character"); + X.Data |= (unsigned)FileCharacter; return X; } SourceLocation getIncludeLoc() const { return SourceLocation::getFromRawEncoding(IncludeLoc); } - const ContentCache* getContentCache() const { return Content; } + const ContentCache* getContentCache() const { + return reinterpret_cast(Data & ~7UL); + } /// getCharacteristic - Return whether this is a system header or not. CharacteristicKind getFileCharacteristic() const { - return (CharacteristicKind)FileCharacteristic; + return (CharacteristicKind)(Data & 3); } }; -- GitLab From 3975bbec587a7b536ba76d8c8a3ca3cfe61d629b Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 07:31:20 +0000 Subject: [PATCH 197/682] LLVM_SUPPORT_DEBUGINFO_H -> LLVM_ANALYSIS_DEBUGINFO_H since DebugInfo.h is under Analysis. llvm-svn: 63005 --- llvm/include/llvm/Analysis/DebugInfo.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/Analysis/DebugInfo.h b/llvm/include/llvm/Analysis/DebugInfo.h index c80a11d3b32c..336d816bc144 100644 --- a/llvm/include/llvm/Analysis/DebugInfo.h +++ b/llvm/include/llvm/Analysis/DebugInfo.h @@ -12,8 +12,8 @@ // //===----------------------------------------------------------------------===// -#ifndef LLVM_SUPPORT_DEBUGINFO_H -#define LLVM_SUPPORT_DEBUGINFO_H +#ifndef LLVM_ANALYSIS_DEBUGINFO_H +#define LLVM_ANALYSIS_DEBUGINFO_H #include "llvm/ADT/StringMap.h" #include "llvm/ADT/DenseMap.h" -- GitLab From 43a85b1e4c8d72b6f49cb6c0f2eefbb0b852d3f1 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 07:37:49 +0000 Subject: [PATCH 198/682] Lazily paging in file contents is a big win for PTH, strip out the old testing code. llvm-svn: 63006 --- clang/lib/Basic/SourceManager.cpp | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index e30e2a81315d..fcca97774df1 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -28,12 +28,6 @@ using llvm::MemoryBuffer; // SourceManager Helper Classes //===--------------------------------------------------------------------===// -// This (temporary) directive toggles between lazy and eager creation of -// MemBuffers. This directive is not permanent, and is here to test a few -// potential optimizations in PTH. Once it is clear whether eager or lazy -// creation of MemBuffers is better this directive will get removed. -#define LAZY - ContentCache::~ContentCache() { delete Buffer; delete [] SourceLineCache; @@ -54,15 +48,13 @@ unsigned ContentCache::getSize() const { return Entry ? Entry->getSize() : Buffer->getBufferSize(); } -const llvm::MemoryBuffer* ContentCache::getBuffer() const { -#ifdef LAZY +const llvm::MemoryBuffer *ContentCache::getBuffer() const { // Lazily create the Buffer for ContentCaches that wrap files. if (!Buffer && Entry) { // FIXME: Should we support a way to not have to do this check over // and over if we cannot open the file? Buffer = MemoryBuffer::getFile(Entry->getName(), 0, Entry->getSize()); } -#endif return Buffer; } @@ -83,18 +75,8 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt) { if (I != FileInfos.end() && I->Entry == FileEnt) return &*I; - // Nope, get information. -#ifndef LAZY - const MemoryBuffer *File = - MemoryBuffer::getFile(FileEnt->getName(), 0, FileEnt->getSize()); - if (File == 0) - return 0; -#endif - + // Nope, create a new Cache entry. ContentCache& Entry = const_cast(*FileInfos.insert(I,FileEnt)); -#ifndef LAZY - Entry.setBuffer(File); -#endif Entry.SourceLineCache = 0; Entry.NumLines = 0; return &Entry; -- GitLab From fd0ab1232761f44cbc17d1176f1d77da7b87ca50 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 07:40:13 +0000 Subject: [PATCH 199/682] Looks like comments were chopped off. llvm-svn: 63007 --- llvm/include/llvm/CodeGen/DwarfWriter.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DwarfWriter.h b/llvm/include/llvm/CodeGen/DwarfWriter.h index 1616dfa4e90b..58a2fa742373 100644 --- a/llvm/include/llvm/CodeGen/DwarfWriter.h +++ b/llvm/include/llvm/CodeGen/DwarfWriter.h @@ -79,8 +79,9 @@ public: /// ValidDebugInfo - Return true if V represents valid debug info value. bool ValidDebugInfo(Value *V); - /// label. Returns a unique label ID used to generate a label and provide - /// correspondence to the source line list. + /// RecordSourceLine - Register a source line with debug info. Returns a + /// unique label ID used to generate a label and provide correspondence to + /// the source line list. unsigned RecordSourceLine(unsigned Line, unsigned Col, unsigned Src); /// RecordSource - Register a source file with debug info. Returns an source -- GitLab From b5706c45fa2ec5e9e35922b68da34c7755f59ac8 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 07:41:49 +0000 Subject: [PATCH 200/682] Add data structure to define and track debug location during codegen. llvm-svn: 63008 --- llvm/include/llvm/CodeGen/DebugLoc.h | 109 ++++++++++++++++++++ llvm/include/llvm/CodeGen/MachineFunction.h | 15 ++- llvm/lib/CodeGen/MachineFunction.cpp | 27 +++++ 3 files changed, 150 insertions(+), 1 deletion(-) create mode 100644 llvm/include/llvm/CodeGen/DebugLoc.h diff --git a/llvm/include/llvm/CodeGen/DebugLoc.h b/llvm/include/llvm/CodeGen/DebugLoc.h new file mode 100644 index 000000000000..ad68839b054c --- /dev/null +++ b/llvm/include/llvm/CodeGen/DebugLoc.h @@ -0,0 +1,109 @@ +//===---- llvm/CodeGen/DebugLoc.h - Debug Location Information --*- 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 a number of light weight data structures used by the code +// generator to describe and track debug location information. + +#ifndef LLVM_CODEGEN_DEBUGLOC_H +#define LLVM_CODEGEN_DEBUGLOC_H + +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/StringMap.h" +#include + +namespace llvm { + + /// DebugLocTuple - Debug location tuple of filename id, line and column. + /// + struct DebugLocTuple { + unsigned FileId, Line, Col; + + DebugLocTuple(unsigned fi, unsigned l, unsigned c) + : FileId(fi), Line(l), Col(c) {}; + }; + + /// DebugLoc - Debug location id. This is carried by SDNode and + /// MachineInstr to index into a vector of unique debug location tuples. + class DebugLoc { + unsigned Idx; + + public: + DebugLoc() : Idx(~0U) {} + + static DebugLoc getNoDebugLoc() { DebugLoc L; L.Idx = 0; return L; } + static DebugLoc get(unsigned idx) { DebugLoc L; L.Idx = idx; return L; } + + bool isInvalid() { return Idx == ~0U; } + bool isUnknown() { return Idx == 0; } + }; + + struct DebugLocTupleDenseMapInfo { + static inline DebugLocTuple getEmptyKey() { + return DebugLocTuple(~0U, ~0U, ~0U); + } + static inline DebugLocTuple getTombstoneKey() { + return DebugLocTuple(~1U, ~1U, ~1U); + } + static unsigned getHashValue(const DebugLocTuple &Val) { + return DenseMapInfo::getHashValue(Val.FileId) ^ + DenseMapInfo::getHashValue(Val.Line) ^ + DenseMapInfo::getHashValue(Val.Col); + } + static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) { + return LHS.FileId == RHS.FileId && + LHS.Line == RHS.Line && + LHS.Col == RHS.Col; + } + + static bool isPod() { return true; } + }; + + typedef DenseMap + DebugIdMapType; + + /// DebugLocTracker - This class tracks debug location information. + /// + struct DebugLocTracker { + // NumFilenames - Size of the DebugFilenames vector. + // + unsigned NumFilenames; + + // DebugFilenames - A vector of unique file names. + // + std::vector DebugFilenames; + + // DebugFilenamesMap - File name to DebugFilenames index map. + // + StringMap DebugFilenamesMap; + + // NumDebugLocations - Size of the DebugLocations vector. + unsigned NumDebugLocations; + + // DebugLocations - A vector of unique DebugLocTuple's. + // + std::vector DebugLocations; + + // DebugIdsMap - This maps DebugLocTuple's to indices into + // DebugLocations vector. + DebugIdMapType DebugIdMap; + + DebugLocTracker() : NumFilenames(0), NumDebugLocations(0) {} + + ~DebugLocTracker() { + NumFilenames = 0; + DebugFilenames.clear(); + DebugFilenamesMap.clear(); + DebugLocations.clear(); + DebugIdMap.clear(); + } + }; + +} // end namespace llvm + +#endif /* LLVM_CODEGEN_DEBUGLOC_H */ diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 835c8a37c56e..1397b846779a 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -19,6 +19,7 @@ #define LLVM_CODEGEN_MACHINEFUNCTION_H #include "llvm/ADT/ilist.h" +#include "llvm/CodeGen/DebugLoc.h" #include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/Support/Annotation.h" #include "llvm/Support/Allocator.h" @@ -27,11 +28,11 @@ namespace llvm { class Function; -class TargetMachine; class MachineRegisterInfo; class MachineFrameInfo; class MachineConstantPool; class MachineJumpTableInfo; +class TargetMachine; template <> struct ilist_traits @@ -94,6 +95,9 @@ class MachineFunction : private Annotation { typedef ilist BasicBlockListType; BasicBlockListType BasicBlocks; + // Tracks debug locations. + DebugLocTracker DebugLocInfo; + public: MachineFunction(const Function *Fn, const TargetMachine &TM); ~MachineFunction(); @@ -302,6 +306,15 @@ public: /// DeleteMachineBasicBlock - Delete the given MachineBasicBlock. /// void DeleteMachineBasicBlock(MachineBasicBlock *MBB); + + //===--------------------------------------------------------------------===// + // Debug location. + // + + /// lookUpDebugLocId - Look up the DebugLocTuple index with the given + /// filename, line, and column. It may add a new filename and / or + /// a new DebugLocTuple. + unsigned lookUpDebugLocId(const char *Filename, unsigned Line, unsigned Col); }; //===--------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 8bae7bbb92cc..0d442af7eda2 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -378,6 +378,33 @@ MachineFunction& MachineFunction::get(const Function *F) return *mc; } +/// lookUpDebugLocId - Look up the DebugLocTuple index with the given +/// filename, line, and column. It may add a new filename and / or +/// a new DebugLocTuple. +unsigned MachineFunction::lookUpDebugLocId(const char *Filename, unsigned Line, + unsigned Col) { + unsigned FileId; + StringMap::iterator I = + DebugLocInfo.DebugFilenamesMap.find(Filename); + if (I != DebugLocInfo.DebugFilenamesMap.end()) + FileId = I->second; + else { + // Add a new filename. + FileId = DebugLocInfo.NumFilenames++; + DebugLocInfo.DebugFilenames.push_back(Filename); + DebugLocInfo.DebugFilenamesMap[Filename] = FileId; + } + + struct DebugLocTuple Tuple(FileId, Line, Col); + DebugIdMapType::iterator II = DebugLocInfo.DebugIdMap.find(Tuple); + if (II != DebugLocInfo.DebugIdMap.end()) + return II->second; + // Add a new tuple. + DebugLocInfo.DebugLocations.push_back(Tuple); + DebugLocInfo.DebugIdMap[Tuple] = DebugLocInfo.NumDebugLocations; + return DebugLocInfo.NumDebugLocations++; +} + //===----------------------------------------------------------------------===// // MachineFrameInfo implementation //===----------------------------------------------------------------------===// -- GitLab From 4e6871da0995ff3d50e0b49f8b2009d171511772 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 07:53:42 +0000 Subject: [PATCH 201/682] Actually source file has already been uniquified into an id during isel. Eliminate the StringMap. llvm-svn: 63009 --- llvm/include/llvm/CodeGen/DebugLoc.h | 30 +++++---------------- llvm/include/llvm/CodeGen/MachineFunction.h | 4 +-- llvm/lib/CodeGen/MachineFunction.cpp | 18 +++---------- 3 files changed, 12 insertions(+), 40 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DebugLoc.h b/llvm/include/llvm/CodeGen/DebugLoc.h index ad68839b054c..b6097afe306d 100644 --- a/llvm/include/llvm/CodeGen/DebugLoc.h +++ b/llvm/include/llvm/CodeGen/DebugLoc.h @@ -14,7 +14,6 @@ #define LLVM_CODEGEN_DEBUGLOC_H #include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/StringMap.h" #include namespace llvm { @@ -22,10 +21,10 @@ namespace llvm { /// DebugLocTuple - Debug location tuple of filename id, line and column. /// struct DebugLocTuple { - unsigned FileId, Line, Col; + unsigned Src, Line, Col; - DebugLocTuple(unsigned fi, unsigned l, unsigned c) - : FileId(fi), Line(l), Col(c) {}; + DebugLocTuple(unsigned s, unsigned l, unsigned c) + : Src(s), Line(l), Col(c) {}; }; /// DebugLoc - Debug location id. This is carried by SDNode and @@ -51,14 +50,14 @@ namespace llvm { return DebugLocTuple(~1U, ~1U, ~1U); } static unsigned getHashValue(const DebugLocTuple &Val) { - return DenseMapInfo::getHashValue(Val.FileId) ^ + return DenseMapInfo::getHashValue(Val.Src) ^ DenseMapInfo::getHashValue(Val.Line) ^ DenseMapInfo::getHashValue(Val.Col); } static bool isEqual(const DebugLocTuple &LHS, const DebugLocTuple &RHS) { - return LHS.FileId == RHS.FileId && + return LHS.Src == RHS.Src && LHS.Line == RHS.Line && - LHS.Col == RHS.Col; + LHS.Col == RHS.Col; } static bool isPod() { return true; } @@ -70,18 +69,6 @@ namespace llvm { /// DebugLocTracker - This class tracks debug location information. /// struct DebugLocTracker { - // NumFilenames - Size of the DebugFilenames vector. - // - unsigned NumFilenames; - - // DebugFilenames - A vector of unique file names. - // - std::vector DebugFilenames; - - // DebugFilenamesMap - File name to DebugFilenames index map. - // - StringMap DebugFilenamesMap; - // NumDebugLocations - Size of the DebugLocations vector. unsigned NumDebugLocations; @@ -93,12 +80,9 @@ namespace llvm { // DebugLocations vector. DebugIdMapType DebugIdMap; - DebugLocTracker() : NumFilenames(0), NumDebugLocations(0) {} + DebugLocTracker() : NumDebugLocations(0) {} ~DebugLocTracker() { - NumFilenames = 0; - DebugFilenames.clear(); - DebugFilenamesMap.clear(); DebugLocations.clear(); DebugIdMap.clear(); } diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 1397b846779a..4fa70fca6fac 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -312,9 +312,9 @@ public: // /// lookUpDebugLocId - Look up the DebugLocTuple index with the given - /// filename, line, and column. It may add a new filename and / or + /// source file, line, and column. It may add a new filename and / or /// a new DebugLocTuple. - unsigned lookUpDebugLocId(const char *Filename, unsigned Line, unsigned Col); + unsigned lookUpDebugLocId(unsigned Src, unsigned Line, unsigned Col); }; //===--------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index 0d442af7eda2..c1ab9afe9f68 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -379,23 +379,11 @@ MachineFunction& MachineFunction::get(const Function *F) } /// lookUpDebugLocId - Look up the DebugLocTuple index with the given -/// filename, line, and column. It may add a new filename and / or +/// source file, line, and column. It may add a new filename and / or /// a new DebugLocTuple. -unsigned MachineFunction::lookUpDebugLocId(const char *Filename, unsigned Line, +unsigned MachineFunction::lookUpDebugLocId(unsigned Src, unsigned Line, unsigned Col) { - unsigned FileId; - StringMap::iterator I = - DebugLocInfo.DebugFilenamesMap.find(Filename); - if (I != DebugLocInfo.DebugFilenamesMap.end()) - FileId = I->second; - else { - // Add a new filename. - FileId = DebugLocInfo.NumFilenames++; - DebugLocInfo.DebugFilenames.push_back(Filename); - DebugLocInfo.DebugFilenamesMap[Filename] = FileId; - } - - struct DebugLocTuple Tuple(FileId, Line, Col); + struct DebugLocTuple Tuple(Src, Line, Col); DebugIdMapType::iterator II = DebugLocInfo.DebugIdMap.find(Tuple); if (II != DebugLocInfo.DebugIdMap.end()) return II->second; -- GitLab From b5fba6f8d8580dffeb0ee7bda8f48b5b4cd15c46 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 07:57:50 +0000 Subject: [PATCH 202/682] start plumbing together the line table information. So far we just unique the Filenames in #line directives, assigning them UIDs. llvm-svn: 63010 --- clang/include/clang/Basic/SourceManager.h | 35 ++++++----- clang/lib/Basic/SourceManager.cpp | 76 +++++++++++++++++++++++ clang/lib/Lex/PPDirectives.cpp | 38 ++++++++++-- 3 files changed, 127 insertions(+), 22 deletions(-) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index a58662443d14..d8c17e11da58 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -31,6 +31,7 @@ class SourceManager; class FileManager; class FileEntry; class IdentifierTokenInfo; +class LineTableInfo; /// SrcMgr - Public enums and private classes that are part of the /// SourceManager implementation. @@ -224,7 +225,6 @@ namespace SrcMgr { return E; } }; - } // end SrcMgr namespace. } // end clang namespace @@ -275,6 +275,10 @@ class SourceManager { /// is very common to look up many tokens from the same file. mutable FileID LastFileIDLookup; + /// LineTable - This holds information for #line directives. It is referenced + /// by indices from SLocEntryTable. + LineTableInfo *LineTable; + /// LastLineNo - These ivars serve as a cache used in the getLineNumber /// method which is used to speedup getLineNumber calls to nearby locations. mutable FileID LastLineNoFileIDQuery; @@ -292,23 +296,13 @@ class SourceManager { explicit SourceManager(const SourceManager&); void operator=(const SourceManager&); public: - SourceManager() : NumLinearScans(0), NumBinaryProbes(0) { + SourceManager() : LineTable(0), NumLinearScans(0), NumBinaryProbes(0) { clearIDTables(); } - ~SourceManager() {} - - void clearIDTables() { - MainFileID = FileID(); - SLocEntryTable.clear(); - LastLineNoFileIDQuery = FileID(); - LastLineNoContentCache = 0; - LastFileIDLookup = FileID(); - - // Use up FileID #0 as an invalid instantiation. - NextOffset = 0; - createInstantiationLoc(SourceLocation(), SourceLocation(), 1); - } - + ~SourceManager(); + + void clearIDTables(); + //===--------------------------------------------------------------------===// // MainFileID creation and querying methods. //===--------------------------------------------------------------------===// @@ -552,6 +546,15 @@ public: return getFileCharacteristic(Loc) != SrcMgr::C_User; } + //===--------------------------------------------------------------------===// + // Line Table Manipulation Routines + //===--------------------------------------------------------------------===// + + /// getLineTableFilenameID - Return the uniqued ID for the specified filename. + /// + unsigned getLineTableFilenameID(const char *Ptr, unsigned Len); + + //===--------------------------------------------------------------------===// // Other miscellaneous methods. //===--------------------------------------------------------------------===// diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index fcca97774df1..42e6040b7464 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -58,10 +58,86 @@ const llvm::MemoryBuffer *ContentCache::getBuffer() const { return Buffer; } +//===--------------------------------------------------------------------===// +// Line Table Implementation +//===--------------------------------------------------------------------===// + +namespace clang { +/// LineTableInfo - This class is used to hold and unique data used to +/// represent #line information. +class LineTableInfo { + /// FilenameIDs - This map is used to assign unique IDs to filenames in + /// #line directives. This allows us to unique the filenames that + /// frequently reoccur and reference them with indices. FilenameIDs holds + /// the mapping from string -> ID, and FilenamesByID holds the mapping of ID + /// to string. + llvm::StringMap FilenameIDs; + std::vector*> FilenamesByID; +public: + LineTableInfo() { + } + + void clear() { + FilenameIDs.clear(); + FilenamesByID.clear(); + } + + ~LineTableInfo() {} + + unsigned getLineTableFilenameID(const char *Ptr, unsigned Len); + +}; +} // namespace clang + + + + +unsigned LineTableInfo::getLineTableFilenameID(const char *Ptr, unsigned Len) { + // Look up the filename in the string table, returning the pre-existing value + // if it exists. + llvm::StringMapEntry &Entry = + FilenameIDs.GetOrCreateValue(Ptr, Ptr+Len, ~0U); + if (Entry.getValue() != ~0U) + return Entry.getValue(); + + // Otherwise, assign this the next available ID. + Entry.setValue(FilenamesByID.size()); + FilenamesByID.push_back(&Entry); + return FilenamesByID.size()-1; +} + +/// getLineTableFilenameID - Return the uniqued ID for the specified filename. +/// +unsigned SourceManager::getLineTableFilenameID(const char *Ptr, unsigned Len) { + if (LineTable == 0) + LineTable = new LineTableInfo(); + return LineTable->getLineTableFilenameID(Ptr, Len); +} + + //===--------------------------------------------------------------------===// // Private 'Create' methods. //===--------------------------------------------------------------------===// +SourceManager::~SourceManager() { + delete LineTable; +} + +void SourceManager::clearIDTables() { + MainFileID = FileID(); + SLocEntryTable.clear(); + LastLineNoFileIDQuery = FileID(); + LastLineNoContentCache = 0; + LastFileIDLookup = FileID(); + + if (LineTable) + LineTable->clear(); + + // Use up FileID #0 as an invalid instantiation. + NextOffset = 0; + createInstantiationLoc(SourceLocation(), SourceLocation(), 1); +} + /// getOrCreateContentCache - Create or return a cached ContentCache for the /// specified file. const ContentCache * diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 5b45ddd35e9a..099dfb4aef09 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -621,6 +621,7 @@ void Preprocessor::HandleLineDirective(Token &Tok) { if (LineNo >= LineLimit) Diag(DigitTok, diag::ext_pp_line_too_big) << LineLimit; + int FilenameID = -1; Token StrTok; Lex(StrTok); @@ -633,6 +634,18 @@ void Preprocessor::HandleLineDirective(Token &Tok) { DiscardUntilEndOfDirective(); return; } else { + // Parse and validate the string, converting it into a unique ID. + StringLiteralParser Literal(&StrTok, 1, *this); + assert(!Literal.AnyWide && "Didn't allow wide strings in"); + if (Literal.hadError) + return DiscardUntilEndOfDirective(); + if (Literal.Pascal) { + Diag(StrTok, diag::err_pp_linemarker_invalid_filename); + return DiscardUntilEndOfDirective(); + } + FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString(), + Literal.GetStringLength()); + // Verify that there is nothing after the string, other than EOM. CheckEndOfDirective("#line"); } @@ -671,6 +684,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, // We must have 3 if there are still flags. if (FlagVal != 3) { PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag); + PP.DiscardUntilEndOfDirective(); return true; } @@ -684,6 +698,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, // We must have 4 if there is yet another flag. if (FlagVal != 4) { PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag); + PP.DiscardUntilEndOfDirective(); return true; } @@ -694,6 +709,7 @@ static bool ReadLineMarkerFlags(bool &IsFileEntry, bool &IsFileExit, // There are no more valid flags here. PP.Diag(FlagTok, diag::err_pp_linemarker_invalid_flag); + PP.DiscardUntilEndOfDirective(); return true; } @@ -717,22 +733,32 @@ void Preprocessor::HandleDigitDirective(Token &DigitTok) { bool IsFileEntry = false, IsFileExit = false; bool IsSystemHeader = false, IsExternCHeader = false; - + int FilenameID = -1; + // If the StrTok is "eom", then it wasn't present. Otherwise, it must be a // string followed by eom. if (StrTok.is(tok::eom)) ; // ok else if (StrTok.isNot(tok::string_literal)) { Diag(StrTok, diag::err_pp_linemarker_invalid_filename); - DiscardUntilEndOfDirective(); - return; + return DiscardUntilEndOfDirective(); } else { + // Parse and validate the string, converting it into a unique ID. + StringLiteralParser Literal(&StrTok, 1, *this); + assert(!Literal.AnyWide && "Didn't allow wide strings in"); + if (Literal.hadError) + return DiscardUntilEndOfDirective(); + if (Literal.Pascal) { + Diag(StrTok, diag::err_pp_linemarker_invalid_filename); + return DiscardUntilEndOfDirective(); + } + FilenameID = SourceMgr.getLineTableFilenameID(Literal.GetString(), + Literal.GetStringLength()); + // If a filename was present, read any flags that are present. if (ReadLineMarkerFlags(IsFileEntry, IsFileExit, - IsSystemHeader, IsExternCHeader, *this)) { - DiscardUntilEndOfDirective(); + IsSystemHeader, IsExternCHeader, *this)) return; - } } // FIXME: do something with the #line info. -- GitLab From 179dd918b93b13c2eb7e9df1f05d4281c7b4250f Mon Sep 17 00:00:00 2001 From: Roman Levenstein Date: Mon, 26 Jan 2009 11:07:20 +0000 Subject: [PATCH 203/682] Fix a bug in BitVector.h. All assignment operations (except the usual assignment operator) were returning a copy of the bit vector, instead of a reference! This old semantics probably did not meet the expectations. With this patch, chained assignments happen to the right object. llvm-svn: 63012 --- llvm/include/llvm/ADT/BitVector.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/ADT/BitVector.h b/llvm/include/llvm/ADT/BitVector.h index d92605b8193f..23fde26e142d 100644 --- a/llvm/include/llvm/ADT/BitVector.h +++ b/llvm/include/llvm/ADT/BitVector.h @@ -286,7 +286,7 @@ public: } // Intersection, union, disjoint union. - BitVector operator&=(const BitVector &RHS) { + BitVector &operator&=(const BitVector &RHS) { unsigned ThisWords = NumBitWords(size()); unsigned RHSWords = NumBitWords(RHS.size()); unsigned i; @@ -302,14 +302,14 @@ public: return *this; } - BitVector operator|=(const BitVector &RHS) { + BitVector &operator|=(const BitVector &RHS) { assert(Size == RHS.Size && "Illegal operation!"); for (unsigned i = 0; i < NumBitWords(size()); ++i) Bits[i] |= RHS.Bits[i]; return *this; } - BitVector operator^=(const BitVector &RHS) { + BitVector &operator^=(const BitVector &RHS) { assert(Size == RHS.Size && "Illegal operation!"); for (unsigned i = 0; i < NumBitWords(size()); ++i) Bits[i] ^= RHS.Bits[i]; -- GitLab From f3a06113c75348d884500b83a538e7dd82476051 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 17:09:15 +0000 Subject: [PATCH 204/682] ccc: Recognize -emit-llvm [-S]. - Unlike llvm-gcc, this doesn't yet treat -emit-llvm output as a linker input. llvm-svn: 63014 --- clang/tools/ccc/ccclib/Arguments.py | 2 +- clang/tools/ccc/ccclib/Driver.py | 25 ++++++++++++++++--------- clang/tools/ccc/ccclib/Phases.py | 4 ++++ clang/tools/ccc/ccclib/ToolChain.py | 18 ++++++++++++------ clang/tools/ccc/ccclib/Tools.py | 15 +++++++++++++++ clang/tools/ccc/ccclib/Types.py | 2 ++ 6 files changed, 50 insertions(+), 16 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 8f3e282967e1..e936aec4a71d 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -689,7 +689,7 @@ class OptionParser: self.addOption(JoinedOption('-i', self.iGroup)) - # Where are these coming from? I can't find them... + self.emitLLVMOption = self.addOption(FlagOption('-emit-llvm')) self.eOption = self.addOption(JoinedOrSeparateOption('-e')) self.rOption = self.addOption(JoinedOrSeparateOption('-r')) diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py index 9a393f183fa0..0fe58068ae40 100644 --- a/clang/tools/ccc/ccclib/Driver.py +++ b/clang/tools/ccc/ccclib/Driver.py @@ -336,6 +336,7 @@ class Driver(object): def buildNormalPipeline(self, args): hasAnalyze = args.getLastArg(self.parser.analyzeOption) hasCombine = args.getLastArg(self.parser.combineOption) + hasEmitLLVM = args.getLastArg(self.parser.emitLLVMOption) hasSyntaxOnly = args.getLastArg(self.parser.syntaxOnlyOption) hasDashC = args.getLastArg(self.parser.cOption) hasDashE = args.getLastArg(self.parser.EOption) @@ -368,7 +369,7 @@ class Driver(object): # worth doing, since the tool presumably does this # anyway, and this just adds an extra stat to the # equation, but this is gcc compatible. - if not os.path.exists(inputValue): + if inputValue != '-' and not os.path.exists(inputValue): self.warning("%s: No such file or directory" % inputValue) else: inputs.append((klass, a)) @@ -408,15 +409,11 @@ class Driver(object): if hasDashE or hasDashM or hasDashMM: finalPhase = Phases.Phase.eOrderPreprocess finalPhaseOpt = hasDashE - elif hasAnalyze: + elif (hasAnalyze or hasSyntaxOnly or + hasEmitLLVM or hasDashS): finalPhase = Phases.Phase.eOrderCompile - finalPhaseOpt = hasAnalyze - elif hasSyntaxOnly: - finalPhase = Phases.Phase.eOrderCompile - finalPhaseOpt = hasSyntaxOnly - elif hasDashS: - finalPhase = Phases.Phase.eOrderCompile - finalPhaseOpt = hasDashS + finalPhaseOpt = (hasAnalyze or hasSyntaxOnly or + hasEmitLLVM or hasDashS) elif hasDashC: finalPhase = Phases.Phase.eOrderAssemble finalPhaseOpt = hasDashC @@ -464,6 +461,8 @@ class Driver(object): sequence.append(Phases.AnalyzePhase()) elif hasSyntaxOnly: sequence.append(Phases.SyntaxOnlyPhase()) + elif hasEmitLLVM: + sequence.append(Phases.EmitLLVMPhase()) else: sequence.extend([Phases.CompilePhase(), Phases.AssemblePhase(), @@ -506,6 +505,14 @@ class Driver(object): current = Phases.JobAction(transition, [current], output) + elif isinstance(transition, Phases.EmitLLVMPhase): + if hasDashS: + output = Types.LLVMAsmType + else: + output = Types.LLVMBCType + current = Phases.JobAction(transition, + [current], + output) elif isinstance(transition, Phases.CompilePhase): output = Types.AsmTypeNoPP current = Phases.JobAction(transition, diff --git a/clang/tools/ccc/ccclib/Phases.py b/clang/tools/ccc/ccclib/Phases.py index 160e72c06eb1..a126027ae6b6 100644 --- a/clang/tools/ccc/ccclib/Phases.py +++ b/clang/tools/ccc/ccclib/Phases.py @@ -76,6 +76,10 @@ class SyntaxOnlyPhase(Phase): def __init__(self): super(SyntaxOnlyPhase, self).__init__("syntax-only", Phase.eOrderCompile) +class EmitLLVMPhase(Phase): + def __init__(self): + super(EmitLLVMPhase, self).__init__("emit-llvm", Phase.eOrderCompile) + class CompilePhase(Phase): def __init__(self): super(CompilePhase, self).__init__("compiler", Phase.eOrderCompile) diff --git a/clang/tools/ccc/ccclib/ToolChain.py b/clang/tools/ccc/ccclib/ToolChain.py index d0c1fe19f5fd..564b6173facc 100644 --- a/clang/tools/ccc/ccclib/ToolChain.py +++ b/clang/tools/ccc/ccclib/ToolChain.py @@ -64,12 +64,14 @@ class Darwin_X86_ToolChain(ToolChain): self.archName = archName self.clangTool = Tools.Clang_CompileTool(self) + cc = Tools.Darwin_X86_CompileTool(self) self.toolMap = { Phases.PreprocessPhase : Tools.Darwin_X86_PreprocessTool(self), Phases.AnalyzePhase : self.clangTool, - Phases.SyntaxOnlyPhase : Tools.Darwin_X86_CompileTool(self), - Phases.CompilePhase : Tools.Darwin_X86_CompileTool(self), - Phases.PrecompilePhase : Tools.Darwin_X86_CompileTool(self), + Phases.SyntaxOnlyPhase : cc, + Phases.EmitLLVMPhase : cc, + Phases.CompilePhase : cc, + Phases.PrecompilePhase : cc, Phases.AssemblePhase : Tools.Darwin_AssembleTool(self), Phases.LinkPhase : Tools.Darwin_X86_LinkTool(self), Phases.LipoPhase : Tools.LipoTool(), @@ -110,7 +112,9 @@ class Darwin_X86_ToolChain(ToolChain): if self.driver.cccClang and self.archName == 'i386': if (action.inputs[0].type in (Types.CType, Types.CTypeNoPP, Types.ObjCType, Types.ObjCTypeNoPP) and - isinstance(action.phase, Phases.CompilePhase)): + (isinstance(action.phase, Phases.CompilePhase) or + isinstance(action.phase, Phases.SyntaxOnlyPhase) or + isinstance(action.phase, Phases.EmitLLVMPhase))): return self.clangTool elif (action.inputs[0].type in (Types.CHeaderType, Types.CHeaderNoPPType, Types.ObjCHeaderType, Types.ObjCHeaderNoPPType) and @@ -200,11 +204,13 @@ class Generic_GCC_ToolChain(ToolChain): def __init__(self, driver): super(Generic_GCC_ToolChain, self).__init__(driver) + cc = Tools.GCC_CompileTool() self.toolMap = { Phases.PreprocessPhase : Tools.GCC_PreprocessTool(), Phases.AnalyzePhase : Tools.Clang_CompileTool(self), - Phases.SyntaxOnlyPhase : Tools.GCC_CompileTool(), - Phases.CompilePhase : Tools.GCC_CompileTool(), + Phases.SyntaxOnlyPhase : cc, + Phases.EmitLLVMPhase : cc, + Phases.CompilePhase : cc, Phases.PrecompilePhase : Tools.GCC_PrecompileTool(), Phases.AssemblePhase : Tools.GCC_AssembleTool(), Phases.LinkPhase : Tools.GCC_LinkTool(), diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py index 8b3ee744bb57..0dcd52e7266d 100644 --- a/clang/tools/ccc/ccclib/Tools.py +++ b/clang/tools/ccc/ccclib/Tools.py @@ -179,9 +179,15 @@ class Clang_CompileTool(Tool): patchOutputNameForPTH = False if isinstance(phase.phase, Phases.AnalyzePhase): + assert outputType is Types.PlistType cmd_args.append('-analyze') elif isinstance(phase.phase, Phases.SyntaxOnlyPhase): + assert outputType is Types.NothingType cmd_args.append('-fsyntax-only') + elif outputType is Types.LLVMAsmType: + cmd_args.append('-emit-llvm') + elif outputType is Types.LLVMBCType: + cmd_args.append('-emit-llvm-bc') elif outputType is Types.AsmTypeNoPP: cmd_args.append('-S') elif outputType is Types.PCHType: @@ -687,6 +693,15 @@ class Darwin_X86_CompileTool(Darwin_X86_CC1Tool): arglist.getLastArg(arglist.parser.f_traditionalOption)): raise Arguments.InvalidArgumentsError("-traditional is not supported without -E") + if outputType is Types.PCHType: + pass + elif outputType is Types.AsmTypeNoPP: + pass + elif outputType is Types.LLVMAsmType: + cmd_args.append('-emit-llvm') + elif outputType is Types.LLVMBCType: + cmd_args.append('-emit-llvm-bc') + if outputType is Types.PCHType: output_args = [] else: diff --git a/clang/tools/ccc/ccclib/Types.py b/clang/tools/ccc/ccclib/Types.py index c04e61d91d84..4af076791446 100644 --- a/clang/tools/ccc/ccclib/Types.py +++ b/clang/tools/ccc/ccclib/Types.py @@ -69,6 +69,8 @@ FortranType = InputType('f95-cpp-input', FortranTypeNoPP, canBeUserSpecified=Tru JavaType = InputType('java', canBeUserSpecified=True) # Misc. +LLVMAsmType = InputType('llvm-asm', tempSuffix='ll') +LLVMBCType = InputType('llvm-bc', tempSuffix='bc') PlistType = InputType('plist', tempSuffix='plist') PCHType = InputType('precompiled-header', tempSuffix='gch') ObjectType = InputType('object', tempSuffix='o') -- GitLab From a7ff032643e9664dba72a8807864aef29c6f0857 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 18:00:14 +0000 Subject: [PATCH 205/682] ccc: -o should not be automatically forwarded to generic gcc tools. llvm-svn: 63015 --- clang/tools/ccc/ccclib/Arguments.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index e936aec4a71d..7c5765c28da2 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -82,7 +82,7 @@ class Option(object): return self.name not in ('-E', '-S', '-c', '-arch', '-fsyntax-only', '-combine', '-x', - '-###') + '-###', '-o') class OptionGroup(Option): """OptionGroup - A fake option class used to group options so that -- GitLab From 02fe8210217066f07578438b06370cdc8d3d8209 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 18:02:34 +0000 Subject: [PATCH 206/682] Comment fix. llvm-svn: 63016 --- clang/lib/CodeGen/CGExprComplex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp index f9685d47544f..ab6dc31a93e5 100644 --- a/clang/lib/CodeGen/CGExprComplex.cpp +++ b/clang/lib/CodeGen/CGExprComplex.cpp @@ -270,7 +270,7 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val, DestType = DestType->getAsComplexType()->getElementType(); // C99 6.3.1.6: When a value of complextype is converted to another - // complex type, both the real and imaginary parts followthe conversion + // complex type, both the real and imaginary parts follow the conversion // rules for the corresponding real types. Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType); Val.second = CGF.EmitScalarConversion(Val.second, SrcType, DestType); -- GitLab From 0113928f9498a93a5c1f49e7a1e8abba75704de2 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 26 Jan 2009 18:08:55 +0000 Subject: [PATCH 207/682] Update VS project files. llvm-svn: 63017 --- llvm/win32/Analysis/Analysis.vcproj | 4 ++++ llvm/win32/CodeGen/CodeGen.vcproj | 20 ++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/llvm/win32/Analysis/Analysis.vcproj b/llvm/win32/Analysis/Analysis.vcproj index c631a66c208d..6119a2bf7038 100644 --- a/llvm/win32/Analysis/Analysis.vcproj +++ b/llvm/win32/Analysis/Analysis.vcproj @@ -435,6 +435,10 @@ RelativePath="..\..\lib\Analysis\Ipa\CallGraphSCCPass.cpp" > + + diff --git a/llvm/win32/CodeGen/CodeGen.vcproj b/llvm/win32/CodeGen/CodeGen.vcproj index 7707e790278b..b0f33152793e 100644 --- a/llvm/win32/CodeGen/CodeGen.vcproj +++ b/llvm/win32/CodeGen/CodeGen.vcproj @@ -340,6 +340,10 @@ RelativePath="..\..\lib\CodeGen\IntrinsicLowering.cpp" > + + @@ -484,6 +488,14 @@ RelativePath="..\..\lib\CodeGen\ScheduleDAGEmit.cpp" > + + + + @@ -571,6 +583,14 @@ RelativePath="..\..\lib\CodeGen\SelectionDAG\ScheduleDAGRRList.cpp" > + + + + -- GitLab From 8f93bd593638b05f20ac88f60e69bc7c11c37394 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 26 Jan 2009 18:09:40 +0000 Subject: [PATCH 208/682] Many updates to Windows project files. llvm-svn: 63018 --- clang/win32/clangAST/clangAST.vcproj | 8 ++++++++ clang/win32/clangLex/clangLex.vcproj | 4 ++++ clang/win32/clangLibDriver/clangLibDriver.vcproj | 4 ++++ clang/win32/clangParse/clangParse.vcproj | 4 ++++ clang/win32/clangSema/clangSema.vcproj | 8 ++++++++ 5 files changed, 28 insertions(+) diff --git a/clang/win32/clangAST/clangAST.vcproj b/clang/win32/clangAST/clangAST.vcproj index 4cbb7de7ae1e..8795412ba8cd 100644 --- a/clang/win32/clangAST/clangAST.vcproj +++ b/clang/win32/clangAST/clangAST.vcproj @@ -154,6 +154,10 @@ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" > + + @@ -174,6 +178,10 @@ RelativePath="..\..\lib\AST\Decl.cpp" > + + diff --git a/clang/win32/clangLex/clangLex.vcproj b/clang/win32/clangLex/clangLex.vcproj index e0cb22efa1b4..5bec4b8b8e7f 100644 --- a/clang/win32/clangLex/clangLex.vcproj +++ b/clang/win32/clangLex/clangLex.vcproj @@ -210,6 +210,10 @@ RelativePath="..\..\lib\Lex\PreprocessorLexer.cpp" > + + diff --git a/clang/win32/clangLibDriver/clangLibDriver.vcproj b/clang/win32/clangLibDriver/clangLibDriver.vcproj index ffbbed943cfa..de42ef72a787 100644 --- a/clang/win32/clangLibDriver/clangLibDriver.vcproj +++ b/clang/win32/clangLibDriver/clangLibDriver.vcproj @@ -156,6 +156,10 @@ RelativePath="..\..\lib\Driver\InitHeaderSearch.cpp" > + + diff --git a/clang/win32/clangParse/clangParse.vcproj b/clang/win32/clangParse/clangParse.vcproj index 1ee5a75de7ec..4cf552530545 100644 --- a/clang/win32/clangParse/clangParse.vcproj +++ b/clang/win32/clangParse/clangParse.vcproj @@ -207,6 +207,10 @@ RelativePath="..\..\lib\Parse\ParseStmt.cpp" > + + diff --git a/clang/win32/clangSema/clangSema.vcproj b/clang/win32/clangSema/clangSema.vcproj index ef3dc58f2877..572c3effcafa 100644 --- a/clang/win32/clangSema/clangSema.vcproj +++ b/clang/win32/clangSema/clangSema.vcproj @@ -210,6 +210,10 @@ RelativePath="..\..\lib\Sema\SemaInit.cpp" > + + @@ -222,6 +226,10 @@ RelativePath="..\..\lib\Sema\SemaStmt.cpp" > + + -- GitLab From cde6e757cfe217db05352dc807b42409a2722595 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 18:21:04 +0000 Subject: [PATCH 209/682] make sure we have a definition of uintptr_t. llvm-svn: 63019 --- clang/include/clang/Basic/SourceManager.h | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index d8c17e11da58..41c2defacd5f 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -16,6 +16,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/Bitcode/SerializationFwd.h" +#include "llvm/Support/DataTypes.h" #include #include #include -- GitLab From 0c8d060715d1099fe06a4b74a058a7862c22329a Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 26 Jan 2009 18:32:24 +0000 Subject: [PATCH 210/682] Meta-data for nonfragile-abi's categories llvm-svn: 63020 --- clang/lib/CodeGen/CGObjCMac.cpp | 53 +++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index f677782ec3e8..1353047aa810 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -590,8 +590,7 @@ public: const ObjCContainerDecl *CD=0) { return 0; } - virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD) - { return; } + virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); @@ -3341,6 +3340,56 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); } +/// GenerateCategory - Build metadata for a category implementation. +/// struct _category_t { +/// const char * const name; +/// struct _class_t *const cls; +/// const struct _method_list_t * const instance_methods; +/// const struct _method_list_t * const class_methods; +/// const struct _protocol_list_t * const protocols; +/// const struct _prop_list_t * const properties; +/// } +/// +void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) +{ + const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); + std::string ExtCatName("\01l_OBJC_$_CATEGORY_" + Interface->getNameAsString()+ + "_$_" + OCD->getNameAsString()); + std::string ExtClassName("\01_OBJC_CLASS_$_" + Interface->getNameAsString()); + + std::vector Values(6); + Values[0] = GetClassName(OCD->getIdentifier()); + // meta-class entry symbol + llvm::GlobalVariable *ClassGV = + CGM.getModule().getGlobalVariable(ExtClassName); + if (!ClassGV) + ClassGV = + new llvm::GlobalVariable(ObjCTypes.ClassnfABITy, false, + llvm::GlobalValue::ExternalLinkage, + 0, + ExtClassName, + &CGM.getModule()); + UsedGlobals.push_back(ClassGV); + Values[1] = ClassGV; + Values[2] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + Values[3] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); + Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); + + llvm::Constant *Init = + llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, + Values); + llvm::GlobalVariable *GCATV + = new llvm::GlobalVariable(ObjCTypes.CategorynfABITy, + false, + llvm::GlobalValue::InternalLinkage, + Init, + ExtCatName, + &CGM.getModule()); + GCATV->setSection(".section __DATA,__data,regular,no_dead_strip"); + UsedGlobals.push_back(GCATV); + DefinedCategories.push_back(GCATV); +} /* *** */ CodeGen::CGObjCRuntime * -- GitLab From 72287a599fa229d76bf1a1adfc75b02e7bc8d095 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 18:33:51 +0000 Subject: [PATCH 211/682] Silence a bogus compiler warning. llvm-svn: 63021 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index e99c70c16428..16a9e6d9b041 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -1238,7 +1238,7 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { } // Find a point to restore the value after the barrier. - unsigned RestoreIndex; + unsigned RestoreIndex = 0; MachineBasicBlock::iterator RestorePt = findRestorePoint(BarrierMBB, Barrier, LR->end, RefsInMBB, RestoreIndex); if (RestorePt == BarrierMBB->end()) -- GitLab From 6c7e85142b0aca5f1cfe13aface10520134f7db2 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 18:43:34 +0000 Subject: [PATCH 212/682] Enhance logic in X86DAGToDAGISel::PreprocessForRMW which move load inside callseq_start to allow it to be folded into a call. It was not considering the cases where a token factor is between the load and the callseq_start. llvm-svn: 63022 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 35 ++++++++++++++----- llvm/test/CodeGen/X86/fold-call-3.ll | 45 +++++++++++++++++++++++++ 2 files changed, 72 insertions(+), 8 deletions(-) create mode 100644 llvm/test/CodeGen/X86/fold-call-3.ll diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index c1d886c32f56..04ba430d2d6e 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -432,14 +432,27 @@ static bool isRMWLoad(SDValue N, SDValue Chain, SDValue Address, /// MoveBelowCallSeqStart - Replace CALLSEQ_START operand with load's chain /// operand and move load below the call's chain operand. static void MoveBelowCallSeqStart(SelectionDAG *CurDAG, SDValue Load, - SDValue Call, SDValue Chain) { + SDValue Call, SDValue CallSeqStart) { SmallVector Ops; - for (unsigned i = 0, e = Chain.getNode()->getNumOperands(); i != e; ++i) - if (Load.getNode() == Chain.getOperand(i).getNode()) - Ops.push_back(Load.getOperand(0)); - else - Ops.push_back(Chain.getOperand(i)); - CurDAG->UpdateNodeOperands(Chain, &Ops[0], Ops.size()); + SDValue Chain = CallSeqStart.getOperand(0); + if (Chain.getNode() == Load.getNode()) + Ops.push_back(Load.getOperand(0)); + else { + assert(Chain.getOpcode() == ISD::TokenFactor && + "Unexpected CallSeqStart chain operand"); + for (unsigned i = 0, e = Chain.getNumOperands(); i != e; ++i) + if (Chain.getOperand(i).getNode() == Load.getNode()) + Ops.push_back(Load.getOperand(0)); + else + Ops.push_back(Chain.getOperand(i)); + SDValue NewChain = + CurDAG->getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size()); + Ops.clear(); + Ops.push_back(NewChain); + } + for (unsigned i = 1, e = CallSeqStart.getNumOperands(); i != e; ++i) + Ops.push_back(CallSeqStart.getOperand(i)); + CurDAG->UpdateNodeOperands(CallSeqStart, &Ops[0], Ops.size()); CurDAG->UpdateNodeOperands(Load, Call.getOperand(0), Load.getOperand(1), Load.getOperand(2)); Ops.clear(); @@ -468,7 +481,13 @@ static bool isCalleeLoad(SDValue Callee, SDValue &Chain) { return false; Chain = Chain.getOperand(0); } - return Chain.getOperand(0).getNode() == Callee.getNode(); + + if (Chain.getOperand(0).getNode() == Callee.getNode()) + return true; + if (Chain.getOperand(0).getOpcode() == ISD::TokenFactor && + Callee.getValue(1).isOperandOf(Chain.getOperand(0).getNode())) + return true; + return false; } diff --git a/llvm/test/CodeGen/X86/fold-call-3.ll b/llvm/test/CodeGen/X86/fold-call-3.ll new file mode 100644 index 000000000000..824ae003da25 --- /dev/null +++ b/llvm/test/CodeGen/X86/fold-call-3.ll @@ -0,0 +1,45 @@ +; RUN: llvm-as < %s | llc -mtriple=x86_64-apple-darwin | grep call | grep 560 +; rdar://6522427 + + %"struct.clang::Action" = type { %"struct.clang::ActionBase" } + %"struct.clang::ActionBase" = type { i32 (...)** } + %"struct.clang::ActionBase::ActionResult<0u>" = type { i8*, i8 } +@NumTrials = internal global i32 10000000 ; [#uses=2] +@llvm.used = appending global [1 x i8*] [ i8* bitcast (void (i8*, %"struct.clang::Action"*)* @_Z25RawPointerPerformanceTestPvRN5clang6ActionE to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define void @_Z25RawPointerPerformanceTestPvRN5clang6ActionE(i8* %Val, %"struct.clang::Action"* %Actions) nounwind { +entry: + %0 = alloca %"struct.clang::ActionBase::ActionResult<0u>", align 8 ; <%"struct.clang::ActionBase::ActionResult<0u>"*> [#uses=3] + %1 = load i32* @NumTrials, align 4 ; [#uses=1] + %2 = icmp eq i32 %1, 0 ; [#uses=1] + br i1 %2, label %return, label %bb.nph + +bb.nph: ; preds = %entry + %3 = getelementptr %"struct.clang::Action"* %Actions, i64 0, i32 0, i32 0 ; [#uses=1] + %mrv_gep = bitcast %"struct.clang::ActionBase::ActionResult<0u>"* %0 to i64* ; [#uses=1] + %mrv_gep1 = getelementptr %"struct.clang::ActionBase::ActionResult<0u>"* %0, i64 0, i32 1 ; [#uses=1] + %4 = bitcast i8* %mrv_gep1 to i64* ; [#uses=1] + %5 = getelementptr %"struct.clang::ActionBase::ActionResult<0u>"* %0, i64 0, i32 0 ; [#uses=1] + br label %bb + +bb: ; preds = %bb, %bb.nph + %Trial.01 = phi i32 [ 0, %bb.nph ], [ %12, %bb ] ; [#uses=1] + %Val_addr.02 = phi i8* [ %Val, %bb.nph ], [ %11, %bb ] ; [#uses=1] + %6 = load i32 (...)*** %3, align 8 ; [#uses=1] + %7 = getelementptr i32 (...)** %6, i64 70 ; [#uses=1] + %8 = load i32 (...)** %7, align 8 ; [#uses=1] + %9 = bitcast i32 (...)* %8 to { i64, i64 } (%"struct.clang::Action"*, i8*)* ; <{ i64, i64 } (%"struct.clang::Action"*, i8*)*> [#uses=1] + %10 = call { i64, i64 } %9(%"struct.clang::Action"* %Actions, i8* %Val_addr.02) nounwind ; <{ i64, i64 }> [#uses=2] + %mrv_gr = extractvalue { i64, i64 } %10, 0 ; [#uses=1] + store i64 %mrv_gr, i64* %mrv_gep + %mrv_gr2 = extractvalue { i64, i64 } %10, 1 ; [#uses=1] + store i64 %mrv_gr2, i64* %4 + %11 = load i8** %5, align 8 ; [#uses=1] + %12 = add i32 %Trial.01, 1 ; [#uses=2] + %13 = load i32* @NumTrials, align 4 ; [#uses=1] + %14 = icmp ult i32 %12, %13 ; [#uses=1] + br i1 %14, label %bb, label %return + +return: ; preds = %bb, %entry + ret void +} -- GitLab From 827c76305162f5a1e88a8a161381f54c4f6cb9e3 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 19:05:20 +0000 Subject: [PATCH 213/682] ABITestGen: Add generation of vector types. llvm-svn: 63024 --- clang/utils/ABITest/ABITestGen.py | 50 +++++++++++++++++-------------- clang/utils/ABITest/TypeGen.py | 15 ++++++++-- 2 files changed, 41 insertions(+), 24 deletions(-) diff --git a/clang/utils/ABITest/ABITestGen.py b/clang/utils/ABITest/ABITestGen.py index c50abe1ea979..957ce2bb16b1 100755 --- a/clang/utils/ABITest/ABITestGen.py +++ b/clang/utils/ABITest/ABITestGen.py @@ -181,14 +181,14 @@ class TypePrinter: yield '{ %s }'%(', '.join(elements)) elif isinstance(t, ComplexType): for t in self.getTestValues(t.elementType): - yield '%s + %si'%(t,t) - elif isinstance(t, ArrayType) and not t.isVector: + yield '%s + %s * 1i'%(t,t) + elif isinstance(t, ArrayType): values = list(self.getTestValues(t.elementType)) if not values: yield '{ }' - for i in range(t.size): + for i in range(t.numElements): for v in values: - elements = [random.choice(values) for i in range(t.size)] + elements = [random.choice(values) for i in range(t.numElements)] elements[i] = v yield '{ %s }'%(', '.join(elements)) else: @@ -220,9 +220,11 @@ class TypePrinter: elif isinstance(t, ComplexType): self.printValueOfType(prefix, '(__real %s)'%name, t.elementType, output=output,indent=indent) self.printValueOfType(prefix, '(__imag %s)'%name, t.elementType, output=output,indent=indent) - elif isinstance(t, ArrayType) and not t.isVector: - for i in range(t.size): - self.printValueOfType(prefix, '(%s)[%d]'%(name,i), t.elementType, output=output,indent=indent) + elif isinstance(t, ArrayType): + for i in range(t.numElements): + # Access in this fashion as a hackish way to portably + # access vectors. + self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent) else: raise NotImplementedError,'Cannot print value of type: "%s"'%(t,) @@ -346,24 +348,28 @@ def main(): # Contruct type generator builtins = [] ints = [] - if opts.useChar: ints.append('char') - if opts.useShort: ints.append('short') - if opts.useInt: ints.append('int') - if opts.useLong: ints.append('long') - if opts.useLongLong: ints.append('long long') + if opts.useChar: ints.append(('char',1)) + if opts.useShort: ints.append(('short',2)) + if opts.useInt: ints.append(('int',4)) + # FIXME: Wrong size. + if opts.useLong: ints.append(('long',4)) + if opts.useLongLong: ints.append(('long long',8)) if opts.useUnsigned: - ints = (['unsigned %s'%i for i in ints] + - ['signed %s'%i for i in ints]) + ints = ([('unsigned %s'%i,s) for i,s in ints] + + [('signed %s'%i,s) for i,s in ints]) builtins.extend(ints) - if opts.useBool: builtins.append('_Bool') - if opts.useFloat: builtins.append('float') - if opts.useDouble: builtins.append('double') - if opts.useLongDouble: builtins.append('long double') - if opts.useVoidPointer: builtins.append('void*') - - btg = FixedTypeGenerator(map(BuiltinType,builtins)) - sbtg = FixedTypeGenerator(map(BuiltinType,['char','int','float'])) + if opts.useBool: builtins.append(('_Bool',1)) + if opts.useFloat: builtins.append(('float',4)) + if opts.useDouble: builtins.append(('double',8)) + if opts.useLongDouble: builtins.append(('long double',16)) + # FIXME: Wrong size. + if opts.useVoidPointer: builtins.append(('void*',4)) + + btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins]) + sbtg = FixedTypeGenerator([BuiltinType('char',1), + BuiltinType('int',4), + BuiltinType('float',4)]) atg = AnyTypeGenerator() artg = AnyTypeGenerator() diff --git a/clang/utils/ABITest/TypeGen.py b/clang/utils/ABITest/TypeGen.py index 3074a5627338..50dd77c61807 100644 --- a/clang/utils/ABITest/TypeGen.py +++ b/clang/utils/ABITest/TypeGen.py @@ -15,8 +15,12 @@ from Enumeration import * # Actual type types class BuiltinType: - def __init__(self, name): + def __init__(self, name, size): self.name = name + self.size = size + + def sizeof(self): + return self.size def __str__(self): return self.name @@ -49,6 +53,12 @@ class ArrayType: self.isVector = isVector self.elementType = elementType self.size = size + if isVector: + eltSize = self.elementType.sizeof() + assert not (self.size % eltSize) + self.numElements = self.size // eltSize + else: + self.numElements = self.size def __str__(self): if self.isVector: @@ -305,7 +315,8 @@ class AnyTypeGenerator(TypeGenerator): def test(): atg = AnyTypeGenerator() - btg = FixedTypeGenerator(map(BuiltinType,['int','float'])) + btg = FixedTypeGenerator([BuiltinType('int',4), + BuiltinType('float',4)]) atg.addGenerator( btg ) atg.addGenerator( ComplexTypeGenerator(btg) ) atg.addGenerator( RecordTypeGenerator(atg, True, 2) ) -- GitLab From feffdec2440bea5c82d4ecb4754f81c2175e6059 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 26 Jan 2009 19:12:06 +0000 Subject: [PATCH 214/682] Fix an issue where LiveIntervals was trying to be smart about removing kill markers, and ended up foiling the interval reconstruction. This allows us to turn on reconstruction in the pre alloc splitter, which fixes a number of miscompilations. llvm-svn: 63025 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 46 +++++++------------------- 1 file changed, 12 insertions(+), 34 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 16a9e6d9b041..0325f7cd02bc 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -748,12 +748,12 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); + LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); + // FIXME: Need to set kills properly for inter-block stuff. if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex); if (intrablock) LI->addKill(ret, EndIndex); - - LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); } else if (ContainsDefs && ContainsUses){ SmallPtrSet& BlockDefs = Defs[MBB]; SmallPtrSet& BlockUses = Uses[MBB]; @@ -805,13 +805,13 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); + LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); + if (foundUse && LI->isKill(ret, StartIndex)) LI->removeKill(ret, StartIndex); if (intrablock) { LI->addKill(ret, EndIndex); } - - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); } // Memoize results so we don't have to recompute them. @@ -1131,18 +1131,10 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, TII->reMaterialize(MBB, RestorePt, vreg, DefMI); LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); - if (KillPt->getParent() == BarrierMBB) { - VNInfo* After = UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, - LIs->getDefIndex(RestoreIdx)); - - RenumberValno(After); - - ++NumSplits; - ++NumRemats; - return true; - } - - RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIdx); + ReconstructLiveInterval(CurrLI); + unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt)); + RematIdx = LiveIntervals::getDefIndex(RematIdx); + RenumberValno(CurrLI->findDefinedVNInfo(RematIdx)); ++NumSplits; ++NumRemats; @@ -1315,28 +1307,14 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { MachineInstr *LoadMI = prior(RestorePt); LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex); - // If live interval is spilled in the same block as the barrier, just - // create a hole in the interval. - if (!DefMBB || - (SpillMI && SpillMI->getParent() == BarrierMBB)) { - // Update spill stack slot live interval. - UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, - LIs->getDefIndex(RestoreIndex)); - - VNInfo* After = UpdateRegisterInterval(ValNo, - LIs->getUseIndex(SpillIndex)+1, - LIs->getDefIndex(RestoreIndex)); - RenumberValno(After); - - ++NumSplits; - return true; - } - // Update spill stack slot live interval. UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, LIs->getDefIndex(RestoreIndex)); - RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIndex); + ReconstructLiveInterval(CurrLI); + unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); + RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx); + RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx)); ++NumSplits; return true; -- GitLab From 5e235d3a7e97677ef1c6df4859b2e5b60bc70201 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 26 Jan 2009 19:18:06 +0000 Subject: [PATCH 215/682] Get rid of a bunch of dead code now that interval reconstruction is enabled. llvm-svn: 63026 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 321 ------------------------- 1 file changed, 321 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 0325f7cd02bc..49cc67ba1f04 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -139,26 +139,11 @@ namespace { void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned); - VNInfo* UpdateRegisterInterval(VNInfo*, unsigned, unsigned); - - bool ShrinkWrapToLastUse(MachineBasicBlock*, VNInfo*, - SmallVector&, - SmallPtrSet&); - - void ShrinkWrapLiveInterval(VNInfo*, MachineBasicBlock*, MachineBasicBlock*, - MachineBasicBlock*, SmallPtrSet&, - DenseMap >&, - DenseMap >&, - SmallVector&); - bool SplitRegLiveInterval(LiveInterval*); bool SplitRegLiveIntervals(const TargetRegisterClass **, SmallPtrSet&); - void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo, - MachineInstr* DefMI, unsigned RestoreIdx); - bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, MachineBasicBlock* BarrierMBB); bool Rematerialize(unsigned vreg, VNInfo* ValNo, @@ -423,176 +408,6 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex, } } -/// UpdateRegisterInterval - Given the specified val# of the current live -/// interval is being split, and the spill and restore indices, update the live -/// interval accordingly. -VNInfo* -PreAllocSplitting::UpdateRegisterInterval(VNInfo *ValNo, unsigned SpillIndex, - unsigned RestoreIndex) { - assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB && - "Expect restore in the barrier mbb"); - - SmallVector, 4> Before; - SmallVector, 4> After; - SmallVector BeforeKills; - SmallVector AfterKills; - SmallPtrSet Processed; - - // First, let's figure out which parts of the live interval is now defined - // by the restore, which are defined by the original definition. - const LiveRange *LR = CurrLI->getLiveRangeContaining(RestoreIndex); - After.push_back(std::make_pair(RestoreIndex, LR->end)); - if (CurrLI->isKill(ValNo, LR->end)) - AfterKills.push_back(LR->end); - - assert(LR->contains(SpillIndex)); - if (SpillIndex > LR->start) { - Before.push_back(std::make_pair(LR->start, SpillIndex)); - BeforeKills.push_back(SpillIndex); - } - Processed.insert(LR); - - // Start from the restore mbb, figure out what part of the live interval - // are defined by the restore. - SmallVector WorkList; - MachineBasicBlock *MBB = BarrierMBB; - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - WorkList.push_back(*SI); - - SmallPtrSet ProcessedBlocks; - ProcessedBlocks.insert(MBB); - - while (!WorkList.empty()) { - MBB = WorkList.back(); - WorkList.pop_back(); - unsigned Idx = LIs->getMBBStartIdx(MBB); - LR = CurrLI->getLiveRangeContaining(Idx); - if (LR && LR->valno == ValNo && !Processed.count(LR)) { - After.push_back(std::make_pair(LR->start, LR->end)); - if (CurrLI->isKill(ValNo, LR->end)) - AfterKills.push_back(LR->end); - Idx = LIs->getMBBEndIdx(MBB); - if (LR->end > Idx) { - // Live range extend beyond at least one mbb. Let's see what other - // mbbs it reaches. - LIs->findReachableMBBs(LR->start, LR->end, WorkList); - } - Processed.insert(LR); - } - - ProcessedBlocks.insert(MBB); - if (LR) - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - if (!ProcessedBlocks.count(*SI)) - WorkList.push_back(*SI); - } - - for (LiveInterval::iterator I = CurrLI->begin(), E = CurrLI->end(); - I != E; ++I) { - LiveRange *LR = I; - if (LR->valno == ValNo && !Processed.count(LR)) { - Before.push_back(std::make_pair(LR->start, LR->end)); - if (CurrLI->isKill(ValNo, LR->end)) - BeforeKills.push_back(LR->end); - } - } - - // Now create new val#s to represent the live ranges defined by the old def - // those defined by the restore. - unsigned AfterDef = ValNo->def; - MachineInstr *AfterCopy = ValNo->copy; - bool HasPHIKill = ValNo->hasPHIKill; - CurrLI->removeValNo(ValNo); - VNInfo *BValNo = (Before.empty()) - ? NULL - : CurrLI->getNextValue(AfterDef, AfterCopy, LIs->getVNInfoAllocator()); - if (BValNo) - CurrLI->addKills(BValNo, BeforeKills); - - VNInfo *AValNo = (After.empty()) - ? NULL - : CurrLI->getNextValue(RestoreIndex, 0, LIs->getVNInfoAllocator()); - if (AValNo) { - AValNo->hasPHIKill = HasPHIKill; - CurrLI->addKills(AValNo, AfterKills); - } - - for (unsigned i = 0, e = Before.size(); i != e; ++i) { - unsigned Start = Before[i].first; - unsigned End = Before[i].second; - CurrLI->addRange(LiveRange(Start, End, BValNo)); - } - for (unsigned i = 0, e = After.size(); i != e; ++i) { - unsigned Start = After[i].first; - unsigned End = After[i].second; - CurrLI->addRange(LiveRange(Start, End, AValNo)); - } - - return AValNo; -} - -/// ShrinkWrapToLastUse - There are uses of the current live interval in the -/// given block, shrink wrap the live interval to the last use (i.e. remove -/// from last use to the end of the mbb). In case mbb is the where the barrier -/// is, remove from the last use to the barrier. -bool -PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB, VNInfo *ValNo, - SmallVector &Uses, - SmallPtrSet &UseMIs) { - MachineOperand *LastMO = 0; - MachineInstr *LastMI = 0; - if (MBB != BarrierMBB && Uses.size() == 1) { - // Single use, no need to traverse the block. We can't assume this for the - // barrier bb though since the use is probably below the barrier. - LastMO = Uses[0]; - LastMI = LastMO->getParent(); - } else { - MachineBasicBlock::iterator MEE = MBB->begin(); - MachineBasicBlock::iterator MII; - if (MBB == BarrierMBB) - MII = Barrier; - else - MII = MBB->end(); - while (MII != MEE) { - --MII; - MachineInstr *UseMI = &*MII; - if (!UseMIs.count(UseMI)) - continue; - for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = UseMI->getOperand(i); - if (MO.isReg() && MO.getReg() == CurrLI->reg) { - LastMO = &MO; - break; - } - } - LastMI = UseMI; - break; - } - } - - // Cut off live range from last use (or beginning of the mbb if there - // are no uses in it) to the end of the mbb. - unsigned RangeStart, RangeEnd = LIs->getMBBEndIdx(MBB)+1; - if (LastMI) { - RangeStart = LIs->getUseIndex(LIs->getInstructionIndex(LastMI))+1; - assert(!LastMO->isKill() && "Last use already terminates the interval?"); - LastMO->setIsKill(); - } else { - assert(MBB == BarrierMBB); - RangeStart = LIs->getMBBStartIdx(MBB); - } - if (MBB == BarrierMBB) - RangeEnd = LIs->getUseIndex(BarrierIdx)+1; - CurrLI->removeRange(RangeStart, RangeEnd); - if (LastMI) - CurrLI->addKill(ValNo, RangeStart); - - // Return true if the last use becomes a new kill. - return LastMI; -} - /// PerformPHIConstruction - From properly set up use and def lists, use a PHI /// construction algorithm to compute the ranges and valnos for an interval. VNInfo* PreAllocSplitting::PerformPHIConstruction( @@ -890,142 +705,6 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { } } -/// ShrinkWrapLiveInterval - Recursively traverse the predecessor -/// chain to find the new 'kills' and shrink wrap the live interval to the -/// new kill indices. -void -PreAllocSplitting::ShrinkWrapLiveInterval(VNInfo *ValNo, MachineBasicBlock *MBB, - MachineBasicBlock *SuccMBB, MachineBasicBlock *DefMBB, - SmallPtrSet &Visited, - DenseMap > &Uses, - DenseMap > &UseMIs, - SmallVector &UseMBBs) { - if (Visited.count(MBB)) - return; - - // If live interval is live in another successor path, then we can't process - // this block. But we may able to do so after all the successors have been - // processed. - if (MBB != BarrierMBB) { - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) { - MachineBasicBlock *SMBB = *SI; - if (SMBB == SuccMBB) - continue; - if (CurrLI->liveAt(LIs->getMBBStartIdx(SMBB))) - return; - } - } - - Visited.insert(MBB); - - DenseMap >::iterator - UMII = Uses.find(MBB); - if (UMII != Uses.end()) { - // At least one use in this mbb, lets look for the kill. - DenseMap >::iterator - UMII2 = UseMIs.find(MBB); - if (ShrinkWrapToLastUse(MBB, ValNo, UMII->second, UMII2->second)) - // Found a kill, shrink wrapping of this path ends here. - return; - } else if (MBB == DefMBB) { - // There are no uses after the def. - MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def); - if (UseMBBs.empty()) { - // The only use must be below barrier in the barrier block. It's safe to - // remove the def. - LIs->RemoveMachineInstrFromMaps(DefMI); - DefMI->eraseFromParent(); - CurrLI->removeRange(ValNo->def, LIs->getMBBEndIdx(MBB)+1); - } - } else if (MBB == BarrierMBB) { - // Remove entire live range from start of mbb to barrier. - CurrLI->removeRange(LIs->getMBBStartIdx(MBB), - LIs->getUseIndex(BarrierIdx)+1); - } else { - // Remove entire live range of the mbb out of the live interval. - CurrLI->removeRange(LIs->getMBBStartIdx(MBB), LIs->getMBBEndIdx(MBB)+1); - } - - if (MBB == DefMBB) - // Reached the def mbb, stop traversing this path further. - return; - - // Traverse the pathes up the predecessor chains further. - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - MachineBasicBlock *Pred = *PI; - if (Pred == MBB) - continue; - if (Pred == DefMBB && ValNo->hasPHIKill) - // Pred is the def bb and the def reaches other val#s, we must - // allow the value to be live out of the bb. - continue; - if (!CurrLI->liveAt(LIs->getMBBEndIdx(Pred)-1)) - return; - ShrinkWrapLiveInterval(ValNo, Pred, MBB, DefMBB, Visited, - Uses, UseMIs, UseMBBs); - } - - return; -} - - -void PreAllocSplitting::RepairLiveInterval(LiveInterval* CurrLI, - VNInfo* ValNo, - MachineInstr* DefMI, - unsigned RestoreIdx) { - // Shrink wrap the live interval by walking up the CFG and find the - // new kills. - // Now let's find all the uses of the val#. - DenseMap > Uses; - DenseMap > UseMIs; - SmallPtrSet Seen; - SmallVector UseMBBs; - for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg), - UE = MRI->use_end(); UI != UE; ++UI) { - MachineOperand &UseMO = UI.getOperand(); - MachineInstr *UseMI = UseMO.getParent(); - unsigned UseIdx = LIs->getInstructionIndex(UseMI); - LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx); - if (ULR->valno != ValNo) - continue; - MachineBasicBlock *UseMBB = UseMI->getParent(); - // Remember which other mbb's use this val#. - if (Seen.insert(UseMBB) && UseMBB != BarrierMBB) - UseMBBs.push_back(UseMBB); - DenseMap >::iterator - UMII = Uses.find(UseMBB); - if (UMII != Uses.end()) { - DenseMap >::iterator - UMII2 = UseMIs.find(UseMBB); - UMII->second.push_back(&UseMO); - UMII2->second.insert(UseMI); - } else { - SmallVector Ops; - Ops.push_back(&UseMO); - Uses.insert(std::make_pair(UseMBB, Ops)); - SmallPtrSet MIs; - MIs.insert(UseMI); - UseMIs.insert(std::make_pair(UseMBB, MIs)); - } - } - - // Walk up the predecessor chains. - SmallPtrSet Visited; - ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited, - Uses, UseMIs, UseMBBs); - - // Remove live range from barrier to the restore. FIXME: Find a better - // point to re-start the live interval. - VNInfo* AfterValNo = UpdateRegisterInterval(ValNo, - LIs->getUseIndex(BarrierIdx)+1, - LIs->getDefIndex(RestoreIdx)); - - // Attempt to renumber the new valno into a new vreg. - RenumberValno(AfterValNo); -} - /// RenumberValno - Split the given valno out into a new vreg, allowing it to /// be allocated to a different register. This function creates a new vreg, /// copies the valno and its live ranges over to the new vreg's interval, -- GitLab From 4b4622454c2836ed27bf2fcb5ad30256fe14802e Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Mon, 26 Jan 2009 19:26:01 +0000 Subject: [PATCH 216/682] During bittest switch lowering emit shift in the test block, which should (theoretically) allow us to generate more efficient code. We don't do this now though :) llvm-svn: 63027 --- .../SelectionDAG/SelectionDAGBuild.cpp | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index f971069e82f5..c467d9c3cb43 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -1416,14 +1416,8 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { else ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB); - // Make desired shift - SDValue SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(), - DAG.getConstant(1, TLI.getPointerTy()), - ShiftOp); - - unsigned SwitchReg = FuncInfo.MakeReg(TLI.getPointerTy()); - SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), SwitchReg, SwitchVal); - B.Reg = SwitchReg; + B.Reg = FuncInfo.MakeReg(TLI.getShiftAmountTy()); + SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), B.Reg, ShiftOp); // Set NextBlock to be the MBB immediately after the current one, if any. // This is used to avoid emitting unnecessary branches to the next block. @@ -1453,10 +1447,14 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, unsigned Reg, BitTestCase &B) { - // Emit bit tests and jumps - SDValue SwitchVal = DAG.getCopyFromReg(getControlRoot(), Reg, - TLI.getPointerTy()); + // Make desired shift + SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), Reg, + TLI.getShiftAmountTy()); + SDValue SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(), + DAG.getConstant(1, TLI.getPointerTy()), + ShiftOp); + // Emit bit tests and jumps SDValue AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal, DAG.getConstant(B.Mask, TLI.getPointerTy())); SDValue AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp.getValueType()), -- GitLab From 5a7971e0c31a10959d555b3c321baece799afb73 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 19:29:26 +0000 Subject: [PATCH 217/682] This change refactors some of the low-level lexer interfaces a bit. Token now has a class of kinds for "literals", which include numeric constants, strings, etc. These tokens can optionally have a pointer to the start of the token in the lexer buffer. This makes it faster to get spelling and do other gymnastics, because we don't have to go through source locations. This change is performance neutral, but will make other changes more feasible down the road. llvm-svn: 63028 --- clang/Driver/CacheTokens.cpp | 37 +++++-------- clang/Driver/PrintPreprocessedOutput.cpp | 2 + clang/include/clang/Lex/Preprocessor.h | 12 ++--- clang/include/clang/Lex/ScratchBuffer.h | 8 +-- clang/include/clang/Lex/Token.h | 66 +++++++++++++++++------- clang/include/clang/Parse/Parser.h | 5 +- clang/lib/Lex/Lexer.cpp | 13 +++-- clang/lib/Lex/MacroArgs.cpp | 3 +- clang/lib/Lex/PPCaching.cpp | 2 +- clang/lib/Lex/PPMacroExpansion.cpp | 24 +++++---- clang/lib/Lex/Pragma.cpp | 5 +- clang/lib/Lex/Preprocessor.cpp | 28 +++++++--- clang/lib/Lex/ScratchBuffer.cpp | 16 ++---- clang/lib/Lex/TokenLexer.cpp | 39 ++++++++------ clang/lib/Rewrite/TokenRewriter.cpp | 5 +- 15 files changed, 153 insertions(+), 112 deletions(-) diff --git a/clang/Driver/CacheTokens.cpp b/clang/Driver/CacheTokens.cpp index 1d33105668fc..fcb4d2f12db1 100644 --- a/clang/Driver/CacheTokens.cpp +++ b/clang/Driver/CacheTokens.cpp @@ -140,32 +140,19 @@ void PTHWriter::EmitToken(const Token& T) { Emit32(ResolveID(T.getIdentifierInfo())); Emit32(fpos); - // For specific tokens we cache their spelling. - if (T.getIdentifierInfo()) - return; - - switch (T.getKind()) { - default: - break; - case tok::string_literal: - case tok::wide_string_literal: - case tok::angle_string_literal: - case tok::numeric_constant: - case tok::char_constant: { - // FIXME: This uses the slow getSpelling(). Perhaps we do better - // in the future? This only slows down PTH generation. - const std::string& spelling = PP.getSpelling(T); - const char* s = spelling.c_str(); - - // Get the string entry. - llvm::StringMapEntry *E = - &CachedStrs.GetOrCreateValue(s, s+spelling.size()); - - // Store the address of the string entry in our spelling map. - (*CurSpellMap).push_back(std::make_pair(fpos, E)); + // Literals (strings, numbers, characters) get cached spellings. + if (T.isLiteral()) { + // FIXME: This uses the slow getSpelling(). Perhaps we do better + // in the future? This only slows down PTH generation. + const std::string &spelling = PP.getSpelling(T); + const char* s = spelling.c_str(); + + // Get the string entry. + llvm::StringMapEntry *E = + &CachedStrs.GetOrCreateValue(s, s+spelling.size()); - break; - } + // Store the address of the string entry in our spelling map. + CurSpellMap->push_back(std::make_pair(fpos, E)); } } diff --git a/clang/Driver/PrintPreprocessedOutput.cpp b/clang/Driver/PrintPreprocessedOutput.cpp index 64cc4c8be65b..deecacb1f4c5 100644 --- a/clang/Driver/PrintPreprocessedOutput.cpp +++ b/clang/Driver/PrintPreprocessedOutput.cpp @@ -430,6 +430,7 @@ bool PrintPPOutputPPCallbacks::AvoidConcat(const Token &PrevTok, // Avoid spelling identifiers, the most common form of token. FirstChar = II->getName()[0]; } else if (!Tok.needsCleaning()) { + // FIXME: SPEED UP LITERALS! SourceManager &SrcMgr = PP.getSourceManager(); FirstChar = *SrcMgr.getCharacterData(SrcMgr.getSpellingLoc(Tok.getLocation())); @@ -556,6 +557,7 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, const char *Str = II->getName(); unsigned Len = Tok.needsCleaning() ? strlen(Str) : Tok.getLength(); OS.write(Str, Len); + // FIXME: ACCELERATE LITERALS } else if (Tok.getLength() < 256) { const char *TokPtr = Buffer; unsigned Len = PP.getSpelling(Tok, TokPtr); diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index bf47bab29529..f6391d9781a2 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -415,7 +415,7 @@ public: /// cached tokens doesn't get re-parsed and re-resolved after a backtrack is /// invoked. void AnnotateCachedTokens(const Token &Tok) { - assert(Tok.isAnnotationToken() && "Expected annotation token"); + assert(Tok.isAnnotation() && "Expected annotation token"); if (CachedLexPos != 0 && isBacktrackEnabled()) AnnotatePreviousCachedTokens(Tok); } @@ -463,11 +463,11 @@ public: return *SourceMgr.getCharacterData(SL); } - /// CreateString - Plop the specified string into a scratch buffer and return - /// a location for it. If specified, the source location provides a source - /// location for the token. - SourceLocation CreateString(const char *Buf, unsigned Len, - SourceLocation SourceLoc = SourceLocation()); + /// CreateString - Plop the specified string into a scratch buffer and set the + /// specified token's location and length to it. If specified, the source + /// location provides a location of the instantiation point of the token. + void CreateString(const char *Buf, unsigned Len, + Token &Tok, SourceLocation SourceLoc = SourceLocation()); /// DumpToken - Print the token to stderr, used for debugging. /// diff --git a/clang/include/clang/Lex/ScratchBuffer.h b/clang/include/clang/Lex/ScratchBuffer.h index eec6a251a560..6506f9262947 100644 --- a/clang/include/clang/Lex/ScratchBuffer.h +++ b/clang/include/clang/Lex/ScratchBuffer.h @@ -30,17 +30,11 @@ class ScratchBuffer { public: ScratchBuffer(SourceManager &SM); - /// getToken - Splat the specified text into a temporary MemoryBuffer and - /// return a SourceLocation that refers to the token. The SourceLoc value - /// gives a virtual location that the token will appear to be from. - SourceLocation getToken(const char *Buf, unsigned Len, - SourceLocation SourceLoc); - /// getToken - Splat the specified text into a temporary MemoryBuffer and /// return a SourceLocation that refers to the token. This is just like the /// previous method, but returns a location that indicates the physloc of the /// token. - SourceLocation getToken(const char *Buf, unsigned Len); + SourceLocation getToken(const char *Buf, unsigned Len, const char *&DestPtr); private: void AllocScratchBuffer(unsigned RequestLen); diff --git a/clang/include/clang/Lex/Token.h b/clang/include/clang/Lex/Token.h index c0dd2b7837cd..73e087ecb6d9 100644 --- a/clang/include/clang/Lex/Token.h +++ b/clang/include/clang/Lex/Token.h @@ -34,21 +34,28 @@ class Token { /// The location of the token. SourceLocation Loc; - // Conceptually these next two fields could be in a union with - // access depending on isAnnotationToken(). However, this causes gcc - // 4.2 to pessimize LexTokenInternal, a very performance critical - // routine. Keeping as separate members with casts until a more - // beautiful fix presents itself. + // Conceptually these next two fields could be in a union. However, this + // causes gcc 4.2 to pessimize LexTokenInternal, a very performance critical + // routine. Keeping as separate members with casts until a more beautiful fix + // presents itself. /// UintData - This holds either the length of the token text, when /// a normal token, or the end of the SourceRange when an annotation /// token. unsigned UintData; - /// PtrData - For normal tokens, this points to the uniqued - /// information for the identifier (if an identifier token) or - /// null. For annotation tokens, this points to information specific - /// to the annotation token. + /// PtrData - This is a union of four different pointer types, which depends + /// on what type of token this is: + /// Identifiers, keywords, etc: + /// This is an IdentifierInfo*, which contains the uniqued identifier + /// spelling. + /// Literals: isLiteral() returns true. + /// This is a pointer to the start of the token in a text buffer, which + /// may be dirty (have trigraphs / escaped newlines). + /// Annotations (resolved type names, C++ scopes, etc): isAnnotation(). + /// This is a pointer to sema-specific data for the annotation token. + /// Other: + /// This is null. void *PtrData; /// Kind - The actual flavor of token this is. @@ -77,32 +84,40 @@ public: bool is(tok::TokenKind K) const { return Kind == (unsigned) K; } bool isNot(tok::TokenKind K) const { return Kind != (unsigned) K; } - bool isAnnotationToken() const { + /// isLiteral - Return true if this is a "literal", like a numeric + /// constant, string, etc. + bool isLiteral() const { + return is(tok::numeric_constant) || is(tok::char_constant) || + is(tok::string_literal) || is(tok::wide_string_literal) || + is(tok::angle_string_literal); + } + + bool isAnnotation() const { return is(tok::annot_typename) || is(tok::annot_cxxscope) || is(tok::annot_template_id); } - + /// getLocation - Return a source location identifier for the specified /// offset in the current file. SourceLocation getLocation() const { return Loc; } unsigned getLength() const { - assert(!isAnnotationToken() && "Annotation tokens have no length field"); + assert(!isAnnotation() && "Annotation tokens have no length field"); return UintData; } void setLocation(SourceLocation L) { Loc = L; } void setLength(unsigned Len) { - assert(!isAnnotationToken() && "Annotation tokens have no length field"); + assert(!isAnnotation() && "Annotation tokens have no length field"); UintData = Len; } SourceLocation getAnnotationEndLoc() const { - assert(isAnnotationToken() && "Used AnnotEndLocID on non-annotation token"); + assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); return SourceLocation::getFromRawEncoding(UintData); } void setAnnotationEndLoc(SourceLocation L) { - assert(isAnnotationToken() && "Used AnnotEndLocID on non-annotation token"); + assert(isAnnotation() && "Used AnnotEndLocID on non-annotation token"); UintData = L.getRawEncoding(); } @@ -130,19 +145,32 @@ public: } IdentifierInfo *getIdentifierInfo() const { - assert(!isAnnotationToken() && "Used IdentInfo on annotation token"); + assert(!isAnnotation() && "Used IdentInfo on annotation token!"); + if (isLiteral()) return 0; return (IdentifierInfo*) PtrData; } void setIdentifierInfo(IdentifierInfo *II) { PtrData = (void*) II; } - + + /// getLiteralData - For a literal token (numeric constant, string, etc), this + /// returns a pointer to the start of it in the text buffer if known, null + /// otherwise. + const char *getLiteralData() const { + assert(isLiteral() && "Cannot get literal data of non-literal"); + return reinterpret_cast(PtrData); + } + void setLiteralData(const char *Ptr) { + assert(isLiteral() && "Cannot set literal data of non-literal"); + PtrData = (void*)Ptr; + } + void *getAnnotationValue() const { - assert(isAnnotationToken() && "Used AnnotVal on non-annotation token"); + assert(isAnnotation() && "Used AnnotVal on non-annotation token"); return PtrData; } void setAnnotationValue(void *val) { - assert(isAnnotationToken() && "Used AnnotVal on non-annotation token"); + assert(isAnnotation() && "Used AnnotVal on non-annotation token"); PtrData = val; } diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index 191613bbcbc8..df8646df796e 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -690,10 +690,11 @@ private: if (!Tok.is(tok::identifier)) return false; - if (Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) + IdentifierInfo *II = Tok.getIdentifierInfo(); + if (Actions.isTypeName(*II, CurScope)) return true; - return Tok.getIdentifierInfo() == Ident_super; + return II == Ident_super; } OwningExprResult ParseObjCAtExpression(SourceLocation AtLocation); diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 9e8d1aa74076..03d81b3b9a16 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -624,7 +624,9 @@ void Lexer::LexNumericConstant(Token &Result, const char *CurPtr) { return LexNumericConstant(Result, ConsumeChar(CurPtr, Size, Result)); // Update the location of token as well as BufferPtr. + const char *TokStart = BufferPtr; FormTokenWithChars(Result, CurPtr, tok::numeric_constant); + Result.setLiteralData(TokStart); } /// LexStringLiteral - Lex the remainder of a string literal, after having lexed @@ -655,8 +657,10 @@ void Lexer::LexStringLiteral(Token &Result, const char *CurPtr, bool Wide) { Diag(NulCharacter, diag::null_in_string); // Update the location of the token as well as the BufferPtr instance var. + const char *TokStart = BufferPtr; FormTokenWithChars(Result, CurPtr, Wide ? tok::wide_string_literal : tok::string_literal); + Result.setLiteralData(TokStart); } /// LexAngledStringLiteral - Lex the remainder of an angled string literal, @@ -687,7 +691,9 @@ void Lexer::LexAngledStringLiteral(Token &Result, const char *CurPtr) { Diag(NulCharacter, diag::null_in_string); // Update the location of token as well as BufferPtr. + const char *TokStart = BufferPtr; FormTokenWithChars(Result, CurPtr, tok::angle_string_literal); + Result.setLiteralData(TokStart); } @@ -735,7 +741,9 @@ void Lexer::LexCharConstant(Token &Result, const char *CurPtr) { Diag(NulCharacter, diag::null_in_char); // Update the location of token as well as BufferPtr. + const char *TokStart = BufferPtr; FormTokenWithChars(Result, CurPtr, tok::char_constant); + Result.setLiteralData(TokStart); } /// SkipWhitespace - Efficiently skip over a series of whitespace characters. @@ -901,9 +909,8 @@ bool Lexer::SaveBCPLComment(Token &Result, const char *CurPtr) { Spelling += "*/"; // add suffix. Result.setKind(tok::comment); - Result.setLocation(PP->CreateString(&Spelling[0], Spelling.size(), - Result.getLocation())); - Result.setLength(Spelling.size()); + PP->CreateString(&Spelling[0], Spelling.size(), Result, + Result.getLocation()); return true; } diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp index 77c96e0ab33f..c3d7738afe0d 100644 --- a/clang/lib/Lex/MacroArgs.cpp +++ b/clang/lib/Lex/MacroArgs.cpp @@ -225,8 +225,7 @@ Token MacroArgs::StringifyArgument(const Token *ArgToks, } } - Tok.setLength(Result.size()); - Tok.setLocation(PP.CreateString(&Result[0], Result.size())); + PP.CreateString(&Result[0], Result.size(), Tok); return Tok; } diff --git a/clang/lib/Lex/PPCaching.cpp b/clang/lib/Lex/PPCaching.cpp index ed67754e6e7d..53aa09c13040 100644 --- a/clang/lib/Lex/PPCaching.cpp +++ b/clang/lib/Lex/PPCaching.cpp @@ -89,7 +89,7 @@ const Token &Preprocessor::PeekAhead(unsigned N) { } void Preprocessor::AnnotatePreviousCachedTokens(const Token &Tok) { - assert(Tok.isAnnotationToken() && "Expected annotation token"); + assert(Tok.isAnnotation() && "Expected annotation token"); assert(CachedLexPos != 0 && "Expected to have some cached tokens"); assert(CachedTokens[CachedLexPos-1].getLocation() == Tok.getAnnotationEndLoc() && "The annotation should be until the most recent cached token"); diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index b14df735ad1c..b3e921c36894 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -429,10 +429,15 @@ static void ComputeDATE_TIME(SourceLocation &DATELoc, SourceLocation &TIMELoc, char TmpBuffer[100]; sprintf(TmpBuffer, "\"%s %2d %4d\"", Months[TM->tm_mon], TM->tm_mday, TM->tm_year+1900); - DATELoc = PP.CreateString(TmpBuffer, strlen(TmpBuffer)); + + Token TmpTok; + TmpTok.startToken(); + PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok); + DATELoc = TmpTok.getLocation(); sprintf(TmpBuffer, "\"%02d:%02d:%02d\"", TM->tm_hour, TM->tm_min, TM->tm_sec); - TIMELoc = PP.CreateString(TmpBuffer, strlen(TmpBuffer)); + PP.CreateString(TmpBuffer, strlen(TmpBuffer), TmpTok); + TIMELoc = TmpTok.getLocation(); } /// ExpandBuiltinMacro - If an identifier token is read that is to be expanded @@ -463,8 +468,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { SourceMgr.getInstantiationLineNumber(Tok.getLocation())); unsigned Length = strlen(TmpBuffer)-1; Tok.setKind(tok::numeric_constant); - Tok.setLength(Length); - Tok.setLocation(CreateString(TmpBuffer, Length+1, Tok.getLocation())); + CreateString(TmpBuffer, Length+1, Tok, Tok.getLocation()); + Tok.setLength(Length); // Trim off space. } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) { SourceLocation Loc = Tok.getLocation(); if (II == Ident__BASE_FILE__) { @@ -480,8 +485,7 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { std::string FN =SourceMgr.getSourceName(SourceMgr.getInstantiationLoc(Loc)); FN = '"' + Lexer::Stringify(FN) + '"'; Tok.setKind(tok::string_literal); - Tok.setLength(FN.size()); - Tok.setLocation(CreateString(&FN[0], FN.size(), Tok.getLocation())); + CreateString(&FN[0], FN.size(), Tok, Tok.getLocation()); } else if (II == Ident__DATE__) { if (!DATELoc.isValid()) ComputeDATE_TIME(DATELoc, TIMELoc, *this); @@ -511,8 +515,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { sprintf(TmpBuffer, "%u ", Depth); unsigned Length = strlen(TmpBuffer)-1; Tok.setKind(tok::numeric_constant); - Tok.setLength(Length); - Tok.setLocation(CreateString(TmpBuffer, Length, Tok.getLocation())); + CreateString(TmpBuffer, Length, Tok, Tok.getLocation()); + Tok.setLength(Length); // Trim off space. } else if (II == Ident__TIMESTAMP__) { // MSVC, ICC, GCC, VisualAge C++ extension. The generated string should be // of the form "Ddd Mmm dd hh::mm::ss yyyy", which is returned by asctime. @@ -540,8 +544,8 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { unsigned Len = strlen(TmpBuffer); TmpBuffer[Len-1] = '"'; // Replace the newline with a quote. Tok.setKind(tok::string_literal); - Tok.setLength(Len); - Tok.setLocation(CreateString(TmpBuffer, Len+1, Tok.getLocation())); + CreateString(TmpBuffer, Len+1, Tok, Tok.getLocation()); + Tok.setLength(Len); // Trim off space. } else { assert(0 && "Unknown identifier!"); } diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index 922af09e5006..a80ba6bd1f1f 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -156,7 +156,10 @@ void Preprocessor::Handle_Pragma(Token &Tok) { // Plop the string (including the newline and trailing null) into a buffer // where we can lex it. - SourceLocation TokLoc = CreateString(&StrVal[0], StrVal.size()); + Token TmpTok; + TmpTok.startToken(); + CreateString(&StrVal[0], StrVal.size(), TmpTok); + SourceLocation TokLoc = TmpTok.getLocation(); // Make and enter a lexer object so that we lex and expand the tokens just // like any others. diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index d0a15e45c414..cb0c850e7ead 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -266,13 +266,20 @@ unsigned Preprocessor::getSpelling(const Token &Tok, } // Otherwise, compute the start of the token in the input lexer buffer. - const char *TokStart = SourceMgr.getCharacterData(Tok.getLocation()); + const char *TokStart = 0; + + if (Tok.isLiteral()) + TokStart = Tok.getLiteralData(); + + if (TokStart == 0) + TokStart = SourceMgr.getCharacterData(Tok.getLocation()); // If this token contains nothing interesting, return it directly. if (!Tok.needsCleaning()) { Buffer = TokStart; return Tok.getLength(); } + // Otherwise, hard case, relex the characters into the string. char *OutBuf = const_cast(Buffer); for (const char *Ptr = TokStart, *End = TokStart+Tok.getLength(); @@ -291,11 +298,20 @@ unsigned Preprocessor::getSpelling(const Token &Tok, /// CreateString - Plop the specified string into a scratch buffer and return a /// location for it. If specified, the source location provides a source /// location for the token. -SourceLocation Preprocessor:: -CreateString(const char *Buf, unsigned Len, SourceLocation SLoc) { - if (SLoc.isValid()) - return ScratchBuf->getToken(Buf, Len, SLoc); - return ScratchBuf->getToken(Buf, Len); +void Preprocessor::CreateString(const char *Buf, unsigned Len, Token &Tok, + SourceLocation InstantiationLoc) { + Tok.setLength(Len); + + const char *DestPtr; + SourceLocation Loc = ScratchBuf->getToken(Buf, Len, DestPtr); + + if (InstantiationLoc.isValid()) + Loc = SourceMgr.createInstantiationLoc(Loc, InstantiationLoc, Len); + Tok.setLocation(Loc); + + // If this is a literal token, set the pointer data. + if (Tok.isLiteral()) + Tok.setLiteralData(DestPtr); } diff --git a/clang/lib/Lex/ScratchBuffer.cpp b/clang/lib/Lex/ScratchBuffer.cpp index 695a5365faf7..9253bc0944df 100644 --- a/clang/lib/Lex/ScratchBuffer.cpp +++ b/clang/lib/Lex/ScratchBuffer.cpp @@ -30,10 +30,14 @@ ScratchBuffer::ScratchBuffer(SourceManager &SM) : SourceMgr(SM), CurBuffer(0) { /// return a SourceLocation that refers to the token. This is just like the /// method below, but returns a location that indicates the physloc of the /// token. -SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len) { +SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, + const char *&DestPtr) { if (BytesUsed+Len > ScratchBufSize) AllocScratchBuffer(Len); + // Return a pointer to the character data. + DestPtr = CurBuffer+BytesUsed; + // Copy the token data into the buffer. memcpy(CurBuffer+BytesUsed, Buf, Len); @@ -43,16 +47,6 @@ SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len) { return BufferStartLoc.getFileLocWithOffset(BytesUsed-Len); } - -/// getToken - Splat the specified text into a temporary MemoryBuffer and -/// return a SourceLocation that refers to the token. The SourceLoc value -/// gives a virtual location that the token will appear to be from. -SourceLocation ScratchBuffer::getToken(const char *Buf, unsigned Len, - SourceLocation SourceLoc) { - // Map the physloc to the specified sourceloc. - return SourceMgr.createInstantiationLoc(getToken(Buf, Len), SourceLoc, Len); -} - void ScratchBuffer::AllocScratchBuffer(unsigned RequestLen) { // Only pay attention to the requested length if it is larger than our default // page size. If it is, we allocate an entire chunk for it. This is to diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index 3707ef1ed6f0..7ae61beb8882 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -352,6 +352,7 @@ void TokenLexer::Lex(Token &Tok) { /// If this returns true, the caller should immediately return the token. bool TokenLexer::PasteTokens(Token &Tok) { llvm::SmallVector Buffer; + const char *ResultTokStrPtr = 0; do { // Consume the ## operator. SourceLocation PasteOpLoc = Tokens[CurToken].getLocation(); @@ -386,8 +387,16 @@ bool TokenLexer::PasteTokens(Token &Tok) { // Plop the pasted result (including the trailing newline and null) into a // scratch buffer where we can lex it. - SourceLocation ResultTokLoc = PP.CreateString(&Buffer[0], Buffer.size()); + Token ResultTokTmp; + ResultTokTmp.startToken(); + // Claim that the tmp token is a string_literal so that we can get the + // character pointer back from CreateString. + ResultTokTmp.setKind(tok::string_literal); + PP.CreateString(&Buffer[0], Buffer.size(), ResultTokTmp); + SourceLocation ResultTokLoc = ResultTokTmp.getLocation(); + ResultTokStrPtr = ResultTokTmp.getLiteralData(); + // Lex the resultant pasted token into Result. Token Result; @@ -405,20 +414,16 @@ bool TokenLexer::PasteTokens(Token &Tok) { assert(ResultTokLoc.isFileID() && "Should be a raw location into scratch buffer"); SourceManager &SourceMgr = PP.getSourceManager(); - std::pair LocInfo = - SourceMgr.getDecomposedLoc(ResultTokLoc); + FileID LocFileID = SourceMgr.getFileID(ResultTokLoc); - const char *ScratchBufStart =SourceMgr.getBufferData(LocInfo.first).first; + const char *ScratchBufStart = SourceMgr.getBufferData(LocFileID).first; // Make a lexer to lex this string from. Lex just this one token. - const char *ResultStrData = ScratchBufStart+LocInfo.second; - // Make a lexer object so that we lex and expand the paste result. - Lexer TL(SourceMgr.getLocForStartOfFile(LocInfo.first), - PP.getLangOptions(), - ScratchBufStart, - ResultStrData, - ResultStrData+LHSLen+RHSLen /*don't include null*/); + Lexer TL(SourceMgr.getLocForStartOfFile(LocFileID), + PP.getLangOptions(), ScratchBufStart, + ResultTokStrPtr, + ResultTokStrPtr+LHSLen+RHSLen /*don't include null*/); // Lex a token in raw mode. This way it won't look up identifiers // automatically, lexing off the end will return an eof token, and @@ -442,12 +447,12 @@ bool TokenLexer::PasteTokens(Token &Tok) { RHS.is(tok::slash)) { HandleMicrosoftCommentPaste(Tok); return true; - } else { - // TODO: If not in assembler language mode. - PP.Diag(PasteOpLoc, diag::err_pp_bad_paste) - << std::string(Buffer.begin(), Buffer.end()-1); - return false; } + + // TODO: If not in assembler language mode. + PP.Diag(PasteOpLoc, diag::err_pp_bad_paste) + << std::string(Buffer.begin(), Buffer.end()-1); + return false; } // Turn ## into 'unknown' to avoid # ## # from looking like a paste @@ -471,7 +476,7 @@ bool TokenLexer::PasteTokens(Token &Tok) { if (Tok.is(tok::identifier)) { // Look up the identifier info for the token. We disabled identifier lookup // by saying we're skipping contents, so we need to do this manually. - Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok)); + Tok.setIdentifierInfo(PP.LookUpIdentifierInfo(Tok, ResultTokStrPtr)); } return false; } diff --git a/clang/lib/Rewrite/TokenRewriter.cpp b/clang/lib/Rewrite/TokenRewriter.cpp index aab6fb0cce8b..e17e80133b11 100644 --- a/clang/lib/Rewrite/TokenRewriter.cpp +++ b/clang/lib/Rewrite/TokenRewriter.cpp @@ -78,14 +78,15 @@ TokenRewriter::AddToken(const Token &T, TokenRefTy Where) { TokenRewriter::token_iterator -TokenRewriter::AddTokenBefore(token_iterator I, const char *Val){ +TokenRewriter::AddTokenBefore(token_iterator I, const char *Val) { unsigned Len = strlen(Val); // Plop the string into the scratch buffer, then create a token for this // string. Token Tok; Tok.startToken(); - Tok.setLocation(ScratchBuf->getToken(Val, Len)); + const char *Spelling; + Tok.setLocation(ScratchBuf->getToken(Val, Len, Spelling)); Tok.setLength(Len); // TODO: Form a whole lexer around this and relex the token! For now, just -- GitLab From 9892ea2fbb47dba59daa21d3cfcf32eb10e99ee9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 19:33:54 +0000 Subject: [PATCH 218/682] minor speedups/cleanups for -E mode. llvm-svn: 63029 --- clang/Driver/PrintPreprocessedOutput.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/clang/Driver/PrintPreprocessedOutput.cpp b/clang/Driver/PrintPreprocessedOutput.cpp index deecacb1f4c5..32b8a8b2792c 100644 --- a/clang/Driver/PrintPreprocessedOutput.cpp +++ b/clang/Driver/PrintPreprocessedOutput.cpp @@ -430,10 +430,13 @@ bool PrintPPOutputPPCallbacks::AvoidConcat(const Token &PrevTok, // Avoid spelling identifiers, the most common form of token. FirstChar = II->getName()[0]; } else if (!Tok.needsCleaning()) { - // FIXME: SPEED UP LITERALS! - SourceManager &SrcMgr = PP.getSourceManager(); - FirstChar = - *SrcMgr.getCharacterData(SrcMgr.getSpellingLoc(Tok.getLocation())); + if (Tok.isLiteral() && Tok.getLiteralData()) { + FirstChar = *Tok.getLiteralData(); + } else { + SourceManager &SrcMgr = PP.getSourceManager(); + FirstChar = + *SrcMgr.getCharacterData(SrcMgr.getSpellingLoc(Tok.getLocation())); + } } else if (Tok.getLength() < 256) { const char *TokPtr = Buffer; PP.getSpelling(Tok, TokPtr); @@ -554,10 +557,10 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, } if (IdentifierInfo *II = Tok.getIdentifierInfo()) { - const char *Str = II->getName(); - unsigned Len = Tok.needsCleaning() ? strlen(Str) : Tok.getLength(); - OS.write(Str, Len); - // FIXME: ACCELERATE LITERALS + OS.write(II->getName(), II->getLength()); + } else if (Tok.isLiteral() && !Tok.needsCleaning() && + Tok.getLiteralData()) { + OS.write(Tok.getLiteralData(), Tok.getLength()); } else if (Tok.getLength() < 256) { const char *TokPtr = Buffer; unsigned Len = PP.getSpelling(Tok, TokPtr); -- GitLab From 31af4e08d1f3565ead6e069508872f7cca04f531 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 19:41:58 +0000 Subject: [PATCH 219/682] fix a negated conditional in getDecomposedInstantiationLocSlowCase, which I think is rdar://6527005, and make getDecomposedSpellingLocSlowCase handle nested spelling locations. llvm-svn: 63030 --- clang/lib/Basic/SourceManager.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 42e6040b7464..031bf4dcbcc5 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -341,7 +341,7 @@ SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, FID = getFileID(Loc); E = &getSLocEntry(FID); Offset += Loc.getOffset()-E->getOffset(); - } while (Loc.isFileID()); + } while (!Loc.isFileID()); return std::make_pair(FID, Offset); } @@ -349,12 +349,18 @@ SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, std::pair SourceManager::getDecomposedSpellingLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const { - // If this is an instantiation record, get and return the spelling. - SourceLocation Loc = E->getInstantiation().getSpellingLoc(); - FileID FID = getFileID(Loc); - E = &getSLocEntry(FID); - Offset += Loc.getOffset()-E->getOffset(); - assert(Loc.isFileID() && "Should only have one spelling link"); + // If this is an instantiation record, walk through all the instantiation + // points. + FileID FID; + SourceLocation Loc; + do { + Loc = E->getInstantiation().getSpellingLoc(); + + FID = getFileID(Loc); + E = &getSLocEntry(FID); + Offset += Loc.getOffset()-E->getOffset(); + } while (!Loc.isFileID()); + return std::make_pair(FID, Offset); } -- GitLab From 54cb4c88e1885b5d08291ebf00d076bba20fd869 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 26 Jan 2009 19:54:12 +0000 Subject: [PATCH 220/682] Correct size assumption; fixes a crash on amd64. llvm-svn: 63031 --- clang/lib/Analysis/RegionStore.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp index f519d4d1cd1b..e50b0abb61e6 100644 --- a/clang/lib/Analysis/RegionStore.cpp +++ b/clang/lib/Analysis/RegionStore.cpp @@ -888,7 +888,8 @@ const GRState* RegionStoreManager::BindArray(const GRState* St, ConstantArrayType* CAT = cast(T.getTypePtr()); llvm::APSInt Size(CAT->getSize(), false); - llvm::APSInt i = getBasicVals().getZeroWithPtrWidth(false); + llvm::APSInt i = getBasicVals().getValue(0, Size.getBitWidth(), + Size.isUnsigned()); // Check if the init expr is a StringLiteral. if (isa(Init)) { -- GitLab From a7bc8473a3837fc7552452973c191721d8eb5d5a Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 26 Jan 2009 19:54:48 +0000 Subject: [PATCH 221/682] Remove an implemented FIXME and extend test cases. Follow-up on Doug's review. llvm-svn: 63032 --- clang/lib/Sema/SemaType.cpp | 17 ++++++++--------- clang/test/SemaCXX/member-pointer.cpp | 7 +++++++ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index d62e767a1c11..719938d9a3be 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -642,15 +642,14 @@ QualType Sema::ObjCGetTypeForMethodDefinition(DeclTy *D) { return T; } -/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types (FIXME: -/// or pointer-to-member types) that may be similar (C++ 4.4), -/// replaces T1 and T2 with the type that they point to and return -/// true. If T1 and T2 aren't pointer types or pointer-to-member -/// types, or if they are not similar at this level, returns false and -/// leaves T1 and T2 unchanged. Top-level qualifiers on T1 and T2 are -/// ignored. This function will typically be called in a loop that -/// successively "unwraps" pointer and pointer-to-member types to -/// compare them at each level. +/// UnwrapSimilarPointerTypes - If T1 and T2 are pointer types that +/// may be similar (C++ 4.4), replaces T1 and T2 with the type that +/// they point to and return true. If T1 and T2 aren't pointer types +/// or pointer-to-member types, or if they are not similar at this +/// level, returns false and leaves T1 and T2 unchanged. Top-level +/// qualifiers on T1 and T2 are ignored. This function will typically +/// be called in a loop that successively "unwraps" pointer and +/// pointer-to-member types to compare them at each level. bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) { const PointerType *T1PtrType = T1->getAsPointerType(), diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index 4aa309846101..bcd3dd65e84f 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -4,6 +4,9 @@ struct A {}; enum B { Dummy }; namespace C {} struct D : A {}; +struct E : A {}; +struct F : D, E {}; +struct G : virtual D {}; int A::*pdi1; int (::A::*pdi2); @@ -29,4 +32,8 @@ void f() { // Conversion to member of derived. int D::*pdid = pdi1; pdid = pdi2; + + // Fail conversion due to ambiguity and virtuality. + int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'struct A' to pointer to member of derived class 'struct F'}} expected-error {{incompatible type}} + int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'struct A' to pointer to member of class 'struct G' via virtual base 'struct D' is not allowed}} expected-error {{incompatible type}} } -- GitLab From 659ac5f08775966b6c24eac74dbf5f8bc4628869 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 20:04:19 +0000 Subject: [PATCH 222/682] make getInstantiationLoc and getSpellingLoc handle multiply instantiated locations, and move the slow case out of line. No perf change on cocoa.h llvm-svn: 63033 --- clang/include/clang/Basic/SourceManager.h | 19 +++++++++---------- clang/lib/Basic/SourceManager.cpp | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 10 deletions(-) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index 41c2defacd5f..84aabe1f3103 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -415,24 +415,20 @@ public: /// Given a SourceLocation object, return the instantiation location /// referenced by the ID. SourceLocation getInstantiationLoc(SourceLocation Loc) const { - // File locations work! + // Handle the non-mapped case inline, defer to out of line code to handle + // instantiations. if (Loc.isFileID()) return Loc; - - std::pair LocInfo = getDecomposedLoc(Loc); - Loc = getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc(); - return Loc.getFileLocWithOffset(LocInfo.second); + return getInstantiationLocSlowCase(Loc); } /// getSpellingLoc - Given a SourceLocation object, return the spelling /// location referenced by the ID. This is the place where the characters /// that make up the lexed token can be found. SourceLocation getSpellingLoc(SourceLocation Loc) const { - // File locations work! + // Handle the non-mapped case inline, defer to out of line code to handle + // instantiations. if (Loc.isFileID()) return Loc; - - std::pair LocInfo = getDecomposedLoc(Loc); - Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc(); - return Loc.getFileLocWithOffset(LocInfo.second); + return getSpellingLocSlowCase(Loc); } /// getDecomposedLoc - Decompose the specified location into a raw FileID + @@ -614,6 +610,9 @@ private: FileID getFileIDSlow(unsigned SLocOffset) const; + SourceLocation getInstantiationLocSlowCase(SourceLocation Loc) const; + SourceLocation getSpellingLocSlowCase(SourceLocation Loc) const; + std::pair getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const; diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 031bf4dcbcc5..f9f51afef847 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -328,6 +328,27 @@ FileID SourceManager::getFileIDSlow(unsigned SLocOffset) const { } } +SourceLocation SourceManager:: +getInstantiationLocSlowCase(SourceLocation Loc) const { + do { + std::pair LocInfo = getDecomposedLoc(Loc); + Loc =getSLocEntry(LocInfo.first).getInstantiation().getInstantiationLoc(); + Loc = Loc.getFileLocWithOffset(LocInfo.second); + } while (!Loc.isFileID()); + + return Loc; +} + +SourceLocation SourceManager::getSpellingLocSlowCase(SourceLocation Loc) const { + do { + std::pair LocInfo = getDecomposedLoc(Loc); + Loc = getSLocEntry(LocInfo.first).getInstantiation().getSpellingLoc(); + Loc = Loc.getFileLocWithOffset(LocInfo.second); + } while (!Loc.isFileID()); + return Loc; +} + + std::pair SourceManager::getDecomposedInstantiationLocSlowCase(const SrcMgr::SLocEntry *E, unsigned Offset) const { -- GitLab From 2d86c700bfb4f4c3345a8ab897ed841082a69005 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 20:08:26 +0000 Subject: [PATCH 223/682] now that everything properly handles multiply instantiated source locations, allow creation of them. We can now say that a token was instantiated here, then here, then here. llvm-svn: 63034 --- clang/lib/Basic/SourceManager.cpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index f9f51afef847..6c82b9bf2e85 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -201,14 +201,6 @@ FileID SourceManager::createFileID(const ContentCache *File, SourceLocation SourceManager::createInstantiationLoc(SourceLocation SpellingLoc, SourceLocation InstantLoc, unsigned TokLength) { - // The specified source location may be a mapped location, due to a macro - // instantiation or #line directive. Strip off this information to find out - // where the characters are actually located. - SpellingLoc = getSpellingLoc(SpellingLoc); - - // Resolve InstantLoc down to a real instantiation location. - InstantLoc = getInstantiationLoc(InstantLoc); - SLocEntryTable.push_back(SLocEntry::get(NextOffset, InstantiationInfo::get(InstantLoc, SpellingLoc))); -- GitLab From 7e20927756bc885a1d1cbd2a2c904c09b1260ef8 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 20:15:46 +0000 Subject: [PATCH 224/682] allow _Pragmas formed from #defines to keep their full instantiation history llvm-svn: 63035 --- clang/lib/Lex/Lexer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 03d81b3b9a16..7f14e7a4a2df 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -321,10 +321,9 @@ static SourceLocation GetMappedTokenLoc(Preprocessor &PP, // Create a new SLoc which is expanded from Instantiation(FileLoc) but whose // characters come from spelling(FileLoc)+Offset. - SourceLocation InstLoc = SourceMgr.getInstantiationLoc(FileLoc); SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(FileLoc); SpellingLoc = SpellingLoc.getFileLocWithOffset(CharNo); - return SourceMgr.createInstantiationLoc(SpellingLoc, InstLoc, TokLen); + return SourceMgr.createInstantiationLoc(SpellingLoc, FileLoc, TokLen); } /// getSourceLocation - Return a source location identifier for the specified -- GitLab From 357b57d7492813fcad9fbaa7fbd0253c3b3dfa81 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 20:24:53 +0000 Subject: [PATCH 225/682] remove my hacks that aggressively threw away multiple instantiation history in an effort to speed up c99-intconst-1.c. Now that multiple nested instantiations are allowed, we just make them and don't pay the cost of lookups. With the other changes that went in before this, reverting this is actually a speedup for c99-intconst-1.c, speeding it up from 1.96s to 1.80s, and preserves much better loc info. llvm-svn: 63036 --- clang/lib/Lex/MacroArgs.cpp | 6 ------ clang/lib/Lex/PPDirectives.cpp | 12 ------------ clang/lib/Lex/PPMacroExpansion.cpp | 9 +-------- clang/lib/Lex/TokenLexer.cpp | 6 ------ 4 files changed, 1 insertion(+), 32 deletions(-) diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp index c3d7738afe0d..7a805f349f2d 100644 --- a/clang/lib/Lex/MacroArgs.cpp +++ b/clang/lib/Lex/MacroArgs.cpp @@ -120,12 +120,6 @@ MacroArgs::getPreExpArgument(unsigned Arg, Preprocessor &PP) { Result.push_back(Token()); Token &Tok = Result.back(); PP.Lex(Tok); - - // Eagerly resolve instantiation ID's to their spelling location. This - // makes it so we only have to get the spelling loc once per macro argument - // preexpansion instead of once per each time the token is expanded. - if (!Tok.getLocation().isFileID()) - Tok.setLocation(PP.getSourceManager().getSpellingLoc(Tok.getLocation())); } while (Result.back().isNot(tok::eof)); // Pop the token stream off the top of the stack. We know that the internal diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 099dfb4aef09..4bf012c1b119 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -1206,12 +1206,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { if (MI->isObjectLike()) { // Object-like macros are very simple, just read their body. while (Tok.isNot(tok::eom)) { - // If this token has a virtual location, resolve it down to its spelling - // location. This is not strictly needed, but avoids extra resolutions - // for macros that are expanded frequently. - if (!Tok.getLocation().isFileID()) - Tok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); - MI->AddTokenToBody(Tok); // Get the next token of the macro. LexUnexpandedToken(Tok); @@ -1221,12 +1215,6 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok) { // Otherwise, read the body of a function-like macro. This has to validate // the # (stringize) operator. while (Tok.isNot(tok::eom)) { - // If this token has a virtual location, resolve it down to its spelling - // location. This is not strictly needed, but avoids extra resolutions - // for macros that are expanded frequently. - if (!Tok.getLocation().isFileID()) - Tok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); - MI->AddTokenToBody(Tok); // Check C99 6.10.3.2p1: ensure that # operators are followed by macro diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index b3e921c36894..8eada6003d81 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -340,13 +340,6 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, if (!MI->isEnabled()) Tok.setFlag(Token::DisableExpand); } - - // If this token has instantiation location, resolve it down to its - // spelling location. This is not strictly needed, but avoids extra - // resolutions for macros that are expanded frequently. - if (!Tok.getLocation().isFileID()) - Tok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); - ArgTokens.push_back(Tok); } @@ -359,7 +352,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName, Token EOFTok; EOFTok.startToken(); EOFTok.setKind(tok::eof); - EOFTok.setLocation(SourceMgr.getSpellingLoc(Tok.getLocation())); + EOFTok.setLocation(Tok.getLocation()); EOFTok.setLength(0); ArgTokens.push_back(EOFTok); ++NumActuals; diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index 7ae61beb8882..40f6640cd75c 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -33,12 +33,6 @@ void TokenLexer::Init(Token &Tok, MacroArgs *Actuals) { CurToken = 0; InstantiateLoc = Tok.getLocation(); - - // If the instantiation loc is not already a FileID, resolve it here. If we - // don't do this, we end up doing it once per token lexed. - if (!InstantiateLoc.isFileID()) - InstantiateLoc = PP.getSourceManager().getInstantiationLoc(InstantiateLoc); - AtStartOfLine = Tok.isAtStartOfLine(); HasLeadingSpace = Tok.hasLeadingSpace(); Tokens = &*Macro->tokens_begin(); -- GitLab From 0b46005b1916d8bee4cad98c13724d728ff8e833 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 26 Jan 2009 20:27:11 +0000 Subject: [PATCH 226/682] Fix the name of an argument. llvm-svn: 63037 --- llvm/include/llvm/CodeGen/LiveStackAnalysis.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/LiveStackAnalysis.h b/llvm/include/llvm/CodeGen/LiveStackAnalysis.h index 6b5235a5d1dd..7cb4151e8705 100644 --- a/llvm/include/llvm/CodeGen/LiveStackAnalysis.h +++ b/llvm/include/llvm/CodeGen/LiveStackAnalysis.h @@ -64,8 +64,8 @@ namespace llvm { return I->second; } - bool hasInterval(unsigned reg) const { - return s2iMap.count(reg); + bool hasInterval(unsigned Slot) const { + return s2iMap.count(Slot); } BumpPtrAllocator& getVNInfoAllocator() { return VNInfoAllocator; } -- GitLab From 336dbba387d732c5d80e496657fac732b93dd749 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 21:25:20 +0000 Subject: [PATCH 227/682] Skip emission of final return block if possible (e.g., functions with a unified return). llvm-svn: 63038 --- clang/lib/CodeGen/CodeGenFunction.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 2fd8d638d657..b509843daa65 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -77,9 +77,13 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); - // Emit function epilog (to return). This has the nice side effect - // of also automatically handling code that falls off the end. - EmitBlock(ReturnBlock); + // Emit function epilog (to return). For cleanliness, skip emission + // if we know it is safe (when it is unused and the current block is + // unterminated). + if (!ReturnBlock->use_empty() || + !Builder.GetInsertBlock() || + Builder.GetInsertBlock()->getTerminator()) + EmitBlock(ReturnBlock); // Emit debug descriptor for function end. if (CGDebugInfo *DI = CGM.getDebugInfo()) { -- GitLab From 94a6f25738cf45c666915c61defa47dcc592981d Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 21:26:08 +0000 Subject: [PATCH 228/682] Add Ignore ABIArgInfo kind, for handling void & empty structures. llvm-svn: 63039 --- clang/lib/CodeGen/CGCall.cpp | 44 ++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index cf0d4cc79bc5..cd781781f919 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -113,6 +113,9 @@ public: /// allocated location passed as an implicit first /// argument to the function. + Ignore, /// Ignore the argument (treat as void). Useful for + /// void and empty structs. + Coerce, /// Only valid for aggregate return types, the argument /// should be accessed by coercion to a provided type. @@ -147,6 +150,9 @@ public: static ABIArgInfo getStructRet() { return ABIArgInfo(StructRet); } + static ABIArgInfo getIgnore() { + return ABIArgInfo(Ignore); + } static ABIArgInfo getCoerce(const llvm::Type *T) { assert(T->isSingleValueType() && "Can only coerce to simple types"); return ABIArgInfo(Coerce, T); @@ -161,6 +167,7 @@ public: Kind getKind() const { return TheKind; } bool isDefault() const { return TheKind == Default; } bool isStructRet() const { return TheKind == StructRet; } + bool isIgnore() const { return TheKind == Ignore; } bool isCoerce() const { return TheKind == Coerce; } bool isByVal() const { return TheKind == ByVal; } bool isExpand() const { return TheKind == Expand; } @@ -432,7 +439,9 @@ void X86_64ABIInfo::classify(QualType Ty, if (const BuiltinType *BT = Ty->getAsBuiltinType()) { BuiltinType::Kind k = BT->getKind(); - if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { + if (k == BuiltinType::Void) { + Lo = NoClass; + } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { Lo = Integer; } else if (k == BuiltinType::Float || k == BuiltinType::Double) { Lo = SSE; @@ -468,7 +477,7 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy, const llvm::Type *ResType = 0; switch (Lo) { case NoClass: - assert(0 && "FIXME: Handle ignored return values."); + return ABIArgInfo::getIgnore(); case SSEUp: case X87Up: @@ -719,6 +728,10 @@ CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end, break; } + case ABIArgInfo::Ignore: + ResultType = llvm::Type::VoidTy; + break; + case ABIArgInfo::Coerce: ResultType = RetAI.getCoerceToType(); break; @@ -729,6 +742,9 @@ CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end, const llvm::Type *Ty = ConvertType(*begin); switch (AI.getKind()) { + case ABIArgInfo::Ignore: + break; + case ABIArgInfo::Coerce: case ABIArgInfo::StructRet: assert(0 && "Invalid ABI kind for non-return argument"); @@ -795,6 +811,7 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, ++Index; break; + case ABIArgInfo::Ignore: case ABIArgInfo::Coerce: break; @@ -830,6 +847,10 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, } break; + case ABIArgInfo::Ignore: + // Skip increment, no matching LLVM parameter. + continue; + case ABIArgInfo::Expand: { std::vector Tys; // FIXME: This is rather inefficient. Do we ever actually need @@ -900,7 +921,10 @@ void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, AI->setName(Name + "." + llvm::utostr(Index)); continue; } - + + case ABIArgInfo::Ignore: + break; + case ABIArgInfo::Coerce: case ABIArgInfo::StructRet: assert(0 && "Invalid ABI kind for non-return argument"); @@ -937,6 +961,9 @@ void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, RV = Builder.CreateLoad(ReturnValue); break; + case ABIArgInfo::Ignore: + break; + case ABIArgInfo::Coerce: { const llvm::Type *CoerceToPTy = llvm::PointerType::getUnqual(RetAI.getCoerceToType()); @@ -972,6 +999,7 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, break; case ABIArgInfo::Default: + case ABIArgInfo::Ignore: case ABIArgInfo::Coerce: break; @@ -999,6 +1027,9 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, } break; + case ABIArgInfo::Ignore: + break; + case ABIArgInfo::StructRet: case ABIArgInfo::Coerce: assert(0 && "Invalid ABI kind for non-return argument"); @@ -1038,6 +1069,9 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, case ABIArgInfo::Default: return RValue::get(RetTy->isVoidType() ? 0 : CI); + case ABIArgInfo::Ignore: + return RValue::get(0); + case ABIArgInfo::Coerce: { const llvm::Type *CoerceToPTy = llvm::PointerType::getUnqual(RetAI.getCoerceToType()); @@ -1045,8 +1079,10 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy)); if (RetTy->isAnyComplexType()) return RValue::getComplex(LoadComplexFromAddr(V, false)); - else + else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) return RValue::getAggregate(V); + else + return RValue::get(Builder.CreateLoad(V)); } case ABIArgInfo::ByVal: -- GitLab From a39c83d118bef5620330fa195dd59cd4a766261d Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 26 Jan 2009 21:27:03 +0000 Subject: [PATCH 229/682] Temporarily revert r63025 until the testsuite failures can be fixed. llvm-svn: 63040 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 46 +++++++++++++++++++------- 1 file changed, 34 insertions(+), 12 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 49cc67ba1f04..09b39fab1b4e 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -563,12 +563,12 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); - // FIXME: Need to set kills properly for inter-block stuff. if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex); if (intrablock) LI->addKill(ret, EndIndex); + + LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); } else if (ContainsDefs && ContainsUses){ SmallPtrSet& BlockDefs = Defs[MBB]; SmallPtrSet& BlockUses = Uses[MBB]; @@ -620,13 +620,13 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); - if (foundUse && LI->isKill(ret, StartIndex)) LI->removeKill(ret, StartIndex); if (intrablock) { LI->addKill(ret, EndIndex); } + + LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); } // Memoize results so we don't have to recompute them. @@ -810,10 +810,18 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, TII->reMaterialize(MBB, RestorePt, vreg, DefMI); LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); - ReconstructLiveInterval(CurrLI); - unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt)); - RematIdx = LiveIntervals::getDefIndex(RematIdx); - RenumberValno(CurrLI->findDefinedVNInfo(RematIdx)); + if (KillPt->getParent() == BarrierMBB) { + VNInfo* After = UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, + LIs->getDefIndex(RestoreIdx)); + + RenumberValno(After); + + ++NumSplits; + ++NumRemats; + return true; + } + + RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIdx); ++NumSplits; ++NumRemats; @@ -986,14 +994,28 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { MachineInstr *LoadMI = prior(RestorePt); LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex); + // If live interval is spilled in the same block as the barrier, just + // create a hole in the interval. + if (!DefMBB || + (SpillMI && SpillMI->getParent() == BarrierMBB)) { + // Update spill stack slot live interval. + UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, + LIs->getDefIndex(RestoreIndex)); + + VNInfo* After = UpdateRegisterInterval(ValNo, + LIs->getUseIndex(SpillIndex)+1, + LIs->getDefIndex(RestoreIndex)); + RenumberValno(After); + + ++NumSplits; + return true; + } + // Update spill stack slot live interval. UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, LIs->getDefIndex(RestoreIndex)); - ReconstructLiveInterval(CurrLI); - unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); - RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx); - RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx)); + RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIndex); ++NumSplits; return true; -- GitLab From e7fa3c37c636ad6bb80750cdb4ec0c4a7efae188 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Mon, 26 Jan 2009 21:30:17 +0000 Subject: [PATCH 230/682] Also revert r63206 llvm-svn: 63041 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 321 +++++++++++++++++++++++++ 1 file changed, 321 insertions(+) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 09b39fab1b4e..16a9e6d9b041 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -139,11 +139,26 @@ namespace { void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned); + VNInfo* UpdateRegisterInterval(VNInfo*, unsigned, unsigned); + + bool ShrinkWrapToLastUse(MachineBasicBlock*, VNInfo*, + SmallVector&, + SmallPtrSet&); + + void ShrinkWrapLiveInterval(VNInfo*, MachineBasicBlock*, MachineBasicBlock*, + MachineBasicBlock*, SmallPtrSet&, + DenseMap >&, + DenseMap >&, + SmallVector&); + bool SplitRegLiveInterval(LiveInterval*); bool SplitRegLiveIntervals(const TargetRegisterClass **, SmallPtrSet&); + void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo, + MachineInstr* DefMI, unsigned RestoreIdx); + bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, MachineBasicBlock* BarrierMBB); bool Rematerialize(unsigned vreg, VNInfo* ValNo, @@ -408,6 +423,176 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex, } } +/// UpdateRegisterInterval - Given the specified val# of the current live +/// interval is being split, and the spill and restore indices, update the live +/// interval accordingly. +VNInfo* +PreAllocSplitting::UpdateRegisterInterval(VNInfo *ValNo, unsigned SpillIndex, + unsigned RestoreIndex) { + assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB && + "Expect restore in the barrier mbb"); + + SmallVector, 4> Before; + SmallVector, 4> After; + SmallVector BeforeKills; + SmallVector AfterKills; + SmallPtrSet Processed; + + // First, let's figure out which parts of the live interval is now defined + // by the restore, which are defined by the original definition. + const LiveRange *LR = CurrLI->getLiveRangeContaining(RestoreIndex); + After.push_back(std::make_pair(RestoreIndex, LR->end)); + if (CurrLI->isKill(ValNo, LR->end)) + AfterKills.push_back(LR->end); + + assert(LR->contains(SpillIndex)); + if (SpillIndex > LR->start) { + Before.push_back(std::make_pair(LR->start, SpillIndex)); + BeforeKills.push_back(SpillIndex); + } + Processed.insert(LR); + + // Start from the restore mbb, figure out what part of the live interval + // are defined by the restore. + SmallVector WorkList; + MachineBasicBlock *MBB = BarrierMBB; + for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), + SE = MBB->succ_end(); SI != SE; ++SI) + WorkList.push_back(*SI); + + SmallPtrSet ProcessedBlocks; + ProcessedBlocks.insert(MBB); + + while (!WorkList.empty()) { + MBB = WorkList.back(); + WorkList.pop_back(); + unsigned Idx = LIs->getMBBStartIdx(MBB); + LR = CurrLI->getLiveRangeContaining(Idx); + if (LR && LR->valno == ValNo && !Processed.count(LR)) { + After.push_back(std::make_pair(LR->start, LR->end)); + if (CurrLI->isKill(ValNo, LR->end)) + AfterKills.push_back(LR->end); + Idx = LIs->getMBBEndIdx(MBB); + if (LR->end > Idx) { + // Live range extend beyond at least one mbb. Let's see what other + // mbbs it reaches. + LIs->findReachableMBBs(LR->start, LR->end, WorkList); + } + Processed.insert(LR); + } + + ProcessedBlocks.insert(MBB); + if (LR) + for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), + SE = MBB->succ_end(); SI != SE; ++SI) + if (!ProcessedBlocks.count(*SI)) + WorkList.push_back(*SI); + } + + for (LiveInterval::iterator I = CurrLI->begin(), E = CurrLI->end(); + I != E; ++I) { + LiveRange *LR = I; + if (LR->valno == ValNo && !Processed.count(LR)) { + Before.push_back(std::make_pair(LR->start, LR->end)); + if (CurrLI->isKill(ValNo, LR->end)) + BeforeKills.push_back(LR->end); + } + } + + // Now create new val#s to represent the live ranges defined by the old def + // those defined by the restore. + unsigned AfterDef = ValNo->def; + MachineInstr *AfterCopy = ValNo->copy; + bool HasPHIKill = ValNo->hasPHIKill; + CurrLI->removeValNo(ValNo); + VNInfo *BValNo = (Before.empty()) + ? NULL + : CurrLI->getNextValue(AfterDef, AfterCopy, LIs->getVNInfoAllocator()); + if (BValNo) + CurrLI->addKills(BValNo, BeforeKills); + + VNInfo *AValNo = (After.empty()) + ? NULL + : CurrLI->getNextValue(RestoreIndex, 0, LIs->getVNInfoAllocator()); + if (AValNo) { + AValNo->hasPHIKill = HasPHIKill; + CurrLI->addKills(AValNo, AfterKills); + } + + for (unsigned i = 0, e = Before.size(); i != e; ++i) { + unsigned Start = Before[i].first; + unsigned End = Before[i].second; + CurrLI->addRange(LiveRange(Start, End, BValNo)); + } + for (unsigned i = 0, e = After.size(); i != e; ++i) { + unsigned Start = After[i].first; + unsigned End = After[i].second; + CurrLI->addRange(LiveRange(Start, End, AValNo)); + } + + return AValNo; +} + +/// ShrinkWrapToLastUse - There are uses of the current live interval in the +/// given block, shrink wrap the live interval to the last use (i.e. remove +/// from last use to the end of the mbb). In case mbb is the where the barrier +/// is, remove from the last use to the barrier. +bool +PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB, VNInfo *ValNo, + SmallVector &Uses, + SmallPtrSet &UseMIs) { + MachineOperand *LastMO = 0; + MachineInstr *LastMI = 0; + if (MBB != BarrierMBB && Uses.size() == 1) { + // Single use, no need to traverse the block. We can't assume this for the + // barrier bb though since the use is probably below the barrier. + LastMO = Uses[0]; + LastMI = LastMO->getParent(); + } else { + MachineBasicBlock::iterator MEE = MBB->begin(); + MachineBasicBlock::iterator MII; + if (MBB == BarrierMBB) + MII = Barrier; + else + MII = MBB->end(); + while (MII != MEE) { + --MII; + MachineInstr *UseMI = &*MII; + if (!UseMIs.count(UseMI)) + continue; + for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) { + MachineOperand &MO = UseMI->getOperand(i); + if (MO.isReg() && MO.getReg() == CurrLI->reg) { + LastMO = &MO; + break; + } + } + LastMI = UseMI; + break; + } + } + + // Cut off live range from last use (or beginning of the mbb if there + // are no uses in it) to the end of the mbb. + unsigned RangeStart, RangeEnd = LIs->getMBBEndIdx(MBB)+1; + if (LastMI) { + RangeStart = LIs->getUseIndex(LIs->getInstructionIndex(LastMI))+1; + assert(!LastMO->isKill() && "Last use already terminates the interval?"); + LastMO->setIsKill(); + } else { + assert(MBB == BarrierMBB); + RangeStart = LIs->getMBBStartIdx(MBB); + } + if (MBB == BarrierMBB) + RangeEnd = LIs->getUseIndex(BarrierIdx)+1; + CurrLI->removeRange(RangeStart, RangeEnd); + if (LastMI) + CurrLI->addKill(ValNo, RangeStart); + + // Return true if the last use becomes a new kill. + return LastMI; +} + /// PerformPHIConstruction - From properly set up use and def lists, use a PHI /// construction algorithm to compute the ranges and valnos for an interval. VNInfo* PreAllocSplitting::PerformPHIConstruction( @@ -705,6 +890,142 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { } } +/// ShrinkWrapLiveInterval - Recursively traverse the predecessor +/// chain to find the new 'kills' and shrink wrap the live interval to the +/// new kill indices. +void +PreAllocSplitting::ShrinkWrapLiveInterval(VNInfo *ValNo, MachineBasicBlock *MBB, + MachineBasicBlock *SuccMBB, MachineBasicBlock *DefMBB, + SmallPtrSet &Visited, + DenseMap > &Uses, + DenseMap > &UseMIs, + SmallVector &UseMBBs) { + if (Visited.count(MBB)) + return; + + // If live interval is live in another successor path, then we can't process + // this block. But we may able to do so after all the successors have been + // processed. + if (MBB != BarrierMBB) { + for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), + SE = MBB->succ_end(); SI != SE; ++SI) { + MachineBasicBlock *SMBB = *SI; + if (SMBB == SuccMBB) + continue; + if (CurrLI->liveAt(LIs->getMBBStartIdx(SMBB))) + return; + } + } + + Visited.insert(MBB); + + DenseMap >::iterator + UMII = Uses.find(MBB); + if (UMII != Uses.end()) { + // At least one use in this mbb, lets look for the kill. + DenseMap >::iterator + UMII2 = UseMIs.find(MBB); + if (ShrinkWrapToLastUse(MBB, ValNo, UMII->second, UMII2->second)) + // Found a kill, shrink wrapping of this path ends here. + return; + } else if (MBB == DefMBB) { + // There are no uses after the def. + MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def); + if (UseMBBs.empty()) { + // The only use must be below barrier in the barrier block. It's safe to + // remove the def. + LIs->RemoveMachineInstrFromMaps(DefMI); + DefMI->eraseFromParent(); + CurrLI->removeRange(ValNo->def, LIs->getMBBEndIdx(MBB)+1); + } + } else if (MBB == BarrierMBB) { + // Remove entire live range from start of mbb to barrier. + CurrLI->removeRange(LIs->getMBBStartIdx(MBB), + LIs->getUseIndex(BarrierIdx)+1); + } else { + // Remove entire live range of the mbb out of the live interval. + CurrLI->removeRange(LIs->getMBBStartIdx(MBB), LIs->getMBBEndIdx(MBB)+1); + } + + if (MBB == DefMBB) + // Reached the def mbb, stop traversing this path further. + return; + + // Traverse the pathes up the predecessor chains further. + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + MachineBasicBlock *Pred = *PI; + if (Pred == MBB) + continue; + if (Pred == DefMBB && ValNo->hasPHIKill) + // Pred is the def bb and the def reaches other val#s, we must + // allow the value to be live out of the bb. + continue; + if (!CurrLI->liveAt(LIs->getMBBEndIdx(Pred)-1)) + return; + ShrinkWrapLiveInterval(ValNo, Pred, MBB, DefMBB, Visited, + Uses, UseMIs, UseMBBs); + } + + return; +} + + +void PreAllocSplitting::RepairLiveInterval(LiveInterval* CurrLI, + VNInfo* ValNo, + MachineInstr* DefMI, + unsigned RestoreIdx) { + // Shrink wrap the live interval by walking up the CFG and find the + // new kills. + // Now let's find all the uses of the val#. + DenseMap > Uses; + DenseMap > UseMIs; + SmallPtrSet Seen; + SmallVector UseMBBs; + for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg), + UE = MRI->use_end(); UI != UE; ++UI) { + MachineOperand &UseMO = UI.getOperand(); + MachineInstr *UseMI = UseMO.getParent(); + unsigned UseIdx = LIs->getInstructionIndex(UseMI); + LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx); + if (ULR->valno != ValNo) + continue; + MachineBasicBlock *UseMBB = UseMI->getParent(); + // Remember which other mbb's use this val#. + if (Seen.insert(UseMBB) && UseMBB != BarrierMBB) + UseMBBs.push_back(UseMBB); + DenseMap >::iterator + UMII = Uses.find(UseMBB); + if (UMII != Uses.end()) { + DenseMap >::iterator + UMII2 = UseMIs.find(UseMBB); + UMII->second.push_back(&UseMO); + UMII2->second.insert(UseMI); + } else { + SmallVector Ops; + Ops.push_back(&UseMO); + Uses.insert(std::make_pair(UseMBB, Ops)); + SmallPtrSet MIs; + MIs.insert(UseMI); + UseMIs.insert(std::make_pair(UseMBB, MIs)); + } + } + + // Walk up the predecessor chains. + SmallPtrSet Visited; + ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited, + Uses, UseMIs, UseMBBs); + + // Remove live range from barrier to the restore. FIXME: Find a better + // point to re-start the live interval. + VNInfo* AfterValNo = UpdateRegisterInterval(ValNo, + LIs->getUseIndex(BarrierIdx)+1, + LIs->getDefIndex(RestoreIdx)); + + // Attempt to renumber the new valno into a new vreg. + RenumberValno(AfterValNo); +} + /// RenumberValno - Split the given valno out into a new vreg, allowing it to /// be allocated to a different register. This function creates a new vreg, /// copies the valno and its live ranges over to the new vreg's interval, -- GitLab From ac272eaf13e278af469ab0da7656ffd925b37e4f Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 26 Jan 2009 21:36:31 +0000 Subject: [PATCH 231/682] At Nick Lewycky's request, rename this test with a more informative name. llvm-svn: 63042 --- llvm/test/CodeGen/X86/{pr3018.ll => dag-rauw-cse.ll} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename llvm/test/CodeGen/X86/{pr3018.ll => dag-rauw-cse.ll} (100%) diff --git a/llvm/test/CodeGen/X86/pr3018.ll b/llvm/test/CodeGen/X86/dag-rauw-cse.ll similarity index 100% rename from llvm/test/CodeGen/X86/pr3018.ll rename to llvm/test/CodeGen/X86/dag-rauw-cse.ll -- GitLab From 99113fd577d74d3f5be9de9976b9008e8236537a Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 26 Jan 2009 21:38:32 +0000 Subject: [PATCH 232/682] Method decription meta-data and its setting in class_ro_t meta-data. llvm-svn: 63043 --- clang/lib/CodeGen/CGObjCMac.cpp | 119 +++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 17 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 1353047aa810..b70ef5e7c325 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -353,6 +353,9 @@ public: { } virtual llvm::Constant *GenerateConstantString(const std::string &String); + + virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, + const ObjCContainerDecl *CD=0); }; class CGObjCMac : public CGObjCCommonMac { @@ -412,9 +415,9 @@ private: llvm::Constant *Protocols, const llvm::Type *InterfaceTy, const ConstantVector &Methods); - + llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); - + llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD); /// EmitMethodList - Emit the method list for the given @@ -473,7 +476,7 @@ private: /// EmitSelector - Return a Value*, of type ObjCTypes.SelectorPtrTy, /// for the given selector. llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel); - + /// GetProtocolRef - Return a reference to the internal protocol /// description, creating an empty one if it has not been /// defined. The return value has type ProtocolPtrTy. @@ -505,9 +508,6 @@ public: virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel); - virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, - const ObjCContainerDecl *CD=0); - virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); @@ -555,8 +555,14 @@ private: llvm::Constant *IsAGV, llvm::Constant *SuperClassGV, llvm::Constant *ClassRoGV); - - + + llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); + + /// EmitMethodList - Emit the method list for the given + /// implementation. The return value has type MethodListnfABITy. + llvm::Constant *EmitMethodList(const std::string &Name, + const char *Section, + const ConstantVector &Methods); public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); @@ -586,10 +592,6 @@ public: virtual llvm::Value *GetSelector(CGBuilderTy &Builder, Selector Sel) { return 0; } - virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD, - const ObjCContainerDecl *CD=0) - { return 0; } - virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); @@ -1607,7 +1609,7 @@ llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name, ObjCTypes.MethodListPtrTy); } -llvm::Function *CGObjCMac::GenerateMethod(const ObjCMethodDecl *OMD, +llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, const ObjCContainerDecl *CD) { std::string Name; GetNameForMethod(OMD, CD, Name); @@ -3100,7 +3102,7 @@ enum MetaDataDlags { CLS = 0x0, CLS_META = 0x1, CLS_ROOT = 0x2, - CLS_HIDDEN = 0x10, + OBJC2_CLS_HIDDEN = 0x10, CLS_EXCEPTION = 0x20 }; /// BuildClassRoTInitializer - generate meta-data for: @@ -3131,7 +3133,27 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( // FIXME. For 64bit targets add 0 here. Values[ 3] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); Values[ 4] = GetClassName(ID->getIdentifier()); - Values[ 5] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + // const struct _method_list_t * const baseMethods; + std::vector Methods; + std::string MethodListName("\01l_OBJC_$_"); + if (flags & CLS_META) { + MethodListName += "CLASS_METHODS_" + ID->getNameAsString(); + for (ObjCImplementationDecl::classmeth_iterator i = ID->classmeth_begin(), + e = ID->classmeth_end(); i != e; ++i) { + // Class methods should always be defined. + Methods.push_back(GetMethodConstant(*i)); + } + } else { + MethodListName += "INSTANCE_METHODS_" + ID->getNameAsString(); + for (ObjCImplementationDecl::instmeth_iterator i = ID->instmeth_begin(), + e = ID->instmeth_end(); i != e; ++i) { + // Instance methods should always be defined. + Methods.push_back(GetMethodConstant(*i)); + } + } + // FIXME. Section may always be .data + Values[ 5] = EmitMethodList(MethodListName, + ".section __DATA,__data,regular,no_dead_strip", Methods); Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); @@ -3215,6 +3237,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { &CGM.getModule()); UsedGlobals.push_back(ObjCEmptyVtableVar); } + assert(ID->getClassInterface() && + "CGObjCNonFragileABIMac::GenerateClass - class is 0"); uint32_t InstanceStart = CGM.getTargetData().getTypePaddedSize(ObjCTypes.ClassnfABITy); uint32_t InstanceSize = InstanceStart; @@ -3224,7 +3248,9 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *SuperClassGV, *IsAGV; - if (ID->getClassInterface() && !ID->getClassInterface()->getSuperClass()) { + if (IsClassHidden(ID->getClassInterface())) + flags |= OBJC2_CLS_HIDDEN; + if (!ID->getClassInterface()->getSuperClass()) { // class is root flags |= CLS_ROOT; std::string SuperClassName = ObjCClassName + ClassName; @@ -3272,7 +3298,9 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { // Metadata for the class flags = CLS; - if (ID->getClassInterface() && !ID->getClassInterface()->getSuperClass()) { + if (IsClassHidden(ID->getClassInterface())) + flags |= OBJC2_CLS_HIDDEN; + if (!ID->getClassInterface()->getSuperClass()) { flags |= CLS_ROOT; SuperClassGV = 0; } @@ -3390,6 +3418,63 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) UsedGlobals.push_back(GCATV); DefinedCategories.push_back(GCATV); } + +/// GetMethodConstant - Return a struct objc_method constant for the +/// given method if it has been defined. The result is null if the +/// method has not been defined. The return value has type MethodPtrTy. +llvm::Constant *CGObjCNonFragileABIMac::GetMethodConstant( + const ObjCMethodDecl *MD) { + // FIXME: Use DenseMap::lookup + llvm::Function *Fn = MethodDefinitions[MD]; + if (!Fn) + return 0; + + std::vector Method(3); + Method[0] = + llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), + ObjCTypes.SelectorPtrTy); + Method[1] = GetMethodVarType(MD); + Method[2] = llvm::ConstantExpr::getBitCast(Fn, ObjCTypes.Int8PtrTy); + return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Method); +} + +/// EmitMethodList - Build meta-data for method declarations +/// struct _method_list_t { +/// uint32_t entsize; // sizeof(struct _objc_method) +/// uint32_t method_count; +/// struct _objc_method method_list[method_count]; +/// } +/// +llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( + const std::string &Name, + const char *Section, + const ConstantVector &Methods) { + // Return null for empty list. + if (Methods.empty()) + return llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + + std::vector Values(3); + // sizeof(struct _objc_method) + unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.MethodTy); + Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); + // method_count + Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Methods.size()); + llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.MethodTy, + Methods.size()); + Values[2] = llvm::ConstantArray::get(AT, Methods); + llvm::Constant *Init = llvm::ConstantStruct::get(Values); + + llvm::GlobalVariable *GV = + new llvm::GlobalVariable(Init->getType(), false, + llvm::GlobalValue::InternalLinkage, + Init, + Name, + &CGM.getModule()); + GV->setSection(Section); + UsedGlobals.push_back(GV); + return llvm::ConstantExpr::getBitCast(GV, + ObjCTypes.MethodListnfABIPtrTy); +} /* *** */ CodeGen::CGObjCRuntime * -- GitLab From a26699211d071d0fb425b95f902d66e5958c5ec8 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 26 Jan 2009 21:42:04 +0000 Subject: [PATCH 233/682] Add method raw_fd_ostream::seek() for random access within a file. llvm-svn: 63044 --- llvm/include/llvm/Support/raw_ostream.h | 6 +++++- llvm/lib/Support/raw_ostream.cpp | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h index 1a4f6bf6f471..030412169d8a 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -181,7 +181,11 @@ public: /// tell - Return the current offset with the file. uint64_t tell() { return pos + (OutBufCur - OutBufStart); - } + } + + /// seek - Flushes the stream and repositions the underlying file descriptor + /// positition to the offset specified from the beginning of the file. + uint64_t seek(uint64_t off); }; /// raw_stdout_ostream - This is a stream that always prints to stdout. diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index 96c9a3a263d0..29665dc350c6 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -255,6 +255,12 @@ void raw_fd_ostream::close() { FD = -1; } +uint64_t raw_fd_ostream::seek(uint64_t off) { + flush(); + pos = lseek(FD, off, SEEK_SET); + return pos; +} + //===----------------------------------------------------------------------===// // raw_stdout/err_ostream //===----------------------------------------------------------------------===// -- GitLab From eb8c8fbd63922f9665a6838b4c2f8eebf4752b08 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 26 Jan 2009 21:43:14 +0000 Subject: [PATCH 234/682] Embed the offset of the PTH table inside the prologue of the PTH file. This will help improve gradual versioning of PTH files instead of relying that the PTH table is at a fixed offset. llvm-svn: 63045 --- clang/Driver/CacheTokens.cpp | 10 ++++++++++ clang/lib/Lex/PTHLexer.cpp | 19 ++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/clang/Driver/CacheTokens.cpp b/clang/Driver/CacheTokens.cpp index fcb4d2f12db1..975d3648ee29 100644 --- a/clang/Driver/CacheTokens.cpp +++ b/clang/Driver/CacheTokens.cpp @@ -454,6 +454,11 @@ void PTHWriter::EmitCachedSpellings() { } void PTHWriter::GeneratePTH() { + // Generate the prologue. + Out << "cfe-pth"; + Offset JumpOffset = Out.tell(); + Emit32(0); + // Iterate over all the files in SourceManager. Create a lexer // for each file and cache the tokens. SourceManager &SM = PP.getSourceManager(); @@ -490,10 +495,15 @@ void PTHWriter::GeneratePTH() { Offset FileTableOff = EmitFileTable(); // Finally, write out the offset table at the end. + Offset JumpTargetOffset = Out.tell(); Emit32(IdTableOff.first); Emit32(IdTableOff.second.first); Emit32(IdTableOff.second.second); Emit32(FileTableOff); + + // Now write the offset in the prologue. + Out.seek(JumpOffset); + Emit32(JumpTargetOffset); } void clang::CacheTokens(Preprocessor& PP, const std::string& OutFile) { diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index f6994e0976d2..747ec101566b 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -520,17 +520,18 @@ PTHManager* PTHManager::Create(const std::string& file) { // words at the end of the file. const unsigned char* BufBeg = (unsigned char*)File->getBufferStart(); const unsigned char* BufEnd = (unsigned char*)File->getBufferEnd(); - - if(!(BufEnd > BufBeg + sizeof(uint32_t)*3)) { - assert(false && "Invalid PTH file."); - return 0; // FIXME: Proper error diagnostic? - } + + // Check the prologue of the file. + if ((BufEnd - BufBeg) < (unsigned) (sizeof("cfe-pth") + 3) || + memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) + return 0; // Compute the address of the index table at the end of the PTH file. - // This table contains the offset of the file lookup table, the - // persistent ID -> identifer data table. - // FIXME: We should just embed this offset in the PTH file. - const unsigned char* EndTable = BufEnd - sizeof(uint32_t)*4; + const unsigned char *p = BufBeg + (sizeof("cfe-pth") - 1); + const unsigned char *EndTable = BufBeg + ReadLE32(p); + + if (EndTable >= BufEnd) + return 0; // Construct the file lookup table. This will be used for mapping from // FileEntry*'s to cached tokens. -- GitLab From 978b5beceadc7e001b1084acc31731203ab610ff Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 26 Jan 2009 21:50:21 +0000 Subject: [PATCH 235/682] Add version number checking to PTH files. llvm-svn: 63047 --- clang/Driver/CacheTokens.cpp | 1 + clang/lib/Lex/PTHLexer.cpp | 10 ++++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/Driver/CacheTokens.cpp b/clang/Driver/CacheTokens.cpp index 975d3648ee29..aef59cbe352b 100644 --- a/clang/Driver/CacheTokens.cpp +++ b/clang/Driver/CacheTokens.cpp @@ -456,6 +456,7 @@ void PTHWriter::EmitCachedSpellings() { void PTHWriter::GeneratePTH() { // Generate the prologue. Out << "cfe-pth"; + Emit32(PTHManager::Version); Offset JumpOffset = Out.tell(); Emit32(0); diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 747ec101566b..54269c9ee15b 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -522,12 +522,18 @@ PTHManager* PTHManager::Create(const std::string& file) { const unsigned char* BufEnd = (unsigned char*)File->getBufferEnd(); // Check the prologue of the file. - if ((BufEnd - BufBeg) < (unsigned) (sizeof("cfe-pth") + 3) || + if ((BufEnd - BufBeg) < (unsigned) (sizeof("cfe-pth") + 3 + 4) || memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) return 0; - // Compute the address of the index table at the end of the PTH file. + // Read the PTH version. const unsigned char *p = BufBeg + (sizeof("cfe-pth") - 1); + unsigned Version = ReadLE32(p); + + if (Version != PTHManager::Version) + return 0; + + // Compute the address of the index table at the end of the PTH file. const unsigned char *EndTable = BufBeg + ReadLE32(p); if (EndTable >= BufEnd) -- GitLab From d77e4769213c0dff8a347ab8c1bdc14ce15077f2 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 26 Jan 2009 21:54:18 +0000 Subject: [PATCH 236/682] Fix PR3393, which amounts to a bug in the expensive checking logic. Rather than make the checking more complicated, I've tweaked some logic to make things conform to how the checking thought things ought to be, since this results in a simpler "mental model". llvm-svn: 63048 --- .../CodeGen/SelectionDAG/LegalizeTypes.cpp | 52 +++++++++++++------ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 1 + .../test/CodeGen/X86/2009-01-26-WrongCheck.ll | 16 ++++++ 3 files changed, 53 insertions(+), 16 deletions(-) create mode 100644 llvm/test/CodeGen/X86/2009-01-26-WrongCheck.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 4c5dd030c7a1..36180c33d46e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -328,14 +328,21 @@ ScanOperands: continue; // The node morphed - this is equivalent to legalizing by replacing every - // value of N with the corresponding value of M. So do that now. - N->setNodeId(ReadyToProcess); + // value of N with the corresponding value of M. So do that now. However + // there is no need to remember the replacement - morphing will make sure + // it is never used non-trivially. assert(N->getNumValues() == M->getNumValues() && "Node morphing changed the number of results!"); for (unsigned i = 0, e = N->getNumValues(); i != e; ++i) - // Replacing the value takes care of remapping the new value. - ReplaceValueWith(SDValue(N, i), SDValue(M, i)); - // Fall through. + // Replacing the value takes care of remapping the new value. Do the + // replacement without recording it in ReplacedValues. This does not + // expunge From but that is fine - it is not really a new node. + ReplaceValueWithHelper(SDValue(N, i), SDValue(M, i)); + assert(N->getNodeId() == NewNode && "Unexpected node state!"); + // The node continues to live on as part of the NewNode fungus that + // grows on top of the useful nodes. Nothing more needs to be done + // with it - move on to the next node. + continue; } if (i == NumOperands) { @@ -668,16 +675,14 @@ namespace { } -/// ReplaceValueWith - The specified value was legalized to the specified other -/// value. Update the DAG and NodeIds replacing any uses of From to use To -/// instead. -void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { - assert(From.getNode()->getNodeId() == ReadyToProcess && - "Only the node being processed may be remapped!"); +/// ReplaceValueWithHelper - Internal helper for ReplaceValueWith. Updates the +/// DAG causing any uses of From to use To instead, but without expunging From +/// or recording the replacement in ReplacedValues. Do not call directly unless +/// you really know what you are doing! +void DAGTypeLegalizer::ReplaceValueWithHelper(SDValue From, SDValue To) { assert(From.getNode() != To.getNode() && "Potential legalization loop!"); // If expansion produced new nodes, make sure they are properly marked. - ExpungeNode(From.getNode()); AnalyzeNewValue(To); // Expunges To. // Anything that used the old node should now use the new one. Note that this @@ -686,10 +691,6 @@ void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { NodeUpdateListener NUL(*this, NodesToAnalyze); DAG.ReplaceAllUsesOfValueWith(From, To, &NUL); - // The old node may still be present in a map like ExpandedIntegers or - // PromotedIntegers. Inform maps about the replacement. - ReplacedValues[From] = To; - // Process the list of nodes that need to be reanalyzed. while (!NodesToAnalyze.empty()) { SDNode *N = NodesToAnalyze.back(); @@ -719,6 +720,25 @@ void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { } } +/// ReplaceValueWith - The specified value was legalized to the specified other +/// value. Update the DAG and NodeIds replacing any uses of From to use To +/// instead. +void DAGTypeLegalizer::ReplaceValueWith(SDValue From, SDValue To) { + assert(From.getNode()->getNodeId() == ReadyToProcess && + "Only the node being processed may be remapped!"); + + // If expansion produced new nodes, make sure they are properly marked. + ExpungeNode(From.getNode()); + AnalyzeNewValue(To); // Expunges To. + + // The old node may still be present in a map like ExpandedIntegers or + // PromotedIntegers. Inform maps about the replacement. + ReplacedValues[From] = To; + + // Do the replacement. + ReplaceValueWithHelper(From, To); +} + void DAGTypeLegalizer::SetPromotedInteger(SDValue Op, SDValue Result) { AnalyzeNewValue(Result); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index a2c91cb5bedb..17b79233e49b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -199,6 +199,7 @@ private: const SDValue *Ops, unsigned NumOps, bool isSigned); SDValue PromoteTargetBoolean(SDValue Bool, MVT VT); void ReplaceValueWith(SDValue From, SDValue To); + void ReplaceValueWithHelper(SDValue From, SDValue To); void SetIgnoredNodeResult(SDNode* N); void SplitInteger(SDValue Op, SDValue &Lo, SDValue &Hi); void SplitInteger(SDValue Op, MVT LoVT, MVT HiVT, diff --git a/llvm/test/CodeGen/X86/2009-01-26-WrongCheck.ll b/llvm/test/CodeGen/X86/2009-01-26-WrongCheck.ll new file mode 100644 index 000000000000..db9dbb67def4 --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-01-26-WrongCheck.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | llc -march=x86 -enable-legalize-types-checking +; PR3393 + +define void @foo(i32 inreg %x) { + %t709 = select i1 false, i32 0, i32 %x ; [#uses=1] + %t711 = add i32 %t709, 1 ; [#uses=4] + %t801 = icmp slt i32 %t711, 0 ; [#uses=1] + %t712 = zext i32 %t711 to i64 ; [#uses=1] + %t804 = select i1 %t801, i64 0, i64 %t712 ; [#uses=1] + store i64 %t804, i64* null + %t815 = icmp slt i32 %t711, 0 ; [#uses=1] + %t814 = sext i32 %t711 to i64 ; [#uses=1] + %t816 = select i1 %t815, i64 0, i64 %t814 ; [#uses=1] + store i64 %t816, i64* null + unreachable +} -- GitLab From e84c3f261ed32672b3da79d191654de433ffc99a Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 26 Jan 2009 21:57:31 +0000 Subject: [PATCH 237/682] Reapply r63025 and r63026, with fixes for the failing testcases. llvm-svn: 63049 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 369 +------------------------ 1 file changed, 13 insertions(+), 356 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 16a9e6d9b041..e3d652ac5e34 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -139,26 +139,11 @@ namespace { void UpdateSpillSlotInterval(VNInfo*, unsigned, unsigned); - VNInfo* UpdateRegisterInterval(VNInfo*, unsigned, unsigned); - - bool ShrinkWrapToLastUse(MachineBasicBlock*, VNInfo*, - SmallVector&, - SmallPtrSet&); - - void ShrinkWrapLiveInterval(VNInfo*, MachineBasicBlock*, MachineBasicBlock*, - MachineBasicBlock*, SmallPtrSet&, - DenseMap >&, - DenseMap >&, - SmallVector&); - bool SplitRegLiveInterval(LiveInterval*); bool SplitRegLiveIntervals(const TargetRegisterClass **, SmallPtrSet&); - void RepairLiveInterval(LiveInterval* CurrLI, VNInfo* ValNo, - MachineInstr* DefMI, unsigned RestoreIdx); - bool createsNewJoin(LiveRange* LR, MachineBasicBlock* DefMBB, MachineBasicBlock* BarrierMBB); bool Rematerialize(unsigned vreg, VNInfo* ValNo, @@ -423,176 +408,6 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex, } } -/// UpdateRegisterInterval - Given the specified val# of the current live -/// interval is being split, and the spill and restore indices, update the live -/// interval accordingly. -VNInfo* -PreAllocSplitting::UpdateRegisterInterval(VNInfo *ValNo, unsigned SpillIndex, - unsigned RestoreIndex) { - assert(LIs->getMBBFromIndex(RestoreIndex) == BarrierMBB && - "Expect restore in the barrier mbb"); - - SmallVector, 4> Before; - SmallVector, 4> After; - SmallVector BeforeKills; - SmallVector AfterKills; - SmallPtrSet Processed; - - // First, let's figure out which parts of the live interval is now defined - // by the restore, which are defined by the original definition. - const LiveRange *LR = CurrLI->getLiveRangeContaining(RestoreIndex); - After.push_back(std::make_pair(RestoreIndex, LR->end)); - if (CurrLI->isKill(ValNo, LR->end)) - AfterKills.push_back(LR->end); - - assert(LR->contains(SpillIndex)); - if (SpillIndex > LR->start) { - Before.push_back(std::make_pair(LR->start, SpillIndex)); - BeforeKills.push_back(SpillIndex); - } - Processed.insert(LR); - - // Start from the restore mbb, figure out what part of the live interval - // are defined by the restore. - SmallVector WorkList; - MachineBasicBlock *MBB = BarrierMBB; - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - WorkList.push_back(*SI); - - SmallPtrSet ProcessedBlocks; - ProcessedBlocks.insert(MBB); - - while (!WorkList.empty()) { - MBB = WorkList.back(); - WorkList.pop_back(); - unsigned Idx = LIs->getMBBStartIdx(MBB); - LR = CurrLI->getLiveRangeContaining(Idx); - if (LR && LR->valno == ValNo && !Processed.count(LR)) { - After.push_back(std::make_pair(LR->start, LR->end)); - if (CurrLI->isKill(ValNo, LR->end)) - AfterKills.push_back(LR->end); - Idx = LIs->getMBBEndIdx(MBB); - if (LR->end > Idx) { - // Live range extend beyond at least one mbb. Let's see what other - // mbbs it reaches. - LIs->findReachableMBBs(LR->start, LR->end, WorkList); - } - Processed.insert(LR); - } - - ProcessedBlocks.insert(MBB); - if (LR) - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) - if (!ProcessedBlocks.count(*SI)) - WorkList.push_back(*SI); - } - - for (LiveInterval::iterator I = CurrLI->begin(), E = CurrLI->end(); - I != E; ++I) { - LiveRange *LR = I; - if (LR->valno == ValNo && !Processed.count(LR)) { - Before.push_back(std::make_pair(LR->start, LR->end)); - if (CurrLI->isKill(ValNo, LR->end)) - BeforeKills.push_back(LR->end); - } - } - - // Now create new val#s to represent the live ranges defined by the old def - // those defined by the restore. - unsigned AfterDef = ValNo->def; - MachineInstr *AfterCopy = ValNo->copy; - bool HasPHIKill = ValNo->hasPHIKill; - CurrLI->removeValNo(ValNo); - VNInfo *BValNo = (Before.empty()) - ? NULL - : CurrLI->getNextValue(AfterDef, AfterCopy, LIs->getVNInfoAllocator()); - if (BValNo) - CurrLI->addKills(BValNo, BeforeKills); - - VNInfo *AValNo = (After.empty()) - ? NULL - : CurrLI->getNextValue(RestoreIndex, 0, LIs->getVNInfoAllocator()); - if (AValNo) { - AValNo->hasPHIKill = HasPHIKill; - CurrLI->addKills(AValNo, AfterKills); - } - - for (unsigned i = 0, e = Before.size(); i != e; ++i) { - unsigned Start = Before[i].first; - unsigned End = Before[i].second; - CurrLI->addRange(LiveRange(Start, End, BValNo)); - } - for (unsigned i = 0, e = After.size(); i != e; ++i) { - unsigned Start = After[i].first; - unsigned End = After[i].second; - CurrLI->addRange(LiveRange(Start, End, AValNo)); - } - - return AValNo; -} - -/// ShrinkWrapToLastUse - There are uses of the current live interval in the -/// given block, shrink wrap the live interval to the last use (i.e. remove -/// from last use to the end of the mbb). In case mbb is the where the barrier -/// is, remove from the last use to the barrier. -bool -PreAllocSplitting::ShrinkWrapToLastUse(MachineBasicBlock *MBB, VNInfo *ValNo, - SmallVector &Uses, - SmallPtrSet &UseMIs) { - MachineOperand *LastMO = 0; - MachineInstr *LastMI = 0; - if (MBB != BarrierMBB && Uses.size() == 1) { - // Single use, no need to traverse the block. We can't assume this for the - // barrier bb though since the use is probably below the barrier. - LastMO = Uses[0]; - LastMI = LastMO->getParent(); - } else { - MachineBasicBlock::iterator MEE = MBB->begin(); - MachineBasicBlock::iterator MII; - if (MBB == BarrierMBB) - MII = Barrier; - else - MII = MBB->end(); - while (MII != MEE) { - --MII; - MachineInstr *UseMI = &*MII; - if (!UseMIs.count(UseMI)) - continue; - for (unsigned i = 0, e = UseMI->getNumOperands(); i != e; ++i) { - MachineOperand &MO = UseMI->getOperand(i); - if (MO.isReg() && MO.getReg() == CurrLI->reg) { - LastMO = &MO; - break; - } - } - LastMI = UseMI; - break; - } - } - - // Cut off live range from last use (or beginning of the mbb if there - // are no uses in it) to the end of the mbb. - unsigned RangeStart, RangeEnd = LIs->getMBBEndIdx(MBB)+1; - if (LastMI) { - RangeStart = LIs->getUseIndex(LIs->getInstructionIndex(LastMI))+1; - assert(!LastMO->isKill() && "Last use already terminates the interval?"); - LastMO->setIsKill(); - } else { - assert(MBB == BarrierMBB); - RangeStart = LIs->getMBBStartIdx(MBB); - } - if (MBB == BarrierMBB) - RangeEnd = LIs->getUseIndex(BarrierIdx)+1; - CurrLI->removeRange(RangeStart, RangeEnd); - if (LastMI) - CurrLI->addKill(ValNo, RangeStart); - - // Return true if the last use becomes a new kill. - return LastMI; -} - /// PerformPHIConstruction - From properly set up use and def lists, use a PHI /// construction algorithm to compute the ranges and valnos for an interval. VNInfo* PreAllocSplitting::PerformPHIConstruction( @@ -748,12 +563,12 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); + LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); + // FIXME: Need to set kills properly for inter-block stuff. if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex); if (intrablock) LI->addKill(ret, EndIndex); - - LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); } else if (ContainsDefs && ContainsUses){ SmallPtrSet& BlockDefs = Defs[MBB]; SmallPtrSet& BlockUses = Uses[MBB]; @@ -805,13 +620,13 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, NewVNs, LiveOut, Phis, false, true); + LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); + if (foundUse && LI->isKill(ret, StartIndex)) LI->removeKill(ret, StartIndex); if (intrablock) { LI->addKill(ret, EndIndex); } - - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); } // Memoize results so we don't have to recompute them. @@ -890,142 +705,6 @@ void PreAllocSplitting::ReconstructLiveInterval(LiveInterval* LI) { } } -/// ShrinkWrapLiveInterval - Recursively traverse the predecessor -/// chain to find the new 'kills' and shrink wrap the live interval to the -/// new kill indices. -void -PreAllocSplitting::ShrinkWrapLiveInterval(VNInfo *ValNo, MachineBasicBlock *MBB, - MachineBasicBlock *SuccMBB, MachineBasicBlock *DefMBB, - SmallPtrSet &Visited, - DenseMap > &Uses, - DenseMap > &UseMIs, - SmallVector &UseMBBs) { - if (Visited.count(MBB)) - return; - - // If live interval is live in another successor path, then we can't process - // this block. But we may able to do so after all the successors have been - // processed. - if (MBB != BarrierMBB) { - for (MachineBasicBlock::succ_iterator SI = MBB->succ_begin(), - SE = MBB->succ_end(); SI != SE; ++SI) { - MachineBasicBlock *SMBB = *SI; - if (SMBB == SuccMBB) - continue; - if (CurrLI->liveAt(LIs->getMBBStartIdx(SMBB))) - return; - } - } - - Visited.insert(MBB); - - DenseMap >::iterator - UMII = Uses.find(MBB); - if (UMII != Uses.end()) { - // At least one use in this mbb, lets look for the kill. - DenseMap >::iterator - UMII2 = UseMIs.find(MBB); - if (ShrinkWrapToLastUse(MBB, ValNo, UMII->second, UMII2->second)) - // Found a kill, shrink wrapping of this path ends here. - return; - } else if (MBB == DefMBB) { - // There are no uses after the def. - MachineInstr *DefMI = LIs->getInstructionFromIndex(ValNo->def); - if (UseMBBs.empty()) { - // The only use must be below barrier in the barrier block. It's safe to - // remove the def. - LIs->RemoveMachineInstrFromMaps(DefMI); - DefMI->eraseFromParent(); - CurrLI->removeRange(ValNo->def, LIs->getMBBEndIdx(MBB)+1); - } - } else if (MBB == BarrierMBB) { - // Remove entire live range from start of mbb to barrier. - CurrLI->removeRange(LIs->getMBBStartIdx(MBB), - LIs->getUseIndex(BarrierIdx)+1); - } else { - // Remove entire live range of the mbb out of the live interval. - CurrLI->removeRange(LIs->getMBBStartIdx(MBB), LIs->getMBBEndIdx(MBB)+1); - } - - if (MBB == DefMBB) - // Reached the def mbb, stop traversing this path further. - return; - - // Traverse the pathes up the predecessor chains further. - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - MachineBasicBlock *Pred = *PI; - if (Pred == MBB) - continue; - if (Pred == DefMBB && ValNo->hasPHIKill) - // Pred is the def bb and the def reaches other val#s, we must - // allow the value to be live out of the bb. - continue; - if (!CurrLI->liveAt(LIs->getMBBEndIdx(Pred)-1)) - return; - ShrinkWrapLiveInterval(ValNo, Pred, MBB, DefMBB, Visited, - Uses, UseMIs, UseMBBs); - } - - return; -} - - -void PreAllocSplitting::RepairLiveInterval(LiveInterval* CurrLI, - VNInfo* ValNo, - MachineInstr* DefMI, - unsigned RestoreIdx) { - // Shrink wrap the live interval by walking up the CFG and find the - // new kills. - // Now let's find all the uses of the val#. - DenseMap > Uses; - DenseMap > UseMIs; - SmallPtrSet Seen; - SmallVector UseMBBs; - for (MachineRegisterInfo::use_iterator UI = MRI->use_begin(CurrLI->reg), - UE = MRI->use_end(); UI != UE; ++UI) { - MachineOperand &UseMO = UI.getOperand(); - MachineInstr *UseMI = UseMO.getParent(); - unsigned UseIdx = LIs->getInstructionIndex(UseMI); - LiveInterval::iterator ULR = CurrLI->FindLiveRangeContaining(UseIdx); - if (ULR->valno != ValNo) - continue; - MachineBasicBlock *UseMBB = UseMI->getParent(); - // Remember which other mbb's use this val#. - if (Seen.insert(UseMBB) && UseMBB != BarrierMBB) - UseMBBs.push_back(UseMBB); - DenseMap >::iterator - UMII = Uses.find(UseMBB); - if (UMII != Uses.end()) { - DenseMap >::iterator - UMII2 = UseMIs.find(UseMBB); - UMII->second.push_back(&UseMO); - UMII2->second.insert(UseMI); - } else { - SmallVector Ops; - Ops.push_back(&UseMO); - Uses.insert(std::make_pair(UseMBB, Ops)); - SmallPtrSet MIs; - MIs.insert(UseMI); - UseMIs.insert(std::make_pair(UseMBB, MIs)); - } - } - - // Walk up the predecessor chains. - SmallPtrSet Visited; - ShrinkWrapLiveInterval(ValNo, BarrierMBB, NULL, DefMI->getParent(), Visited, - Uses, UseMIs, UseMBBs); - - // Remove live range from barrier to the restore. FIXME: Find a better - // point to re-start the live interval. - VNInfo* AfterValNo = UpdateRegisterInterval(ValNo, - LIs->getUseIndex(BarrierIdx)+1, - LIs->getDefIndex(RestoreIdx)); - - // Attempt to renumber the new valno into a new vreg. - RenumberValno(AfterValNo); -} - /// RenumberValno - Split the given valno out into a new vreg, allowing it to /// be allocated to a different register. This function creates a new vreg, /// copies the valno and its live ranges over to the new vreg's interval, @@ -1055,12 +734,12 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) { for (SmallVector::iterator KI = OldVN->kills.begin(), KE = OldVN->kills.end(); KI != KE; ++KI) { MachineInstr* MI = LIs->getInstructionFromIndex(*KI); - //if (!MI) continue; unsigned DefIdx = MI->findRegisterDefOperandIdx(CurrLI->reg); if (DefIdx == ~0U) continue; if (MI->isRegReDefinedByTwoAddr(DefIdx)) { VNInfo* NextVN = CurrLI->findDefinedVNInfo(LiveIntervals::getDefIndex(*KI)); + if (NextVN == OldVN) continue; Stack.push_back(NextVN); } } @@ -1131,18 +810,10 @@ bool PreAllocSplitting::Rematerialize(unsigned vreg, VNInfo* ValNo, TII->reMaterialize(MBB, RestorePt, vreg, DefMI); LIs->InsertMachineInstrInMaps(prior(RestorePt), RestoreIdx); - if (KillPt->getParent() == BarrierMBB) { - VNInfo* After = UpdateRegisterInterval(ValNo, LIs->getUseIndex(KillIdx)+1, - LIs->getDefIndex(RestoreIdx)); - - RenumberValno(After); - - ++NumSplits; - ++NumRemats; - return true; - } - - RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIdx); + ReconstructLiveInterval(CurrLI); + unsigned RematIdx = LIs->getInstructionIndex(prior(RestorePt)); + RematIdx = LiveIntervals::getDefIndex(RematIdx); + RenumberValno(CurrLI->findDefinedVNInfo(RematIdx)); ++NumSplits; ++NumRemats; @@ -1315,28 +986,14 @@ bool PreAllocSplitting::SplitRegLiveInterval(LiveInterval *LI) { MachineInstr *LoadMI = prior(RestorePt); LIs->InsertMachineInstrInMaps(LoadMI, RestoreIndex); - // If live interval is spilled in the same block as the barrier, just - // create a hole in the interval. - if (!DefMBB || - (SpillMI && SpillMI->getParent() == BarrierMBB)) { - // Update spill stack slot live interval. - UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, - LIs->getDefIndex(RestoreIndex)); - - VNInfo* After = UpdateRegisterInterval(ValNo, - LIs->getUseIndex(SpillIndex)+1, - LIs->getDefIndex(RestoreIndex)); - RenumberValno(After); - - ++NumSplits; - return true; - } - // Update spill stack slot live interval. UpdateSpillSlotInterval(ValNo, LIs->getUseIndex(SpillIndex)+1, LIs->getDefIndex(RestoreIndex)); - RepairLiveInterval(CurrLI, ValNo, DefMI, RestoreIndex); + ReconstructLiveInterval(CurrLI); + unsigned RestoreIdx = LIs->getInstructionIndex(prior(RestorePt)); + RestoreIdx = LiveIntervals::getDefIndex(RestoreIdx); + RenumberValno(CurrLI->findDefinedVNInfo(RestoreIdx)); ++NumSplits; return true; -- GitLab From 8cf220398b7854799da3698f4a2c82949ab770d6 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 26 Jan 2009 22:03:42 +0000 Subject: [PATCH 238/682] More updates to VC proj... llvm-svn: 63050 --- llvm/win32/Analysis/Analysis.vcproj | 4 ++ llvm/win32/AsmParser/AsmParser.vcproj | 76 +++++---------------------- 2 files changed, 18 insertions(+), 62 deletions(-) diff --git a/llvm/win32/Analysis/Analysis.vcproj b/llvm/win32/Analysis/Analysis.vcproj index 6119a2bf7038..3f5550fe3bff 100644 --- a/llvm/win32/Analysis/Analysis.vcproj +++ b/llvm/win32/Analysis/Analysis.vcproj @@ -340,6 +340,10 @@ RelativePath="..\..\lib\Analysis\ConstantFolding.cpp" > + + diff --git a/llvm/win32/AsmParser/AsmParser.vcproj b/llvm/win32/AsmParser/AsmParser.vcproj index 782ca2a889c6..96ca6d172b61 100644 --- a/llvm/win32/AsmParser/AsmParser.vcproj +++ b/llvm/win32/AsmParser/AsmParser.vcproj @@ -90,11 +90,11 @@ /> - - - - - - - - - - - - - - - - -- GitLab From 2483a6126f2aac46cc7ff67a1fc32b69dda16463 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 26 Jan 2009 22:15:00 +0000 Subject: [PATCH 239/682] Add version number to PTH files. llvm-svn: 63052 --- clang/include/clang/Lex/PTHManager.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Lex/PTHManager.h b/clang/include/clang/Lex/PTHManager.h index 09cd9e9e3c92..31cf78f03635 100644 --- a/clang/include/clang/Lex/PTHManager.h +++ b/clang/include/clang/Lex/PTHManager.h @@ -117,7 +117,10 @@ class PTHManager : public IdentifierInfoLookup { } IdentifierInfo* LazilyCreateIdentifierInfo(unsigned PersistentID); -public: +public: + // The current PTH version. + enum { Version = 0 }; + ~PTHManager(); /// get - Return the identifier token info for the specified named identifier. -- GitLab From 327d00cd459b659fa88ffe81500480c5e57fcfa1 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 26 Jan 2009 22:16:12 +0000 Subject: [PATCH 240/682] Silence warning. llvm-svn: 63054 --- clang/lib/Lex/PTHLexer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 54269c9ee15b..d94ab7052564 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -522,7 +522,7 @@ PTHManager* PTHManager::Create(const std::string& file) { const unsigned char* BufEnd = (unsigned char*)File->getBufferEnd(); // Check the prologue of the file. - if ((BufEnd - BufBeg) < (unsigned) (sizeof("cfe-pth") + 3 + 4) || + if ((BufEnd - BufBeg) < (signed) (sizeof("cfe-pth") + 3 + 4) || memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) return 0; -- GitLab From b44ab5f25df06bd511caa2873727a1040d96761c Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Mon, 26 Jan 2009 22:19:12 +0000 Subject: [PATCH 241/682] Add support for member pointers to const_cast. llvm-svn: 63055 --- clang/lib/Sema/SemaNamedCast.cpp | 8 ++++++-- clang/test/SemaCXX/const-cast.cpp | 7 +++++++ clang/www/cxx_status.html | 10 +++++----- 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/clang/lib/Sema/SemaNamedCast.cpp b/clang/lib/Sema/SemaNamedCast.cpp index 06fc9d83bad0..2aeab44db3df 100644 --- a/clang/lib/Sema/SemaNamedCast.cpp +++ b/clang/lib/Sema/SemaNamedCast.cpp @@ -133,7 +133,10 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, SrcType = SrcExpr->getType(); } - if (!DestType->isPointerType()) { + // C++ 5.2.11p5: For a const_cast involving pointers to data members [...] + // the rules for const_cast are the same as those used for pointers. + + if (!DestType->isPointerType() && !DestType->isMemberPointerType()) { // Cannot cast to non-pointer, non-reference type. Note that, if DestType // was a reference type, we converted it to a pointer above. // C++ 5.2.11p3: For two pointer types [...] @@ -141,7 +144,8 @@ CheckConstCast(Sema &Self, Expr *&SrcExpr, QualType DestType, << OrigDestType << DestRange; return; } - if (DestType->isFunctionPointerType()) { + if (DestType->isFunctionPointerType() || + DestType->isMemberFunctionPointerType()) { // Cannot cast direct function pointers. // C++ 5.2.11p2: [...] where T is any object type or the void type [...] // T is the ultimate pointee of source and target type. diff --git a/clang/test/SemaCXX/const-cast.cpp b/clang/test/SemaCXX/const-cast.cpp index 03a0e908ebbf..0c334bf9faa5 100644 --- a/clang/test/SemaCXX/const-cast.cpp +++ b/clang/test/SemaCXX/const-cast.cpp @@ -1,5 +1,7 @@ // RUN: clang -fsyntax-only -verify %s +struct A {}; + // See if aliasing can confuse this baby. typedef char c; typedef c *cp; @@ -33,6 +35,9 @@ char ***good_const_cast_test(ccvpcvpp var) f fp = 0; // Don't misidentify fn** as a function pointer. f *fpp = const_cast(&fp); + int const A::* const A::*icapcap = 0; + int A::* A::* iapap = const_cast(icapcap); + return var4; } @@ -52,5 +57,7 @@ short *bad_const_cast_test(char const *volatile *const volatile *var) f fp1 = 0; // Function pointers. f fp2 = const_cast(fp1); // expected-error {{const_cast to 'f', which is not a reference, pointer-to-object, or pointer-to-data-member}} + void (A::*mfn)() = 0; + (void)const_cast(mfn); // expected-error {{const_cast to 'void (struct A::*)(void)', which is not a reference, pointer-to-object, or pointer-to-data-member}} return **var3; } diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 664e452987e3..5c57f913abac 100644 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -578,7 +578,7 @@ welcome!

    5.2.10 [expr.reinterpret.cast] - ✓ + ✓ @@ -586,11 +586,11 @@ welcome!

    5.2.11 [expr.const.cast] - ✓ - - + ✓ + ✓ + ✓ + - Missing member pointer conversions   5.3 [expr.unary]     5.3.1 [expr.unary.op] -- GitLab From b6d36e1d14edc54d137f6b36c85b042b6dfe17d3 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 26 Jan 2009 22:22:31 +0000 Subject: [PATCH 242/682] Implement Red Zone utilization on x86-64. This is currently disabled by default; I'll enable it when I hook it up with the llvm-gcc flag which controls it. llvm-svn: 63056 --- llvm/include/llvm/Target/TargetOptions.h | 4 ++++ llvm/lib/Target/TargetMachine.cpp | 7 +++++++ llvm/lib/Target/X86/X86RegisterInfo.cpp | 12 ++++++++++++ 3 files changed, 23 insertions(+) diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h index 2419376c5396..d53e399b8593 100644 --- a/llvm/include/llvm/Target/TargetOptions.h +++ b/llvm/include/llvm/Target/TargetOptions.h @@ -107,6 +107,10 @@ namespace llvm { /// wth earlier copy coalescing. extern bool StrongPHIElim; + /// DisableRedZone - This flag disables use of the "Red Zone" on + /// targets which would otherwise have one. + extern bool DisableRedZone; + } // End llvm namespace #endif diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index a1d6fa7eb975..fd577c7438ac 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -40,6 +40,7 @@ namespace llvm { bool VerboseAsm; bool DisableJumpTables; bool StrongPHIElim; + bool DisableRedZone; } static cl::opt PrintCode("print-machineinstrs", @@ -164,6 +165,12 @@ EnableStrongPHIElim(cl::Hidden, "strong-phi-elim", cl::location(StrongPHIElim), cl::init(false)); +static cl::opt +DisableRedZoneOption("disable-red-zone", + cl::desc("Do not emit code that uses the red zone."), + cl::location(DisableRedZone), + cl::init(true)); + //--------------------------------------------------------------------------- // TargetMachine Class // diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index a0d8b58b789c..08746f2ffb47 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -721,6 +721,18 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { // Get desired stack alignment uint64_t MaxAlign = MFI->getMaxAlignment(); + // If this is x86-64 and the Red Zone is not disabled, if we are a leaf + // function, and use up to 128 bytes of stack space, don't have a frame + // pointer, calls, or dynamic alloca then we do not need to adjust the + // stack pointer (we fit in the Red Zone). + if (Is64Bit && !DisableRedZone && + !MFI->hasVarSizedObjects() && // No dynamic alloca. + !MFI->hasCalls()) { // No calls. + StackSize = std::max((uint64_t)X86FI->getCalleeSavedFrameSize(), + StackSize > 128 ? StackSize - 128 : 0); + MFI->setStackSize(StackSize); + } + // Add RETADDR move area to callee saved frame size. int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); if (TailCallReturnAddrDelta < 0) -- GitLab From d38172181012d0eab2c30a58d9ca97f193bf67a5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 22:24:27 +0000 Subject: [PATCH 243/682] Fix a bug I introduced in my changes, which caused MeasureTokenLength to crash when given an instantiation location. Thanks to Fariborz for the testcase. llvm-svn: 63057 --- clang/lib/Lex/Lexer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 7f14e7a4a2df..986dd13d5d8f 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -222,7 +222,8 @@ unsigned Lexer::MeasureTokenLength(SourceLocation Loc, // If this comes from a macro expansion, we really do want the macro name, not // the token this macro expanded to. - std::pair LocInfo = SM.getDecomposedInstantiationLoc(Loc); + Loc = SM.getInstantiationLoc(Loc); + std::pair LocInfo = SM.getDecomposedLoc(Loc); std::pair Buffer = SM.getBufferData(LocInfo.first); const char *StrData = Buffer.first+LocInfo.second; -- GitLab From 3789a13c30e25fb86447b5c9a2e12c169bacc2dd Mon Sep 17 00:00:00 2001 From: Scott Michel Date: Mon, 26 Jan 2009 22:32:51 +0000 Subject: [PATCH 244/682] Make the Dwarf macro information section optional; CellSPU's assembler doesn't support it. The default is set to 'true', so this should not impact any other target backends. llvm-svn: 63058 --- llvm/include/llvm/Target/TargetAsmInfo.h | 17 ++++++++++++----- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 14 +++++++++----- llvm/lib/Target/TargetAsmInfo.cpp | 1 + 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/llvm/include/llvm/Target/TargetAsmInfo.h b/llvm/include/llvm/Target/TargetAsmInfo.h index 0de74103adcf..bdfacf765715 100644 --- a/llvm/include/llvm/Target/TargetAsmInfo.h +++ b/llvm/include/llvm/Target/TargetAsmInfo.h @@ -429,27 +429,31 @@ namespace llvm { /// HasLEB128 - True if target asm supports leb128 directives. /// bool HasLEB128; // Defaults to false. - + /// hasDotLocAndDotFile - True if target asm supports .loc and .file /// directives for emitting debugging information. /// bool HasDotLocAndDotFile; // Defaults to false. - + /// SupportsDebugInformation - True if target supports emission of debugging /// information. bool SupportsDebugInformation; - + /// SupportsExceptionHandling - True if target supports /// exception handling. /// bool SupportsExceptionHandling; // Defaults to false. - + /// RequiresFrameSection - true if the Dwarf2 output needs a frame section /// bool DwarfRequiresFrameSection; // Defaults to true. + /// SupportsMacInfo - true if the Dwarf output supports macro information + /// + bool SupportsMacInfoSection; // Defaults to true + /// NonLocalEHFrameLabel - If set, the EH_frame label needs to be non-local. - /// + /// bool NonLocalEHFrameLabel; // Defaults to false. /// GlobalEHDirective - This is the directive used to make exception frame @@ -818,6 +822,9 @@ namespace llvm { bool doesDwarfRequireFrameSection() const { return DwarfRequiresFrameSection; } + bool doesSupportMacInfoSection() const { + return SupportsMacInfoSection; + } bool doesRequireNonLocalEHFrameLabel() const { return NonLocalEHFrameLabel; } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 4b19d06c924e..c651cb66ceb4 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -2167,8 +2167,10 @@ private: EmitLabel("section_abbrev", 0); Asm->SwitchToDataSection(TAI->getDwarfARangesSection()); EmitLabel("section_aranges", 0); - Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); - EmitLabel("section_macinfo", 0); + if (TAI->doesSupportMacInfoSection()) { + Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); + EmitLabel("section_macinfo", 0); + } Asm->SwitchToDataSection(TAI->getDwarfLineSection()); EmitLabel("section_line", 0); Asm->SwitchToDataSection(TAI->getDwarfLocSection()); @@ -2755,10 +2757,12 @@ private: /// EmitDebugMacInfo - Emit visible names into a debug macinfo section. /// void EmitDebugMacInfo() { - // Start the dwarf macinfo section. - Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); + if (TAI->doesSupportMacInfoSection()) { + // Start the dwarf macinfo section. + Asm->SwitchToDataSection(TAI->getDwarfMacInfoSection()); - Asm->EOL(); + Asm->EOL(); + } } /// ConstructCompileUnits - Create a compile unit DIEs. diff --git a/llvm/lib/Target/TargetAsmInfo.cpp b/llvm/lib/Target/TargetAsmInfo.cpp index 532b8b9a5bbf..4666875c34c2 100644 --- a/llvm/lib/Target/TargetAsmInfo.cpp +++ b/llvm/lib/Target/TargetAsmInfo.cpp @@ -99,6 +99,7 @@ void TargetAsmInfo::fillDefaultValues() { SupportsDebugInformation = false; SupportsExceptionHandling = false; DwarfRequiresFrameSection = true; + SupportsMacInfoSection = true; NonLocalEHFrameLabel = false; GlobalEHDirective = 0; SupportsWeakOmittedEHFrame = true; -- GitLab From 49483188c3cd40ebadd63a4d8d2d0f9b932d559d Mon Sep 17 00:00:00 2001 From: Scott Michel Date: Mon, 26 Jan 2009 22:33:37 +0000 Subject: [PATCH 245/682] CellSPU: - Update DWARF debugging support. llvm-svn: 63059 --- .../CellSPU/AsmPrinter/SPUAsmPrinter.cpp | 38 +++++------ llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp | 66 +++++++------------ llvm/lib/Target/CellSPU/SPUISelLowering.cpp | 7 +- llvm/lib/Target/CellSPU/SPUInstrFormats.td | 3 + llvm/lib/Target/CellSPU/SPUInstrInfo.td | 7 +- llvm/lib/Target/CellSPU/SPUTargetAsmInfo.cpp | 24 +++++++ 6 files changed, 75 insertions(+), 70 deletions(-) diff --git a/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp index bc8f6812a2b1..62da3b7493c3 100644 --- a/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp +++ b/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp @@ -90,13 +90,13 @@ namespace { printOp(MO); } } - + bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, unsigned AsmVariant, const char *ExtraCode); - - + + void printS7ImmOperand(const MachineInstr *MI, unsigned OpNo) { @@ -115,7 +115,7 @@ namespace { assert(value < (1 << 8) && "Invalid u7 argument"); O << value; } - + void printShufAddr(const MachineInstr *MI, unsigned OpNo) { @@ -143,7 +143,7 @@ namespace { { O << (unsigned)MI->getOperand(OpNo).getImm(); } - + void printMemRegReg(const MachineInstr *MI, unsigned OpNo) { // When used as the base register, r0 reads constant zero rather than @@ -286,7 +286,7 @@ namespace { /// LinuxAsmPrinter - SPU assembly printer, customized for Linux struct VISIBILITY_HIDDEN LinuxAsmPrinter : public SPUAsmPrinter { - + DwarfWriter *DW; MachineModuleInfo *MMI; @@ -300,12 +300,12 @@ namespace { virtual const char *getPassName() const { return "STI CBEA SPU Assembly Printer"; } - + bool runOnMachineFunction(MachineFunction &F); bool doInitialization(Module &M); //! Dump globals, perform cleanup after function emission bool doFinalization(Module &M); - + void getAnalysisUsage(AnalysisUsage &AU) const { AU.setPreservesAll(); AU.addRequired(); @@ -365,7 +365,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) { } } O << Name; - + if (GV->hasExternalWeakLinkage()) ExtWeakSymbols.insert(GV); return; @@ -380,15 +380,15 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) { /// PrintAsmOperand - Print out an operand for an inline asm expression. /// bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, + unsigned AsmVariant, const char *ExtraCode) { // Does this asm operand have a single letter operand modifier? if (ExtraCode && ExtraCode[0]) { if (ExtraCode[1] != 0) return true; // Unknown modifier. - + switch (ExtraCode[0]) { default: return true; // Unknown modifier. - case 'L': // Write second word of DImode reference. + case 'L': // Write second word of DImode reference. // Verify that this operand has two consecutive registers. if (!MI->getOperand(OpNo).isReg() || OpNo+1 == MI->getNumOperands() || @@ -398,14 +398,14 @@ bool SPUAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, break; } } - + printOperand(MI, OpNo); return false; } bool SPUAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo, - unsigned AsmVariant, + unsigned AsmVariant, const char *ExtraCode) { if (ExtraCode && ExtraCode[0]) return true; // Unknown modifier. @@ -429,7 +429,7 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) { SetupMachineFunction(MF); O << "\n\n"; - + // Print out constants referenced by the function EmitConstantPool(MF.getConstantPool()); @@ -478,10 +478,10 @@ LinuxAsmPrinter::runOnMachineFunction(MachineFunction &MF) // Print out jump tables referenced by the function. EmitJumpTableInfo(MF.getJumpTableInfo(), MF); - + // Emit post-function debug information. DW->EndFunction(&MF); - + // We didn't modify anything. return false; } @@ -509,7 +509,7 @@ static void PrintUnmangledNameSafely(const Value *V, raw_ostream &OS) { /*! Emit a global variable according to its section, alignment, etc. - + \note This code was shamelessly copied from the PowerPC's assembly printer, which sort of screams for some kind of refactorization of common code. */ @@ -602,8 +602,6 @@ bool LinuxAsmPrinter::doFinalization(Module &M) { I != E; ++I) printModuleLevelGV(I); - // TODO - // Emit initial debug information. DW->EndModule(); diff --git a/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp b/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp index 63fbb6d3beea..ea767586b060 100644 --- a/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelDAGToDAG.cpp @@ -51,16 +51,6 @@ namespace { return isS10Constant(CN->getSExtValue()); } -#if 0 - //! SDNode predicate for sign-extended, 10-bit immediate values - bool - isI32IntS10Immediate(SDNode *N) - { - return (N->getOpcode() == ISD::Constant - && isI32IntS10Immediate(cast(N))); - } -#endif - //! ConstantSDNode predicate for i32 unsigned 10-bit immediate values bool isI32IntU10Immediate(ConstantSDNode *CN) @@ -79,8 +69,8 @@ namespace { bool isI16IntS10Immediate(SDNode *N) { - return (N->getOpcode() == ISD::Constant - && isI16IntS10Immediate(cast(N))); + ConstantSDNode *CN = dyn_cast(N); + return (CN != 0 && isI16IntS10Immediate(CN)); } //! ConstantSDNode predicate for i16 unsigned 10-bit immediate values @@ -230,7 +220,7 @@ public: SelectionDAGISel(tm), TM(tm), SPUtli(*tm.getTargetLowering()) - {} + { } virtual bool runOnFunction(Function &Fn) { // Make sure we re-emit a set of the global base reg if necessary @@ -259,32 +249,21 @@ public: SDNode *emitBuildVector(SDValue build_vec) { MVT vecVT = build_vec.getValueType(); SDNode *bvNode = build_vec.getNode(); - bool canBeSelected = false; // Check to see if this vector can be represented as a CellSPU immediate - // constant. - if (vecVT == MVT::v8i16) { - if (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0) { - canBeSelected = true; - } - } else if (vecVT == MVT::v4i32) { - if ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) - || (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) - || (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) - || (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0)) { - canBeSelected = true; - } - } else if (vecVT == MVT::v2i64) { - if ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) - || (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) - || (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)) { - canBeSelected = true; - } - } - - if (canBeSelected) { + // constant by invoking all of the instruction selection predicates: + if (((vecVT == MVT::v8i16) && + (SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i16).getNode() != 0)) || + ((vecVT == MVT::v4i32) && + ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || + (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || + (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i32).getNode() != 0) || + (SPU::get_v4i32_imm(bvNode, *CurDAG).getNode() != 0))) || + ((vecVT == MVT::v2i64) && + ((SPU::get_vec_i16imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || + (SPU::get_ILHUvec_imm(bvNode, *CurDAG, MVT::i64).getNode() != 0) || + (SPU::get_vec_u18imm(bvNode, *CurDAG, MVT::i64).getNode() != 0)))) return Select(build_vec); - } // No, need to emit a constant pool spill: std::vector CV; @@ -411,7 +390,7 @@ SPUDAGToDAGISel::InstructionSelect() } /*! - \arg Op The ISD instructio operand + \arg Op The ISD instruction operand \arg N The address to be tested \arg Base The base address \arg Index The base address index @@ -790,9 +769,10 @@ SPUDAGToDAGISel::Select(SDValue Op) { if ((Op0.getOpcode() == ISD::SRA || Op0.getOpcode() == ISD::SRL) && OpVT == MVT::i32 && Op0.getValueType() == MVT::i64) { - // Catch the (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 to - // take advantage of the fact that the upper 32 bits are in the - // i32 preferred slot and avoid all kinds of other shuffle gymnastics: + // Catch (truncate:i32 ([sra|srl]:i64 arg, c), where c >= 32 + // + // Take advantage of the fact that the upper 32 bits are in the + // i32 preferred slot and avoid shuffle gymnastics: ConstantSDNode *CN = dyn_cast(Op0.getOperand(1)); if (CN != 0) { unsigned shift_amt = unsigned(CN->getZExtValue()); @@ -806,7 +786,7 @@ SPUDAGToDAGISel::Select(SDValue Op) { // Take care of the additional shift, if present: SDValue shift = CurDAG->getTargetConstant(shift_amt, MVT::i32); unsigned Opc = SPU::ROTMAIr32_i32; - + if (Op0.getOpcode() == ISD::SRL) Opc = SPU::ROTMr32; @@ -1113,8 +1093,8 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) { // The degenerate case where the upper and lower bits in the splat are // identical: SDValue Op0 = i64vec.getOperand(0); - ReplaceUses(i64vec, Op0); + ReplaceUses(i64vec, Op0); return CurDAG->getTargetNode(SPU::ORi64_v2i64, OpVT, SDValue(emitBuildVector(Op0), 0)); } else if (i64vec.getOpcode() == SPUISD::SHUFB) { @@ -1139,7 +1119,7 @@ SDNode *SPUDAGToDAGISel::SelectI64Constant(SDValue& Op, MVT OpVT) { SDNode *rhsNode = (rhs.getNode()->isMachineOpcode() ? rhs.getNode() : emitBuildVector(rhs)); - + if (shufmask.getOpcode() == ISD::BIT_CONVERT) { ReplaceUses(shufmask, shufmask.getOperand(0)); shufmask = shufmask.getOperand(0); diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp index 3a399c139bd2..86b233c1ecd1 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp @@ -293,7 +293,7 @@ SPUTargetLowering::SPUTargetLowering(SPUTargetMachine &TM) // FDIV on SPU requires custom lowering setOperationAction(ISD::FDIV, MVT::f64, Expand); // to libcall - // SPU has [U|S]INT_TO_FP + // SPU has [U|S]INT_TO_FP for f32->i32, but not for f64->i32, f64->i64: setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); setOperationAction(ISD::SINT_TO_FP, MVT::i16, Promote); setOperationAction(ISD::SINT_TO_FP, MVT::i8, Promote); @@ -2281,6 +2281,7 @@ LowerByteImmed(SDValue Op, SelectionDAG &DAG) { DAG.getNode(ISD::BUILD_VECTOR, VT, tcVec, tcVecSize)); } } + // These operations (AND, OR, XOR) are legal, they just couldn't be custom // lowered. Return the operation, rather than a null SDValue. return Op; @@ -2417,7 +2418,7 @@ static SDValue LowerFP_TO_INT(SDValue Op, SelectionDAG &DAG, return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI); } - return SDValue(); + return Op; // return unmolested, legalized op } //! Lower ISD::SINT_TO_FP, ISD::UINT_TO_FP for i32 @@ -2443,7 +2444,7 @@ static SDValue LowerINT_TO_FP(SDValue Op, SelectionDAG &DAG, return ExpandLibCall(LC, Op, DAG, false, Dummy, TLI); } - return SDValue(); + return Op; // return unmolested, legalized } //! Lower ISD::SETCC diff --git a/llvm/lib/Target/CellSPU/SPUInstrFormats.td b/llvm/lib/Target/CellSPU/SPUInstrFormats.td index 710196467bc1..21bc275209c6 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrFormats.td +++ b/llvm/lib/Target/CellSPU/SPUInstrFormats.td @@ -290,6 +290,9 @@ class RR_Int_v4i32 opcode, string opc, InstrItinClass itin, class Pseudo pattern> : SPUInstr { + let OutOperandList = OOL; + let InOperandList = IOL; + let AsmString = asmstr; let Pattern = pattern; let Inst{31-0} = 0; } diff --git a/llvm/lib/Target/CellSPU/SPUInstrInfo.td b/llvm/lib/Target/CellSPU/SPUInstrInfo.td index 05b31bbc21eb..250a57dd128d 100644 --- a/llvm/lib/Target/CellSPU/SPUInstrInfo.td +++ b/llvm/lib/Target/CellSPU/SPUInstrInfo.td @@ -34,10 +34,9 @@ let hasCtrlDep = 1, Defs = [R1], Uses = [R1] in { // DWARF debugging Pseudo Instructions //===----------------------------------------------------------------------===// -def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), - "${:comment} .loc $file, $line, $col", - [(dwarf_loc (i32 imm:$line), (i32 imm:$col), - (i32 imm:$file))]>; +def DWARF_LOC : Pseudo<(outs), (ins i32imm:$line, i32imm:$col, i32imm:$file), + ".loc $file, $line, $col", + [(dwarf_loc (i32 imm:$line), (i32 imm:$col), (i32 imm:$file))]>; //===----------------------------------------------------------------------===// // Loads: diff --git a/llvm/lib/Target/CellSPU/SPUTargetAsmInfo.cpp b/llvm/lib/Target/CellSPU/SPUTargetAsmInfo.cpp index 72752555e499..ff88ed810716 100644 --- a/llvm/lib/Target/CellSPU/SPUTargetAsmInfo.cpp +++ b/llvm/lib/Target/CellSPU/SPUTargetAsmInfo.cpp @@ -15,8 +15,10 @@ #include "SPUTargetMachine.h" #include "llvm/Function.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Dwarf.h" using namespace llvm; +using namespace llvm::dwarf; SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) : SPUTargetAsmInfo(TM) { @@ -27,12 +29,34 @@ SPULinuxTargetAsmInfo::SPULinuxTargetAsmInfo(const SPUTargetMachine &TM) : // This corresponds to what the gcc SPU compiler emits, for consistency. CStringSection = ".rodata.str"; + // Has leb128, .loc and .file + HasLEB128 = true; + HasDotLocAndDotFile = true; + // BSS section needs to be emitted as ".section" BSSSection = "\t.section\t.bss"; BSSSection_ = getUnnamedSection("\t.section\t.bss", SectionFlags::Writeable | SectionFlags::BSS, true); + SupportsDebugInformation = true; + NeedsSet = true; + SupportsMacInfoSection = false; + DwarfAbbrevSection = "\t.section .debug_abbrev,\"\",@progbits"; + DwarfInfoSection = "\t.section .debug_info,\"\",@progbits"; + DwarfLineSection = "\t.section .debug_line,\"\",@progbits"; + DwarfFrameSection = "\t.section .debug_frame,\"\",@progbits"; + DwarfPubNamesSection = "\t.section .debug_pubnames,\"\",@progbits"; + DwarfPubTypesSection = "\t.section .debug_pubtypes,\"\",progbits"; + DwarfStrSection = "\t.section .debug_str,\"MS\",@progbits,1"; + DwarfLocSection = "\t.section .debug_loc,\"\",@progbits"; + DwarfARangesSection = "\t.section .debug_aranges,\"\",@progbits"; + DwarfRangesSection = "\t.section .debug_ranges,\"\",@progbits"; + DwarfMacInfoSection = "\t.section .debug_macinfo,\"\",progbits"; + + // Exception handling is not supported on CellSPU (think about it: you only + // have 256K for code+data. Would you support exception handling?) + SupportsExceptionHandling = false; } /// PreferredEHDataFormat - This hook allows the target to select data -- GitLab From 9240b3eccb9c2500f596fb491fd848d9c83e1423 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 26 Jan 2009 22:36:52 +0000 Subject: [PATCH 246/682] rename getSpelledCharacterAt to getSpellingOfSingleCharacterNumericConstant, optimize it to use the LiteralData when possible. llvm-svn: 63060 --- clang/clang.xcodeproj/project.pbxproj | 2 +- clang/include/clang/Lex/Preprocessor.h | 20 +++++++++++++++----- clang/lib/Sema/SemaExpr.cpp | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index 05f26ae2d97d..042e0e3df88f 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -382,7 +382,7 @@ 35A057E10EAE2D950069249F /* SVals.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SVals.cpp; path = lib/Analysis/SVals.cpp; sourceTree = ""; }; 35A057E60EAE2DDD0069249F /* CacheTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CacheTokens.cpp; path = Driver/CacheTokens.cpp; sourceTree = ""; }; 35A2B8610CF8FFA300E6C317 /* SemaUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = SemaUtil.h; path = lib/Sema/SemaUtil.h; sourceTree = ""; tabWidth = 2; }; - 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDebugInfo.cpp; path = lib/CodeGen/CGDebugInfo.cpp; sourceTree = ""; tabWidth = 2; }; + 35A3E7000DD3874400757F74 /* CGDebugInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CGDebugInfo.cpp; path = lib/CodeGen/CGDebugInfo.cpp; sourceTree = ""; tabWidth = 2; wrapsLines = 1; }; 35A3E7010DD3874400757F74 /* CGDebugInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CGDebugInfo.h; path = lib/CodeGen/CGDebugInfo.h; sourceTree = ""; tabWidth = 2; }; 35A8FCF60D9B4ADD001C2F97 /* ProgramPoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProgramPoint.h; path = clang/Analysis/ProgramPoint.h; sourceTree = ""; }; 35A8FCF70D9B4ADD001C2F97 /* PathDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PathDiagnostic.h; path = clang/Analysis/PathDiagnostic.h; sourceTree = ""; }; diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index f6391d9781a2..095c1db1de3c 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -451,16 +451,26 @@ public: /// if an internal buffer is returned. unsigned getSpelling(const Token &Tok, const char *&Buffer) const; - /// getSpelledCharacterAt - Return a pointer to the start of the specified - /// location in the appropriate MemoryBuffer. - char getSpelledCharacterAt(SourceLocation SL) const { + /// getSpellingOfSingleCharacterNumericConstant - Tok is a numeric constant + /// with length 1, return the character. + char getSpellingOfSingleCharacterNumericConstant(const Token &Tok) const { + assert(Tok.is(tok::numeric_constant) && + Tok.getLength() == 1 && "Called on unsupported token"); + assert(!Tok.needsCleaning() && "Token can't need cleaning with length 1"); + + // If the token is carrying a literal data pointer, just use it. + if (const char *D = Tok.getLiteralData()) + return *D; + if (PTH) { const char *Data; - if (PTH->getSpelling(SL, Data)) + if (PTH->getSpelling(Tok.getLocation(), Data)) return *Data; } - return *SourceMgr.getCharacterData(SL); + // Otherwise, fall back on getCharacterData, which is slower, but always + // works. + return *SourceMgr.getCharacterData(Tok.getLocation()); } /// CreateString - Plop the specified string into a scratch buffer and set the diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9b91ec6ee5f4..9e80946b43d2 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -869,7 +869,7 @@ Action::OwningExprResult Sema::ActOnNumericConstant(const Token &Tok) { // Fast path for a single digit (which is quite common). A single digit // cannot have a trigraph, escaped newline, radix prefix, or type suffix. if (Tok.getLength() == 1) { - const char Val = PP.getSpelledCharacterAt(Tok.getLocation()); + const char Val = PP.getSpellingOfSingleCharacterNumericConstant(Tok); unsigned IntSize = Context.Target.getIntWidth(); return Owned(new (Context) IntegerLiteral(llvm::APInt(IntSize, Val-'0'), Context.IntTy, Tok.getLocation())); -- GitLab From f829825d04b3029a62b470058a12d1186c6eefea Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 26 Jan 2009 22:44:13 +0000 Subject: [PATCH 247/682] Some micro-optimizations for DISABLE_SMART_POINTERS: - When it's safe, ActionResult uses the low bit of the pointer for the "invalid" flag rather than a separate "bool" value. This keeps GCC from generating some truly awful code, for a > 3x speedup in the result-passing microbenchmark. - When DISABLE_SMART_POINTERS is defined, store an ActionResult within ASTOwningResult rather than an ASTOwningPtr. Brings the performance benefits of the above to smart pointers with DISABLE_SMART_POINTERS defined. Sadly, these micro-benchmark performance improvements don't seem to make much of a difference on Cocoa.h right now. However, they're harmless and might help with future optimizations. llvm-svn: 63061 --- clang/include/clang/Parse/Action.h | 8 ++ clang/include/clang/Parse/Ownership.h | 147 ++++++++++++++++++++++---- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseDeclCXX.cpp | 8 +- clang/lib/Parse/ParseExprCXX.cpp | 6 +- clang/lib/Sema/Sema.h | 4 +- clang/lib/Sema/SemaExprObjC.cpp | 4 +- 7 files changed, 144 insertions(+), 35 deletions(-) diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 0f0d88acc84e..02948bbbcf70 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -38,6 +38,14 @@ namespace clang { class Preprocessor; class Token; + // We can re-use the low bit of expression, statement, base, and + // member-initializer pointers for the "invalid" flag of + // ActionResult. + template<> struct IsResultPtrLowBitFree<0> { static const bool value = true; }; + template<> struct IsResultPtrLowBitFree<1> { static const bool value = true; }; + template<> struct IsResultPtrLowBitFree<3> { static const bool value = true; }; + template<> struct IsResultPtrLowBitFree<4> { static const bool value = true; }; + /// Action - As the parser reads the input file and recognizes the productions /// of the grammar, it invokes methods on this class to turn the parsed input /// into something useful: e.g. a parse tree. diff --git a/clang/include/clang/Parse/Ownership.h b/clang/include/clang/Parse/Ownership.h index 2144481c3d1d..704d6b5f1e9a 100644 --- a/clang/include/clang/Parse/Ownership.h +++ b/clang/include/clang/Parse/Ownership.h @@ -110,6 +110,14 @@ namespace clang // Basic class DiagnosticBuilder; + // Determines whether the low bit of the result pointer for the + // given UID is always zero. If so, ActionResult will use that bit + // for it's "invalid" flag. + template + struct IsResultPtrLowBitFree { + static const bool value = false; + }; + /// ActionBase - A small part split from Action because of the horrible /// definition order dependencies between Action and the smart pointers. class ActionBase { @@ -127,19 +135,65 @@ namespace clang /// ActionResult - This structure is used while parsing/acting on /// expressions, stmts, etc. It encapsulates both the object returned by /// the action, plus a sense of whether or not it is valid. - template - struct ActionResult { + /// When CompressInvalid is true, the "invalid" flag will be + /// stored in the low bit of the Val pointer. + template::value> + class ActionResult { void *Val; - bool isInvalid; + bool Invalid; - ActionResult(bool Invalid = false) : Val(0), isInvalid(Invalid) {} + public: + ActionResult(bool Invalid = false) : Val(0), Invalid(Invalid) {} template - ActionResult(ActualExprTy *val) : Val(val), isInvalid(false) {} - ActionResult(const DiagnosticBuilder &) : Val(0), isInvalid(true) {} + ActionResult(ActualExprTy *val) : Val(val), Invalid(false) {} + ActionResult(const DiagnosticBuilder &) : Val(0), Invalid(true) {} + + void *get() const { return Val; } + void set(void *V) { Val = V; } + bool isInvalid() const { return Invalid; } const ActionResult &operator=(void *RHS) { Val = RHS; - isInvalid = false; + Invalid = false; + return *this; + } + }; + + // This ActionResult partial specialization places the "invalid" + // flag into the low bit of the pointer. + template + class ActionResult { + // A pointer whose low bit is 1 if this result is invalid, 0 + // otherwise. + uintptr_t PtrWithInvalid; + + public: + ActionResult(bool Invalid = false) + : PtrWithInvalid(static_cast(Invalid)) { } + + template + ActionResult(ActualExprTy *val) + : PtrWithInvalid(reinterpret_cast(val)) { + assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); + } + + ActionResult(const DiagnosticBuilder &) : PtrWithInvalid(0x01) { } + + void *get() const { + return reinterpret_cast(PtrWithInvalid & ~0x01); + } + + void set(void *V) { + PtrWithInvalid = reinterpret_cast(V); + assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); + } + + bool isInvalid() const { return PtrWithInvalid & 0x01; } + + const ActionResult &operator=(void *RHS) { + PtrWithInvalid = reinterpret_cast(RHS); + assert((PtrWithInvalid & 0x01) == 0 && "Badly aligned pointer"); return *this; } }; @@ -167,7 +221,7 @@ namespace clang static const unsigned UID = 1; }; template <> struct DestroyerToUID<&ActionBase::DeleteTemplateArg> { - static const unsigned UID = 1; + static const unsigned UID = 5; // FIXME }; /// ASTOwningResult - A moveable smart pointer for AST nodes that also @@ -311,18 +365,22 @@ namespace clang #endif }; + // Important: There are two different implementations of + // ASTOwningResult below, depending on whether + // DISABLE_SMART_POINTERS is defined. If you make changes that + // affect the interface, be sure to compile and test both ways! + +#if !defined(DISABLE_SMART_POINTERS) template class ASTOwningResult { ASTOwningPtr Ptr; bool Invalid; -#if !defined(DISABLE_SMART_POINTERS) friend class moving::ASTResultMover; ASTOwningResult(ASTOwningResult&); // DO NOT IMPLEMENT ASTOwningResult& operator =(ASTOwningResult&); // DO NOT IMPLEMENT -#endif public: typedef ActionBase::ActionResult::UID> DumbResult; @@ -332,8 +390,7 @@ namespace clang ASTOwningResult(ActionBase &actions, void *node) : Ptr(actions, node), Invalid(false) {} ASTOwningResult(ActionBase &actions, const DumbResult &res) - : Ptr(actions, res.Val), Invalid(res.isInvalid) {} -#if !defined(DISABLE_SMART_POINTERS) + : Ptr(actions, res.get()), Invalid(res.isInvalid()) {} /// Move from another owning result ASTOwningResult(moving::ASTResultMover mover) : Ptr(moving::ASTPtrMover(mover->Ptr)), @@ -341,13 +398,7 @@ namespace clang /// Move from an owning pointer ASTOwningResult(moving::ASTPtrMover mover) : Ptr(mover), Invalid(false) {} -#else - // Normal copying semantics are defined implicitly. - // The fake movers need this: - explicit ASTOwningResult(void *ptr) : Ptr(ptr), Invalid(false) {} -#endif -#if !defined(DISABLE_SMART_POINTERS) /// Move assignment from another owning result ASTOwningResult & operator =(moving::ASTResultMover mover) { Ptr = move(mover->Ptr); @@ -361,7 +412,6 @@ namespace clang Invalid = false; return *this; } -#endif /// Assignment from a raw pointer. Takes ownership - beware! ASTOwningResult & operator =(void *raw) @@ -373,8 +423,8 @@ namespace clang /// Assignment from an ActionResult. Takes ownership - beware! ASTOwningResult & operator =(const DumbResult &res) { - Ptr = res.Val; - Invalid = res.isInvalid; + Ptr = res.get(); + Invalid = res.isInvalid(); return *this; } @@ -404,7 +454,6 @@ namespace clang return Ptr.take(); } -#if !defined(DISABLE_SMART_POINTERS) /// Move hook operator moving::ASTResultMover() { return moving::ASTResultMover(*this); @@ -414,8 +463,60 @@ namespace clang moving::ASTPtrMover ptr_move() { return moving::ASTPtrMover(Ptr); } -#endif }; +#else + template + class ASTOwningResult + { + public: + typedef ActionBase::ActionResult::UID> DumbResult; + + private: + DumbResult Result; + + public: + explicit ASTOwningResult(ActionBase &actions, bool invalid = false) + : Result(invalid) { } + ASTOwningResult(ActionBase &actions, void *node) : Result(node) { } + ASTOwningResult(ActionBase &actions, const DumbResult &res) : Result(res) { } + // Normal copying semantics are defined implicitly. + // The fake movers need this: + explicit ASTOwningResult(void *ptr) : Result(ptr) { } + + /// Assignment from a raw pointer. Takes ownership - beware! + ASTOwningResult & operator =(void *raw) + { + Result = raw; + return *this; + } + + /// Assignment from an ActionResult. Takes ownership - beware! + ASTOwningResult & operator =(const DumbResult &res) { + Result = res; + return *this; + } + + /// Access to the raw pointer. + void * get() const { return Result.get(); } + + bool isInvalid() const { return Result.isInvalid(); } + + /// Does this point to a usable AST node? To be usable, the node must be + /// valid and non-null. + bool isUsable() const { return !Result.isInvalid() && get(); } + + /// Take outside ownership of the raw pointer. + void * take() { + return Result.get(); + } + + /// Alias for interface familiarity with unique_ptr. + void * release() { return take(); } + + /// Pass ownership to a classical ActionResult. + DumbResult result() { return Result; } + }; +#endif template class ASTMultiPtr diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 0ac9e0898229..5a8f22348809 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -37,7 +37,7 @@ Parser::TypeTy *Parser::ParseTypeName() { Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); ParseDeclarator(DeclaratorInfo); - return Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; + return Actions.ActOnTypeName(CurScope, DeclaratorInfo).get(); } /// ParseAttributes - Parse a non-empty attributes list. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 26787aec1231..1041410f2a40 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -393,13 +393,13 @@ void Parser::ParseBaseClause(DeclTy *ClassDecl) while (true) { // Parse a base-specifier. BaseResult Result = ParseBaseSpecifier(ClassDecl); - if (Result.isInvalid) { + if (Result.isInvalid()) { // Skip the rest of this base specifier, up until the comma or // opening brace. SkipUntil(tok::comma, tok::l_brace, true, true); } else { // Add this to our array of base specifiers. - BaseInfo.push_back(Result.Val); + BaseInfo.push_back(Result.get()); } // If the next token is a comma, consume it and keep reading @@ -835,8 +835,8 @@ void Parser::ParseConstructorInitializer(DeclTy *ConstructorDecl) { do { MemInitResult MemInit = ParseMemInitializer(ConstructorDecl); - if (!MemInit.isInvalid) - MemInitializers.push_back(MemInit.Val); + if (!MemInit.isInvalid()) + MemInitializers.push_back(MemInit.get()); if (Tok.is(tok::comma)) ConsumeToken(); diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 04e53a94efca..945ff245fbee 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -333,7 +333,7 @@ Parser::OwningExprResult Parser::ParseCXXThis() { Parser::OwningExprResult Parser::ParseCXXTypeConstructExpression(const DeclSpec &DS) { Declarator DeclaratorInfo(DS, Declarator::TypeNameContext); - TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).Val; + TypeTy *TypeRep = Actions.ActOnTypeName(CurScope, DeclaratorInfo).get(); assert(Tok.is(tok::l_paren) && "Expected '('!"); SourceLocation LParenLoc = ConsumeParen(); @@ -629,10 +629,10 @@ Parser::TypeTy *Parser::ParseConversionFunctionId() { // Finish up the type. Action::TypeResult Result = Actions.ActOnTypeName(CurScope, D); - if (Result.isInvalid) + if (Result.isInvalid()) return 0; else - return Result.Val; + return Result.get(); } /// ParseCXXNewExpression - Parse a C++ new-expression. New is used to allocate diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 51d2e38c938b..0adea514d0c4 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -252,9 +252,9 @@ public: OwningExprResult Owned(Expr* E) { return OwningExprResult(*this, E); } OwningExprResult Owned(ExprResult R) { - if (R.isInvalid) + if (R.isInvalid()) return ExprError(); - return OwningExprResult(*this, R.Val); + return OwningExprResult(*this, R.get()); } OwningStmtResult Owned(Stmt* S) { return OwningStmtResult(*this, S); } diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 8f4d67717966..607e640b32c9 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -202,7 +202,7 @@ Sema::ExprResult Sema::ActOnClassMessage( superTy = Context.getPointerType(superTy); ExprResult ReceiverExpr = new ObjCSuperExpr(SourceLocation(), superTy); // We are really in an instance method, redirect. - return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac, + return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac, rbrac, Args, NumArgs); } // We are sending a message to 'super' within a class method. Do nothing, @@ -216,7 +216,7 @@ Sema::ExprResult Sema::ActOnClassMessage( ExprResult ReceiverExpr = new DeclRefExpr(VD, VD->getType(), receiverLoc); // We are really in an instance method, redirect. - return ActOnInstanceMessage(ReceiverExpr.Val, Sel, lbrac, rbrac, + return ActOnInstanceMessage(ReceiverExpr.get(), Sel, lbrac, rbrac, Args, NumArgs); } return Diag(receiverLoc, diag::err_undeclared_var_use) << receiverName; -- GitLab From 2612e149ef0ffcd73eee51e1e70671af4b5a0dd6 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 26 Jan 2009 22:58:07 +0000 Subject: [PATCH 248/682] Build method-description-list for category meta-data as well (for nonfragile-abi). llvm-svn: 63062 --- clang/lib/CodeGen/CGObjCMac.cpp | 34 ++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index b70ef5e7c325..f1460bd01935 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3171,6 +3171,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( CLASS_RO_GV->setSection(".section __DATA,__data,regular,no_dead_strip"); UsedGlobals.push_back(CLASS_RO_GV); return CLASS_RO_GV; + } /// BuildClassMetaData - This routine defines that to-level meta-data @@ -3381,7 +3382,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) { const ObjCInterfaceDecl *Interface = OCD->getClassInterface(); - std::string ExtCatName("\01l_OBJC_$_CATEGORY_" + Interface->getNameAsString()+ + const char *Prefix = "\01l_OBJC_$_CATEGORY_"; + std::string ExtCatName(Prefix + Interface->getNameAsString()+ "_$_" + OCD->getNameAsString()); std::string ExtClassName("\01_OBJC_CLASS_$_" + Interface->getNameAsString()); @@ -3399,8 +3401,34 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) &CGM.getModule()); UsedGlobals.push_back(ClassGV); Values[1] = ClassGV; - Values[2] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); - Values[3] = llvm::Constant::getNullValue(ObjCTypes.MethodListnfABIPtrTy); + std::vector Methods; + std::string MethodListName(Prefix); + MethodListName += "INSTANCE_METHODS_" + Interface->getNameAsString() + + "_$_" + OCD->getNameAsString(); + + for (ObjCCategoryImplDecl::instmeth_iterator i = OCD->instmeth_begin(), + e = OCD->instmeth_end(); i != e; ++i) { + // Instance methods should always be defined. + Methods.push_back(GetMethodConstant(*i)); + } + + Values[2] = EmitMethodList(MethodListName, + ".section __DATA,__data,regular,no_dead_strip", + Methods); + + MethodListName = Prefix; + MethodListName += "CLASS_METHODS_" + Interface->getNameAsString() + "_$_" + + OCD->getNameAsString(); + Methods.clear(); + for (ObjCCategoryImplDecl::classmeth_iterator i = OCD->classmeth_begin(), + e = OCD->classmeth_end(); i != e; ++i) { + // Class methods should always be defined. + Methods.push_back(GetMethodConstant(*i)); + } + + Values[3] = EmitMethodList(MethodListName, + ".section __DATA,__data,regular,no_dead_strip", + Methods); Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); -- GitLab From 03490f0ce1cf10a55a34e18af810995f4f013781 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 26 Jan 2009 23:22:19 +0000 Subject: [PATCH 249/682] Testcase for 6522054. llvm-svn: 63067 --- llvm/test/FrontendObjC/2009-01-26-WriteBarrier-2.m | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 llvm/test/FrontendObjC/2009-01-26-WriteBarrier-2.m diff --git a/llvm/test/FrontendObjC/2009-01-26-WriteBarrier-2.m b/llvm/test/FrontendObjC/2009-01-26-WriteBarrier-2.m new file mode 100644 index 000000000000..32833a81e169 --- /dev/null +++ b/llvm/test/FrontendObjC/2009-01-26-WriteBarrier-2.m @@ -0,0 +1,14 @@ +// RUN: %llvmgcc -x objective-c -S %s -fobjc-gc -o - | grep objc_assign_strongCast +// rdar://5541393 + +typedef struct { + void (^ivarBlock)(void); +} StructWithBlock_t; + +int main(char *argc, char *argv[]) { + StructWithBlock_t *swbp = (StructWithBlock_t *)malloc(sizeof(StructWithBlock_t*)); + __block int i = 10; + // assigning a Block into an struct slot should elicit a write-barrier under GC + swbp->ivarBlock = ^ { ++i; }; + return 0; +} -- GitLab From fd346a3644816eb3513bf9e46162a21212d010b7 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 23:27:52 +0000 Subject: [PATCH 250/682] Pull EmitReturnBlock out of FinishFunction and catch unified return case correctly. llvm-svn: 63068 --- clang/lib/CodeGen/CodeGenFunction.cpp | 48 +++++++++++++++++++++++---- clang/lib/CodeGen/CodeGenFunction.h | 4 +++ 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index b509843daa65..5d34f65fc14d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -70,6 +70,45 @@ bool CodeGenFunction::hasAggregateLLVMType(QualType T) { !T->isBlockPointerType(); } +void CodeGenFunction::EmitReturnBlock() { + // For cleanliness, we try to avoid emitting the return block for + // simple cases. + llvm::BasicBlock *CurBB = Builder.GetInsertBlock(); + + if (CurBB) { + assert(!CurBB->getTerminator() && "Unexpected terminated block."); + + // We have a valid insert point, reuse it if there are no explicit + // jumps to the return block. + if (ReturnBlock->use_empty()) + delete ReturnBlock; + else + EmitBlock(ReturnBlock); + return; + } + + // Otherwise, if the return block is the target of a single direct + // branch then we can just put the code in that block instead. This + // cleans up functions which started with a unified return block. + if (ReturnBlock->hasOneUse()) { + llvm::BranchInst *BI = + dyn_cast(*ReturnBlock->use_begin()); + if (BI && BI->isUnconditional() && BI->getSuccessor(0) == ReturnBlock) { + // Reset insertion point and delete the branch. + Builder.SetInsertPoint(BI->getParent()); + BI->eraseFromParent(); + delete ReturnBlock; + return; + } + } + + // FIXME: We are at an unreachable point, there is no reason to emit + // the block unless it has uses. However, we still need a place to + // put the debug region.end for now. + + EmitBlock(ReturnBlock); +} + void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { // Finish emission of indirect switches. EmitIndirectSwitches(); @@ -77,13 +116,8 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { assert(BreakContinueStack.empty() && "mismatched push/pop in break/continue stack!"); - // Emit function epilog (to return). For cleanliness, skip emission - // if we know it is safe (when it is unused and the current block is - // unterminated). - if (!ReturnBlock->use_empty() || - !Builder.GetInsertBlock() || - Builder.GetInsertBlock()->getTerminator()) - EmitBlock(ReturnBlock); + // Emit function epilog (to return). + EmitReturnBlock(); // Emit debug descriptor for function end. if (CGDebugInfo *DI = CGM.getDebugInfo()) { diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index f469b970dc37..e736fe5e167d 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -206,6 +206,10 @@ public: const FunctionArgList &Args, SourceLocation StartLoc); + /// EmitReturnBlock - Emit the unified return block, trying to avoid + /// its emission when possible. + void EmitReturnBlock(); + /// FinishFunction - Complete IR generation of the current /// function. It is legal to call this function even if there is no /// current insertion point. -- GitLab From 7a88d1fcc4f3aeb9d705ac30611280252b1d9124 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 26 Jan 2009 23:43:02 +0000 Subject: [PATCH 251/682] Fix definition of __builtin_ia32_vec_set_v2di and de-XFAIL builtins-x86.c. llvm-svn: 63069 --- clang/include/clang/AST/X86Builtins.def | 2 +- clang/test/CodeGen/builtins-x86.c | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/clang/include/clang/AST/X86Builtins.def b/clang/include/clang/AST/X86Builtins.def index 9d5770adc37c..73a4d1e0d021 100644 --- a/clang/include/clang/AST/X86Builtins.def +++ b/clang/include/clang/AST/X86Builtins.def @@ -420,7 +420,7 @@ BUILTIN(__builtin_ia32_vec_set_v8hi, "V8sV8ssi", "") BUILTIN(__builtin_ia32_vec_set_v4hi, "V4sV4ssi", "") BUILTIN(__builtin_ia32_vec_set_v16qi, "V16cV16cii", "") BUILTIN(__builtin_ia32_vec_set_v4si, "V4iV4iii", "") -BUILTIN(__builtin_ia32_vec_set_v2di, "V2LLiV2LLiLLi", "") +BUILTIN(__builtin_ia32_vec_set_v2di, "V2LLiV2LLiLLii", "") BUILTIN(__builtin_ia32_insertps128, "V4fV4fV4fi", "") BUILTIN(__builtin_ia32_movqv4si, "V4iV4i", "") diff --git a/clang/test/CodeGen/builtins-x86.c b/clang/test/CodeGen/builtins-x86.c index 0b039aa9705e..5e1aea4c6205 100644 --- a/clang/test/CodeGen/builtins-x86.c +++ b/clang/test/CodeGen/builtins-x86.c @@ -1,6 +1,5 @@ // RUN: clang -DUSE_64 -triple x86_64-unknown-unknown -emit-llvm -o %t %s && -// RUN: clang -DUSE_ALL -triple x86_64-unknown-unknown -emit-llvm -o %t %s -// XFAIL +// RUN: clang -DUSE_ALL -triple x86_64-unknown-unknown -fsyntax-only -o %t %s #ifdef USE_ALL #define USE_3DNOW @@ -523,13 +522,13 @@ void f0() { tmp_V2LLi = __builtin_ia32_pmuldq128(tmp_V4i, tmp_V4i); tmp_V4i = __builtin_ia32_pmulld128(tmp_V4i, tmp_V4i); tmp_V4f = __builtin_ia32_roundps(tmp_V4f, imm_i_0_16); - tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16); - tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16); + // tmp_V4f = __builtin_ia32_roundss(tmp_V4f, tmp_V4f, imm_i_0_16); + // tmp_V2d = __builtin_ia32_roundsd(tmp_V2d, tmp_V2d, imm_i_0_16); tmp_V2d = __builtin_ia32_roundpd(tmp_V2d, imm_i_0_16); tmp_V16c = __builtin_ia32_vec_set_v16qi(tmp_V16c, tmp_i, tmp_i); tmp_V4i = __builtin_ia32_vec_set_v4si(tmp_V4i, tmp_i, tmp_i); tmp_V4f = __builtin_ia32_insertps128(tmp_V4f, tmp_V4f, tmp_i); - tmp_V2LLi = __builtin_ia32_vec_set_v2di(tmp_V2LLi, tmp_LLi); + tmp_V2LLi = __builtin_ia32_vec_set_v2di(tmp_V2LLi, tmp_LLi, tmp_i); #endif } -- GitLab From b8c79bdc3124d8cf382c63545942d6c50d14e2d9 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 26 Jan 2009 23:47:30 +0000 Subject: [PATCH 252/682] No need to keep size of DebugLocations vector separately. llvm-svn: 63070 --- llvm/include/llvm/CodeGen/DebugLoc.h | 5 +---- llvm/lib/CodeGen/MachineFunction.cpp | 5 +++-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DebugLoc.h b/llvm/include/llvm/CodeGen/DebugLoc.h index b6097afe306d..baf6583a8ba7 100644 --- a/llvm/include/llvm/CodeGen/DebugLoc.h +++ b/llvm/include/llvm/CodeGen/DebugLoc.h @@ -69,9 +69,6 @@ namespace llvm { /// DebugLocTracker - This class tracks debug location information. /// struct DebugLocTracker { - // NumDebugLocations - Size of the DebugLocations vector. - unsigned NumDebugLocations; - // DebugLocations - A vector of unique DebugLocTuple's. // std::vector DebugLocations; @@ -80,7 +77,7 @@ namespace llvm { // DebugLocations vector. DebugIdMapType DebugIdMap; - DebugLocTracker() : NumDebugLocations(0) {} + DebugLocTracker() {} ~DebugLocTracker() { DebugLocations.clear(); diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index c1ab9afe9f68..abd84ecbd5c3 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -388,9 +388,10 @@ unsigned MachineFunction::lookUpDebugLocId(unsigned Src, unsigned Line, if (II != DebugLocInfo.DebugIdMap.end()) return II->second; // Add a new tuple. + unsigned Id = DebugLocInfo.DebugLocations.size(); DebugLocInfo.DebugLocations.push_back(Tuple); - DebugLocInfo.DebugIdMap[Tuple] = DebugLocInfo.NumDebugLocations; - return DebugLocInfo.NumDebugLocations++; + DebugLocInfo.DebugIdMap[Tuple] = Id; + return Id; } //===----------------------------------------------------------------------===// -- GitLab From d0e8e85afc43f36280b0b7e860dec808c413b724 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 26 Jan 2009 23:49:05 +0000 Subject: [PATCH 253/682] Added a FIXME. llvm-svn: 63071 --- clang/lib/CodeGen/CGObjCMac.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index f1460bd01935..9365535079a2 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -2324,6 +2324,8 @@ void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, NameOut += '['; assert (CD && "Missing container decl in GetNameForMethod"); NameOut += CD->getNameAsString(); + // FIXME. For a method in a category, (CAT_NAME) is inserted here. + // Right now! there is not enough info. to do this. NameOut += ' '; NameOut += D->getSelector().getAsString(); NameOut += ']'; -- GitLab From 8d178f435720f7180a7594ddd10109d61ee392e5 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 27 Jan 2009 00:01:05 +0000 Subject: [PATCH 254/682] PTH: Use Token::setLiteralData() to directly store a pointer to cached spelling data in the PTH file. This removes a ton of code for looking up spellings using sourcelocations in the PTH file. This simplifies both PTH-generation and reading. Performance impact for -fsyntax-only on Cocoa.h (with Cocoa.h in the PTH file): - PTH generation time improves by 5% - PTH reading improves by 0.3%. llvm-svn: 63072 --- clang/Driver/CacheTokens.cpp | 123 +++++++----------- clang/include/clang/Lex/PTHLexer.h | 17 +-- clang/include/clang/Lex/PTHManager.h | 48 ++----- clang/include/clang/Lex/Preprocessor.h | 6 - clang/lib/Lex/PTHLexer.cpp | 168 ++++--------------------- clang/lib/Lex/Preprocessor.cpp | 29 +---- 6 files changed, 81 insertions(+), 310 deletions(-) diff --git a/clang/Driver/CacheTokens.cpp b/clang/Driver/CacheTokens.cpp index aef59cbe352b..5409a64e8bcd 100644 --- a/clang/Driver/CacheTokens.cpp +++ b/clang/Driver/CacheTokens.cpp @@ -30,33 +30,34 @@ using namespace clang; typedef uint32_t Offset; -typedef std::vector*> > - SpellMapTy; - namespace { class VISIBILITY_HIDDEN PCHEntry { Offset TokenData, PPCondData; - union { Offset SpellingOff; SpellMapTy* Spellings; }; public: PCHEntry() {} - PCHEntry(Offset td, Offset ppcd, SpellMapTy* sp) - : TokenData(td), PPCondData(ppcd), Spellings(sp) {} + PCHEntry(Offset td, Offset ppcd) + : TokenData(td), PPCondData(ppcd) {} - Offset getTokenOffset() const { return TokenData; } + Offset getTokenOffset() const { return TokenData; } Offset getPPCondTableOffset() const { return PPCondData; } - SpellMapTy& getSpellings() const { return *Spellings; } - - void setSpellingTableOffset(Offset off) { SpellingOff = off; } - Offset getSpellingTableOffset() const { return SpellingOff; } +}; +class OffsetOpt { + bool valid; + Offset off; +public: + OffsetOpt() : valid(false) {} + bool hasOffset() const { return valid; } + Offset getOffset() const { assert(valid); return off; } + void setOffset(Offset o) { off = o; valid = true; } }; } // end anonymous namespace typedef llvm::DenseMap PCHMap; typedef llvm::DenseMap IDMap; -typedef llvm::StringMap CachedStrsTy; +typedef llvm::StringMap CachedStrsTy; namespace { class VISIBILITY_HIDDEN PTHWriter { @@ -66,8 +67,8 @@ class VISIBILITY_HIDDEN PTHWriter { uint32_t idcount; PCHMap PM; CachedStrsTy CachedStrs; - - SpellMapTy* CurSpellMap; + Offset CurStrOffset; + std::vector*> StrEntries; //// Get the persistent id for the given IdentifierInfo*. uint32_t ResolveID(const IdentifierInfo* II); @@ -106,11 +107,11 @@ class VISIBILITY_HIDDEN PTHWriter { std::pair > EmitIdentifierTable(); Offset EmitFileTable(); PCHEntry LexTokens(Lexer& L); - void EmitCachedSpellings(); + Offset EmitCachedSpellings(); public: PTHWriter(llvm::raw_fd_ostream& out, Preprocessor& pp) - : Out(out), PP(pp), idcount(0) {} + : Out(out), PP(pp), idcount(0), CurStrOffset(0) {} void GeneratePTH(); }; @@ -132,14 +133,10 @@ uint32_t PTHWriter::ResolveID(const IdentifierInfo* II) { } void PTHWriter::EmitToken(const Token& T) { - uint32_t fpos = PP.getSourceManager().getFullFilePos(T.getLocation()); - Emit32(((uint32_t) T.getKind()) | (((uint32_t) T.getFlags()) << 8) | (((uint32_t) T.getLength()) << 16)); - Emit32(ResolveID(T.getIdentifierInfo())); - Emit32(fpos); - + // Literals (strings, numbers, characters) get cached spellings. if (T.isLiteral()) { // FIXME: This uses the slow getSpelling(). Perhaps we do better @@ -148,12 +145,21 @@ void PTHWriter::EmitToken(const Token& T) { const char* s = spelling.c_str(); // Get the string entry. - llvm::StringMapEntry *E = - &CachedStrs.GetOrCreateValue(s, s+spelling.size()); - - // Store the address of the string entry in our spelling map. - CurSpellMap->push_back(std::make_pair(fpos, E)); + llvm::StringMapEntry *E = + &CachedStrs.GetOrCreateValue(s, s+spelling.size()); + + if (!E->getValue().hasOffset()) { + E->getValue().setOffset(CurStrOffset); + StrEntries.push_back(E); + CurStrOffset += spelling.size() + 1; + } + + Emit32(E->getValue().getOffset()); } + else + Emit32(ResolveID(T.getIdentifierInfo())); + + Emit32(PP.getSourceManager().getFullFilePos(T.getLocation())); } namespace { @@ -251,7 +257,6 @@ Offset PTHWriter::EmitFileTable() { EmitBuf(Name, Name+size); Emit32(I->second.getTokenOffset()); Emit32(I->second.getPPCondTableOffset()); - Emit32(I->second.getSpellingTableOffset()); } return off; @@ -268,11 +273,6 @@ PCHEntry PTHWriter::LexTokens(Lexer& L) { PPCondTable PPCond; std::vector PPStartCond; bool ParsingPreprocessorDirective = false; - - // Allocate a spelling map for this source file. - llvm::OwningPtr Spellings(new SpellMapTy()); - CurSpellMap = Spellings.get(); - Token Tok; do { @@ -401,56 +401,22 @@ PCHEntry PTHWriter::LexTokens(Lexer& L) { Emit32(x == i ? 0 : x); } - return PCHEntry(off, PPCondOff, Spellings.take()); + return PCHEntry(off, PPCondOff); } -void PTHWriter::EmitCachedSpellings() { - // Write each cached string to the PTH file and update the - // the string map entry to contain the relevant offset. - // - // FIXME: We can write the strings out in order of their frequency. This - // may result in better locality. - // - for (CachedStrsTy::iterator I = CachedStrs.begin(), E = CachedStrs.end(); - I!=E; ++I) { - - Offset off = Out.tell(); - - // Write out the length of the string before the string itself. - unsigned len = I->getKeyLength(); - Emit16(len); +Offset PTHWriter::EmitCachedSpellings() { + // Write each cached strings to the PTH file. + Offset SpellingsOff = Out.tell(); + + for (std::vector*>::iterator + I = StrEntries.begin(), E = StrEntries.end(); I!=E; ++I) { - // Write out the string data. - const char* data = I->getKeyData(); - EmitBuf(data, data+len); - - // Write out a single blank character. - Emit8(' '); - - // Now patch the offset of the string in the PTH file into the string map. - I->setValue(off); + const char* data = (*I)->getKeyData(); + EmitBuf(data, data + (*I)->getKeyLength()); + Emit8('\0'); } - // Now emit the spelling tables. - for (PCHMap::iterator I=PM.begin(), E=PM.end(); I!=E; ++I) { - SpellMapTy& spellings = I->second.getSpellings(); - I->second.setSpellingTableOffset(Out.tell()); - - // Write out the number of spellings. - unsigned n = spellings.size(); - Emit32(n); - - for (unsigned i = 0; i < n; ++i) { - // Write out the offset of the token within the source file. - Emit32(spellings[i].first); - - // Write out the offset of the spelling data within the PTH file. - Emit32(spellings[i].second->getValue()); - } - - // Delete the spelling map for this source file. - delete &spellings; - } + return SpellingsOff; } void PTHWriter::GeneratePTH() { @@ -490,7 +456,7 @@ void PTHWriter::GeneratePTH() { = EmitIdentifierTable(); // Write out the cached strings table. - EmitCachedSpellings(); + Offset SpellingOff = EmitCachedSpellings(); // Write out the file table. Offset FileTableOff = EmitFileTable(); @@ -501,6 +467,7 @@ void PTHWriter::GeneratePTH() { Emit32(IdTableOff.second.first); Emit32(IdTableOff.second.second); Emit32(FileTableOff); + Emit32(SpellingOff); // Now write the offset in the prologue. Out.seek(JumpOffset); diff --git a/clang/include/clang/Lex/PTHLexer.h b/clang/include/clang/Lex/PTHLexer.h index c6837d2a8b3a..369b818a1fc9 100644 --- a/clang/include/clang/Lex/PTHLexer.h +++ b/clang/include/clang/Lex/PTHLexer.h @@ -45,10 +45,6 @@ class PTHLexer : public PreprocessorLexer { /// to process when doing quick skipping of preprocessor blocks. const unsigned char* CurPPCondPtr; - /// MySpellingMgr - Reference to the spelling manager used to get spellings - /// for the source file indicated by \c FileID. - PTHSpellingSearch& MySpellingSrch; - PTHLexer(const PTHLexer&); // DO NOT IMPLEMENT void operator=(const PTHLexer&); // DO NOT IMPLEMENT @@ -65,8 +61,7 @@ protected: /// Create a PTHLexer for the specified token stream. PTHLexer(Preprocessor& pp, FileID FID, const unsigned char *D, - const unsigned char* ppcond, - PTHSpellingSearch& mySpellingSrch, PTHManager &PM); + const unsigned char* ppcond, PTHManager &PM); public: ~PTHLexer() {} @@ -95,16 +90,6 @@ public: /// IndirectLex - An indirect call to 'Lex' that can be invoked via /// the PreprocessorLexer interface. void IndirectLex(Token &Result) { Lex(Result); } - - /// Returns the cached spelling of a token. - /// \param[in] sloc The SourceLocation of the token. - /// \param[out] Buffer If a token's spelling is found in the PTH file then - /// upon exit from this method \c Buffer will be set to the address of - /// the character array representing that spelling. No characters - /// are copied. - /// \returns The number of characters for the spelling of the token. This - /// value is 0 if the spelling could not be found in the PTH file. - unsigned getSpelling(SourceLocation sloc, const char *&Buffer); /// getSourceLocation - Return a source location for the token in /// the current file. diff --git a/clang/include/clang/Lex/PTHManager.h b/clang/include/clang/Lex/PTHManager.h index 31cf78f03635..b77cda1f0b7d 100644 --- a/clang/include/clang/Lex/PTHManager.h +++ b/clang/include/clang/Lex/PTHManager.h @@ -29,42 +29,13 @@ namespace clang { class FileEntry; class PTHLexer; -class PTHManager; - -class PTHSpellingSearch { - PTHManager& PTHMgr; - - const unsigned char* const TableBeg; - const unsigned char* const TableEnd; - - const unsigned NumSpellings; - const unsigned char* LinearItr; - -public: - enum { SpellingEntrySize = 4*2 }; - - unsigned getSpellingBinarySearch(unsigned fpos, const char *&Buffer); - unsigned getSpellingLinearSearch(unsigned fpos, const char *&Buffer); - - PTHSpellingSearch(PTHManager& pm, unsigned numSpellings, - const unsigned char* tableBeg) - : PTHMgr(pm), - TableBeg(tableBeg), - TableEnd(tableBeg + numSpellings*SpellingEntrySize), - NumSpellings(numSpellings), - LinearItr(tableBeg) {} -}; class PTHManager : public IdentifierInfoLookup { friend class PTHLexer; - friend class PTHSpellingSearch; /// The memory mapped PTH file. const llvm::MemoryBuffer* Buf; - - /// A map from FileIDs to SpellingSearch objects. - llvm::DenseMap SpellingMap; - + /// Alloc - Allocator used for IdentifierInfo objects. llvm::BumpPtrAllocator Alloc; @@ -84,7 +55,7 @@ class PTHManager : public IdentifierInfoLookup { /// SortedIdTable - Array ordering persistent identifier IDs by the lexical /// order of their corresponding strings. This is used by get(). const unsigned char* const SortedIdTable; - + /// NumIds - The number of identifiers in the PTH file. const unsigned NumIds; @@ -92,11 +63,16 @@ class PTHManager : public IdentifierInfoLookup { /// PTHLexer objects. Preprocessor* PP; + /// SpellingBase - The base offset within the PTH memory buffer that + /// contains the cached spellings for literals. + const unsigned char* const SpellingBase; + /// This constructor is intended to only be called by the static 'Create' /// method. PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup, const unsigned char* idDataTable, IdentifierInfo** perIDCache, - const unsigned char* sortedIdTable, unsigned numIds); + const unsigned char* sortedIdTable, unsigned numIds, + const unsigned char* spellingBase); // Do not implement. PTHManager(); @@ -119,7 +95,7 @@ class PTHManager : public IdentifierInfoLookup { public: // The current PTH version. - enum { Version = 0 }; + enum { Version = 1 }; ~PTHManager(); @@ -138,11 +114,7 @@ public: /// CreateLexer - Return a PTHLexer that "lexes" the cached tokens for the /// specified file. This method returns NULL if no cached tokens exist. /// It is the responsibility of the caller to 'delete' the returned object. - PTHLexer *CreateLexer(FileID FID); - - unsigned getSpelling(SourceLocation Loc, const char *&Buffer); -private: - unsigned getSpelling(FileID FID, unsigned fpos, const char *& Buffer); + PTHLexer *CreateLexer(FileID FID); }; } // end namespace clang diff --git a/clang/include/clang/Lex/Preprocessor.h b/clang/include/clang/Lex/Preprocessor.h index 095c1db1de3c..4e57069385d0 100644 --- a/clang/include/clang/Lex/Preprocessor.h +++ b/clang/include/clang/Lex/Preprocessor.h @@ -461,12 +461,6 @@ public: // If the token is carrying a literal data pointer, just use it. if (const char *D = Tok.getLiteralData()) return *D; - - if (PTH) { - const char *Data; - if (PTH->getSpelling(Tok.getLocation(), Data)) - return *Data; - } // Otherwise, fall back on getCharacterData, which is slower, but always // works. diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index d94ab7052564..f9f2b2106120 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -56,11 +56,9 @@ static inline uint32_t ReadLE32(const unsigned char *&Data) { //===----------------------------------------------------------------------===// PTHLexer::PTHLexer(Preprocessor &PP, FileID FID, const unsigned char *D, - const unsigned char *ppcond, - PTHSpellingSearch &mySpellingSrch, PTHManager &PM) + const unsigned char *ppcond, PTHManager &PM) : PreprocessorLexer(&PP, FID), TokBuf(D), CurPtr(D), LastHashTokPtr(0), - PPCond(ppcond), CurPPCondPtr(ppcond), MySpellingSrch(mySpellingSrch), - PTHMgr(PM) { + PPCond(ppcond), CurPPCondPtr(ppcond), PTHMgr(PM) { FileStartLoc = PP.getSourceManager().getLocForStartOfFile(FID); } @@ -98,7 +96,10 @@ LexNextToken: Tok.setLength(Len); // Handle identifiers. - if (IdentifierID) { + if (Tok.isLiteral()) { + Tok.setLiteralData((const char*) (PTHMgr.SpellingBase + IdentifierID)); + } + else if (IdentifierID) { MIOpt.ReadToken(); IdentifierInfo *II = PTHMgr.GetIdentifierInfo(IdentifierID-1); @@ -304,119 +305,6 @@ SourceLocation PTHLexer::getSourceLocation() { return FileStartLoc.getFileLocWithOffset(Offset); } -//===----------------------------------------------------------------------===// -// getSpelling() - Use cached data in PTH files for getSpelling(). -//===----------------------------------------------------------------------===// - -unsigned PTHManager::getSpelling(FileID FID, unsigned FPos, - const char *&Buffer) { - llvm::DenseMap::iterator I =SpellingMap.find(FID); - - if (I == SpellingMap.end()) - return 0; - - return I->second->getSpellingBinarySearch(FPos, Buffer); -} - -unsigned PTHManager::getSpelling(SourceLocation Loc, const char *&Buffer) { - SourceManager &SM = PP->getSourceManager(); - Loc = SM.getSpellingLoc(Loc); - std::pair LocInfo = SM.getDecomposedLoc(Loc); - return getSpelling(LocInfo.first, LocInfo.second, Buffer); -} - -unsigned PTHManager::getSpellingAtPTHOffset(unsigned PTHOffset, - const char *&Buffer) { - assert(PTHOffset < Buf->getBufferSize()); - const unsigned char* Ptr = - (const unsigned char*)Buf->getBufferStart() + PTHOffset; - - // The string is prefixed by 16 bits for its length, followed by the string - // itself. - unsigned Len = ReadUnalignedLE16(Ptr); - Buffer = (const char *)Ptr; - return Len; -} - -unsigned PTHSpellingSearch::getSpellingLinearSearch(unsigned FPos, - const char *&Buffer) { - const unsigned char *Ptr = LinearItr; - unsigned Len = 0; - - if (Ptr == TableEnd) - return getSpellingBinarySearch(FPos, Buffer); - - do { - uint32_t TokOffset = ReadLE32(Ptr); - - if (TokOffset > FPos) - return getSpellingBinarySearch(FPos, Buffer); - - // Did we find a matching token offset for this spelling? - if (TokOffset == FPos) { - uint32_t SpellingPTHOffset = ReadLE32(Ptr); - Len = PTHMgr.getSpellingAtPTHOffset(SpellingPTHOffset, Buffer); - break; - } - } while (Ptr != TableEnd); - - LinearItr = Ptr; - return Len; -} - - -unsigned PTHSpellingSearch::getSpellingBinarySearch(unsigned FPos, - const char *&Buffer) { - - assert((TableEnd - TableBeg) % SpellingEntrySize == 0); - assert(TableEnd >= TableBeg); - - if (TableEnd == TableBeg) - return 0; - - unsigned min = 0; - const unsigned char *tb = TableBeg; - unsigned max = NumSpellings; - - do { - unsigned i = (max - min) / 2 + min; - const unsigned char *Ptr = tb + (i * SpellingEntrySize); - - uint32_t TokOffset = ReadLE32(Ptr); - if (TokOffset > FPos) { - max = i; - assert(!(max == min) || (min == i)); - continue; - } - - if (TokOffset < FPos) { - if (i == min) - break; - - min = i; - continue; - } - - uint32_t SpellingPTHOffset = ReadLE32(Ptr); - return PTHMgr.getSpellingAtPTHOffset(SpellingPTHOffset, Buffer); - } - while (min != max); - - return 0; -} - -unsigned PTHLexer::getSpelling(SourceLocation Loc, const char *&Buffer) { - SourceManager &SM = PP->getSourceManager(); - std::pair LocInfo = SM.getDecomposedSpellingLoc(Loc); - - FileID FID = LocInfo.first; - unsigned FPos = LocInfo.second; - - if (FID == getFileID()) - return MySpellingSrch.getSpellingLinearSearch(FPos, Buffer); - return PTHMgr.getSpelling(FID, FPos, Buffer); -} - //===----------------------------------------------------------------------===// // Internal Data Structures for PTH file lookup and resolving identifiers. //===----------------------------------------------------------------------===// @@ -431,11 +319,10 @@ public: class Val { uint32_t TokenOff; uint32_t PPCondOff; - uint32_t SpellingOff; public: Val() : TokenOff(~0) {} - Val(uint32_t toff, uint32_t poff, uint32_t soff) - : TokenOff(toff), PPCondOff(poff), SpellingOff(soff) {} + Val(uint32_t toff, uint32_t poff) + : TokenOff(toff), PPCondOff(poff) {} bool isValid() const { return TokenOff != ~((uint32_t)0); } @@ -447,12 +334,7 @@ public: uint32_t getPPCondOffset() const { assert(isValid() && "PTHFileLookup entry initialized."); return PPCondOff; - } - - uint32_t getSpellingOffset() const { - assert(isValid() && "PTHFileLookup entry initialized."); - return SpellingOff; - } + } }; private: @@ -481,10 +363,9 @@ public: uint32_t TokenOff = ReadLE32(D); uint32_t PPCondOff = ReadLE32(D); - uint32_t SpellingOff = ReadLE32(D); FileMap.GetOrCreateValue(s, s+Len).getValue() = - Val(TokenOff, PPCondOff, SpellingOff); + Val(TokenOff, PPCondOff); } } }; @@ -497,10 +378,11 @@ public: PTHManager::PTHManager(const llvm::MemoryBuffer* buf, void* fileLookup, const unsigned char* idDataTable, IdentifierInfo** perIDCache, - const unsigned char* sortedIdTable, unsigned numIds) + const unsigned char* sortedIdTable, unsigned numIds, + const unsigned char* spellingBase) : Buf(buf), PerIDCache(perIDCache), FileLookup(fileLookup), IdDataTable(idDataTable), SortedIdTable(sortedIdTable), - NumIds(numIds), PP(0) {} + NumIds(numIds), PP(0), SpellingBase(spellingBase) {} PTHManager::~PTHManager() { delete Buf; @@ -573,6 +455,14 @@ PTHManager* PTHManager::Create(const std::string& file) { return 0; // FIXME: Proper error diagnostic? } + // Get the location of the spelling cache. + const unsigned char* spellingBaseOffset = EndTable + sizeof(uint32_t)*4; + const unsigned char* spellingBase = BufBeg + ReadLE32(spellingBaseOffset); + if (!(spellingBase >= BufBeg && spellingBase < BufEnd)) { + assert(false && "Invalid PTH file."); + return 0; + } + // Get the number of IdentifierInfos and pre-allocate the identifier cache. uint32_t NumIds = ReadLE32(IData); @@ -591,7 +481,7 @@ PTHManager* PTHManager::Create(const std::string& file) { // Create the new PTHManager. return new PTHManager(File.take(), FL.take(), IData, PerIDCache, - SortedIdTable, NumIds); + SortedIdTable, NumIds, spellingBase); } IdentifierInfo* PTHManager::LazilyCreateIdentifierInfo(unsigned PersistentID) { // Look in the PTH file for the string data for the IdentifierInfo object. @@ -678,18 +568,6 @@ PTHLexer *PTHManager::CreateLexer(FileID FID) { uint32_t Len = ReadLE32(ppcond); if (Len == 0) ppcond = 0; - // Get the location of the spelling table. - const unsigned char* spellingTable = BufStart + FileData.getSpellingOffset(); - - Len = ReadLE32(spellingTable); - if (Len == 0) spellingTable = 0; - - assert(data < (const unsigned char*)Buf->getBufferEnd()); - - // Create the SpellingSearch object for this FileID. - PTHSpellingSearch* ss = new PTHSpellingSearch(*this, Len, spellingTable); - SpellingMap[FID] = ss; - assert(PP && "No preprocessor set yet!"); - return new PTHLexer(*PP, FID, data, ppcond, *ss, *this); + return new PTHLexer(*PP, FID, data, ppcond, *this); } diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index cb0c850e7ead..e6bf1777a891 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -198,17 +198,9 @@ void Preprocessor::PrintStats() { /// UCNs, etc. std::string Preprocessor::getSpelling(const Token &Tok) const { assert((int)Tok.getLength() >= 0 && "Token character range is bogus!"); - const char* TokStart; - - if (PTH) { - if (unsigned Len = PTH->getSpelling(Tok.getLocation(), TokStart)) { - assert(!Tok.needsCleaning()); - return std::string(TokStart, TokStart+Len); - } - } - + // If this token contains nothing interesting, return it directly. - TokStart = SourceMgr.getCharacterData(Tok.getLocation()); + const char* TokStart = SourceMgr.getCharacterData(Tok.getLocation()); if (!Tok.needsCleaning()) return std::string(TokStart, TokStart+Tok.getLength()); @@ -248,23 +240,6 @@ unsigned Preprocessor::getSpelling(const Token &Tok, return II->getLength(); } - // If using PTH, try and get the spelling from the PTH file. - if (PTH) { - unsigned Len; - - if (CurPTHLexer) { - Len = CurPTHLexer.get()->getSpelling(Tok.getLocation(), Buffer); - } else { - Len = PTH->getSpelling(Tok.getLocation(), Buffer); - } - - // Did we find a spelling? If so return its length. Otherwise fall - // back to the default behavior for getting the spelling by looking at - // at the source code. - if (Len) - return Len; - } - // Otherwise, compute the start of the token in the input lexer buffer. const char *TokStart = 0; -- GitLab From 1cd2a2c9f84c2148e1eb791ba5d69fd98945cef4 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 00:40:06 +0000 Subject: [PATCH 256/682] Fix the Red Zone calculation for functions with frame pointers. Don't use the Red Zone when dynamic stack realignment is needed. This could be implemented, but most x86-64 ABIs don't require dynamic stack realignment so it isn't urgent. llvm-svn: 63074 --- llvm/lib/Target/X86/X86RegisterInfo.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp index 08746f2ffb47..73cab622b668 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.cpp +++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp @@ -721,24 +721,27 @@ void X86RegisterInfo::emitPrologue(MachineFunction &MF) const { // Get desired stack alignment uint64_t MaxAlign = MFI->getMaxAlignment(); + // Add RETADDR move area to callee saved frame size. + int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); + if (TailCallReturnAddrDelta < 0) + X86FI->setCalleeSavedFrameSize( + X86FI->getCalleeSavedFrameSize() +(-TailCallReturnAddrDelta)); + // If this is x86-64 and the Red Zone is not disabled, if we are a leaf // function, and use up to 128 bytes of stack space, don't have a frame // pointer, calls, or dynamic alloca then we do not need to adjust the // stack pointer (we fit in the Red Zone). if (Is64Bit && !DisableRedZone && + !needsStackRealignment(MF) && !MFI->hasVarSizedObjects() && // No dynamic alloca. !MFI->hasCalls()) { // No calls. - StackSize = std::max((uint64_t)X86FI->getCalleeSavedFrameSize(), + uint64_t MinSize = X86FI->getCalleeSavedFrameSize(); + if (hasFP(MF)) MinSize += SlotSize; + StackSize = std::max(MinSize, StackSize > 128 ? StackSize - 128 : 0); MFI->setStackSize(StackSize); } - // Add RETADDR move area to callee saved frame size. - int TailCallReturnAddrDelta = X86FI->getTCReturnAddrDelta(); - if (TailCallReturnAddrDelta < 0) - X86FI->setCalleeSavedFrameSize( - X86FI->getCalleeSavedFrameSize() +(-TailCallReturnAddrDelta)); - // Insert stack pointer adjustment for later moving of return addr. Only // applies to tail call optimized functions where the callee argument stack // size is bigger than the callers. -- GitLab From 8738997c11e6bd7ba1347a307c94f75334fedd38 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 00:40:27 +0000 Subject: [PATCH 257/682] Add a regression test for x86-64 red zone usage. llvm-svn: 63075 --- llvm/test/CodeGen/X86/red-zone.ll | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 llvm/test/CodeGen/X86/red-zone.ll diff --git a/llvm/test/CodeGen/X86/red-zone.ll b/llvm/test/CodeGen/X86/red-zone.ll new file mode 100644 index 000000000000..60e16b05ca75 --- /dev/null +++ b/llvm/test/CodeGen/X86/red-zone.ll @@ -0,0 +1,13 @@ +; RUN: llvm-as < %s | llc -march=x86-64 > %t +; RUN: not grep subq %t +; RUN: not grep addq %t +; RUN: grep {\\-4(%%rsp)} %t | count 2 +; RUN: llvm-as < %s | llc -march=x86-64 -disable-red-zone > %t +; RUN: grep subq %t | count 1 +; RUN: grep addq %t | count 1 + +define x86_fp80 @f0(float %f) nounwind readnone { +entry: + %0 = fpext float %f to x86_fp80 ; [#uses=1] + ret x86_fp80 %0 +} -- GitLab From 45c899cd1519c7b796290dc8875ff987cfb5be83 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 27 Jan 2009 00:45:04 +0000 Subject: [PATCH 258/682] Assorted debug info fixes. - DW_AT_bit_size is only suitable for bitfields. - Encode source location info for derived types. - Source location and type size info is not useful for subroutine_type (info is included in respective DISubprogram) and array_type. llvm-svn: 63077 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 36 +++++++++++---------- llvm/test/DebugInfo/forwardDecl.ll | 2 +- 2 files changed, 20 insertions(+), 18 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index c651cb66ceb4..19edd9514686 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1733,8 +1733,8 @@ private: // Add source line info if available and TyDesc is not a forward // declaration. - // FIXME - Enable this. if (!DTy.isForwardDecl()) - // FIXME - Enable this. AddSourceLine(&Buffer, *DTy); + if (!DTy.isForwardDecl()) + AddSourceLine(&Buffer, &DTy); } /// ConstructTypeDIE - Construct type DIE from DICompositeType. @@ -1815,20 +1815,23 @@ private: // Add name if not anonymous or intermediate type. if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name); - // Add size if non-zero (derived types might be zero-sized.) - if (Size) - AddUInt(&Buffer, DW_AT_byte_size, 0, Size); - else { - // Add zero size if it is not a forward declaration. - if (CTy.isForwardDecl()) - AddUInt(&Buffer, DW_AT_declaration, DW_FORM_flag, 1); - else - AddUInt(&Buffer, DW_AT_byte_size, 0, 0); + if (Tag == DW_TAG_enumeration_type || Tag == DW_TAG_structure_type + || Tag == DW_TAG_union_type) { + // Add size if non-zero (derived types might be zero-sized.) + if (Size) + AddUInt(&Buffer, DW_AT_byte_size, 0, Size); + else { + // Add zero size if it is not a forward declaration. + if (CTy.isForwardDecl()) + AddUInt(&Buffer, DW_AT_declaration, DW_FORM_flag, 1); + else + AddUInt(&Buffer, DW_AT_byte_size, 0, 0); + } + + // Add source line info if available. + if (!CTy.isForwardDecl()) + AddSourceLine(&Buffer, &CTy); } - - // Add source line info if available. - if (!CTy.isForwardDecl()) - AddSourceLine(&Buffer, &CTy); } // ConstructSubrangeDIE - Construct subrange DIE from DISubrange. @@ -1853,7 +1856,6 @@ private: AddUInt(&Buffer, DW_AT_GNU_vector, DW_FORM_flag, 1); DIArray Elements = CTy->getTypeArray(); - AddType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom()); // Construct an anonymous type for index type. DIE IdxBuffer(DW_TAG_base_type); @@ -1906,7 +1908,7 @@ private: AddSourceLine(MemberDie, &DT); - AddUInt(MemberDie, DW_AT_bit_size, 0, DT.getSizeInBits()); + // FIXME _ Handle bitfields DIEBlock *Block = new DIEBlock(); AddUInt(Block, 0, DW_FORM_data1, DW_OP_plus_uconst); AddUInt(Block, 0, DW_FORM_udata, DT.getOffsetInBits() >> 3); diff --git a/llvm/test/DebugInfo/forwardDecl.ll b/llvm/test/DebugInfo/forwardDecl.ll index a8bb9fffd0bb..c918f32cfb11 100644 --- a/llvm/test/DebugInfo/forwardDecl.ll +++ b/llvm/test/DebugInfo/forwardDecl.ll @@ -18,7 +18,7 @@ target triple = "i386-apple-darwin9.6" @.str3 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] @llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 393473, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([2 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] @.str4 = internal constant [2 x i8] c"x\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] -@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 393231, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* null, i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 393231, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.compositetype.type* @llvm.dbg.compositetype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] @llvm.dbg.compositetype = internal constant %llvm.dbg.compositetype.type { i32 393235, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([3 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 1, i64 0, i64 8, i64 0, i32 4, { }* null, { }* bitcast ([0 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.compositetype.type*> [#uses=1] @.str5 = internal constant [3 x i8] c"ST\00", section "llvm.metadata" ; <[3 x i8]*> [#uses=1] @llvm.dbg.array = internal constant [0 x { }*] zeroinitializer, section "llvm.metadata" ; <[0 x { }*]*> [#uses=1] -- GitLab From 75cee3a93c82ada7f9dd90906b858d200617e007 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 00:58:47 +0000 Subject: [PATCH 259/682] Enable the red zone on x86-64 by default. llvm-svn: 63078 --- llvm/lib/Target/TargetMachine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Target/TargetMachine.cpp b/llvm/lib/Target/TargetMachine.cpp index fd577c7438ac..49f1e4dfaae6 100644 --- a/llvm/lib/Target/TargetMachine.cpp +++ b/llvm/lib/Target/TargetMachine.cpp @@ -169,7 +169,7 @@ static cl::opt DisableRedZoneOption("disable-red-zone", cl::desc("Do not emit code that uses the red zone."), cl::location(DisableRedZone), - cl::init(true)); + cl::init(false)); //--------------------------------------------------------------------------- // TargetMachine Class -- GitLab From 52e907a78007c738ecea6eaabaffd6d47488e8b0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 00:59:55 +0000 Subject: [PATCH 260/682] Add a FrontendC testcase for the x86-64 Red Zone feature, to help verify that the feature may be disabled through the -mno-red-zone option. llvm-svn: 63079 --- llvm/test/FrontendC/x86-64-red-zone.c | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 llvm/test/FrontendC/x86-64-red-zone.c diff --git a/llvm/test/FrontendC/x86-64-red-zone.c b/llvm/test/FrontendC/x86-64-red-zone.c new file mode 100644 index 000000000000..e3e3cab2ff81 --- /dev/null +++ b/llvm/test/FrontendC/x86-64-red-zone.c @@ -0,0 +1,11 @@ +// RUN: $llvmgcc -m64 -fomit-frame-pointer -O2 %s -S -o - > %t +// RUN: not grep subq %t +// RUN: not grep addq %t +// RUN: grep {\\-4(%%rsp)} %t | count 2 +// RUN: $llvmgcc -m64 -fomit-frame-pointer -O2 %s -S -o - -mno-red-zone > %t +// RUN: grep subq %t | count 1 +// RUN: grep addq %t | count 1 +// This is a test for x86-64, add your target below if it FAILs. +// XFAIL: alpha|ia64|arm|powerpc|sparc|x86 + +long double f0(float f) { return f; } -- GitLab From 725fb43012391b9d76511f9beceea6b5f9205045 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 27 Jan 2009 01:19:08 +0000 Subject: [PATCH 261/682] Have 'Analyzer Failures' files be named to reflect the category of problem. llvm-svn: 63080 --- clang/utils/ccc-analyzer | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/clang/utils/ccc-analyzer b/clang/utils/ccc-analyzer index 6c5e700ae4f6..a3b7851247ed 100755 --- a/clang/utils/ccc-analyzer +++ b/clang/utils/ccc-analyzer @@ -41,15 +41,20 @@ sub GetPPExt { return ".i"; } +my $ParserRejects = "Parser Rejects"; + sub ProcessClangFailure { my ($Clang, $Lang, $file, $Args, $HtmlDir, $ErrorType, $ofile) = @_; my $Dir = "$HtmlDir/crashes"; mkpath $Dir; + + my $prefix = "clang_crash"; + if ($ErrorType == $ParserRejects) { $prefix = "clang_parser_rejects"; } # Generate the preprocessed file with cc (i.e., gcc). - my ($PPH, $PPFile) = tempfile("clang_crash_XXXXXX", - SUFFIX => GetPPExt($Lang), - DIR => $Dir); + my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX", + SUFFIX => GetPPExt($Lang), + DIR => $Dir); system $CC, @$Args, "-E", "-o", $PPFile; close ($PPH); @@ -171,7 +176,7 @@ sub Analyze { } elsif ($Result) { ProcessClangFailure($Clang, $Lang, $file, \@CmdArgsSansAnalyses, $HtmlDir, - "Parser Rejects", $ofile); + $ParserRejects, $ofile); } `rm -f $ofile`; -- GitLab From 0f4aa3cbb1a7cc2480fc8159b3cd46df7fcc2b16 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 27 Jan 2009 01:36:03 +0000 Subject: [PATCH 262/682] Implement support for coercion to wider types during ABI handling. - Code quality is poor, but simple. llvm-svn: 63083 --- clang/lib/CodeGen/CGCall.cpp | 76 ++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index cd781781f919..9e632c0e272e 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -22,6 +22,7 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Attributes.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Target/TargetData.h" using namespace clang; using namespace CodeGen; @@ -935,6 +936,71 @@ void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, assert(AI == Fn->arg_end() && "Argument mismatch!"); } +/// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as +/// a pointer to an object of type \arg Ty. +/// +/// This safely handles the case when the src type is smaller than the +/// destination type; in this situation the values of bits which not +/// present in the src are undefined. +static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr, + const llvm::Type *Ty, + CodeGenFunction &CGF) { + const llvm::Type *SrcTy = + cast(SrcPtr->getType())->getElementType(); + unsigned SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy); + unsigned DstSize = CGF.CGM.getTargetData().getTypePaddedSize(Ty); + + // If load is legal, just bitcase the src pointer. + if (SrcSize == DstSize) { + llvm::Value *Casted = + CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty)); + return CGF.Builder.CreateLoad(Casted); + } else { + assert(SrcSize < DstSize && "Coercion is losing source bits!"); + + // Otherwise do coercion through memory. This is stupid, but + // simple. + llvm::Value *Tmp = CGF.CreateTempAlloca(Ty); + llvm::Value *Casted = + CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(SrcTy)); + CGF.Builder.CreateStore(CGF.Builder.CreateLoad(SrcPtr), Casted); + return CGF.Builder.CreateLoad(Tmp); + } +} + +/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src, +/// where the source and destination may have different types. +/// +/// This safely handles the case when the src type is larger than the +/// destination type; the upper bits of the src will be lost. +static void CreateCoercedStore(llvm::Value *Src, + llvm::Value *DstPtr, + CodeGenFunction &CGF) { + const llvm::Type *SrcTy = Src->getType(); + const llvm::Type *DstTy = + cast(DstPtr->getType())->getElementType(); + + unsigned SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy); + unsigned DstSize = CGF.CGM.getTargetData().getTypePaddedSize(DstTy); + + // If store is legal, just bitcase the src pointer. + if (SrcSize == DstSize) { + llvm::Value *Casted = + CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy)); + CGF.Builder.CreateStore(Src, Casted); + } else { + assert(SrcSize > DstSize && "Coercion is missing bits!"); + + // Otherwise do coercion through memory. This is stupid, but + // simple. + llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy); + CGF.Builder.CreateStore(Src, Tmp); + llvm::Value *Casted = + CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(DstTy)); + CGF.Builder.CreateStore(CGF.Builder.CreateLoad(Casted), DstPtr); + } +} + void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, llvm::Value *ReturnValue) { llvm::Value *RV = 0; @@ -965,9 +1031,7 @@ void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, break; case ABIArgInfo::Coerce: { - const llvm::Type *CoerceToPTy = - llvm::PointerType::getUnqual(RetAI.getCoerceToType()); - RV = Builder.CreateLoad(Builder.CreateBitCast(ReturnValue, CoerceToPTy)); + RV = CreateCoercedLoad(ReturnValue, RetAI.getCoerceToType(), *this); break; } @@ -1073,10 +1137,8 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, return RValue::get(0); case ABIArgInfo::Coerce: { - const llvm::Type *CoerceToPTy = - llvm::PointerType::getUnqual(RetAI.getCoerceToType()); - llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "tmp"); - Builder.CreateStore(CI, Builder.CreateBitCast(V, CoerceToPTy)); + llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "coerce"); + CreateCoercedStore(CI, V, *this); if (RetTy->isAnyComplexType()) return RValue::getComplex(LoadComplexFromAddr(V, false)); else if (CodeGenFunction::hasAggregateLLVMType(RetTy)) -- GitLab From a3f462e49aed3ef3c41a687df768de45eb079047 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 27 Jan 2009 01:53:39 +0000 Subject: [PATCH 263/682] PathDiagnostics: - Add the distinction between the 'bug type' and the 'bug description' HTMLDiagnostics: - Output the bug type field as HTML comments scan-build: - Use the bug type field instead of the bug description for the HTML table. - Radar filing now automatically picks up the bug description in the title (addresses ) llvm-svn: 63084 --- clang/include/clang/Analysis/PathDiagnostic.h | 11 +++++++---- clang/lib/Analysis/BugReporter.cpp | 1 + clang/lib/Driver/HTMLDiagnostics.cpp | 8 ++++++++ clang/utils/scan-build | 8 ++++---- 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/clang/include/clang/Analysis/PathDiagnostic.h b/clang/include/clang/Analysis/PathDiagnostic.h index bedc6da40f7f..bc68ac59116f 100644 --- a/clang/include/clang/Analysis/PathDiagnostic.h +++ b/clang/include/clang/Analysis/PathDiagnostic.h @@ -78,20 +78,23 @@ class PathDiagnostic { unsigned Size; std::string Desc; std::string Category; + std::string BugType; std::vector OtherDesc; public: PathDiagnostic() : Size(0) {} - PathDiagnostic(const char* desc, const char* category) - : Size(0), Desc(desc), Category(category) {} + PathDiagnostic(const char* bugtype, const char* desc, const char* category) + : Size(0), Desc(desc), Category(category), BugType(bugtype) {} - PathDiagnostic(const std::string& desc, const std::string& category) - : Size(0), Desc(desc), Category(category) {} + PathDiagnostic(const std::string& bugtype, const std::string& desc, + const std::string& category) + : Size(0), Desc(desc), Category(category), BugType(bugtype) {} ~PathDiagnostic(); const std::string& getDescription() const { return Desc; } + const std::string& getBugType() const { return BugType; } const std::string& getCategory() const { return Category; } typedef std::vector::const_iterator meta_iterator; diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index b08f5cb793e3..f59f89a1a82e 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/lib/Analysis/BugReporter.cpp @@ -727,6 +727,7 @@ void BugReporter::EmitWarning(BugReport& R) { return; llvm::OwningPtr D(new PathDiagnostic(R.getName(), + R.getDescription(), R.getCategory())); GeneratePathDiagnostic(*D.get(), R); diff --git a/clang/lib/Driver/HTMLDiagnostics.cpp b/clang/lib/Driver/HTMLDiagnostics.cpp index 2772cf342268..6b60588ca56c 100644 --- a/clang/lib/Driver/HTMLDiagnostics.cpp +++ b/clang/lib/Driver/HTMLDiagnostics.cpp @@ -246,6 +246,14 @@ void HTMLDiagnostics::ReportDiag(const PathDiagnostic& D) { R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); } + const std::string& BugType = D.getBugType(); + if (!BugType.empty()) { + std::string s; + llvm::raw_string_ostream os(s); + os << "\n\n"; + R.InsertStrBefore(SMgr.getLocForStartOfFile(FID), os.str()); + } + const std::string& BugCategory = D.getCategory(); if (!BugCategory.empty()) { diff --git a/clang/utils/scan-build b/clang/utils/scan-build index 44f0cbc64177..39b9ede93916 100755 --- a/clang/utils/scan-build +++ b/clang/utils/scan-build @@ -350,7 +350,7 @@ sub ScanFile { # Scan the report file for tags. open(IN, "$Dir/$FName") or DieDiag("Cannot open '$Dir/$FName'\n"); - my $BugDesc = ""; + my $BugType = ""; my $BugFile = ""; my $BugCategory; my $BugPathLength = 1; @@ -361,8 +361,8 @@ sub ScanFile { last if ($found == 5); - if (/$/) { - $BugDesc = $1; + if (/$/) { + $BugType = $1; ++$found; } elsif (/$/) { @@ -390,7 +390,7 @@ sub ScanFile { $BugCategory = "Other"; } - push @$Index,[ $FName, $BugCategory, $BugDesc, $BugFile, $BugLine, + push @$Index,[ $FName, $BugCategory, $BugType, $BugFile, $BugLine, $BugPathLength ]; } -- GitLab From 9b415d614268fe3d3cdd15d5a25608c7b1e13366 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 01:58:38 +0000 Subject: [PATCH 264/682] add SparcV8 asm register info support. Patch by Ben Lickly! llvm-svn: 63085 --- clang/lib/Basic/Targets.cpp | 67 +++++++++++++++++++++++++++++++------ 1 file changed, 57 insertions(+), 10 deletions(-) diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp index 026641c7c7db..f82b0fcdb1bb 100644 --- a/clang/lib/Basic/Targets.cpp +++ b/clang/lib/Basic/Targets.cpp @@ -800,6 +800,8 @@ public: namespace { class SparcV8TargetInfo : public TargetInfo { + static const TargetInfo::GCCRegAlias GCCRegAliases[]; + static const char * const GCCRegNames[]; public: SparcV8TargetInfo(const std::string& triple) : TargetInfo(triple) { // FIXME: Support Sparc quad-precision long double? @@ -824,17 +826,9 @@ public: return "sparc"; } virtual void getGCCRegNames(const char * const *&Names, - unsigned &NumNames) const { - // FIXME: Implement! - Names = 0; - NumNames = 0; - } + unsigned &NumNames) const; virtual void getGCCRegAliases(const GCCRegAlias *&Aliases, - unsigned &NumAliases) const { - // FIXME: Implement! - Aliases = 0; - NumAliases = 0; - } + unsigned &NumAliases) const; virtual bool validateAsmConstraint(char c, TargetInfo::ConstraintInfo &info) const { // FIXME: Implement! @@ -846,6 +840,59 @@ public: } }; +const char * const SparcV8TargetInfo::GCCRegNames[] = { + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", + "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", + "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31" +}; + +void SparcV8TargetInfo::getGCCRegNames(const char * const *&Names, + unsigned &NumNames) const { + Names = GCCRegNames; + NumNames = llvm::array_lengthof(GCCRegNames); +} + +const TargetInfo::GCCRegAlias SparcV8TargetInfo::GCCRegAliases[] = { + { { "g0" }, "r0" }, + { { "g1" }, "r1" }, + { { "g2" }, "r2" }, + { { "g3" }, "r3" }, + { { "g4" }, "r4" }, + { { "g5" }, "r5" }, + { { "g6" }, "r6" }, + { { "g7" }, "r7" }, + { { "o0" }, "r8" }, + { { "o1" }, "r9" }, + { { "o2" }, "r10" }, + { { "o3" }, "r11" }, + { { "o4" }, "r12" }, + { { "o5" }, "r13" }, + { { "o6", "sp" }, "r14" }, + { { "o7" }, "r15" }, + { { "l0" }, "r16" }, + { { "l1" }, "r17" }, + { { "l2" }, "r18" }, + { { "l3" }, "r19" }, + { { "l4" }, "r20" }, + { { "l5" }, "r21" }, + { { "l6" }, "r22" }, + { { "l7" }, "r23" }, + { { "i0" }, "r24" }, + { { "i1" }, "r25" }, + { { "i2" }, "r26" }, + { { "i3" }, "r27" }, + { { "i4" }, "r28" }, + { { "i5" }, "r29" }, + { { "i6", "fp" }, "r30" }, + { { "i7" }, "r31" }, +}; + +void SparcV8TargetInfo::getGCCRegAliases(const GCCRegAlias *&Aliases, + unsigned &NumAliases) const { + Aliases = GCCRegAliases; + NumAliases = llvm::array_lengthof(GCCRegAliases); +} } // end anonymous namespace. namespace { -- GitLab From d678d3d970972906536d147463b3185b31f91d2a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 27 Jan 2009 02:01:34 +0000 Subject: [PATCH 265/682] x86_64: Classify __m64 and __m128 "correctly". - gcc appears to be classifying <1 x double> as INTEGER which is odd. Will investigate later. llvm-svn: 63086 --- clang/lib/CodeGen/CGCall.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 9e632c0e272e..72ba7f879af5 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -450,12 +450,24 @@ void X86_64ABIInfo::classify(QualType Ty, Lo = X87; Hi = X87Up; } - // FIXME: _Decimal32, _Decimal64, and __m64 are SSE. - // FIXME: _float128, _Decimal128, and __m128 are (SSE, SSEUp). + + // FIXME: _Decimal32 and _Decimal64 are SSE. + // FIXME: _float128 and _Decimal128 are (SSE, SSEUp). // FIXME: __int128 is (Integer, Integer). } else if (Ty->isPointerLikeType() || Ty->isBlockPointerType() || Ty->isObjCQualifiedInterfaceType()) { Lo = Integer; + } else if (const VectorType *VT = Ty->getAsVectorType()) { + unsigned Size = Context.getTypeSize(VT); + if (Size == 64) { + // FIXME: For some reason, gcc appears to be treating <1 x + // double> as INTEGER; this seems wrong, but we will match for + // now (icc rejects <1 x double>, so...). + Lo = (VT->getElementType() == Context.DoubleTy) ? Integer : SSE; + } else if (Size == 128) { + Lo = SSE; + Hi = SSEUp; + } } else if (const ComplexType *CT = Ty->getAsComplexType()) { QualType ET = CT->getElementType(); -- GitLab From 7740523a890e1a1cdd99fc087d33ec238fd893bd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 02:37:43 +0000 Subject: [PATCH 266/682] Eliminate unnecessary operands-list traversals. llvm-svn: 63088 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index 04ba430d2d6e..c5a6edd87a77 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -242,12 +242,9 @@ namespace { static SDNode *findFlagUse(SDNode *N) { unsigned FlagResNo = N->getNumValues()-1; for (SDNode::use_iterator I = N->use_begin(), E = N->use_end(); I != E; ++I) { - SDNode *User = *I; - for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) { - SDValue Op = User->getOperand(i); - if (Op.getNode() == N && Op.getResNo() == FlagResNo) - return User; - } + SDUse &Use = I.getUse(); + if (Use.getResNo() == FlagResNo) + return Use.getUser(); } return NULL; } -- GitLab From ce95cddd0fddee773e7b8311573ac20fecbd0589 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 27 Jan 2009 02:59:39 +0000 Subject: [PATCH 267/682] Forgot this test case. llvm-svn: 63089 --- llvm/test/FrontendC/implicit-arg.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 llvm/test/FrontendC/implicit-arg.c diff --git a/llvm/test/FrontendC/implicit-arg.c b/llvm/test/FrontendC/implicit-arg.c new file mode 100644 index 000000000000..971245f3badc --- /dev/null +++ b/llvm/test/FrontendC/implicit-arg.c @@ -0,0 +1,10 @@ +// RUN: %llvmgcc %s -S -emit-llvm -O0 -o - +// RUN: %llvmgcc %s -S -emit-llvm -O1 -o - +// rdar://6518089 + +static int bar(); +void foo() { + int a = bar(); +} +int bar(unsigned a) { +} -- GitLab From 1bc8af207ef075bea5dce5fd98ec45918a8dcad6 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 27 Jan 2009 03:30:42 +0000 Subject: [PATCH 268/682] Implement multiple with overflow by 2 with an add instruction. llvm-svn: 63090 --- llvm/lib/Target/X86/X86InstrInfo.td | 11 ++++++++++ llvm/test/CodeGen/X86/smul-with-overflow-2.ll | 20 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 llvm/test/CodeGen/X86/smul-with-overflow-2.ll diff --git a/llvm/lib/Target/X86/X86InstrInfo.td b/llvm/lib/Target/X86/X86InstrInfo.td index 9649c234de45..f4a57be007e1 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.td +++ b/llvm/lib/Target/X86/X86InstrInfo.td @@ -3612,6 +3612,17 @@ def : Pat<(parallel (X86smul_ovf (load addr:$src1), i32immSExt8:$src2), (implicit EFLAGS)), (IMUL32rmi8 addr:$src1, i32immSExt8:$src2)>; +// Optimize multiple with overflow by 2. +let AddedComplexity = 2 in { +def : Pat<(parallel (X86smul_ovf GR16:$src1, 2), + (implicit EFLAGS)), + (ADD16rr GR16:$src1, GR16:$src1)>; + +def : Pat<(parallel (X86smul_ovf GR32:$src1, 2), + (implicit EFLAGS)), + (ADD32rr GR32:$src1, GR32:$src1)>; +} + //===----------------------------------------------------------------------===// // Floating Point Stack Support //===----------------------------------------------------------------------===// diff --git a/llvm/test/CodeGen/X86/smul-with-overflow-2.ll b/llvm/test/CodeGen/X86/smul-with-overflow-2.ll new file mode 100644 index 000000000000..c3dbfd796f20 --- /dev/null +++ b/llvm/test/CodeGen/X86/smul-with-overflow-2.ll @@ -0,0 +1,20 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep mul | count 1 +; RUN: llvm-as < %s | llc -march=x86 | grep add | count 3 + +define i32 @t1(i32 %a, i32 %b) nounwind readnone { +entry: + %tmp0 = add i32 %b, %a + %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 2) + %tmp2 = extractvalue { i32, i1 } %tmp1, 0 + ret i32 %tmp2 +} + +define i32 @t2(i32 %a, i32 %b) nounwind readnone { +entry: + %tmp0 = add i32 %b, %a + %tmp1 = call { i32, i1 } @llvm.smul.with.overflow.i32(i32 %tmp0, i32 4) + %tmp2 = extractvalue { i32, i1 } %tmp1, 0 + ret i32 %tmp2 +} + +declare { i32, i1 } @llvm.smul.with.overflow.i32(i32, i32) nounwind -- GitLab From 431053ed2ca26dbbaf06bc5ec5f88227d5e1546b Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Tue, 27 Jan 2009 05:01:15 +0000 Subject: [PATCH 269/682] Make the pre-split-limit option more useful by using a per-function counter. llvm-svn: 63091 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index e3d652ac5e34..2a009b0aef81 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -38,7 +38,7 @@ using namespace llvm; static cl::opt PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden); -STATISTIC(NumSplits, "Number of intervals split"); +STATISTIC(NumTotalSplits, "Number of intervals split"); STATISTIC(NumRemats, "Number of intervals split by rematerialization"); STATISTIC(NumFolds, "Number of intervals split with spill folding"); STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers"); @@ -77,6 +77,8 @@ namespace { // Def2SpillMap - A map from a def instruction index to spill index. DenseMap Def2SpillMap; + + unsigned NumSplits; public: static char ID; @@ -1191,6 +1193,7 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) { LSs = &getAnalysis(); bool MadeChange = false; + NumSplits = 0; // Make sure blocks are numbered in order. MF.RenumberBlocks(); @@ -1217,6 +1220,9 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) { } MadeChange |= removeDeadSpills(Split); + + if (NumSplits) + NumTotalSplits += NumSplits; return MadeChange; } -- GitLab From 8d3f4a4b2f9493dd748d0a12e5084283db064310 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 05:06:01 +0000 Subject: [PATCH 270/682] improvements for GNU objc runtime support, patch by David Chisnall! llvm-svn: 63092 --- clang/lib/CodeGen/CGObjCGNU.cpp | 86 +++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 32 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 2621a8491406..10ceee9c6b20 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -26,6 +26,8 @@ #include "llvm/Support/Compiler.h" #include "llvm/Target/TargetData.h" #include + + using namespace clang; using namespace CodeGen; using llvm::dyn_cast; @@ -40,15 +42,14 @@ class CGObjCGNU : public CodeGen::CGObjCRuntime { private: CodeGen::CodeGenModule &CGM; llvm::Module &TheModule; - const llvm::StructType *SelStructTy; - const llvm::Type *SelectorTy; - const llvm::Type *PtrToInt8Ty; + const llvm::PointerType *SelectorTy; + const llvm::PointerType *PtrToInt8Ty; const llvm::Type *IMPTy; - const llvm::Type *IdTy; - const llvm::Type *IntTy; - const llvm::Type *PtrTy; - const llvm::Type *LongTy; - const llvm::Type *PtrToIntTy; + const llvm::PointerType *IdTy; + const llvm::IntegerType *IntTy; + const llvm::PointerType *PtrTy; + const llvm::IntegerType *LongTy; + const llvm::PointerType *PtrToIntTy; std::vector Classes; std::vector Categories; std::vector ConstantStrings; @@ -157,8 +158,10 @@ static std::string SymbolNameForMethod(const std::string &ClassName, const CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) : CGM(cgm), TheModule(CGM.getModule()) { - IntTy = CGM.getTypes().ConvertType(CGM.getContext().IntTy); - LongTy = CGM.getTypes().ConvertType(CGM.getContext().LongTy); + IntTy = cast( + CGM.getTypes().ConvertType(CGM.getContext().IntTy)); + LongTy = cast( + CGM.getTypes().ConvertType(CGM.getContext().LongTy)); Zeros[0] = llvm::ConstantInt::get(LongTy, 0); Zeros[1] = Zeros[0]; @@ -168,21 +171,20 @@ CGObjCGNU::CGObjCGNU(CodeGen::CodeGenModule &cgm) PtrToInt8Ty = llvm::PointerType::getUnqual(llvm::Type::Int8Ty); // Get the selector Type. - SelStructTy = llvm::StructType::get( - PtrToInt8Ty, - PtrToInt8Ty, - NULL); - SelectorTy = llvm::PointerType::getUnqual(SelStructTy); + SelectorTy = cast( + CGM.getTypes().ConvertType(CGM.getContext().getObjCSelType())); + PtrToIntTy = llvm::PointerType::getUnqual(IntTy); PtrTy = PtrToInt8Ty; // Object type llvm::PATypeHolder OpaqueObjTy = llvm::OpaqueType::get(); llvm::Type *OpaqueIdTy = llvm::PointerType::getUnqual(OpaqueObjTy); - IdTy = llvm::StructType::get(OpaqueIdTy, NULL); - llvm::cast(OpaqueObjTy.get())->refineAbstractTypeTo(IdTy); - IdTy = llvm::cast(OpaqueObjTy.get()); - IdTy = llvm::PointerType::getUnqual(IdTy); + llvm::Type *ObjectTy = llvm::StructType::get(OpaqueIdTy, NULL); + llvm::cast(OpaqueObjTy.get())->refineAbstractTypeTo( + ObjectTy); + ObjectTy = llvm::cast(OpaqueObjTy.get()); + IdTy = llvm::PointerType::getUnqual(ObjectTy); // IMP type std::vector IMPArgs; @@ -445,8 +447,7 @@ llvm::Constant *CGObjCGNU::GenerateIvarList( Elements.clear(); - Elements.push_back(llvm::ConstantInt::get( - llvm::cast(IntTy), (int)IvarNames.size())); + Elements.push_back(llvm::ConstantInt::get(IntTy, (int)IvarNames.size())); Elements.push_back(llvm::ConstantArray::get(ObjCIvarArrayTy, Ivars)); // Structure containing array and array count llvm::StructType *ObjCIvarListTy = llvm::StructType::get(IntTy, @@ -489,7 +490,7 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure( NULL); llvm::Constant *Zero = llvm::ConstantInt::get(LongTy, 0); llvm::Constant *NullP = - llvm::ConstantPointerNull::get(llvm::cast(PtrTy)); + llvm::ConstantPointerNull::get(PtrTy); // Fill in the structure std::vector Elements; Elements.push_back(llvm::ConstantExpr::getBitCast(MetaClass, PtrToInt8Ty)); @@ -558,8 +559,7 @@ llvm::Constant *CGObjCGNU::GenerateProtocolList( Elements); Elements.clear(); Elements.push_back(NULLPtr); - Elements.push_back(llvm::ConstantInt::get( - llvm::cast(LongTy), Protocols.size())); + Elements.push_back(llvm::ConstantInt::get(LongTy, Protocols.size())); Elements.push_back(ProtocolArray); return MakeGlobal(ProtocolListTy, Elements, ".objc_protocol_list"); } @@ -763,8 +763,7 @@ void CGObjCGNU::GenerateClass(const ObjCImplementationDecl *OID) { if (!SuperClassName.empty()) { SuperClass = MakeConstantString(SuperClassName, ".super_class_name"); } else { - SuperClass = llvm::ConstantPointerNull::get( - llvm::cast(PtrToInt8Ty)); + SuperClass = llvm::ConstantPointerNull::get(PtrToInt8Ty); } // Empty vector used to construct empty method lists llvm::SmallVector empty; @@ -797,8 +796,18 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { UntypedSelectors.empty()) return NULL; + const llvm::StructType *SelStructTy = dyn_cast( + SelectorTy->getElementType()); + const llvm::Type *SelStructPtrTy = SelectorTy; + bool isSelOpaque = false; + if (SelStructTy == 0) { + SelStructTy = llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, NULL); + SelStructPtrTy = llvm::PointerType::getUnqual(SelStructTy); + isSelOpaque = true; + } + // Name the ObjC types to make the IR a bit easier to read - TheModule.addTypeName(".objc_selector", SelectorTy); + TheModule.addTypeName(".objc_selector", SelStructPtrTy); TheModule.addTypeName(".objc_id", IdTy); TheModule.addTypeName(".objc_imp", IMPTy); @@ -825,7 +834,7 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { // Array of classes, categories, and constant objects llvm::ArrayType *ClassListTy = llvm::ArrayType::get(PtrToInt8Ty, Classes.size() + Categories.size() + 2); - llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelectorTy, + llvm::StructType *SymTabTy = llvm::StructType::get(LongTy, SelStructPtrTy, llvm::Type::Int16Ty, llvm::Type::Int16Ty, ClassListTy, NULL); @@ -860,7 +869,8 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { llvm::Constant *SelectorList = MakeGlobal( llvm::ArrayType::get(SelStructTy, Selectors.size()), Selectors, ".objc_selector_list"); - Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, SelectorTy)); + Elements.push_back(llvm::ConstantExpr::getBitCast(SelectorList, + SelStructPtrTy)); // Now that all of the static selectors exist, create pointers to them. int index = 0; @@ -869,10 +879,16 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { iter != iterEnd; ++iter) { llvm::Constant *Idxs[] = {Zeros[0], llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; - llvm::GlobalVariable *SelPtr = new llvm::GlobalVariable(SelectorTy, true, - llvm::GlobalValue::InternalLinkage, + llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, + true, llvm::GlobalValue::InternalLinkage, llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), ".objc_sel_ptr", &TheModule); + // If selectors are defined as an opaque type, cast the pointer to this + // type. + if (isSelOpaque) { + SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, + llvm::PointerType::getUnqual(SelectorTy)); + } (*iter).second->setAliasee(SelPtr); } for (llvm::StringMap::iterator @@ -880,10 +896,16 @@ llvm::Function *CGObjCGNU::ModuleInitFunction() { iter != iterEnd; iter++) { llvm::Constant *Idxs[] = {Zeros[0], llvm::ConstantInt::get(llvm::Type::Int32Ty, index++), Zeros[0]}; - llvm::GlobalVariable *SelPtr = new llvm::GlobalVariable(SelectorTy, true, + llvm::Constant *SelPtr = new llvm::GlobalVariable(SelStructPtrTy, true, llvm::GlobalValue::InternalLinkage, llvm::ConstantExpr::getGetElementPtr(SelectorList, Idxs, 2), ".objc_sel_ptr", &TheModule); + // If selectors are defined as an opaque type, cast the pointer to this + // type. + if (isSelOpaque) { + SelPtr = llvm::ConstantExpr::getBitCast(SelPtr, + llvm::PointerType::getUnqual(SelectorTy)); + } (*iter).second->setAliasee(SelPtr); } // Number of classes defined. -- GitLab From 6d61c3e6df17a43bd1861437b839571263d4c948 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 05:22:43 +0000 Subject: [PATCH 271/682] make -print-stats print stats about the amount of the SLoc address space we used up. Some interesting data: For c99-intconst-1.c: 6912762 SLocEntry's allocated, 25592386B of Sloc address space used. For cocoa.h: 26469 SLocEntry's allocated, 10278752B of Sloc address space used. For carbon.h: 27364 SLocEntry's allocated, 12398141B of Sloc address space used. Clearly 2G of sloc address space should be enough for anyone?! llvm-svn: 63093 --- clang/lib/Basic/SourceManager.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 6c82b9bf2e85..9b509a568452 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -576,8 +576,9 @@ const char *SourceManager::getSourceName(SourceLocation Loc) const { void SourceManager::PrintStats() const { llvm::cerr << "\n*** Source Manager Stats:\n"; llvm::cerr << FileInfos.size() << " files mapped, " << MemBufferInfos.size() - << " mem buffers mapped, " << SLocEntryTable.size() - << " SLocEntry's allocated.\n"; + << " mem buffers mapped.\n"; + llvm::cerr << SLocEntryTable.size() << " SLocEntry's allocated, " + << NextOffset << "B of Sloc address space used.\n"; unsigned NumLineNumsComputed = 0; unsigned NumFileBytesMapped = 0; -- GitLab From bf648a3a639b4a2b4c50bee3575cd53ac04882fc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 05:34:03 +0000 Subject: [PATCH 272/682] Fix a bug that I noticed by inspection. llvm-svn: 63094 --- clang/lib/Lex/PPDirectives.cpp | 1 + clang/test/Preprocessor/skipping_unclean.c | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 clang/test/Preprocessor/skipping_unclean.c diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index 4bf012c1b119..d277ec9dd47c 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -219,6 +219,7 @@ void Preprocessor::SkipExcludedConditionalBlock(SourceLocation IfTokenLoc, } memcpy(Directive, &DirectiveStr[0], IdLen); Directive[IdLen] = 0; + FirstChar = Directive[0]; } if (FirstChar == 'i' && Directive[1] == 'f') { diff --git a/clang/test/Preprocessor/skipping_unclean.c b/clang/test/Preprocessor/skipping_unclean.c new file mode 100644 index 000000000000..9efdd648b48f --- /dev/null +++ b/clang/test/Preprocessor/skipping_unclean.c @@ -0,0 +1,9 @@ +// RUN: clang -E %s | grep bark + +#if 0 +blah +#\ +else +bark +#endif + -- GitLab From dd62885f40738fc25925c02e03e0e19437ec2195 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 27 Jan 2009 05:34:28 +0000 Subject: [PATCH 273/682] Use string comparison rather than '=='. llvm-svn: 63095 --- clang/utils/ccc-analyzer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/utils/ccc-analyzer b/clang/utils/ccc-analyzer index a3b7851247ed..2a9a99367d90 100755 --- a/clang/utils/ccc-analyzer +++ b/clang/utils/ccc-analyzer @@ -49,7 +49,7 @@ sub ProcessClangFailure { mkpath $Dir; my $prefix = "clang_crash"; - if ($ErrorType == $ParserRejects) { $prefix = "clang_parser_rejects"; } + if ($ErrorType eq $ParserRejects) { $prefix = "clang_parser_rejects"; } # Generate the preprocessed file with cc (i.e., gcc). my ($PPH, $PPFile) = tempfile( $prefix . "_XXXXXX", -- GitLab From c360bf2e4868ec6455cea10e26764456098adc5e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 06:27:13 +0000 Subject: [PATCH 274/682] rename getFullFilePos -> getFileOffset. llvm-svn: 63097 --- clang/Driver/CacheTokens.cpp | 2 +- clang/Driver/RewriteMacros.cpp | 12 ++++++------ clang/include/clang/Basic/SourceManager.h | 9 ++++----- clang/lib/Rewrite/HTMLRewrite.cpp | 8 ++++---- 4 files changed, 15 insertions(+), 16 deletions(-) diff --git a/clang/Driver/CacheTokens.cpp b/clang/Driver/CacheTokens.cpp index 5409a64e8bcd..c64797ec3835 100644 --- a/clang/Driver/CacheTokens.cpp +++ b/clang/Driver/CacheTokens.cpp @@ -159,7 +159,7 @@ void PTHWriter::EmitToken(const Token& T) { else Emit32(ResolveID(T.getIdentifierInfo())); - Emit32(PP.getSourceManager().getFullFilePos(T.getLocation())); + Emit32(PP.getSourceManager().getFileOffset(T.getLocation())); } namespace { diff --git a/clang/Driver/RewriteMacros.cpp b/clang/Driver/RewriteMacros.cpp index 6ad4a7160cdc..809a3b510b22 100644 --- a/clang/Driver/RewriteMacros.cpp +++ b/clang/Driver/RewriteMacros.cpp @@ -130,13 +130,13 @@ void clang::RewriteMacrosInInput(Preprocessor &PP,const std::string &InFileName, const IdentifierInfo *II = RawTokens[CurRawTok].getIdentifierInfo(); if (!strcmp(II->getName(), "warning")) { // Comment out #warning. - RB.InsertTextAfter(SM.getFullFilePos(RawTok.getLocation()), "//", 2); + RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//", 2); } else if (!strcmp(II->getName(), "pragma") && RawTokens[CurRawTok+1].is(tok::identifier) && !strcmp(RawTokens[CurRawTok+1].getIdentifierInfo()->getName(), "mark")){ // Comment out #pragma mark. - RB.InsertTextAfter(SM.getFullFilePos(RawTok.getLocation()), "//", 2); + RB.InsertTextAfter(SM.getFileOffset(RawTok.getLocation()), "//", 2); } } @@ -150,8 +150,8 @@ void clang::RewriteMacrosInInput(Preprocessor &PP,const std::string &InFileName, // Okay, both tokens are from the same file. Get their offsets from the // start of the file. - unsigned PPOffs = SM.getFullFilePos(PPLoc); - unsigned RawOffs = SM.getFullFilePos(RawTok.getLocation()); + unsigned PPOffs = SM.getFileOffset(PPLoc); + unsigned RawOffs = SM.getFileOffset(RawTok.getLocation()); // If the offsets are the same and the token kind is the same, ignore them. if (PPOffs == RawOffs && isSameToken(RawTok, PPTok)) { @@ -173,7 +173,7 @@ void clang::RewriteMacrosInInput(Preprocessor &PP,const std::string &InFileName, EndPos = RawOffs+RawTok.getLength(); RawTok = GetNextRawTok(RawTokens, CurRawTok, true); - RawOffs = SM.getFullFilePos(RawTok.getLocation()); + RawOffs = SM.getFileOffset(RawTok.getLocation()); if (RawTok.is(tok::comment)) { // Skip past the comment. @@ -197,7 +197,7 @@ void clang::RewriteMacrosInInput(Preprocessor &PP,const std::string &InFileName, Expansion += ' ' + PP.getSpelling(PPTok); PP.Lex(PPTok); PPLoc = SM.getInstantiationLoc(PPTok.getLocation()); - PPOffs = SM.getFullFilePos(PPLoc); + PPOffs = SM.getFileOffset(PPLoc); } Expansion += ' '; RB.InsertTextBefore(InsertPos, &Expansion[0], Expansion.size()); diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index 84aabe1f3103..dab3badea291 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -468,11 +468,10 @@ public: return getDecomposedSpellingLocSlowCase(E, Offset); } - /// getFullFilePos - This (efficient) method returns the offset from the start - /// of the file that the specified spelling SourceLocation represents. This - /// returns the location of the actual character data, not the instantiation - /// position. - unsigned getFullFilePos(SourceLocation SpellingLoc) const { + /// getFileOffset - This method returns the offset from the start + /// of the file that the specified SourceLocation represents. This is not very + /// meaningful for a macro ID. + unsigned getFileOffset(SourceLocation SpellingLoc) const { return getDecomposedLoc(SpellingLoc).second; } diff --git a/clang/lib/Rewrite/HTMLRewrite.cpp b/clang/lib/Rewrite/HTMLRewrite.cpp index b5f0fc395118..6e5d1c32b11c 100644 --- a/clang/lib/Rewrite/HTMLRewrite.cpp +++ b/clang/lib/Rewrite/HTMLRewrite.cpp @@ -36,8 +36,8 @@ void html::HighlightRange(Rewriter &R, SourceLocation B, SourceLocation E, FileID FID = SM.getFileID(B); assert(SM.getFileID(E) == FID && "B/E not in the same file!"); - unsigned BOffset = SM.getFullFilePos(B); - unsigned EOffset = SM.getFullFilePos(E); + unsigned BOffset = SM.getFileOffset(B); + unsigned EOffset = SM.getFileOffset(E); // Include the whole end token in the range. EOffset += Lexer::MeasureTokenLength(E, R.getSourceMgr()); @@ -359,7 +359,7 @@ void html::SyntaxHighlight(Rewriter &R, FileID FID, Preprocessor &PP) { while (Tok.isNot(tok::eof)) { // Since we are lexing unexpanded tokens, all tokens are from the main // FileID. - unsigned TokOffs = SourceMgr.getFullFilePos(Tok.getLocation()); + unsigned TokOffs = SourceMgr.getFileOffset(Tok.getLocation()); unsigned TokLen = Tok.getLength(); switch (Tok.getKind()) { default: break; @@ -397,7 +397,7 @@ void html::SyntaxHighlight(Rewriter &R, FileID FID, Preprocessor &PP) { unsigned TokEnd = TokOffs+TokLen; L.LexFromRawLexer(Tok); while (!Tok.isAtStartOfLine() && Tok.isNot(tok::eof)) { - TokEnd = SourceMgr.getFullFilePos(Tok.getLocation())+Tok.getLength(); + TokEnd = SourceMgr.getFileOffset(Tok.getLocation())+Tok.getLength(); L.LexFromRawLexer(Tok); } -- GitLab From f1ca7d3e02e0fb4d5fa6ed56459a31776e82a605 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 07:57:44 +0000 Subject: [PATCH 275/682] Introduce a new PresumedLoc class to represent the concept of a location as reported to the user and as manipulated by #line. This is what __FILE__, __INCLUDE_LEVEL__, diagnostics and other things should follow (but not dependency generation!). This patch also includes several cleanups along the way: - SourceLocation now has a dump method, and several other places that did similar things now use it. - I cleaned up some code in AnalysisConsumer, but it should probably be simplified further now that NamedDecl is better. - TextDiagnosticPrinter is now simplified and cleaned up a bit. This patch is a prerequisite for #line, but does not actually provide any #line functionality. llvm-svn: 63098 --- clang/Driver/AnalysisConsumer.cpp | 18 ++- clang/Driver/DependencyFile.cpp | 11 +- clang/Driver/PrintPreprocessedOutput.cpp | 7 +- clang/include/clang/Basic/SourceLocation.h | 57 +++++++-- clang/include/clang/Basic/SourceManager.h | 20 ++- .../clang/Driver/TextDiagnosticPrinter.h | 4 +- clang/lib/AST/StmtDumper.cpp | 27 ++-- clang/lib/Analysis/LiveVariables.cpp | 10 +- clang/lib/Basic/SourceLocation.cpp | 52 ++++---- clang/lib/Basic/SourceManager.cpp | 29 +++-- clang/lib/Driver/TextDiagnosticPrinter.cpp | 118 ++++++++++-------- clang/lib/Lex/PPMacroExpansion.cpp | 34 +++-- clang/lib/Lex/Preprocessor.cpp | 12 +- clang/test/Preprocessor/dumptokens_phyloc.c | 2 +- 14 files changed, 230 insertions(+), 171 deletions(-) diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp index 4dab9c7b4bc1..171ffbf2df66 100644 --- a/clang/Driver/AnalysisConsumer.cpp +++ b/clang/Driver/AnalysisConsumer.cpp @@ -257,18 +257,14 @@ case PD_##NAME: C.PD.reset(CREATEFN(C.HTMLDir, C.PP, C.PPF)); break; DisplayedFunction = true; - if (FunctionDecl *FD = dyn_cast(getCodeDecl())) { + // FIXME: Is getCodeDecl() always a named decl? + if (isa(getCodeDecl()) || + isa(getCodeDecl())) { + NamedDecl *ND = cast(getCodeDecl()); + SourceManager &SM = getContext().getSourceManager(); llvm::cerr << "ANALYZE: " - << getContext().getSourceManager().getSourceName(FD->getLocation()) - << ' ' - << FD->getIdentifier()->getName() - << '\n'; - } - else if (ObjCMethodDecl *MD = dyn_cast(getCodeDecl())) { - llvm::cerr << "ANALYZE (ObjC Method): " - << getContext().getSourceManager().getSourceName(MD->getLocation()) - << " '" - << MD->getSelector().getAsString() << "'\n"; + << SM.getPresumedLoc(ND->getLocation()).getFilename() + << ' ' << ND->getNameAsString() << '\n'; } } diff --git a/clang/Driver/DependencyFile.cpp b/clang/Driver/DependencyFile.cpp index 282164fdd6cc..0d4ee91f01bb 100644 --- a/clang/Driver/DependencyFile.cpp +++ b/clang/Driver/DependencyFile.cpp @@ -13,6 +13,7 @@ #include "clang.h" #include "clang/Basic/SourceManager.h" +#include "clang/Basic/FileManager.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PPCallbacks.h" #include "clang/Lex/DirectoryLookup.h" @@ -167,8 +168,14 @@ void DependencyFileCallback::FileChanged(SourceLocation Loc, SrcMgr::CharacteristicKind FileType) { if (Reason != PPCallbacks::EnterFile) return; - - const char *Filename = PP->getSourceManager().getSourceName(Loc); + + // Depedency generation really does want to go all the way to the file entry + // for a source location to find out what is depended on. We do not want + // #line markers to affect dependency generation! + SourceManager &SM = PP->getSourceManager(); + + FileID FID = SM.getFileID(SM.getInstantiationLoc(Loc)); + const char *Filename = SM.getFileEntryForID(FID)->getName(); if (!FileMatchesDepCriteria(Filename, FileType)) return; diff --git a/clang/Driver/PrintPreprocessedOutput.cpp b/clang/Driver/PrintPreprocessedOutput.cpp index 32b8a8b2792c..5c4a140fa9ae 100644 --- a/clang/Driver/PrintPreprocessedOutput.cpp +++ b/clang/Driver/PrintPreprocessedOutput.cpp @@ -150,7 +150,7 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, // #include directive was at. SourceManager &SourceMgr = PP.getSourceManager(); if (Reason == PPCallbacks::EnterFile) { - MoveToLine(SourceMgr.getIncludeLoc(Loc)); + MoveToLine(SourceMgr.getPresumedLoc(Loc).getIncludeLoc()); } else if (Reason == PPCallbacks::SystemHeaderPragma) { MoveToLine(Loc); @@ -165,7 +165,7 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, if (DisableLineMarkers) return; CurFilename.clear(); - CurFilename += SourceMgr.getSourceName(Loc); + CurFilename += SourceMgr.getPresumedLoc(Loc).getFilename(); Lexer::Stringify(CurFilename); FileType = NewFileType; @@ -540,7 +540,8 @@ void clang::DoPrintPreprocessedInput(Preprocessor &PP, const SourceManager &SourceMgr = PP.getSourceManager(); do PP.Lex(Tok); while (Tok.isNot(tok::eof) && Tok.getLocation().isFileID() && - !strcmp(SourceMgr.getSourceName(Tok.getLocation()), "")); + !strcmp(SourceMgr.getPresumedLoc(Tok.getLocation()).getFilename(), + "")); while (1) { diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index 6da9a87ee3ac..31fbc0218bbb 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -133,6 +133,8 @@ public: /// ReadVal - Read a SourceLocation object from Bitcode. static SourceLocation ReadVal(llvm::Deserializer& D); + + void dump(const SourceManager &SM) const; }; inline bool operator==(const SourceLocation &LHS, const SourceLocation &RHS) { @@ -182,13 +184,13 @@ public: explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM) : SourceLocation(Loc), SrcMgr(&SM) {} - SourceManager& getManager() { - assert (SrcMgr && "SourceManager is NULL."); + SourceManager &getManager() { + assert(SrcMgr && "SourceManager is NULL."); return *SrcMgr; } - const SourceManager& getManager() const { - assert (SrcMgr && "SourceManager is NULL."); + const SourceManager &getManager() const { + assert(SrcMgr && "SourceManager is NULL."); return *SrcMgr; } @@ -196,7 +198,6 @@ public: FullSourceLoc getInstantiationLoc() const; FullSourceLoc getSpellingLoc() const; - FullSourceLoc getIncludeLoc() const; unsigned getLineNumber() const; unsigned getColumnNumber() const; @@ -211,13 +212,11 @@ public: const llvm::MemoryBuffer* getBuffer() const; - const char* getSourceName() const; - bool isInSystemHeader() const; /// Prints information about this FullSourceLoc to stderr. Useful for /// debugging. - void dump() const; + void dump() const { SourceLocation::dump(*SrcMgr); } friend inline bool operator==(const FullSourceLoc &LHS, const FullSourceLoc &RHS) { @@ -231,7 +230,47 @@ public: } }; - + +/// PresumedLoc - This class represents an unpacked "presumed" location which +/// can be presented to the user. A 'presumed' location can be modified by +/// #line and GNU line marker directives and is always the instantiation point +/// of a normal location. +/// +/// You can get a PresumedLoc from a SourceLocation with SourceManager. +class PresumedLoc { + const char *Filename; + unsigned Line, Col; + SourceLocation IncludeLoc; +public: + PresumedLoc() : Filename(0) {} + PresumedLoc(const char *FN, unsigned Ln, unsigned Co, SourceLocation IL) + : Filename(FN), Line(Ln), Col(Co), IncludeLoc(IL) { + } + + /// isInvalid - Return true if this object is invalid or uninitialized. This + /// occurs when created with invalid source locations or when walking off + /// the top of a #include stack. + bool isInvalid() const { return Filename == 0; } + bool isValid() const { return Filename != 0; } + + /// getFilename - Return the presumed filename of this location. This can be + /// affected by #line etc. + const char *getFilename() const { return Filename; } + + /// getLine - Return the presumed line number of this location. This can be + /// affected by #line etc. + unsigned getLine() const { return Line; } + + /// getColumn - Return the presumed column number of this location. This can + /// not be affected by #line, but is packaged here for convenience. + unsigned getColumn() const { return Col; } + + /// getIncludeLoc - Return the presumed include location of this location. + /// This can be affected by GNU linemarker directives. + SourceLocation getIncludeLoc() const { return IncludeLoc; } +}; + + } // end namespace clang namespace llvm { diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index dab3badea291..a63ef7903728 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -404,14 +404,6 @@ public: return SourceLocation::getFileLoc(FileOffset); } - /// getIncludeLoc - Return the location of the #include for the specified - /// SourceLocation. If this is a macro expansion, this transparently figures - /// out which file includes the file being expanded into. - SourceLocation getIncludeLoc(SourceLocation ID) const { - return getSLocEntry(getFileID(getInstantiationLoc(ID))) - .getFile().getIncludeLoc(); - } - /// Given a SourceLocation object, return the instantiation location /// referenced by the ID. SourceLocation getInstantiationLoc(SourceLocation Loc) const { @@ -518,10 +510,14 @@ public: return getSLocEntry(FID).getFile().getFileCharacteristic(); } - /// getSourceName - This method returns the name of the file or buffer that - /// the SourceLocation specifies. This can be modified with #line directives, - /// etc. - const char *getSourceName(SourceLocation Loc) const; + /// getPresumedLoc - This method returns the "presumed" location of a + /// SourceLocation specifies. A "presumed location" can be modified by #line + /// or GNU line marker directives. This provides a view on the data that a + /// user should see in diagnostics, for example. + /// + /// Note that a presumed location is always given as the instantiation point + /// of an instantiation location, not at the spelling location. + PresumedLoc getPresumedLoc(SourceLocation Loc) const; diff --git a/clang/include/clang/Driver/TextDiagnosticPrinter.h b/clang/include/clang/Driver/TextDiagnosticPrinter.h index 550c337b50b1..b49094dcb1e9 100644 --- a/clang/include/clang/Driver/TextDiagnosticPrinter.h +++ b/clang/include/clang/Driver/TextDiagnosticPrinter.h @@ -26,7 +26,7 @@ namespace clang { class SourceManager; class TextDiagnosticPrinter : public DiagnosticClient { - FullSourceLoc LastWarningLoc; + SourceLocation LastWarningLoc; FullSourceLoc LastLoc; llvm::raw_ostream &OS; bool ShowColumn; @@ -36,7 +36,7 @@ public: bool caretDiagnistics = true) : OS(os), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics) {} - void PrintIncludeStack(FullSourceLoc Pos); + void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM); void HighlightRange(const SourceRange &R, const SourceManager& SrcMgr, diff --git a/clang/lib/AST/StmtDumper.cpp b/clang/lib/AST/StmtDumper.cpp index 0a7de350d081..83313ed9be94 100644 --- a/clang/lib/AST/StmtDumper.cpp +++ b/clang/lib/AST/StmtDumper.cpp @@ -153,21 +153,26 @@ namespace { void StmtDumper::DumpLocation(SourceLocation Loc) { SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); + + if (SpellingLoc.isInvalid()) { + fprintf(stderr, ""); + return; + } // The general format we print out is filename:line:col, but we drop pieces // that haven't changed since the last loc printed. - const char *Filename = SM->getSourceName(SpellingLoc); - unsigned LineNo = SM->getLineNumber(SpellingLoc); - unsigned ColNo = SM->getColumnNumber(SpellingLoc); - if (strcmp(Filename, LastLocFilename) != 0) { - fprintf(stderr, "%s:%u:%u", Filename, LineNo, ColNo); - LastLocFilename = Filename; - LastLocLine = LineNo; - } else if (LineNo != LastLocLine) { - fprintf(stderr, "line:%u:%u", LineNo, ColNo); - LastLocLine = LineNo; + PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); + + if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { + fprintf(stderr, "%s:%u:%u", PLoc.getFilename(), PLoc.getLine(), + PLoc.getColumn()); + LastLocFilename = PLoc.getFilename(); + LastLocLine = PLoc.getLine(); + } else if (PLoc.getLine() != LastLocLine) { + fprintf(stderr, "line:%u:%u", PLoc.getLine(), PLoc.getColumn()); + LastLocLine = PLoc.getLine(); } else { - fprintf(stderr, "col:%u", ColNo); + fprintf(stderr, "col:%u", PLoc.getColumn()); } } diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index ac0aa9ba8c63..4c86d44e4db6 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -358,13 +358,9 @@ void LiveVariables::dumpLiveness(const ValTy& V, SourceManager& SM) const { for (AnalysisDataTy::decl_iterator I = AD.begin_decl(), E = AD.end_decl(); I!=E; ++I) if (V.getDeclBit(I->second)) { - SourceLocation SpellingLoc = SM.getSpellingLoc(I->first->getLocation()); - - fprintf(stderr, " %s <%s:%u:%u>\n", - I->first->getIdentifier()->getName(), - SM.getSourceName(SpellingLoc), - SM.getLineNumber(SpellingLoc), - SM.getColumnNumber(SpellingLoc)); + fprintf(stderr, " %s <", I->first->getIdentifier()->getName()); + I->first->getLocation().dump(SM); + fprintf(stderr, ">\n"); } } diff --git a/clang/lib/Basic/SourceLocation.cpp b/clang/lib/Basic/SourceLocation.cpp index f0c8274de91f..5d484721bd4e 100644 --- a/clang/lib/Basic/SourceLocation.cpp +++ b/clang/lib/Basic/SourceLocation.cpp @@ -26,6 +26,29 @@ SourceLocation SourceLocation::ReadVal(llvm::Deserializer& D) { return SourceLocation::getFromRawEncoding(D.ReadInt()); } +void SourceLocation::dump(const SourceManager &SM) const { + if (!isValid()) { + fprintf(stderr, ""); + return; + } + + if (isFileID()) { + PresumedLoc PLoc = SM.getPresumedLoc(*this); + + // The instantiation and spelling pos is identical for file locs. + fprintf(stderr, "%s:%d:%d", + PLoc.getFilename(), PLoc.getLine(), PLoc.getColumn()); + return; + } + + SM.getInstantiationLoc(*this).dump(SM); + + fprintf(stderr, " "); +} + + void SourceRange::Emit(llvm::Serializer& S) const { B.Emit(S); E.Emit(S); @@ -53,11 +76,6 @@ FullSourceLoc FullSourceLoc::getSpellingLoc() const { return FullSourceLoc(SrcMgr->getSpellingLoc(*this), *SrcMgr); } -FullSourceLoc FullSourceLoc::getIncludeLoc() const { - assert(isValid()); - return FullSourceLoc(SrcMgr->getIncludeLoc(*this), *SrcMgr); -} - unsigned FullSourceLoc::getLineNumber() const { assert(isValid()); return SrcMgr->getLineNumber(*this); @@ -89,11 +107,6 @@ unsigned FullSourceLoc::getSpellingColumnNumber() const { return SrcMgr->getSpellingColumnNumber(*this); } -const char* FullSourceLoc::getSourceName() const { - assert(isValid()); - return SrcMgr->getSourceName(*this); -} - bool FullSourceLoc::isInSystemHeader() const { assert(isValid()); return SrcMgr->isInSystemHeader(*this); @@ -109,22 +122,3 @@ const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const { return SrcMgr->getBuffer(SrcMgr->getFileID(*this)); } -void FullSourceLoc::dump() const { - if (!isValid()) { - fprintf(stderr, "Invalid Loc\n"); - return; - } - - if (isFileID()) { - // The instantiation and spelling pos is identical for file locs. - fprintf(stderr, "File Loc from '%s': %d: %d\n", - getSourceName(), getInstantiationLineNumber(), - getInstantiationColumnNumber()); - } else { - fprintf(stderr, "Macro Loc (\n Spelling: "); - getSpellingLoc().dump(); - fprintf(stderr, " Instantiation: "); - getInstantiationLoc().dump(); - fprintf(stderr, ")\n"); - } -} diff --git a/clang/lib/Basic/SourceManager.cpp b/clang/lib/Basic/SourceManager.cpp index 9b509a568452..88292cd42bd9 100644 --- a/clang/lib/Basic/SourceManager.cpp +++ b/clang/lib/Basic/SourceManager.cpp @@ -552,18 +552,31 @@ unsigned SourceManager::getLineNumber(SourceLocation Loc) const { return LineNo; } -/// getSourceName - This method returns the name of the file or buffer that -/// the SourceLocation specifies. This can be modified with #line directives, -/// etc. -const char *SourceManager::getSourceName(SourceLocation Loc) const { - if (Loc.isInvalid()) return ""; +/// getPresumedLoc - This method returns the "presumed" location of a +/// SourceLocation specifies. A "presumed location" can be modified by #line +/// or GNU line marker directives. This provides a view on the data that a +/// user should see in diagnostics, for example. +/// +/// Note that a presumed location is always given as the instantiation point +/// of an instantiation location, not at the spelling location. +PresumedLoc SourceManager::getPresumedLoc(SourceLocation Loc) const { + if (Loc.isInvalid()) return PresumedLoc(); + + // Presumed locations are always for instantiation points. + Loc = getInstantiationLoc(Loc); - const SrcMgr::ContentCache *C = - getSLocEntry(getFileID(getSpellingLoc(Loc))).getFile().getContentCache(); + // FIXME: Could just decompose Loc once! + const SrcMgr::FileInfo &FI = getSLocEntry(getFileID(Loc)).getFile(); + const SrcMgr::ContentCache *C = FI.getContentCache(); + // To get the source name, first consult the FileEntry (if one exists) before // the MemBuffer as this will avoid unnecessarily paging in the MemBuffer. - return C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); + const char *Filename = + C->Entry ? C->Entry->getName() : C->getBuffer()->getBufferIdentifier(); + + return PresumedLoc(Filename, getLineNumber(Loc), getColumnNumber(Loc), + FI.getIncludeLoc()); } //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp index 71a5e401075b..b19d61c160f2 100644 --- a/clang/lib/Driver/TextDiagnosticPrinter.cpp +++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp @@ -15,28 +15,26 @@ #include "clang/Basic/SourceManager.h" #include "clang/Lex/Lexer.h" #include "llvm/Support/raw_ostream.h" -#include "llvm/Support/MemoryBuffer.h" #include "llvm/ADT/SmallString.h" using namespace clang; void TextDiagnosticPrinter:: -PrintIncludeStack(FullSourceLoc Pos) { - if (Pos.isInvalid()) return; +PrintIncludeStack(SourceLocation Loc, const SourceManager &SM) { + if (Loc.isInvalid()) return; - Pos = Pos.getInstantiationLoc(); + PresumedLoc PLoc = SM.getPresumedLoc(Loc); // Print out the other include frames first. - PrintIncludeStack(Pos.getIncludeLoc()); - unsigned LineNo = Pos.getLineNumber(); + PrintIncludeStack(PLoc.getIncludeLoc(), SM); - OS << "In file included from " << Pos.getSourceName() - << ':' << LineNo << ":\n"; + OS << "In file included from " << PLoc.getFilename() + << ':' << PLoc.getLine() << ":\n"; } /// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s) /// any characters in LineNo that intersect the SourceRange. void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, - const SourceManager &SourceMgr, + const SourceManager &SM, unsigned LineNo, FileID FID, std::string &CaretLine, const std::string &SourceLine) { @@ -44,23 +42,21 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, "Expect a correspondence between source and caret line!"); if (!R.isValid()) return; - SourceLocation InstantiationStart = - SourceMgr.getInstantiationLoc(R.getBegin()); - unsigned StartLineNo = SourceMgr.getLineNumber(InstantiationStart); - if (StartLineNo > LineNo || - SourceMgr.getFileID(InstantiationStart) != FID) + SourceLocation Begin = SM.getInstantiationLoc(R.getBegin()); + SourceLocation End = SM.getInstantiationLoc(R.getEnd()); + + unsigned StartLineNo = SM.getLineNumber(Begin); + if (StartLineNo > LineNo || SM.getFileID(Begin) != FID) return; // No intersection. - SourceLocation InstantiationEnd = SourceMgr.getInstantiationLoc(R.getEnd()); - unsigned EndLineNo = SourceMgr.getLineNumber(InstantiationEnd); - if (EndLineNo < LineNo || - SourceMgr.getFileID(InstantiationEnd) != FID) + unsigned EndLineNo = SM.getLineNumber(End); + if (EndLineNo < LineNo || SM.getFileID(End) != FID) return; // No intersection. // Compute the column number of the start. unsigned StartColNo = 0; if (StartLineNo == LineNo) { - StartColNo = SourceMgr.getInstantiationColumnNumber(R.getBegin()); + StartColNo = SM.getColumnNumber(Begin); if (StartColNo) --StartColNo; // Zero base the col #. } @@ -72,12 +68,12 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, // Compute the column number of the end. unsigned EndColNo = CaretLine.size(); if (EndLineNo == LineNo) { - EndColNo = SourceMgr.getInstantiationColumnNumber(R.getEnd()); + EndColNo = SM.getColumnNumber(End); if (EndColNo) { --EndColNo; // Zero base the col #. // Add in the length of the token, so that we cover multi-char tokens. - EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr); + EndColNo += Lexer::MeasureTokenLength(End, SM); } else { EndColNo = CaretLine.size(); } @@ -99,39 +95,25 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) { - unsigned LineNo = 0, ColNo = 0; - FileID FID; - const char *LineStart = 0, *LineEnd = 0; - const FullSourceLoc &Pos = Info.getLocation(); + const SourceManager &SM = Info.getLocation().getManager(); + unsigned ColNo = 0; - if (Pos.isValid()) { - FullSourceLoc LPos = Pos.getInstantiationLoc(); - FID = LPos.getFileID(); - LineNo = LPos.getLineNumber(); + // If the location is specified, print out a file/line/col and include trace + // if enabled. + if (Info.getLocation().isValid()) { + PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation()); + unsigned LineNo = PLoc.getLine(); // First, if this diagnostic is not in the main file, print out the // "included from" lines. - if (LastWarningLoc != LPos.getIncludeLoc()) { - LastWarningLoc = LPos.getIncludeLoc(); - PrintIncludeStack(LastWarningLoc); + if (LastWarningLoc != PLoc.getIncludeLoc()) { + LastWarningLoc = PLoc.getIncludeLoc(); + PrintIncludeStack(LastWarningLoc, SM); } - // Compute the column number. Rewind from the current position to the start - // of the line. - ColNo = LPos.getColumnNumber(); - const char *TokInstantiationPtr = LPos.getCharacterData(); - LineStart = TokInstantiationPtr-ColNo+1; // Column # is 1-based - - // Compute the line end. Scan forward from the error position to the end of - // the line. - const llvm::MemoryBuffer *Buffer = LPos.getBuffer(); - const char *BufEnd = Buffer->getBufferEnd(); - LineEnd = TokInstantiationPtr; - while (LineEnd != BufEnd && - *LineEnd != '\n' && *LineEnd != '\r') - ++LineEnd; - - OS << Buffer->getBufferIdentifier() << ':' << LineNo << ':'; + // Compute the column number. + ColNo = PLoc.getColumn(); + OS << PLoc.getFilename() << ':' << LineNo << ':'; if (ColNo && ShowColumn) OS << ColNo << ':'; OS << ' '; @@ -149,21 +131,49 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, OS.write(OutStr.begin(), OutStr.size()); OS << '\n'; - if (CaretDiagnostics && Pos.isValid() && - ((LastLoc != Pos) || Info.getNumRanges())) { + // If caret diagnostics are enabled and we have location, we want to emit the + // caret. However, we only do this if the location moved from the last + // diagnostic, or if the diagnostic has ranges. We don't want to emit the + // same caret multiple times if one loc has multiple diagnostics. + if (CaretDiagnostics && Info.getLocation().isValid() && + ((LastLoc != Info.getLocation()) || Info.getNumRanges())) { // Cache the LastLoc, it allows us to omit duplicate source/caret spewage. - LastLoc = Pos; + LastLoc = Info.getLocation(); + + // Inspect the actual instantiation point of the diagnostic, we don't care + // about presumed locations anymore. + SourceLocation ILoc = SM.getInstantiationLoc(Info.getLocation()); + + // Get the file and line that we want to highlight. We only draw ranges + // that intersect this. + FileID ILocFID = SM.getFileID(ILoc); + unsigned LineNo = SM.getLineNumber(ILoc); - // Get the line of the source file. + // Get the line of the source file. Scan from the location backward and + // forward to find the start/end of the line. + + // Rewind from the current position to the start of the line. + const char *TokInstantiationPtr = SM.getCharacterData(ILoc); + const char *LineStart = TokInstantiationPtr-ColNo+1; // Column # is 1-based. + + // Compute the line end. Scan forward from the error position to the end of + // the line. + const char *BufEnd = SM.getBufferData(ILocFID).second; + const char *LineEnd = TokInstantiationPtr; + while (LineEnd != BufEnd && + *LineEnd != '\n' && *LineEnd != '\r') + ++LineEnd; + + // Copy the line of code into an std::string for ease of manipulation. std::string SourceLine(LineStart, LineEnd); // Create a line for the caret that is filled with spaces that is the same // length as the line of source code. std::string CaretLine(LineEnd-LineStart, ' '); - + // Highlight all of the characters covered by Ranges with ~ characters. for (unsigned i = 0; i != Info.getNumRanges(); ++i) - HighlightRange(Info.getRange(i), Pos.getManager(), LineNo, FID, + HighlightRange(Info.getRange(i), SM, LineNo, ILocFID, CaretLine, SourceLine); // Next, insert the caret itself. diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index 8eada6003d81..a517b1d4f56e 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -454,28 +454,37 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { Tok.clearFlag(Token::NeedsCleaning); if (II == Ident__LINE__) { + // C99 6.10.8: "__LINE__: The presumed line number (within the current + // source file) of the current source line (an integer constant)". This can + // be affected by #line. + PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); + // __LINE__ expands to a simple numeric value. Add a space after it so that // it will tokenize as a number (and not run into stuff after it in the temp // buffer). - sprintf(TmpBuffer, "%u ", - SourceMgr.getInstantiationLineNumber(Tok.getLocation())); + sprintf(TmpBuffer, "%u ", PLoc.getLine()); unsigned Length = strlen(TmpBuffer)-1; Tok.setKind(tok::numeric_constant); CreateString(TmpBuffer, Length+1, Tok, Tok.getLocation()); Tok.setLength(Length); // Trim off space. } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) { - SourceLocation Loc = Tok.getLocation(); + // C99 6.10.8: "__FILE__: The presumed name of the current source file (a + // character string literal)". This can be affected by #line. + PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); + + // __BASE_FILE__ is a GNU extension that returns the top of the presumed + // #include stack instead of the current file. if (II == Ident__BASE_FILE__) { Diag(Tok, diag::ext_pp_base_file); - SourceLocation NextLoc = SourceMgr.getIncludeLoc(Loc); + SourceLocation NextLoc = PLoc.getIncludeLoc(); while (NextLoc.isValid()) { - Loc = NextLoc; - NextLoc = SourceMgr.getIncludeLoc(Loc); + PLoc = SourceMgr.getPresumedLoc(NextLoc); + NextLoc = PLoc.getIncludeLoc(); } } // Escape this filename. Turn '\' -> '\\' '"' -> '\"' - std::string FN =SourceMgr.getSourceName(SourceMgr.getInstantiationLoc(Loc)); + std::string FN = PLoc.getFilename(); FN = '"' + Lexer::Stringify(FN) + '"'; Tok.setKind(tok::string_literal); CreateString(&FN[0], FN.size(), Tok, Tok.getLocation()); @@ -496,11 +505,14 @@ void Preprocessor::ExpandBuiltinMacro(Token &Tok) { } else if (II == Ident__INCLUDE_LEVEL__) { Diag(Tok, diag::ext_pp_include_level); - // Compute the include depth of this token. + // Compute the presumed include depth of this token. This can be affected + // by GNU line markers. unsigned Depth = 0; - SourceLocation Loc = SourceMgr.getIncludeLoc(Tok.getLocation()); - for (; Loc.isValid(); ++Depth) - Loc = SourceMgr.getIncludeLoc(Loc); + + PresumedLoc PLoc = SourceMgr.getPresumedLoc(Tok.getLocation()); + PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc()); + for (; PLoc.isValid(); ++Depth) + PLoc = SourceMgr.getPresumedLoc(PLoc.getIncludeLoc()); // __INCLUDE_LEVEL__ expands to a simple numeric value. Add a space after // it so that it will tokenize as a number (and not run into stuff after it diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index e6bf1777a891..48fdd68ab9b2 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -142,17 +142,7 @@ void Preprocessor::DumpToken(const Token &Tok, bool DumpFlags) const { } void Preprocessor::DumpLocation(SourceLocation Loc) const { - SourceLocation LogLoc = SourceMgr.getInstantiationLoc(Loc); - llvm::cerr << SourceMgr.getSourceName(LogLoc) << ':' - << SourceMgr.getLineNumber(LogLoc) << ':' - << SourceMgr.getColumnNumber(LogLoc); - - SourceLocation SpellingLoc = SourceMgr.getSpellingLoc(Loc); - if (SpellingLoc != LogLoc) { - llvm::cerr << " "; - } + Loc.dump(SourceMgr); } void Preprocessor::DumpMacro(const MacroInfo &MI) const { diff --git a/clang/test/Preprocessor/dumptokens_phyloc.c b/clang/test/Preprocessor/dumptokens_phyloc.c index e48a9d44ab87..ae7ccc7d210f 100644 --- a/clang/test/Preprocessor/dumptokens_phyloc.c +++ b/clang/test/Preprocessor/dumptokens_phyloc.c @@ -1,4 +1,4 @@ -// RUN: clang -dump-tokens %s 2>&1 | grep "SpellingLoc=.*dumptokens_phyloc.c:3:20" +// RUN: clang -dump-tokens %s 2>&1 | grep "Spelling=.*dumptokens_phyloc.c:3:20" #define TESTPHYLOC 10 -- GitLab From eb3a9b03ab3379185c8af2574272149a7f9a56c6 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 27 Jan 2009 08:43:38 +0000 Subject: [PATCH 276/682] Fix for PR3418: make sure to handle the RHS of expressions starting with __extension__. This sort of construct shows up in the gcc source code. llvm-svn: 63100 --- clang/include/clang/Parse/Parser.h | 2 ++ clang/lib/Parse/ParseExpr.cpp | 19 +++++++++++++++++++ clang/lib/Parse/ParseStmt.cpp | 12 +++--------- clang/test/Parser/expressions.c | 4 ++++ 4 files changed, 28 insertions(+), 9 deletions(-) diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index df8646df796e..cf479f000e4c 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -567,6 +567,8 @@ private: OwningExprResult ParseExpressionWithLeadingAt(SourceLocation AtLoc); + OwningExprResult ParseExpressionWithLeadingExtension(SourceLocation ExtLoc); + OwningExprResult ParseRHSOfBinaryExpression(OwningExprResult LHS, unsigned MinPrec); OwningExprResult ParseCastExpression(bool isUnaryExpression); diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 38518557a3f8..1bec279890d4 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -192,6 +192,25 @@ Parser::ParseExpressionWithLeadingAt(SourceLocation AtLoc) { return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); } +/// This routine is called when a leading '__extension__' is seen and +/// consumed. This is necessary because the token gets consumed in the +/// process of disambiguating between an expression and a declaration. +Parser::OwningExprResult +Parser::ParseExpressionWithLeadingExtension(SourceLocation ExtLoc) { + // FIXME: The handling for throw is almost certainly wrong. + if (Tok.is(tok::kw_throw)) + return ParseThrowExpression(); + + OwningExprResult LHS(ParseCastExpression(false)); + if (LHS.isInvalid()) return move(LHS); + + LHS = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, + move_arg(LHS)); + if (LHS.isInvalid()) return move(LHS); + + return ParseRHSOfBinaryExpression(move(LHS), prec::Comma); +} + /// ParseAssignmentExpression - Parse an expr that doesn't include commas. /// Parser::OwningExprResult Parser::ParseAssignmentExpression() { diff --git a/clang/lib/Parse/ParseStmt.cpp b/clang/lib/Parse/ParseStmt.cpp index f7014991bf8c..5ff09052f58d 100644 --- a/clang/lib/Parse/ParseStmt.cpp +++ b/clang/lib/Parse/ParseStmt.cpp @@ -366,6 +366,7 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // __extension__ can start declarations and it can also be a unary // operator for expressions. Consume multiple __extension__ markers here // until we can determine which is which. + // FIXME: This loses extension expressions in the AST! SourceLocation ExtLoc = ConsumeToken(); while (Tok.is(tok::kw___extension__)) ConsumeToken(); @@ -381,21 +382,14 @@ Parser::OwningStmtResult Parser::ParseCompoundStatementBody(bool isStmtExpr) { // FIXME: Pass in the right location for the end of the declstmt. R = Actions.ActOnDeclStmt(Res, DeclStart, DeclStart); } else { - // Otherwise this was a unary __extension__ marker. Parse the - // subexpression and add the __extension__ unary op. - OwningExprResult Res(ParseCastExpression(false)); + // Otherwise this was a unary __extension__ marker. + OwningExprResult Res(ParseExpressionWithLeadingExtension(ExtLoc)); if (Res.isInvalid()) { SkipUntil(tok::semi); continue; } - // Add the __extension__ node to the AST. - Res = Actions.ActOnUnaryOp(CurScope, ExtLoc, tok::kw___extension__, - move_arg(Res)); - if (Res.isInvalid()) - continue; - // Eat the semicolon at the end of stmt and convert the expr into a // statement. ExpectAndConsume(tok::semi, diag::err_expected_semi_after_expr); diff --git a/clang/test/Parser/expressions.c b/clang/test/Parser/expressions.c index 3b47260c32f2..29621f1975e6 100644 --- a/clang/test/Parser/expressions.c +++ b/clang/test/Parser/expressions.c @@ -36,4 +36,8 @@ void test_sizeof(){ sizeof(arr)[0]; } +// PR3418 +int test_leading_extension() { + __extension__ (*(char*)0) = 1; +} -- GitLab From 3f66b84c869d1f939811987f023e0860cdef61d4 Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Tue, 27 Jan 2009 09:03:41 +0000 Subject: [PATCH 277/682] Support CodeGen for __extension__ operator on aggregates. llvm-svn: 63101 --- clang/lib/CodeGen/CGExprAgg.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp index 058b561f95b3..9181bf665450 100644 --- a/clang/lib/CodeGen/CGExprAgg.cpp +++ b/clang/lib/CodeGen/CGExprAgg.cpp @@ -58,6 +58,7 @@ public: CGF.ErrorUnsupported(S, "aggregate expression"); } void VisitParenExpr(ParenExpr *PE) { Visit(PE->getSubExpr()); } + void VisitUnaryExtension(UnaryOperator *E) { Visit(E->getSubExpr()); } // l-values. void VisitDeclRefExpr(DeclRefExpr *DRE) { EmitAggLoadOfLValue(DRE); } -- GitLab From ed2ba0fb015c02c5d6427b0b2b29143656cf54c1 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 17:28:23 +0000 Subject: [PATCH 278/682] Make some comments doxygen-friendly. llvm-svn: 63104 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 209fedb1e96c..c04436be277b 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -533,11 +533,11 @@ public: SDValue getIndexedStore(SDValue OrigStoe, SDValue Base, SDValue Offset, ISD::MemIndexedMode AM); - // getSrcValue - Construct a node to track a Value* through the backend. + /// getSrcValue - Construct a node to track a Value* through the backend. SDValue getSrcValue(const Value *v); - // getMemOperand - Construct a node to track a memory reference - // through the backend. + /// getMemOperand - Construct a node to track a memory reference + /// through the backend. SDValue getMemOperand(const MachineMemOperand &MO); /// UpdateNodeOperands - *Mutate* the specified node in-place to have the @@ -814,10 +814,10 @@ private: void allnodes_clear(); - // List of non-single value types. + /// VTList - List of non-single value types. std::vector VTList; - // Maps to auto-CSE operations. + /// CondCodeNodes - Maps to auto-CSE operations. std::vector CondCodeNodes; std::vector ValueTypeNodes; -- GitLab From ec39eb851984f5ddcabfcde7cb8e28bf4f442261 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Tue, 27 Jan 2009 18:06:03 +0000 Subject: [PATCH 279/682] APInt's countLeadingOnes() was broken for negative i128 values, causing assertion failures in getSExtValue(). Fix it by making highWordBits actually contain what its name says, and add some more unit-tests for APInt. This fixes PR3419. llvm-svn: 63107 --- llvm/lib/Support/APInt.cpp | 8 +++- llvm/unittests/ADT/APInt.cpp | 79 +++++++++++++++++++++++++++++++++++- 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Support/APInt.cpp b/llvm/lib/Support/APInt.cpp index 367c75be1af6..3d38a0c60666 100644 --- a/llvm/lib/Support/APInt.cpp +++ b/llvm/lib/Support/APInt.cpp @@ -683,7 +683,13 @@ unsigned APInt::countLeadingOnes() const { return countLeadingOnes_64(VAL, APINT_BITS_PER_WORD - BitWidth); unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD; - unsigned shift = (highWordBits == 0 ? 0 : APINT_BITS_PER_WORD - highWordBits); + unsigned shift; + if (!highWordBits) { + highWordBits = APINT_BITS_PER_WORD; + shift = 0; + } else { + shift = APINT_BITS_PER_WORD - highWordBits; + } int i = getNumWords() - 1; unsigned Count = countLeadingOnes_64(pVal[i], shift); if (Count == highWordBits) { diff --git a/llvm/unittests/ADT/APInt.cpp b/llvm/unittests/ADT/APInt.cpp index 5bca5b6b4063..cbcc1390bca8 100644 --- a/llvm/unittests/ADT/APInt.cpp +++ b/llvm/unittests/ADT/APInt.cpp @@ -18,8 +18,83 @@ namespace { TEST(APIntTest, ShiftLeftByZero) { APInt One = APInt::getNullValue(65) + 1; APInt Shl = One.shl(0); - EXPECT_EQ(Shl[0], true); - EXPECT_EQ(Shl[1], false); + EXPECT_EQ(true, Shl[0]); + EXPECT_EQ(false, Shl[1]); +} + +TEST(APIntTest, I128NegativeCount) { + APInt Minus3(128, (uint64_t)-3, true); + EXPECT_EQ(126u, Minus3.countLeadingOnes()); + EXPECT_EQ(-3, Minus3.getSExtValue()); + + APInt Minus1(128, (uint64_t)-1, true); + EXPECT_EQ(0u, Minus1.countLeadingZeros()); + EXPECT_EQ(128u, Minus1.countLeadingOnes()); + EXPECT_EQ(128u, Minus1.getActiveBits()); + EXPECT_EQ(0u, Minus1.countTrailingZeros()); + EXPECT_EQ(128u, Minus1.countTrailingOnes()); + EXPECT_EQ(128u, Minus1.countPopulation()); + EXPECT_EQ(-1, Minus1.getSExtValue()); +} + +TEST(APIntTest, I33Count) { + APInt i33minus2(33, -2, true); + EXPECT_EQ(0u, i33minus2.countLeadingZeros()); + EXPECT_EQ(32u, i33minus2.countLeadingOnes()); + EXPECT_EQ(33u, i33minus2.getActiveBits()); + EXPECT_EQ(1u, i33minus2.countTrailingZeros()); + EXPECT_EQ(32u, i33minus2.countPopulation()); + EXPECT_EQ(-2, i33minus2.getSExtValue()); + EXPECT_EQ(((uint64_t)-2)&((1ull<<33) -1), i33minus2.getZExtValue()); +} + +TEST(APIntTest, I65Count) { + APInt i65minus(65, 0, true); + i65minus.set(64); + EXPECT_EQ(0u, i65minus.countLeadingZeros()); + EXPECT_EQ(1u, i65minus.countLeadingOnes()); + EXPECT_EQ(65u, i65minus.getActiveBits()); + EXPECT_EQ(64u, i65minus.countTrailingZeros()); + EXPECT_EQ(1u, i65minus.countPopulation()); +} + +TEST(APIntTest, I128PositiveCount) { + APInt u128max = APInt::getAllOnesValue(128); + EXPECT_EQ(128u, u128max.countLeadingOnes()); + EXPECT_EQ(0u, u128max.countLeadingZeros()); + EXPECT_EQ(128u, u128max.getActiveBits()); + EXPECT_EQ(0u, u128max.countTrailingZeros()); + EXPECT_EQ(128u, u128max.countTrailingOnes()); + EXPECT_EQ(128u, u128max.countPopulation()); + + APInt u64max(128, (uint64_t)-1, false); + EXPECT_EQ(64u, u64max.countLeadingZeros()); + EXPECT_EQ(0u, u64max.countLeadingOnes()); + EXPECT_EQ(64u, u64max.getActiveBits()); + EXPECT_EQ(0u, u64max.countTrailingZeros()); + EXPECT_EQ(64u, u64max.countTrailingOnes()); + EXPECT_EQ(64u, u64max.countPopulation()); + EXPECT_EQ((uint64_t)~0ull, u64max.getZExtValue()); + + APInt zero(128, 0, true); + EXPECT_EQ(128u, zero.countLeadingZeros()); + EXPECT_EQ(0u, zero.countLeadingOnes()); + EXPECT_EQ(0u, zero.getActiveBits()); + EXPECT_EQ(128u, zero.countTrailingZeros()); + EXPECT_EQ(0u, zero.countTrailingOnes()); + EXPECT_EQ(0u, zero.countPopulation()); + EXPECT_EQ(0u, zero.getSExtValue()); + EXPECT_EQ(0u, zero.getZExtValue()); + + APInt one(128, 1, true); + EXPECT_EQ(127u, one.countLeadingZeros()); + EXPECT_EQ(0u, one.countLeadingOnes()); + EXPECT_EQ(1u, one.getActiveBits()); + EXPECT_EQ(0u, one.countTrailingZeros()); + EXPECT_EQ(1u, one.countTrailingOnes()); + EXPECT_EQ(1u, one.countPopulation()); + EXPECT_EQ(1, one.getSExtValue()); + EXPECT_EQ(1u, one.getZExtValue()); } } -- GitLab From a3402cd52403e07013edf952ce9e70685bcc4ead Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 18:08:34 +0000 Subject: [PATCH 280/682] add a new "getPreferredTypeAlign" method to return the preferred alignment of a type. The implementation is currently something of a hack, but is sufficient for now and allows clients to be built on it. llvm-svn: 63108 --- clang/include/clang/AST/ASTContext.h | 10 ++++++++-- clang/lib/AST/ASTContext.cpp | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 684feb24025d..a01199d4b2aa 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -394,8 +394,8 @@ public: return getTypeInfo(T).first; } - /// getTypeAlign - Return the alignment of the specified type, in bits. This - /// method does not work on incomplete types. + /// getTypeAlign - Return the ABI-specified alignment of a type, in bits. + /// This method does not work on incomplete types. unsigned getTypeAlign(QualType T) { return getTypeInfo(T).second; } @@ -403,6 +403,12 @@ public: return getTypeInfo(T).second; } + /// getPreferredTypeAlign - Return the "preferred" alignment of the specified + /// type for the current target in bits. This can be different than the ABI + /// alignment in cases where it is beneficial for performance to overalign + /// a data type. + unsigned getPreferredTypeAlign(const Type *T); + /// getDeclAlign - Return the alignment of the specified decl that should be /// returned by __alignof(). Note that bitfields do not have a valid /// alignment, so this method will assert on them. diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 2662860af2fe..e7c08e2da39b 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -453,6 +453,22 @@ ASTContext::getTypeInfo(const Type *T) { return std::make_pair(Width, Align); } +/// getPreferredTypeAlign - Return the "preferred" alignment of the specified +/// type for the current target in bits. This can be different than the ABI +/// alignment in cases where it is beneficial for performance to overalign +/// a data type. +unsigned ASTContext::getPreferredTypeAlign(const Type *T) { + unsigned ABIAlign = getTypeAlign(T); + + // Doubles should be naturally aligned if possible. + if (const BuiltinType *BT = dyn_cast(getCanonicalType(T))) + if (BT->getKind() == BuiltinType::Double) + return std::max(ABIAlign, 8U); + + return ABIAlign; +} + + /// LayoutField - Field layout. void ASTRecordLayout::LayoutField(const FieldDecl *FD, unsigned FieldNo, bool IsUnion, unsigned StructPacking, -- GitLab From 422d81dcd4b0c5fd4538a2feaf0ec4df5f5bf7b1 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 27 Jan 2009 18:29:03 +0000 Subject: [PATCH 281/682] Fix bug in BasicStore::getLValueElement where if the base of an array subscript expression was an ElementRegion we stacked another ElementRegion on top of that. This fixes PR 3422. llvm-svn: 63110 --- clang/lib/Analysis/BasicStore.cpp | 14 ++++++++++++-- clang/test/Analysis/misc-ps.m | 8 ++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/clang/lib/Analysis/BasicStore.cpp b/clang/lib/Analysis/BasicStore.cpp index a36a239e0de2..2feea594b8aa 100644 --- a/clang/lib/Analysis/BasicStore.cpp +++ b/clang/lib/Analysis/BasicStore.cpp @@ -203,7 +203,6 @@ SVal BasicStoreManager::getLValueField(const GRState* St, SVal Base, SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, SVal Offset) { - if (Base.isUnknownOrUndef()) return Base; @@ -233,6 +232,17 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, case loc::MemRegionKind: { const MemRegion *R = cast(BaseL).getRegion(); + + if (isa(R)) { + // Basic example: + // char buf[100]; + // char *q = &buf[1]; // p points to ElementRegion(buf,Unknown) + // &q[10] + assert(cast(R)->getIndex().isUnknown()); + return Base; + } + + if (const TypedRegion *TR = dyn_cast(R)) { BaseR = TR; break; @@ -244,7 +254,7 @@ SVal BasicStoreManager::getLValueElement(const GRState* St, SVal Base, break; } - + case loc::ConcreteIntKind: // While these seem funny, this can happen through casts. // FIXME: What we should return is the field offset. For example, diff --git a/clang/test/Analysis/misc-ps.m b/clang/test/Analysis/misc-ps.m index f221f8b989f1..4e7f0ad5b32d 100644 --- a/clang/test/Analysis/misc-ps.m +++ b/clang/test/Analysis/misc-ps.m @@ -100,3 +100,11 @@ void handle_sizeof_void(unsigned flag) { *p = 1; // no-warning } +// PR 3422 +void pr3422_helper(char *p); +void pr3422() { + char buf[100]; + char *q = &buf[10]; + pr3422_helper(&q[1]); +} + -- GitLab From 7368d581c1be44b0081851a356f0771ae7b77c60 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 18:30:58 +0000 Subject: [PATCH 282/682] Split the single monolithic DiagnosticKinds.def file into one .def file for each library. This means that adding a diagnostic to sema doesn't require all the other libraries to be rebuilt. Patch by Anders Johnsen! llvm-svn: 63111 --- clang/Driver/clang.cpp | 1 + clang/include/clang/Basic/Diagnostic.h | 19 +- clang/include/clang/Basic/DiagnosticKinds.def | 1775 +---------------- clang/lib/AST/ExprConstant.cpp | 2 +- clang/lib/Analysis/UninitializedValues.cpp | 2 +- clang/lib/Basic/Diagnostic.cpp | 99 +- clang/lib/Lex/Lexer.cpp | 2 +- clang/lib/Lex/LiteralSupport.cpp | 2 +- clang/lib/Lex/MacroArgs.cpp | 2 +- clang/lib/Lex/PPDirectives.cpp | 2 +- clang/lib/Lex/PPExpressions.cpp | 2 +- clang/lib/Lex/PPLexerChange.cpp | 2 +- clang/lib/Lex/PPMacroExpansion.cpp | 2 +- clang/lib/Lex/Pragma.cpp | 2 +- clang/lib/Lex/Preprocessor.cpp | 2 +- clang/lib/Lex/PreprocessorLexer.cpp | 2 +- clang/lib/Lex/TokenLexer.cpp | 2 +- clang/lib/Parse/DeclSpec.cpp | 2 +- clang/lib/Parse/ExtensionRAIIObject.h | 2 +- clang/lib/Parse/ParseCXXInlineMethods.cpp | 2 +- clang/lib/Parse/ParseDecl.cpp | 2 +- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- clang/lib/Parse/ParseExprCXX.cpp | 2 +- clang/lib/Parse/ParseInit.cpp | 2 +- clang/lib/Parse/ParseObjc.cpp | 2 +- clang/lib/Parse/ParsePragma.cpp | 2 +- clang/lib/Parse/ParseTemplate.cpp | 2 +- clang/lib/Parse/ParseTentative.cpp | 2 +- clang/lib/Parse/Parser.cpp | 2 +- clang/lib/Sema/Sema.cpp | 2 +- clang/lib/Sema/Sema.h | 2 +- clang/lib/Sema/SemaCXXScopeSpec.cpp | 2 +- clang/lib/Sema/SemaChecking.cpp | 2 +- clang/lib/Sema/SemaDecl.cpp | 2 +- clang/lib/Sema/SemaDeclAttr.cpp | 2 +- clang/lib/Sema/SemaDeclCXX.cpp | 2 +- clang/lib/Sema/SemaDeclObjC.cpp | 2 +- clang/lib/Sema/SemaExpr.cpp | 2 +- clang/lib/Sema/SemaExprCXX.cpp | 2 +- clang/lib/Sema/SemaExprObjC.cpp | 2 +- clang/lib/Sema/SemaInherit.cpp | 2 +- clang/lib/Sema/SemaInit.cpp | 2 +- clang/lib/Sema/SemaNamedCast.cpp | 2 +- clang/lib/Sema/SemaStmt.cpp | 2 +- clang/lib/Sema/SemaType.cpp | 2 +- 45 files changed, 150 insertions(+), 1826 deletions(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index d7c8beb1d39f..8002318b6ada 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -40,6 +40,7 @@ #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/DiagnosticDriver.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/StringExtras.h" diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index a78f73331574..d1c045704a6a 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -18,6 +18,13 @@ #include #include +#define DIAG_START_LEX 300 +#define DIAG_START_PARSE (DIAG_START_LEX + 300) +#define DIAG_START_AST (DIAG_START_PARSE + 300) +#define DIAG_START_SEMA (DIAG_START_AST + 100) +#define DIAG_START_ANALYSIS (DIAG_START_SEMA + 1000) +#define DIAG_UPPER_LIMIT (DIAG_START_ANALYSIS + 100) + namespace llvm { template class SmallVectorImpl; } @@ -34,12 +41,8 @@ namespace clang { class CustomDiagInfo; /// diag::kind - All of the diagnostics that can be emitted by the frontend. - enum kind { -#define DIAG(ENUM,FLAGS,DESC) ENUM, -#include "DiagnosticKinds.def" - NUM_BUILTIN_DIAGNOSTICS - }; - + typedef unsigned kind; + /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR /// (emit as an error), or MAP_DEFAULT (handle the default way). @@ -82,7 +85,7 @@ private: /// DiagMappings - Mapping information for diagnostics. Mapping info is /// packed into two bits per diagnostic. - unsigned char DiagMappings[(diag::NUM_BUILTIN_DIAGNOSTICS+3)/4]; + unsigned char DiagMappings[DIAG_UPPER_LIMIT/4]; /// ErrorOccurred - This is set to true when an error is emitted, and is /// sticky. @@ -144,7 +147,7 @@ public: /// setDiagnosticMapping - This allows the client to specify that certain /// warnings are ignored. Only NOTEs, WARNINGs, and EXTENSIONs can be mapped. void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) { - assert(Diag < diag::NUM_BUILTIN_DIAGNOSTICS && + assert(Diag < DIAG_UPPER_LIMIT && "Can only map builtin diagnostics"); assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!"); unsigned char &Slot = DiagMappings[Diag/4]; diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def index 5ff6728283c0..70a4821ea170 100644 --- a/clang/include/clang/Basic/DiagnosticKinds.def +++ b/clang/include/clang/Basic/DiagnosticKinds.def @@ -22,1775 +22,12 @@ // by default. // ERROR - Error, compilation will stop after parsing completes. -//===----------------------------------------------------------------------===// -// Common Helpers -//===----------------------------------------------------------------------===// - -DIAG(note_previous_definition, NOTE, - "previous definition is here") -DIAG(note_previous_declaration, NOTE, - "previous declaration is here") -DIAG(note_previous_implicit_declaration, NOTE, - "previous implicit declaration is here") -DIAG(note_previous_use, NOTE, - "previous use is here") -DIAG(note_duplicate_case_prev, NOTE, - "previous case defined here") -DIAG(note_forward_declaration, NOTE, - "forward declaration of %0") -DIAG(note_type_being_defined, NOTE, - "definition of %0 is not complete until the closing '}'") -/// note_matching - this is used as a continuation of a previous diagnostic, -/// e.g. to specify the '(' when we expected a ')'. -DIAG(note_matching, NOTE, - "to match this '%0'") - -DIAG(note_using_decl, NOTE, - "using") -DIAG(note_also_found_decl, NOTE, - "also found") - -//===----------------------------------------------------------------------===// -// Lexer Diagnostics -//===----------------------------------------------------------------------===// - -DIAG(null_in_string, WARNING, - "null character(s) preserved in string literal") -DIAG(null_in_char , WARNING, - "null character(s) preserved in character literal") -DIAG(null_in_file , WARNING, - "null character ignored") -DIAG(warn_nested_block_comment, WARNING, - "'/*' within block comment") -DIAG(escaped_newline_block_comment_end, WARNING, - "escaped newline between */ characters at block comment end") -DIAG(backslash_newline_space, WARNING, - "backslash and newline separated by space") - -// Trigraphs. -DIAG(trigraph_ignored, WARNING, "trigraph ignored") -DIAG(trigraph_ignored_block_comment, WARNING, - "ignored trigraph would end block comment") -DIAG(trigraph_ends_block_comment, WARNING, - "trigraph ends block comment") -DIAG(trigraph_converted, WARNING, - "trigraph converted to '%0' character") - -DIAG(ext_multi_line_bcpl_comment, EXTENSION, - "multi-line // comment") -DIAG(ext_bcpl_comment, EXTENSION, - "// comments are not allowed in this language") -DIAG(ext_no_newline_eof, EXTENSION, - "no newline at end of file") -DIAG(ext_backslash_newline_eof, EXTENSION, - "backslash-newline at end of file") -DIAG(ext_dollar_in_identifier, EXTENSION, - "'$' in identifier") -DIAG(charize_microsoft_ext, EXTENSION, - "@# is a microsoft extension") - -DIAG(ext_token_used, EXTENSION, - "extension used") - -DIAG(err_unterminated_string, ERROR, - "missing terminating \" character") -DIAG(err_unterminated_char, ERROR, - "missing terminating ' character") -DIAG(err_empty_character, ERROR, - "empty character constant") -DIAG(err_unterminated_block_comment, ERROR, - "unterminated /* comment") -DIAG(err_invalid_character_to_charify, ERROR, - "invalid argument to convert to character") - -//===----------------------------------------------------------------------===// -// Preprocessor Diagnostics -//===----------------------------------------------------------------------===// - -DIAG(pp_hash_warning, WARNING, - "#warning%0") -DIAG(pp_include_next_in_primary, WARNING, - "#include_next in primary source file") -DIAG(pp_include_next_absolute_path, WARNING, - "#include_next with absolute path") -DIAG(ext_c99_whitespace_required_after_macro_name, WARNING, - "ISO C99 requires whitespace after the macro name") -DIAG(pp_pragma_once_in_main_file, WARNING, - "#pragma once in main file") -DIAG(pp_pragma_sysheader_in_main_file, WARNING, - "#pragma system_header ignored in main file") -DIAG(pp_poisoning_existing_macro, WARNING, - "poisoning existing macro") -DIAG(pp_out_of_date_dependency, WARNING, - "current file is older than dependency %0") -DIAG(pp_undef_builtin_macro, WARNING, - "undefining builtin macro") -DIAG(pp_redef_builtin_macro, WARNING, - "redefining builtin macro") -DIAG(pp_macro_not_used, WARNING, // -Wunused-macros - "macro is not used") -DIAG(pp_invalid_string_literal, WARNING, - "invalid string literal, ignoring final '\\'") -DIAG(warn_pp_expr_overflow, WARNING, - "integer overflow in preprocessor expression") -DIAG(warn_pp_convert_lhs_to_positive, WARNING, - "left side of operator converted from negative value to unsigned: %0") -DIAG(warn_pp_convert_rhs_to_positive, WARNING, - "right side of operator converted from negative value to unsigned: %0") - -DIAG(ext_pp_import_directive, EXTENSION, - "#import is a language extension") -DIAG(ext_pp_ident_directive, EXTENSION, - "#ident is a language extension") -DIAG(ext_pp_include_next_directive, EXTENSION, - "#include_next is a language extension") -DIAG(ext_pp_warning_directive, EXTENSION, - "#warning is a language extension") -DIAG(ext_pp_extra_tokens_at_eol, EXTENSION, - "extra tokens at end of %0 directive") -DIAG(ext_pp_comma_expr, EXTENSION, - "comma operator in operand of #if") -DIAG(ext_pp_bad_vaargs_use, EXTENSION, - "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro") -DIAG(ext_pp_macro_redef, EXTENSION, - "%0 macro redefined") -DIAG(ext_variadic_macro, EXTENSION, - "variadic macros were introduced in C99") -DIAG(ext_named_variadic_macro, EXTENSION, - "named variadic macros are a GNU extension") -DIAG(ext_embedded_directive, EXTENSION, - "embedding a directive within macro arguments is not portable") -DIAG(ext_missing_varargs_arg, EXTENSION, - "varargs argument missing, but tolerated as an extension") -DIAG(ext_empty_fnmacro_arg, EXTENSION, - "empty macro arguments were standardized in C99") - -DIAG(ext_pp_base_file, EXTENSION, - "__BASE_FILE__ is a language extension") -DIAG(ext_pp_include_level, EXTENSION, - "__INCLUDE_LEVEL__ is a language extension") -DIAG(ext_pp_timestamp, EXTENSION, - "__TIMESTAMP__ is a language extension") - -DIAG(err_pp_invalid_directive, ERROR, - "invalid preprocessing directive") -DIAG(err_pp_hash_error, ERROR, - "#error%0") -DIAG(err_pp_file_not_found, ERROR, - "'%0' file not found") -DIAG(err_pp_empty_filename, ERROR, - "empty filename") -DIAG(err_pp_include_too_deep, ERROR, - "#include nested too deeply") -DIAG(err_pp_expects_filename, ERROR, - "expected \"FILENAME\" or ") -DIAG(err_pp_macro_not_identifier, ERROR, - "macro names must be identifiers") -DIAG(err_pp_missing_macro_name, ERROR, - "macro name missing") -DIAG(err_pp_missing_rparen_in_macro_def, ERROR, - "missing ')' in macro parameter list") -DIAG(err_pp_invalid_tok_in_arg_list, ERROR, - "invalid token in macro parameter list") -DIAG(err_pp_expected_ident_in_arg_list, ERROR, - "expected identifier in macro parameter list") -DIAG(err_pp_expected_comma_in_arg_list, ERROR, - "expected comma in macro parameter list") -DIAG(err_pp_duplicate_name_in_arg_list, ERROR, - "duplicate macro parameter name %0") -DIAG(err_pp_stringize_not_parameter, ERROR, - "'#' is not followed by a macro parameter") -DIAG(err_pp_line_requires_integer, ERROR, - "#line directive requires a positive integer argument") -DIAG(err_pp_line_invalid_filename, ERROR, - "invalid filename for #line directive") -DIAG(err_pp_linemarker_requires_integer, ERROR, - "line marker directive requires a positive integer argument") -DIAG(err_pp_linemarker_invalid_filename, ERROR, - "invalid filename for line marker directive") -DIAG(err_pp_linemarker_invalid_flag, ERROR, - "invalid flag line marker directive") -DIAG(ext_pp_line_too_big, EXTENSION, - "C requires #line number to be less than %0, allowed as extension") - -DIAG(err_pp_malformed_ident, ERROR, - "invalid #ident directive") -DIAG(err_pp_unterminated_conditional, ERROR, - "unterminated conditional directive") -DIAG(pp_err_else_after_else, ERROR, - "#else after #else") -DIAG(pp_err_elif_after_else, ERROR, - "#elif after #else") -DIAG(pp_err_else_without_if, ERROR, - "#else without #if") -DIAG(pp_err_elif_without_if, ERROR, - "#elif without #if") -DIAG(err_pp_endif_without_if, ERROR, - "#endif without #if") -DIAG(err_pp_expected_value_in_expr, ERROR, - "expected value in expression") -DIAG(err_pp_missing_val_before_operator, ERROR, - "missing value before operator") -DIAG(err_pp_expected_rparen, ERROR, - "expected ')' in preprocessor expression") -DIAG(err_pp_expected_eol, ERROR, - "expected end of line in preprocessor expression") -DIAG(warn_pp_undef_identifier, WARNING, - "%0 is not defined, evaluates to 0") -DIAG(err_pp_defined_requires_identifier, ERROR, - "operator 'defined' requires an identifier") -DIAG(err_pp_missing_rparen, ERROR, - "missing ')' after 'defined'") -DIAG(err_pp_colon_without_question, ERROR, - "':' without preceding '?'") -DIAG(err_pp_division_by_zero, ERROR, - "division by zero in preprocessor expression") -DIAG(err_pp_remainder_by_zero, ERROR, - "remainder by zero in preprocessor expression") -DIAG(err_pp_expr_bad_token_binop, ERROR, - "token is not a valid binary operator in a preprocessor subexpression") -DIAG(err_pp_expr_bad_token_start_expr, ERROR, - "invalid token at start of a preprocessor expression") -DIAG(err_pp_invalid_poison, ERROR, - "can only poison identifier tokens") -DIAG(err_pp_used_poisoned_id, ERROR, - "attempt to use a poisoned identifier") -DIAG(err__Pragma_malformed, ERROR, - "_Pragma takes a parenthesized string literal") -DIAG(err_pragma_comment_malformed, ERROR, - "pragma comment requires parenthesized identifier and optional string") -DIAG(err_pragma_comment_unknown_kind, ERROR, - "unknown kind of pragma comment") -DIAG(err_defined_macro_name, ERROR, - "'defined' cannot be used as a macro name") -DIAG(err_paste_at_start, ERROR, - "'##' cannot appear at start of macro expansion") -DIAG(err_paste_at_end, ERROR, - "'##' cannot appear at end of macro expansion") -DIAG(ext_paste_comma, EXTENSION, - "Use of comma pasting extension is non-portable") -DIAG(err_unterm_macro_invoc, ERROR, - "unterminated function-like macro invocation") -DIAG(err_too_many_args_in_macro_invoc, ERROR, - "too many arguments provided to function-like macro invocation") -DIAG(err_too_few_args_in_macro_invoc, ERROR, - "too few arguments provided to function-like macro invocation") -DIAG(err_pp_bad_paste, ERROR, - "pasting formed '%0', an invalid preprocessing token") -DIAG(err_pp_operator_used_as_macro_name, ERROR, - "C++ operator '%0' cannot be used as a macro name") -DIAG(err_pp_illegal_floating_literal, ERROR, - "floating point literal in preprocessor expression") - -// Should be a sorry? -DIAG(err_pp_I_dash_not_supported, ERROR, - "-I- not supported, please use -iquote instead") - -//===----------------------------------------------------------------------===// -// Parser Diagnostics -//===----------------------------------------------------------------------===// - -DIAG(w_asm_qualifier_ignored, WARNING, - "ignored %0 qualifier on asm") - -DIAG(ext_empty_source_file, EXTENSION, - "ISO C forbids an empty source file") -DIAG(ext_top_level_semi, EXTENSION, - "ISO C does not allow an extra ';' outside of a function") -DIAG(ext_extra_struct_semi, EXTENSION, - "ISO C does not allow an extra ';' inside a struct or union") -DIAG(ext_missing_declspec, EXTENSION, - "declaration specifier missing, defaulting to 'int'") -DIAG(ext_missing_type_specifier, EXTENSION, - "type specifier missing, defaults to 'int'") - -DIAG(ext_duplicate_declspec, EXTENSION, - "duplicate '%0' declaration specifier") -DIAG(ext_plain_complex, EXTENSION, - "ISO C does not support plain '_Complex' meaning '_Complex double'") -DIAG(ext_integer_complex, EXTENSION, - "ISO C does not support complex integer types") -DIAG(ext_thread_before, EXTENSION, - "'__thread' before 'static'") -DIAG(ext_integer_increment_complex, EXTENSION, - "ISO C does not support '++'/'--' on complex integer type %0") -DIAG(ext_integer_complement_complex, EXTENSION, - "ISO C does not support '~' for complex conjugation of %0") - -DIAG(ext_mixed_decls_code, EXTENSION, - "ISO C90 forbids mixing declarations and code") - -DIAG(ext_empty_struct_union_enum, EXTENSION, - "use of empty %0 extension") -DIAG(warn_enum_value_overflow, WARNING, - "overflow in enumeration value") - -DIAG(ext_ident_list_in_param, EXTENSION, - "type-less parameter names in function declaration") -DIAG(ext_c99_array_usage, EXTENSION, - "use of C99-specific array features, accepted as an extension") -DIAG(ext_c99_variable_decl_in_for_loop, EXTENSION, - "variable declaration in for loop is a C99-specific feature") -DIAG(ext_c99_compound_literal, EXTENSION, - "compound literals are a C99-specific feature") -DIAG(ext_c99_enumerator_list_comma, EXTENSION, - "commas at the end of enumerator lists are a C99-specific feature") - -DIAG(ext_gnu_void_ptr, EXTENSION, - "use of GNU void* extension") -DIAG(ext_gnu_indirect_goto, EXTENSION, - "use of GNU indirect-goto extension") -DIAG(ext_gnu_address_of_label, EXTENSION, - "use of GNU address-of-label extension") -DIAG(ext_gnu_statement_expr, EXTENSION, - "use of GNU statement expression extension") -DIAG(ext_gnu_conditional_expr, EXTENSION, - "use of GNU ?: expression extension, eliding middle term") -DIAG(ext_gnu_empty_initializer, EXTENSION, - "use of GNU empty initializer extension") -DIAG(ext_gnu_array_range, EXTENSION, - "use of GNU array range extension") -DIAG(ext_gnu_missing_equal_designator, EXTENSION, - "use of GNU 'missing =' extension in designator") -DIAG(err_expected_equal_designator, ERROR, - "expected '=' or another designator") -DIAG(ext_gnu_old_style_field_designator, EXTENSION, - "use of GNU old-style field designator extension") -DIAG(ext_gnu_case_range, EXTENSION, - "use of GNU case range extension") -DIAG(ext_gnu_ptr_func_arith, EXTENSION, - "arithmetic on pointer to function type %0 is a GNU extension") - -// Generic errors. -DIAG(err_parse_error, ERROR, - "parse error") -DIAG(err_expected_expression, ERROR, - "expected expression") -DIAG(err_expected_type, ERROR, - "expected a type") -DIAG(err_expected_external_declaration, ERROR, - "expected external declaration") -DIAG(err_expected_ident, ERROR, - "expected identifier") -DIAG(err_expected_ident_lparen, ERROR, - "expected identifier or '('") -DIAG(err_expected_ident_lbrace, ERROR, - "expected identifier or '{'") -DIAG(err_expected_lbrace, ERROR, - "expected '{'") -DIAG(err_expected_lparen, ERROR, - "expected '('") -DIAG(err_expected_rparen, ERROR, - "expected ')'") -DIAG(err_expected_rsquare, ERROR, - "expected ']'") -DIAG(err_expected_rbrace, ERROR, - "expected '}'") -DIAG(err_expected_greater, ERROR, - "expected '>'") -DIAG(err_expected_semi_decl_list, ERROR, - "expected ';' at end of declaration list") -DIAG(ext_expected_semi_decl_list, EXTENSION, - "expected ';' at end of declaration list") -DIAG(err_function_declared_typedef, ERROR, - "function definition declared 'typedef'") -DIAG(err_expected_fn_body, ERROR, - "expected function body after function declarator") -DIAG(err_expected_method_body, ERROR, - "expected method body") -DIAG(err_expected_after_declarator, ERROR, - "expected '=', ',', ';', 'asm', or '__attribute__' after declarator") -DIAG(err_expected_statement, ERROR, - "expected statement") -DIAG(err_expected_lparen_after, ERROR, - "expected '(' after '%0'") -DIAG(err_expected_lparen_after_id, ERROR, - "expected '(' after %0") -DIAG(err_expected_less_after, ERROR, - "expected '<' after '%0'") -DIAG(err_expected_comma, ERROR, - "expected ','") -DIAG(err_expected_lbrace_in_compound_literal, ERROR, - "expected '{' in compound literal") -DIAG(err_expected_while, ERROR, - "expected 'while' in do/while loop") -DIAG(err_expected_semi_after, ERROR, - "expected ';' after %0") -DIAG(err_expected_semi_after_expr, ERROR, - "expected ';' after expression") -DIAG(err_expected_semi_for, ERROR, - "expected ';' in 'for' statement specifier") -DIAG(err_non_variable_decl_in_for, ERROR, - "declaration of non-local variable in 'for' loop") -DIAG(err_expected_colon_after, ERROR, - "expected ':' after %0") -DIAG(err_label_end_of_compound_statement, ERROR, - "label at end of compound statement: expected statement") -DIAG(err_expected_colon, ERROR, - "expected ':'") -DIAG(err_expected_string_literal, ERROR, - "expected string literal") -DIAG(err_expected_asm_operand, ERROR, - "expected string literal or '[' for asm operand") -DIAG(err_expected_selector_for_method, ERROR, - "expected selector for Objective-C method") -DIAG(err_object_as_method_param, ERROR, - "can not use an object as parameter to a method") -DIAG(err_nsobject_attribute, ERROR, - "__attribute ((NSObject)) is for pointer types only") - -DIAG(err_unexpected_at, ERROR, - "unexpected '@' in program") - -/// Objective-C parser diagnostics -DIAG(err_unexpected_interface, ERROR, - "unexpected interface name %0: expected expression") -DIAG(err_objc_no_attributes_on_category, ERROR, - "attributes may not be specified on a category") -DIAG(err_objc_missing_end, ERROR, - "missing @end") -DIAG(warn_objc_protocol_qualifier_missing_id, WARNING, - "protocol qualifiers without 'id' is archaic") -DIAG(warn_objc_array_of_interfaces, WARNING, - "array of interface %0 should probably be an array of pointers") - -DIAG(err_invalid_receiver_to_message, ERROR, - "invalid receiver to message expression") -DIAG(err_objc_illegal_visibility_spec, ERROR, - "illegal visibility specification") -DIAG(err_objc_illegal_interface_qual, ERROR, - "illegal interface qualifier") -DIAG(err_objc_expected_equal, ERROR, - "setter/getter expects '=' followed by name") -DIAG(err_objc_property_requires_field_name, ERROR, - "property requires fields to be named") -DIAG(err_objc_property_bitfield, ERROR, - "property name cannot be a bitfield") -DIAG(err_objc_expected_property_attr, ERROR, - "unknown property attribute %0") -DIAG(err_objc_propertoes_require_objc2, ERROR, - "properties are an Objective-C 2 feature") -DIAG(err_objc_unexpected_attr, ERROR, - "prefix attribute must be followed by an interface or protocol") -DIAG(err_objc_property_attr_mutually_exclusive, ERROR, - "property attributes '%0' and '%1' are mutually exclusive") -DIAG(warn_objc_property_attr_mutually_exclusive, WARNING, - "property attributes '%0' and '%1' are mutually exclusive") -DIAG(warn_objc_property_no_assignment_attribute, WARNING, - "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed") -DIAG(warn_objc_property_default_assign_on_object, WARNING, - "default property attribute 'assign' not appropriate for non-gc object") -DIAG(err_objc_property_requires_object, ERROR, - "property with '%0' attribute must be of object type") -DIAG(err_property_type, ERROR, - "property cannot have array or function type %0") -DIAG(err_property_not_found, ERROR, - "property %0 not found on object of type %1") -DIAG(err_objc_directive_only_in_protocol, ERROR, - "directive may only be specified in protocols only") -DIAG(err_missing_catch_finally, ERROR, - "@try statement without a @catch and @finally clause") -DIAG(err_objc_concat_string, ERROR, - "unexpected token after Objective-C string") -DIAG(err_undef_superclass, ERROR, - "cannot find interface declaration for %0, superclass of %1") -DIAG(err_duplicate_class_def, ERROR, - "duplicate interface definition for class %0") -DIAG(warn_undef_protocolref, WARNING, - "cannot find protocol definition for %0") -DIAG(err_duplicate_protocol_def, ERROR, - "duplicate protocol definition of %0") -DIAG(err_undef_interface, ERROR, - "cannot find interface declaration for %0") -DIAG(warn_dup_category_def, WARNING, - "duplicate definition of category %1 on interface %0") -DIAG(warn_undef_interface, WARNING, - "cannot find interface declaration for %0") -DIAG(err_dup_implementation_class, ERROR, - "reimplementation of class %0") -DIAG(err_conflicting_super_class, ERROR, - "conflicting super class name %0") -DIAG(err_conflicting_ivar_name, ERROR, - "conflicting instance variable names: %0 vs %1") -DIAG(err_inconsistant_ivar_count, ERROR, - "inconsistent number of instance variables specified") -DIAG(err_conflicting_ivar_type, ERROR, - "instance variable %0 has conflicting type: %1 vs %2") -DIAG(warn_undef_method_impl, WARNING, - "method definition for %0 not found") -DIAG(warn_incomplete_impl, WARNING, - "incomplete implementation") -DIAG(warn_multiple_method_decl, WARNING, - "multiple methods named %0 found") -DIAG(err_duplicate_method_decl, ERROR, - "duplicate declaration of method %0") -DIAG(err_undeclared_protocol, ERROR, - "cannot find protocol declaration for %0") -DIAG(err_missing_sel_definition, ERROR, - "cannot find definition of 'SEL'") -DIAG(err_missing_id_definition, ERROR, - "cannot find definition of 'id'") -DIAG(err_missing_proto_definition, ERROR, - "cannot find definition of 'Protocol'") -DIAG(err_missing_class_definition, ERROR, - "cannot find definition of 'Class'") -DIAG(warn_previous_alias_decl, WARNING, - "previously declared alias is ignored") -DIAG(err_conflicting_aliasing_type, ERROR, - "conflicting types for alias %0") -DIAG(err_statically_allocated_object, ERROR, - "statically allocated Objective-C object %0") -DIAG(warn_class_method_not_found, WARNING, - "method %objcclass0 not found (return type defaults to 'id')") -DIAG(warn_inst_method_not_found, WARNING, - "method %objcinstance0 not found (return type defaults to 'id')") -DIAG(warn_method_not_found_in_protocol, WARNING, - "method %objcinstance0 not found in protocol (return type defaults to 'id')") -DIAG(err_collection_expr_type, ERROR, - "collection expression type %0 is not a valid object") -DIAG(err_selector_element_type, ERROR, - "selector element type %0 is not a valid object") -DIAG(err_selector_element_not_lvalue, ERROR, - "selector element is not a valid lvalue") -DIAG(err_toomany_element_decls, ERROR, - "Only one element declaration is allowed") -DIAG(warn_expected_implementation, WARNING, - "@end must appear in an @implementation context") -DIAG(error_missing_method_context, ERROR, - "missing context for method declaration") -DIAG(error_bad_receiver_type, ERROR, - "bad receiver type %0") -DIAG(error_no_super_class, ERROR, - "no super class declared in @interface for %0") -DIAG(error_no_super_class_message, ERROR, - "no @interface declaration found in class messaging of %0") -DIAG(error_missing_property_context, ERROR, - "missing context for property implementation declaration") -DIAG(error_bad_property_context, ERROR, - "property implementation must be in a class or category implementation") -DIAG(error_bad_property_decl, ERROR, - "property implementation must have its declaration in interface %0") -DIAG(error_bad_category_property_decl, ERROR, - "property implementation must have its declaration in the category %0") -DIAG(error_property_ivar_decl, ERROR, - "property synthesize requires specification of an ivar") -DIAG(error_dynamic_property_ivar_decl, ERROR, - "dynamic property can not have ivar specification") -DIAG(error_missing_property_interface, ERROR, - "property implementation in a category with no category declaration") -DIAG(error_missing_property_ivar_decl, ERROR, - "synthesized property %0 must either be named the same as a compatible" - " ivar or must explicitly name an ivar") -DIAG(error_synthesize_category_decl, ERROR, - "@synthesize not allowed in a category's implementation") -DIAG(error_property_ivar_type, ERROR, - "type of property %0 does not match type of ivar %1") -DIAG(error_readonly_property_assignment, ERROR, - "assigning to property with 'readonly' attribute not allowed") -DIAG(error_nosetter_property_assignment, ERROR, - "setter method is needed to assign to object using property" - " assignment syntax") -DIAG(warn_readonly_property, WARNING, - "attribute 'readonly' of property %0 restricts attribute " - "'readwrite' of property inherited from %1") -DIAG(warn_property_attribute, WARNING, - "property %0 '%1' attribute does not match the property inherited from %2") -DIAG(warn_property_type, WARNING, - "property type %0 does not match property type inherited from %1") -DIAG(err_continuation_class, ERROR, - "continuation class has no primary class") -DIAG(err_use_continuation_class, ERROR, - "attribute of property in continuation class of %0 can only be 'readwrite'") -DIAG(warn_property_attr_mismatch, WARNING, - "property attribute in continuation class does not match the primary class") -DIAG(err_accessor_property_type_mismatch, ERROR, - "type of property %0 does not match type of accessor %1") -DIAG(note_declared_at, NOTE, - "declared at") -DIAG(err_setter_type_void, ERROR, - "type of setter must be void") -DIAG(warn_conflicting_types, WARNING, - "conflicting types for %0") -DIAG(error_property_implemented, ERROR, - "property %0 is already implemented") -DIAG(error_duplicate_ivar_use, ERROR, - "synthesized properties %0 and %1 both claim ivar %2") - -/// C++ parser diagnostics -DIAG(err_expected_unqualified_id, ERROR, - "expected unqualified-id") -DIAG(err_no_declarators, ERROR, - "declaration does not declare anything") -DIAG(ext_typedef_without_a_name, EXTWARN, - "typedef requires a name") -DIAG(err_func_def_no_params, ERROR, - "function definition does not declare parameters") -DIAG(err_expected_lparen_after_type, ERROR, - "expected '(' for function-style cast or type construction") -DIAG(err_expected_equal_after_declarator, ERROR, - "expected '=' after declarator") -DIAG(warn_parens_disambiguated_as_function_decl, WARNING, - "parentheses were disambiguated as a function declarator") -DIAG(err_expected_member_or_base_name, ERROR, - "expected class member or base class name") -DIAG(ext_ellipsis_exception_spec, EXTENSION, - "exception specification of '...' is a Microsoft extension") -DIAG(err_expected_catch, ERROR, - "expected catch") - -/// C++ Templates -DIAG(err_expected_template, ERROR, - "expected template") -DIAG(err_expected_comma_greater, ERROR, - "expected ',' or '>' in template-parameter-list") -DIAG(err_expected_type_id_after, ERROR, - "expected type-id after '%0'") -DIAG(err_expected_class_before, ERROR, - "expected 'class' before '%0'") - -// Language specific pragmas - -// #pragma pack -DIAG(warn_pragma_pack_expected_lparen, WARNING, - "missing '(' after '#pragma pack' - ignoring") -DIAG(warn_pragma_pack_expected_rparen, WARNING, - "missing ')' after '#pragma pack' - ignoring") -DIAG(warn_pragma_pack_invalid_action, WARNING, - "unknown action for '#pragma pack' - ignored") -DIAG(warn_pragma_pack_invalid_constant, WARNING, - "invalid constant for '#pragma pack', expected %0 - ignored") -DIAG(warn_pragma_pack_malformed, WARNING, - "expected integer or identifier in '#pragma pack' - ignored") -// Follow the MSVC implementation. -DIAG(warn_pragma_pack_show, WARNING, - "value of #pragma pack(show) == %0") -// FIXME: Dehardcode. -DIAG(warn_pragma_pack_invalid_alignment, WARNING, - "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'") -DIAG(warn_pragma_pack_pop_identifer_and_alignment, WARNING, - "specifying both a name and alignment to 'pop' is undefined") -DIAG(warn_pragma_pack_pop_failed, WARNING, - "#pragma pack(pop, ...) failed: %0") - -//===----------------------------------------------------------------------===// -// Semantic Analysis -//===----------------------------------------------------------------------===// - -// Constant expressions -DIAG(err_expr_not_ice, ERROR, - "expression is not an integer constant expression") -DIAG(ext_expr_not_ice, EXTENSION, - "expression is not integer constant expression " - "(but is allowed as an extension)") -DIAG(ext_null_pointer_expr_not_ice, EXTENSION, - "null pointer expression is not an integer constant expression " - "(but is allowed as an extension)") - -DIAG(note_comma_in_ice, NOTE, - "C does not permit evaluated commas in an integer constant expression") -DIAG(note_invalid_subexpr_in_ice, NOTE, - "subexpression not valid in an integer constant expression") -DIAG(note_expr_divide_by_zero, NOTE, - "division by zero") - -// Semantic analysis of string and character constant literals. -DIAG(ext_nonstandard_escape, EXTENSION, - "use of non-standard escape character '\\%0'") -DIAG(ext_unknown_escape, EXTENSION, - "unknown escape sequence '\\%0'") -DIAG(warn_extraneous_wide_char_constant, WARNING, - "extraneous characters in wide character constant ignored") -DIAG(warn_char_constant_too_large, WARNING, - "character constant too long for its type") -DIAG(warn_hex_escape_too_large, WARNING, - "hex escape sequence out of range") -DIAG(warn_octal_escape_too_large, WARNING, - "octal escape sequence out of range") - -DIAG(err_hex_escape_no_digits, ERROR, - "\\x used with no following hex digits") - -DIAG(ext_predef_outside_function, WARNING, - "predefined identifier is only valid inside function") - -// C99 Designated Initializers -DIAG(err_array_designator_nonconstant, ERROR, - "array designator value must be a constant expression") -DIAG(err_array_designator_negative, ERROR, - "array designator value '%0' is negative") -DIAG(err_array_designator_empty_range, ERROR, - "array designator range [%0, %1] is empty") -DIAG(err_array_designator_non_array, ERROR, - "array designator cannot initialize non-array type %0") -DIAG(err_array_designator_too_large, ERROR, - "array designator index (%0) exceeds array bounds (%1)") -DIAG(err_field_designator_non_aggr, ERROR, - "field designator cannot initialize a %select{non-struct, non-union|non-class}0 type %1") -DIAG(err_field_designator_unknown, ERROR, - "field designator %0 does not refer to any field in type %1") -DIAG(err_field_designator_nonfield, ERROR, - "field designator %0 does not refer to a non-static data member") -DIAG(note_field_designator_found, NOTE, - "field designator refers here") -DIAG(err_designator_for_scalar_init, ERROR, - "designator in initializer for scalar type %0") - -// Declarations. -DIAG(err_typename_requires_specqual, ERROR, - "type name requires a specifier or qualifier") -DIAG(err_typename_invalid_storageclass, ERROR, - "type name does not allow storage class to be specified") -DIAG(err_typename_invalid_functionspec, ERROR, - "type name does not allow function specifier to be specified") -DIAG(err_invalid_decl_spec_combination, ERROR, - "cannot combine with previous '%0' declaration specifier") -DIAG(err_invalid_sign_spec, ERROR, - "'%0' cannot be signed or unsigned") -DIAG(ext_invalid_sign_spec, EXTENSION, - "'%0' cannot be signed or unsigned") -DIAG(err_invalid_short_spec, ERROR, - "'short %0' is invalid") -DIAG(err_invalid_long_spec, ERROR, - "'long %0' is invalid") -DIAG(err_invalid_longlong_spec, ERROR, - "'long long %0' is invalid") -DIAG(ext_longlong, EXTENSION, - "'long long' is an extension when C99 mode is not enabled") -DIAG(err_invalid_complex_spec, ERROR, - "'_Complex %0' is invalid") -DIAG(err_invalid_thread_spec, ERROR, - "'__thread %0' is invalid") -DIAG(err_ellipsis_first_arg, ERROR, - "ISO C requires a named argument before '...'") -DIAG(err_unspecified_vla_size_with_static, ERROR, - "'static' may not be used with an unspecified variable length array size") -DIAG(ext_vla, EXTENSION, - "variable length arrays are a C99 feature, accepted as an extension") -DIAG(err_invalid_storage_class_in_func_decl, ERROR, - "invalid storage class specifier in function declarator") -DIAG(ext_anon_param_requires_type_specifier, EXTENSION, - "type specifier required for unnamed parameter, defaults to int") -DIAG(err_missing_param, ERROR, - "expected parameter declarator") -DIAG(err_bad_variable_name, ERROR, - "'%0' cannot be the name of a variable or data member") -DIAG(err_parameter_name_omitted, ERROR, - "parameter name omitted") -DIAG(warn_decl_in_param_list, WARNING, - "declaration of %0 will not be visible outside of this function") - -DIAG(err_declarator_need_ident, ERROR, - "declarator requires an identifier") -DIAG(err_bad_language, ERROR, - "unknown linkage language") - -// C++ class members -DIAG(err_storageclass_invalid_for_member, ERROR, - "storage class specified for a member declaration") -DIAG(err_mutable_function, ERROR, - "'mutable' cannot be applied to functions") -DIAG(err_mutable_reference, ERROR, - "'mutable' cannot be applied to references") -DIAG(err_mutable_const, ERROR, - "'mutable' and 'const' cannot be mixed") -DIAG(err_mutable_nonmember, ERROR, - "'mutable' can only be applied to member variables") -DIAG(err_virtual_non_function, ERROR, - "'virtual' can only appear on non-static member functions") -DIAG(err_not_bitfield_type, ERROR, - "cannot declare %0 to be a bit-field type") -DIAG(err_static_not_bitfield, ERROR, - "static member %0 cannot be a bit-field") -DIAG(err_not_integral_type_bitfield, ERROR, - "bit-field %0 with non-integral type") -DIAG(err_member_initialization, ERROR, - "%0 can only be initialized if it is a static const integral data member") -DIAG(err_member_function_initialization, ERROR, - "initializer on function does not look like a pure-specifier") -DIAG(err_non_virtual_pure, ERROR, - "%0 is not virtual and cannot be declared pure") -DIAG(err_implicit_object_parameter_init, ERROR, - "cannot initialize object parameter of type %0 with an expression of type %1") - -// C++ constructors -DIAG(err_constructor_cannot_be, ERROR, - "constructor cannot be declared '%0'") -DIAG(err_invalid_qualified_constructor, ERROR, - "'%0' qualifier is not allowed on a constructor") -DIAG(err_constructor_return_type, ERROR, - "constructor cannot have a return type") -DIAG(err_constructor_redeclared, ERROR, - "constructor cannot be redeclared") -DIAG(err_constructor_byvalue_arg, ERROR, - "copy constructor must pass its first argument by reference") - -// C++ destructors -DIAG(err_destructor_not_member, ERROR, - "destructor must be a non-static member function") -DIAG(err_destructor_cannot_be, ERROR, - "destructor cannot be declared '%0'") -DIAG(err_invalid_qualified_destructor, ERROR, - "'%0' qualifier is not allowed on a destructor") -DIAG(err_destructor_return_type, ERROR, - "destructor cannot have a return type") -DIAG(err_destructor_redeclared, ERROR, - "destructor cannot be redeclared") -DIAG(err_destructor_with_params, ERROR, - "destructor cannot have any parameters") -DIAG(err_destructor_variadic, ERROR, - "destructor cannot be variadic") -DIAG(err_destructor_typedef_name, ERROR, - "destructor cannot be declared using a typedef %0 of the class name") - -// C++ initialization -// FIXME: passing in an English string as %1! -DIAG(err_not_reference_to_const_init, ERROR, - "non-const reference to type %0 cannot be initialized with a %1 of type %2") -// FIXME: passing in an English string as %1! -DIAG(err_reference_init_drops_quals, ERROR, - "initialization of reference to type %0 with a %1 of type %2 drops qualifiers") -DIAG(err_reference_var_requires_init, ERROR, - "declaration of reference variable %0 requires an initializer") -DIAG(err_const_var_requires_init, ERROR, - "declaration of const variable '%0' requires an initializer") -DIAG(err_init_non_aggr_init_list, ERROR, - "initialization of non-aggregate type %0 with an initializer list") - -// Objective-C++ -DIAG(err_objc_decls_may_only_appear_in_global_scope, ERROR, - "Objective-C declarations may only appear in global scope") - -// Attributes -DIAG(err_attribute_can_be_applied_only_to_symbol_declaration, ERROR, - "%0 attribute can be applied only to symbol declaration") -DIAG(err_attributes_are_not_compatible, ERROR, - "%0 and %1 attributes are not compatible") -DIAG(err_attribute_wrong_number_arguments, ERROR, - "attribute requires %0 argument(s)") -DIAG(err_attribute_missing_parameter_name, ERROR, - "attribute requires unquoted parameter") -DIAG(err_attribute_invalid_vector_type, ERROR, - "invalid vector type %0") -DIAG(err_attribute_argument_not_int, ERROR, - "'%0' attribute requires integer constant") -DIAG(err_attribute_argument_n_not_int, ERROR, - "'%0' attribute requires parameter %1 to be an integer constant") -DIAG(err_attribute_argument_n_not_string, ERROR, - "'%0' attribute requires parameter %1 to be a string") -DIAG(err_attribute_argument_out_of_bounds, ERROR, - "'%0' attribute parameter %1 is out of bounds") -DIAG(err_nonnull_pointers_only, ERROR, - "nonnull attribute only applies to pointer arguments") -DIAG(err_format_strftime_third_parameter, ERROR, - "strftime format attribute requires 3rd parameter to be 0") -DIAG(err_format_attribute_requires_variadic, ERROR, - "format attribute requires variadic function") -DIAG(err_format_attribute_not, ERROR, - "format argument not %0") -DIAG(err_attribute_invalid_size, ERROR, - "vector size not an integral multiple of component size") -DIAG(err_attribute_zero_size, ERROR, - "zero vector size") -DIAG(err_typecheck_vector_not_convertable, ERROR, - "can't convert between vector values of different size (%0 and %1)") -DIAG(err_typecheck_ext_vector_not_typedef, ERROR, - "ext_vector_type only applies to types, not variables") -DIAG(err_ext_vector_component_exceeds_length, ERROR, - "vector component access exceeds type %0") -DIAG(err_ext_vector_component_requires_even, ERROR, - "vector component access invalid for odd-sized type %0") -DIAG(err_ext_vector_component_name_illegal, ERROR, - "illegal vector component name '%0'") -DIAG(err_attribute_address_space_not_int, ERROR, - "address space attribute requires an integer constant") -DIAG(err_attribute_address_multiple_qualifiers, ERROR, - "multiple address spaces specified for type") -DIAG(err_implicit_pointer_address_space_cast, ERROR, - "illegal implicit cast between two pointers with different address spaces") -DIAG(err_as_qualified_auto_decl, ERROR, - "automatic variable qualified with an address space") -DIAG(err_attribute_annotate_no_string, ERROR, - "argument to annotate attribute was not a string literal") -DIAG(warn_redeclaration_without_attribute_prev_attribute_ignored, WARNING, - "'%0' redeclared without %1 attribute: previous %1 ignored") -DIAG(warn_attribute_ignored, WARNING, - "%0 attribute ignored") -DIAG(warn_attribute_weak_on_field, WARNING, - "__weak attribute cannot be specified on a field declaration") -DIAG(warn_attribute_wrong_decl_type, WARNING, - "'%0' attribute only applies to %1 types") -DIAG(warn_attribute_ignored_for_field_of_type, WARNING, - "%0 attribute ignored for field of type %1") -DIAG(warn_attribute_type_not_supported, WARNING, - "'%0' attribute argument not supported: %1") -DIAG(warn_attribute_unknown_visibility, WARNING, - "unknown visibility '%1'") -DIAG(err_unknown_machine_mode, ERROR, - "unknown machine mode %0") -DIAG(err_unsupported_machine_mode, ERROR, - "unsupported machine mode %0") -DIAG(err_mode_not_primitive, ERROR, - "mode attribute only supported for integer and floating-point types") -DIAG(err_mode_wrong_type, ERROR, - "type of machine mode does not match type of base type") -DIAG(err_attr_wrong_decl, ERROR, - "'%0' attribute invalid on this declaration, requires typedef or value") -DIAG(warn_attribute_nonnull_no_pointers, WARNING, - "'nonnull' attribute applied to function with no pointer arguments") -DIAG(warn_transparent_union_nonpointer, WARNING, - "'transparent_union' attribute support incomplete; only supported for" - "pointer unions") -DIAG(warn_attribute_sentinel_not_variadic, WARNING, - "'sentinel' attribute only supported for variadic functions") -DIAG(err_attribute_sentinel_less_than_zero, ERROR, - "'sentinel' parameter 1 less than zero") -DIAG(err_attribute_sentinel_not_zero_or_one, ERROR, - "'sentinel' parameter 2 not 0 or 1") - -// Clang-Specific Attributes -DIAG(err_attribute_iboutlet_non_ivar, ERROR, - "'iboutlet' attribute can only be applied to instance variables") - -// Function Parameter Semantic Analysis. -DIAG(err_argument_required_after_attribute, ERROR, - "argument required after attribute") -DIAG(err_param_with_void_type, ERROR, - "argument may not have 'void' type") -DIAG(err_void_only_param, ERROR, - "'void' must be the first and only parameter if specified") -DIAG(err_void_param_qualified, ERROR, - "'void' as parameter must not have type qualifiers") -DIAG(err_param_redefinition, ERROR, - "redefinition of parameter %0") -DIAG(err_ident_list_in_fn_declaration, ERROR, - "a parameter list without types is only allowed in a function definition") -DIAG(err_declaration_does_not_declare_param, ERROR, - "declaration does not declare a parameter") -DIAG(err_no_matching_param, ERROR, - "parameter named %0 is missing") -DIAG(ext_param_not_declared, EXTENSION, - "parameter %0 was not declared, defaulting to type 'int'") -DIAG(ext_param_typedef_of_void, EXTENSION, - "empty parameter list defined with a typedef of 'void' not allowed in C++") -DIAG(err_param_default_argument, ERROR, - "C does not support default arguments") -DIAG(err_param_default_argument_redefinition, ERROR, - "redefinition of default argument") -DIAG(err_param_default_argument_missing, ERROR, - "missing default argument on parameter") -DIAG(err_param_default_argument_missing_name, ERROR, - "missing default argument on parameter %0") -DIAG(err_param_default_argument_references_param, ERROR, - "default argument references parameter %0") -DIAG(err_param_default_argument_references_local, ERROR, - "default argument references local variable %0 of enclosing function") -DIAG(err_param_default_argument_references_this, ERROR, - "default argument references 'this'") -DIAG(err_param_default_argument_nonfunc, ERROR, - "default arguments can only be specified for parameters in a function" - " declaration") - -// C++ Overloading Semantic Analysis. -DIAG(err_ovl_diff_return_type, ERROR, - "functions that differ only in their return type cannot be overloaded") -DIAG(err_ovl_static_nonstatic_member, ERROR, - "static and non-static member functions with the same parameter types " - "cannot be overloaded") -DIAG(err_ovl_no_viable_function_in_call, ERROR, - "no matching function for call to %0" - "%plural{0:|1:; candidate is|:; candidates are:}1") -DIAG(err_ovl_no_viable_member_function_in_call, ERROR, - "no matching member function for call to %0" - "%plural{0:|1:; candidate is|:; candidates are:}1") -DIAG(err_ovl_ambiguous_call, ERROR, - "call to %0 is ambiguous; candidates are:") -DIAG(err_ovl_ambiguous_member_call, ERROR, - "call to member function %0 is ambiguous; candidates are:") -DIAG(err_ovl_candidate, NOTE, - "candidate function") -DIAG(err_ovl_builtin_candidate, NOTE, - "built-in candidate function %0") -DIAG(err_ovl_no_viable_function_in_init, ERROR, - "no matching constructor for initialization of %0" - "%plural{0:|1:; candidate is|:; candidates are:}1") -DIAG(err_ovl_ambiguous_init, ERROR, - "call to constructor of %0 is ambiguous; candidates are:") -DIAG(err_ovl_ambiguous_oper, ERROR, - "use of overloaded operator '%0' is ambiguous; candidates are:") -DIAG(err_ovl_no_viable_oper, ERROR, - "no viable overloaded '%0'; candidate%plural{1: is|:s are}1:") -DIAG(err_ovl_no_viable_object_call, ERROR, - "no matching function for call to object of type %0" - "%plural{0:|1:; candidate is|:; candidates are:}1") -DIAG(err_ovl_ambiguous_object_call, ERROR, - "call to object of type %0 is ambiguous; candidates are:") -DIAG(err_ovl_surrogate_cand, NOTE, - "conversion candidate of type %0") -DIAG(err_member_call_without_object, ERROR, - "call to non-static member function without an object argument") - -/// C++ Templates Semantic Analysis -DIAG(err_template_param_shadow, ERROR, - "declaration of %0 shadows template parameter") -DIAG(note_template_param_here, NOTE, - "template parameter is declared here") -DIAG(note_template_export_unsupported, NOTE, - "exported templates are unsupported") - -DIAG(err_unexpected_typedef, ERROR, - "unexpected type name %0: expected expression") -DIAG(err_unexpected_namespace, ERROR, - "unexpected namespace name %0: expected expression") -DIAG(err_unexpected_typedef_ident, ERROR, - "unexpected type name %0: expected identifier") -DIAG(err_undeclared_var_use, ERROR, - "use of undeclared identifier %0") -DIAG(err_undeclared_use, ERROR, - "use of undeclared '%0'") -DIAG(warn_deprecated, WARNING, - "%0 is deprecated") -DIAG(warn_unavailable, WARNING, - "%0 is unavailable") -DIAG(err_redefinition, ERROR, - "redefinition of %0") -DIAG(err_static_non_static, ERROR, - "static declaration of %0 follows non-static declaration") -DIAG(err_non_static_static, ERROR, - "non-static declaration of %0 follows static declaration") -DIAG(err_redefinition_different_type, ERROR, - "redefinition of %0 with a different type") -DIAG(err_redefinition_different_kind, ERROR, - "redefinition of %0 as different kind of symbol") -DIAG(err_redefinition_different_typedef, ERROR, - "typedef redefinition with different types (%0 vs %1)") -DIAG(err_conflicting_types, ERROR, - "conflicting types for %0") -DIAG(err_nested_redefinition, ERROR, - "nested redefinition of %0") -DIAG(err_use_with_wrong_tag, ERROR, - "use of %0 with tag type that does not match previous declaration") -DIAG(ext_forward_ref_enum, EXTENSION, - "ISO C forbids forward references to 'enum' types") -DIAG(err_redefinition_of_enumerator, ERROR, - "redefinition of enumerator %0") -DIAG(err_duplicate_member, ERROR, - "duplicate member %0") -DIAG(ext_enum_value_not_int, EXTENSION, - "ISO C restricts enumerator values to range of 'int' (%0 is too large)") -DIAG(warn_enum_too_large, WARNING, - "enumeration values exceed range of largest integer") -DIAG(warn_illegal_constant_array_size, EXTENSION, - "size of static array must be an integer constant expression") -DIAG(err_vla_decl_in_file_scope, ERROR, - "variable length array declaration not allowed at file scope") -DIAG(err_vla_decl_has_static_storage, ERROR, - "variable length array declaration can not have 'static' storage duration") -DIAG(err_vla_decl_has_extern_linkage, ERROR, - "variable length array declaration can not have 'extern' linkage") -DIAG(err_vm_decl_in_file_scope, ERROR, - "variably modified type declaration not allowed at file scope") -DIAG(err_vm_decl_has_extern_linkage, ERROR, - "variably modified type declaration can not have 'extern' linkage") -DIAG(err_typecheck_field_variable_size, ERROR, - "fields must have a constant size") -DIAG(err_typecheck_negative_array_size, ERROR, - "array size is negative") -DIAG(warn_typecheck_function_qualifiers, WARNING, - "qualifier on function type %0 has unspecified behavior") -DIAG(err_typecheck_invalid_restrict_not_pointer, ERROR, - "restrict requires a pointer or reference (%0 is invalid)") -DIAG(err_typecheck_invalid_restrict_invalid_pointee, ERROR, - "pointer to function type %0 may not be 'restrict' qualified") -DIAG(ext_typecheck_zero_array_size, EXTENSION, - "zero size arrays are an extension") -DIAG(err_at_least_one_initializer_needed_to_size_array, ERROR, - "at least one initializer value required to size array") -DIAG(err_array_size_non_int, ERROR, - "size of array has non-integer type %0") -DIAG(err_init_element_not_constant, ERROR, - "initializer element is not a compile-time constant") -DIAG(err_block_extern_cant_init, ERROR, - "'extern' variable cannot have an initializer") -DIAG(warn_extern_init, WARNING, - "'extern' variable has an initializer") -DIAG(err_variable_object_no_init, ERROR, - "variable-sized object may not be initialized") -DIAG(err_array_init_list_required, ERROR, - "initialization with '{...}' expected for array") -DIAG(warn_excess_initializers, WARNING, - "excess elements in array initializer") -DIAG(err_excess_initializers_in_char_array_initializer, ERROR, - "excess elements in char array initializer") -DIAG(warn_initializer_string_for_char_array_too_long, WARNING, - "initializer-string for char array is too long") -DIAG(warn_braces_around_scalar_init, WARNING, - "braces around scalar initializer") -DIAG(err_many_braces_around_scalar_init, ERROR, - "too many braces around scalar initializer") -DIAG(err_empty_scalar_initializer, ERROR, - "scalar initializer cannot be empty") -DIAG(err_illegal_initializer, ERROR, - "illegal initializer (only variables can be initialized)") -DIAG(err_illegal_initializer_type, ERROR, - "illegal initializer type %0") -DIAG(err_implicit_empty_initializer, ERROR, - "initializer for aggregate with no elements requires explicit braces") -DIAG(err_bitfield_has_negative_width, ERROR, - "bit-field %0 has negative width") -DIAG(err_bitfield_has_zero_width, ERROR, - "bit-field %0 has zero width") -DIAG(err_bitfield_width_exceeds_type_size, ERROR, - "size of bit-field %0 exceeds size of its type (%1 bits)") - -DIAG(err_redefinition_of_label, ERROR, - "redefinition of label '%0'") -DIAG(err_undeclared_label_use, ERROR, - "use of undeclared label '%0'") - -DIAG(warn_implicit_function_decl, WARNING, - "implicit declaration of function %0") -DIAG(ext_implicit_function_decl, EXTENSION, - "implicit declaration of function %0 is invalid in C99") - -DIAG(err_func_returning_array_function, ERROR, - "function cannot return array or function type %0") -DIAG(err_field_declared_as_function, ERROR, - "field %0 declared as a function") -DIAG(err_field_incomplete, ERROR, - "field has incomplete type %0") -DIAG(err_variable_sized_type_in_struct, EXTENSION, - "variable sized type %0 must be at end of struct or class") -DIAG(err_flexible_array_empty_struct, ERROR, - "flexible array %0 not allowed in otherwise empty struct") -DIAG(ext_flexible_array_in_struct, EXTENSION, - "%0 may not be nested in a struct due to flexible array member") -DIAG(err_flexible_array_in_array, ERROR, - "%0 may not be used as an array element due to flexible array member") -DIAG(err_illegal_decl_array_of_functions, ERROR, - "'%0' declared as array of functions") -DIAG(err_illegal_decl_array_incomplete_type, ERROR, - "array has incomplete element type %0") -DIAG(err_illegal_decl_array_of_references, ERROR, - "'%0' declared as array of references") -DIAG(err_illegal_decl_pointer_to_reference, ERROR, - "'%0' declared as a pointer to a reference") -DIAG(err_illegal_decl_mempointer_to_void, ERROR, - "'%0' declared as a member pointer to void") -DIAG(err_illegal_decl_mempointer_in_nonclass, ERROR, - "'%0' does not point into a class") -DIAG(err_illegal_decl_reference_to_reference, ERROR, - "%0 declared as a reference to a reference") -DIAG(err_invalid_reference_qualifier_application, ERROR, - "'%0' qualifier may not be applied to a reference") -DIAG(err_reference_to_void, ERROR, - "cannot form a reference to 'void'") -DIAG(err_qualified_block_pointer_type, ERROR, - "qualifier specification on block pointer type not allowed") -DIAG(err_nonfunction_block_type, ERROR, - "block pointer to non-function type is invalid") -DIAG(err_return_block_has_expr, ERROR, - "void block should not return a value") -DIAG(err_block_return_missing_expr, ERROR, - "non-void block should return a value") -DIAG(err_block_with_return_type_requires_args, ERROR, - "block with explicit return type requires argument list") - -// Expressions. -DIAG(ext_sizeof_function_type, EXTENSION, - "invalid application of 'sizeof' to a function type") -DIAG(ext_sizeof_void_type, EXTENSION, - "invalid application of '%0' to a void type") -// FIXME: merge with %select -DIAG(err_sizeof_incomplete_type, ERROR, - "invalid application of 'sizeof' to an incomplete type %0") -DIAG(err_alignof_incomplete_type, ERROR, - "invalid application of '__alignof' to an incomplete type %0") -DIAG(err_sizeof_alignof_bitfield, ERROR, - "invalid application of '%select{sizeof|__alignof}0' to bitfield") -DIAG(err_offsetof_record_type, ERROR, - "offsetof requires struct, union, or class type, %0 invalid") -DIAG(err_offsetof_array_type, ERROR, - "offsetof requires array type, %0 invalid") -DIAG(ext_offsetof_extended_field_designator, EXTENSION, - "using extended field designator is an extension") -DIAG(err_expected_field_designator, ERROR, - "expected a field designator, such as '.field = 4'") - -DIAG(err_invalid_suffix_integer_constant, ERROR, - "invalid suffix '%0' on integer constant") -DIAG(err_invalid_suffix_float_constant, ERROR, - "invalid suffix '%0' on floating constant") -DIAG(ext_imaginary_constant, EXTENSION, - "imaginary constants are an extension") -DIAG(warn_integer_too_large, WARNING, - "integer constant is too large for its type") -DIAG(warn_integer_too_large_for_signed, WARNING, - "integer constant is so large that it is unsigned") -DIAG(err_exponent_has_no_digits, ERROR, - "exponent has no digits") -DIAG(ext_binary_literal, EXTENSION, - "binary integer literals are an extension") -DIAG(err_invalid_binary_digit, ERROR, - "invalid digit '%0' in binary constant") -DIAG(err_invalid_octal_digit, ERROR, - "invalid digit '%0' in octal constant") -DIAG(err_invalid_decimal_digit, ERROR, - "invalid digit '%0' in decimal constant") -DIAG(err_hexconstant_requires_exponent, ERROR, - "hexadecimal floating constants require an exponent") -DIAG(ext_hexconstant_invalid, EXTENSION, - "hexadecimal floating constants are a C99 feature") -DIAG(err_typecheck_subscript_value, ERROR, - "subscripted value is neither array nor pointer") -DIAG(err_typecheck_subscript, ERROR, - "array subscript is not an integer") -DIAG(err_typecheck_subscript_not_object, ERROR, - "illegal subscript of non-object type %0") -DIAG(err_typecheck_member_reference_struct_union, ERROR, - "member reference base type %0 is not a structure or union") -DIAG(err_typecheck_member_reference_ivar, ERROR, - "%0 does not have a member named %1") -DIAG(err_typecheck_member_reference_arrow, ERROR, - "member reference type %0 is not a pointer") -DIAG(err_typecheck_member_reference_type, ERROR, - "cannot refer to type member %0 with '%select{.|->}1'") -DIAG(err_typecheck_member_reference_unknown, ERROR, - "cannot refer to member %0 with '%select{.|->}1'") -DIAG(err_typecheck_incomplete_tag, ERROR, - "incomplete definition of type %0") -DIAG(err_typecheck_no_member, ERROR, - "no member named %0") -DIAG(err_member_redeclared, ERROR, - "class member cannot be redeclared") -DIAG(err_member_def_does_not_match, ERROR, - "out-of-line definition does not match any declaration in %0") -DIAG(err_nonstatic_member_out_of_line, ERROR, - "non-static data member defined out-of-line") -DIAG(err_qualified_typedef_declarator, ERROR, - "typedef declarator cannot be qualified") -DIAG(err_qualified_param_declarator, ERROR, - "parameter declarator cannot be qualified") -DIAG(err_out_of_line_declaration, ERROR, - "out-of-line declaration of a member must be a definition") -DIAG(note_member_def_close_match, NOTE, - "member declaration nearly matches") -DIAG(err_typecheck_ivar_variable_size, ERROR, - "instance variables must have a constant size") -// FIXME: Improve with %select -DIAG(err_typecheck_illegal_increment_decrement, ERROR, - "cannot modify value of type %0") -DIAG(err_typecheck_arithmetic_incomplete_type, ERROR, - "arithmetic on pointer to incomplete type %0") -DIAG(err_typecheck_pointer_arith_function_type, ERROR, - "arithmetic on pointer to function type %0") -DIAG(err_typecheck_pointer_arith_void_type, ERROR, - "arithmetic on pointer to void type") -DIAG(err_typecheck_decl_incomplete_type, ERROR, - "variable has incomplete type %0") -// FIXME: Use %select -DIAG(err_realimag_invalid_type, ERROR, - "invalid type %0 to __real or __imag operator") -DIAG(err_typecheck_sclass_fscope, ERROR, - "illegal storage class on file-scoped variable") -DIAG(err_typecheck_sclass_func, ERROR, - "illegal storage class on function") -DIAG(err_typecheck_address_of, ERROR, - "address of %0 requested") -DIAG(err_typecheck_invalid_lvalue_addrof, ERROR, - "address expression must be an lvalue or a function designator") -DIAG(err_typecheck_unary_expr, ERROR, - "invalid argument type %0 to unary expression") -DIAG(err_typecheck_indirection_requires_pointer, ERROR, - "indirection requires pointer operand (%0 invalid)") -DIAG(err_typecheck_invalid_operands, ERROR, - "invalid operands to binary expression (%0 and %1)") -DIAG(err_typecheck_sub_ptr_object, ERROR, - "subtraction of pointer %0 requires pointee to be a complete object type") -DIAG(err_typecheck_sub_ptr_compatible, ERROR, - "%0 and %1 are not pointers to compatible types") -DIAG(ext_typecheck_comparison_of_pointer_integer, WARNING, - "comparison between pointer and integer (%0 and %1)") -DIAG(ext_typecheck_comparison_of_distinct_pointers, WARNING, - "comparison of distinct pointer types (%0 and %1)") -DIAG(err_typecheck_assign_const, ERROR, - "read-only variable is not assignable") -DIAG(err_stmtexpr_file_scope, ERROR, - "statement expression not allowed at file scope") - -DIAG(err_invalid_this_use, ERROR, - "invalid use of 'this' outside of a nonstatic member function") -DIAG(err_invalid_member_use_in_static_method, ERROR, - "invalid use of member %0 in static member function") -DIAG(err_invalid_qualified_function_type, ERROR, - "type qualifier is not allowed on this function") -DIAG(err_invalid_qualified_typedef_function_type_use, ERROR, - "a qualified function type cannot be used to declare a nonmember function " - "or a static member function") -DIAG(err_invalid_non_static_member_use, ERROR, - "invalid use of nonstatic data member %0") -DIAG(err_invalid_incomplete_type_use, ERROR, - "invalid use of incomplete type %0") -DIAG(err_builtin_func_cast_more_than_one_arg, ERROR, - "function-style cast to a builtin type can only take one argument") -DIAG(err_builtin_direct_init_more_than_one_arg, ERROR, - "initializer of a builtin type can only take one argument") -DIAG(err_value_init_for_array_type, ERROR, - "array types cannot be value-initialized") - -// C++ casts -DIAG(err_bad_cxx_cast_generic, ERROR, - "%0 from %2 to %1 is not allowed") -DIAG(err_bad_cxx_cast_rvalue, ERROR, - "%0 from rvalue to reference type %1") -DIAG(err_bad_cxx_cast_const_away, ERROR, - "%0 from %2 to %1 casts away constness") -DIAG(err_bad_const_cast_dest, ERROR, - "const_cast to %0, which is not a reference, pointer-to-object, " - "or pointer-to-data-member") -DIAG(err_bad_reinterpret_cast_same_type, ERROR, - "source and destination type of reinterpret_cast are not distinct") -DIAG(ext_reinterpret_cast_fn_obj, EXTENSION, - "reinterpret_cast between pointer-to-function and pointer-to-object is " - "an extension") -DIAG(err_bad_reinterpret_cast_small_int, ERROR, - "cast from pointer to smaller type %0 loses information") -DIAG(err_bad_dynamic_cast_not_ref_or_ptr, ERROR, - "%0 is not a reference or pointer") -DIAG(err_bad_dynamic_cast_not_class, ERROR, - "%0 is not a class") -DIAG(err_bad_dynamic_cast_incomplete, ERROR, - "%0 is an incomplete type") -DIAG(err_bad_dynamic_cast_not_ptr, ERROR, - "%0 is not a pointer") -DIAG(err_bad_dynamic_cast_not_polymorphic, ERROR, - "%0 is not polymorphic") -// FIXME: Display the path somehow better. -DIAG(err_ambiguous_base_to_derived_cast, ERROR, - "ambiguous static_cast from base %0 to derived %1:%2") -DIAG(err_static_downcast_via_virtual, ERROR, - "cannot cast %0 to %1 via virtual base %2") - -// Other C++ expressions -DIAG(err_need_header_before_typeid, ERROR, - "you need to include before using the 'typeid' operator") -DIAG(err_static_illegal_in_new, ERROR, - "the 'static' modifier for the array size is not legal in new expressions") -DIAG(err_array_new_needs_size, ERROR, - "array size must be specified in new expressions") -DIAG(err_bad_new_type, ERROR, - "cannot allocate %select{function|incomplete|reference}1 type %0 with new") -DIAG(err_new_array_nonconst, ERROR, - "only the first dimension of an allocated array may be non-const") -DIAG(err_array_size_not_integral, ERROR, - "array size expression must have integral or enumerated type, not %0") -DIAG(err_new_uninitialized_const, ERROR, - "must provide an initializer if the allocated object is 'const'") -DIAG(err_delete_operand, ERROR, - "cannot delete expression of type %0") -DIAG(warn_delete_incomplete, WARNING, - "deleting pointer to incomplete type %0 may cause undefined behaviour") -DIAG(err_decrement_bool, ERROR, - "cannot decrement expression of type bool") -DIAG(warn_increment_bool, WARNING, - "incrementing expression of type bool is deprecated") -DIAG(err_catch_incomplete_ptr, ERROR, - "cannot catch pointer to incomplete type %0") -DIAG(err_catch_incomplete_ref, ERROR, - "cannot catch reference to incomplete type %0") -DIAG(err_catch_incomplete, ERROR, - "cannot catch incomplete type %0") -DIAG(err_qualified_catch_declarator, ERROR, - "exception declarator cannot be qualified") -DIAG(err_early_catch_all, ERROR, - "catch-all handler must come last") - -DIAG(err_invalid_use_of_function_type, ERROR, - "a function type is not allowed here") -DIAG(err_invalid_use_of_array_type, ERROR, - "an array type is not allowed here") -DIAG(err_type_defined_in_condition, ERROR, - "types may not be defined in conditions") -DIAG(err_typecheck_bool_condition, ERROR, - "value of type %0 is not contextually convertible to 'bool'") -DIAG(err_expected_class_or_namespace, ERROR, - "expected a class or namespace") -DIAG(err_invalid_declarator_scope, ERROR, - "definition or redeclaration of %0 not in a namespace enclosing %1") -DIAG(err_invalid_declarator_in_function, ERROR, - "definition or redeclaration of %0 not allowed inside a function") -DIAG(err_not_tag_in_scope, ERROR, - "%0 does not name a tag member in the specified scope") - -DIAG(warn_value_always_zero, WARNING, - "%0 is always zero in this context") -DIAG(warn_value_always_false, WARNING, - "%0 is always false in this context") - -// assignment related diagnostics (also for argument passing, returning, etc). -// FIXME: %2 is an english string here. -DIAG(err_typecheck_convert_incompatible, ERROR, - "incompatible type %2 %1, expected %0") -DIAG(err_cannot_initialize_decl_noname, ERROR, - "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 of type %2") -DIAG(err_cannot_initialize_decl, ERROR, - "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2") -DIAG(warn_incompatible_qualified_id, WARNING, - "incompatible type %2 %1, expected %0") -DIAG(warn_incompatible_qualified_id_operands, WARNING, - "invalid operands to binary expression (%0 and %1)") -DIAG(ext_typecheck_convert_pointer_int, EXTWARN, - "incompatible pointer to integer conversion %2 %1, expected %0") -DIAG(ext_typecheck_convert_int_pointer, EXTWARN, - "incompatible integer to pointer conversion %2 %1, expected %0") -DIAG(ext_typecheck_convert_pointer_void_func, EXTENSION, - "%2 %1 converts between void* and function pointer, expected %0") -DIAG(ext_typecheck_convert_incompatible_pointer, EXTWARN, - "incompatible pointer types %2 %1, expected %0") -DIAG(ext_typecheck_convert_discards_qualifiers, EXTWARN, - "%2 %1 discards qualifiers, expected %0") -DIAG(err_int_to_block_pointer, ERROR, - "invalid conversion %2 integer %1, expected block pointer %0") -DIAG(err_typecheck_comparison_of_distinct_blocks, ERROR, - "comparison of distinct block types (%0 and %1)") -DIAG(ext_typecheck_convert_incompatible_block_pointer, EXTWARN, - "incompatible block pointer types %2 %1, expected %0") - -DIAG(err_typecheck_array_not_modifiable_lvalue, ERROR, - "array type %0 is not assignable") -DIAG(err_typecheck_non_object_not_modifiable_lvalue, ERROR, - "non-object type %0 is not assignable") -DIAG(err_typecheck_expression_not_modifiable_lvalue, ERROR, - "expression is not assignable") -DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, ERROR, - "incomplete type %0 is not assignable") -DIAG(err_typecheck_lvalue_casts_not_supported, ERROR, - "assignment to cast is illegal, lvalue casts are not supported") - -DIAG(err_typecheck_duplicate_vector_components_not_mlvalue, ERROR, - "vector is not assignable (contains duplicate components)") -DIAG(err_block_decl_ref_not_modifiable_lvalue, ERROR, - "variable is not assignable (missing __block type specifier)") -DIAG(err_typecheck_call_not_function, ERROR, - "called object type %0 is not a function or function pointer") -DIAG(err_typecheck_call_too_few_args, ERROR, - "too few arguments to %select{function|block|method}0 call") -DIAG(err_typecheck_call_too_many_args, ERROR, - "too many arguments to %select{function|block|method}0 call") -DIAG(warn_cannot_pass_non_pod_arg_to_vararg, WARNING, - "cannot pass object of non-POD type %0 through variadic " - "%select{function|block|method}1; call will abort at runtime") -DIAG(err_typecheck_closure_too_many_args, ERROR, - "too many arguments to closure call") -DIAG(err_typecheck_call_invalid_ordered_compare, ERROR, - "ordered compare requires two args of floating point type (%0 and %1)") -DIAG(err_typecheck_cond_expect_scalar, ERROR, - "used type %0 where arithmetic or pointer type is required") -DIAG(ext_typecheck_cond_one_void, EXTENSION, - "C99 forbids conditional expressions with only one void side") -DIAG(ext_typecheck_cast_nonscalar, EXTENSION, - "C99 forbids casting nonscalar type %0 to the same type") -DIAG(ext_typecheck_cast_to_union, EXTENSION, - "C99 forbids casts to union type") -DIAG(err_typecheck_cast_to_union_no_type, ERROR, - "cast to union type from type %0 not present in union") -DIAG(err_typecheck_expect_scalar_operand, ERROR, - "operand of type %0 where arithmetic or pointer type is required") -DIAG(err_typecheck_cond_incompatible_operands, ERROR, - "incompatible operand types (%0 and %1)") -DIAG(warn_typecheck_cond_incompatible_pointers, WARNING, - "pointer type mismatch (%0 and %1)") -DIAG(err_typecheck_choose_expr_requires_constant, ERROR, - "'__builtin_choose_expr' requires a constant expression") -DIAG(ext_typecheck_expression_not_constant_but_accepted, EXTENSION, - "expression is not a constant, but is accepted as one by GNU extensions") -DIAG(warn_unused_expr, WARNING, - "expression result unused") -DIAG(err_pascal_string_too_long, ERROR, - "Pascal string is too long") -DIAG(err_asm_wide_character, ERROR, - "wide string is invalid in 'asm'") -DIAG(err_asm_invalid_lvalue_in_output, ERROR, - "invalid lvalue in asm output") -DIAG(err_asm_invalid_output_constraint, ERROR, - "invalid output constraint '%0' in asm") -DIAG(err_asm_invalid_lvalue_in_input, ERROR, - "invalid lvalue in asm input for constraint '%0'") -DIAG(err_asm_invalid_input_constraint, ERROR, - "invalid input constraint '%0' in asm") -DIAG(err_asm_invalid_type_in_input, ERROR, - "invalid type %0 in asm input for constraint '%1'") -DIAG(err_asm_unknown_register_name, ERROR, - "unknown register name '%0' in asm") -DIAG(err_invalid_conversion_between_vectors, ERROR, - "invalid conversion between vector type %0 and %1 of different size") -DIAG(err_invalid_conversion_between_vector_and_integer, ERROR, - "invalid conversion between vector type %0 and integer type %1 " - "of different size") -DIAG(err_invalid_conversion_between_vector_and_scalar, ERROR, - "invalid conversion between vector type %0 and scalar type %1") -DIAG(err_overload_expr_requires_non_zero_constant, ERROR, - "overload requires a non-zero constant expression as first argument") -DIAG(err_overload_incorrect_fntype, ERROR, - "argument is not a function, or has wrong number of parameters") - -// FIXME: PASSING TYPES AS STRING. -DIAG(err_overload_no_match, ERROR, - "no matching overload found for arguments of type '%0'") -DIAG(err_overload_multiple_match, ERROR, - "more than one matching function found in __builtin_overload") - -// Classes. -DIAG(err_expected_class_name, ERROR, - "expected class name") -DIAG(err_anon_type_definition, ERROR, - "declaration of anonymous %0 must be a definition") - -// Namespaces. -DIAG(err_expected_namespace_name, ERROR, - "expected namespace name") - -// C++ member initializers. -DIAG(err_mem_init_not_member_or_class, ERROR, - "member initializer %0 does not name a non-static data member or base " - "class") -DIAG(err_base_init_does_not_name_class, ERROR, - "constructor initializer %0 does not name a class") -DIAG(err_base_init_direct_and_virtual, ERROR, - "base class initializer %0 names both a direct base class and an" - " inherited virtual base class") - -// C++ anonymous unions and GNU anonymous structs/unions -DIAG(ext_anonymous_union, EXTENSION, - "anonymous unions are a GNU extension in C") -DIAG(ext_anonymous_struct, EXTENSION, - "anonymous structs are a GNU extension") -DIAG(err_anonymous_union_not_static, ERROR, - "anonymous unions at namespace or global scope must be declared 'static'") -DIAG(err_anonymous_union_with_storage_spec, ERROR, - "anonymous union at class scope must not have a storage specifier") -DIAG(err_anonymous_struct_not_member, ERROR, - "anonymous %select{structs|structs and classes}0 must be %select{struct or union|class}0 members") -DIAG(err_anonymous_union_not_member, ERROR, - "anonymous unions must be struct or union members") -DIAG(err_anonymous_union_member_redecl, ERROR, - "member of anonymous union redeclares %0") -DIAG(err_anonymous_struct_member_redecl, ERROR, - "member of anonymous struct redeclares %0") -DIAG(err_anonymous_record_with_type, ERROR, - "types cannot be declared in an anonymous %select{struct|union}0") -DIAG(err_anonymous_record_with_function, ERROR, - "functions cannot be declared in an anonymous %select{struct|union}0") -DIAG(err_anonymous_record_with_static, ERROR, - "static members cannot be declared in an anonymous %select{struct|union}0") -DIAG(err_anonymous_record_bad_member, ERROR, - "anonymous %select{struct|union}0 can only contain non-static data members") -DIAG(err_anonymous_record_nonpublic_member, ERROR, - "anonymous %select{struct|union}0 cannot contain a %select{private|protected}1 data member") - -// C++ derived classes -DIAG(err_dup_virtual, ERROR, - "duplicate 'virtual' in base specifier") -DIAG(err_base_clause_on_union, ERROR, - "unions cannot have base classes") -DIAG(err_base_must_be_class, ERROR, - "base specifier must name a class") -DIAG(err_union_as_base_class, ERROR, - "unions cannot be base classes") -DIAG(err_incomplete_base_class, ERROR, - "base class has incomplete type") -DIAG(err_duplicate_base_class, ERROR, - "base class %0 specified more than once as a direct base class") -// FIXME: better way to display derivation? Pass entire thing into diagclient? -DIAG(err_ambiguous_derived_to_base_conv, ERROR, - "ambiguous conversion from derived class %0 to base class %1:%2") -DIAG(err_ambiguous_base_to_derived_memptr_conv, ERROR, - "ambiguous conversion from pointer to member of base class %0 " - "to pointer to member of derived class %1:%2") -DIAG(err_memptr_conv_via_virtual, ERROR, - "conversion from pointer to member of class %0 to pointer to member " - "of class %1 via virtual base %2 is not allowed") - -// C++ member name lookup -DIAG(err_ambiguous_member_multiple_subobjects, ERROR, - "non-static member %0 found in multiple base-class subobjects of type %1:%2") -DIAG(err_ambiguous_member_multiple_subobject_types, ERROR, - "member %0 found in multiple base classes of different types") -DIAG(note_ambiguous_member_found, NOTE, - "member found by ambiguous name lookup") - -// C++ operator overloading -DIAG(err_operator_overload_needs_class_or_enum, ERROR, - "overloaded %0 must have at least one parameter of class " - "or enumeration type") -DIAG(err_operator_overload_variadic, ERROR, - "overloaded %0 cannot be variadic") -DIAG(err_operator_overload_static, ERROR, - "overloaded %0 cannot be a static member function") -DIAG(err_operator_overload_default_arg, ERROR, - "parameter of overloaded %0 cannot have a default argument") -DIAG(err_operator_overload_must_be, ERROR, - "overloaded %0 must be a %select{unary|binary|unary or binary}2 operator" - " (has %1 parameter%s1)") -DIAG(err_operator_overload_must_be_member, ERROR, - "overloaded %0 must be a non-static member function") -DIAG(err_operator_overload_post_incdec_must_be_int, ERROR, - "parameter of overloaded post-%select{increment|decrement}1 operator must" - " have type 'int' (not %0)") -DIAG(err_operator_missing_type_specifier, ERROR, - "missing type specifier after 'operator'") - -// C++ conversion functions -DIAG(err_conv_function_not_member, ERROR, - "conversion function must be a non-static member function") -DIAG(err_conv_function_return_type, ERROR, - "conversion function cannot have a return type") -DIAG(err_conv_function_with_params, ERROR, - "conversion function cannot have any parameters") -DIAG(err_conv_function_variadic, ERROR, - "conversion function cannot be variadic") -DIAG(err_conv_function_to_array, ERROR, - "conversion function cannot convert to an array type") -DIAG(err_conv_function_to_function, ERROR, - "conversion function cannot convert to a function type") -DIAG(err_conv_function_redeclared, ERROR, - "conversion function cannot be redeclared") -DIAG(warn_conv_to_self_not_used, WARNING, - "conversion function converting %0 to itself will never be used") -DIAG(warn_conv_to_base_not_used, WARNING, - "conversion function converting %0 to its base class %1 will never be used") -DIAG(warn_conv_to_void_not_used, WARNING, - "conversion function converting %0 to %1 will never be used") - -DIAG(warn_not_compound_assign, WARNING, - "use of unary operator that may be intended as compound assignment (%0=)") - -// C++0x explicit conversion operators -DIAG(warn_explicit_conversion_functions, WARNING, - "explicit conversion functions are a C++0x extension") - -// CHECK: printf format string errors -DIAG(warn_printf_not_string_constant, WARNING, - "format string is not a string literal (potentially insecure)") -DIAG(warn_printf_write_back, WARNING, - "use of '%%n' in format string discouraged (potentially insecure)") -DIAG(warn_printf_insufficient_data_args, WARNING, - "more '%%' conversions than data arguments") -DIAG(warn_printf_too_many_data_args, WARNING, - "more data arguments than '%%' conversions") -DIAG(warn_printf_invalid_conversion, WARNING, - "invalid conversion '%0'") -DIAG(warn_printf_missing_format_string, WARNING, - "format string missing") -DIAG(warn_printf_empty_format_string, WARNING, - "format string is empty") -DIAG(warn_printf_format_string_is_wide_literal, WARNING, - "format string should not be a wide string") -DIAG(warn_printf_format_string_contains_null_char, WARNING, - "format string contains '\\0' within the string body") -DIAG(warn_printf_asterisk_width_missing_arg, WARNING, - "'*' specified field width is missing a matching 'int' argument") -DIAG(warn_printf_asterisk_precision_missing_arg, WARNING, - "'.*' specified field precision is missing a matching 'int' argument") -DIAG(warn_printf_asterisk_width_wrong_type, WARNING, - "field width should have type 'int', but argument has type %0") -DIAG(warn_printf_asterisk_precision_wrong_type, WARNING, - "field precision should have type 'int', but argument has type %0") - -// CHECK: returning address/reference of stack memory -DIAG(warn_ret_stack_addr, WARNING, - "address of stack memory associated with local variable %0 returned") -DIAG(warn_ret_stack_ref, WARNING, - "reference to stack memory associated with local variable %0 returned") - -// CHECK: floating point values should not use "==" or "!=" -DIAG(warn_floatingpoint_eq, WARNING, - "comparing floating point with == or != is unsafe") - -// CHECK: for non-floating point, expressions of the form x == x or x != x -// should result in a warning, since these always evaluate to a constant. -DIAG(warn_selfcomparison,WARNING, - "self-comparison always results in a constant value.") - -// CHECK: use of uninitialized values -DIAG(warn_uninit_val, WARNING, "use of uninitialized variable") - -// Blocks -DIAG(err_expected_block_lbrace, ERROR, - "expected '{' in block literal") -DIAG(err_goto_in_block, ERROR, - "goto not allowed in block literal") -DIAG(err_return_in_block_expression, ERROR, - "return not allowed in block expression literal") - -DIAG(err_ret_local_block, ERROR, - "returning block that lives on the local stack") - -// CFString checking -DIAG(err_cfstring_literal_not_string_constant, ERROR, - "CFString literal is not a string constant") -DIAG(warn_cfstring_literal_contains_non_ascii_character, WARNING, - "CFString literal contains non-ASCII character") -DIAG(warn_cfstring_literal_contains_nul_character, WARNING, - "CFString literal contains NUL character") - -// Statements. -DIAG(err_continue_not_in_loop, ERROR, - "'continue' statement not in loop statement") -DIAG(err_break_not_in_loop_or_switch, ERROR, - "'break' statement not in loop or switch statement") -DIAG(err_default_not_in_switch, ERROR, - "'default' statement not in switch statement") -DIAG(err_case_not_in_switch, ERROR, - "'case' statement not in switch statement") -DIAG(warn_case_value_overflow, WARNING, - "overflow converting case value to switch condition type (%0 to %1)") -DIAG(err_duplicate_case, ERROR, - "duplicate case value '%0'") -DIAG(warn_case_empty_range, WARNING, - "empty case range specified") -DIAG(err_typecheck_statement_requires_scalar, ERROR, - "statement requires expression of scalar type (%0 invalid)") -DIAG(err_typecheck_statement_requires_integer, ERROR, - "statement requires expression of integer type (%0 invalid)") -DIAG(err_multiple_default_labels_defined, ERROR, - "multiple default labels in one switch") -DIAG(warn_empty_if_body, WARNING, - "if statement has empty body") -DIAG(err_va_start_used_in_non_variadic_function, ERROR, - "'va_start' used in function with fixed args") -DIAG(warn_second_parameter_of_va_start_not_last_named_argument, WARNING, - "second parameter of 'va_start' not last named argument") -DIAG(err_first_argument_to_va_arg_not_of_type_va_list, ERROR, - "first argument to 'va_arg' is of type %0 and not 'va_list'") - -DIAG(warn_return_missing_expr, WARNING, - "non-void %select{function|method}1 %0 should return a value") -DIAG(ext_return_missing_expr, EXTENSION, - "non-void %select{function|method}1 %0 should return a value") -DIAG(ext_return_has_expr, EXTWARN, - "void %select{function|method}1 %0 should not return a value") -DIAG(ext_return_has_void_expr, EXTENSION, - "void %select{function|method}1 %0 should not return void expression") - -DIAG(err_shufflevector_non_vector, ERROR, - "first two arguments to __builtin_shufflevector must be vectors") -DIAG(err_shufflevector_incompatible_vector, ERROR, - "first two arguments to __builtin_shufflevector must have the same type") -DIAG(err_shufflevector_nonconstant_argument, ERROR, - "index for __builtin_shufflevector must be a constant integer") -DIAG(err_shufflevector_argument_too_large, ERROR, - "index for __builtin_shufflevector must be less than the total number" - " of vector elements") - -DIAG(err_stack_const_level, ERROR, - "level argument for a stack address builtin must be constant") - -DIAG(err_prefetch_invalid_argument, ERROR, - "argument to __builtin_prefetch must be a constant integer") -DIAG(err_argument_invalid_range, ERROR, - "argument should be a value from %0 to %1") -DIAG(err_object_size_invalid_argument, ERROR, - "argument to __builtin_object_size must be a constant integer") +#include "clang/Basic/DiagnosticCommonKinds.def" +#include "clang/Basic/DiagnosticLexKinds.def" +#include "clang/Basic/DiagnosticParseKinds.def" +#include "clang/Basic/DiagnosticASTKinds.def" +#include "clang/Basic/DiagnosticSemaKinds.def" +#include "clang/Basic/DiagnosticAnalysisKinds.def" #undef DIAG diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index 43b45612b940..66261045a5b6 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -15,7 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/StmtVisitor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticAST.h" #include "clang/Basic/TargetInfo.h" #include "llvm/Support/Compiler.h" using namespace clang; diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp index 490aef2467be..3947803ee888 100644 --- a/clang/lib/Analysis/UninitializedValues.cpp +++ b/clang/lib/Analysis/UninitializedValues.cpp @@ -14,7 +14,7 @@ #include "clang/Analysis/Analyses/UninitializedValues.h" #include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h" #include "clang/Analysis/LocalCheckers.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticAnalysis.h" #include "clang/AST/ASTContext.h" #include "clang/Analysis/FlowSensitive/DataflowSolver.h" #include "llvm/Support/Compiler.h" diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp index 2271095b5963..ee0345b18d8a 100644 --- a/clang/lib/Basic/Diagnostic.cpp +++ b/clang/lib/Basic/Diagnostic.cpp @@ -36,29 +36,99 @@ enum { class_mask = 0x07 }; +namespace clang { + namespace diag { + enum _kind{ +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#define LEXSTART +#define PARSESTART +#define ASTSTART +#define SEMASTART +#define ANALYSISSTART +#include "clang/Basic/DiagnosticKinds.def" + NUM_BUILTIN_DIAGNOSTICS = DIAG_UPPER_LIMIT + }; + } +} + /// DiagnosticFlags - A set of flags, or'd together, that describe the /// diagnostic. -static unsigned char DiagnosticFlags[] = { #define DIAG(ENUM,FLAGS,DESC) FLAGS, -#include "clang/Basic/DiagnosticKinds.def" +static unsigned char DiagnosticFlagsCommon[] = { +#include "clang/Basic/DiagnosticCommonKinds.def" + 0 +}; +static unsigned char DiagnosticFlagsLex[] = { +#include "clang/Basic/DiagnosticLexKinds.def" + 0 +}; +static unsigned char DiagnosticFlagsParse[] = { +#include "clang/Basic/DiagnosticParseKinds.def" + 0 +}; +static unsigned char DiagnosticFlagsAST[] = { +#include "clang/Basic/DiagnosticASTKinds.def" + 0 +}; +static unsigned char DiagnosticFlagsSema[] = { +#include "clang/Basic/DiagnosticSemaKinds.def" + 0 +}; +static unsigned char DiagnosticFlagsAnalysis[] = { +#include "clang/Basic/DiagnosticAnalysisKinds.def" 0 }; +#undef DIAG /// getDiagClass - Return the class field of the diagnostic. /// static unsigned getBuiltinDiagClass(unsigned DiagID) { assert(DiagID < diag::NUM_BUILTIN_DIAGNOSTICS && "Diagnostic ID out of range!"); - return DiagnosticFlags[DiagID] & class_mask; + unsigned res; + if (DiagID < DIAG_START_LEX) + res = DiagnosticFlagsCommon[DiagID]; + else if (DiagID < DIAG_START_PARSE) + res = DiagnosticFlagsLex[DiagID - DIAG_START_LEX - 1]; + else if (DiagID < DIAG_START_AST) + res = DiagnosticFlagsParse[DiagID - DIAG_START_PARSE - 1]; + else if (DiagID < DIAG_START_SEMA) + res = DiagnosticFlagsAST[DiagID - DIAG_START_AST - 1]; + else if (DiagID < DIAG_START_ANALYSIS) + res = DiagnosticFlagsSema[DiagID - DIAG_START_SEMA - 1]; + else + res = DiagnosticFlagsAnalysis[DiagID - DIAG_START_ANALYSIS - 1]; + return res & class_mask; } /// DiagnosticText - An english message to print for the diagnostic. These /// should be localized. -static const char * const DiagnosticText[] = { #define DIAG(ENUM,FLAGS,DESC) DESC, -#include "clang/Basic/DiagnosticKinds.def" +static const char * const DiagnosticTextCommon[] = { +#include "clang/Basic/DiagnosticCommonKinds.def" + 0 +}; +static const char * const DiagnosticTextLex[] = { +#include "clang/Basic/DiagnosticLexKinds.def" + 0 +}; +static const char * const DiagnosticTextParse[] = { +#include "clang/Basic/DiagnosticParseKinds.def" 0 }; +static const char * const DiagnosticTextAST[] = { +#include "clang/Basic/DiagnosticASTKinds.def" + 0 +}; +static const char * const DiagnosticTextSema[] = { +#include "clang/Basic/DiagnosticSemaKinds.def" + 0 +}; +static const char * const DiagnosticTextAnalysis[] = { +#include "clang/Basic/DiagnosticAnalysisKinds.def" + 0 +}; +#undef DIAG //===----------------------------------------------------------------------===// // Custom Diagnostic information @@ -170,9 +240,22 @@ bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) { /// issue. const char *Diagnostic::getDescription(unsigned DiagID) const { if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS) - return DiagnosticText[DiagID]; - else - return CustomDiagInfo->getDescription(DiagID); + { + if (DiagID < DIAG_START_LEX) + return DiagnosticTextCommon[DiagID]; + else if (DiagID < DIAG_START_PARSE) + return DiagnosticTextLex[DiagID - DIAG_START_LEX - 1]; + else if (DiagID < DIAG_START_AST) + return DiagnosticTextParse[DiagID - DIAG_START_PARSE - 1]; + else if (DiagID < DIAG_START_SEMA) + return DiagnosticTextAST[DiagID - DIAG_START_AST - 1]; + else if (DiagID < DIAG_START_ANALYSIS) + return DiagnosticTextSema[DiagID - DIAG_START_SEMA - 1]; + else if (DiagID < DIAG_UPPER_LIMIT) + return DiagnosticTextAnalysis[DiagID - DIAG_START_ANALYSIS - 1]; + } + + return CustomDiagInfo->getDescription(DiagID); } /// getDiagnosticLevel - Based on the way the client configured the Diagnostic diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp index 986dd13d5d8f..2bf9300e9168 100644 --- a/clang/lib/Lex/Lexer.cpp +++ b/clang/lib/Lex/Lexer.cpp @@ -26,7 +26,7 @@ #include "clang/Lex/Lexer.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp index 76c90e4ed063..b06f9a4cf29c 100644 --- a/clang/lib/Lex/LiteralSupport.cpp +++ b/clang/lib/Lex/LiteralSupport.cpp @@ -14,7 +14,7 @@ #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/StringExtras.h" using namespace clang; diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp index 7a805f349f2d..63086ad27473 100644 --- a/clang/lib/Lex/MacroArgs.cpp +++ b/clang/lib/Lex/MacroArgs.cpp @@ -14,7 +14,7 @@ #include "MacroArgs.h" #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" using namespace clang; /// MacroArgs ctor function - This destroys the vector passed in. diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp index d277ec9dd47c..0ddd2292209f 100644 --- a/clang/lib/Lex/PPDirectives.cpp +++ b/clang/lib/Lex/PPDirectives.cpp @@ -15,7 +15,7 @@ #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/APInt.h" using namespace clang; diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp index 86f93e407a4f..73d677fe15b0 100644 --- a/clang/lib/Lex/PPExpressions.cpp +++ b/clang/lib/Lex/PPExpressions.cpp @@ -20,7 +20,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "llvm/ADT/APSInt.h" using namespace clang; diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp index e425f6b737ba..f00283bfbda9 100644 --- a/clang/lib/Lex/PPLexerChange.cpp +++ b/clang/lib/Lex/PPLexerChange.cpp @@ -15,7 +15,7 @@ #include "clang/Lex/Preprocessor.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/MemoryBuffer.h" diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp index a517b1d4f56e..fb7d22a5813e 100644 --- a/clang/lib/Lex/PPMacroExpansion.cpp +++ b/clang/lib/Lex/PPMacroExpansion.cpp @@ -17,7 +17,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/FileManager.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include using namespace clang; diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp index a80ba6bd1f1f..ad467630b163 100644 --- a/clang/lib/Lex/Pragma.cpp +++ b/clang/lib/Lex/Pragma.cpp @@ -16,7 +16,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/LiteralSupport.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/SourceManager.h" using namespace clang; diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp index 48fdd68ab9b2..c265c2c75d4b 100644 --- a/clang/lib/Lex/Preprocessor.cpp +++ b/clang/lib/Lex/Preprocessor.cpp @@ -30,7 +30,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Pragma.h" #include "clang/Lex/ScratchBuffer.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/APFloat.h" diff --git a/clang/lib/Lex/PreprocessorLexer.cpp b/clang/lib/Lex/PreprocessorLexer.cpp index e98afccbba08..f75ce429c65d 100644 --- a/clang/lib/Lex/PreprocessorLexer.cpp +++ b/clang/lib/Lex/PreprocessorLexer.cpp @@ -13,7 +13,7 @@ #include "clang/Lex/PreprocessorLexer.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "clang/Basic/SourceManager.h" using namespace clang; diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp index 40f6640cd75c..eaa49f36b9e2 100644 --- a/clang/lib/Lex/TokenLexer.cpp +++ b/clang/lib/Lex/TokenLexer.cpp @@ -16,7 +16,7 @@ #include "clang/Lex/MacroInfo.h" #include "clang/Lex/Preprocessor.h" #include "clang/Basic/SourceManager.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticLex.h" #include "llvm/ADT/SmallVector.h" using namespace clang; diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp index 83bf36c71630..f75e3ea8b8b1 100644 --- a/clang/lib/Parse/DeclSpec.cpp +++ b/clang/lib/Parse/DeclSpec.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/DeclSpec.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Basic/LangOptions.h" #include "llvm/ADT/STLExtras.h" using namespace clang; diff --git a/clang/lib/Parse/ExtensionRAIIObject.h b/clang/lib/Parse/ExtensionRAIIObject.h index e7d44464b585..4593dcff44e7 100644 --- a/clang/lib/Parse/ExtensionRAIIObject.h +++ b/clang/lib/Parse/ExtensionRAIIObject.h @@ -14,7 +14,7 @@ #ifndef LLVM_CLANG_PARSE_EXTENSION_RAII_OBJECT_H #define LLVM_CLANG_PARSE_EXTENSION_RAII_OBJECT_H -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" namespace clang { diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp index 90d2f6fefce2..bf9b3b2fb50a 100644 --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Parse/Parser.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 5a8f22348809..89e0f10d741c 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Parse/Scope.h" #include "ExtensionRAIIObject.h" #include "AstGuard.h" diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index 1041410f2a40..ed4d1dffee8d 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" #include "AstGuard.h" diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp index 945ff245fbee..6a2ef36a37e7 100644 --- a/clang/lib/Parse/ParseExprCXX.cpp +++ b/clang/lib/Parse/ParseExprCXX.cpp @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Parse/Parser.h" #include "clang/Parse/DeclSpec.h" #include "AstGuard.h" diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index b5d0ec05dbc2..1e14dd6741ad 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -14,7 +14,7 @@ #include "clang/Parse/Designator.h" #include "clang/Parse/Parser.h" #include "AstGuard.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "llvm/ADT/SmallString.h" using namespace clang; diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp index 1c94dbb6aad7..2cbb56417b41 100644 --- a/clang/lib/Parse/ParseObjc.cpp +++ b/clang/lib/Parse/ParseObjc.cpp @@ -15,7 +15,7 @@ #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" #include "AstGuard.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "llvm/ADT/SmallVector.h" using namespace clang; diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp index 40f0f652d90a..279038c37ef6 100644 --- a/clang/lib/Parse/ParsePragma.cpp +++ b/clang/lib/Parse/ParsePragma.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "ParsePragma.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Lex/Preprocessor.h" #include "clang/Parse/Action.h" using namespace clang; diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp index ed5e22401e75..ea54e7ed3020 100644 --- a/clang/lib/Parse/ParseTemplate.cpp +++ b/clang/lib/Parse/ParseTemplate.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp index e7914cccea06..5b242d82e754 100644 --- a/clang/lib/Parse/ParseTentative.cpp +++ b/clang/lib/Parse/ParseTentative.cpp @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" using namespace clang; /// isCXXDeclarationStatement - C++-specialized function that disambiguates diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 7e1cef950fdc..0e1b22202cd4 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/Parse/Parser.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticParse.h" #include "clang/Parse/DeclSpec.h" #include "clang/Parse/Scope.h" #include "ExtensionRAIIObject.h" diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp index 7e61bbd14c5f..4f659b6beb80 100644 --- a/clang/lib/Sema/Sema.cpp +++ b/clang/lib/Sema/Sema.cpp @@ -17,7 +17,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" using namespace clang; /// ConvertQualTypeToStringFn - This function is used to pretty print the diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 0adea514d0c4..5e67084353ca 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -21,7 +21,7 @@ #include "clang/AST/DeclBase.h" #include "clang/AST/Expr.h" #include "clang/Parse/Action.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/SmallPtrSet.h" diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp index 699f8908079c..357dcd7b60cf 100644 --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp @@ -14,7 +14,7 @@ #include "Sema.h" #include "clang/AST/ASTContext.h" #include "clang/Parse/DeclSpec.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "llvm/ADT/STLExtras.h" using namespace clang; diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 9a60861bc28c..5b15a1a5be56 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -18,7 +18,7 @@ #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "SemaUtil.h" using namespace clang; diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 9f308842d9ec..41ecf13563ea 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -18,7 +18,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/Parse/DeclSpec.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/TargetInfo.h" #include "clang/Basic/SourceManager.h" // FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's) diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index f444c71e4f5e..c87483dd0c95 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -15,7 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/TargetInfo.h" #include "clang/Parse/DeclSpec.h" #include diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index d5d83be87d0e..14a481eb715f 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -18,7 +18,7 @@ #include "clang/AST/TypeOrdering.h" #include "clang/AST/StmtVisitor.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Parse/DeclSpec.h" #include "llvm/ADT/STLExtras.h" #include "llvm/Support/Compiler.h" diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index 26538876460f..b636e2994557 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -14,7 +14,7 @@ #include "Sema.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Parse/DeclSpec.h" using namespace clang; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 9e80946b43d2..48d62729dc96 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -18,7 +18,7 @@ #include "clang/AST/ExprObjC.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/LiteralSupport.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" #include "clang/Parse/DeclSpec.h" diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp index 04e37d1ebf43..ee40a30ff1c2 100644 --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -16,7 +16,7 @@ #include "clang/AST/ASTContext.h" #include "clang/Parse/DeclSpec.h" #include "clang/Lex/Preprocessor.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/STLExtras.h" using namespace clang; diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp index 607e640b32c9..f0aa3b76a594 100644 --- a/clang/lib/Sema/SemaExprObjC.cpp +++ b/clang/lib/Sema/SemaExprObjC.cpp @@ -15,7 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprObjC.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" using namespace clang; Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, diff --git a/clang/lib/Sema/SemaInherit.cpp b/clang/lib/Sema/SemaInherit.cpp index 43caa9286eb6..b5bd8939ad41 100644 --- a/clang/lib/Sema/SemaInherit.cpp +++ b/clang/lib/Sema/SemaInherit.cpp @@ -19,7 +19,7 @@ #include "clang/AST/DeclCXX.h" #include "clang/AST/Type.h" #include "clang/AST/TypeOrdering.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include #include #include diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 55d11b439854..041e994bca8f 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -15,7 +15,7 @@ #include "clang/Parse/Designator.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Expr.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include // for std::count_if #include // for std::mem_fun diff --git a/clang/lib/Sema/SemaNamedCast.cpp b/clang/lib/Sema/SemaNamedCast.cpp index 2aeab44db3df..17de7321dee8 100644 --- a/clang/lib/Sema/SemaNamedCast.cpp +++ b/clang/lib/Sema/SemaNamedCast.cpp @@ -15,7 +15,7 @@ #include "SemaInherit.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ASTContext.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "llvm/ADT/SmallVector.h" #include using namespace clang; diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 9b6da0504ad0..0001f649eedc 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -17,7 +17,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" #include "clang/Basic/TargetInfo.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" using namespace clang; Sema::OwningStmtResult Sema::ActOnExprStmt(ExprArg expr) { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 719938d9a3be..60219fe29272 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -15,7 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/Expr.h" -#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticSema.h" #include "clang/Parse/DeclSpec.h" using namespace clang; -- GitLab From 660419289a28778b7d1593910b4b836c43c33ee4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 18:34:32 +0000 Subject: [PATCH 283/682] Add the new .def files llvm-svn: 63112 --- .../clang/Basic/DiagnosticASTKinds.def | 10 + .../clang/Basic/DiagnosticAnalysisKinds.def | 8 + .../clang/Basic/DiagnosticCommonKinds.def | 74 + .../clang/Basic/DiagnosticLexKinds.def | 266 ++++ .../clang/Basic/DiagnosticParseKinds.def | 279 ++++ .../clang/Basic/DiagnosticSemaKinds.def | 1195 +++++++++++++++++ 6 files changed, 1832 insertions(+) create mode 100644 clang/include/clang/Basic/DiagnosticASTKinds.def create mode 100644 clang/include/clang/Basic/DiagnosticAnalysisKinds.def create mode 100644 clang/include/clang/Basic/DiagnosticCommonKinds.def create mode 100644 clang/include/clang/Basic/DiagnosticLexKinds.def create mode 100644 clang/include/clang/Basic/DiagnosticParseKinds.def create mode 100644 clang/include/clang/Basic/DiagnosticSemaKinds.def diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.def b/clang/include/clang/Basic/DiagnosticASTKinds.def new file mode 100644 index 000000000000..6f39559bc086 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticASTKinds.def @@ -0,0 +1,10 @@ + +#ifdef ASTSTART +__ASTSTART = DIAG_START_AST, +#undef ASTSTART +#endif + +DIAG(note_comma_in_ice, NOTE, + "C does not permit evaluated commas in an integer constant expression") +DIAG(note_expr_divide_by_zero, NOTE, + "division by zero") diff --git a/clang/include/clang/Basic/DiagnosticAnalysisKinds.def b/clang/include/clang/Basic/DiagnosticAnalysisKinds.def new file mode 100644 index 000000000000..d8768ba910ab --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticAnalysisKinds.def @@ -0,0 +1,8 @@ + +#ifdef ANALYSISSTART +__ANALYSISSTART = DIAG_START_ANALYSIS, +#undef ANALYSISSTART +#endif + +// CHECK: use of uninitialized values +DIAG(warn_uninit_val, WARNING, "use of uninitialized variable") diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.def b/clang/include/clang/Basic/DiagnosticCommonKinds.def new file mode 100644 index 000000000000..aab81acefc6a --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.def @@ -0,0 +1,74 @@ +//===----------------------------------------------------------------------===// +// Common Helpers +//===----------------------------------------------------------------------===// + + +DIAG(note_previous_definition, NOTE, + "previous definition is here") +DIAG(note_previous_declaration, NOTE, + "previous declaration is here") +DIAG(note_previous_implicit_declaration, NOTE, + "previous implicit declaration is here") +DIAG(note_previous_use, NOTE, + "previous use is here") +DIAG(note_duplicate_case_prev, NOTE, + "previous case defined here") +DIAG(note_forward_declaration, NOTE, + "forward declaration of %0") +DIAG(note_type_being_defined, NOTE, + "definition of %0 is not complete until the closing '}'") +/// note_matching - this is used as a continuation of a previous diagnostic, +/// e.g. to specify the '(' when we expected a ')'. +DIAG(note_matching, NOTE, + "to match this '%0'") + +DIAG(note_using_decl, NOTE, + "using") +DIAG(note_also_found_decl, NOTE, + "also found") + +// Parse && Lex +DIAG(err_expected_colon, ERROR, + "expected ':'") + +// Parse && Sema +DIAG(err_no_declarators, ERROR, + "declaration does not declare anything") +DIAG(err_param_redefinition, ERROR, + "redefinition of parameter %0") +DIAG(err_invalid_storage_class_in_func_decl, ERROR, + "invalid storage class specifier in function declarator") +DIAG(err_expected_namespace_name, ERROR, + "expected namespace name") + +// Sema && Lex +DIAG(ext_longlong, EXTENSION, + "'long long' is an extension when C99 mode is not enabled") +DIAG(warn_integer_too_large, WARNING, + "integer constant is too large for its type") +DIAG(warn_integer_too_large_for_signed, WARNING, + "integer constant is so large that it is unsigned") + +// Sema && AST +DIAG(note_invalid_subexpr_in_ice, NOTE, + "subexpression not valid in an integer constant expression") + +// Driver +DIAG(pp_macro_not_used, WARNING, // -Wunused-macros + "macro is not used") +DIAG(warn_floatingpoint_eq, WARNING, + "comparing floating point with == or != is unsafe") +DIAG(warn_objc_property_attr_mutually_exclusive, WARNING, + "property attributes '%0' and '%1' are mutually exclusive") +DIAG(warn_printf_not_string_constant, WARNING, + "format string is not a string literal (potentially insecure)") +DIAG(warn_implicit_function_decl, WARNING, + "implicit declaration of function %0") +DIAG(err_pp_I_dash_not_supported, ERROR, + "-I- not supported, please use -iquote instead") +DIAG(warn_octal_escape_too_large, WARNING, + "octal escape sequence out of range") +DIAG(warn_hex_escape_too_large, WARNING, + "hex escape sequence out of range") +DIAG(warn_pp_undef_identifier, WARNING, + "%0 is not defined, evaluates to 0") diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.def b/clang/include/clang/Basic/DiagnosticLexKinds.def new file mode 100644 index 000000000000..54394e10709d --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticLexKinds.def @@ -0,0 +1,266 @@ +//===----------------------------------------------------------------------===// +// Lexer Diagnostics +//===----------------------------------------------------------------------===// + +#ifdef LEXSTART +__LEXSTART = DIAG_START_LEX, +#undef LEXSTART +#endif + +DIAG(null_in_string, WARNING, + "null character(s) preserved in string literal") +DIAG(null_in_char , WARNING, + "null character(s) preserved in character literal") +DIAG(null_in_file , WARNING, + "null character ignored") +DIAG(warn_nested_block_comment, WARNING, + "'/*' within block comment") +DIAG(escaped_newline_block_comment_end, WARNING, + "escaped newline between */ characters at block comment end") +DIAG(backslash_newline_space, WARNING, + "backslash and newline separated by space") + +// Trigraphs. +DIAG(trigraph_ignored, WARNING, "trigraph ignored") +DIAG(trigraph_ignored_block_comment, WARNING, + "ignored trigraph would end block comment") +DIAG(trigraph_ends_block_comment, WARNING, + "trigraph ends block comment") +DIAG(trigraph_converted, WARNING, + "trigraph converted to '%0' character") + +DIAG(ext_multi_line_bcpl_comment, EXTENSION, + "multi-line // comment") +DIAG(ext_bcpl_comment, EXTENSION, + "// comments are not allowed in this language") +DIAG(ext_no_newline_eof, EXTENSION, + "no newline at end of file") +DIAG(ext_backslash_newline_eof, EXTENSION, + "backslash-newline at end of file") +DIAG(ext_dollar_in_identifier, EXTENSION, + "'$' in identifier") +DIAG(charize_microsoft_ext, EXTENSION, + "@# is a microsoft extension") + +DIAG(ext_token_used, EXTENSION, + "extension used") + +DIAG(err_unterminated_string, ERROR, + "missing terminating \" character") +DIAG(err_unterminated_char, ERROR, + "missing terminating ' character") +DIAG(err_empty_character, ERROR, + "empty character constant") +DIAG(err_unterminated_block_comment, ERROR, + "unterminated /* comment") +DIAG(err_invalid_character_to_charify, ERROR, + "invalid argument to convert to character") + +// Literal +DIAG(ext_nonstandard_escape, EXTENSION, + "use of non-standard escape character '\\%0'") +DIAG(ext_unknown_escape, EXTENSION, + "unknown escape sequence '\\%0'") +DIAG(err_hex_escape_no_digits, ERROR, + "\\x used with no following hex digits") +DIAG(err_invalid_decimal_digit, ERROR, + "invalid digit '%0' in decimal constant") +DIAG(err_invalid_binary_digit, ERROR, + "invalid digit '%0' in binary constant") +DIAG(err_invalid_octal_digit, ERROR, + "invalid digit '%0' in octal constant") +DIAG(err_invalid_suffix_integer_constant, ERROR, + "invalid suffix '%0' on integer constant") +DIAG(err_invalid_suffix_float_constant, ERROR, + "invalid suffix '%0' on floating constant") +DIAG(warn_extraneous_wide_char_constant, WARNING, + "extraneous characters in wide character constant ignored") +DIAG(warn_char_constant_too_large, WARNING, + "character constant too long for its type") +DIAG(err_exponent_has_no_digits, ERROR, + "exponent has no digits") +DIAG(ext_imaginary_constant, EXTENSION, + "imaginary constants are an extension") +DIAG(err_hexconstant_requires_exponent, ERROR, + "hexadecimal floating constants require an exponent") +DIAG(ext_hexconstant_invalid, EXTENSION, + "hexadecimal floating constants are a C99 feature") +DIAG(ext_binary_literal, EXTENSION, + "binary integer literals are an extension") +DIAG(err_pascal_string_too_long, ERROR, + "Pascal string is too long") + +//===----------------------------------------------------------------------===// +// Preprocessor Diagnostics +//===----------------------------------------------------------------------===// + +DIAG(pp_hash_warning, WARNING, + "#warning%0") +DIAG(pp_include_next_in_primary, WARNING, + "#include_next in primary source file") +DIAG(pp_include_next_absolute_path, WARNING, + "#include_next with absolute path") +DIAG(ext_c99_whitespace_required_after_macro_name, WARNING, + "ISO C99 requires whitespace after the macro name") +DIAG(pp_pragma_once_in_main_file, WARNING, + "#pragma once in main file") +DIAG(pp_pragma_sysheader_in_main_file, WARNING, + "#pragma system_header ignored in main file") +DIAG(pp_poisoning_existing_macro, WARNING, + "poisoning existing macro") +DIAG(pp_out_of_date_dependency, WARNING, + "current file is older than dependency %0") +DIAG(pp_undef_builtin_macro, WARNING, + "undefining builtin macro") +DIAG(pp_redef_builtin_macro, WARNING, + "redefining builtin macro") +DIAG(pp_invalid_string_literal, WARNING, + "invalid string literal, ignoring final '\\'") +DIAG(warn_pp_expr_overflow, WARNING, + "integer overflow in preprocessor expression") +DIAG(warn_pp_convert_lhs_to_positive, WARNING, + "left side of operator converted from negative value to unsigned: %0") +DIAG(warn_pp_convert_rhs_to_positive, WARNING, + "right side of operator converted from negative value to unsigned: %0") + +DIAG(ext_pp_import_directive, EXTENSION, + "#import is a language extension") +DIAG(ext_pp_ident_directive, EXTENSION, + "#ident is a language extension") +DIAG(ext_pp_include_next_directive, EXTENSION, + "#include_next is a language extension") +DIAG(ext_pp_warning_directive, EXTENSION, + "#warning is a language extension") +DIAG(ext_pp_extra_tokens_at_eol, EXTENSION, + "extra tokens at end of %0 directive") +DIAG(ext_pp_comma_expr, EXTENSION, + "comma operator in operand of #if") +DIAG(ext_pp_bad_vaargs_use, EXTENSION, + "__VA_ARGS__ can only appear in the expansion of a C99 variadic macro") +DIAG(ext_pp_macro_redef, EXTENSION, + "%0 macro redefined") +DIAG(ext_variadic_macro, EXTENSION, + "variadic macros were introduced in C99") +DIAG(ext_named_variadic_macro, EXTENSION, + "named variadic macros are a GNU extension") +DIAG(ext_embedded_directive, EXTENSION, + "embedding a directive within macro arguments is not portable") +DIAG(ext_missing_varargs_arg, EXTENSION, + "varargs argument missing, but tolerated as an extension") +DIAG(ext_empty_fnmacro_arg, EXTENSION, + "empty macro arguments were standardized in C99") + +DIAG(ext_pp_base_file, EXTENSION, + "__BASE_FILE__ is a language extension") +DIAG(ext_pp_include_level, EXTENSION, + "__INCLUDE_LEVEL__ is a language extension") +DIAG(ext_pp_timestamp, EXTENSION, + "__TIMESTAMP__ is a language extension") + +DIAG(err_pp_invalid_directive, ERROR, + "invalid preprocessing directive") +DIAG(err_pp_hash_error, ERROR, + "#error%0") +DIAG(err_pp_file_not_found, ERROR, + "'%0' file not found") +DIAG(err_pp_empty_filename, ERROR, + "empty filename") +DIAG(err_pp_include_too_deep, ERROR, + "#include nested too deeply") +DIAG(err_pp_expects_filename, ERROR, + "expected \"FILENAME\" or ") +DIAG(err_pp_macro_not_identifier, ERROR, + "macro names must be identifiers") +DIAG(err_pp_missing_macro_name, ERROR, + "macro name missing") +DIAG(err_pp_missing_rparen_in_macro_def, ERROR, + "missing ')' in macro parameter list") +DIAG(err_pp_invalid_tok_in_arg_list, ERROR, + "invalid token in macro parameter list") +DIAG(err_pp_expected_ident_in_arg_list, ERROR, + "expected identifier in macro parameter list") +DIAG(err_pp_expected_comma_in_arg_list, ERROR, + "expected comma in macro parameter list") +DIAG(err_pp_duplicate_name_in_arg_list, ERROR, + "duplicate macro parameter name %0") +DIAG(err_pp_stringize_not_parameter, ERROR, + "'#' is not followed by a macro parameter") +DIAG(err_pp_malformed_ident, ERROR, + "invalid #ident directive") +DIAG(err_pp_unterminated_conditional, ERROR, + "unterminated conditional directive") +DIAG(pp_err_else_after_else, ERROR, + "#else after #else") +DIAG(pp_err_elif_after_else, ERROR, + "#elif after #else") +DIAG(pp_err_else_without_if, ERROR, + "#else without #if") +DIAG(pp_err_elif_without_if, ERROR, + "#elif without #if") +DIAG(err_pp_endif_without_if, ERROR, + "#endif without #if") +DIAG(err_pp_expected_value_in_expr, ERROR, + "expected value in expression") +DIAG(err_pp_missing_val_before_operator, ERROR, + "missing value before operator") +DIAG(err_pp_expected_rparen, ERROR, + "expected ')' in preprocessor expression") +DIAG(err_pp_expected_eol, ERROR, + "expected end of line in preprocessor expression") +DIAG(err_pp_defined_requires_identifier, ERROR, + "operator 'defined' requires an identifier") +DIAG(err_pp_missing_rparen, ERROR, + "missing ')' after 'defined'") +DIAG(err_pp_colon_without_question, ERROR, + "':' without preceding '?'") +DIAG(err_pp_division_by_zero, ERROR, + "division by zero in preprocessor expression") +DIAG(err_pp_remainder_by_zero, ERROR, + "remainder by zero in preprocessor expression") +DIAG(err_pp_expr_bad_token_binop, ERROR, + "token is not a valid binary operator in a preprocessor subexpression") +DIAG(err_pp_expr_bad_token_start_expr, ERROR, + "invalid token at start of a preprocessor expression") +DIAG(err_pp_invalid_poison, ERROR, + "can only poison identifier tokens") +DIAG(err_pp_used_poisoned_id, ERROR, + "attempt to use a poisoned identifier") +DIAG(err__Pragma_malformed, ERROR, + "_Pragma takes a parenthesized string literal") +DIAG(err_pragma_comment_malformed, ERROR, + "pragma comment requires parenthesized identifier and optional string") +DIAG(err_pragma_comment_unknown_kind, ERROR, + "unknown kind of pragma comment") +DIAG(err_defined_macro_name, ERROR, + "'defined' cannot be used as a macro name") +DIAG(err_paste_at_start, ERROR, + "'##' cannot appear at start of macro expansion") +DIAG(err_paste_at_end, ERROR, + "'##' cannot appear at end of macro expansion") +DIAG(ext_paste_comma, EXTENSION, + "Use of comma pasting extension is non-portable") +DIAG(err_unterm_macro_invoc, ERROR, + "unterminated function-like macro invocation") +DIAG(err_too_many_args_in_macro_invoc, ERROR, + "too many arguments provided to function-like macro invocation") +DIAG(err_too_few_args_in_macro_invoc, ERROR, + "too few arguments provided to function-like macro invocation") +DIAG(err_pp_bad_paste, ERROR, + "pasting formed '%0', an invalid preprocessing token") +DIAG(err_pp_operator_used_as_macro_name, ERROR, + "C++ operator '%0' cannot be used as a macro name") +DIAG(err_pp_illegal_floating_literal, ERROR, + "floating point literal in preprocessor expression") +DIAG(err_pp_line_requires_integer, ERROR, + "#line directive requires a positive integer argument") +DIAG(err_pp_line_invalid_filename, ERROR, + "invalid filename for #line directive") +DIAG(err_pp_linemarker_requires_integer, ERROR, + "line marker directive requires a positive integer argument") +DIAG(err_pp_linemarker_invalid_filename, ERROR, + "invalid filename for line marker directive") +DIAG(err_pp_linemarker_invalid_flag, ERROR, + "invalid flag line marker directive") +DIAG(ext_pp_line_too_big, EXTENSION, + "C requires #line number to be less than %0, allowed as extension") + diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.def b/clang/include/clang/Basic/DiagnosticParseKinds.def new file mode 100644 index 000000000000..6b87ff26ab16 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticParseKinds.def @@ -0,0 +1,279 @@ +//===----------------------------------------------------------------------===// +// Parser Diagnostics +//===----------------------------------------------------------------------===// + +#ifdef PARSESTART +__PARSESTART = DIAG_START_PARSE, +#undef PARSESTART +#endif + +DIAG(w_asm_qualifier_ignored, WARNING, + "ignored %0 qualifier on asm") + +DIAG(ext_empty_source_file, EXTENSION, + "ISO C forbids an empty source file") +DIAG(ext_top_level_semi, EXTENSION, + "ISO C does not allow an extra ';' outside of a function") +DIAG(ext_extra_struct_semi, EXTENSION, + "ISO C does not allow an extra ';' inside a struct or union") + +DIAG(ext_duplicate_declspec, EXTENSION, + "duplicate '%0' declaration specifier") +DIAG(ext_plain_complex, EXTENSION, + "ISO C does not support plain '_Complex' meaning '_Complex double'") +DIAG(ext_integer_complex, EXTENSION, + "ISO C does not support complex integer types") +DIAG(ext_thread_before, EXTENSION, + "'__thread' before 'static'") + +DIAG(ext_empty_struct_union_enum, EXTENSION, + "use of empty %0 extension") + +DIAG(err_invalid_sign_spec, ERROR, + "'%0' cannot be signed or unsigned") +DIAG(err_invalid_short_spec, ERROR, + "'short %0' is invalid") +DIAG(err_invalid_long_spec, ERROR, + "'long %0' is invalid") +DIAG(err_invalid_longlong_spec, ERROR, + "'long long %0' is invalid") +DIAG(err_invalid_complex_spec, ERROR, + "'_Complex %0' is invalid") +DIAG(err_invalid_thread_spec, ERROR, + "'__thread %0' is invalid") + +DIAG(ext_ident_list_in_param, EXTENSION, + "type-less parameter names in function declaration") +DIAG(ext_c99_variable_decl_in_for_loop, EXTENSION, + "variable declaration in for loop is a C99-specific feature") +DIAG(ext_c99_compound_literal, EXTENSION, + "compound literals are a C99-specific feature") +DIAG(ext_c99_enumerator_list_comma, EXTENSION, + "commas at the end of enumerator lists are a C99-specific feature") + +DIAG(ext_gnu_indirect_goto, EXTENSION, + "use of GNU indirect-goto extension") +DIAG(ext_gnu_address_of_label, EXTENSION, + "use of GNU address-of-label extension") +DIAG(ext_gnu_statement_expr, EXTENSION, + "use of GNU statement expression extension") +DIAG(ext_gnu_conditional_expr, EXTENSION, + "use of GNU ?: expression extension, eliding middle term") +DIAG(ext_gnu_empty_initializer, EXTENSION, + "use of GNU empty initializer extension") +DIAG(ext_gnu_array_range, EXTENSION, + "use of GNU array range extension") +DIAG(ext_gnu_missing_equal_designator, EXTENSION, + "use of GNU 'missing =' extension in designator") +DIAG(err_expected_equal_designator, ERROR, + "expected '=' or another designator") +DIAG(ext_gnu_old_style_field_designator, EXTENSION, + "use of GNU old-style field designator extension") +DIAG(ext_gnu_case_range, EXTENSION, + "use of GNU case range extension") + +// Generic errors. +DIAG(err_parse_error, ERROR, + "parse error") +DIAG(err_expected_expression, ERROR, + "expected expression") +DIAG(err_expected_type, ERROR, + "expected a type") +DIAG(err_expected_external_declaration, ERROR, + "expected external declaration") +DIAG(err_expected_ident, ERROR, + "expected identifier") +DIAG(err_expected_ident_lparen, ERROR, + "expected identifier or '('") +DIAG(err_expected_ident_lbrace, ERROR, + "expected identifier or '{'") +DIAG(err_expected_lbrace, ERROR, + "expected '{'") +DIAG(err_expected_lparen, ERROR, + "expected '('") +DIAG(err_expected_rparen, ERROR, + "expected ')'") +DIAG(err_expected_rsquare, ERROR, + "expected ']'") +DIAG(err_expected_rbrace, ERROR, + "expected '}'") +DIAG(err_expected_greater, ERROR, + "expected '>'") +DIAG(err_expected_semi_decl_list, ERROR, + "expected ';' at end of declaration list") +DIAG(ext_expected_semi_decl_list, EXTENSION, + "expected ';' at end of declaration list") +DIAG(err_function_declared_typedef, ERROR, + "function definition declared 'typedef'") +DIAG(err_expected_fn_body, ERROR, + "expected function body after function declarator") +DIAG(err_expected_method_body, ERROR, + "expected method body") +DIAG(err_expected_after_declarator, ERROR, + "expected '=', ',', ';', 'asm', or '__attribute__' after declarator") +DIAG(err_expected_statement, ERROR, + "expected statement") +DIAG(err_expected_lparen_after, ERROR, + "expected '(' after '%0'") +DIAG(err_expected_lparen_after_id, ERROR, + "expected '(' after %0") +DIAG(err_expected_less_after, ERROR, + "expected '<' after '%0'") +DIAG(err_expected_comma, ERROR, + "expected ','") +DIAG(err_expected_lbrace_in_compound_literal, ERROR, + "expected '{' in compound literal") +DIAG(err_expected_while, ERROR, + "expected 'while' in do/while loop") +DIAG(err_expected_semi_after, ERROR, + "expected ';' after %0") +DIAG(err_expected_semi_after_expr, ERROR, + "expected ';' after expression") +DIAG(err_expected_semi_for, ERROR, + "expected ';' in 'for' statement specifier") +DIAG(err_expected_colon_after, ERROR, + "expected ':' after %0") +DIAG(err_label_end_of_compound_statement, ERROR, + "label at end of compound statement: expected statement") +DIAG(err_expected_string_literal, ERROR, + "expected string literal") +DIAG(err_expected_asm_operand, ERROR, + "expected string literal or '[' for asm operand") +DIAG(err_expected_selector_for_method, ERROR, + "expected selector for Objective-C method") + +DIAG(err_unexpected_at, ERROR, + "unexpected '@' in program") + +DIAG(err_invalid_reference_qualifier_application, ERROR, + "'%0' qualifier may not be applied to a reference") +DIAG(err_illegal_decl_reference_to_reference, ERROR, + "%0 declared as a reference to a reference") +DIAG(err_argument_required_after_attribute, ERROR, + "argument required after attribute") +DIAG(err_ellipsis_first_arg, ERROR, + "ISO C requires a named argument before '...'") +DIAG(err_missing_param, ERROR, + "expected parameter declarator") +DIAG(err_unexpected_typedef_ident, ERROR, + "unexpected type name %0: expected identifier") +DIAG(err_expected_class_name, ERROR, + "expected class name") +DIAG(err_unspecified_vla_size_with_static, ERROR, + "'static' may not be used with an unspecified variable length array size") + +// Declarations. +DIAG(err_typename_requires_specqual, ERROR, + "type name requires a specifier or qualifier") +DIAG(err_typename_invalid_storageclass, ERROR, + "type name does not allow storage class to be specified") +DIAG(err_typename_invalid_functionspec, ERROR, + "type name does not allow function specifier to be specified") +DIAG(err_invalid_decl_spec_combination, ERROR, + "cannot combine with previous '%0' declaration specifier") + +/// Objective-C parser diagnostics +DIAG(err_objc_no_attributes_on_category, ERROR, + "attributes may not be specified on a category") +DIAG(err_objc_missing_end, ERROR, + "missing @end") +DIAG(warn_objc_protocol_qualifier_missing_id, WARNING, + "protocol qualifiers without 'id' is archaic") + +DIAG(err_objc_illegal_visibility_spec, ERROR, + "illegal visibility specification") +DIAG(err_objc_illegal_interface_qual, ERROR, + "illegal interface qualifier") +DIAG(err_objc_expected_equal, ERROR, + "setter/getter expects '=' followed by name") +DIAG(err_objc_property_requires_field_name, ERROR, + "property requires fields to be named") +DIAG(err_objc_property_bitfield, ERROR, + "property name cannot be a bitfield") +DIAG(err_objc_expected_property_attr, ERROR, + "unknown property attribute %0") +DIAG(err_objc_propertoes_require_objc2, ERROR, + "properties are an Objective-C 2 feature") +DIAG(err_objc_unexpected_attr, ERROR, + "prefix attribute must be followed by an interface or protocol") +DIAG(err_objc_directive_only_in_protocol, ERROR, + "directive may only be specified in protocols only") +DIAG(err_missing_catch_finally, ERROR, + "@try statement without a @catch and @finally clause") +DIAG(err_objc_concat_string, ERROR, + "unexpected token after Objective-C string") +DIAG(err_missing_sel_definition, ERROR, + "cannot find definition of 'SEL'") +DIAG(err_missing_id_definition, ERROR, + "cannot find definition of 'id'") +DIAG(err_missing_proto_definition, ERROR, + "cannot find definition of 'Protocol'") +DIAG(err_missing_class_definition, ERROR, + "cannot find definition of 'Class'") +DIAG(warn_expected_implementation, WARNING, + "@end must appear in an @implementation context") +DIAG(error_property_ivar_decl, ERROR, + "property synthesize requires specification of an ivar") + +DIAG(err_expected_field_designator, ERROR, + "expected a field designator, such as '.field = 4'") + +DIAG(err_declaration_does_not_declare_param, ERROR, + "declaration does not declare a parameter") +DIAG(err_no_matching_param, ERROR, + "parameter named %0 is missing") + +/// C++ parser diagnostics +DIAG(err_expected_unqualified_id, ERROR, + "expected unqualified-id") +DIAG(err_func_def_no_params, ERROR, + "function definition does not declare parameters") +DIAG(err_expected_lparen_after_type, ERROR, + "expected '(' for function-style cast or type construction") +DIAG(err_expected_equal_after_declarator, ERROR, + "expected '=' after declarator") +DIAG(warn_parens_disambiguated_as_function_decl, WARNING, + "parentheses were disambiguated as a function declarator") +DIAG(err_expected_member_or_base_name, ERROR, + "expected class member or base class name") +DIAG(ext_ellipsis_exception_spec, EXTENSION, + "exception specification of '...' is a Microsoft extension") +DIAG(err_expected_catch, ERROR, + "expected catch") + +// C++ derived classes +DIAG(err_dup_virtual, ERROR, + "duplicate 'virtual' in base specifier") + +// C++ operator overloading +DIAG(err_operator_missing_type_specifier, ERROR, + "missing type specifier after 'operator'") + +// Classes. +DIAG(err_anon_type_definition, ERROR, + "declaration of anonymous %0 must be a definition") + + +/// C++ Templates +DIAG(err_expected_template, ERROR, + "expected template") +DIAG(err_expected_comma_greater, ERROR, + "expected ',' or '>' in template-parameter-list") +DIAG(err_expected_type_id_after, ERROR, + "expected type-id after '%0'") +DIAG(err_expected_class_before, ERROR, + "expected 'class' before '%0'") + +// Language specific pragmas + +// #pragma pack +DIAG(warn_pragma_pack_expected_lparen, WARNING, + "missing '(' after '#pragma pack' - ignoring") +DIAG(warn_pragma_pack_expected_rparen, WARNING, + "missing ')' after '#pragma pack' - ignoring") +DIAG(warn_pragma_pack_invalid_action, WARNING, + "unknown action for '#pragma pack' - ignored") +DIAG(warn_pragma_pack_invalid_constant, WARNING, + "invalid constant for '#pragma pack', expected %0 - ignored") +DIAG(warn_pragma_pack_malformed, WARNING, + "expected integer or identifier in '#pragma pack' - ignored") diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def new file mode 100644 index 000000000000..b412bca184ef --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -0,0 +1,1195 @@ +//===----------------------------------------------------------------------===// +// Semantic Analysis +//===----------------------------------------------------------------------===// + +#ifdef SEMASTART +__SEMASTART = DIAG_START_SEMA, +#undef SEMASTART +#endif + +// Constant expressions +DIAG(err_expr_not_ice, ERROR, + "expression is not an integer constant expression") +DIAG(ext_expr_not_ice, EXTENSION, + "expression is not integer constant expression " + "(but is allowed as an extension)") +DIAG(ext_null_pointer_expr_not_ice, EXTENSION, + "null pointer expression is not an integer constant expression " + "(but is allowed as an extension)") + + +// Semantic analysis of string and character constant literals. +DIAG(ext_predef_outside_function, WARNING, + "predefined identifier is only valid inside function") + +// C99 Designated Initializers +DIAG(err_array_designator_nonconstant, ERROR, + "array designator value must be a constant expression") +DIAG(err_array_designator_negative, ERROR, + "array designator value '%0' is negative") +DIAG(err_array_designator_empty_range, ERROR, + "array designator range [%0, %1] is empty") +DIAG(err_array_designator_non_array, ERROR, + "array designator cannot initialize non-array type %0") +DIAG(err_array_designator_too_large, ERROR, + "array designator index (%0) exceeds array bounds (%1)") +DIAG(err_field_designator_non_aggr, ERROR, + "field designator cannot initialize a %select{non-struct, non-union|non-class}0 type %1") +DIAG(err_field_designator_unknown, ERROR, + "field designator %0 does not refer to any field in type %1") +DIAG(err_field_designator_nonfield, ERROR, + "field designator %0 does not refer to a non-static data member") +DIAG(note_field_designator_found, NOTE, + "field designator refers here") +DIAG(err_designator_for_scalar_init, ERROR, + "designator in initializer for scalar type %0") + +// Declarations. +DIAG(ext_vla, EXTENSION, + "variable length arrays are a C99 feature, accepted as an extension") +DIAG(ext_anon_param_requires_type_specifier, EXTENSION, + "type specifier required for unnamed parameter, defaults to int") +DIAG(err_bad_variable_name, ERROR, + "'%0' cannot be the name of a variable or data member") +DIAG(err_parameter_name_omitted, ERROR, + "parameter name omitted") +DIAG(warn_decl_in_param_list, WARNING, + "declaration of %0 will not be visible outside of this function") + +DIAG(err_declarator_need_ident, ERROR, + "declarator requires an identifier") +DIAG(err_bad_language, ERROR, + "unknown linkage language") + +/// parser diagnostics +DIAG(ext_typedef_without_a_name, EXTWARN, + "typedef requires a name") +DIAG(err_statically_allocated_object, ERROR, + "statically allocated Objective-C object %0") +DIAG(warn_enum_value_overflow, WARNING, + "overflow in enumeration value") +DIAG(warn_pragma_pack_invalid_alignment, WARNING, + "expected #pragma pack parameter to be '1', '2', '4', '8', or '16'") +// Follow the MSVC implementation. +DIAG(warn_pragma_pack_show, WARNING, + "value of #pragma pack(show) == %0") +// FIXME: Dehardcode. +DIAG(warn_pragma_pack_pop_identifer_and_alignment, WARNING, + "specifying both a name and alignment to 'pop' is undefined") +DIAG(warn_pragma_pack_pop_failed, WARNING, + "#pragma pack(pop, ...) failed: %0") + + +/// Objective-C parser diagnostics +DIAG(err_duplicate_class_def, ERROR, + "duplicate interface definition for class %0") +DIAG(err_undef_superclass, ERROR, + "cannot find interface declaration for %0, superclass of %1") +DIAG(warn_previous_alias_decl, WARNING, + "previously declared alias is ignored") +DIAG(err_conflicting_aliasing_type, ERROR, + "conflicting types for alias %0") +DIAG(warn_undef_interface, WARNING, + "cannot find interface declaration for %0") +DIAG(err_duplicate_protocol_def, ERROR, + "duplicate protocol definition of %0") +DIAG(err_undeclared_protocol, ERROR, + "cannot find protocol declaration for %0") +DIAG(warn_undef_protocolref, WARNING, + "cannot find protocol definition for %0") +DIAG(warn_readonly_property, WARNING, + "attribute 'readonly' of property %0 restricts attribute " + "'readwrite' of property inherited from %1") +DIAG(warn_property_attribute, WARNING, + "property %0 '%1' attribute does not match the property inherited from %2") +DIAG(warn_property_type, WARNING, + "property type %0 does not match property type inherited from %1") +DIAG(err_undef_interface, ERROR, + "cannot find interface declaration for %0") +DIAG(warn_dup_category_def, WARNING, + "duplicate definition of category %1 on interface %0") +DIAG(err_conflicting_super_class, ERROR, + "conflicting super class name %0") +DIAG(err_dup_implementation_class, ERROR, + "reimplementation of class %0") +DIAG(err_conflicting_ivar_type, ERROR, + "instance variable %0 has conflicting type: %1 vs %2") +DIAG(err_conflicting_ivar_name, ERROR, + "conflicting instance variable names: %0 vs %1") +DIAG(err_inconsistant_ivar_count, ERROR, + "inconsistent number of instance variables specified") +DIAG(warn_incomplete_impl, WARNING, + "incomplete implementation") +DIAG(warn_undef_method_impl, WARNING, + "method definition for %0 not found") +DIAG(warn_conflicting_types, WARNING, + "conflicting types for %0") +DIAG(warn_multiple_method_decl, WARNING, + "multiple methods named %0 found") +DIAG(err_accessor_property_type_mismatch, ERROR, + "type of property %0 does not match type of accessor %1") +DIAG(note_declared_at, NOTE, + "declared at") +DIAG(err_setter_type_void, ERROR, + "type of setter must be void") +DIAG(err_duplicate_method_decl, ERROR, + "duplicate declaration of method %0") +DIAG(error_missing_method_context, ERROR, + "missing context for method declaration") +DIAG(err_object_as_method_param, ERROR, + "can not use an object as parameter to a method") +DIAG(err_objc_property_attr_mutually_exclusive, ERROR, + "property attributes '%0' and '%1' are mutually exclusive") +DIAG(err_objc_property_requires_object, ERROR, + "property with '%0' attribute must be of object type") +DIAG(warn_objc_property_no_assignment_attribute, WARNING, + "no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed") +DIAG(warn_objc_property_default_assign_on_object, WARNING, + "default property attribute 'assign' not appropriate for non-gc object") +DIAG(warn_property_attr_mismatch, WARNING, + "property attribute in continuation class does not match the primary class") +DIAG(err_use_continuation_class, ERROR, + "attribute of property in continuation class of %0 can only be 'readwrite'") +DIAG(err_continuation_class, ERROR, + "continuation class has no primary class") +DIAG(err_property_type, ERROR, + "property cannot have array or function type %0") +DIAG(error_missing_property_context, ERROR, + "missing context for property implementation declaration") +DIAG(error_bad_property_decl, ERROR, + "property implementation must have its declaration in interface %0") +DIAG(error_synthesize_category_decl, ERROR, + "@synthesize not allowed in a category's implementation") +DIAG(error_missing_property_interface, ERROR, + "property implementation in a category with no category declaration") +DIAG(error_bad_category_property_decl, ERROR, + "property implementation must have its declaration in the category %0") +DIAG(error_bad_property_context, ERROR, + "property implementation must be in a class or category implementation") +DIAG(error_missing_property_ivar_decl, ERROR, + "synthesized property %0 must either be named the same as a compatible" + " ivar or must explicitly name an ivar") +DIAG(error_property_ivar_type, ERROR, + "type of property %0 does not match type of ivar %1") +DIAG(error_dynamic_property_ivar_decl, ERROR, + "dynamic property can not have ivar specification") +DIAG(error_duplicate_ivar_use, ERROR, + "synthesized properties %0 and %1 both claim ivar %2") +DIAG(error_property_implemented, ERROR, + "property %0 is already implemented") + +// C++ class members +DIAG(err_storageclass_invalid_for_member, ERROR, + "storage class specified for a member declaration") +DIAG(err_mutable_function, ERROR, + "'mutable' cannot be applied to functions") +DIAG(err_mutable_reference, ERROR, + "'mutable' cannot be applied to references") +DIAG(err_mutable_const, ERROR, + "'mutable' and 'const' cannot be mixed") +DIAG(err_mutable_nonmember, ERROR, + "'mutable' can only be applied to member variables") +DIAG(err_virtual_non_function, ERROR, + "'virtual' can only appear on non-static member functions") +DIAG(err_not_bitfield_type, ERROR, + "cannot declare %0 to be a bit-field type") +DIAG(err_static_not_bitfield, ERROR, + "static member %0 cannot be a bit-field") +DIAG(err_not_integral_type_bitfield, ERROR, + "bit-field %0 with non-integral type") +DIAG(err_member_initialization, ERROR, + "%0 can only be initialized if it is a static const integral data member") +DIAG(err_member_function_initialization, ERROR, + "initializer on function does not look like a pure-specifier") +DIAG(err_non_virtual_pure, ERROR, + "%0 is not virtual and cannot be declared pure") +DIAG(err_implicit_object_parameter_init, ERROR, + "cannot initialize object parameter of type %0 with an expression of type %1") + +// C++ constructors +DIAG(err_constructor_cannot_be, ERROR, + "constructor cannot be declared '%0'") +DIAG(err_invalid_qualified_constructor, ERROR, + "'%0' qualifier is not allowed on a constructor") +DIAG(err_constructor_return_type, ERROR, + "constructor cannot have a return type") +DIAG(err_constructor_redeclared, ERROR, + "constructor cannot be redeclared") +DIAG(err_constructor_byvalue_arg, ERROR, + "copy constructor must pass its first argument by reference") + +// C++ destructors +DIAG(err_destructor_not_member, ERROR, + "destructor must be a non-static member function") +DIAG(err_destructor_cannot_be, ERROR, + "destructor cannot be declared '%0'") +DIAG(err_invalid_qualified_destructor, ERROR, + "'%0' qualifier is not allowed on a destructor") +DIAG(err_destructor_return_type, ERROR, + "destructor cannot have a return type") +DIAG(err_destructor_redeclared, ERROR, + "destructor cannot be redeclared") +DIAG(err_destructor_with_params, ERROR, + "destructor cannot have any parameters") +DIAG(err_destructor_variadic, ERROR, + "destructor cannot be variadic") +DIAG(err_destructor_typedef_name, ERROR, + "destructor cannot be declared using a typedef %0 of the class name") + +// C++ initialization +// FIXME: passing in an English string as %1! +DIAG(err_not_reference_to_const_init, ERROR, + "non-const reference to type %0 cannot be initialized with a %1 of type %2") +// FIXME: passing in an English string as %1! +DIAG(err_reference_init_drops_quals, ERROR, + "initialization of reference to type %0 with a %1 of type %2 drops qualifiers") +DIAG(err_reference_var_requires_init, ERROR, + "declaration of reference variable %0 requires an initializer") +DIAG(err_const_var_requires_init, ERROR, + "declaration of const variable '%0' requires an initializer") +DIAG(err_init_non_aggr_init_list, ERROR, + "initialization of non-aggregate type %0 with an initializer list") + +// Objective-C++ +DIAG(err_objc_decls_may_only_appear_in_global_scope, ERROR, + "Objective-C declarations may only appear in global scope") +DIAG(err_nsobject_attribute, ERROR, + "__attribute ((NSObject)) is for pointer types only") + +// Attributes +DIAG(err_attribute_can_be_applied_only_to_symbol_declaration, ERROR, + "%0 attribute can be applied only to symbol declaration") +DIAG(err_attributes_are_not_compatible, ERROR, + "%0 and %1 attributes are not compatible") +DIAG(err_attribute_wrong_number_arguments, ERROR, + "attribute requires %0 argument(s)") +DIAG(err_attribute_missing_parameter_name, ERROR, + "attribute requires unquoted parameter") +DIAG(err_attribute_invalid_vector_type, ERROR, + "invalid vector type %0") +DIAG(err_attribute_argument_not_int, ERROR, + "'%0' attribute requires integer constant") +DIAG(err_attribute_argument_n_not_int, ERROR, + "'%0' attribute requires parameter %1 to be an integer constant") +DIAG(err_attribute_argument_n_not_string, ERROR, + "'%0' attribute requires parameter %1 to be a string") +DIAG(err_attribute_argument_out_of_bounds, ERROR, + "'%0' attribute parameter %1 is out of bounds") +DIAG(err_nonnull_pointers_only, ERROR, + "nonnull attribute only applies to pointer arguments") +DIAG(err_format_strftime_third_parameter, ERROR, + "strftime format attribute requires 3rd parameter to be 0") +DIAG(err_format_attribute_requires_variadic, ERROR, + "format attribute requires variadic function") +DIAG(err_format_attribute_not, ERROR, + "format argument not %0") +DIAG(err_attribute_invalid_size, ERROR, + "vector size not an integral multiple of component size") +DIAG(err_attribute_zero_size, ERROR, + "zero vector size") +DIAG(err_typecheck_vector_not_convertable, ERROR, + "can't convert between vector values of different size (%0 and %1)") +DIAG(err_typecheck_ext_vector_not_typedef, ERROR, + "ext_vector_type only applies to types, not variables") +DIAG(err_ext_vector_component_exceeds_length, ERROR, + "vector component access exceeds type %0") +DIAG(err_ext_vector_component_requires_even, ERROR, + "vector component access invalid for odd-sized type %0") +DIAG(err_ext_vector_component_name_illegal, ERROR, + "illegal vector component name '%0'") +DIAG(err_attribute_address_space_not_int, ERROR, + "address space attribute requires an integer constant") +DIAG(err_attribute_address_multiple_qualifiers, ERROR, + "multiple address spaces specified for type") +DIAG(err_implicit_pointer_address_space_cast, ERROR, + "illegal implicit cast between two pointers with different address spaces") +DIAG(err_as_qualified_auto_decl, ERROR, + "automatic variable qualified with an address space") +DIAG(err_attribute_annotate_no_string, ERROR, + "argument to annotate attribute was not a string literal") +DIAG(warn_redeclaration_without_attribute_prev_attribute_ignored, WARNING, + "'%0' redeclared without %1 attribute: previous %1 ignored") +DIAG(warn_attribute_ignored, WARNING, + "%0 attribute ignored") +DIAG(warn_attribute_weak_on_field, WARNING, + "__weak attribute cannot be specified on a field declaration") +DIAG(warn_attribute_wrong_decl_type, WARNING, + "'%0' attribute only applies to %1 types") +DIAG(warn_attribute_ignored_for_field_of_type, WARNING, + "%0 attribute ignored for field of type %1") +DIAG(warn_transparent_union_attribute_field_size, WARNING, + "transparent_union attribute ignored, size of type %0 must match type of first field") +DIAG(warn_transparent_union_attribute_not_difinition, WARNING, + "transparent_union attribute ignored, union type must be defined") +DIAG(warn_transparent_union_attribute_floating, WARNING, + "transparent_union attribute ignored, first field cannot be a floating-point or vector type") +DIAG(warn_transparent_union_attribute_zero_fields, WARNING, + "transparent_union attribute ignored, the union does not contain any fields") +DIAG(warn_transparent_union_attribute_not_c, WARNING, + "transparent_union attribute ignored, attribute is c only") +DIAG(warn_attribute_type_not_supported, WARNING, + "'%0' attribute argument not supported: %1") +DIAG(warn_attribute_unknown_visibility, WARNING, + "unknown visibility '%1'") +DIAG(err_unknown_machine_mode, ERROR, + "unknown machine mode %0") +DIAG(err_unsupported_machine_mode, ERROR, + "unsupported machine mode %0") +DIAG(err_mode_not_primitive, ERROR, + "mode attribute only supported for integer and floating-point types") +DIAG(err_mode_wrong_type, ERROR, + "type of machine mode does not match type of base type") +DIAG(err_attr_wrong_decl, ERROR, + "'%0' attribute invalid on this declaration, requires typedef or value") +DIAG(warn_attribute_nonnull_no_pointers, WARNING, + "'nonnull' attribute applied to function with no pointer arguments") +DIAG(warn_transparent_union_nonpointer, WARNING, + "'transparent_union' attribute support incomplete; only supported for" + "pointer unions") +DIAG(warn_attribute_sentinel_not_variadic, WARNING, + "'sentinel' attribute only supported for variadic functions") +DIAG(err_attribute_sentinel_less_than_zero, ERROR, + "'sentinel' parameter 1 less than zero") +DIAG(err_attribute_sentinel_not_zero_or_one, ERROR, + "'sentinel' parameter 2 not 0 or 1") + +// Clang-Specific Attributes +DIAG(err_attribute_iboutlet_non_ivar, ERROR, + "'iboutlet' attribute can only be applied to instance variables") + +// Function Parameter Semantic Analysis. +DIAG(err_param_with_void_type, ERROR, + "argument may not have 'void' type") +DIAG(err_void_only_param, ERROR, + "'void' must be the first and only parameter if specified") +DIAG(err_void_param_qualified, ERROR, + "'void' as parameter must not have type qualifiers") +DIAG(err_ident_list_in_fn_declaration, ERROR, + "a parameter list without types is only allowed in a function definition") +DIAG(ext_param_not_declared, EXTENSION, + "parameter %0 was not declared, defaulting to type 'int'") +DIAG(ext_param_typedef_of_void, EXTENSION, + "empty parameter list defined with a typedef of 'void' not allowed in C++") +DIAG(err_param_default_argument, ERROR, + "C does not support default arguments") +DIAG(err_param_default_argument_redefinition, ERROR, + "redefinition of default argument") +DIAG(err_param_default_argument_missing, ERROR, + "missing default argument on parameter") +DIAG(err_param_default_argument_missing_name, ERROR, + "missing default argument on parameter %0") +DIAG(err_param_default_argument_references_param, ERROR, + "default argument references parameter %0") +DIAG(err_param_default_argument_references_local, ERROR, + "default argument references local variable %0 of enclosing function") +DIAG(err_param_default_argument_references_this, ERROR, + "default argument references 'this'") +DIAG(err_param_default_argument_nonfunc, ERROR, + "default arguments can only be specified for parameters in a function" + " declaration") + +// C++ Overloading Semantic Analysis. +DIAG(err_ovl_diff_return_type, ERROR, + "functions that differ only in their return type cannot be overloaded") +DIAG(err_ovl_static_nonstatic_member, ERROR, + "static and non-static member functions with the same parameter types " + "cannot be overloaded") +DIAG(err_ovl_no_viable_function_in_call, ERROR, + "no matching function for call to %0" + "%plural{0:|1:; candidate is|:; candidates are:}1") +DIAG(err_ovl_no_viable_member_function_in_call, ERROR, + "no matching member function for call to %0" + "%plural{0:|1:; candidate is|:; candidates are:}1") +DIAG(err_ovl_ambiguous_call, ERROR, + "call to %0 is ambiguous; candidates are:") +DIAG(err_ovl_ambiguous_member_call, ERROR, + "call to member function %0 is ambiguous; candidates are:") +DIAG(err_ovl_candidate, NOTE, + "candidate function") +DIAG(err_ovl_builtin_candidate, NOTE, + "built-in candidate function %0") +DIAG(err_ovl_no_viable_function_in_init, ERROR, + "no matching constructor for initialization of %0" + "%plural{0:|1:; candidate is|:; candidates are:}1") +DIAG(err_ovl_ambiguous_init, ERROR, + "call to constructor of %0 is ambiguous; candidates are:") +DIAG(err_ovl_ambiguous_oper, ERROR, + "use of overloaded operator '%0' is ambiguous; candidates are:") +DIAG(err_ovl_no_viable_oper, ERROR, + "no viable overloaded '%0'; candidate%plural{1: is|:s are}1:") +DIAG(err_ovl_no_viable_object_call, ERROR, + "no matching function for call to object of type %0" + "%plural{0:|1:; candidate is|:; candidates are:}1") +DIAG(err_ovl_ambiguous_object_call, ERROR, + "call to object of type %0 is ambiguous; candidates are:") +DIAG(err_ovl_surrogate_cand, NOTE, + "conversion candidate of type %0") +DIAG(err_member_call_without_object, ERROR, + "call to non-static member function without an object argument") + +/// C++ Templates Semantic Analysis +DIAG(err_template_param_shadow, ERROR, + "declaration of %0 shadows template parameter") +DIAG(note_template_param_here, NOTE, + "template parameter is declared here") +DIAG(note_template_export_unsupported, NOTE, + "exported templates are unsupported") + +DIAG(err_unexpected_typedef, ERROR, + "unexpected type name %0: expected expression") +DIAG(err_unexpected_namespace, ERROR, + "unexpected namespace name %0: expected expression") +DIAG(err_undeclared_var_use, ERROR, + "use of undeclared identifier %0") +DIAG(err_undeclared_use, ERROR, + "use of undeclared '%0'") +DIAG(warn_deprecated, WARNING, + "%0 is deprecated") +DIAG(warn_unavailable, WARNING, + "%0 is unavailable") +DIAG(err_redefinition, ERROR, + "redefinition of %0") +DIAG(err_static_non_static, ERROR, + "static declaration of %0 follows non-static declaration") +DIAG(err_non_static_static, ERROR, + "non-static declaration of %0 follows static declaration") +DIAG(err_redefinition_different_type, ERROR, + "redefinition of %0 with a different type") +DIAG(err_redefinition_different_kind, ERROR, + "redefinition of %0 as different kind of symbol") +DIAG(err_redefinition_different_typedef, ERROR, + "typedef redefinition with different types (%0 vs %1)") +DIAG(err_conflicting_types, ERROR, + "conflicting types for %0") +DIAG(err_nested_redefinition, ERROR, + "nested redefinition of %0") +DIAG(err_use_with_wrong_tag, ERROR, + "use of %0 with tag type that does not match previous declaration") +DIAG(ext_forward_ref_enum, EXTENSION, + "ISO C forbids forward references to 'enum' types") +DIAG(err_redefinition_of_enumerator, ERROR, + "redefinition of enumerator %0") +DIAG(err_duplicate_member, ERROR, + "duplicate member %0") +DIAG(ext_enum_value_not_int, EXTENSION, + "ISO C restricts enumerator values to range of 'int' (%0 is too large)") +DIAG(warn_enum_too_large, WARNING, + "enumeration values exceed range of largest integer") +DIAG(warn_illegal_constant_array_size, EXTENSION, + "size of static array must be an integer constant expression") +DIAG(err_vla_decl_in_file_scope, ERROR, + "variable length array declaration not allowed at file scope") +DIAG(err_vla_decl_has_static_storage, ERROR, + "variable length array declaration can not have 'static' storage duration") +DIAG(err_vla_decl_has_extern_linkage, ERROR, + "variable length array declaration can not have 'extern' linkage") +DIAG(err_vm_decl_in_file_scope, ERROR, + "variably modified type declaration not allowed at file scope") +DIAG(err_vm_decl_has_extern_linkage, ERROR, + "variably modified type declaration can not have 'extern' linkage") +DIAG(err_typecheck_field_variable_size, ERROR, + "fields must have a constant size") +DIAG(err_typecheck_negative_array_size, ERROR, + "array size is negative") +DIAG(warn_typecheck_function_qualifiers, WARNING, + "qualifier on function type %0 has unspecified behavior") +DIAG(err_typecheck_invalid_restrict_not_pointer, ERROR, + "restrict requires a pointer or reference (%0 is invalid)") +DIAG(err_typecheck_invalid_restrict_invalid_pointee, ERROR, + "pointer to function type %0 may not be 'restrict' qualified") +DIAG(ext_typecheck_zero_array_size, EXTENSION, + "zero size arrays are an extension") +DIAG(err_at_least_one_initializer_needed_to_size_array, ERROR, + "at least one initializer value required to size array") +DIAG(err_array_size_non_int, ERROR, + "size of array has non-integer type %0") +DIAG(err_init_element_not_constant, ERROR, + "initializer element is not a compile-time constant") +DIAG(err_block_extern_cant_init, ERROR, + "'extern' variable cannot have an initializer") +DIAG(warn_extern_init, WARNING, + "'extern' variable has an initializer") +DIAG(err_variable_object_no_init, ERROR, + "variable-sized object may not be initialized") +DIAG(err_array_init_list_required, ERROR, + "initialization with '{...}' expected for array") +DIAG(warn_excess_initializers, WARNING, + "excess elements in array initializer") +DIAG(err_excess_initializers_in_char_array_initializer, ERROR, + "excess elements in char array initializer") +DIAG(warn_initializer_string_for_char_array_too_long, WARNING, + "initializer-string for char array is too long") +DIAG(warn_braces_around_scalar_init, WARNING, + "braces around scalar initializer") +DIAG(err_many_braces_around_scalar_init, ERROR, + "too many braces around scalar initializer") +DIAG(err_empty_scalar_initializer, ERROR, + "scalar initializer cannot be empty") +DIAG(err_illegal_initializer, ERROR, + "illegal initializer (only variables can be initialized)") +DIAG(err_illegal_initializer_type, ERROR, + "illegal initializer type %0") +DIAG(err_implicit_empty_initializer, ERROR, + "initializer for aggregate with no elements requires explicit braces") +DIAG(err_bitfield_has_negative_width, ERROR, + "bit-field %0 has negative width") +DIAG(err_bitfield_has_zero_width, ERROR, + "bit-field %0 has zero width") +DIAG(err_bitfield_width_exceeds_type_size, ERROR, + "size of bit-field %0 exceeds size of its type (%1 bits)") + +DIAG(err_redefinition_of_label, ERROR, + "redefinition of label '%0'") +DIAG(err_undeclared_label_use, ERROR, + "use of undeclared label '%0'") + +DIAG(ext_implicit_function_decl, EXTENSION, + "implicit declaration of function %0 is invalid in C99") + +DIAG(err_func_returning_array_function, ERROR, + "function cannot return array or function type %0") +DIAG(err_field_declared_as_function, ERROR, + "field %0 declared as a function") +DIAG(err_field_incomplete, ERROR, + "field has incomplete type %0") +DIAG(err_variable_sized_type_in_struct, EXTENSION, + "variable sized type %0 must be at end of struct or class") +DIAG(err_flexible_array_empty_struct, ERROR, + "flexible array %0 not allowed in otherwise empty struct") +DIAG(ext_flexible_array_in_struct, EXTENSION, + "%0 may not be nested in a struct due to flexible array member") +DIAG(err_flexible_array_in_array, ERROR, + "%0 may not be used as an array element due to flexible array member") +DIAG(err_illegal_decl_array_of_functions, ERROR, + "'%0' declared as array of functions") +DIAG(err_illegal_decl_array_incomplete_type, ERROR, + "array has incomplete element type %0") +DIAG(err_illegal_decl_array_of_references, ERROR, + "'%0' declared as array of references") +DIAG(err_illegal_decl_pointer_to_reference, ERROR, + "'%0' declared as a pointer to a reference") +DIAG(err_illegal_decl_mempointer_to_void, ERROR, + "'%0' declared as a member pointer to void") +DIAG(err_illegal_decl_mempointer_in_nonclass, ERROR, + "'%0' does not point into a class") +DIAG(err_reference_to_void, ERROR, + "cannot form a reference to 'void'") +DIAG(err_qualified_block_pointer_type, ERROR, + "qualifier specification on block pointer type not allowed") +DIAG(err_nonfunction_block_type, ERROR, + "block pointer to non-function type is invalid") +DIAG(err_return_block_has_expr, ERROR, + "void block should not return a value") +DIAG(err_block_return_missing_expr, ERROR, + "non-void block should return a value") +DIAG(err_block_with_return_type_requires_args, ERROR, + "block with explicit return type requires argument list") + +// Expressions. +DIAG(ext_sizeof_function_type, EXTENSION, + "invalid application of 'sizeof' to a function type") +DIAG(ext_sizeof_void_type, EXTENSION, + "invalid application of '%0' to a void type") +// FIXME: merge with %select +DIAG(err_sizeof_incomplete_type, ERROR, + "invalid application of 'sizeof' to an incomplete type %0") +DIAG(err_alignof_incomplete_type, ERROR, + "invalid application of '__alignof' to an incomplete type %0") +DIAG(err_sizeof_alignof_bitfield, ERROR, + "invalid application of '%select{sizeof|__alignof}0' to bitfield") +DIAG(err_offsetof_record_type, ERROR, + "offsetof requires struct, union, or class type, %0 invalid") +DIAG(err_offsetof_array_type, ERROR, + "offsetof requires array type, %0 invalid") +DIAG(ext_offsetof_extended_field_designator, EXTENSION, + "using extended field designator is an extension") + +DIAG(err_typecheck_subscript_value, ERROR, + "subscripted value is neither array nor pointer") +DIAG(err_typecheck_subscript, ERROR, + "array subscript is not an integer") +DIAG(err_typecheck_subscript_not_object, ERROR, + "illegal subscript of non-object type %0") +DIAG(err_typecheck_member_reference_struct_union, ERROR, + "member reference base type %0 is not a structure or union") +DIAG(err_typecheck_member_reference_ivar, ERROR, + "%0 does not have a member named %1") +DIAG(err_typecheck_member_reference_arrow, ERROR, + "member reference type %0 is not a pointer") +DIAG(err_typecheck_member_reference_type, ERROR, + "cannot refer to type member %0 with '%select{.|->}1'") +DIAG(err_typecheck_member_reference_unknown, ERROR, + "cannot refer to member %0 with '%select{.|->}1'") +DIAG(err_typecheck_incomplete_tag, ERROR, + "incomplete definition of type %0") +DIAG(err_typecheck_no_member, ERROR, + "no member named %0") +DIAG(err_member_redeclared, ERROR, + "class member cannot be redeclared") +DIAG(err_member_def_does_not_match, ERROR, + "out-of-line definition does not match any declaration in %0") +DIAG(err_nonstatic_member_out_of_line, ERROR, + "non-static data member defined out-of-line") +DIAG(err_qualified_typedef_declarator, ERROR, + "typedef declarator cannot be qualified") +DIAG(err_qualified_param_declarator, ERROR, + "parameter declarator cannot be qualified") +DIAG(err_out_of_line_declaration, ERROR, + "out-of-line declaration of a member must be a definition") +DIAG(note_member_def_close_match, NOTE, + "member declaration nearly matches") +DIAG(err_typecheck_ivar_variable_size, ERROR, + "instance variables must have a constant size") +// FIXME: Improve with %select +DIAG(err_typecheck_illegal_increment_decrement, ERROR, + "cannot modify value of type %0") +DIAG(err_typecheck_arithmetic_incomplete_type, ERROR, + "arithmetic on pointer to incomplete type %0") +DIAG(err_typecheck_pointer_arith_function_type, ERROR, + "arithmetic on pointer to function type %0") +DIAG(err_typecheck_pointer_arith_void_type, ERROR, + "arithmetic on pointer to void type") +DIAG(err_typecheck_decl_incomplete_type, ERROR, + "variable has incomplete type %0") +// FIXME: Use %select +DIAG(err_realimag_invalid_type, ERROR, + "invalid type %0 to __real or __imag operator") +DIAG(err_typecheck_sclass_fscope, ERROR, + "illegal storage class on file-scoped variable") +DIAG(err_typecheck_sclass_func, ERROR, + "illegal storage class on function") +DIAG(err_typecheck_address_of, ERROR, + "address of %0 requested") +DIAG(err_typecheck_invalid_lvalue_addrof, ERROR, + "address expression must be an lvalue or a function designator") +DIAG(err_typecheck_unary_expr, ERROR, + "invalid argument type %0 to unary expression") +DIAG(err_typecheck_indirection_requires_pointer, ERROR, + "indirection requires pointer operand (%0 invalid)") +DIAG(err_typecheck_invalid_operands, ERROR, + "invalid operands to binary expression (%0 and %1)") +DIAG(err_typecheck_sub_ptr_object, ERROR, + "subtraction of pointer %0 requires pointee to be a complete object type") +DIAG(err_typecheck_sub_ptr_compatible, ERROR, + "%0 and %1 are not pointers to compatible types") +DIAG(ext_typecheck_comparison_of_pointer_integer, WARNING, + "comparison between pointer and integer (%0 and %1)") +DIAG(ext_typecheck_comparison_of_distinct_pointers, WARNING, + "comparison of distinct pointer types (%0 and %1)") +DIAG(err_typecheck_assign_const, ERROR, + "read-only variable is not assignable") +DIAG(err_stmtexpr_file_scope, ERROR, + "statement expression not allowed at file scope") + +DIAG(err_invalid_this_use, ERROR, + "invalid use of 'this' outside of a nonstatic member function") +DIAG(err_invalid_member_use_in_static_method, ERROR, + "invalid use of member %0 in static member function") +DIAG(err_invalid_qualified_function_type, ERROR, + "type qualifier is not allowed on this function") +DIAG(err_invalid_qualified_typedef_function_type_use, ERROR, + "a qualified function type cannot be used to declare a nonmember function " + "or a static member function") +DIAG(err_invalid_non_static_member_use, ERROR, + "invalid use of nonstatic data member %0") +DIAG(err_invalid_incomplete_type_use, ERROR, + "invalid use of incomplete type %0") +DIAG(err_builtin_func_cast_more_than_one_arg, ERROR, + "function-style cast to a builtin type can only take one argument") +DIAG(err_builtin_direct_init_more_than_one_arg, ERROR, + "initializer of a builtin type can only take one argument") +DIAG(err_value_init_for_array_type, ERROR, + "array types cannot be value-initialized") + +DIAG(err_unexpected_interface, ERROR, + "unexpected interface name %0: expected expression") +DIAG(err_property_not_found, ERROR, + "property %0 not found on object of type %1") +DIAG(ext_gnu_void_ptr, EXTENSION, + "use of GNU void* extension") +DIAG(ext_gnu_ptr_func_arith, EXTENSION, + "arithmetic on pointer to function type %0 is a GNU extension") +DIAG(error_readonly_property_assignment, ERROR, + "assigning to property with 'readonly' attribute not allowed") +DIAG(ext_integer_increment_complex, EXTENSION, + "ISO C does not support '++'/'--' on complex integer type %0") +DIAG(ext_integer_complement_complex, EXTENSION, + "ISO C does not support '~' for complex conjugation of %0") +DIAG(error_nosetter_property_assignment, ERROR, + "setter method is needed to assign to object using property" + " assignment syntax") + +// Obj-c expressions +DIAG(warn_class_method_not_found, WARNING, + "method %objcclass0 not found (return type defaults to 'id')") +DIAG(warn_inst_method_not_found, WARNING, + "method %objcinstance0 not found (return type defaults to 'id')") +DIAG(error_no_super_class_message, ERROR, + "no @interface declaration found in class messaging of %0") +DIAG(error_no_super_class, ERROR, + "no super class declared in @interface for %0") +DIAG(err_invalid_receiver_to_message, ERROR, + "invalid receiver to message expression") +DIAG(warn_method_not_found_in_protocol, WARNING, + "method %objcinstance0 not found in protocol (return type defaults to 'id')") +DIAG(error_bad_receiver_type, ERROR, + "bad receiver type %0") + + +// C++ casts +DIAG(err_bad_cxx_cast_generic, ERROR, + "%0 from %2 to %1 is not allowed") +DIAG(err_bad_cxx_cast_rvalue, ERROR, + "%0 from rvalue to reference type %1") +DIAG(err_bad_cxx_cast_const_away, ERROR, + "%0 from %2 to %1 casts away constness") +DIAG(err_bad_const_cast_dest, ERROR, + "const_cast to %0, which is not a reference, pointer-to-object, " + "or pointer-to-data-member") +DIAG(err_bad_reinterpret_cast_same_type, ERROR, + "source and destination type of reinterpret_cast are not distinct") +DIAG(ext_reinterpret_cast_fn_obj, EXTENSION, + "reinterpret_cast between pointer-to-function and pointer-to-object is " + "an extension") +DIAG(err_bad_reinterpret_cast_small_int, ERROR, + "cast from pointer to smaller type %0 loses information") +DIAG(err_bad_dynamic_cast_not_ref_or_ptr, ERROR, + "%0 is not a reference or pointer") +DIAG(err_bad_dynamic_cast_not_class, ERROR, + "%0 is not a class") +DIAG(err_bad_dynamic_cast_incomplete, ERROR, + "%0 is an incomplete type") +DIAG(err_bad_dynamic_cast_not_ptr, ERROR, + "%0 is not a pointer") +DIAG(err_bad_dynamic_cast_not_polymorphic, ERROR, + "%0 is not polymorphic") +// FIXME: Display the path somehow better. +DIAG(err_ambiguous_base_to_derived_cast, ERROR, + "ambiguous static_cast from base %0 to derived %1:%2") +DIAG(err_static_downcast_via_virtual, ERROR, + "cannot cast %0 to %1 via virtual base %2") + +// Other C++ expressions +DIAG(err_need_header_before_typeid, ERROR, + "you need to include before using the 'typeid' operator") +DIAG(err_static_illegal_in_new, ERROR, + "the 'static' modifier for the array size is not legal in new expressions") +DIAG(err_array_new_needs_size, ERROR, + "array size must be specified in new expressions") +DIAG(err_bad_new_type, ERROR, + "cannot allocate %select{function|incomplete|reference}1 type %0 with new") +DIAG(err_new_array_nonconst, ERROR, + "only the first dimension of an allocated array may be non-const") +DIAG(err_array_size_not_integral, ERROR, + "array size expression must have integral or enumerated type, not %0") +DIAG(err_new_uninitialized_const, ERROR, + "must provide an initializer if the allocated object is 'const'") +DIAG(err_delete_operand, ERROR, + "cannot delete expression of type %0") +DIAG(warn_delete_incomplete, WARNING, + "deleting pointer to incomplete type %0 may cause undefined behaviour") +DIAG(err_decrement_bool, ERROR, + "cannot decrement expression of type bool") +DIAG(warn_increment_bool, WARNING, + "incrementing expression of type bool is deprecated") +DIAG(err_catch_incomplete_ptr, ERROR, + "cannot catch pointer to incomplete type %0") +DIAG(err_catch_incomplete_ref, ERROR, + "cannot catch reference to incomplete type %0") +DIAG(err_catch_incomplete, ERROR, + "cannot catch incomplete type %0") +DIAG(err_qualified_catch_declarator, ERROR, + "exception declarator cannot be qualified") +DIAG(err_early_catch_all, ERROR, + "catch-all handler must come last") + +DIAG(err_invalid_use_of_function_type, ERROR, + "a function type is not allowed here") +DIAG(err_invalid_use_of_array_type, ERROR, + "an array type is not allowed here") +DIAG(err_type_defined_in_condition, ERROR, + "types may not be defined in conditions") +DIAG(err_typecheck_bool_condition, ERROR, + "value of type %0 is not contextually convertible to 'bool'") +DIAG(err_expected_class_or_namespace, ERROR, + "expected a class or namespace") +DIAG(err_invalid_declarator_scope, ERROR, + "definition or redeclaration of %0 not in a namespace enclosing %1") +DIAG(err_invalid_declarator_in_function, ERROR, + "definition or redeclaration of %0 not allowed inside a function") +DIAG(err_not_tag_in_scope, ERROR, + "%0 does not name a tag member in the specified scope") + +DIAG(warn_value_always_zero, WARNING, + "%0 is always zero in this context") +DIAG(warn_value_always_false, WARNING, + "%0 is always false in this context") + +// assignment related diagnostics (also for argument passing, returning, etc). +// FIXME: %2 is an english string here. +DIAG(err_typecheck_convert_incompatible, ERROR, + "incompatible type %2 %1, expected %0") +DIAG(err_cannot_initialize_decl_noname, ERROR, + "cannot initialize a value of type %0 with an %select{rvalue|lvalue}1 of type %2") +DIAG(err_cannot_initialize_decl, ERROR, + "cannot initialize %0 with an %select{rvalue|lvalue}1 of type %2") +DIAG(warn_incompatible_qualified_id, WARNING, + "incompatible type %2 %1, expected %0") +DIAG(warn_incompatible_qualified_id_operands, WARNING, + "invalid operands to binary expression (%0 and %1)") +DIAG(ext_typecheck_convert_pointer_int, EXTWARN, + "incompatible pointer to integer conversion %2 %1, expected %0") +DIAG(ext_typecheck_convert_int_pointer, EXTWARN, + "incompatible integer to pointer conversion %2 %1, expected %0") +DIAG(ext_typecheck_convert_pointer_void_func, EXTENSION, + "%2 %1 converts between void* and function pointer, expected %0") +DIAG(ext_typecheck_convert_incompatible_pointer, EXTWARN, + "incompatible pointer types %2 %1, expected %0") +DIAG(ext_typecheck_convert_discards_qualifiers, EXTWARN, + "%2 %1 discards qualifiers, expected %0") +DIAG(err_int_to_block_pointer, ERROR, + "invalid conversion %2 integer %1, expected block pointer %0") +DIAG(err_typecheck_comparison_of_distinct_blocks, ERROR, + "comparison of distinct block types (%0 and %1)") +DIAG(ext_typecheck_convert_incompatible_block_pointer, EXTWARN, + "incompatible block pointer types %2 %1, expected %0") + +DIAG(err_typecheck_array_not_modifiable_lvalue, ERROR, + "array type %0 is not assignable") +DIAG(err_typecheck_non_object_not_modifiable_lvalue, ERROR, + "non-object type %0 is not assignable") +DIAG(err_typecheck_expression_not_modifiable_lvalue, ERROR, + "expression is not assignable") +DIAG(err_typecheck_incomplete_type_not_modifiable_lvalue, ERROR, + "incomplete type %0 is not assignable") +DIAG(err_typecheck_lvalue_casts_not_supported, ERROR, + "assignment to cast is illegal, lvalue casts are not supported") + +DIAG(err_typecheck_duplicate_vector_components_not_mlvalue, ERROR, + "vector is not assignable (contains duplicate components)") +DIAG(err_block_decl_ref_not_modifiable_lvalue, ERROR, + "variable is not assignable (missing __block type specifier)") +DIAG(err_typecheck_call_not_function, ERROR, + "called object type %0 is not a function or function pointer") +DIAG(err_typecheck_call_too_few_args, ERROR, + "too few arguments to %select{function|block|method}0 call") +DIAG(err_typecheck_call_too_many_args, ERROR, + "too many arguments to %select{function|block|method}0 call") +DIAG(warn_cannot_pass_non_pod_arg_to_vararg, WARNING, + "cannot pass object of non-POD type %0 through variadic " + "%select{function|block|method}1; call will abort at runtime") +DIAG(err_typecheck_closure_too_many_args, ERROR, + "too many arguments to closure call") +DIAG(err_typecheck_call_invalid_ordered_compare, ERROR, + "ordered compare requires two args of floating point type (%0 and %1)") +DIAG(err_typecheck_cond_expect_scalar, ERROR, + "used type %0 where arithmetic or pointer type is required") +DIAG(ext_typecheck_cond_one_void, EXTENSION, + "C99 forbids conditional expressions with only one void side") +DIAG(ext_typecheck_cast_nonscalar, EXTENSION, + "C99 forbids casting nonscalar type %0 to the same type") +DIAG(ext_typecheck_cast_to_union, EXTENSION, + "C99 forbids casts to union type") +DIAG(err_typecheck_cast_to_union_no_type, ERROR, + "cast to union type from type %0 not present in union") +DIAG(err_typecheck_expect_scalar_operand, ERROR, + "operand of type %0 where arithmetic or pointer type is required") +DIAG(err_typecheck_cond_incompatible_operands, ERROR, + "incompatible operand types (%0 and %1)") +DIAG(warn_typecheck_cond_incompatible_pointers, WARNING, + "pointer type mismatch (%0 and %1)") +DIAG(err_typecheck_choose_expr_requires_constant, ERROR, + "'__builtin_choose_expr' requires a constant expression") +DIAG(ext_typecheck_expression_not_constant_but_accepted, EXTENSION, + "expression is not a constant, but is accepted as one by GNU extensions") +DIAG(warn_unused_expr, WARNING, + "expression result unused") +DIAG(err_asm_wide_character, ERROR, + "wide string is invalid in 'asm'") +DIAG(err_asm_invalid_lvalue_in_output, ERROR, + "invalid lvalue in asm output") +DIAG(err_asm_invalid_output_constraint, ERROR, + "invalid output constraint '%0' in asm") +DIAG(err_asm_invalid_lvalue_in_input, ERROR, + "invalid lvalue in asm input for constraint '%0'") +DIAG(err_asm_invalid_input_constraint, ERROR, + "invalid input constraint '%0' in asm") +DIAG(err_asm_invalid_type_in_input, ERROR, + "invalid type %0 in asm input for constraint '%1'") +DIAG(err_asm_unknown_register_name, ERROR, + "unknown register name '%0' in asm") +DIAG(err_invalid_conversion_between_vectors, ERROR, + "invalid conversion between vector type %0 and %1 of different size") +DIAG(err_invalid_conversion_between_vector_and_integer, ERROR, + "invalid conversion between vector type %0 and integer type %1 " + "of different size") +DIAG(err_invalid_conversion_between_vector_and_scalar, ERROR, + "invalid conversion between vector type %0 and scalar type %1") +DIAG(err_overload_expr_requires_non_zero_constant, ERROR, + "overload requires a non-zero constant expression as first argument") +DIAG(err_overload_incorrect_fntype, ERROR, + "argument is not a function, or has wrong number of parameters") + +// FIXME: PASSING TYPES AS STRING. +DIAG(err_overload_no_match, ERROR, + "no matching overload found for arguments of type '%0'") +DIAG(err_overload_multiple_match, ERROR, + "more than one matching function found in __builtin_overload") + +// C++ member initializers. +DIAG(err_mem_init_not_member_or_class, ERROR, + "member initializer %0 does not name a non-static data member or base " + "class") +DIAG(err_base_init_does_not_name_class, ERROR, + "constructor initializer %0 does not name a class") +DIAG(err_base_init_direct_and_virtual, ERROR, + "base class initializer %0 names both a direct base class and an" + " inherited virtual base class") + +// C++ anonymous unions and GNU anonymous structs/unions +DIAG(ext_anonymous_union, EXTENSION, + "anonymous unions are a GNU extension in C") +DIAG(ext_anonymous_struct, EXTENSION, + "anonymous structs are a GNU extension") +DIAG(err_anonymous_union_not_static, ERROR, + "anonymous unions at namespace or global scope must be declared 'static'") +DIAG(err_anonymous_union_with_storage_spec, ERROR, + "anonymous union at class scope must not have a storage specifier") +DIAG(err_anonymous_struct_not_member, ERROR, + "anonymous %select{structs|structs and classes}0 must be %select{struct or union|class}0 members") +DIAG(err_anonymous_union_not_member, ERROR, + "anonymous unions must be struct or union members") +DIAG(err_anonymous_union_member_redecl, ERROR, + "member of anonymous union redeclares %0") +DIAG(err_anonymous_struct_member_redecl, ERROR, + "member of anonymous struct redeclares %0") +DIAG(err_anonymous_record_with_type, ERROR, + "types cannot be declared in an anonymous %select{struct|union}0") +DIAG(err_anonymous_record_with_function, ERROR, + "functions cannot be declared in an anonymous %select{struct|union}0") +DIAG(err_anonymous_record_with_static, ERROR, + "static members cannot be declared in an anonymous %select{struct|union}0") +DIAG(err_anonymous_record_bad_member, ERROR, + "anonymous %select{struct|union}0 can only contain non-static data members") +DIAG(err_anonymous_record_nonpublic_member, ERROR, + "anonymous %select{struct|union}0 cannot contain a %select{private|protected}1 data member") + +// C++ derived classes +DIAG(err_base_clause_on_union, ERROR, + "unions cannot have base classes") +DIAG(err_base_must_be_class, ERROR, + "base specifier must name a class") +DIAG(err_union_as_base_class, ERROR, + "unions cannot be base classes") +DIAG(err_incomplete_base_class, ERROR, + "base class has incomplete type") +DIAG(err_duplicate_base_class, ERROR, + "base class %0 specified more than once as a direct base class") +// FIXME: better way to display derivation? Pass entire thing into diagclient? +DIAG(err_ambiguous_derived_to_base_conv, ERROR, + "ambiguous conversion from derived class %0 to base class %1:%2") +DIAG(err_ambiguous_base_to_derived_memptr_conv, ERROR, + "ambiguous conversion from pointer to member of base class %0 " + "to pointer to member of derived class %1:%2") +DIAG(err_memptr_conv_via_virtual, ERROR, + "conversion from pointer to member of class %0 to pointer to member " + "of class %1 via virtual base %2 is not allowed") + +// C++ member name lookup +DIAG(err_ambiguous_member_multiple_subobjects, ERROR, + "non-static member %0 found in multiple base-class subobjects of type %1:%2") +DIAG(err_ambiguous_member_multiple_subobject_types, ERROR, + "member %0 found in multiple base classes of different types") +DIAG(note_ambiguous_member_found, NOTE, + "member found by ambiguous name lookup") + +// C++ operator overloading +DIAG(err_operator_overload_needs_class_or_enum, ERROR, + "overloaded %0 must have at least one parameter of class " + "or enumeration type") +DIAG(err_operator_overload_variadic, ERROR, + "overloaded %0 cannot be variadic") +DIAG(err_operator_overload_static, ERROR, + "overloaded %0 cannot be a static member function") +DIAG(err_operator_overload_default_arg, ERROR, + "parameter of overloaded %0 cannot have a default argument") +DIAG(err_operator_overload_must_be, ERROR, + "overloaded %0 must be a %select{unary|binary|unary or binary}2 operator" + " (has %1 parameter%s1)") +DIAG(err_operator_overload_must_be_member, ERROR, + "overloaded %0 must be a non-static member function") +DIAG(err_operator_overload_post_incdec_must_be_int, ERROR, + "parameter of overloaded post-%select{increment|decrement}1 operator must" + " have type 'int' (not %0)") + +// C++ conversion functions +DIAG(err_conv_function_not_member, ERROR, + "conversion function must be a non-static member function") +DIAG(err_conv_function_return_type, ERROR, + "conversion function cannot have a return type") +DIAG(err_conv_function_with_params, ERROR, + "conversion function cannot have any parameters") +DIAG(err_conv_function_variadic, ERROR, + "conversion function cannot be variadic") +DIAG(err_conv_function_to_array, ERROR, + "conversion function cannot convert to an array type") +DIAG(err_conv_function_to_function, ERROR, + "conversion function cannot convert to a function type") +DIAG(err_conv_function_redeclared, ERROR, + "conversion function cannot be redeclared") +DIAG(warn_conv_to_self_not_used, WARNING, + "conversion function converting %0 to itself will never be used") +DIAG(warn_conv_to_base_not_used, WARNING, + "conversion function converting %0 to its base class %1 will never be used") +DIAG(warn_conv_to_void_not_used, WARNING, + "conversion function converting %0 to %1 will never be used") + +DIAG(warn_not_compound_assign, WARNING, + "use of unary operator that may be intended as compound assignment (%0=)") + +// C++0x explicit conversion operators +DIAG(warn_explicit_conversion_functions, WARNING, + "explicit conversion functions are a C++0x extension") + +DIAG(warn_printf_write_back, WARNING, + "use of '%%n' in format string discouraged (potentially insecure)") +DIAG(warn_printf_insufficient_data_args, WARNING, + "more '%%' conversions than data arguments") +DIAG(warn_printf_too_many_data_args, WARNING, + "more data arguments than '%%' conversions") +DIAG(warn_printf_invalid_conversion, WARNING, + "invalid conversion '%0'") +DIAG(warn_printf_missing_format_string, WARNING, + "format string missing") +DIAG(warn_printf_empty_format_string, WARNING, + "format string is empty") +DIAG(warn_printf_format_string_is_wide_literal, WARNING, + "format string should not be a wide string") +DIAG(warn_printf_format_string_contains_null_char, WARNING, + "format string contains '\\0' within the string body") +DIAG(warn_printf_asterisk_width_missing_arg, WARNING, + "'*' specified field width is missing a matching 'int' argument") +DIAG(warn_printf_asterisk_precision_missing_arg, WARNING, + "'.*' specified field precision is missing a matching 'int' argument") +DIAG(warn_printf_asterisk_width_wrong_type, WARNING, + "field width should have type 'int', but argument has type %0") +DIAG(warn_printf_asterisk_precision_wrong_type, WARNING, + "field precision should have type 'int', but argument has type %0") + +// CHECK: returning address/reference of stack memory +DIAG(warn_ret_stack_addr, WARNING, + "address of stack memory associated with local variable %0 returned") +DIAG(warn_ret_stack_ref, WARNING, + "reference to stack memory associated with local variable %0 returned") + + +// CHECK: for non-floating point, expressions of the form x == x or x != x +// should result in a warning, since these always evaluate to a constant. +DIAG(warn_selfcomparison,WARNING, + "self-comparison always results in a constant value.") + + +// Blocks +DIAG(err_expected_block_lbrace, ERROR, + "expected '{' in block literal") +DIAG(err_goto_in_block, ERROR, + "goto not allowed in block literal") +DIAG(err_return_in_block_expression, ERROR, + "return not allowed in block expression literal") + +DIAG(err_ret_local_block, ERROR, + "returning block that lives on the local stack") + +// CFString checking +DIAG(err_cfstring_literal_not_string_constant, ERROR, + "CFString literal is not a string constant") +DIAG(warn_cfstring_literal_contains_non_ascii_character, WARNING, + "CFString literal contains non-ASCII character") +DIAG(warn_cfstring_literal_contains_nul_character, WARNING, + "CFString literal contains NUL character") + +// Statements. +DIAG(err_continue_not_in_loop, ERROR, + "'continue' statement not in loop statement") +DIAG(err_break_not_in_loop_or_switch, ERROR, + "'break' statement not in loop or switch statement") +DIAG(err_default_not_in_switch, ERROR, + "'default' statement not in switch statement") +DIAG(err_case_not_in_switch, ERROR, + "'case' statement not in switch statement") +DIAG(warn_case_value_overflow, WARNING, + "overflow converting case value to switch condition type (%0 to %1)") +DIAG(err_duplicate_case, ERROR, + "duplicate case value '%0'") +DIAG(warn_case_empty_range, WARNING, + "empty case range specified") +DIAG(err_typecheck_statement_requires_scalar, ERROR, + "statement requires expression of scalar type (%0 invalid)") +DIAG(err_typecheck_statement_requires_integer, ERROR, + "statement requires expression of integer type (%0 invalid)") +DIAG(err_multiple_default_labels_defined, ERROR, + "multiple default labels in one switch") +DIAG(warn_empty_if_body, WARNING, + "if statement has empty body") +DIAG(err_va_start_used_in_non_variadic_function, ERROR, + "'va_start' used in function with fixed args") +DIAG(warn_second_parameter_of_va_start_not_last_named_argument, WARNING, + "second parameter of 'va_start' not last named argument") +DIAG(err_first_argument_to_va_arg_not_of_type_va_list, ERROR, + "first argument to 'va_arg' is of type %0 and not 'va_list'") + +DIAG(warn_return_missing_expr, WARNING, + "non-void %select{function|method}1 %0 should return a value") +DIAG(ext_return_missing_expr, EXTENSION, + "non-void %select{function|method}1 %0 should return a value") +DIAG(ext_return_has_expr, EXTWARN, + "void %select{function|method}1 %0 should not return a value") +DIAG(ext_return_has_void_expr, EXTENSION, + "void %select{function|method}1 %0 should not return void expression") + +DIAG(err_shufflevector_non_vector, ERROR, + "first two arguments to __builtin_shufflevector must be vectors") +DIAG(err_shufflevector_incompatible_vector, ERROR, + "first two arguments to __builtin_shufflevector must have the same type") +DIAG(err_shufflevector_nonconstant_argument, ERROR, + "index for __builtin_shufflevector must be a constant integer") +DIAG(err_shufflevector_argument_too_large, ERROR, + "index for __builtin_shufflevector must be less than the total number" + " of vector elements") + +DIAG(err_stack_const_level, ERROR, + "level argument for a stack address builtin must be constant") + +DIAG(err_prefetch_invalid_argument, ERROR, + "argument to __builtin_prefetch must be a constant integer") +DIAG(err_argument_invalid_range, ERROR, + "argument should be a value from %0 to %1") + +DIAG(err_object_size_invalid_argument, ERROR, + "argument to __builtin_object_size must be a constant integer") + +DIAG(ext_mixed_decls_code, EXTENSION, + "ISO C90 forbids mixing declarations and code") +DIAG(err_non_variable_decl_in_for, ERROR, + "declaration of non-local variable in 'for' loop") +DIAG(err_toomany_element_decls, ERROR, + "Only one element declaration is allowed") +DIAG(err_selector_element_not_lvalue, ERROR, + "selector element is not a valid lvalue") +DIAG(err_selector_element_type, ERROR, + "selector element type %0 is not a valid object") +DIAG(err_collection_expr_type, ERROR, + "collection expression type %0 is not a valid object") + +// Type +DIAG(ext_invalid_sign_spec, EXTENSION, + "'%0' cannot be signed or unsigned") +DIAG(ext_missing_declspec, EXTENSION, + "declaration specifier missing, defaulting to 'int'") +DIAG(ext_missing_type_specifier, EXTENSION, + "type specifier missing, defaults to 'int'") +DIAG(warn_objc_array_of_interfaces, WARNING, + "array of interface %0 should probably be an array of pointers") +DIAG(ext_c99_array_usage, EXTENSION, + "use of C99-specific array features, accepted as an extension") + -- GitLab From 7687a998a41858338e2c607bf28e4814350ea719 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 18:34:53 +0000 Subject: [PATCH 284/682] add new headers llvm-svn: 63113 --- clang/include/clang/Basic/DiagnosticAST.h | 18 +++++++ .../include/clang/Basic/DiagnosticAnalysis.h | 18 +++++++ clang/include/clang/Basic/DiagnosticDriver.h | 48 +++++++++++++++++++ clang/include/clang/Basic/DiagnosticLex.h | 18 +++++++ clang/include/clang/Basic/DiagnosticParse.h | 18 +++++++ clang/include/clang/Basic/DiagnosticSema.h | 18 +++++++ 6 files changed, 138 insertions(+) create mode 100644 clang/include/clang/Basic/DiagnosticAST.h create mode 100644 clang/include/clang/Basic/DiagnosticAnalysis.h create mode 100644 clang/include/clang/Basic/DiagnosticDriver.h create mode 100644 clang/include/clang/Basic/DiagnosticLex.h create mode 100644 clang/include/clang/Basic/DiagnosticParse.h create mode 100644 clang/include/clang/Basic/DiagnosticSema.h diff --git a/clang/include/clang/Basic/DiagnosticAST.h b/clang/include/clang/Basic/DiagnosticAST.h new file mode 100644 index 000000000000..4f8382bdca04 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticAST.h @@ -0,0 +1,18 @@ +#ifndef LLVM_CLANG_DIAGNOSTICAST_H +#define LLVM_CLANG_DIAGNOSTICAST_H + +#include "clang/Basic/DiagnosticAST.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" +#define ASTSTART +#include "DiagnosticASTKinds.def" + NUM_BUILTIN_AST_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/clang/include/clang/Basic/DiagnosticAnalysis.h b/clang/include/clang/Basic/DiagnosticAnalysis.h new file mode 100644 index 000000000000..fc13eea4c966 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticAnalysis.h @@ -0,0 +1,18 @@ +#ifndef LLVM_CLANG_DIAGNOSTICANALYSIS_H +#define LLVM_CLANG_DIAGNOSTICANALYSIS_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" +#define ANALYSISSTART +#include "DiagnosticAnalysisKinds.def" + NUM_BUILTIN_ANALYSIS_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/clang/include/clang/Basic/DiagnosticDriver.h b/clang/include/clang/Basic/DiagnosticDriver.h new file mode 100644 index 000000000000..44e93b4d3cac --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticDriver.h @@ -0,0 +1,48 @@ +#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H +#define LLVM_CLANG_DIAGNOSTICDRIVER_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" + NUM_BUILTIN_DRIVER_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif +#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H +#define LLVM_CLANG_DIAGNOSTICDRIVER_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" + NUM_BUILTIN_DRIVER_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif +#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H +#define LLVM_CLANG_DIAGNOSTICDRIVER_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" + NUM_BUILTIN_DRIVER_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/clang/include/clang/Basic/DiagnosticLex.h b/clang/include/clang/Basic/DiagnosticLex.h new file mode 100644 index 000000000000..90665b5bad4e --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticLex.h @@ -0,0 +1,18 @@ +#ifndef LLVM_CLANG_DIAGNOSTICLEX_H +#define LLVM_CLANG_DIAGNOSTICLEX_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" +#define LEXSTART +#include "DiagnosticLexKinds.def" + NUM_BUILTIN_LEX_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/clang/include/clang/Basic/DiagnosticParse.h b/clang/include/clang/Basic/DiagnosticParse.h new file mode 100644 index 000000000000..81a073e84153 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticParse.h @@ -0,0 +1,18 @@ +#ifndef LLVM_CLANG_DIAGNOSTICPARSE_H +#define LLVM_CLANG_DIAGNOSTICPARSE_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" +#define PARSESTART +#include "DiagnosticParseKinds.def" + NUM_BUILTIN_PARSE_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif diff --git a/clang/include/clang/Basic/DiagnosticSema.h b/clang/include/clang/Basic/DiagnosticSema.h new file mode 100644 index 000000000000..9ed7ca4c6e55 --- /dev/null +++ b/clang/include/clang/Basic/DiagnosticSema.h @@ -0,0 +1,18 @@ +#ifndef LLVM_CLANG_DIAGNOSTICSEMA_H +#define LLVM_CLANG_DIAGNOSTICSEMA_H + +#include "clang/Basic/Diagnostic.h" + +namespace clang { + namespace diag { + enum { +#define DIAG(ENUM,FLAGS,DESC) ENUM, +#include "DiagnosticCommonKinds.def" +#define SEMASTART +#include "DiagnosticSemaKinds.def" + NUM_BUILTIN_SEMA_DIAGNOSTICS + }; + } // end namespace diag +} // end namespace clang + +#endif -- GitLab From 7ec8851c8970eddeadf25724e4762ea736477e6d Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 27 Jan 2009 18:55:00 +0000 Subject: [PATCH 285/682] Fixed a typo in getPreferredTypeAlign method. llvm-svn: 63116 --- clang/lib/AST/ASTContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index e7c08e2da39b..28007659ec97 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -463,7 +463,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) { // Doubles should be naturally aligned if possible. if (const BuiltinType *BT = dyn_cast(getCanonicalType(T))) if (BT->getKind() == BuiltinType::Double) - return std::max(ABIAlign, 8U); + return std::max(ABIAlign, 64U); return ABIAlign; } -- GitLab From 75441a3870fdd29668513b6978798f9d223e78c5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 27 Jan 2009 18:56:08 +0000 Subject: [PATCH 286/682] eliminate some random .ll file outputs llvm-svn: 63117 --- clang/test/CodeGen/opaque-pointer.c | 2 +- clang/test/CodeGen/pointer-arithmetic.c | 2 +- clang/test/CodeGen/string-literal.c | 2 +- clang/test/CodeGen/struct-comma.c | 2 +- clang/test/CodeGen/struct-init.c | 2 +- clang/test/CodeGen/struct.c | 2 +- clang/test/CodeGen/typedef.c | 2 +- clang/test/CodeGen/union.c | 2 +- clang/test/CodeGen/unsupported.c | 2 +- clang/test/CodeGen/vector.c | 2 +- clang/test/CodeGen/whilestmt.c | 2 +- clang/test/CodeGen/writable-strings.c | 2 +- 12 files changed, 12 insertions(+), 12 deletions(-) diff --git a/clang/test/CodeGen/opaque-pointer.c b/clang/test/CodeGen/opaque-pointer.c index 31c27f49144f..ba307f4d1939 100644 --- a/clang/test/CodeGen/opaque-pointer.c +++ b/clang/test/CodeGen/opaque-pointer.c @@ -1,4 +1,4 @@ -// RUN: clang %s -emit-llvm -o %t +// RUN: clang %s -emit-llvm -o - struct test; typedef void (*my_func) (struct test *); diff --git a/clang/test/CodeGen/pointer-arithmetic.c b/clang/test/CodeGen/pointer-arithmetic.c index 23a6ab41a1c6..b1436b92492f 100644 --- a/clang/test/CodeGen/pointer-arithmetic.c +++ b/clang/test/CodeGen/pointer-arithmetic.c @@ -1,4 +1,4 @@ -// RUN: clang -S %s -o %t +// RUN: clang -S %s -o - typedef int Int; diff --git a/clang/test/CodeGen/string-literal.c b/clang/test/CodeGen/string-literal.c index e19168e4104c..104477ee12ea 100644 --- a/clang/test/CodeGen/string-literal.c +++ b/clang/test/CodeGen/string-literal.c @@ -1,4 +1,4 @@ -// RUN: clang -emit-llvm %s -o %t +// RUN: clang -emit-llvm %s -o - int main() { char a[10] = "abc"; diff --git a/clang/test/CodeGen/struct-comma.c b/clang/test/CodeGen/struct-comma.c index b53013f7aab7..293052921079 100644 --- a/clang/test/CodeGen/struct-comma.c +++ b/clang/test/CodeGen/struct-comma.c @@ -1,4 +1,4 @@ -// RUN: clang %s -emit-llvm -o %t +// RUN: clang %s -emit-llvm -o - struct S {int a, b;} x; void a(struct S* b) {*b = (r(), x);} diff --git a/clang/test/CodeGen/struct-init.c b/clang/test/CodeGen/struct-init.c index ab14a1dc1d47..7d9d7082a762 100644 --- a/clang/test/CodeGen/struct-init.c +++ b/clang/test/CodeGen/struct-init.c @@ -1,4 +1,4 @@ -// RUN: clang %s -emit-llvm -o %t +// RUN: clang %s -emit-llvm -o - typedef struct _zend_ini_entry zend_ini_entry; struct _zend_ini_entry { diff --git a/clang/test/CodeGen/struct.c b/clang/test/CodeGen/struct.c index 76d9b772742e..c71796d9da10 100644 --- a/clang/test/CodeGen/struct.c +++ b/clang/test/CodeGen/struct.c @@ -1,4 +1,4 @@ -// RUN: clang %s -emit-llvm -o %t +// RUN: clang %s -emit-llvm -o - struct { int x; diff --git a/clang/test/CodeGen/typedef.c b/clang/test/CodeGen/typedef.c index 75f6933c40d0..a615285620df 100644 --- a/clang/test/CodeGen/typedef.c +++ b/clang/test/CodeGen/typedef.c @@ -1,4 +1,4 @@ -// RUN: clang -emit-llvm %s -o %t +// RUN: clang -emit-llvm %s -o - typedef struct { int i; } Value; typedef Value *PValue; diff --git a/clang/test/CodeGen/union.c b/clang/test/CodeGen/union.c index 9d82f4fd9b6f..4b09a845b5db 100644 --- a/clang/test/CodeGen/union.c +++ b/clang/test/CodeGen/union.c @@ -1,4 +1,4 @@ -// RUN: clang %s -emit-llvm -o %t +// RUN: clang %s -emit-llvm -o - union u_tag { int a; diff --git a/clang/test/CodeGen/unsupported.c b/clang/test/CodeGen/unsupported.c index 664119acdd49..c5221493edf1 100644 --- a/clang/test/CodeGen/unsupported.c +++ b/clang/test/CodeGen/unsupported.c @@ -1,4 +1,4 @@ -// RUN: clang -verify -emit-llvm -o %t %s +// RUN: clang -verify -emit-llvm -o - %s int f0(int x) { int vla[x]; diff --git a/clang/test/CodeGen/vector.c b/clang/test/CodeGen/vector.c index 86956e05f58f..366c9aafddcb 100644 --- a/clang/test/CodeGen/vector.c +++ b/clang/test/CodeGen/vector.c @@ -1,4 +1,4 @@ -// RUN: clang -emit-llvm %s -o %t +// RUN: clang -emit-llvm %s -o - typedef short __v4hi __attribute__ ((__vector_size__ (8))); void f() diff --git a/clang/test/CodeGen/whilestmt.c b/clang/test/CodeGen/whilestmt.c index c7f8de8a5291..fe17e1b2f192 100644 --- a/clang/test/CodeGen/whilestmt.c +++ b/clang/test/CodeGen/whilestmt.c @@ -1,4 +1,4 @@ -// RUN: clang %s -emit-llvm -o %t +// RUN: clang %s -emit-llvm -o - int bar(); int foo() { diff --git a/clang/test/CodeGen/writable-strings.c b/clang/test/CodeGen/writable-strings.c index cde64aa5e6d3..a2a8f3cc4023 100644 --- a/clang/test/CodeGen/writable-strings.c +++ b/clang/test/CodeGen/writable-strings.c @@ -1,4 +1,4 @@ -// RUN: clang -emit-llvm -o %t -fwritable-strings %s +// RUN: clang -emit-llvm -o - -fwritable-strings %s int main() { char *str = "abc"; -- GitLab From f77f0ce21aaba21df9754fa4e7332d300af0bb31 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 19:04:30 +0000 Subject: [PATCH 287/682] Simplify findNonImmUse; return the result using the return value instead of via a by-reference argument. No functionality change. llvm-svn: 63118 --- llvm/lib/Target/X86/X86ISelDAGToDAG.cpp | 30 ++++++++++++------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp index c5a6edd87a77..54b04ecabc69 100644 --- a/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp +++ b/llvm/lib/Target/X86/X86ISelDAGToDAG.cpp @@ -249,30 +249,30 @@ static SDNode *findFlagUse(SDNode *N) { return NULL; } -/// findNonImmUse - Return true by reference in "found" if "Use" is an -/// non-immediate use of "Def". This function recursively traversing -/// up the operand chain ignoring certain nodes. -static void findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, - SDNode *Root, bool &found, +/// findNonImmUse - Return true if "Use" is a non-immediate use of "Def". +/// This function recursively traverses up the operand chain, ignoring +/// certain nodes. +static bool findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, + SDNode *Root, SmallPtrSet &Visited) { - if (found || - Use->getNodeId() < Def->getNodeId() || + if (Use->getNodeId() < Def->getNodeId() || !Visited.insert(Use)) - return; - - for (unsigned i = 0, e = Use->getNumOperands(); !found && i != e; ++i) { + return false; + + for (unsigned i = 0, e = Use->getNumOperands(); i != e; ++i) { SDNode *N = Use->getOperand(i).getNode(); if (N == Def) { if (Use == ImmedUse || Use == Root) continue; // We are not looking for immediate use. assert(N != Root); - found = true; - break; + return true; } // Traverse up the operand chain. - findNonImmUse(N, Def, ImmedUse, Root, found, Visited); + if (findNonImmUse(N, Def, ImmedUse, Root, Visited)) + return true; } + return false; } /// isNonImmUse - Start searching from Root up the DAG to check is Def can @@ -287,9 +287,7 @@ static void findNonImmUse(SDNode *Use, SDNode* Def, SDNode *ImmedUse, /// its chain operand. static inline bool isNonImmUse(SDNode *Root, SDNode *Def, SDNode *ImmedUse) { SmallPtrSet Visited; - bool found = false; - findNonImmUse(Root, Def, ImmedUse, Root, found, Visited); - return found; + return findNonImmUse(Root, Def, ImmedUse, Root, Visited); } -- GitLab From 13f18e853fcc1ad04d7d06786de0c647e0924aae Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 19:19:28 +0000 Subject: [PATCH 288/682] Respect the DisableRedZone flag on PowerPC. llvm-svn: 63119 --- llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp index b7e3ac282404..c5c9defd9dac 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp @@ -893,7 +893,8 @@ void PPCRegisterInfo::determineFrameLayout(MachineFunction &MF) const { // If we are a leaf function, and use up to 224 bytes of stack space, // don't have a frame pointer, calls, or dynamic alloca then we do not need // to adjust the stack pointer (we fit in the Red Zone). - if (FrameSize <= 224 && // Fits in red zone. + if (!DisableRedZone && + FrameSize <= 224 && // Fits in red zone. !MFI->hasVarSizedObjects() && // No dynamic alloca. !MFI->hasCalls() && // No calls. (!ALIGN_STACK || MaxAlign <= TargetAlign)) { // No special alignment. -- GitLab From 0bd9546039e0815e028fb3a507eefff722d92d7b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 19:23:22 +0000 Subject: [PATCH 289/682] Delete redundant return statements. llvm-svn: 63120 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 7 ------- 1 file changed, 7 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index c467d9c3cb43..982177cf61e5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -1341,7 +1341,6 @@ void SelectionDAGLowering::visitJumpTable(JumpTable &JT) { SDValue Table = DAG.getJumpTable(JT.JTI, PTy); DAG.setRoot(DAG.getNode(ISD::BR_JT, MVT::Other, Index.getValue(1), Table, Index)); - return; } /// visitJumpTableHeader - This function emits necessary code to produce index @@ -1392,8 +1391,6 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT, else DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond, DAG.getBasicBlock(JT.MBB))); - - return; } /// visitBitTestHeader - This function emits necessary code to produce value @@ -1439,8 +1436,6 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { else DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, CopyTo, DAG.getBasicBlock(MBB))); - - return; } /// visitBitTestCase - this function produces one "bit test" @@ -1479,8 +1474,6 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, else DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrAnd, DAG.getBasicBlock(NextMBB))); - - return; } void SelectionDAGLowering::visitInvoke(InvokeInst &I) { -- GitLab From 0ca1e7c6b6e139208dc5dd60feaedeb1b8cf1727 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 19:25:38 +0000 Subject: [PATCH 290/682] Reformat the allocation-order arrays to a more conventional style. llvm-svn: 63121 --- llvm/lib/Target/X86/X86RegisterInfo.td | 99 ++++++++++++++------------ 1 file changed, 55 insertions(+), 44 deletions(-) diff --git a/llvm/lib/Target/X86/X86RegisterInfo.td b/llvm/lib/Target/X86/X86RegisterInfo.td index b67b1bb2f3fa..7303e8a40d4e 100644 --- a/llvm/lib/Target/X86/X86RegisterInfo.td +++ b/llvm/lib/Target/X86/X86RegisterInfo.td @@ -237,20 +237,23 @@ def GR8 : RegisterClass<"X86", [i8], 8, iterator allocation_order_end(const MachineFunction &MF) const; }]; let MethodBodies = [{ - // Does the function dedicate RBP / EBP to being a frame ptr? - // If so, don't allocate SPL or BPL. - static const unsigned X86_GR8_AO_64_fp[] = - {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, - X86::R8B, X86::R9B, X86::R10B, X86::R11B, - X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B}; - // If not, just don't allocate SPL. - static const unsigned X86_GR8_AO_64[] = - {X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, - X86::R8B, X86::R9B, X86::R10B, X86::R11B, - X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, X86::BPL}; - // In 32-mode, none of the 8-bit registers aliases EBP or ESP. - static const unsigned X86_GR8_AO_32[] = - {X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH}; + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate SPL or BPL. + static const unsigned X86_GR8_AO_64_fp[] = { + X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, + X86::R8B, X86::R9B, X86::R10B, X86::R11B, + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B + }; + // If not, just don't allocate SPL. + static const unsigned X86_GR8_AO_64[] = { + X86::AL, X86::CL, X86::DL, X86::SIL, X86::DIL, + X86::R8B, X86::R9B, X86::R10B, X86::R11B, + X86::BL, X86::R14B, X86::R15B, X86::R12B, X86::R13B, X86::BPL + }; + // In 32-mode, none of the 8-bit registers aliases EBP or ESP. + static const unsigned X86_GR8_AO_32[] = { + X86::AL, X86::CL, X86::DL, X86::AH, X86::CH, X86::DH, X86::BL, X86::BH + }; GR8Class::iterator GR8Class::allocation_order_begin(const MachineFunction &MF) const { @@ -290,21 +293,25 @@ def GR16 : RegisterClass<"X86", [i16], 16, iterator allocation_order_end(const MachineFunction &MF) const; }]; let MethodBodies = [{ - // Does the function dedicate RBP / EBP to being a frame ptr? - // If so, don't allocate SP or BP. - static const unsigned X86_GR16_AO_64_fp[] = - {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, - X86::R8W, X86::R9W, X86::R10W, X86::R11W, - X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W}; - static const unsigned X86_GR16_AO_32_fp[] = - {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX}; - // If not, just don't allocate SPL. - static const unsigned X86_GR16_AO_64[] = - {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, - X86::R8W, X86::R9W, X86::R10W, X86::R11W, - X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, X86::BP}; - static const unsigned X86_GR16_AO_32[] = - {X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP}; + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate SP or BP. + static const unsigned X86_GR16_AO_64_fp[] = { + X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, + X86::R8W, X86::R9W, X86::R10W, X86::R11W, + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W + }; + static const unsigned X86_GR16_AO_32_fp[] = { + X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX + }; + // If not, just don't allocate SPL. + static const unsigned X86_GR16_AO_64[] = { + X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, + X86::R8W, X86::R9W, X86::R10W, X86::R11W, + X86::BX, X86::R14W, X86::R15W, X86::R12W, X86::R13W, X86::BP + }; + static const unsigned X86_GR16_AO_32[] = { + X86::AX, X86::CX, X86::DX, X86::SI, X86::DI, X86::BX, X86::BP + }; GR16Class::iterator GR16Class::allocation_order_begin(const MachineFunction &MF) const { @@ -354,21 +361,25 @@ def GR32 : RegisterClass<"X86", [i32], 32, iterator allocation_order_end(const MachineFunction &MF) const; }]; let MethodBodies = [{ - // Does the function dedicate RBP / EBP to being a frame ptr? - // If so, don't allocate ESP or EBP. - static const unsigned X86_GR32_AO_64_fp[] = - {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, - X86::R8D, X86::R9D, X86::R10D, X86::R11D, - X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D}; - static const unsigned X86_GR32_AO_32_fp[] = - {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX}; - // If not, just don't allocate SPL. - static const unsigned X86_GR32_AO_64[] = - {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, - X86::R8D, X86::R9D, X86::R10D, X86::R11D, - X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP}; - static const unsigned X86_GR32_AO_32[] = - {X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP}; + // Does the function dedicate RBP / EBP to being a frame ptr? + // If so, don't allocate ESP or EBP. + static const unsigned X86_GR32_AO_64_fp[] = { + X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, + X86::R8D, X86::R9D, X86::R10D, X86::R11D, + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D + }; + static const unsigned X86_GR32_AO_32_fp[] = { + X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX + }; + // If not, just don't allocate SPL. + static const unsigned X86_GR32_AO_64[] = { + X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, + X86::R8D, X86::R9D, X86::R10D, X86::R11D, + X86::EBX, X86::R14D, X86::R15D, X86::R12D, X86::R13D, X86::EBP + }; + static const unsigned X86_GR32_AO_32[] = { + X86::EAX, X86::ECX, X86::EDX, X86::ESI, X86::EDI, X86::EBX, X86::EBP + }; GR32Class::iterator GR32Class::allocation_order_begin(const MachineFunction &MF) const { -- GitLab From 2ad3ff0bd6e2530066c67598d2c9d84efcee5baf Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 27 Jan 2009 19:29:51 +0000 Subject: [PATCH 291/682] ccc: Normalize machine name to i386 for platforms which report the machine as x86_64. llvm-svn: 63122 --- clang/tools/ccc/ccclib/Driver.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py index 0fe58068ae40..095745facc65 100644 --- a/clang/tools/ccc/ccclib/Driver.py +++ b/clang/tools/ccc/ccclib/Driver.py @@ -52,6 +52,8 @@ class Driver(object): # Normalize names. if machine == 'Power Macintosh': return 'ppc' + if machine == 'x86_64': + return 'i386' return machine def getHostSystemName(self): -- GitLab From 7415caa3d4269213f1849f5c0a3b80e10431c53c Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 27 Jan 2009 19:38:51 +0000 Subject: [PATCH 292/682] ivar meta-data generation for nonfragile-abi. Still more work to do in this area. llvm-svn: 63126 --- clang/include/clang/AST/DeclObjC.h | 2 + clang/lib/CodeGen/CGObjCMac.cpp | 89 +++++++++++++++++++++++++++++- 2 files changed, 89 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index 3dbef7083754..fcf6e5864e51 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -927,9 +927,11 @@ public: /// ObjCImplementationDecl - Represents a class definition - this is where /// method definitions are specified. For example: /// +/// @code /// @implementation MyClass /// - (void)myMethod { /* do something */ } /// @end +/// @endcode /// /// Typically, instance variables are specified in the class interface, /// *not* in the implementation. Nevertheless (for legacy reasons), we diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 9365535079a2..eef74083daea 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -562,7 +562,13 @@ private: /// implementation. The return value has type MethodListnfABITy. llvm::Constant *EmitMethodList(const std::string &Name, const char *Section, - const ConstantVector &Methods); + const ConstantVector &Methods); + /// EmitIvarList - Emit the ivar list for the given + /// implementation. If ForClass is true the list of class ivars + /// (i.e. metaclass ivars) is emitted, otherwise the list of + /// interface ivars will be emitted. The return value has type + /// IvarListnfABIPtrTy. + llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); @@ -3157,7 +3163,10 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( Values[ 5] = EmitMethodList(MethodListName, ".section __DATA,__data,regular,no_dead_strip", Methods); Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); - Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); + if (flags & CLS_META) + Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); + else + Values[ 7] = EmitIvarList(ID); Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy, @@ -3505,6 +3514,82 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.MethodListnfABIPtrTy); } + +/// EmitIvarList - Emit the ivar list for the given +/// implementation. If ForClass is true the list of class ivars +/// (i.e. metaclass ivars) is emitted, otherwise the list of +/// interface ivars will be emitted. The return value has type +/// IvarListnfABIPtrTy. +/// struct _ivar_t { +/// unsigned long int *offset; // pointer to ivar offset location +/// char *name; +/// char *type; +/// uint32_t alignment; +/// uint32_t size; +/// } +/// struct _ivar_list_t { +/// uint32 entsize; // sizeof(struct _ivar_t) +/// uint32 count; +/// struct _iver_t list[count]; +/// } +/// +llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( + const ObjCImplementationDecl *ID) { + + std::vector Ivars, Ivar(5); + + const ObjCInterfaceDecl *OID = ID->getClassInterface(); + assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); + + for(ObjCInterfaceDecl::ivar_iterator i = OID->ivar_begin(), + e = OID->ivar_end(); i != e; ++i) { + FieldDecl *Field = *i; + // FIXME. Put the offset symbol address after code gen. + // for non-fragile ivar access is in. + Ivar[0] = llvm::Constant::getNullValue( + llvm::PointerType::getUnqual(ObjCTypes.LongTy)); + if (Field->getIdentifier()) + Ivar[1] = GetMethodVarName(Field->getIdentifier()); + else + Ivar[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); + std::string TypeStr; + CGM.getContext().getObjCEncodingForType(Field->getType(), TypeStr, Field); + Ivar[2] = GetMethodVarType(TypeStr); + const llvm::Type *FieldTy = + CGM.getTypes().ConvertTypeForMem(Field->getType()); + unsigned Size = CGM.getTargetData().getTypePaddedSize(FieldTy); + unsigned Align = CGM.getContext().getPreferredTypeAlign( + Field->getType().getTypePtr()) >> 3; + Align = llvm::Log2_32(Align); + Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); + Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); + Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); + } + // Return null for empty list. + if (Ivars.empty()) + return llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); + std::vector Values(3); + unsigned Size = CGM.getTargetData().getTypePaddedSize(ObjCTypes.IvarnfABITy); + Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); + Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, Ivars.size()); + llvm::ArrayType *AT = llvm::ArrayType::get(ObjCTypes.IvarnfABITy, + Ivars.size()); + Values[2] = llvm::ConstantArray::get(AT, Ivars); + llvm::Constant *Init = llvm::ConstantStruct::get(Values); + const char *Prefix = "\01l_OBJC_$_INSTANCE_VARIABLES_"; + llvm::GlobalVariable *GV = + new llvm::GlobalVariable(Init->getType(), false, + llvm::GlobalValue::InternalLinkage, + Init, + Prefix + OID->getNameAsString(), + &CGM.getModule()); + + GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + + UsedGlobals.push_back(GV); + return llvm::ConstantExpr::getBitCast(GV, + ObjCTypes.IvarListnfABIPtrTy); +} /* *** */ CodeGen::CGObjCRuntime * -- GitLab From 570c357ded427b55c35ddfe4b5ff73e221ea1305 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Tue, 27 Jan 2009 20:38:24 +0000 Subject: [PATCH 293/682] If an input constraint refers to an output constraint, it should have the same constraint info as the output constraint. Fixes PR3417 llvm-svn: 63127 --- clang/include/clang/Basic/TargetInfo.h | 1 + clang/lib/Basic/TargetInfo.cpp | 5 +++++ clang/lib/CodeGen/CGStmt.cpp | 7 ++++++- clang/lib/Sema/SemaStmt.cpp | 8 +++++++- clang/test/CodeGen/asm.c | 9 +++++---- clang/test/Sema/asm.c | 2 +- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h index da14365e4dd5..67d7e6381452 100644 --- a/clang/include/clang/Basic/TargetInfo.h +++ b/clang/include/clang/Basic/TargetInfo.h @@ -201,6 +201,7 @@ public: bool validateInputConstraint(const char *Name, const std::string *OutputNamesBegin, const std::string *OutputNamesEnd, + ConstraintInfo* OutputConstraints, ConstraintInfo &info) const; bool resolveSymbolicName(const char *&Name, const std::string *OutputNamesBegin, diff --git a/clang/lib/Basic/TargetInfo.cpp b/clang/lib/Basic/TargetInfo.cpp index 3ec3551ebb32..2b73582b7862 100644 --- a/clang/lib/Basic/TargetInfo.cpp +++ b/clang/lib/Basic/TargetInfo.cpp @@ -222,6 +222,7 @@ bool TargetInfo::resolveSymbolicName(const char *&Name, bool TargetInfo::validateInputConstraint(const char *Name, const std::string *OutputNamesBegin, const std::string *OutputNamesEnd, + ConstraintInfo* OutputConstraints, ConstraintInfo &info) const { info = CI_None; @@ -236,6 +237,10 @@ bool TargetInfo::validateInputConstraint(const char *Name, // Check if matching constraint is out of bounds. if (i >= NumOutputs) return false; + + // The constraint should have the same info as the respective + // output constraint. + info = (ConstraintInfo)(info|OutputConstraints[i]); } else if (!validateAsmConstraint(*Name, info)) { // FIXME: This error return is in place temporarily so we can // add more constraints as we hit it. Eventually, an unknown diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp index 4adff72470d5..939ebec01e3d 100644 --- a/clang/lib/CodeGen/CGStmt.cpp +++ b/clang/lib/CodeGen/CGStmt.cpp @@ -932,7 +932,9 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { std::string InOutConstraints; std::vector InOutArgs; std::vector InOutArgTypes; - + + llvm::SmallVector OutputConstraintInfos; + for (unsigned i = 0, e = S.getNumOutputs(); i != e; i++) { std::string OutputConstraint(S.getOutputConstraint(i)->getStrData(), S.getOutputConstraint(i)->getByteLength()); @@ -942,6 +944,8 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { Info); assert(result && "Failed to parse output constraint"); result=result; + OutputConstraintInfos.push_back(Info); + // Simplify the output constraint. OutputConstraint = SimplifyConstraint(OutputConstraint.c_str() + 1, Target); @@ -993,6 +997,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) { bool result = Target.validateInputConstraint(InputConstraint.c_str(), S.begin_output_names(), S.end_output_names(), + &OutputConstraintInfos[0], Info); result=result; assert(result && "Failed to parse input constraint"); diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index 0001f649eedc..c01eceb4ba9e 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/lib/Sema/SemaStmt.cpp @@ -849,6 +849,8 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, StringLiteral *AsmString = cast((Expr *)asmString.get()); StringLiteral **Clobbers = reinterpret_cast(clobbers.get()); + llvm::SmallVector OutputConstraintInfos; + // The parser verifies that there is a string literal here. if (AsmString->isWide()) return StmtError(Diag(AsmString->getLocStart(),diag::err_asm_wide_character) @@ -877,6 +879,8 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, diag::err_asm_invalid_lvalue_in_output) << OutputExpr->getSubExpr()->getSourceRange()); } + + OutputConstraintInfos.push_back(info); } for (unsigned i = NumOutputs, e = NumOutputs + NumInputs; i != e; i++) { @@ -891,7 +895,9 @@ Sema::OwningStmtResult Sema::ActOnAsmStmt(SourceLocation AsmLoc, TargetInfo::ConstraintInfo info; if (!Context.Target.validateInputConstraint(InputConstraint.c_str(), &Names[0], - &Names[0] + NumOutputs, info)) { + &Names[0] + NumOutputs, + &OutputConstraintInfos[0], + info)) { return StmtError(Diag(Literal->getLocStart(), diag::err_asm_invalid_input_constraint) << InputConstraint); } diff --git a/clang/test/CodeGen/asm.c b/clang/test/CodeGen/asm.c index 4ef97bde2ad3..26aa3bd61b3a 100644 --- a/clang/test/CodeGen/asm.c +++ b/clang/test/CodeGen/asm.c @@ -22,7 +22,8 @@ void t4() __asm__ volatile ("":: "m"(a), "m"(b)); } - - - - +// PR3417 +void t5(int i) +{ + asm("nop" : "=r"(i) : "0"(t5)); +} diff --git a/clang/test/Sema/asm.c b/clang/test/Sema/asm.c index fa9b125b6dd4..3acb58a015a2 100644 --- a/clang/test/Sema/asm.c +++ b/clang/test/Sema/asm.c @@ -59,4 +59,4 @@ void test5() void test6(long i) { asm("nop" : : "er"(i)); -} \ No newline at end of file +} -- GitLab From fb58faf29e10a4f798f661a317ed5f0992284842 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 20:39:34 +0000 Subject: [PATCH 294/682] Add an assertion to the form of SelectionDAG::getConstant that takes a uint64_t to verify that the value is in range for the given type, to help catch accidental overflow. Fix a few places that relied on getConstant implicitly truncating the value. llvm-svn: 63128 --- llvm/include/llvm/CodeGen/ValueTypes.h | 7 +++++-- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 +++++++++------ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 +++ 4 files changed, 18 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 1a08f4d6086e..2846eb02db28 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -444,8 +444,11 @@ namespace llvm { /// getIntegerVTBitMask - Return an integer with 1's every place there are /// bits in the specified integer value type. FIXME: Should return an apint. uint64_t getIntegerVTBitMask() const { - assert(isInteger() && !isVector() && "Only applies to int scalars!"); - return ~uint64_t(0UL) >> (64-getSizeInBits()); + assert(isInteger() && "Only applies to integers!"); + MVT EltVT = isVector() ? getVectorElementType() : *this; + assert(EltVT.getSizeInBits() <= 64 && + "getIntegerVTBitMask doesn't use APInt!"); + return ~uint64_t(0UL) >> (64-EltVT.getSizeInBits()); } /// getIntegerVTSignBit - Return an integer with a 1 in the position of the diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d1759c1ab0e3..d4df880d0be5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2434,11 +2434,12 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { if (ConstantSDNode *N101C = dyn_cast(N101)) { MVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); + uint64_t TruncC = TruncVT.getIntegerVTBitMask() & + N101C->getZExtValue(); return DAG.getNode(ISD::SHL, VT, N0, DAG.getNode(ISD::AND, TruncVT, DAG.getNode(ISD::TRUNCATE, TruncVT, N100), - DAG.getConstant(N101C->getZExtValue(), - TruncVT))); + DAG.getConstant(TruncC, TruncVT))); } } @@ -2561,11 +2562,12 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { if (ConstantSDNode *N101C = dyn_cast(N101)) { MVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); + uint64_t TruncC = TruncVT.getIntegerVTBitMask() & + N101C->getZExtValue(); return DAG.getNode(ISD::SRA, VT, N0, DAG.getNode(ISD::AND, TruncVT, DAG.getNode(ISD::TRUNCATE, TruncVT, N100), - DAG.getConstant(N101C->getZExtValue(), - TruncVT))); + DAG.getConstant(TruncC, TruncVT))); } } @@ -2678,11 +2680,12 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (ConstantSDNode *N101C = dyn_cast(N101)) { MVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); + uint64_t TruncC = TruncVT.getIntegerVTBitMask() & + N101C->getZExtValue(); return DAG.getNode(ISD::SRL, VT, N0, DAG.getNode(ISD::AND, TruncVT, DAG.getNode(ISD::TRUNCATE, TruncVT, N100), - DAG.getConstant(N101C->getZExtValue(), - TruncVT))); + DAG.getConstant(TruncC, TruncVT))); } } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 723c512c92ed..58ac8c285c95 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -6293,7 +6293,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { unsigned len = VT.getSizeInBits(); for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8]) - SDValue Tmp2 = DAG.getConstant(mask[i], VT); + SDValue Tmp2 = DAG.getConstant(VT.getIntegerVTBitMask() & mask[i], VT); SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2), DAG.getNode(ISD::AND, VT, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 7fd50aca401d..63fc97c20a82 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -848,6 +848,9 @@ SDValue SelectionDAG::getNOT(SDValue Val, MVT VT) { SDValue SelectionDAG::getConstant(uint64_t Val, MVT VT, bool isT) { MVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT; + assert((EltVT.getSizeInBits() >= 64 || + (uint64_t)((int64_t)Val >> EltVT.getSizeInBits()) + 1 < 2) && + "getConstant with a uint64_t value that doesn't fit in the type!"); return getConstant(APInt(EltVT.getSizeInBits(), Val), VT, isT); } -- GitLab From f4a0cba545e4ada42dd5b7ae240a86573c779044 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 27 Jan 2009 20:42:58 +0000 Subject: [PATCH 295/682] ccc/Darwin/clang: Fix a mistranslation for the llvm-backend; llvm-gcc doesn't set the relocation model when -mdynamic-no-pic is present. llvm-svn: 63129 --- clang/tools/ccc/ccclib/Tools.py | 4 ++-- clang/tools/ccc/test/ccc/darwin-hello.m | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 clang/tools/ccc/test/ccc/darwin-hello.m diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py index 0dcd52e7266d..62720624cb1c 100644 --- a/clang/tools/ccc/ccclib/Tools.py +++ b/clang/tools/ccc/ccclib/Tools.py @@ -227,7 +227,7 @@ class Clang_CompileTool(Tool): cmd_args.extend(arglist.renderAsInput(arg)) else: # Perform argument translation for LLVM backend. This - # performs some care in reconciling with llvm-gcc. The + # takes some care in reconciling with llvm-gcc. The # issue is that llvm-gcc translates these options based on # the values in cc1, whereas we are processing based on # the driver arguments. @@ -251,7 +251,7 @@ class Clang_CompileTool(Tool): if (archName == 'x86_64' or picEnabled): cmd_args.append('--relocation-model=pic') - else: + elif not arglist.getLastArg(arglist.parser.m_dynamicNoPicOption): cmd_args.append('--relocation-model=static') if arglist.getLastArg(arglist.parser.f_timeReportOption): diff --git a/clang/tools/ccc/test/ccc/darwin-hello.m b/clang/tools/ccc/test/ccc/darwin-hello.m new file mode 100644 index 000000000000..73289e99cf89 --- /dev/null +++ b/clang/tools/ccc/test/ccc/darwin-hello.m @@ -0,0 +1,17 @@ +// Check that object files compiled with -mdynamic-no-pic can be +// linked. +// +// RUN: xcc -ccc-clang -m32 -mdynamic-no-pic %s -c -o %t.o && +// RUN: xcc -ccc-clang -m32 %t.o -o %t && +// RUN: %t | grep "Hello, World" && +// RUN: xcc -ccc-clang -m64 -mdynamic-no-pic %s -c -o %t.o && +// RUN: xcc -ccc-clang -m64 %t.o -o %t && +// RUN: %t | grep "Hello, World" && +// RUN: true + +#include + +int main(int argc, char **argv) { + fprintf(stdout, "Hello, World"); + return 0; +} -- GitLab From 573e5291274d1e419a5996ac4a461a0275ad36bd Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Tue, 27 Jan 2009 21:15:07 +0000 Subject: [PATCH 296/682] Refine DebugLoc per review comments. llvm-svn: 63132 --- llvm/include/llvm/CodeGen/DebugLoc.h | 20 +++++++++++--------- llvm/include/llvm/CodeGen/MachineFunction.h | 8 ++++---- llvm/lib/CodeGen/MachineFunction.cpp | 13 +++++++------ 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DebugLoc.h b/llvm/include/llvm/CodeGen/DebugLoc.h index baf6583a8ba7..89c51c443b05 100644 --- a/llvm/include/llvm/CodeGen/DebugLoc.h +++ b/llvm/include/llvm/CodeGen/DebugLoc.h @@ -33,16 +33,21 @@ namespace llvm { unsigned Idx; public: - DebugLoc() : Idx(~0U) {} + DebugLoc() : Idx(~0U) {} // Defaults to invalid. - static DebugLoc getNoDebugLoc() { DebugLoc L; L.Idx = 0; return L; } + static DebugLoc getUnknownLoc() { DebugLoc L; L.Idx = 0; return L; } static DebugLoc get(unsigned idx) { DebugLoc L; L.Idx = idx; return L; } - bool isInvalid() { return Idx == ~0U; } - bool isUnknown() { return Idx == 0; } + // isInvalid - Return true if the DebugLoc is invalid. + bool isInvalid() const { return Idx == ~0U; } + + // isUnknown - Return true if there is no debug info for the SDNode / + // MachineInstr. + bool isUnknown() const { return Idx == 0; } }; - struct DebugLocTupleDenseMapInfo { + // Partially specialize DenseMapInfo for DebugLocTyple. + template<> struct DenseMapInfo { static inline DebugLocTuple getEmptyKey() { return DebugLocTuple(~0U, ~0U, ~0U); } @@ -63,9 +68,6 @@ namespace llvm { static bool isPod() { return true; } }; - typedef DenseMap - DebugIdMapType; - /// DebugLocTracker - This class tracks debug location information. /// struct DebugLocTracker { @@ -75,7 +77,7 @@ namespace llvm { // DebugIdsMap - This maps DebugLocTuple's to indices into // DebugLocations vector. - DebugIdMapType DebugIdMap; + DenseMap DebugIdMap; DebugLocTracker() {} diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 4fa70fca6fac..0d5a71d142d7 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -311,10 +311,10 @@ public: // Debug location. // - /// lookUpDebugLocId - Look up the DebugLocTuple index with the given - /// source file, line, and column. It may add a new filename and / or - /// a new DebugLocTuple. - unsigned lookUpDebugLocId(unsigned Src, unsigned Line, unsigned Col); + /// getOrCreateDebugLocID - Look up the DebugLocTuple index with the given + /// source file, line, and column. If none currently exists, create add a new + /// new DebugLocTuple and insert it into the DebugIdMap. + unsigned getOrCreateDebugLocID(unsigned Src, unsigned Line, unsigned Col); }; //===--------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index abd84ecbd5c3..b303b1b58c92 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -378,13 +378,14 @@ MachineFunction& MachineFunction::get(const Function *F) return *mc; } -/// lookUpDebugLocId - Look up the DebugLocTuple index with the given -/// source file, line, and column. It may add a new filename and / or -/// a new DebugLocTuple. -unsigned MachineFunction::lookUpDebugLocId(unsigned Src, unsigned Line, - unsigned Col) { +/// getOrCreateDebugLocID - Look up the DebugLocTuple index with the given +/// source file, line, and column. If none currently exists, create add a new +/// new DebugLocTuple and insert it into the DebugIdMap. +unsigned MachineFunction::getOrCreateDebugLocID(unsigned Src, unsigned Line, + unsigned Col) { struct DebugLocTuple Tuple(Src, Line, Col); - DebugIdMapType::iterator II = DebugLocInfo.DebugIdMap.find(Tuple); + DenseMap::iterator II + = DebugLocInfo.DebugIdMap.find(Tuple); if (II != DebugLocInfo.DebugIdMap.end()) return II->second; // Add a new tuple. -- GitLab From 13ae6f47cdf4f70c5a2c61ca9a7ccbbfcd4348f5 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 27 Jan 2009 21:25:57 +0000 Subject: [PATCH 297/682] Remove many references to ASTContext::getAllocator(), replacing them with calls to the recently added placement new (which uses ASTContext's allocator for memory). Also added ASTContext::Deallocate(). This will simplify runtime replacement of ASTContext's allocator. Keeping the allocator private (and removing getAllocator() entirely) is also goodness. llvm-svn: 63135 --- clang/include/clang/AST/ASTContext.h | 4 ++- clang/lib/AST/Decl.cpp | 45 ++++++++++------------------ clang/lib/AST/DeclBase.cpp | 2 +- clang/lib/AST/DeclCXX.cpp | 33 ++++++++------------ clang/lib/AST/DeclGroup.cpp | 2 +- clang/lib/AST/DeclObjC.cpp | 41 +++++++++---------------- clang/lib/AST/DeclSerialization.cpp | 44 +++++++++------------------ clang/lib/AST/Type.cpp | 6 ++-- 8 files changed, 64 insertions(+), 113 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index a01199d4b2aa..9cf11b85784d 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -129,6 +129,8 @@ public: SourceManager& getSourceManager() { return SourceMgr; } llvm::MallocAllocator &getAllocator() { return Allocator; } + void Deallocate(void *Ptr) { Allocator.Deallocate(Ptr); } + const LangOptions& getLangOptions() const { return LangOpts; } FullSourceLoc getFullLoc(SourceLocation Loc) const { @@ -567,7 +569,7 @@ private: FieldDecl *Field, bool OutermostType = false, bool EncodingProperty = false) const; - + }; } // end namespace clang diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 165a6c094816..c8b7fc2dcf98 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -24,14 +24,12 @@ using namespace clang; //===----------------------------------------------------------------------===// TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) TranslationUnitDecl(); + return new (C) TranslationUnitDecl(); } NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) NamespaceDecl(DC, L, Id); + return new (C) NamespaceDecl(DC, L, Id); } void NamespaceDecl::Destroy(ASTContext& C) { @@ -39,22 +37,20 @@ void NamespaceDecl::Destroy(ASTContext& C) { // together. They are all top-level Decls. this->~NamespaceDecl(); - C.getAllocator().Deallocate((void *)this); + C.Deallocate((void *)this); } ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); + return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); } ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, Expr *DefArg) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg); + return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, S, DefArg); } QualType ParmVarDecl::getOriginalType() const { @@ -69,8 +65,7 @@ ParmVarWithOriginalTypeDecl *ParmVarWithOriginalTypeDecl::Create( SourceLocation L, IdentifierInfo *Id, QualType T, QualType OT, StorageClass S, Expr *DefArg) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ParmVarWithOriginalTypeDecl(DC, L, Id, T, OT, S, DefArg); + return new (C) ParmVarWithOriginalTypeDecl(DC, L, Id, T, OT, S, DefArg); } FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, @@ -78,21 +73,18 @@ FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, DeclarationName N, QualType T, StorageClass S, bool isInline, SourceLocation TypeSpecStartLoc) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) FunctionDecl(Function, DC, L, N, T, S, isInline, + return new (C) FunctionDecl(Function, DC, L, N, T, S, isInline, TypeSpecStartLoc); } BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) BlockDecl(DC, L); + return new (C) BlockDecl(DC, L); } FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW, bool Mutable) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable); + return new (C) FieldDecl(Decl::Field, DC, L, Id, T, BW, Mutable); } bool FieldDecl::isAnonymousStructOrUnion() const { @@ -109,8 +101,7 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *E, const llvm::APSInt &V) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) EnumConstantDecl(CD, L, Id, T, E, V); + return new (C) EnumConstantDecl(CD, L, Id, T, E, V); } void EnumConstantDecl::Destroy(ASTContext& C) { @@ -121,8 +112,7 @@ void EnumConstantDecl::Destroy(ASTContext& C) { TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) TypedefDecl(DC, L, Id, T); + return new (C) TypedefDecl(DC, L, Id, T); } EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, @@ -147,8 +137,7 @@ void EnumDecl::completeDefinition(ASTContext &C, QualType NewType) { FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, StringLiteral *Str) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) FileScopeAsmDecl(DC, L, Str); + return new (C) FileScopeAsmDecl(DC, L, Str); } //===----------------------------------------------------------------------===// @@ -176,13 +165,12 @@ bool NamedDecl::declarationReplaces(NamedDecl *OldD) const { VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, SourceLocation TypeSpecStartLoc) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) VarDecl(Var, DC, L, Id, T, S, TypeSpecStartLoc); + return new (C) VarDecl(Var, DC, L, Id, T, S, TypeSpecStartLoc); } void VarDecl::Destroy(ASTContext& C) { this->~VarDecl(); - C.getAllocator().Deallocate((void *)this); + C.Deallocate((void *)this); } VarDecl::~VarDecl() { @@ -200,7 +188,7 @@ void FunctionDecl::Destroy(ASTContext& C) { for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I) (*I)->Destroy(C); - C.getAllocator().Deallocate(ParamInfo); + C.Deallocate(ParamInfo); Decl::Destroy(C); } @@ -309,8 +297,7 @@ RecordDecl *RecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, RecordDecl* PrevDecl) { - void *Mem = C.getAllocator().Allocate(); - RecordDecl* R = new (Mem) RecordDecl(Record, TK, DC, L, Id); + RecordDecl* R = new (C) RecordDecl(Record, TK, DC, L, Id); C.getTypeDeclType(R, PrevDecl); return R; } diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 016f7b1e041b..983c726c228f 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -405,7 +405,7 @@ void Decl::Destroy(ASTContext& C) { } this->~Decl(); - C.getAllocator().Deallocate((void *)this); + C.Deallocate((void *)this); #endif } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index a9c129ba2274..ee242c5dffcb 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -25,16 +25,14 @@ TemplateTypeParmDecl * TemplateTypeParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, bool Typename) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) TemplateTypeParmDecl(DC, L, Id, Typename); + return new (C) TemplateTypeParmDecl(DC, L, Id, Typename); } NonTypeTemplateParmDecl * NonTypeTemplateParmDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, SourceLocation TypeSpecStartLoc) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) NonTypeTemplateParmDecl(DC, L, Id, T, TypeSpecStartLoc); + return new (C) NonTypeTemplateParmDecl(DC, L, Id, T, TypeSpecStartLoc); } TemplateParameterList::TemplateParameterList(Decl **Params, unsigned NumParams) @@ -46,6 +44,7 @@ TemplateParameterList::TemplateParameterList(Decl **Params, unsigned NumParams) TemplateParameterList * TemplateParameterList::Create(ASTContext &C, Decl **Params, unsigned NumParams) { + // FIXME: how do I pass in Size to ASTContext::new? unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams; unsigned Align = llvm::AlignOf::Alignment; void *Mem = C.getAllocator().Allocate(Size, Align); @@ -63,8 +62,7 @@ CXXRecordDecl::CXXRecordDecl(TagKind TK, DeclContext *DC, CXXRecordDecl *CXXRecordDecl::Create(ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, CXXRecordDecl* PrevDecl) { - void *Mem = C.getAllocator().Allocate(); - CXXRecordDecl* R = new (Mem) CXXRecordDecl(TK, DC, L, Id); + CXXRecordDecl* R = new (C) CXXRecordDecl(TK, DC, L, Id); C.getTypeDeclType(R, PrevDecl); return R; } @@ -211,8 +209,7 @@ CXXMethodDecl * CXXMethodDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, DeclarationName N, QualType T, bool isStatic, bool isInline) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline); + return new (C) CXXMethodDecl(CXXMethod, RD, L, N, T, isStatic, isInline); } QualType CXXMethodDecl::getThisType(ASTContext &C) const { @@ -268,8 +265,7 @@ CXXConstructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, bool isInline, bool isImplicitlyDeclared) { assert(N.getNameKind() == DeclarationName::CXXConstructorName && "Name must refer to a constructor"); - void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline, + return new (C) CXXConstructorDecl(RD, L, N, T, isExplicit, isInline, isImplicitlyDeclared); } @@ -336,9 +332,8 @@ CXXDestructorDecl::Create(ASTContext &C, CXXRecordDecl *RD, bool isImplicitlyDeclared) { assert(N.getNameKind() == DeclarationName::CXXDestructorName && "Name must refer to a destructor"); - void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXDestructorDecl(RD, L, N, T, isInline, - isImplicitlyDeclared); + return new (C) CXXDestructorDecl(RD, L, N, T, isInline, + isImplicitlyDeclared); } CXXConversionDecl * @@ -347,28 +342,24 @@ CXXConversionDecl::Create(ASTContext &C, CXXRecordDecl *RD, QualType T, bool isInline, bool isExplicit) { assert(N.getNameKind() == DeclarationName::CXXConversionFunctionName && "Name must refer to a conversion function"); - void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXConversionDecl(RD, L, N, T, isInline, isExplicit); + return new (C) CXXConversionDecl(RD, L, N, T, isInline, isExplicit); } CXXClassVarDecl *CXXClassVarDecl::Create(ASTContext &C, CXXRecordDecl *RD, SourceLocation L, IdentifierInfo *Id, QualType T) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) CXXClassVarDecl(RD, L, Id, T); + return new (C) CXXClassVarDecl(RD, L, Id, T); } OverloadedFunctionDecl * OverloadedFunctionDecl::Create(ASTContext &C, DeclContext *DC, DeclarationName N) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) OverloadedFunctionDecl(DC, N); + return new (C) OverloadedFunctionDecl(DC, N); } LinkageSpecDecl *LinkageSpecDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, LanguageIDs Lang, bool Braces) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) LinkageSpecDecl(DC, L, Lang, Braces); + return new (C) LinkageSpecDecl(DC, L, Lang, Braces); } diff --git a/clang/lib/AST/DeclGroup.cpp b/clang/lib/AST/DeclGroup.cpp index 62b4077a3fc2..c7af7cd89ea3 100644 --- a/clang/lib/AST/DeclGroup.cpp +++ b/clang/lib/AST/DeclGroup.cpp @@ -60,7 +60,7 @@ void DeclGroup::Destroy(ASTContext& C) { Decls[i]->Destroy(C); this->~DeclGroup(); - C.getAllocator().Deallocate((void*) this); + C.Deallocate((void*) this); } DeclGroupOwningRef::~DeclGroupOwningRef() { diff --git a/clang/lib/AST/DeclObjC.cpp b/clang/lib/AST/DeclObjC.cpp index bbbcc5f6714f..b36da643ecf8 100644 --- a/clang/lib/AST/DeclObjC.cpp +++ b/clang/lib/AST/DeclObjC.cpp @@ -29,8 +29,7 @@ ObjCMethodDecl *ObjCMethodDecl::Create(ASTContext &C, bool isVariadic, bool isSynthesized, ImplementationControl impControl) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCMethodDecl(beginLoc, endLoc, + return new (C) ObjCMethodDecl(beginLoc, endLoc, SelInfo, T, contextDecl, isInstance, isVariadic, isSynthesized, impControl); @@ -56,8 +55,7 @@ ObjCInterfaceDecl *ObjCInterfaceDecl::Create(ASTContext &C, IdentifierInfo *Id, SourceLocation ClassLoc, bool ForwardDecl, bool isInternal){ - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, + return new (C) ObjCInterfaceDecl(DC, atLoc, Id, ClassLoc, ForwardDecl, isInternal); } @@ -83,28 +81,25 @@ void ObjCInterfaceDecl::Destroy(ASTContext& C) { ObjCIvarDecl *ObjCIvarDecl::Create(ASTContext &C, SourceLocation L, IdentifierInfo *Id, QualType T, AccessControl ac, Expr *BW) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCIvarDecl(L, Id, T, ac, BW); + return new (C) ObjCIvarDecl(L, Id, T, ac, BW); } ObjCAtDefsFieldDecl *ObjCAtDefsFieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, Expr *BW) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); + return new (C) ObjCAtDefsFieldDecl(DC, L, Id, T, BW); } void ObjCAtDefsFieldDecl::Destroy(ASTContext& C) { this->~ObjCAtDefsFieldDecl(); - C.getAllocator().Deallocate((void *)this); + C.Deallocate((void *)this); } ObjCProtocolDecl *ObjCProtocolDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCProtocolDecl(DC, L, Id); + return new (C) ObjCProtocolDecl(DC, L, Id); } ObjCProtocolDecl::~ObjCProtocolDecl() { @@ -115,8 +110,7 @@ ObjCProtocolDecl::~ObjCProtocolDecl() { ObjCClassDecl *ObjCClassDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ObjCInterfaceDecl **Elts, unsigned nElts) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCClassDecl(DC, L, Elts, nElts); + return new (C) ObjCClassDecl(DC, L, Elts, nElts); } ObjCClassDecl::~ObjCClassDecl() { @@ -140,8 +134,7 @@ ObjCForwardProtocolDecl * ObjCForwardProtocolDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ObjCProtocolDecl **Elts, unsigned NumElts) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCForwardProtocolDecl(DC, L, Elts, NumElts); + return new (C) ObjCForwardProtocolDecl(DC, L, Elts, NumElts); } ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() { @@ -151,16 +144,14 @@ ObjCForwardProtocolDecl::~ObjCForwardProtocolDecl() { ObjCCategoryDecl *ObjCCategoryDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCCategoryDecl(DC, L, Id); + return new (C) ObjCCategoryDecl(DC, L, Id); } ObjCCategoryImplDecl * ObjCCategoryImplDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,IdentifierInfo *Id, ObjCInterfaceDecl *ClassInterface) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCCategoryImplDecl(DC, L, Id, ClassInterface); + return new (C) ObjCCategoryImplDecl(DC, L, Id, ClassInterface); } ObjCImplementationDecl * @@ -168,8 +159,7 @@ ObjCImplementationDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, ObjCInterfaceDecl *ClassInterface, ObjCInterfaceDecl *SuperDecl) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl); + return new (C) ObjCImplementationDecl(DC, L, ClassInterface, SuperDecl); } ObjCCompatibleAliasDecl * @@ -177,8 +167,7 @@ ObjCCompatibleAliasDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl* AliasedClass) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); + return new (C) ObjCCompatibleAliasDecl(DC, L, Id, AliasedClass); } ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, @@ -186,8 +175,7 @@ ObjCPropertyDecl *ObjCPropertyDecl::Create(ASTContext &C, DeclContext *DC, IdentifierInfo *Id, QualType T, PropertyControl propControl) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCPropertyDecl(DC, L, Id, T); + return new (C) ObjCPropertyDecl(DC, L, Id, T); } //===----------------------------------------------------------------------===// @@ -638,8 +626,7 @@ ObjCPropertyImplDecl *ObjCPropertyImplDecl::Create(ASTContext &C, ObjCPropertyDecl *property, Kind PK, ObjCIvarDecl *ivar) { - void *Mem = C.getAllocator().Allocate(); - return new (Mem) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar); + return new (C) ObjCPropertyImplDecl(DC, atLoc, L, property, PK, ivar); } diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index 7d848ff2f226..662de369a7f3 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -303,10 +303,7 @@ void TranslationUnitDecl::EmitImpl(llvm::Serializer& S) const TranslationUnitDecl* TranslationUnitDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - TranslationUnitDecl* decl = new (Mem) TranslationUnitDecl(); - - return decl; + return new (C) TranslationUnitDecl(); } //===----------------------------------------------------------------------===// @@ -321,8 +318,7 @@ void NamespaceDecl::EmitImpl(llvm::Serializer& S) const } NamespaceDecl* NamespaceDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - NamespaceDecl* decl = new (Mem) NamespaceDecl(0, SourceLocation(), 0); + NamespaceDecl* decl = new (C) NamespaceDecl(0, SourceLocation(), 0); decl->NamedDecl::ReadInRec(D, C); decl->LBracLoc = SourceLocation::ReadVal(D); @@ -336,9 +332,8 @@ NamespaceDecl* NamespaceDecl::CreateImpl(Deserializer& D, ASTContext& C) { //===----------------------------------------------------------------------===// VarDecl* VarDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); VarDecl* decl = - new (Mem) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None); + new (C) VarDecl(Var, 0, SourceLocation(), NULL, QualType(), None); decl->VarDecl::ReadImpl(D, C); return decl; @@ -355,8 +350,7 @@ void ParmVarDecl::EmitImpl(llvm::Serializer& S) const { } ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - ParmVarDecl* decl = new (Mem) + ParmVarDecl* decl = new (C) ParmVarDecl(ParmVar, 0, SourceLocation(), NULL, QualType(), None, NULL); @@ -377,8 +371,7 @@ void ParmVarWithOriginalTypeDecl::EmitImpl(llvm::Serializer& S) const { ParmVarWithOriginalTypeDecl* ParmVarWithOriginalTypeDecl::CreateImpl( Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - ParmVarWithOriginalTypeDecl* decl = new (Mem) + ParmVarWithOriginalTypeDecl* decl = new (C) ParmVarWithOriginalTypeDecl(0, SourceLocation(), NULL, QualType(), QualType(), None, NULL); @@ -397,8 +390,7 @@ void EnumDecl::EmitImpl(Serializer& S) const { } EnumDecl* EnumDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - EnumDecl* decl = new (Mem) EnumDecl(0, SourceLocation(), NULL); + EnumDecl* decl = new (C) EnumDecl(0, SourceLocation(), NULL); decl->NamedDecl::ReadInRec(D, C); decl->setDefinition(D.ReadBool()); @@ -421,8 +413,7 @@ EnumConstantDecl* EnumConstantDecl::CreateImpl(Deserializer& D, ASTContext& C) { llvm::APSInt val(1); D.Read(val); - void *Mem = C.getAllocator().Allocate(); - EnumConstantDecl* decl = new (Mem) + EnumConstantDecl* decl = new (C) EnumConstantDecl(0, SourceLocation(), NULL, QualType(), NULL, val); decl->ValueDecl::ReadInRec(D, C); @@ -442,8 +433,7 @@ void FieldDecl::EmitImpl(Serializer& S) const { } FieldDecl* FieldDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - FieldDecl* decl = new (Mem) FieldDecl(Field, 0, SourceLocation(), NULL, + FieldDecl* decl = new (C) FieldDecl(Field, 0, SourceLocation(), NULL, QualType(), 0, false); decl->Mutable = D.ReadBool(); decl->DeclType.ReadBackpatch(D); @@ -480,8 +470,7 @@ FunctionDecl* FunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) { StorageClass SClass = static_cast(D.ReadInt()); bool IsInline = D.ReadBool(); - void *Mem = C.getAllocator().Allocate(); - FunctionDecl* decl = new (Mem) + FunctionDecl* decl = new (C) FunctionDecl(Function, 0, SourceLocation(), DeclarationName(), QualType(), SClass, IsInline); @@ -537,8 +526,7 @@ void OverloadedFunctionDecl::EmitImpl(Serializer& S) const { OverloadedFunctionDecl * OverloadedFunctionDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - OverloadedFunctionDecl* decl = new (Mem) + OverloadedFunctionDecl* decl = new (C) OverloadedFunctionDecl(0, DeclarationName()); decl->NamedDecl::ReadInRec(D, C); @@ -567,8 +555,7 @@ void RecordDecl::EmitImpl(Serializer& S) const { RecordDecl* RecordDecl::CreateImpl(Deserializer& D, ASTContext& C) { TagKind TK = TagKind(D.ReadInt()); - void *Mem = C.getAllocator().Allocate(); - RecordDecl* decl = new (Mem) RecordDecl(Record, TK, 0, SourceLocation(), NULL); + RecordDecl* decl = new (C) RecordDecl(Record, TK, 0, SourceLocation(), NULL); decl->NamedDecl::ReadInRec(D, C); decl->setDefinition(D.ReadBool()); @@ -590,8 +577,7 @@ void TypedefDecl::EmitImpl(Serializer& S) const { TypedefDecl* TypedefDecl::CreateImpl(Deserializer& D, ASTContext& C) { QualType T = QualType::ReadVal(D); - void *Mem = C.getAllocator().Allocate(); - TypedefDecl* decl = new (Mem) TypedefDecl(0, SourceLocation(), NULL, T); + TypedefDecl* decl = new (C) TypedefDecl(0, SourceLocation(), NULL, T); decl->NamedDecl::ReadInRec(D, C); @@ -610,9 +596,8 @@ void TemplateTypeParmDecl::EmitImpl(Serializer& S) const { TemplateTypeParmDecl * TemplateTypeParmDecl::CreateImpl(Deserializer& D, ASTContext& C) { bool Typename = D.ReadBool(); - void *Mem = C.getAllocator().Allocate(); TemplateTypeParmDecl *decl - = new (Mem) TemplateTypeParmDecl(0, SourceLocation(), NULL, Typename); + = new (C) TemplateTypeParmDecl(0, SourceLocation(), NULL, Typename); decl->NamedDecl::ReadInRec(D, C); return decl; } @@ -641,8 +626,7 @@ void FileScopeAsmDecl::EmitImpl(llvm::Serializer& S) const } FileScopeAsmDecl* FileScopeAsmDecl::CreateImpl(Deserializer& D, ASTContext& C) { - void *Mem = C.getAllocator().Allocate(); - FileScopeAsmDecl* decl = new (Mem) FileScopeAsmDecl(0, SourceLocation(), 0); + FileScopeAsmDecl* decl = new (C) FileScopeAsmDecl(0, SourceLocation(), 0); decl->AsmString = cast(D.ReadOwnedPtr(C)); // D.ReadOwnedPtr(D.ReadOwnedPtr())<#T * * Ptr#>, <#bool AutoRegister#>)(decl->AsmString); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 7d9be2d72c70..65fd3b40408c 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -32,19 +32,19 @@ bool QualType::isConstant(ASTContext &Ctx) const { void Type::Destroy(ASTContext& C) { this->~Type(); - C.getAllocator().Deallocate(this); + C.Deallocate(this); } void VariableArrayType::Destroy(ASTContext& C) { SizeExpr->Destroy(C); this->~VariableArrayType(); - C.getAllocator().Deallocate(this); + C.Deallocate(this); } void DependentSizedArrayType::Destroy(ASTContext& C) { SizeExpr->Destroy(C); this->~DependentSizedArrayType(); - C.getAllocator().Deallocate(this); + C.Deallocate(this); } /// getArrayElementTypeNoTypeQual - If this is an array type, return the -- GitLab From f041127bdad501550a06704ce6fffadfc4ca609b Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 27 Jan 2009 21:41:04 +0000 Subject: [PATCH 298/682] Add DebugLoc field and simple accessors. llvm-svn: 63136 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 47 +++++++++++++++++-- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 7a5cd3b43eed..f1cd6c08c11b 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -30,6 +30,7 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/RecyclingAllocator.h" #include "llvm/Support/DataTypes.h" +#include "llvm/CodeGen/DebugLoc.h" #include namespace llvm { @@ -901,6 +902,7 @@ public: inline bool isTargetOpcode() const; inline bool isMachineOpcode() const; inline unsigned getMachineOpcode() const; + inline DebugLoc getDebugLoc() const; /// reachesChainWithoutSideEffects - Return true if this operand (which must @@ -1077,6 +1079,9 @@ private: /// NodeId - Unique id per SDNode in the DAG. int NodeId; + /// debugLoc - source line information. + DebugLoc debugLoc; + /// OperandList - The values that are used by this operation. /// SDUse *OperandList; @@ -1146,6 +1151,12 @@ public: /// setNodeId - Set unique node id. void setNodeId(int Id) { NodeId = Id; } + /// getDebugLoc - Return the source location info. + DebugLoc getDebugLoc() const { return debugLoc; } + + /// setDebugLoc - Set source location info. + void setDebugLoc(DebugLoc sl) { debugLoc = sl; } + /// use_iterator - This class provides iterator support for SDUse /// operands that use a specific SDNode. class use_iterator @@ -1326,9 +1337,11 @@ protected: return Ret; } + /// The constructors that supply DebugLoc explicitly should be preferred + /// for new code. SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), + NodeId(-1), debugLoc(DebugLoc::getNoDebugLoc()), OperandList(NumOps ? new SDUse[NumOps] : 0), ValueList(VTs.VTs), NumOperands(NumOps), NumValues(VTs.NumVTs), @@ -1343,8 +1356,33 @@ protected: /// set later with InitOperands. SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), - NodeId(-1), OperandList(0), ValueList(VTs.VTs), - NumOperands(0), NumValues(VTs.NumVTs), + NodeId(-1), debugLoc(DebugLoc::getNoDebugLoc()), OperandList(0), + ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs), + UseList(NULL) {} + + /// The next two constructors specify DebugLoc explicitly; the intent + /// is that they will replace the above two over time, and eventually + /// the ones above can be removed. + SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, + DebugLoc sl) + : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), + NodeId(-1), debugLoc(sl), + OperandList(NumOps ? new SDUse[NumOps] : 0), + ValueList(VTs.VTs), + NumOperands(NumOps), NumValues(VTs.NumVTs), + UseList(NULL) { + for (unsigned i = 0; i != NumOps; ++i) { + OperandList[i].setUser(this); + OperandList[i].setInitial(Ops[i]); + } + } + + /// This constructor adds no operands itself; operands can be + /// set later with InitOperands. + SDNode(unsigned Opc, SDVTList VTs, DebugLoc sl) + : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), + NodeId(-1), debugLoc(sl), OperandList(0), + ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs), UseList(NULL) {} /// InitOperands - Initialize the operands list of this with 1 operand. @@ -1441,6 +1479,9 @@ inline bool SDValue::use_empty() const { inline bool SDValue::hasOneUse() const { return Node->hasNUsesOfValue(1, ResNo); } +inline DebugLoc SDValue::getDebugLoc() const { + return Node->getDebugLoc(); +} // Define inline functions from the SDUse class. -- GitLab From 096bab711ee0df73c801fa0aa8f70219b4c06153 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 27 Jan 2009 22:08:43 +0000 Subject: [PATCH 299/682] Convert types over to placement new() that takes an ASTContext. Also changed FunctionTypeProto to be allocated with 8-byte alignment (noticed by Doug). I couldn't think of any reason to allocate on 16-byte boundaries. If anyone remembers why we were doing this, let me know! llvm-svn: 63137 --- clang/lib/AST/ASTContext.cpp | 87 +++++++++++++----------------------- 1 file changed, 30 insertions(+), 57 deletions(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 28007659ec97..7cc67e03d493 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -177,8 +177,7 @@ void ASTContext::PrintStats() const { void ASTContext::InitBuiltinType(QualType &R, BuiltinType::Kind K) { - void *Mem = Allocator.Allocate(sizeof(BuiltinType), 8); - Types.push_back((R = QualType(new (Mem) BuiltinType(K),0)).getTypePtr()); + Types.push_back((R = QualType(new (*this,8) BuiltinType(K),0)).getTypePtr()); } void ASTContext::InitBuiltinTypes() { @@ -733,8 +732,8 @@ QualType ASTContext::getASQualType(QualType T, unsigned AddressSpace) { ASQualType *NewIP = ASQualTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(ASQualType), 8); - ASQualType *New = new (Mem) ASQualType(T.getTypePtr(), Canonical, AddressSpace); + ASQualType *New = new (*this, 8) ASQualType(T.getTypePtr(), Canonical, + AddressSpace); ASQualTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, T.getCVRQualifiers()); @@ -763,8 +762,7 @@ QualType ASTContext::getComplexType(QualType T) { ComplexType *NewIP = ComplexTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(ComplexType), 8); - ComplexType *New = new (Mem) ComplexType(T, Canonical); + ComplexType *New = new (*this,8) ComplexType(T, Canonical); Types.push_back(New); ComplexTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -793,8 +791,7 @@ QualType ASTContext::getPointerType(QualType T) { PointerType *NewIP = PointerTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(PointerType), 8); - PointerType *New = new (Mem) PointerType(T, Canonical); + PointerType *New = new (*this,8) PointerType(T, Canonical); Types.push_back(New); PointerTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -825,8 +822,7 @@ QualType ASTContext::getBlockPointerType(QualType T) { BlockPointerTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(BlockPointerType), 8); - BlockPointerType *New = new (Mem) BlockPointerType(T, Canonical); + BlockPointerType *New = new (*this,8) BlockPointerType(T, Canonical); Types.push_back(New); BlockPointerTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -855,8 +851,7 @@ QualType ASTContext::getReferenceType(QualType T) { assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(ReferenceType), 8); - ReferenceType *New = new (Mem) ReferenceType(T, Canonical); + ReferenceType *New = new (*this,8) ReferenceType(T, Canonical); Types.push_back(New); ReferenceTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -887,8 +882,7 @@ QualType ASTContext::getMemberPointerType(QualType T, const Type *Cls) MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(MemberPointerType), 8); - MemberPointerType *New = new (Mem) MemberPointerType(T, Cls, Canonical); + MemberPointerType *New = new (*this,8) MemberPointerType(T, Cls, Canonical); Types.push_back(New); MemberPointerTypes.InsertNode(New, InsertPos); return QualType(New, 0); @@ -920,9 +914,8 @@ QualType ASTContext::getConstantArrayType(QualType EltTy, assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(ConstantArrayType), 8); ConstantArrayType *New = - new (Mem) ConstantArrayType(EltTy, Canonical, ArySize, ASM, EltTypeQuals); + new(*this,8)ConstantArrayType(EltTy, Canonical, ArySize, ASM, EltTypeQuals); ConstantArrayTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -936,9 +929,8 @@ QualType ASTContext::getVariableArrayType(QualType EltTy, Expr *NumElts, // Since we don't unique expressions, it isn't possible to unique VLA's // that have an expression provided for their size. - void *Mem = Allocator.Allocate(sizeof(VariableArrayType), 8); VariableArrayType *New = - new (Mem) VariableArrayType(EltTy, QualType(), NumElts, ASM, EltTypeQuals); + new(*this,8)VariableArrayType(EltTy,QualType(), NumElts, ASM, EltTypeQuals); VariableArrayTypes.push_back(New); Types.push_back(New); @@ -958,10 +950,9 @@ QualType ASTContext::getDependentSizedArrayType(QualType EltTy, Expr *NumElts, // Since we don't unique expressions, it isn't possible to unique // dependently-sized array types. - void *Mem = Allocator.Allocate(sizeof(DependentSizedArrayType), 8); DependentSizedArrayType *New = - new (Mem) DependentSizedArrayType(EltTy, QualType(), NumElts, - ASM, EltTypeQuals); + new (*this,8) DependentSizedArrayType(EltTy, QualType(), NumElts, + ASM, EltTypeQuals); DependentSizedArrayTypes.push_back(New); Types.push_back(New); @@ -993,8 +984,7 @@ QualType ASTContext::getIncompleteArrayType(QualType EltTy, assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(IncompleteArrayType), 8); - IncompleteArrayType *New = new (Mem) IncompleteArrayType(EltTy, Canonical, + IncompleteArrayType *New = new (*this,8) IncompleteArrayType(EltTy, Canonical, ASM, EltTypeQuals); IncompleteArrayTypes.InsertNode(New, InsertPos); @@ -1027,8 +1017,7 @@ QualType ASTContext::getVectorType(QualType vecType, unsigned NumElts) { VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(VectorType), 8); - VectorType *New = new (Mem) VectorType(vecType, NumElts, Canonical); + VectorType *New = new (*this,8) VectorType(vecType, NumElts, Canonical); VectorTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -1059,8 +1048,7 @@ QualType ASTContext::getExtVectorType(QualType vecType, unsigned NumElts) { VectorType *NewIP = VectorTypes.FindNodeOrInsertPos(ID, InsertPos); assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(ExtVectorType), 8); - ExtVectorType *New = new (Mem) ExtVectorType(vecType, NumElts, Canonical); + ExtVectorType *New = new (*this,8) ExtVectorType(vecType, NumElts, Canonical); VectorTypes.InsertNode(New, InsertPos); Types.push_back(New); return QualType(New, 0); @@ -1089,8 +1077,7 @@ QualType ASTContext::getFunctionTypeNoProto(QualType ResultTy) { assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP; } - void *Mem = Allocator.Allocate(sizeof(FunctionTypeNoProto), 8); - FunctionTypeNoProto *New = new (Mem) FunctionTypeNoProto(ResultTy, Canonical); + FunctionTypeNoProto *New =new(*this,8)FunctionTypeNoProto(ResultTy,Canonical); Types.push_back(New); FunctionTypeNoProtos.InsertNode(New, InsertPos); return QualType(New, 0); @@ -1138,10 +1125,9 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, // FunctionTypeProto objects are allocated with extra bytes after them // for a variable size array (for parameter types) at the end of them. - // FIXME: Can we do better than forcing a 16-byte alignment? FunctionTypeProto *FTP = (FunctionTypeProto*)Allocator.Allocate(sizeof(FunctionTypeProto) + - NumArgs*sizeof(QualType), 16); + NumArgs*sizeof(QualType), 8); new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic, TypeQuals, Canonical); Types.push_back(FTP); @@ -1165,26 +1151,20 @@ QualType ASTContext::getTypeDeclType(TypeDecl *Decl, TypeDecl* PrevDecl) { if (CXXRecordDecl *CXXRecord = dyn_cast(Decl)) { if (PrevDecl) Decl->TypeForDecl = PrevDecl->TypeForDecl; - else { - void *Mem = Allocator.Allocate(sizeof(CXXRecordType), 8); - Decl->TypeForDecl = new (Mem) CXXRecordType(CXXRecord); - } + else + Decl->TypeForDecl = new (*this,8) CXXRecordType(CXXRecord); } else if (RecordDecl *Record = dyn_cast(Decl)) { if (PrevDecl) Decl->TypeForDecl = PrevDecl->TypeForDecl; - else { - void *Mem = Allocator.Allocate(sizeof(RecordType), 8); - Decl->TypeForDecl = new (Mem) RecordType(Record); - } + else + Decl->TypeForDecl = new (*this,8) RecordType(Record); } else if (EnumDecl *Enum = dyn_cast(Decl)) { if (PrevDecl) Decl->TypeForDecl = PrevDecl->TypeForDecl; - else { - void *Mem = Allocator.Allocate(sizeof(EnumType), 8); - Decl->TypeForDecl = new (Mem) EnumType(Enum); - } + else + Decl->TypeForDecl = new (*this,8) EnumType(Enum); } else assert(false && "TypeDecl without a type?"); @@ -1199,8 +1179,7 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) { if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); QualType Canonical = getCanonicalType(Decl->getUnderlyingType()); - void *Mem = Allocator.Allocate(sizeof(TypedefType), 8); - Decl->TypeForDecl = new (Mem) TypedefType(Type::TypeName, Decl, Canonical); + Decl->TypeForDecl = new(*this,8) TypedefType(Type::TypeName, Decl, Canonical); Types.push_back(Decl->TypeForDecl); return QualType(Decl->TypeForDecl, 0); } @@ -1209,8 +1188,7 @@ QualType ASTContext::getTypedefType(TypedefDecl *Decl) { /// for the specified template type parameter declaration. QualType ASTContext::getTemplateTypeParmType(TemplateTypeParmDecl *Decl) { if (!Decl->TypeForDecl) { - void *Mem = Allocator.Allocate(sizeof(TemplateTypeParmType), 8); - Decl->TypeForDecl = new (Mem) TemplateTypeParmType(Decl); + Decl->TypeForDecl = new (*this,8) TemplateTypeParmType(Decl); Types.push_back(Decl->TypeForDecl); } return QualType(Decl->TypeForDecl, 0); @@ -1221,8 +1199,7 @@ QualType ASTContext::getTemplateTypeParmType(TemplateTypeParmDecl *Decl) { QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) { if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0); - void *Mem = Allocator.Allocate(sizeof(ObjCInterfaceType), 8); - Decl->TypeForDecl = new (Mem) ObjCInterfaceType(Type::ObjCInterface, Decl); + Decl->TypeForDecl = new(*this,8) ObjCInterfaceType(Type::ObjCInterface, Decl); Types.push_back(Decl->TypeForDecl); return QualType(Decl->TypeForDecl, 0); } @@ -1263,9 +1240,8 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl, return QualType(QT, 0); // No Match; - void *Mem = Allocator.Allocate(sizeof(ObjCQualifiedInterfaceType), 8); ObjCQualifiedInterfaceType *QType = - new (Mem) ObjCQualifiedInterfaceType(Decl, Protocols, NumProtocols); + new (*this,8) ObjCQualifiedInterfaceType(Decl, Protocols, NumProtocols); Types.push_back(QType); ObjCQualifiedInterfaceTypes.InsertNode(QType, InsertPos); @@ -1288,9 +1264,8 @@ QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols, return QualType(QT, 0); // No Match; - void *Mem = Allocator.Allocate(sizeof(ObjCQualifiedIdType), 8); ObjCQualifiedIdType *QType = - new (Mem) ObjCQualifiedIdType(Protocols, NumProtocols); + new (*this,8) ObjCQualifiedIdType(Protocols, NumProtocols); Types.push_back(QType); ObjCQualifiedIdTypes.InsertNode(QType, InsertPos); return QualType(QType, 0); @@ -1303,8 +1278,7 @@ QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols, /// on canonical type's (which are always unique). QualType ASTContext::getTypeOfExpr(Expr *tofExpr) { QualType Canonical = getCanonicalType(tofExpr->getType()); - void *Mem = Allocator.Allocate(sizeof(TypeOfExpr), 8); - TypeOfExpr *toe = new (Mem) TypeOfExpr(tofExpr, Canonical); + TypeOfExpr *toe = new (*this,8) TypeOfExpr(tofExpr, Canonical); Types.push_back(toe); return QualType(toe, 0); } @@ -1316,8 +1290,7 @@ QualType ASTContext::getTypeOfExpr(Expr *tofExpr) { /// on canonical type's (which are always unique). QualType ASTContext::getTypeOfType(QualType tofType) { QualType Canonical = getCanonicalType(tofType); - void *Mem = Allocator.Allocate(sizeof(TypeOfType), 8); - TypeOfType *tot = new (Mem) TypeOfType(tofType, Canonical); + TypeOfType *tot = new (*this,8) TypeOfType(tofType, Canonical); Types.push_back(tot); return QualType(tot, 0); } -- GitLab From aa064e6cd68aa9bdd0d6854bd769f85f96b2b42e Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 27 Jan 2009 22:09:11 +0000 Subject: [PATCH 300/682] Update to latest spelling. llvm-svn: 63138 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index f1cd6c08c11b..772ef07e5f1e 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1341,7 +1341,7 @@ protected: /// for new code. SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), debugLoc(DebugLoc::getNoDebugLoc()), + NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()), OperandList(NumOps ? new SDUse[NumOps] : 0), ValueList(VTs.VTs), NumOperands(NumOps), NumValues(VTs.NumVTs), @@ -1356,7 +1356,7 @@ protected: /// set later with InitOperands. SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), - NodeId(-1), debugLoc(DebugLoc::getNoDebugLoc()), OperandList(0), + NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()), OperandList(0), ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs), UseList(NULL) {} -- GitLab From b841dc29578d93d820bfafc66928a0c74aaaf4a6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 27 Jan 2009 22:12:23 +0000 Subject: [PATCH 301/682] Use .empty() instead of comparing .size() with 0. llvm-svn: 63139 --- llvm/include/llvm/CodeGen/ScheduleDAGSDNodes.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/CodeGen/ScheduleDAGSDNodes.h b/llvm/include/llvm/CodeGen/ScheduleDAGSDNodes.h index 52cf4eb998b7..8950433062f5 100644 --- a/llvm/include/llvm/CodeGen/ScheduleDAGSDNodes.h +++ b/llvm/include/llvm/CodeGen/ScheduleDAGSDNodes.h @@ -61,7 +61,7 @@ namespace llvm { SUnit *NewSUnit(SDNode *N) { #ifndef NDEBUG const SUnit *Addr = 0; - if (SUnits.size() > 0) + if (!SUnits.empty()) Addr = &SUnits[0]; #endif SUnits.push_back(SUnit(N, (unsigned)SUnits.size())); -- GitLab From 3efd355b9d0f96e4244a939aaa6e940f66d8527f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Tue, 27 Jan 2009 22:24:33 +0000 Subject: [PATCH 302/682] Updated checker build. llvm-svn: 63140 --- clang/www/latest_checker.html.incl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/www/latest_checker.html.incl b/clang/www/latest_checker.html.incl index 56439ef56696..2600d753b867 100644 --- a/clang/www/latest_checker.html.incl +++ b/clang/www/latest_checker.html.incl @@ -1 +1 @@ -checker-0.144.tar.bz2 (built January 24, 2009) +checker-0.145.tar.bz2 (built January 27, 2009) -- GitLab From e19a1f15aef6f5992266f28f313d74454727ceea Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 27 Jan 2009 22:27:56 +0000 Subject: [PATCH 303/682] After talking to our runtime guru, I added a comment. llvm-svn: 63141 --- clang/lib/CodeGen/CGObjCMac.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index eef74083daea..eb26a95807b4 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3562,6 +3562,11 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( Field->getType().getTypePtr()) >> 3; Align = llvm::Log2_32(Align); Ivar[3] = llvm::ConstantInt::get(ObjCTypes.IntTy, Align); + // NOTE. Size of a bitfield does not match gcc's, because of the way + // bitfields are treated special in each. But I am told that 'size' + // for bitfield ivars is ignored by the runtime so it does not matter. + // (even if it matters, some day, there is enough info. to get the bitfield + // right! Ivar[4] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size); Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarnfABITy, Ivar)); } -- GitLab From 70d4c08cfeb75f6df20d6927525ca83b5a45cd5c Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Tue, 27 Jan 2009 22:29:24 +0000 Subject: [PATCH 304/682] Treat [1 x i8] zeroinitializer as a C string, placing such stuff into mergeable string section. I don't see any bad impact of such decision (rather then placing it into mergeable const section, as it was before), but at least Darwin linker won't complain anymore. The problem in LLVM is that we don't have special type for string constants (like gcc does). Even more, we have two separate types: ConstatArray for non-null strings and ConstantAggregateZero for null stuff.... It's a bit weird :) llvm-svn: 63142 --- llvm/lib/Target/DarwinTargetAsmInfo.cpp | 4 ++-- llvm/lib/Target/ELFTargetAsmInfo.cpp | 3 +-- llvm/lib/Target/TargetAsmInfo.cpp | 23 +++++++++++++++++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/DarwinTargetAsmInfo.cpp b/llvm/lib/Target/DarwinTargetAsmInfo.cpp index 57e70148f481..cc05c09c5170 100644 --- a/llvm/lib/Target/DarwinTargetAsmInfo.cpp +++ b/llvm/lib/Target/DarwinTargetAsmInfo.cpp @@ -115,9 +115,9 @@ const Section* DarwinTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { const TargetData *TD = TM.getTargetData(); Constant *C = cast(GV)->getInitializer(); - const Type *Type = cast(C)->getType()->getElementType(); + const Type *Ty = cast(C->getType())->getElementType(); - unsigned Size = TD->getTypePaddedSize(Type); + unsigned Size = TD->getTypePaddedSize(Ty); if (Size) { unsigned Align = TD->getPreferredAlignment(GV); if (Align <= 32) diff --git a/llvm/lib/Target/ELFTargetAsmInfo.cpp b/llvm/lib/Target/ELFTargetAsmInfo.cpp index 5a3b93a52f37..624b95c7b6c1 100644 --- a/llvm/lib/Target/ELFTargetAsmInfo.cpp +++ b/llvm/lib/Target/ELFTargetAsmInfo.cpp @@ -126,8 +126,7 @@ const Section* ELFTargetAsmInfo::MergeableStringSection(const GlobalVariable *GV) const { const TargetData *TD = TM.getTargetData(); Constant *C = cast(GV)->getInitializer(); - const ConstantArray *CVA = cast(C); - const Type *Ty = CVA->getType()->getElementType(); + const Type *Ty = cast(C->getType())->getElementType(); unsigned Size = TD->getTypePaddedSize(Ty); if (Size <= 16) { diff --git a/llvm/lib/Target/TargetAsmInfo.cpp b/llvm/lib/Target/TargetAsmInfo.cpp index 4666875c34c2..d687e2f44cfd 100644 --- a/llvm/lib/Target/TargetAsmInfo.cpp +++ b/llvm/lib/Target/TargetAsmInfo.cpp @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" #include "llvm/GlobalVariable.h" #include "llvm/Function.h" #include "llvm/Module.h" @@ -170,6 +171,25 @@ static bool isSuitableForBSS(const GlobalVariable *GV) { return (C->isNullValue() && !GV->isConstant() && !NoZerosInBSS); } +static bool isConstantString(const Constant *C) { + // First check: is we have constant array of i8 terminated with zero + const ConstantArray *CVA = dyn_cast(C); + // Check, if initializer is a null-terminated string + if (CVA && CVA->isCString()) + return true; + + // Another possibility: [1 x i8] zeroinitializer + if (isa(C)) { + if (const ArrayType *Ty = dyn_cast(C->getType())) { + return (Ty->getElementType() == Type::Int8Ty && + Ty->getNumElements() == 1); + } + } + + return false; +} + + SectionKind::Kind TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { // Early exit - functions should be always in text sections. @@ -191,9 +211,8 @@ TargetAsmInfo::SectionKindForGlobal(const GlobalValue *GV) const { if (C->ContainsRelocations()) return SectionKind::ROData; else { - const ConstantArray *CVA = dyn_cast(C); // Check, if initializer is a null-terminated string - if (CVA && CVA->isCString()) + if (isConstantString(C)) return SectionKind::RODataMergeStr; else return SectionKind::RODataMergeConst; -- GitLab From fd03bdd00cfdb258a0906ad34c3d66ca71aa6cc8 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 27 Jan 2009 23:00:53 +0000 Subject: [PATCH 305/682] Add testcase for r63142. llvm-svn: 63149 --- .../CodeGen/X86/2009-01-27-NullStrings.ll | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll diff --git a/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll b/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll new file mode 100644 index 000000000000..0b087d00e238 --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll @@ -0,0 +1,40 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {\\.cstring} | count 1 +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin9.6" + %struct.A = type { } + %struct.NSString = type opaque + %struct.__builtin_CFString = type { i32*, i32, i8*, i32 } + %struct._objc_module = type { i32, i32, i8*, %struct._objc_symtab* } + %struct._objc_symtab = type { i32, %struct.objc_selector**, i16, i16 } + %struct.objc_object = type opaque + %struct.objc_selector = type opaque +@"\01L_unnamed_cfstring_0" = internal constant %struct.__builtin_CFString { i32* getelementptr ([0 x i32]* @__CFConstantStringClassReference, i32 0, i32 0), i32 1992, i8* getelementptr ([1 x i8]* @"\01LC", i32 0, i32 0), i32 0 }, section "__DATA, __cfstring" ; <%struct.__builtin_CFString*> [#uses=1] +@__CFConstantStringClassReference = external global [0 x i32] ; <[0 x i32]*> [#uses=1] +@"\01LC" = internal constant [1 x i8] zeroinitializer ; <[1 x i8]*> [#uses=1] +@"\01L_OBJC_SELECTOR_REFERENCES_0" = internal global %struct.objc_selector* bitcast ([6 x i8]* @"\01L_OBJC_METH_VAR_NAME_0" to %struct.objc_selector*), section "__OBJC,__message_refs,literal_pointers,no_dead_strip", align 4 ; <%struct.objc_selector**> [#uses=2] +@"\01L_OBJC_SYMBOLS" = internal global %struct._objc_symtab zeroinitializer, section "__OBJC,__symbols,regular,no_dead_strip", align 4 ; <%struct._objc_symtab*> [#uses=2] +@"\01L_OBJC_METH_VAR_NAME_0" = internal global [6 x i8] c"bork:\00", section "__TEXT,__cstring,cstring_literals", align 1 ; <[6 x i8]*> [#uses=2] +@"\01L_OBJC_IMAGE_INFO" = internal constant [2 x i32] zeroinitializer, section "__OBJC, __image_info,regular" ; <[2 x i32]*> [#uses=1] +@"\01L_OBJC_CLASS_NAME_0" = internal global [1 x i8] zeroinitializer, section "__TEXT,__cstring,cstring_literals", align 1 ; <[1 x i8]*> [#uses=1] +@"\01L_OBJC_MODULES" = internal global %struct._objc_module { i32 7, i32 16, i8* getelementptr ([1 x i8]* @"\01L_OBJC_CLASS_NAME_0", i32 0, i32 0), %struct._objc_symtab* @"\01L_OBJC_SYMBOLS" }, section "__OBJC,__module_info,regular,no_dead_strip", align 4 ; <%struct._objc_module*> [#uses=1] +@llvm.used = appending global [6 x i8*] [ i8* bitcast (%struct.objc_selector** @"\01L_OBJC_SELECTOR_REFERENCES_0" to i8*), i8* bitcast (%struct._objc_symtab* @"\01L_OBJC_SYMBOLS" to i8*), i8* getelementptr ([6 x i8]* @"\01L_OBJC_METH_VAR_NAME_0", i32 0, i32 0), i8* bitcast ([2 x i32]* @"\01L_OBJC_IMAGE_INFO" to i8*), i8* getelementptr ([1 x i8]* @"\01L_OBJC_CLASS_NAME_0", i32 0, i32 0), i8* bitcast (%struct._objc_module* @"\01L_OBJC_MODULES" to i8*) ], section "llvm.metadata" ; <[6 x i8*]*> [#uses=0] + +define void @func(%struct.A* %a) nounwind { +entry: + %a_addr = alloca %struct.A* ; <%struct.A**> [#uses=2] + %a.0 = alloca %struct.objc_object* ; <%struct.objc_object**> [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + store %struct.A* %a, %struct.A** %a_addr + %0 = load %struct.A** %a_addr, align 4 ; <%struct.A*> [#uses=1] + %1 = bitcast %struct.A* %0 to %struct.objc_object* ; <%struct.objc_object*> [#uses=1] + store %struct.objc_object* %1, %struct.objc_object** %a.0, align 4 + %2 = load %struct.objc_selector** @"\01L_OBJC_SELECTOR_REFERENCES_0", align 4 ; <%struct.objc_selector*> [#uses=1] + %3 = load %struct.objc_object** %a.0, align 4 ; <%struct.objc_object*> [#uses=1] + call void bitcast (%struct.objc_object* (%struct.objc_object*, %struct.objc_selector*, ...)* @objc_msgSend to void (%struct.objc_object*, %struct.objc_selector*, %struct.NSString*)*)(%struct.objc_object* %3, %struct.objc_selector* %2, %struct.NSString* bitcast (%struct.__builtin_CFString* @"\01L_unnamed_cfstring_0" to %struct.NSString*)) nounwind + br label %return + +return: ; preds = %entry + ret void +} + +declare %struct.objc_object* @objc_msgSend(%struct.objc_object*, %struct.objc_selector*, ...) -- GitLab From a5a77a6dc625ed6f920fc8ef88761ceb341e6d49 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 27 Jan 2009 23:18:31 +0000 Subject: [PATCH 306/682] Add handling of member pointers to reinterpret_cast. llvm-svn: 63150 --- clang/lib/Sema/SemaNamedCast.cpp | 55 ++++++++++++++++++------- clang/test/SemaCXX/reinterpret-cast.cpp | 18 ++++++++ clang/www/cxx_status.html | 6 +-- 3 files changed, 61 insertions(+), 18 deletions(-) diff --git a/clang/lib/Sema/SemaNamedCast.cpp b/clang/lib/Sema/SemaNamedCast.cpp index 17de7321dee8..e88a3b2079f2 100644 --- a/clang/lib/Sema/SemaNamedCast.cpp +++ b/clang/lib/Sema/SemaNamedCast.cpp @@ -237,6 +237,32 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, // Canonicalize source for comparison. SrcType = Self.Context.getCanonicalType(SrcType); + const MemberPointerType *DestMemPtr = DestType->getAsMemberPointerType(), + *SrcMemPtr = SrcType->getAsMemberPointerType(); + if (DestMemPtr && SrcMemPtr) { + // C++ 5.2.10p9: An rvalue of type "pointer to member of X of type T1" + // can be explicitly converted to an rvalue of type "pointer to member + // of Y of type T2" if T1 and T2 are both function types or both object + // types. + if (DestMemPtr->getPointeeType()->isFunctionType() != + SrcMemPtr->getPointeeType()->isFunctionType()) { + Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic) + << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange; + return; + } + + // C++ 5.2.10p2: The reinterpret_cast operator shall not cast away + // constness. + if (CastsAwayConstness(Self, SrcType, DestType)) { + Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_const_away) + << "reinterpret_cast" << OrigDestType << OrigSrcType << OpRange; + return; + } + + // A valid member pointer cast. + return; + } + bool destIsPtr = DestType->isPointerType(); bool srcIsPtr = SrcType->isPointerType(); if (!destIsPtr && !srcIsPtr) { @@ -253,8 +279,8 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, // restrictions, a cast to the same type is allowed. The intent is not // entirely clear here, since all other paragraphs explicitly forbid casts // to the same type. However, the behavior of compilers is pretty consistent - // on this point: allow same-type conversion if the involved are pointers, - // disallow otherwise. + // on this point: allow same-type conversion if the involved types are + // pointers, disallow otherwise. return; } @@ -304,8 +330,6 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, return; } - // FIXME: Handle member pointers. - // C++0x 5.2.10p8: Converting a pointer to a function into a pointer to // an object type or vice versa is conditionally-supported. // Compilers support it in C++03 too, though, because it's necessary for @@ -319,8 +343,6 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, return; } - // FIXME: Handle member pointers. - if (DestType->isFunctionPointerType()) { // See above. if (!Self.getLangOptions().CPlusPlus0x) { @@ -337,18 +359,21 @@ CheckReinterpretCast(Sema &Self, Expr *&SrcExpr, QualType DestType, // object pointers. } -/// CastsAwayConstness - Check if the pointer conversion from SrcType -/// to DestType casts away constness as defined in C++ -/// 5.2.11p8ff. This is used by the cast checkers. Both arguments -/// must denote pointer types. +/// CastsAwayConstness - Check if the pointer conversion from SrcType to +/// DestType casts away constness as defined in C++ 5.2.11p8ff. This is used by +/// the cast checkers. Both arguments must denote pointer (possibly to member) +/// types. bool CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType) { - // Casting away constness is defined in C++ 5.2.11p8 with reference to - // C++ 4.4. - // We piggyback on Sema::IsQualificationConversion for this, since the rules - // are non-trivial. So first we construct Tcv *...cv* as described in - // C++ 5.2.11p8. + // Casting away constness is defined in C++ 5.2.11p8 with reference to + // C++ 4.4. We piggyback on Sema::IsQualificationConversion for this, since + // the rules are non-trivial. So first we construct Tcv *...cv* as described + // in C++ 5.2.11p8. + assert((SrcType->isPointerType() || SrcType->isMemberPointerType()) && + "Source type is not pointer or pointer to member."); + assert((DestType->isPointerType() || DestType->isMemberPointerType()) && + "Destination type is not pointer or pointer to member."); QualType UnwrappedSrcType = SrcType, UnwrappedDestType = DestType; llvm::SmallVector cv1, cv2; diff --git a/clang/test/SemaCXX/reinterpret-cast.cpp b/clang/test/SemaCXX/reinterpret-cast.cpp index 6172c9f8d9e3..e6d635242dab 100644 --- a/clang/test/SemaCXX/reinterpret-cast.cpp +++ b/clang/test/SemaCXX/reinterpret-cast.cpp @@ -70,3 +70,21 @@ void refs() // Bad: from rvalue (void)reinterpret_cast(&c); // expected-error {{reinterpret_cast from rvalue to reference type 'int &'}} } + +void memptrs() +{ + const int structure::*psi = 0; + (void)reinterpret_cast(psi); + (void)reinterpret_cast(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'int struct structure::*' casts away constness}} + + void (structure::*psf)() = 0; + (void)reinterpret_cast(psf); + + (void)reinterpret_cast(psi); // expected-error {{reinterpret_cast from 'int const struct structure::*' to 'void (struct structure::*)(void)' is not allowed}} + (void)reinterpret_cast(psf); // expected-error {{reinterpret_cast from 'void (struct structure::*)(void)' to 'int struct structure::*' is not allowed}} + + // Cannot cast from integers to member pointers, not even the null pointer + // literal. + (void)reinterpret_cast(0); // expected-error {{reinterpret_cast from 'int' to 'void (struct structure::*)(void)' is not allowed}} + (void)reinterpret_cast(0); // expected-error {{reinterpret_cast from 'int' to 'int struct structure::*' is not allowed}} +} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 5c57f913abac..a83157b193e2 100644 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -579,10 +579,10 @@ welcome!

    5.2.10 [expr.reinterpret.cast] ✓ - - + ✓ + ✓ + - Missing member pointer conversions     5.2.11 [expr.const.cast] -- GitLab From 675869aef0d1b80ce67a4d28027fb8b303b6e8af Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 27 Jan 2009 23:19:41 +0000 Subject: [PATCH 307/682] Reorder args, constify. llvm-svn: 63151 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 772ef07e5f1e..3aa3f5ce0523 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -902,7 +902,7 @@ public: inline bool isTargetOpcode() const; inline bool isMachineOpcode() const; inline unsigned getMachineOpcode() const; - inline DebugLoc getDebugLoc() const; + inline const DebugLoc getDebugLoc() const; /// reachesChainWithoutSideEffects - Return true if this operand (which must @@ -1152,10 +1152,10 @@ public: void setNodeId(int Id) { NodeId = Id; } /// getDebugLoc - Return the source location info. - DebugLoc getDebugLoc() const { return debugLoc; } + const DebugLoc getDebugLoc() const { return debugLoc; } /// setDebugLoc - Set source location info. - void setDebugLoc(DebugLoc sl) { debugLoc = sl; } + void setDebugLoc(const DebugLoc dl) { debugLoc = dl; } /// use_iterator - This class provides iterator support for SDUse /// operands that use a specific SDNode. @@ -1363,10 +1363,10 @@ protected: /// The next two constructors specify DebugLoc explicitly; the intent /// is that they will replace the above two over time, and eventually /// the ones above can be removed. - SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, - DebugLoc sl) + SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops, + unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), debugLoc(sl), + NodeId(-1), debugLoc(dl), OperandList(NumOps ? new SDUse[NumOps] : 0), ValueList(VTs.VTs), NumOperands(NumOps), NumValues(VTs.NumVTs), @@ -1379,9 +1379,9 @@ protected: /// This constructor adds no operands itself; operands can be /// set later with InitOperands. - SDNode(unsigned Opc, SDVTList VTs, DebugLoc sl) + SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), - NodeId(-1), debugLoc(sl), OperandList(0), + NodeId(-1), debugLoc(dl), OperandList(0), ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs), UseList(NULL) {} @@ -1479,7 +1479,7 @@ inline bool SDValue::use_empty() const { inline bool SDValue::hasOneUse() const { return Node->hasNUsesOfValue(1, ResNo); } -inline DebugLoc SDValue::getDebugLoc() const { +inline const DebugLoc SDValue::getDebugLoc() const { return Node->getDebugLoc(); } -- GitLab From 4e04ef3c55b88d5fb581419b8f394da219e3375c Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 27 Jan 2009 23:20:29 +0000 Subject: [PATCH 308/682] Add a DebugLoc field and some simple accessors. llvm-svn: 63152 --- llvm/include/llvm/CodeGen/MachineInstr.h | 31 +++++++++++++- llvm/lib/CodeGen/MachineInstr.cpp | 53 ++++++++++++++++++++---- 2 files changed, 75 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 379cf8fbd340..3488ea3a0dcc 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -22,6 +22,7 @@ #include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/Target/TargetInstrDesc.h" +#include "llvm/CodeGen/DebugLoc.h" #include #include @@ -43,6 +44,7 @@ class MachineInstr : public ilist_node { std::vector Operands; // the operands std::list MemOperands; // information on memory references MachineBasicBlock *Parent; // Pointer to the owning basic block. + DebugLoc debugLoc; // Source line information. // OperandComplete - Return true if it's illegal to add a new operand bool OperandsComplete() const; @@ -64,17 +66,34 @@ class MachineInstr : public ilist_node { /// TID NULL and no operands. MachineInstr(); + // The next two constructors have DebugLoc and non-DebugLoc versions; + // 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. + /// 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. + /// 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 + /// implicit operands. It reserves space for number of operands specified by + /// TargetInstrDesc. An explicit DebugLoc is supplied. + explicit MachineInstr(const TargetInstrDesc &TID, const DebugLoc dl, + 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. + /// + MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, + const TargetInstrDesc &TID); + ~MachineInstr(); // MachineInstrs are pool-allocated and owned by MachineFunction. @@ -83,6 +102,10 @@ class MachineInstr : public ilist_node { public: const MachineBasicBlock* getParent() const { return Parent; } MachineBasicBlock* getParent() { return Parent; } + + /// getDebugLoc - Returns the debug location id of this MachineInstr. + /// + const DebugLoc getDebugLoc() const { return debugLoc; } /// getDesc - Returns the target instruction descriptor of this /// MachineInstr. @@ -289,6 +312,10 @@ public: /// void setDesc(const TargetInstrDesc &tid) { TID = &tid; } + /// setDebugLoc - Replace current source information with new such. + /// + void setDebugLoc(const DebugLoc dl) { debugLoc = dl; } + /// RemoveOperand - Erase an operand from an instruction, leaving it with one /// fewer operand than it started with. /// diff --git a/llvm/lib/CodeGen/MachineInstr.cpp b/llvm/lib/CodeGen/MachineInstr.cpp index 3825ddbb0742..d4a60bc6ae88 100644 --- a/llvm/lib/CodeGen/MachineInstr.cpp +++ b/llvm/lib/CodeGen/MachineInstr.cpp @@ -283,7 +283,7 @@ void MachineMemOperand::Profile(FoldingSetNodeID &ID) const { /// MachineInstr ctor - This constructor creates a dummy MachineInstr with /// TID NULL and no operands. MachineInstr::MachineInstr() - : TID(0), NumImplicitOps(0), Parent(0) { + : TID(0), NumImplicitOps(0), Parent(0), debugLoc(DebugLoc::getUnknownLoc()) { // Make sure that we get added to a machine basicblock LeakDetector::addGarbageObject(this); } @@ -302,7 +302,8 @@ void MachineInstr::addImplicitDefUseOperands() { /// TargetInstrDesc or the numOperands if it is not zero. (for /// instructions with variable number of operands). MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) - : TID(&tid), NumImplicitOps(0), Parent(0) { + : TID(&tid), NumImplicitOps(0), Parent(0), + debugLoc(DebugLoc::getUnknownLoc()) { if (!NoImp && TID->getImplicitDefs()) for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) NumImplicitOps++; @@ -316,12 +317,49 @@ MachineInstr::MachineInstr(const TargetInstrDesc &tid, bool NoImp) LeakDetector::addGarbageObject(this); } -/// 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 ctor - As above, but with a DebugLoc. +MachineInstr::MachineInstr(const TargetInstrDesc &tid, const DebugLoc dl, + bool NoImp) + : TID(&tid), NumImplicitOps(0), Parent(0), debugLoc(dl) { + if (!NoImp && TID->getImplicitDefs()) + for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) + NumImplicitOps++; + if (!NoImp && TID->getImplicitUses()) + for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses) + NumImplicitOps++; + Operands.reserve(NumImplicitOps + TID->getNumOperands()); + if (!NoImp) + addImplicitDefUseOperands(); + // Make sure that we get added to a machine basicblock + LeakDetector::addGarbageObject(this); +} + +/// MachineInstr ctor - Work exactly the same as the ctor two above, except +/// that the MachineInstr is created and added to the end of the specified +/// basic block. +/// +MachineInstr::MachineInstr(MachineBasicBlock *MBB, const TargetInstrDesc &tid) + : TID(&tid), NumImplicitOps(0), Parent(0), + debugLoc(DebugLoc::getUnknownLoc()) { + assert(MBB && "Cannot use inserting ctor with null basic block!"); + if (TID->ImplicitDefs) + for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) + NumImplicitOps++; + if (TID->ImplicitUses) + for (const unsigned *ImpUses = TID->getImplicitUses(); *ImpUses; ++ImpUses) + NumImplicitOps++; + Operands.reserve(NumImplicitOps + TID->getNumOperands()); + addImplicitDefUseOperands(); + // Make sure that we get added to a machine basicblock + LeakDetector::addGarbageObject(this); + MBB->push_back(this); // Add instruction to end of basic block! +} + +/// MachineInstr ctor - As above, but with a DebugLoc. /// -MachineInstr::MachineInstr(MachineBasicBlock *MBB, +MachineInstr::MachineInstr(MachineBasicBlock *MBB, const DebugLoc dl, const TargetInstrDesc &tid) - : TID(&tid), NumImplicitOps(0), Parent(0) { + : TID(&tid), NumImplicitOps(0), Parent(0), debugLoc(dl) { assert(MBB && "Cannot use inserting ctor with null basic block!"); if (TID->ImplicitDefs) for (const unsigned *ImpDefs = TID->getImplicitDefs(); *ImpDefs; ++ImpDefs) @@ -339,7 +377,8 @@ MachineInstr::MachineInstr(MachineBasicBlock *MBB, /// MachineInstr ctor - Copies MachineInstr arg exactly /// MachineInstr::MachineInstr(MachineFunction &MF, const MachineInstr &MI) - : TID(&MI.getDesc()), NumImplicitOps(0), Parent(0) { + : TID(&MI.getDesc()), NumImplicitOps(0), Parent(0), + debugLoc(MI.getDebugLoc()) { Operands.reserve(MI.getNumOperands()); // Add operands -- GitLab From 99c0cdf899af1320b76020c02349ba5864996c0c Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Tue, 27 Jan 2009 23:20:32 +0000 Subject: [PATCH 309/682] Finish making AST BumpPtrAllocation runtime configurable (based on -disable-free). snaroff% time ../../Release-Asserts/bin/clang INPUTS/Cocoa_h.m 0.179u 0.051s 0:00.23 95.6% 0+0k 0+0io 0pf+0w snaroff% time ../../Release-Asserts/bin/clang INPUTS/Cocoa_h.m -disable-free 0.169u 0.052s 0:00.22 95.4% 0+0k 0+0io 0pf+0w llvm-svn: 63153 --- clang/include/clang/AST/ASTContext.h | 26 ++++++++++++++++---------- clang/lib/AST/ASTContext.cpp | 8 ++++---- clang/lib/AST/Decl.cpp | 5 ++--- clang/lib/AST/DeclCXX.cpp | 2 +- clang/lib/AST/DeclGroup.cpp | 4 ++-- clang/lib/AST/Expr.cpp | 7 +++---- clang/lib/Sema/ParseAST.cpp | 3 ++- 7 files changed, 30 insertions(+), 25 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 9cf11b85784d..bf585b6d9e76 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -118,9 +118,10 @@ class ASTContext { /// this ASTContext object. LangOptions LangOpts; - /// Allocator - The allocator object used to create AST objects. - llvm::MallocAllocator Allocator; - + /// MallocAlloc/BumpAlloc - The allocator objects used to create AST objects. + bool FreeMemory; + llvm::MallocAllocator MallocAlloc; + llvm::BumpPtrAllocator BumpAlloc; public: TargetInfo &Target; IdentifierTable &Idents; @@ -128,9 +129,14 @@ public: DeclarationNameTable DeclarationNames; SourceManager& getSourceManager() { return SourceMgr; } - llvm::MallocAllocator &getAllocator() { return Allocator; } - void Deallocate(void *Ptr) { Allocator.Deallocate(Ptr); } - + void *Allocate(unsigned Size, unsigned Align = 8) { + return FreeMemory ? MallocAlloc.Allocate(Size, Align) : + BumpAlloc.Allocate(Size, Align); + } + void Deallocate(void *Ptr) { + if (FreeMemory) + MallocAlloc.Deallocate(Ptr); + } const LangOptions& getLangOptions() const { return LangOpts; } FullSourceLoc getFullLoc(SourceLocation Loc) const { @@ -159,8 +165,8 @@ public: QualType DependentTy; ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t, - IdentifierTable &idents, SelectorTable &sels, - unsigned size_reserve=0); + IdentifierTable &idents, SelectorTable &sels, + bool FreeMemory = true, unsigned size_reserve=0); ~ASTContext(); @@ -600,7 +606,7 @@ private: /// @return The allocated memory. Could be NULL. inline void *operator new(size_t Bytes, clang::ASTContext &C, size_t Alignment = 16) throw () { - return C.getAllocator().Allocate(Bytes, Alignment); + return C.Allocate(Bytes, Alignment); } /// @brief Placement delete companion to the new above. /// @@ -610,7 +616,7 @@ inline void *operator new(size_t Bytes, clang::ASTContext &C, /// the ASTContext throws in the object constructor. inline void operator delete(void *Ptr, clang::ASTContext &C) throw () { - C.getAllocator().Deallocate(Ptr); + C.Deallocate(Ptr); } #endif diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 7cc67e03d493..5e2269105992 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -31,9 +31,9 @@ enum FloatingRank { ASTContext::ASTContext(const LangOptions& LOpts, SourceManager &SM, TargetInfo &t, IdentifierTable &idents, SelectorTable &sels, - unsigned size_reserve) : + bool FreeMem, unsigned size_reserve) : CFConstantStringTypeDecl(0), ObjCFastEnumerationStateTypeDecl(0), - SourceMgr(SM), LangOpts(LOpts), Target(t), + SourceMgr(SM), LangOpts(LOpts), FreeMemory(FreeMem), Target(t), Idents(idents), Selectors(sels) { if (size_reserve > 0) Types.reserve(size_reserve); @@ -1126,8 +1126,8 @@ QualType ASTContext::getFunctionType(QualType ResultTy,const QualType *ArgArray, // FunctionTypeProto objects are allocated with extra bytes after them // for a variable size array (for parameter types) at the end of them. FunctionTypeProto *FTP = - (FunctionTypeProto*)Allocator.Allocate(sizeof(FunctionTypeProto) + - NumArgs*sizeof(QualType), 8); + (FunctionTypeProto*)Allocate(sizeof(FunctionTypeProto) + + NumArgs*sizeof(QualType), 8); new (FTP) FunctionTypeProto(ResultTy, ArgArray, NumArgs, isVariadic, TypeQuals, Canonical); Types.push_back(FTP); diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index c8b7fc2dcf98..25317dbeb109 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -118,8 +118,7 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, EnumDecl *PrevDecl) { - void *Mem = C.getAllocator().Allocate(); - EnumDecl *Enum = new (Mem) EnumDecl(DC, L, Id); + EnumDecl *Enum = new (C) EnumDecl(DC, L, Id); C.getTypeDeclType(Enum, PrevDecl); return Enum; } @@ -229,7 +228,7 @@ void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, // Zero params -> null pointer. if (NumParams) { - void *Mem = C.getAllocator().Allocate(NumParams); + void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); ParamInfo = new (Mem) ParmVarDecl*[NumParams]; memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index ee242c5dffcb..39ca8787914e 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -47,7 +47,7 @@ TemplateParameterList::Create(ASTContext &C, Decl **Params, // FIXME: how do I pass in Size to ASTContext::new? unsigned Size = sizeof(TemplateParameterList) + sizeof(Decl *) * NumParams; unsigned Align = llvm::AlignOf::Alignment; - void *Mem = C.getAllocator().Allocate(Size, Align); + void *Mem = C.Allocate(Size, Align); return new (Mem) TemplateParameterList(Params, NumParams); } diff --git a/clang/lib/AST/DeclGroup.cpp b/clang/lib/AST/DeclGroup.cpp index c7af7cd89ea3..e7f84e1f46c8 100644 --- a/clang/lib/AST/DeclGroup.cpp +++ b/clang/lib/AST/DeclGroup.cpp @@ -24,7 +24,7 @@ DeclGroup* DeclGroup::Create(ASTContext& C, unsigned numdecls, Decl** decls) { assert (numdecls > 0); unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * numdecls; unsigned alignment = llvm::AlignOf::Alignment; - void* mem = C.getAllocator().Allocate(size, alignment); + void* mem = C.Allocate(size, alignment); new (mem) DeclGroup(numdecls, decls); return static_cast(mem); } @@ -40,7 +40,7 @@ DeclGroup* DeclGroup::Create(llvm::Deserializer& D, ASTContext& C) { unsigned NumDecls = (unsigned) D.ReadInt(); unsigned size = sizeof(DeclGroup) + sizeof(Decl*) * NumDecls; unsigned alignment = llvm::AlignOf::Alignment; - DeclGroup* DG = (DeclGroup*) C.getAllocator().Allocate(size, alignment); + DeclGroup* DG = (DeclGroup*) C.Allocate(size, alignment); new (DG) DeclGroup(); DG->NumDecls = NumDecls; D.BatchReadOwnedPtrs(NumDecls, &(*DG)[0], C); diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index 63484d1b87dc..8e43f99b6729 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -1387,10 +1387,9 @@ DesignatedInitExpr::Create(ASTContext &C, Designator *Designators, Expr **IndexExprs, unsigned NumIndexExprs, SourceLocation ColonOrEqualLoc, bool UsesColonSyntax, Expr *Init) { - void *Mem = C.getAllocator().Allocate(sizeof(DesignatedInitExpr) + - sizeof(Designator) * NumDesignators + - sizeof(Stmt *) * (NumIndexExprs + 1), - 8); + void *Mem = C.Allocate(sizeof(DesignatedInitExpr) + + sizeof(Designator) * NumDesignators + + sizeof(Stmt *) * (NumIndexExprs + 1), 8); DesignatedInitExpr *DIE = new (Mem) DesignatedInitExpr(C.VoidTy, NumDesignators, ColonOrEqualLoc, UsesColonSyntax, diff --git a/clang/lib/Sema/ParseAST.cpp b/clang/lib/Sema/ParseAST.cpp index ff6de25c1dc2..67af28531501 100644 --- a/clang/lib/Sema/ParseAST.cpp +++ b/clang/lib/Sema/ParseAST.cpp @@ -39,7 +39,8 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, ASTContext *Context = new ASTContext(PP.getLangOptions(), PP.getSourceManager(), PP.getTargetInfo(), - PP.getIdentifierTable(), PP.getSelectorTable()); + PP.getIdentifierTable(), PP.getSelectorTable(), + FreeMemory); TranslationUnit *TU = new TranslationUnit(*Context); Sema S(PP, *Context, *Consumer); Parser P(PP, S); -- GitLab From 5adc3dbc96890cbb83d809a874ea1a678c5f4128 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Tue, 27 Jan 2009 23:22:55 +0000 Subject: [PATCH 310/682] Add type DIE into appropriate context DIE. llvm-svn: 63154 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 19edd9514686..63fb68b5ec75 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1687,9 +1687,23 @@ private: ConstructTypeDIE(DW_Unit, Buffer, DICompositeType(Ty.getGV())); } - // Add debug information entry to entity and unit. - DIE *Die = DW_Unit->AddDie(Buffer); - SetDIEntry(Slot, Die); + // Add debug information entry to entity and appropriate context. + DIE *Die = NULL; + DIDescriptor Context = Ty.getContext(); + if (!Context.isNull()) + Die = DW_Unit->getDieMapSlotFor(Context.getGV()); + + if (Die) { + DIE *Child = new DIE(Buffer); + Die->AddChild(Child); + Buffer.Detach(); + SetDIEntry(Slot, Child); + } + else { + Die = DW_Unit->AddDie(Buffer); + SetDIEntry(Slot, Die); + } + Entity->AddValue(DW_AT_type, DW_FORM_ref4, Slot); } -- GitLab From b3e09314018150abba7f065a6dda92d8567119a8 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 27 Jan 2009 23:32:10 +0000 Subject: [PATCH 311/682] Embalm my ideas of how things should work. Not that anyone will pay attention. llvm-svn: 63155 --- llvm/include/llvm/CodeGen/MachineInstr.h | 1 + llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/llvm/include/llvm/CodeGen/MachineInstr.h b/llvm/include/llvm/CodeGen/MachineInstr.h index 3488ea3a0dcc..2a3f98dbc5bd 100644 --- a/llvm/include/llvm/CodeGen/MachineInstr.h +++ b/llvm/include/llvm/CodeGen/MachineInstr.h @@ -313,6 +313,7 @@ public: void setDesc(const TargetInstrDesc &tid) { TID = &tid; } /// setDebugLoc - Replace current source information with new such. + /// Avoid using this, the constructor argument is preferable. /// void setDebugLoc(const DebugLoc dl) { debugLoc = dl; } diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 3aa3f5ce0523..c22b90ceedf7 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1154,7 +1154,8 @@ public: /// getDebugLoc - Return the source location info. const DebugLoc getDebugLoc() const { return debugLoc; } - /// setDebugLoc - Set source location info. + /// setDebugLoc - Set source location info. Try to avoid this, putting + /// it in the constructor is preferable. void setDebugLoc(const DebugLoc dl) { debugLoc = dl; } /// use_iterator - This class provides iterator support for SDUse -- GitLab From 5c04bd81edc00cb201d04e80ae45be50c4cf83db Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 00:27:31 +0000 Subject: [PATCH 312/682] Add a some comments to designate Windows-specific/Unix-specific code. No functionality change. llvm-svn: 63157 --- clang/lib/Basic/FileManager.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index cfc08ed084b1..3f7c4fd74b02 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -22,6 +22,7 @@ #include "llvm/Bitcode/Serialize.h" #include "llvm/Bitcode/Deserialize.h" #include "llvm/Support/Streams.h" +#include "llvm/Support/Allocator.h" #include "llvm/Config/config.h" using namespace clang; @@ -36,6 +37,10 @@ using namespace clang; /// represent a dir name that doesn't exist on the disk. #define NON_EXISTENT_DIR reinterpret_cast((intptr_t)-1) +//===----------------------------------------------------------------------===// +// Windows. +//===----------------------------------------------------------------------===// + #ifdef LLVM_ON_WIN32 #define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/' || (x) == '\\') @@ -87,6 +92,10 @@ public: size_t size() { return UniqueFiles.size(); } }; +//===----------------------------------------------------------------------===// +// Unix-like Systems. +//===----------------------------------------------------------------------===// + #else #define IS_DIR_SEPARATOR_CHAR(x) ((x) == '/') @@ -122,6 +131,9 @@ public: #endif +//===----------------------------------------------------------------------===// +// Common logic. +//===----------------------------------------------------------------------===// FileManager::FileManager() : UniqueDirs(*new UniqueDirContainer), UniqueFiles(*new UniqueFileContainer), -- GitLab From bb537dc189c33fedebaddc7ad1ab474136390427 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Wed, 28 Jan 2009 00:35:17 +0000 Subject: [PATCH 313/682] fix PR3427: fix debuginfo for incomplete array types llvm-svn: 63158 --- clang/lib/CodeGen/CGDebugInfo.cpp | 7 +++++-- clang/test/CodeGen/debug-info.c | 8 +++++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index e0a52d61844d..79abc340644a 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -337,11 +337,14 @@ llvm::DIType CGDebugInfo::CreateType(const ArrayType *Ty, uint64_t Align; + // FIXME: make getTypeAlign() aware of VLAs and incomplete array types if (const VariableArrayType *VAT = dyn_cast(Ty)) { - Size = 0; Align = - M->getContext().getTypeSize(M->getContext().getBaseElementType(VAT)); + M->getContext().getTypeAlign(M->getContext().getBaseElementType(VAT)); + } else if (Ty->isIncompleteArrayType()) { + Size = 0; + Align = M->getContext().getTypeAlign(Ty->getElementType()); } else { // Size and align of the whole array, not the element type. Size = M->getContext().getTypeSize(Ty); diff --git a/clang/test/CodeGen/debug-info.c b/clang/test/CodeGen/debug-info.c index f5a31631fbad..2ecae9fa6d59 100644 --- a/clang/test/CodeGen/debug-info.c +++ b/clang/test/CodeGen/debug-info.c @@ -18,7 +18,13 @@ struct s0 { struct s0 *p; } g0; struct s0 *f0(struct s0 *a0) { return a0->p; } - + // PR3134 char xpto[]; +// PR3427 +struct foo { + int a; + void *ptrs[]; +}; +struct foo bar; -- GitLab From bb2f25b40f115841f7e159821528ade49ce82c21 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 00:44:12 +0000 Subject: [PATCH 314/682] FileManager: Use a BumpPtrAllocator for the StringMaps DirEntries and FileEntries. Performance impact (clang -fsyntax-only INPUTS/Cocoa_h.m): non-PTH: 0.4% improvement PTH: 0.8% improvement llvm-svn: 63159 --- clang/include/clang/Basic/FileManager.h | 5 +++-- clang/lib/Basic/FileManager.cpp | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h index 1b4ca81c3974..aff9758f8146 100644 --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -16,6 +16,7 @@ #include "llvm/ADT/StringMap.h" #include "llvm/Bitcode/SerializationFwd.h" +#include "llvm/Support/Allocator.h" #include #include #include @@ -86,8 +87,8 @@ class FileManager { /// DirEntries/FileEntries - This is a cache of directory/file entries we have /// looked up. The actual Entry is owned by UniqueFiles/UniqueDirs above. /// - llvm::StringMap DirEntries; - llvm::StringMap FileEntries; + llvm::StringMap DirEntries; + llvm::StringMap FileEntries; /// NextFileUID - Each FileEntry we create is assigned a unique ID #. /// diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index 3f7c4fd74b02..c1a486f91efa 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -22,7 +22,6 @@ #include "llvm/Bitcode/Serialize.h" #include "llvm/Bitcode/Deserialize.h" #include "llvm/Support/Streams.h" -#include "llvm/Support/Allocator.h" #include "llvm/Config/config.h" using namespace clang; -- GitLab From b81d94ff5805f2cd7d4a16db2110c41d6c9040e0 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Wed, 28 Jan 2009 00:44:33 +0000 Subject: [PATCH 315/682] add test for PR2502, which was already fixed some time ago llvm-svn: 63160 --- clang/test/Sema/merge-decls.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/clang/test/Sema/merge-decls.c b/clang/test/Sema/merge-decls.c index b26532c5eace..0d3cce36bdc5 100644 --- a/clang/test/Sema/merge-decls.c +++ b/clang/test/Sema/merge-decls.c @@ -17,3 +17,6 @@ int funcdef(); int funcdef2() { return 0; } // expected-note {{previous definition is here}} int funcdef2() { return 0; } // expected-error {{redefinition of 'funcdef2'}} +// PR2502 +void (*f)(void); +void (*f)() = 0; -- GitLab From e4510972a6d260c66772abc04659adab74506b1a Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Wed, 28 Jan 2009 00:53:34 +0000 Subject: [PATCH 316/682] Suppress a compile time warning. llvm-svn: 63161 --- llvm/lib/Target/ARM/ARMConstantIslandPass.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp index e544c67d45cb..5ecb28e9ec1f 100644 --- a/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp +++ b/llvm/lib/Target/ARM/ARMConstantIslandPass.cpp @@ -701,6 +701,7 @@ bool ARMConstantIslands::CPEIsInRange(MachineInstr *MI, unsigned UserOffset, return OffsetIsInRange(UserOffset, CPEOffset, MaxDisp, !isThumb); } +#ifndef NDEBUG /// BBIsJumpedOver - Return true of the specified basic block's only predecessor /// unconditionally branches to its only successor. static bool BBIsJumpedOver(MachineBasicBlock *MBB) { @@ -714,6 +715,7 @@ static bool BBIsJumpedOver(MachineBasicBlock *MBB) { return PredMI->getOperand(0).getMBB() == Succ; return false; } +#endif // NDEBUG void ARMConstantIslands::AdjustBBOffsetsAfter(MachineBasicBlock *BB, int delta) { -- GitLab From 1502b7e288364c4b193c57cef46cb47680f0c9cd Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 01:01:07 +0000 Subject: [PATCH 317/682] On Windows use a BumpPtrAllocator for the UniqueFileContainer's StringMap. llvm-svn: 63162 --- clang/lib/Basic/FileManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/Basic/FileManager.cpp b/clang/lib/Basic/FileManager.cpp index c1a486f91efa..9ae1ad4c28de 100644 --- a/clang/lib/Basic/FileManager.cpp +++ b/clang/lib/Basic/FileManager.cpp @@ -77,7 +77,7 @@ public: class FileManager::UniqueFileContainer { /// UniqueFiles - Cache from full path to existing directories/files. /// - llvm::StringMap UniqueFiles; + llvm::StringMap UniqueFiles; public: FileEntry &getFile(const char *Name, struct stat &StatBuf) { -- GitLab From 40a4bcd49bd6fee4fdea25eabaa1e943dc56052d Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 28 Jan 2009 01:05:23 +0000 Subject: [PATCH 318/682] Generation of ivar-offset symbols in objc2's non-fragile abi. Changed section names for meta-data (to match current gcc). llvm-svn: 63163 --- clang/lib/CodeGen/CGObjCMac.cpp | 72 +++++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 13 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index eb26a95807b4..ad8bba4aaf0c 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -570,6 +570,10 @@ private: /// IvarListnfABIPtrTy. llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); + llvm::Constant *EmitIvarOffsetVar(const ObjCImplementationDecl *ID, + const FieldDecl *Field, + unsigned long int offset); + public: CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm); // FIXME. All stubs for now! @@ -3161,7 +3165,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( } // FIXME. Section may always be .data Values[ 5] = EmitMethodList(MethodListName, - ".section __DATA,__data,regular,no_dead_strip", Methods); + "__DATA, __objc_const", Methods); Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); if (flags & CLS_META) Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy); @@ -3179,7 +3183,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, &CGM.getModule()); - CLASS_RO_GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + CLASS_RO_GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(CLASS_RO_GV); return CLASS_RO_GV; @@ -3220,7 +3224,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( Init, ClassName, &CGM.getModule()); - GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); // FIXME! why? GV->setAlignment(32); @@ -3424,7 +3428,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) } Values[2] = EmitMethodList(MethodListName, - ".section __DATA,__data,regular,no_dead_strip", + "__DATA, __objc_const", Methods); MethodListName = Prefix; @@ -3438,7 +3442,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) } Values[3] = EmitMethodList(MethodListName, - ".section __DATA,__data,regular,no_dead_strip", + "__DATA, __objc_const", Methods); Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy); Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy); @@ -3453,7 +3457,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) Init, ExtCatName, &CGM.getModule()); - GCATV->setSection(".section __DATA,__data,regular,no_dead_strip"); + GCATV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GCATV); DefinedCategories.push_back(GCATV); } @@ -3515,6 +3519,38 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( ObjCTypes.MethodListnfABIPtrTy); } +llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( + const ObjCImplementationDecl *ID, + const FieldDecl *Field, + unsigned long int Offset) { + + std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.' + + Field->getNameAsString()); + llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); + + llvm::GlobalVariable *IvarOffsetGV = + CGM.getModule().getGlobalVariable(ExternalName); + if (IvarOffsetGV) { + // ivar offset symbol already built due to user code referencing it. + IvarOffsetGV->setInitializer(Init); + return IvarOffsetGV; + } + + IvarOffsetGV = + new llvm::GlobalVariable(Init->getType(), + false, + llvm::GlobalValue::ExternalLinkage, + Init, + ExternalName, + &CGM.getModule()); + IvarOffsetGV->setSection("__DATA, __objc_const"); + UsedGlobals.push_back(IvarOffsetGV); + + return llvm::ConstantExpr::getBitCast( + IvarOffsetGV, + llvm::PointerType::getUnqual(ObjCTypes.LongTy)); +} + /// EmitIvarList - Emit the ivar list for the given /// implementation. If ForClass is true the list of class ivars /// (i.e. metaclass ivars) is emitted, otherwise the list of @@ -3541,13 +3577,23 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( const ObjCInterfaceDecl *OID = ID->getClassInterface(); assert(OID && "CGObjCNonFragileABIMac::EmitIvarList - null interface"); - for(ObjCInterfaceDecl::ivar_iterator i = OID->ivar_begin(), - e = OID->ivar_end(); i != e; ++i) { + // FIXME. Consolidate this with similar code in GenerateClass. + const llvm::Type *InterfaceTy = + CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType( + const_cast(OID))); + + const llvm::StructLayout *Layout = + CGM.getTargetData().getStructLayout(cast(InterfaceTy)); + int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); + const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); + RecordDecl::field_iterator i = RD->field_begin(); + while (countSuperClassIvars-- > 0) + ++i; + for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { FieldDecl *Field = *i; - // FIXME. Put the offset symbol address after code gen. - // for non-fragile ivar access is in. - Ivar[0] = llvm::Constant::getNullValue( - llvm::PointerType::getUnqual(ObjCTypes.LongTy)); + unsigned long offset = Layout->getElementOffset(CGM.getTypes(). + getLLVMFieldNo(Field)); + Ivar[0] = EmitIvarOffsetVar(ID, Field, offset); if (Field->getIdentifier()) Ivar[1] = GetMethodVarName(Field->getIdentifier()); else @@ -3589,7 +3635,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( Prefix + OID->getNameAsString(), &CGM.getModule()); - GV->setSection(".section __DATA,__data,regular,no_dead_strip"); + GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); return llvm::ConstantExpr::getBitCast(GV, -- GitLab From 3cf43ca5716546ccb0262dcd9b997f63f4e7c402 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 28 Jan 2009 01:19:52 +0000 Subject: [PATCH 319/682] Comment fixes. llvm-svn: 63164 --- llvm/include/llvm/CodeGen/DebugLoc.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DebugLoc.h b/llvm/include/llvm/CodeGen/DebugLoc.h index 89c51c443b05..b89bf6302a08 100644 --- a/llvm/include/llvm/CodeGen/DebugLoc.h +++ b/llvm/include/llvm/CodeGen/DebugLoc.h @@ -9,6 +9,8 @@ // // This file defines a number of light weight data structures used by the code // generator to describe and track debug location information. +// +//===----------------------------------------------------------------------===// #ifndef LLVM_CODEGEN_DEBUGLOC_H #define LLVM_CODEGEN_DEBUGLOC_H @@ -27,8 +29,8 @@ namespace llvm { : Src(s), Line(l), Col(c) {}; }; - /// DebugLoc - Debug location id. This is carried by SDNode and - /// MachineInstr to index into a vector of unique debug location tuples. + /// DebugLoc - Debug location id. This is carried by SDNode and MachineInstr + /// to index into a vector of unique debug location tuples. class DebugLoc { unsigned Idx; @@ -38,11 +40,11 @@ namespace llvm { static DebugLoc getUnknownLoc() { DebugLoc L; L.Idx = 0; return L; } static DebugLoc get(unsigned idx) { DebugLoc L; L.Idx = idx; return L; } - // isInvalid - Return true if the DebugLoc is invalid. + /// isInvalid - Return true if the DebugLoc is invalid. bool isInvalid() const { return Idx == ~0U; } - // isUnknown - Return true if there is no debug info for the SDNode / - // MachineInstr. + /// isUnknown - Return true if there is no debug info for the SDNode / + /// MachineInstr. bool isUnknown() const { return Idx == 0; } }; @@ -71,12 +73,12 @@ namespace llvm { /// DebugLocTracker - This class tracks debug location information. /// struct DebugLocTracker { - // DebugLocations - A vector of unique DebugLocTuple's. - // + /// DebugLocations - A vector of unique DebugLocTuple's. + /// std::vector DebugLocations; - // DebugIdsMap - This maps DebugLocTuple's to indices into - // DebugLocations vector. + /// DebugIdsMap - This maps DebugLocTuple's to indices into DebugLocations + /// vector. DenseMap DebugIdMap; DebugLocTracker() {} -- GitLab From 3d3426f321127105a193148252b6be42a3fdfd03 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 28 Jan 2009 01:36:42 +0000 Subject: [PATCH 320/682] Set visibility of ivar offset symbols according to accessibility of the ivar (related to objc2's non-fragile abi). llvm-svn: 63166 --- clang/lib/CodeGen/CGObjCMac.cpp | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index ad8bba4aaf0c..f786a4729bed 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -571,7 +571,7 @@ private: llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID); llvm::Constant *EmitIvarOffsetVar(const ObjCImplementationDecl *ID, - const FieldDecl *Field, + const ObjCIvarDecl *Ivar, unsigned long int offset); public: @@ -3521,11 +3521,11 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( const ObjCImplementationDecl *ID, - const FieldDecl *Field, + const ObjCIvarDecl *Ivar, unsigned long int Offset) { std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.' - + Field->getNameAsString()); + + Ivar->getNameAsString()); llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); llvm::GlobalVariable *IvarOffsetGV = @@ -3533,6 +3533,7 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( if (IvarOffsetGV) { // ivar offset symbol already built due to user code referencing it. IvarOffsetGV->setInitializer(Init); + UsedGlobals.push_back(IvarOffsetGV); return IvarOffsetGV; } @@ -3543,6 +3544,11 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( Init, ExternalName, &CGM.getModule()); + // @private and @package have hidden visibility. + bool globalVisibility = (Ivar->getAccessControl() == ObjCIvarDecl::Public || + Ivar->getAccessControl() == ObjCIvarDecl::Protected); + if (!globalVisibility) + IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); IvarOffsetGV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(IvarOffsetGV); @@ -3589,11 +3595,14 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( RecordDecl::field_iterator i = RD->field_begin(); while (countSuperClassIvars-- > 0) ++i; + ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(); + for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { FieldDecl *Field = *i; unsigned long offset = Layout->getElementOffset(CGM.getTypes(). getLLVMFieldNo(Field)); - Ivar[0] = EmitIvarOffsetVar(ID, Field, offset); + const ObjCIvarDecl *ivarDecl = *I++; + Ivar[0] = EmitIvarOffsetVar(ID, ivarDecl, offset); if (Field->getIdentifier()) Ivar[1] = GetMethodVarName(Field->getIdentifier()); else -- GitLab From 6ec8a4d9e3d999770f0b18615adc33677dcce82c Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 28 Jan 2009 02:01:23 +0000 Subject: [PATCH 321/682] ABITest: Support --test-layout option for generating size/alignment/offsetof based tests of types instead of calling convention tests. llvm-svn: 63167 --- clang/utils/ABITest/ABITestGen.py | 59 ++++++++++++++++++++++--- clang/utils/ABITest/layout/Makefile | 68 +++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 7 deletions(-) create mode 100644 clang/utils/ABITest/layout/Makefile diff --git a/clang/utils/ABITest/ABITestGen.py b/clang/utils/ABITest/ABITestGen.py index 957ce2bb16b1..8f922d7e52f3 100755 --- a/clang/utils/ABITest/ABITestGen.py +++ b/clang/utils/ABITest/ABITestGen.py @@ -21,6 +21,7 @@ class TypePrinter: self.types = {} self.testValues = {} self.testReturnValues = {} + self.layoutTests = [] if info: for f in (self.output,self.outputHeader,self.outputTests,self.outputDriver): @@ -41,9 +42,16 @@ class TypePrinter: print >>self.outputDriver, 'int main(int argc, char **argv) {' def finish(self): + if self.layoutTests: + print >>self.output, 'int main(int argc, char **argv) {' + for f in self.layoutTests: + print >>self.output, ' %s();' % f + print >>self.output, ' return 0;' + print >>self.output, '}' + if self.outputDriver: print >>self.outputDriver, ' return 0;' - print >>self.outputDriver, '}' + print >>self.outputDriver, '}' def getTypeName(self, T): if isinstance(T,BuiltinType): @@ -62,6 +70,20 @@ class TypePrinter: self.types[T] = name return name + def writeLayoutTest(self, i, ty): + tyName = self.getTypeName(ty) + tyNameClean = tyName.replace(' ','_').replace('*','star') + fnName = 'test_%s' % tyNameClean + + print >>self.output,'void %s(void) {' % fnName + self.printSizeOfType(' %s'%fnName, tyName, ty, self.output) + self.printAlignOfType(' %s'%fnName, tyName, ty, self.output) + self.printOffsetsOfType(' %s'%fnName, tyName, ty, self.output) + print >>self.output,'}' + print >>self.output + + self.layoutTests.append(fnName) + def writeFunction(self, i, FT): args = ', '.join(['%s arg%d'%(self.getTypeName(t),i) for i,t in enumerate(FT.argTypes)]) if not args: @@ -194,6 +216,16 @@ class TypePrinter: else: raise NotImplementedError,'Cannot make tests values of type: "%s"'%(t,) + def printSizeOfType(self, prefix, name, t, output=None, indent=2): + print >>output, '%*sprintf("%s: sizeof(%s) = %%ld\\n", sizeof(%s));'%(indent, '', prefix, name, name) + def printAlignOfType(self, prefix, name, t, output=None, indent=2): + print >>output, '%*sprintf("%s: __alignof__(%s) = %%ld\\n", __alignof__(%s));'%(indent, '', prefix, name, name) + def printOffsetsOfType(self, prefix, name, t, output=None, indent=2): + if isinstance(t, RecordType): + for i,f in enumerate(t.fields): + fname = 'field%d' % i + print >>output, '%*sprintf("%s: __builtin_offsetof(%s, %s) = %%ld\\n", __builtin_offsetof(%s, %s));'%(indent, '', prefix, name, fname, name, fname) + def printValueOfType(self, prefix, name, t, output=None, indent=2): if output is None: output = self.output @@ -263,6 +295,9 @@ def main(): parser.add_option("-D", "--output-driver", dest="outputDriver", metavar="FILE", help="write test driver to FILE [default %default]", type=str, default=None) + parser.add_option("", "--test-layout", dest="testLayout", metavar="FILE", + help="test structure layout", + action='store_true', default=False) group = OptionGroup(parser, "Type Enumeration Options") # Builtins - Ints @@ -325,7 +360,7 @@ def main(): action="store_false", default=True) group.add_option("", "--vector-sizes", dest="vectorSizes", help="comma separated list of sizes for vectors [default %default]", - action="store", type=str, default='4,8', metavar="N") + action="store", type=str, default='8,16', metavar="N") group.add_option("", "--max-args", dest="functionMaxArgs", help="maximum number of arguments per function [default %default]", @@ -369,7 +404,8 @@ def main(): btg = FixedTypeGenerator([BuiltinType(n,s) for n,s in builtins]) sbtg = FixedTypeGenerator([BuiltinType('char',1), BuiltinType('int',4), - BuiltinType('float',4)]) + BuiltinType('float',4), + BuiltinType('double',8)]) atg = AnyTypeGenerator() artg = AnyTypeGenerator() @@ -408,7 +444,10 @@ def main(): atg = AnyTypeGenerator() makeGenerator(atg, base, True, False) - ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) + if opts.testLayout: + ftg = atg + else: + ftg = FunctionTypeGenerator(atg, opts.functionUseReturn, opts.functionMaxArgs) # Override max,min,count if finite if opts.maxIndex is None: @@ -447,23 +486,29 @@ def main(): info += '// Generated: %s\n'%(time.strftime('%Y-%m-%d %H:%M'),) info += '// Cardinality of function generator: %s\n'%(ftg.cardinality,) info += '// Cardinality of type generator: %s\n'%(atg.cardinality,) + + if opts.testLayout: + info += '\n#include ' P = TypePrinter(output, outputHeader=outputHeader, outputTests=outputTests, outputDriver=outputDriver, - headerName=opts.outputHeader, + headerName=opts.outputHeader, info=info) def write(N): - try: + try: FT = ftg.get(N) except RuntimeError,e: if e.args[0]=='maximum recursion depth exceeded': print >>sys.stderr,'WARNING: Skipped %d, recursion limit exceeded (bad arguments?)'%(N,) return raise - P.writeFunction(N, FT) + if opts.testLayout: + P.writeLayoutTest(N, FT) + else: + P.writeFunction(N, FT) if args: [write(int(a)) for a in args] diff --git a/clang/utils/ABITest/layout/Makefile b/clang/utils/ABITest/layout/Makefile new file mode 100644 index 000000000000..f93a74e5920b --- /dev/null +++ b/clang/utils/ABITest/layout/Makefile @@ -0,0 +1,68 @@ +# Usage: make test.N.report +# +# COUNT can be over-ridden to change the number of tests generated per +# file, and TESTARGS is used to change the type generation. Make sure +# to 'make clean' after changing either of these parameters. + +ABITESTGEN := ../ABITestGen.py +TESTARGS := --max-args 0 --no-complex --no-vector --no-union --test-layout +COUNT := 1000 +TIMEOUT := 5 + +CFLAGS := -std=gnu99 + +X_COMPILER := llvm-gcc +Y_COMPILER := xcc -ccc-clang +CC := gcc + +ifeq (0, 0) +X_CFLAGS := -m32 +Y_CFLAGS := -m32 +CC_CFLAGS := -m32 +else +X_CFLAGS := -m64 +Y_CFLAGS := -m64 +CC_CFLAGS := -m64 +endif + +.PHONY: test.%.report +test.%.report: test.%.x.diff test.%.y.diff + @for t in $^; do \ + if [ -s $$t ]; then \ + echo "TEST $*: $$t failed"; \ + fi; \ + done + +.PHONY: test.%.build +test.%.build: test.%.ref test.%.x test.%.y + @true + +### + +.PRECIOUS: test.%.x.diff +test.%.x.diff: test.%.ref.out test.%.x.out + -diff $^ > $@ +.PRECIOUS: test.%.y.diff +test.%.y.diff: test.%.ref.out test.%.y.out + -diff $^ > $@ + +.PRECIOUS: test.%.out +test.%.out: test.% + -./$< > $@ + +.PRECIOUS: test.%.ref +test.%.ref: test.%.c + $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.x +test.%.x: test.%.c + $(X_COMPILER) $(CFLAGS) $(X_CFLAGS) -o $@ $^ +.PRECIOUS: test.%.y +test.%.y: test.%.c + $(Y_COMPILER) $(CFLAGS) $(Y_CFLAGS) -o $@ $^ + +.PRECIOUS: test.%.c +test.%.c: $(ABITESTGEN) + $(ABITESTGEN) $(TESTARGS) -o $@ --min=$(shell expr $* '*' $(COUNT)) --count=$(COUNT) + +clean: + rm -f test.* *~ -- GitLab From 5d1ebe90b377419fc37ae6853651c0b5881d43b0 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Wed, 28 Jan 2009 02:43:35 +0000 Subject: [PATCH 322/682] Add a preliminary version number. llvm-svn: 63168 --- clang/Driver/clang.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 8002318b6ada..51f4a5d1d830 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -1620,6 +1620,10 @@ int main(int argc, char **argv) { } } + if (Verbose) + fprintf(stderr, "clang version 1.0 based upon " PACKAGE_STRING + " hosted on " LLVM_HOSTTRIPLE "\n"); + if (unsigned NumDiagnostics = Diags.getNumDiagnostics()) fprintf(stderr, "%d diagnostic%s generated.\n", NumDiagnostics, (NumDiagnostics == 1 ? "" : "s")); -- GitLab From 172ad92b290e492bb8d66ee39c6a8ea4299568b0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 02:58:31 +0000 Subject: [PATCH 323/682] Use ZERO_EXTEND instead of ANY_EXTEND when promoting shift amounts, to avoid implicitly assuming that target architectures will ignore the high bits. llvm-svn: 63169 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 58ac8c285c95..4ee17bf807c0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -974,7 +974,7 @@ SDValue SelectionDAGLegalize::LegalizeShiftAmount(SDValue ShiftAmt) { return DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt); if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType())) - return DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), ShiftAmt); + return DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), ShiftAmt); return ShiftAmt; } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 3823f65263a1..420a8d374c68 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -114,7 +114,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_ShiftOp(SDNode *N) { if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType())) ShiftAmt = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt); else if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType())) - ShiftAmt = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), ShiftAmt); + ShiftAmt = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), ShiftAmt); return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, ShiftAmt); } -- GitLab From b3bbde3e62d04ecc868109b7873db702bdfecf1b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 03:10:52 +0000 Subject: [PATCH 324/682] Use ValueType::bitsLT to simplify some code. llvm-svn: 63170 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 2 +- llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 4ee17bf807c0..2183431e1aa8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -8515,7 +8515,7 @@ SDValue SelectionDAGLegalize::StoreWidenVectorOp(StoreSDNode *ST, // It must be true that we the widen vector type is bigger than where // we need to store. assert(StVT.isVector() && VVT.isVector()); - assert(StVT.getSizeInBits() < VVT.getSizeInBits()); + assert(StVT.bitsLT(VVT)); assert(StVT.getVectorElementType() == VVT.getVectorElementType()); // Store value diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 420a8d374c68..128dc3351e4c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -1865,7 +1865,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { // It must be true that we the widen vector type is bigger than where // we need to store. assert(StVT.isVector() && ValOp.getValueType().isVector()); - assert(StVT.getSizeInBits() < ValOp.getValueType().getSizeInBits()); + assert(StVT.bitsLT(ValOp.getValueType())); SmallVector StChain; if (ST->isTruncatingStore()) { -- GitLab From 57cf3964f3fe9872eb1f9f6d089d959646c166ab Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Wed, 28 Jan 2009 03:46:22 +0000 Subject: [PATCH 325/682] Clarify comment. llvm-svn: 63171 --- llvm/lib/Support/CommandLine.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index 8cd483a25e5d..2414734869db 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -396,7 +396,12 @@ static void ExpandResponseFiles(int argc, char** argv, // If we could open the file, parse its contents, otherwise // pass the @file option verbatim. - // TODO: support recursion. + + // TODO: we should also support recursive loading of response files, + // since this is how gcc behaves. (From their man page: "The file may + // itself contain additional @file options; any such options will be + // processed recursively.") + if (respFilePtr != 0) { ParseCStringVector(newArgv, respFilePtr->getBufferStart()); continue; -- GitLab From 2115d09a10f0b4f463d71527dd7e53e071e304a8 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Wed, 28 Jan 2009 03:47:20 +0000 Subject: [PATCH 326/682] Add three new option properties. Adds new option properties 'multi_val', 'one_or_more' and 'zero_or_one'. llvm-svn: 63172 --- llvm/include/llvm/CompilerDriver/Common.td | 5 +- llvm/test/LLVMC/ExternOptions.td | 3 +- llvm/test/LLVMC/MultiValuedOption.td | 21 +++ llvm/test/LLVMC/OneOrMore.td | 22 +++ llvm/tools/llvmc/doc/LLVMC-Reference.rst | 57 ++++--- .../TableGen/LLVMCConfigurationEmitter.cpp | 148 ++++++++++++++---- 6 files changed, 201 insertions(+), 55 deletions(-) create mode 100644 llvm/test/LLVMC/MultiValuedOption.td create mode 100644 llvm/test/LLVMC/OneOrMore.td diff --git a/llvm/include/llvm/CompilerDriver/Common.td b/llvm/include/llvm/CompilerDriver/Common.td index 097dd4f38ee9..1f6bacc787bc 100644 --- a/llvm/include/llvm/CompilerDriver/Common.td +++ b/llvm/include/llvm/CompilerDriver/Common.td @@ -36,11 +36,14 @@ def prefix_list_option; // Possible option properties. +def extern; def help; def hidden; +def multi_val; +def one_or_more; def really_hidden; def required; -def extern; +def zero_or_one; // Empty DAG marker. def empty; diff --git a/llvm/test/LLVMC/ExternOptions.td b/llvm/test/LLVMC/ExternOptions.td index 11383cb15bae..a04a88b002aa 100644 --- a/llvm/test/LLVMC/ExternOptions.td +++ b/llvm/test/LLVMC/ExternOptions.td @@ -1,6 +1,7 @@ // Check that extern options work. // The dummy tool and graph are required to silence warnings. -// RUN: tblgen -I $srcroot/include --gen-llvmc %s | grep {extern .* AutoGeneratedSwitch_Wall} +// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t +// RUN: grep {extern .* AutoGeneratedSwitch_Wall} %t include "llvm/CompilerDriver/Common.td" diff --git a/llvm/test/LLVMC/MultiValuedOption.td b/llvm/test/LLVMC/MultiValuedOption.td new file mode 100644 index 000000000000..d68a115af19d --- /dev/null +++ b/llvm/test/LLVMC/MultiValuedOption.td @@ -0,0 +1,21 @@ +// Check that multivalued options work. +// The dummy tool and graph are required to silence warnings. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t +// RUN: grep cl::multi_val(2) %t | count 1 + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[ + (prefix_list_option "foo", (multi_val 2)), + (parameter_list_option "baz", (multi_val 2), (extern))]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd"), +(in_language "dummy"), +(out_language "dummy"), +(actions (case + (not_empty "foo"), (forward_as "foo", "bar"), + (not_empty "baz"), (forward "baz"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; diff --git a/llvm/test/LLVMC/OneOrMore.td b/llvm/test/LLVMC/OneOrMore.td new file mode 100644 index 000000000000..f27ae9707d70 --- /dev/null +++ b/llvm/test/LLVMC/OneOrMore.td @@ -0,0 +1,22 @@ +// Check that (one_or_more) and (zero_or_one) properties work. +// The dummy tool and graph are required to silence warnings. +// RUN: tblgen -I $srcroot/include --gen-llvmc %s -o %t +// RUN: grep cl::ZeroOrOne %t | count 1 +// RUN: grep cl::OneOrMore %t | count 1 + +include "llvm/CompilerDriver/Common.td" + +def OptList : OptionList<[ + (prefix_list_option "foo", (one_or_more)), + (parameter_list_option "baz", (zero_or_one))]>; + +def dummy_tool : Tool<[ +(cmd_line "dummy_cmd"), +(in_language "dummy"), +(out_language "dummy"), +(actions (case + (not_empty "foo"), (forward_as "foo", "bar"), + (not_empty "baz"), (forward "baz"))) +]>; + +def DummyGraph : CompilationGraph<[SimpleEdge<"root", "dummy_tool">]>; diff --git a/llvm/tools/llvmc/doc/LLVMC-Reference.rst b/llvm/tools/llvmc/doc/LLVMC-Reference.rst index 53049d7b3c26..9aca609ca1de 100644 --- a/llvm/tools/llvmc/doc/LLVMC-Reference.rst +++ b/llvm/tools/llvmc/doc/LLVMC-Reference.rst @@ -262,37 +262,47 @@ separate option groups syntactically. * Possible option types: - - ``switch_option`` - a simple boolean switch without arguments, - for example ``-O2`` or ``-time``. + - ``switch_option`` - a simple boolean switch without arguments, for example + ``-O2`` or ``-time``. At most one occurrence is allowed. - - ``parameter_option`` - option that takes one argument, for - example ``-std=c99``. It is also allowed to use spaces instead of - the equality sign: ``-std c99``. + - ``parameter_option`` - option that takes one argument, for example + ``-std=c99``. It is also allowed to use spaces instead of the equality + sign: ``-std c99``. At most one occurrence is allowed. - - ``parameter_list_option`` - same as the above, but more than one - option occurence is allowed. + - ``parameter_list_option`` - same as the above, but more than one option + occurence is allowed. - - ``prefix_option`` - same as the parameter_option, but the option - name and argument do not have to be separated. Example: - ``-ofile``. This can be also specified as ``-o file``; however, - ``-o=file`` will be parsed incorrectly (``=file`` will be - interpreted as option value). + - ``prefix_option`` - same as the parameter_option, but the option name and + argument do not have to be separated. Example: ``-ofile``. This can be also + specified as ``-o file``; however, ``-o=file`` will be parsed incorrectly + (``=file`` will be interpreted as option value). At most one occurrence is + allowed. - - ``prefix_list_option`` - same as the above, but more than one - occurence of the option is allowed; example: ``-lm -lpthread``. + - ``prefix_list_option`` - same as the above, but more than one occurence of + the option is allowed; example: ``-lm -lpthread``. - - ``alias_option`` - a special option type for creating - aliases. Unlike other option types, aliases are not allowed to - have any properties besides the aliased option name. Usage - example: ``(alias_option "preprocess", "E")`` + - ``alias_option`` - a special option type for creating aliases. Unlike other + option types, aliases are not allowed to have any properties besides the + aliased option name. Usage example: ``(alias_option "preprocess", "E")`` * Possible option properties: - - ``help`` - help string associated with this option. Used for - ``--help`` output. + - ``help`` - help string associated with this option. Used for ``--help`` + output. + + - ``required`` - this option must be specified exactly once (or, in case of + the list options without the ``multi_val`` property, at least + once). Incompatible with ``zero_or_one`` and ``one_or_more``. - - ``required`` - this option is obligatory. + - ``one_or_more`` - the option must be specified at least one time. Useful + only for list options in conjunction with ``multi_val``; for ordinary lists + it is synonymous with ``required``. Incompatible with ``required`` and + ``zero_or_one``. + + - ``zero_or_one`` - the option can be specified zero or one times. Useful + only for list options in conjunction with ``multi_val``. Incompatible with + ``required`` and ``one_or_more``. - ``hidden`` - the description of this option will not appear in the ``--help`` output (but will appear in the ``--help-hidden`` @@ -301,6 +311,11 @@ separate option groups syntactically. - ``really_hidden`` - the option will not be mentioned in any help output. + - ``multi_val n`` - this option takes *n* arguments (can be useful in some + special cases). Usage example: ``(parameter_list_option "foo", (multi_val + 3))``. Only list options can have this attribute; you can, however, use + the ``one_or_more`` and ``zero_or_one`` properties. + - ``extern`` - this option is defined in some other plugin, see below. External options diff --git a/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp b/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp index ec023ba728a3..bd9073d55928 100644 --- a/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp +++ b/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp @@ -127,13 +127,19 @@ bool oneOf(const char* lst, char c) { return false; } +template +void checkedIncrement(I& P, I E, S ErrorString) { + ++P; + if (P == E) + throw ErrorString; +} + //===----------------------------------------------------------------------===// /// Back-end specific code /// OptionType - One of six different option types. See the /// documentation for detailed description of differences. -/// Extern* options are those that are defined in some other plugin. namespace OptionType { enum OptionType { Alias, Switch, Parameter, ParameterList, Prefix, PrefixList}; @@ -171,7 +177,8 @@ OptionType::OptionType stringToOptionType(const std::string& T) { namespace OptionDescriptionFlags { enum OptionDescriptionFlags { Required = 0x1, Hidden = 0x2, - ReallyHidden = 0x4, Extern = 0x8 }; + ReallyHidden = 0x4, Extern = 0x8, + OneOrMore = 0x10, ZeroOrOne = 0x20 }; } /// OptionDescription - Represents data contained in a single @@ -181,11 +188,12 @@ struct OptionDescription { std::string Name; unsigned Flags; std::string Help; + unsigned MultiVal; OptionDescription(OptionType::OptionType t = OptionType::Switch, const std::string& n = "", const std::string& h = DefaultHelpString) - : Type(t), Name(n), Flags(0x0), Help(h) + : Type(t), Name(n), Flags(0x0), Help(h), MultiVal(1) {} /// GenTypeDeclaration - Returns the C++ variable type of this @@ -203,17 +211,26 @@ struct OptionDescription { bool isAlias() const; + bool isMultiVal() const; + bool isExtern() const; void setExtern(); bool isRequired() const; void setRequired(); + bool isOneOrMore() const; + void setOneOrMore(); + + bool isZeroOrOne() const; + void setZeroOrOne(); + bool isHidden() const; void setHidden(); bool isReallyHidden() const; void setReallyHidden(); + }; void OptionDescription::Merge (const OptionDescription& other) @@ -235,6 +252,10 @@ bool OptionDescription::isAlias() const { return Type == OptionType::Alias; } +bool OptionDescription::isMultiVal() const { + return MultiVal == 1; +} + bool OptionDescription::isExtern() const { return Flags & OptionDescriptionFlags::Extern; } @@ -249,6 +270,20 @@ void OptionDescription::setRequired() { Flags |= OptionDescriptionFlags::Required; } +bool OptionDescription::isOneOrMore() const { + return Flags & OptionDescriptionFlags::OneOrMore; +} +void OptionDescription::setOneOrMore() { + Flags |= OptionDescriptionFlags::OneOrMore; +} + +bool OptionDescription::isZeroOrOne() const { + return Flags & OptionDescriptionFlags::ZeroOrOne; +} +void OptionDescription::setZeroOrOne() { + Flags |= OptionDescriptionFlags::ZeroOrOne; +} + bool OptionDescription::isHidden() const { return Flags & OptionDescriptionFlags::Hidden; } @@ -405,8 +440,11 @@ public: AddHandler("extern", &CollectOptionProperties::onExtern); AddHandler("help", &CollectOptionProperties::onHelp); AddHandler("hidden", &CollectOptionProperties::onHidden); + AddHandler("multi_val", &CollectOptionProperties::onMultiVal); + AddHandler("one_or_more", &CollectOptionProperties::onOneOrMore); AddHandler("really_hidden", &CollectOptionProperties::onReallyHidden); AddHandler("required", &CollectOptionProperties::onRequired); + AddHandler("zero_or_one", &CollectOptionProperties::onZeroOrOne); staticMembersInitialized_ = true; } @@ -439,9 +477,46 @@ private: void onRequired (const DagInit* d) { checkNumberOfArguments(d, 0); + if (optDesc_.isOneOrMore()) + throw std::string("An option can't have both (required) " + "and (one_or_more) properties!"); optDesc_.setRequired(); } + void onOneOrMore (const DagInit* d) { + checkNumberOfArguments(d, 0); + if (optDesc_.isRequired() || optDesc_.isZeroOrOne()) + throw std::string("Only one of (required), (zero_or_one) or " + "(one_or_more) properties is allowed!"); + if (!OptionType::IsList(optDesc_.Type)) + llvm::cerr << "Warning: specifying the 'one_or_more' property " + "on a non-list option will have no effect.\n"; + optDesc_.setOneOrMore(); + } + + void onZeroOrOne (const DagInit* d) { + checkNumberOfArguments(d, 0); + if (optDesc_.isRequired() || optDesc_.isOneOrMore()) + throw std::string("Only one of (required), (zero_or_one) or " + "(one_or_more) properties is allowed!"); + if (!OptionType::IsList(optDesc_.Type)) + llvm::cerr << "Warning: specifying the 'zero_or_one' property" + "on a non-list option will have no effect.\n"; + optDesc_.setZeroOrOne(); + } + + void onMultiVal (const DagInit* d) { + checkNumberOfArguments(d, 1); + int val = InitPtrToInt(d->getArg(0)); + if (val < 2) + throw std::string("Error in the 'multi_val' property: " + "the value must be greater than 1!"); + if (!OptionType::IsList(optDesc_.Type)) + throw std::string("The multi_val property is valid only " + "on list options!"); + optDesc_.MultiVal = val; + } + }; /// AddOption - A function object that is applied to every option @@ -639,7 +714,6 @@ private: }; - /// CollectToolDescriptions - Gather information about tool properties /// from the parsed TableGen data (basically a wrapper for the /// CollectToolProperties function object). @@ -1131,13 +1205,6 @@ void TokenizeCmdline(const std::string& CmdLine, StrVector& Out) { } } -template -void checkedIncrement(I& P, I E, S ErrorString) { - ++P; - if (P == E) - throw ErrorString; -} - /// SubstituteSpecialCommands - Perform string substitution for $CALL /// and $ENV. Helper function used by EmitCmdLineVecFill(). StrVector::const_iterator SubstituteSpecialCommands @@ -1308,18 +1375,31 @@ void EmitForwardOptionPropertyHandlingCode (const OptionDescription& D, case OptionType::PrefixList: O << Indent << "for (" << D.GenTypeDeclaration() << "::iterator B = " << D.GenVariableName() << ".begin(),\n" - << Indent << "E = " << D.GenVariableName() << ".end(); B != E; ++B)\n" + << Indent << "E = " << D.GenVariableName() << ".end(); B != E;) {\n" << Indent << Indent1 << "vec.push_back(\"" << Name << "\" + " - << "*B);\n"; + << "*B);\n" + << Indent << Indent1 << "++B;\n"; + + for (int i = 1, j = D.MultiVal; i < j; ++i) { + O << Indent << Indent1 << "vec.push_back(*B);\n" + << Indent << Indent1 << "++B;\n"; + } + + O << Indent << "}\n"; break; case OptionType::ParameterList: O << Indent << "for (" << D.GenTypeDeclaration() << "::iterator B = " << D.GenVariableName() << ".begin(),\n" << Indent << "E = " << D.GenVariableName() - << ".end() ; B != E; ++B) {\n" - << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n" - << Indent << Indent1 << "vec.push_back(*B);\n" - << Indent << "}\n"; + << ".end() ; B != E;) {\n" + << Indent << Indent1 << "vec.push_back(\"" << Name << "\");\n"; + + for (int i = 0, j = D.MultiVal; i < j; ++i) { + O << Indent << Indent1 << "vec.push_back(*B);\n" + << Indent << Indent1 << "++B;\n"; + } + + O << Indent << "}\n"; break; case OptionType::Alias: default: @@ -1376,6 +1456,9 @@ class EmitActionHandler { const std::string& Name = InitPtrToString(Dag.getArg(0)); const OptionDescription& D = OptDescs.FindOption(Name); + if (D.isMultiVal()) + throw std::string("Can't use unpack_values with multi-valued options!"); + if (OptionType::IsList(D.Type)) { O << IndentLevel << "for (" << D.GenTypeDeclaration() << "::iterator B = " << D.GenVariableName() << ".begin(),\n" @@ -1599,27 +1682,28 @@ void EmitOptionDefintions (const OptionDescriptions& descs, O << ", cl::Prefix"; if (val.isRequired()) { - switch (val.Type) { - case OptionType::PrefixList: - case OptionType::ParameterList: + if (OptionType::IsList(val.Type) && !val.isMultiVal()) O << ", cl::OneOrMore"; - break; - default: + else O << ", cl::Required"; - } + } + else if (val.isOneOrMore() && OptionType::IsList(val.Type)) { + O << ", cl::OneOrMore"; + } + else if (val.isZeroOrOne() && OptionType::IsList(val.Type)) { + O << ", cl::ZeroOrOne"; } - if (val.isReallyHidden() || val.isHidden()) { - if (val.isRequired()) - O << " |"; - else - O << ","; - if (val.isReallyHidden()) - O << " cl::ReallyHidden"; - else - O << " cl::Hidden"; + if (val.isReallyHidden()) { + O << ", cl::ReallyHidden"; + } + else if (val.isHidden()) { + O << ", cl::Hidden"; } + if (val.MultiVal > 1) + O << ", cl::multi_val(" << val.MultiVal << ")"; + if (!val.Help.empty()) O << ", cl::desc(\"" << val.Help << "\")"; -- GitLab From 84172f7dca98a663636530c4c8b9055424389bc8 Mon Sep 17 00:00:00 2001 From: Mikhail Glushenkov Date: Wed, 28 Jan 2009 03:47:38 +0000 Subject: [PATCH 327/682] Update the generated docs. llvm-svn: 63173 --- llvm/docs/CompilerDriver.html | 73 +++++++++++++++++++++-------------- 1 file changed, 45 insertions(+), 28 deletions(-) diff --git a/llvm/docs/CompilerDriver.html b/llvm/docs/CompilerDriver.html index 977bd470c682..fc687f166751 100644 --- a/llvm/docs/CompilerDriver.html +++ b/llvm/docs/CompilerDriver.html @@ -263,38 +263,50 @@ separate option groups syntactically.

  • Possible option types:

      -
    • switch_option - a simple boolean switch without arguments, -for example -O2 or -time.
    • -
    • parameter_option - option that takes one argument, for -example -std=c99. It is also allowed to use spaces instead of -the equality sign: -std c99.
    • -
    • parameter_list_option - same as the above, but more than one -option occurence is allowed.
    • -
    • prefix_option - same as the parameter_option, but the option -name and argument do not have to be separated. Example: --ofile. This can be also specified as -o file; however, --o=file will be parsed incorrectly (=file will be -interpreted as option value).
    • -
    • prefix_list_option - same as the above, but more than one -occurence of the option is allowed; example: -lm -lpthread.
    • -
    • alias_option - a special option type for creating -aliases. Unlike other option types, aliases are not allowed to -have any properties besides the aliased option name. Usage -example: (alias_option "preprocess", "E")
    • +
    • switch_option - a simple boolean switch without arguments, for example +-O2 or -time. At most one occurrence is allowed.
    • +
    • parameter_option - option that takes one argument, for example +-std=c99. It is also allowed to use spaces instead of the equality +sign: -std c99. At most one occurrence is allowed.
    • +
    • parameter_list_option - same as the above, but more than one option +occurence is allowed.
    • +
    • prefix_option - same as the parameter_option, but the option name and +argument do not have to be separated. Example: -ofile. This can be also +specified as -o file; however, -o=file will be parsed incorrectly +(=file will be interpreted as option value). At most one occurrence is +allowed.
    • +
    • prefix_list_option - same as the above, but more than one occurence of +the option is allowed; example: -lm -lpthread.
    • +
    • alias_option - a special option type for creating aliases. Unlike other +option types, aliases are not allowed to have any properties besides the +aliased option name. Usage example: (alias_option "preprocess", "E")
  • Possible option properties:

      -
    • help - help string associated with this option. Used for ---help output.
    • -
    • required - this option is obligatory.
    • +
    • help - help string associated with this option. Used for --help +output.
    • +
    • required - this option must be specified exactly once (or, in case of +the list options without the multi_val property, at least +once). Incompatible with zero_or_one and one_or_more.
    • +
    • one_or_more - the option must be specified at least one time. Useful +only for list options in conjunction with multi_val; for ordinary lists +it is synonymous with required. Incompatible with required and +zero_or_one.
    • +
    • zero_or_one - the option can be specified zero or one times. Useful +only for list options in conjunction with multi_val. Incompatible with +required and one_or_more.
    • hidden - the description of this option will not appear in the --help output (but will appear in the --help-hidden output).
    • really_hidden - the option will not be mentioned in any help output.
    • +
    • multi_val n - this option takes n arguments (can be useful in some +special cases). Usage example: (parameter_list_option "foo", (multi_val +3)). Only list options can have this attribute; you can, however, use +the one_or_more and zero_or_one properties.
    • extern - this option is defined in some other plugin, see below.
    @@ -526,16 +538,21 @@ output languages should match. This is enforced at compile-time.

    Hooks and environment variables

    Normally, LLVMC executes programs from the system PATH. Sometimes, -this is not sufficient: for example, we may want to specify tool names -in the configuration file. This can be achieved via the mechanism of -hooks - to write your own hooks, just add their definitions to the -PluginMain.cpp or drop a .cpp file into the -$LLVMC_DIR/driver directory. Hooks should live in the hooks -namespace and have the signature std::string hooks::MyHookName -(void). They can be used from the cmd_line tool property:

    +this is not sufficient: for example, we may want to specify tool paths +or names in the configuration file. This can be easily achieved via +the hooks mechanism. To write your own hooks, just add their +definitions to the PluginMain.cpp or drop a .cpp file into the +your plugin directory. Hooks should live in the hooks namespace +and have the signature std::string hooks::MyHookName ([const char* +Arg0 [ const char* Arg2 [, ...]]]). They can be used from the +cmd_line tool property:

     (cmd_line "$CALL(MyHook)/path/to/file -o $CALL(AnotherHook)")
     
    +

    To pass arguments to hooks, use the following syntax:

    +
    +(cmd_line "$CALL(MyHook, 'Arg1', 'Arg2', 'Arg # 3')/path/to/file -o1 -o2")
    +

    It is also possible to use environment variables in the same manner:

     (cmd_line "$ENV(VAR1)/path/to/file -o $ENV(VAR2)")
    -- 
    GitLab
    
    
    From 02b47b5e7a1a7940182b81b21af173cb4a117dec Mon Sep 17 00:00:00 2001
    From: Mikhail Glushenkov 
    Date: Wed, 28 Jan 2009 03:47:58 +0000
    Subject: [PATCH 328/682] Typo.
    
    llvm-svn: 63174
    ---
     llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp b/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp
    index bd9073d55928..fc166ef30934 100644
    --- a/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp
    +++ b/llvm/utils/TableGen/LLVMCConfigurationEmitter.cpp
    @@ -253,7 +253,7 @@ bool OptionDescription::isAlias() const {
     }
     
     bool OptionDescription::isMultiVal() const {
    -  return MultiVal == 1;
    +  return MultiVal > 1;
     }
     
     bool OptionDescription::isExtern() const {
    -- 
    GitLab
    
    
    From 062115af595b7605447a9be6f96ef2a2b50d6f71 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 04:29:29 +0000
    Subject: [PATCH 329/682] Patch by Alexei Svitkine: Refactor Sema::ParseAST API
     to allow clients to pass as an argument a TranslationUnit object whose
     contents live beyond the call to ParseAST.
    
    llvm-svn: 63175
    ---
     clang/Driver/clang.cpp              | 17 +++++++++---
     clang/include/clang/Sema/ParseAST.h | 11 +++++---
     clang/lib/Sema/ParseAST.cpp         | 40 ++++++++++++++++-------------
     3 files changed, 43 insertions(+), 25 deletions(-)
    
    diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
    index 51f4a5d1d830..bc548e4e8b84 100644
    --- a/clang/Driver/clang.cpp
    +++ b/clang/Driver/clang.cpp
    @@ -1418,9 +1418,20 @@ static void ProcessInputFile(Preprocessor &PP, PreprocessorFactory &PPF,
         ClearSourceMgr = true;
         break;
       }
    -  
    -  if (Consumer)
    -    ParseAST(PP, Consumer.get(), Stats, !DisableFree);
    +
    +  if (Consumer) {
    +    TranslationUnit *TU = 0;
    +    if (DisableFree) {
    +      ASTContext *Context = new ASTContext(PP.getLangOptions(),
    +                                           PP.getSourceManager(),
    +                                           PP.getTargetInfo(),
    +                                           PP.getIdentifierTable(),
    +                                           PP.getSelectorTable(),
    +                                           /* FreeMemory = */ false);
    +      TU = new TranslationUnit(*Context);
    +    }
    +    ParseAST(PP, Consumer.get(), TU, Stats);
    +  }
     
       if (VerifyDiagnostics)
         if (CheckDiagnostics(PP))
    diff --git a/clang/include/clang/Sema/ParseAST.h b/clang/include/clang/Sema/ParseAST.h
    index 91d7f1aa36b6..b18e5a672959 100644
    --- a/clang/include/clang/Sema/ParseAST.h
    +++ b/clang/include/clang/Sema/ParseAST.h
    @@ -17,14 +17,17 @@
     namespace clang {
       class Preprocessor;
       class ASTConsumer;
    -  
    +  class TranslationUnit;
    +
       /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
       /// the file is parsed.
       ///
    -  /// \param FreeMemory If false, the memory used for AST elements is
    -  /// not released.
    +  /// \param TU If 0, then memory used for AST elements will be allocated only
    +  /// for the duration of the ParseAST() call. In this case, the client should
    +  /// not access any AST elements after ParseAST() returns.
       void ParseAST(Preprocessor &pp, ASTConsumer *C, 
    -                bool PrintStats = false, bool FreeMemory = true);
    +                TranslationUnit *TU = 0,
    +                bool PrintStats = false);
     
     }  // end namespace clang
     
    diff --git a/clang/lib/Sema/ParseAST.cpp b/clang/lib/Sema/ParseAST.cpp
    index 67af28531501..6923476aeba0 100644
    --- a/clang/lib/Sema/ParseAST.cpp
    +++ b/clang/lib/Sema/ParseAST.cpp
    @@ -11,6 +11,7 @@
     //
     //===----------------------------------------------------------------------===//
     
    +#include 
     #include "clang/Sema/ParseAST.h"
     #include "clang/AST/ASTConsumer.h"
     #include "clang/AST/Stmt.h"
    @@ -26,23 +27,31 @@ using namespace clang;
     /// ParseAST - Parse the entire file specified, notifying the ASTConsumer as
     /// the file is parsed.
     ///
    -/// \param FreeMemory If false, the memory used for AST elements is
    -/// not released.
    -void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer, 
    -                     bool PrintStats, bool FreeMemory) {
    +/// \param TU If 0, then memory used for AST elements will be allocated only
    +/// for the duration of the ParseAST() call. In this case, the client should
    +/// not access any AST elements after ParseAST() returns.
    +void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
    +                     TranslationUnit *TU, bool PrintStats) {
       // Collect global stats on Decls/Stmts (until we have a module streamer).
       if (PrintStats) {
         Decl::CollectingStats(true);
         Stmt::CollectingStats(true);
       }
    -  
    -  ASTContext *Context = 
    -    new ASTContext(PP.getLangOptions(), PP.getSourceManager(),
    -                   PP.getTargetInfo(),
    -                   PP.getIdentifierTable(), PP.getSelectorTable(),
    -                   FreeMemory);
    -  TranslationUnit *TU = new TranslationUnit(*Context);
    -  Sema S(PP, *Context, *Consumer);
    +
    +  llvm::OwningPtr ContextOwner;
    +  llvm::OwningPtr TranslationUnitOwner;
    +  if (TU == 0) {
    +    ASTContext *Context = new ASTContext(PP.getLangOptions(),
    +                                         PP.getSourceManager(),
    +                                         PP.getTargetInfo(),
    +                                         PP.getIdentifierTable(),
    +                                         PP.getSelectorTable());
    +    ContextOwner.reset(Context);
    +    TU = new TranslationUnit(*Context);
    +    TranslationUnitOwner.reset(TU);
    +  }
    +
    +  Sema S(PP, TU->getContext(), *Consumer);
       Parser P(PP, S);
       PP.EnterMainSourceFile();
         
    @@ -68,7 +77,7 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
       if (PrintStats) {
         fprintf(stderr, "\nSTATISTICS:\n");
         P.getActions().PrintStats();
    -    Context->PrintStats();
    +    TU->getContext().PrintStats();
         Decl::PrintStats();
         Stmt::PrintStats();
         Consumer->PrintStats();
    @@ -76,9 +85,4 @@ void clang::ParseAST(Preprocessor &PP, ASTConsumer *Consumer,
         Decl::CollectingStats(false);
         Stmt::CollectingStats(false);
       }
    -
    -  if (FreeMemory) {
    -    delete TU;
    -    delete Context;      
    -  }
     }
    -- 
    GitLab
    
    
    From 99ae4120d69e2e895aed8db1eb213679acb3c325 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 04:37:52 +0000
    Subject: [PATCH 330/682] Remove '#if 0' code.
    
    llvm-svn: 63176
    ---
     clang/lib/Analysis/CFRefCount.cpp | 5 -----
     1 file changed, 5 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index bfc9d9058b3c..0f2208bd89bd 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -1524,10 +1524,6 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
             }
         }  
         else if (isa(V)) {
    -#if 0
    -      // Nuke all arguments passed by reference.
    -      StateMgr.Unbind(StVals, cast(V));
    -#else
           if (loc::MemRegionVal* MR = dyn_cast(&V)) {
     
             if (GetArgE(Summ, idx) == DoNothingByRef)
    @@ -1588,7 +1584,6 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
             // Nuke all other arguments passed by reference.
             state = state.Unbind(cast(V));
           }
    -#endif
         }
         else if (isa(V))
           state = state.Unbind(cast(V).getLoc());
    -- 
    GitLab
    
    
    From 424c61ff6d580134702f5dd57740e58dcaab3669 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 04:47:13 +0000
    Subject: [PATCH 331/682] Refactor some diagnostic code to use
     raw_string_ostream.  No functionality change.
    
    llvm-svn: 63177
    ---
     clang/lib/Analysis/CFRefCount.cpp | 37 ++++++++++++++-----------------
     1 file changed, 17 insertions(+), 20 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index 0f2208bd89bd..89169fa2187d 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2323,39 +2323,41 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
       if (!CurrT)
         return NULL;  
       
    -  const char* Msg = NULL;  
       const RefVal& CurrV = *CurrB.lookup(Sym);
     
       if (!PrevT) {
    +    std::string sbuf;
    +    llvm::raw_string_ostream os(sbuf);
         
         Stmt* S = cast(N->getLocation()).getStmt();
     
         if (CurrV.isOwned()) {
     
    -      if (isa(S))
    -        Msg = "Function call returns an object with a +1 retain count"
    -              " (owning reference).";
    +      if (isa(S)) {
    +        os <<  "Function call returns an object with a +1 retain count"
    +                " (owning reference).";
    +      }
           else {
             assert (isa(S));
    -        Msg = "Method returns an object with a +1 retain count"
    -              " (owning reference).";
    +        os << "Method returns an object with a +1 retain count"
    +                " (owning reference).";
           }
         }
         else {
           assert (CurrV.isNotOwned());
           
           if (isa(S))
    -        Msg = "Function call returns an object with a +0 retain count"
    +        os << "Function call returns an object with a +0 retain count"
                   " (non-owning reference).";
           else {
             assert (isa(S));
    -        Msg = "Method returns an object with a +0 retain count"
    +        os << "Method returns an object with a +0 retain count"
                   " (non-owning reference).";
           }      
         }
         
         FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager());
    -    PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, Msg);
    +    PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str());
         
         if (Expr* Exp = dyn_cast(S))
           P->addRange(Exp->getSourceRange());
    @@ -2370,9 +2372,8 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
         return NULL;
       
       // The typestate has changed.
    -  
    -  std::ostringstream os;
    -  std::string s;
    +  std::string sbuf;
    +  llvm::raw_string_ostream os(sbuf);
       
       switch (CurrV.getKind()) {
         case RefVal::Owned:
    @@ -2387,7 +2388,6 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
             os << "Reference count incremented.";
           
           if (unsigned Count = CurrV.getCount()) {
    -
             os << " Object has +" << Count;
             
             if (Count > 1)
    @@ -2396,22 +2396,19 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
               os << " retain count.";
           }
           
    -      s = os.str();
    -      Msg = s.c_str();
    -      
           break;
           
         case RefVal::Released:
    -      Msg = "Object released.";
    +      os << "Object released.";
           break;
           
         case RefVal::ReturnedOwned:
    -      Msg = "Object returned to caller as an owning reference (single retain "
    +      os << "Object returned to caller as an owning reference (single retain "
                 "count transferred to caller).";
           break;
           
         case RefVal::ReturnedNotOwned:
    -      Msg = "Object returned to caller with a +0 (non-owning) retain count.";
    +      os << "Object returned to caller with a +0 (non-owning) retain count.";
           break;
     
         default:
    @@ -2420,7 +2417,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
       
       Stmt* S = cast(N->getLocation()).getStmt();    
       FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager());
    -  PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, Msg);
    +  PathDiagnosticPiece* P = new PathDiagnosticPiece(Pos, os.str());
       
       // Add the range by scanning the children of the statement for any bindings
       // to Sym.
    -- 
    GitLab
    
    
    From c4118ac79cad1d2ab9b13db7d11d571a33ed89b9 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 05:06:46 +0000
    Subject: [PATCH 332/682] retain/release checker: Output the name of the
     function that allocates an object.
    
    llvm-svn: 63178
    ---
     clang/lib/Analysis/CFRefCount.cpp | 29 +++++++++++++++--------------
     1 file changed, 15 insertions(+), 14 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index 89169fa2187d..d3cf89caa472 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2312,10 +2312,10 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
       // Check if the type state has changed.
       
       const GRState* PrevSt = PrevN->getState();
    -  const GRState* CurrSt = N->getState();
    -  
    +  GRStateRef CurrSt(N->getState(), cast(BR).getStateManager());
    +
       RefBindings PrevB = PrevSt->get();
    -  RefBindings CurrB = CurrSt->get();
    +  RefBindings CurrB = CurrSt.get();
       
       const RefVal* PrevT = PrevB.lookup(Sym);
       const RefVal* CurrT = CurrB.lookup(Sym);
    @@ -2332,10 +2332,17 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
         Stmt* S = cast(N->getLocation()).getStmt();
     
         if (CurrV.isOwned()) {
    +      if (CallExpr *CE = dyn_cast(S)) {
    +        // Get the name of the callee (if it is available).
    +        SVal X = CurrSt.GetSVal(CE->getCallee());
     
    -      if (isa(S)) {
    -        os <<  "Function call returns an object with a +1 retain count"
    -                " (owning reference).";
    +        if (loc::FuncVal* FV = dyn_cast(&X))
    +          os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\'';
    +        else
    +          os << "Function call";
    +        
    +        os << " returns an object with a +1 retain count"
    +              " (owning reference).";
           }
           else {
             assert (isa(S));
    @@ -2421,17 +2428,11 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
       
       // Add the range by scanning the children of the statement for any bindings
       // to Sym.
    -  
    -  GRStateManager& VSM = cast(BR).getStateManager();
    -  
       for (Stmt::child_iterator I = S->child_begin(), E = S->child_end(); I!=E; ++I)
         if (Expr* Exp = dyn_cast_or_null(*I)) {
    -      SVal X = VSM.GetSVal(CurrSt, Exp);
    -      
    +      SVal X = CurrSt.GetSVal(Exp);      
           if (loc::SymbolVal* SV = dyn_cast(&X))
    -        if (SV->getSymbol() == Sym) {
    -          P->addRange(Exp->getSourceRange()); break;
    -        }
    +        if (SV->getSymbol() == Sym) P->addRange(Exp->getSourceRange()); break;
         }
       
       return P;
    -- 
    GitLab
    
    
    From 758fda632b55366670af6b759cd78fcdd3f1994d Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 05:15:02 +0000
    Subject: [PATCH 333/682] retain/release checker: More diagnostic refactoring.
    
    llvm-svn: 63179
    ---
     clang/lib/Analysis/CFRefCount.cpp | 42 +++++++++++--------------------
     1 file changed, 15 insertions(+), 27 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index d3cf89caa472..a042b909e1a7 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2331,36 +2331,24 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
         
         Stmt* S = cast(N->getLocation()).getStmt();
     
    -    if (CurrV.isOwned()) {
    -      if (CallExpr *CE = dyn_cast(S)) {
    -        // Get the name of the callee (if it is available).
    -        SVal X = CurrSt.GetSVal(CE->getCallee());
    -
    -        if (loc::FuncVal* FV = dyn_cast(&X))
    -          os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\'';
    -        else
    -          os << "Function call";
    -        
    -        os << " returns an object with a +1 retain count"
    -              " (owning reference).";
    -      }
    -      else {
    -        assert (isa(S));
    -        os << "Method returns an object with a +1 retain count"
    -                " (owning reference).";
    -      }
    +    if (CallExpr *CE = dyn_cast(S)) {
    +      // Get the name of the callee (if it is available).
    +      SVal X = CurrSt.GetSVal(CE->getCallee());        
    +      if (loc::FuncVal* FV = dyn_cast(&X))
    +        os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\'';
    +      else
    +        os << "function call";
    +    }          
    +    else {
    +      assert (isa(S));
    +      os << "Method returns an object with a ";
         }
    +    
    +    if (CurrV.isOwned())
    +        os << "+1 retain count (owning reference).";
         else {
           assert (CurrV.isNotOwned());
    -      
    -      if (isa(S))
    -        os << "Function call returns an object with a +0 retain count"
    -              " (non-owning reference).";
    -      else {
    -        assert (isa(S));
    -        os << "Method returns an object with a +0 retain count"
    -              " (non-owning reference).";
    -      }      
    +      os << "+0 retain count (non-owning reference).";
         }
         
         FullSourceLoc Pos(S->getLocStart(), BR.getContext().getSourceManager());
    -- 
    GitLab
    
    
    From ff3c2bdfeef96193e3923fe8b7452cca3d5890b6 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 05:18:08 +0000
    Subject: [PATCH 334/682] Fix diagnostic truncated by my last patch.
    
    llvm-svn: 63180
    ---
     clang/lib/Analysis/CFRefCount.cpp | 2 ++
     1 file changed, 2 insertions(+)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index a042b909e1a7..bbbe7646fd86 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2338,6 +2338,8 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
             os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\'';
           else
             os << "function call";
    +      
    +      os << " returns an object with a ";
         }          
         else {
           assert (isa(S));
    -- 
    GitLab
    
    
    From 21114f21c4ac8c06a0aaad05f2e47f068610febc Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 05:29:13 +0000
    Subject: [PATCH 335/682] retain/release checker: More cleanups (no real
     functionality change).
    
    llvm-svn: 63181
    ---
     clang/lib/Analysis/CFRefCount.cpp | 25 ++++++++++---------------
     1 file changed, 10 insertions(+), 15 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index bbbe7646fd86..4e6544c98eea 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2309,21 +2309,16 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
                                                 const ExplodedGraph& G,
                                                 BugReporter& BR) {
     
    -  // Check if the type state has changed.
    -  
    -  const GRState* PrevSt = PrevN->getState();
    -  GRStateRef CurrSt(N->getState(), cast(BR).getStateManager());
    +  // Check if the type state has changed.  
    +  GRStateManager &StMgr = cast(BR).getStateManager();
    +  GRStateRef PrevSt(PrevN->getState(), StMgr);
    +  GRStateRef CurrSt(N->getState(), StMgr);
     
    -  RefBindings PrevB = PrevSt->get();
    -  RefBindings CurrB = CurrSt.get();
    -  
    -  const RefVal* PrevT = PrevB.lookup(Sym);
    -  const RefVal* CurrT = CurrB.lookup(Sym);
    -  
    -  if (!CurrT)
    -    return NULL;  
    -  
    -  const RefVal& CurrV = *CurrB.lookup(Sym);
    +  const RefVal* CurrT = CurrSt.get(Sym);  
    +  if (!CurrT) return NULL;
    +
    +  const RefVal& CurrV = *CurrT;
    +  const RefVal* PrevT = PrevSt.get(Sym);
     
       if (!PrevT) {
         std::string sbuf;
    @@ -2363,7 +2358,7 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
       }
       
       // Determine if the typestate has changed.  
    -  RefVal PrevV = *PrevB.lookup(Sym);
    +  RefVal PrevV = *PrevT;
       
       if (PrevV == CurrV)
         return NULL;
    -- 
    GitLab
    
    
    From 64d8fc25d6d10df2c23131882da018c201f19c49 Mon Sep 17 00:00:00 2001
    From: Chris Lattner 
    Date: Wed, 28 Jan 2009 05:42:38 +0000
    Subject: [PATCH 336/682] fix a crash I introduced, thanks to Ted for the
     awesome reduced testcase :)
    
    llvm-svn: 63182
    ---
     clang/Driver/DependencyFile.cpp    | 7 +++++--
     clang/test/Driver/dependency-gen.c | 5 +++++
     2 files changed, 10 insertions(+), 2 deletions(-)
     create mode 100644 clang/test/Driver/dependency-gen.c
    
    diff --git a/clang/Driver/DependencyFile.cpp b/clang/Driver/DependencyFile.cpp
    index 0d4ee91f01bb..673ca0734a18 100644
    --- a/clang/Driver/DependencyFile.cpp
    +++ b/clang/Driver/DependencyFile.cpp
    @@ -174,8 +174,11 @@ void DependencyFileCallback::FileChanged(SourceLocation Loc,
       // #line markers to affect dependency generation!
       SourceManager &SM = PP->getSourceManager();
       
    -  FileID FID = SM.getFileID(SM.getInstantiationLoc(Loc));
    -  const char *Filename = SM.getFileEntryForID(FID)->getName();
    +  const FileEntry *FE =
    +    SM.getFileEntryForID(SM.getFileID(SM.getInstantiationLoc(Loc)));
    +  if (FE == 0) return;
    +  
    +  const char *Filename = FE->getName();
       if (!FileMatchesDepCriteria(Filename, FileType))
         return;
     
    diff --git a/clang/test/Driver/dependency-gen.c b/clang/test/Driver/dependency-gen.c
    new file mode 100644
    index 000000000000..ad9029f9f147
    --- /dev/null
    +++ b/clang/test/Driver/dependency-gen.c
    @@ -0,0 +1,5 @@
    +
    +// rdar://6533411
    +// RUN: clang -MD -MF /tmp/null.d -x c /dev/null
    +
    +
    -- 
    GitLab
    
    
    From aeb115f93a6e582dc9cb615bbd0263e21309401d Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 05:56:51 +0000
    Subject: [PATCH 337/682] retain/release checker: Embed an "object type" into
     the RetEffect/RetVal objects to help distinguish between Objective-C and Core
     Foundation objects (for better diagnostics).
    
    llvm-svn: 63183
    ---
     clang/lib/Analysis/CFRefCount.cpp | 95 +++++++++++++++++--------------
     1 file changed, 53 insertions(+), 42 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index 4e6544c98eea..61c1f1835b05 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -158,18 +158,25 @@ class VISIBILITY_HIDDEN RetEffect {
     public:
       enum Kind { NoRet, Alias, OwnedSymbol, OwnedAllocatedSymbol,
                   NotOwnedSymbol, ReceiverAlias };
    -  
    +    
    +  enum ObjKind { CF, ObjC, AnyObj };  
    +
     private:
    -  unsigned Data;
    -  RetEffect(Kind k, unsigned D = 0) { Data = (D << 3) | (unsigned) k; }
    +  Kind K;
    +  ObjKind O;
    +  unsigned index;
    +
    +  RetEffect(Kind k, unsigned idx = 0) : K(k), O(AnyObj), index(idx) {}
    +  RetEffect(Kind k, ObjKind o) : K(k), O(o), index(0) {}
       
     public:
    -  
    -  Kind getKind() const { return (Kind) (Data & 0x7); }
    +  Kind getKind() const { return K; }
    +
    +  ObjKind getObjKind() const { return O; }
       
       unsigned getIndex() const { 
         assert(getKind() == Alias);
    -    return Data >> 3;
    +    return index;
       }
       
       static RetEffect MakeAlias(unsigned Idx) {
    @@ -178,22 +185,20 @@ public:
       static RetEffect MakeReceiverAlias() {
         return RetEffect(ReceiverAlias);
       }  
    -  static RetEffect MakeOwned(bool isAllocated = false) {
    -    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol);
    +  static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
    +    return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
       }  
    -  static RetEffect MakeNotOwned() {
    -    return RetEffect(NotOwnedSymbol);
    +  static RetEffect MakeNotOwned(ObjKind o) {
    +    return RetEffect(NotOwnedSymbol, o);
       }  
       static RetEffect MakeNoRet() {
         return RetEffect(NoRet);
       }
       
    -  operator Kind() const {
    -    return getKind();
    -  }  
    -  
       void Profile(llvm::FoldingSetNodeID& ID) const {
    -    ID.AddInteger(Data);
    +    ID.AddInteger((unsigned)K);
    +    ID.AddInteger((unsigned)O);
    +    ID.AddInteger(index);
       }
     };
       
    @@ -879,12 +884,13 @@ RetainSummary* RetainSummaryManager::getCFSummaryCreateRule(FunctionDecl* FD) {
         ScratchArgs.push_back(std::make_pair(2, DoNothingByRef));
       }
       
    -  return getPersistentSummary(RetEffect::MakeOwned(true));
    +  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF, true));
     }
     
     RetainSummary* RetainSummaryManager::getCFSummaryGetRule(FunctionDecl* FD) {
       assert (ScratchArgs.empty());  
    -  return getPersistentSummary(RetEffect::MakeNotOwned(), DoNothing, DoNothing);
    +  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),
    +                              DoNothing, DoNothing);
     }
     
     //===----------------------------------------------------------------------===//
    @@ -928,7 +934,7 @@ RetainSummaryManager::getMethodSummary(ObjCMessageExpr* ME,
     
       if (followsFundamentalRule(s)) {    
         RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
    -                                : RetEffect::MakeOwned(true);
    +                                : RetEffect::MakeOwned(RetEffect::ObjC, true);
         RetainSummary* Summ = getPersistentSummary(E);
         ObjCMethodSummaries[ME] = Summ;
         return Summ;
    @@ -959,7 +965,7 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
       assert (ScratchArgs.empty());
       
       RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
    -                              : RetEffect::MakeOwned(true);  
    +                              : RetEffect::MakeOwned(RetEffect::ObjC, true);  
       
       RetainSummary* Summ = getPersistentSummary(E);
       
    @@ -971,8 +977,8 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
       
       // Create the [NSAssertionHandler currentHander] summary.  
       addClsMethSummary(&Ctx.Idents.get("NSAssertionHandler"),
    -                    GetNullarySelector("currentHandler", Ctx),
    -                    getPersistentSummary(RetEffect::MakeNotOwned()));
    +                GetNullarySelector("currentHandler", Ctx),
    +                getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
       
       // Create the [NSAutoreleasePool addObject:] summary.
       if (!isGCEnabled()) {    
    @@ -995,7 +1001,7 @@ void RetainSummaryManager::InitializeMethodSummaries() {
       
       // The next methods are allocators.
       RetEffect E = isGCEnabled() ? RetEffect::MakeNoRet()
    -                              : RetEffect::MakeOwned(true);
    +                              : RetEffect::MakeOwned(RetEffect::ObjC, true);
       
       RetainSummary* Summ = getPersistentSummary(E);  
       
    @@ -1056,7 +1062,6 @@ namespace {
       
     class VISIBILITY_HIDDEN RefVal {
     public:  
    -  
       enum Kind {
         Owned = 0, // Owning reference.    
         NotOwned,  // Reference is not owned by still valid (not freed).    
    @@ -1069,19 +1074,23 @@ public:
         ErrorLeakReturned // A memory leak due to the returning method not having
                           // the correct naming conventions.            
       };
    -  
    -private:
    -  
    +
    +private:  
       Kind kind;
    +  RetEffect::ObjKind okind;
       unsigned Cnt;
       QualType T;
     
    -  RefVal(Kind k, unsigned cnt, QualType t) : kind(k), Cnt(cnt), T(t) {}
    -  RefVal(Kind k, unsigned cnt = 0) : kind(k), Cnt(cnt) {}
    +  RefVal(Kind k, RetEffect::ObjKind o, unsigned cnt, QualType t)
    +    : kind(k), okind(o), Cnt(cnt), T(t) {}
     
    -public:  
    -  
    +  RefVal(Kind k, unsigned cnt = 0)
    +    : kind(k), okind(RetEffect::AnyObj), Cnt(cnt) {}
    +
    +public:    
       Kind getKind() const { return kind; }
    +  
    +  RetEffect::ObjKind getObjKind() const { return okind; }
     
       unsigned getCount() const { return Cnt; }  
       QualType getType() const { return T; }
    @@ -1115,12 +1124,14 @@ public:
       
       // State creation: normal state.
       
    -  static RefVal makeOwned(QualType t, unsigned Count = 1) {
    -    return RefVal(Owned, Count, t);
    +  static RefVal makeOwned(RetEffect::ObjKind o, QualType t,
    +                          unsigned Count = 1) {
    +    return RefVal(Owned, o, Count, t);
       }
       
    -  static RefVal makeNotOwned(QualType t, unsigned Count = 0) {
    -    return RefVal(NotOwned, Count, t);
    +  static RefVal makeNotOwned(RetEffect::ObjKind o, QualType t,
    +                             unsigned Count = 0) {
    +    return RefVal(NotOwned, o, Count, t);
       }
     
       static RefVal makeReturnedOwned(unsigned Count) {
    @@ -1138,17 +1149,16 @@ public:
       }
       
       RefVal operator-(size_t i) const {
    -    return RefVal(getKind(), getCount() - i, getType());
    +    return RefVal(getKind(), getObjKind(), getCount() - i, getType());
       }
       
       RefVal operator+(size_t i) const {
    -    return RefVal(getKind(), getCount() + i, getType());
    +    return RefVal(getKind(), getObjKind(), getCount() + i, getType());
       }
       
       RefVal operator^(Kind k) const {
    -    return RefVal(k, getCount(), getType());
    +    return RefVal(k, getObjKind(), getCount(), getType());
       }
    -    
       
       void Profile(llvm::FoldingSetNodeID& ID) const {
         ID.AddInteger((unsigned) kind);
    @@ -1661,9 +1671,9 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
         case RetEffect::OwnedSymbol: {
           unsigned Count = Builder.getCurrentBlockCount();
           SymbolRef Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
    -      QualType RetT = GetReturnType(Ex, Eng.getContext());
    -      
    -      state = state.set(Sym, RefVal::makeOwned(RetT));
    +      QualType RetT = GetReturnType(Ex, Eng.getContext());      
    +      state =
    +        state.set(Sym, RefVal::makeOwned(RE.getObjKind(), RetT));      
           state = state.BindExpr(Ex, loc::SymbolVal(Sym), false);
     
     #if 0
    @@ -1683,7 +1693,8 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
           SymbolRef Sym = Eng.getSymbolManager().getConjuredSymbol(Ex, Count);
           QualType RetT = GetReturnType(Ex, Eng.getContext());
           
    -      state = state.set(Sym, RefVal::makeNotOwned(RetT));
    +      state =
    +        state.set(Sym, RefVal::makeNotOwned(RE.getObjKind(),RetT));
           state = state.BindExpr(Ex, loc::SymbolVal(Sym), false);
           break;
         }
    -- 
    GitLab
    
    
    From bdaa384453c5b1b4470b99da96c25cddfb1cda88 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 06:01:42 +0000
    Subject: [PATCH 338/682] retain/release checker: More diagnostic refactoring.
    
    llvm-svn: 63184
    ---
     clang/lib/Analysis/CFRefCount.cpp | 10 ++++------
     1 file changed, 4 insertions(+), 6 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index 61c1f1835b05..bd11c3a0b272 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -606,8 +606,6 @@ public:
       
     } // end anonymous namespace
     
    -
    -
     //===----------------------------------------------------------------------===//
     // Implementation of checker data structures.
     //===----------------------------------------------------------------------===//
    @@ -2343,15 +2341,15 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
           if (loc::FuncVal* FV = dyn_cast(&X))
             os << "Call to function '" << FV->getDecl()->getNameAsString() <<'\'';
           else
    -        os << "function call";
    -      
    -      os << " returns an object with a ";
    +        os << "function call";      
         }          
         else {
           assert (isa(S));
    -      os << "Method returns an object with a ";
    +      os << "Method";
         }
         
    +    os << " returns an object with a ";
    +    
         if (CurrV.isOwned())
             os << "+1 retain count (owning reference).";
         else {
    -- 
    GitLab
    
    
    From e1d49c25729afb99beba4f8113308a03a1aec17e Mon Sep 17 00:00:00 2001
    From: Chris Lattner 
    Date: Wed, 28 Jan 2009 06:02:52 +0000
    Subject: [PATCH 339/682] add diagnostics files to xcode proj
    
    llvm-svn: 63185
    ---
     clang/clang.xcodeproj/project.pbxproj | 24 ++++++++++++++++++++++++
     1 file changed, 24 insertions(+)
    
    diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj
    index 042e0e3df88f..5d36c5f653fd 100644
    --- a/clang/clang.xcodeproj/project.pbxproj
    +++ b/clang/clang.xcodeproj/project.pbxproj
    @@ -533,6 +533,18 @@
     		DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenModule.cpp; path = lib/CodeGen/CodeGenModule.cpp; sourceTree = ""; tabWidth = 2; };
     		DE928B800C0A615B00231DA4 /* CodeGenFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenFunction.h; path = lib/CodeGen/CodeGenFunction.h; sourceTree = ""; tabWidth = 2; usesTabs = 0; };
     		DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenFunction.cpp; path = lib/CodeGen/CodeGenFunction.cpp; sourceTree = ""; tabWidth = 2; };
    +		DEA099FD0F302C65000C2258 /* DiagnosticAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticAnalysis.h; sourceTree = ""; };
    +		DEA099FE0F302C65000C2258 /* DiagnosticAnalysisKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticAnalysisKinds.def; sourceTree = ""; };
    +		DEA099FF0F302C65000C2258 /* DiagnosticAST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticAST.h; sourceTree = ""; };
    +		DEA09A000F302C65000C2258 /* DiagnosticASTKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticASTKinds.def; sourceTree = ""; };
    +		DEA09A010F302C65000C2258 /* DiagnosticCommonKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticCommonKinds.def; sourceTree = ""; };
    +		DEA09A020F302C65000C2258 /* DiagnosticDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticDriver.h; sourceTree = ""; };
    +		DEA09A030F302C65000C2258 /* DiagnosticLex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLex.h; sourceTree = ""; };
    +		DEA09A040F302C65000C2258 /* DiagnosticLexKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticLexKinds.def; sourceTree = ""; };
    +		DEA09A050F302C65000C2258 /* DiagnosticParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticParse.h; sourceTree = ""; };
    +		DEA09A060F302C65000C2258 /* DiagnosticParseKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticParseKinds.def; sourceTree = ""; };
    +		DEA09A070F302C65000C2258 /* DiagnosticSema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticSema.h; sourceTree = ""; };
    +		DEA09A080F302C65000C2258 /* DiagnosticSemaKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticSemaKinds.def; sourceTree = ""; };
     		DEA0EBD90DD2D3C8007A02A9 /* RewriteMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteMacros.cpp; path = Driver/RewriteMacros.cpp; sourceTree = ""; };
     		DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = ""; };
     		DEAEED4A0A5AF89A0045101B /* NOTES.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = NOTES.txt; sourceTree = ""; };
    @@ -1057,6 +1069,18 @@
     			children = (
     				DED7D7310A524295003AD0FB /* Diagnostic.h */,
     				DED7D7320A524295003AD0FB /* DiagnosticKinds.def */,
    +				DEA099FD0F302C65000C2258 /* DiagnosticAnalysis.h */,
    +				DEA099FE0F302C65000C2258 /* DiagnosticAnalysisKinds.def */,
    +				DEA099FF0F302C65000C2258 /* DiagnosticAST.h */,
    +				DEA09A000F302C65000C2258 /* DiagnosticASTKinds.def */,
    +				DEA09A010F302C65000C2258 /* DiagnosticCommonKinds.def */,
    +				DEA09A020F302C65000C2258 /* DiagnosticDriver.h */,
    +				DEA09A030F302C65000C2258 /* DiagnosticLex.h */,
    +				DEA09A040F302C65000C2258 /* DiagnosticLexKinds.def */,
    +				DEA09A050F302C65000C2258 /* DiagnosticParse.h */,
    +				DEA09A060F302C65000C2258 /* DiagnosticParseKinds.def */,
    +				DEA09A070F302C65000C2258 /* DiagnosticSema.h */,
    +				DEA09A080F302C65000C2258 /* DiagnosticSemaKinds.def */,
     				DED7D7330A524295003AD0FB /* FileManager.h */,
     				DE3986EF0CB8D4B300223765 /* IdentifierTable.h */,
     				DE06B73D0A8307640050E87E /* LangOptions.h */,
    -- 
    GitLab
    
    
    From f0ec316a04d358c5dd1023a30b1e65f68d15c5ce Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 06:06:36 +0000
    Subject: [PATCH 340/682] retain/release checker: Indicate whether a tracked
     object is a Core Foundation or Objective-C object.
    
    llvm-svn: 63186
    ---
     clang/lib/Analysis/CFRefCount.cpp | 8 +++++++-
     1 file changed, 7 insertions(+), 1 deletion(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index bd11c3a0b272..bd5e3b4d5372 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2348,7 +2348,13 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
           os << "Method";
         }
         
    -    os << " returns an object with a ";
    +    if (CurrV.getObjKind() == RetEffect::CF) {
    +      os << " returns a Core Foundation object with a ";
    +    }
    +    else {
    +      assert (CurrV.getObjKind() == RetEffect::ObjC);
    +      os << " returns an Objective-C object with a ";
    +    }
         
         if (CurrV.isOwned())
             os << "+1 retain count (owning reference).";
    -- 
    GitLab
    
    
    From 4daeccf28fffbc73667669e04529840bf50247d0 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 06:25:48 +0000
    Subject: [PATCH 341/682] retain/release checker: Improve diagnostics to
     indicate that CF objects are not automatically garbage collected.
    
    llvm-svn: 63187
    ---
     clang/lib/Analysis/CFRefCount.cpp | 11 +++++++++--
     clang/test/Analysis/CFDateGC.m    |  8 +++++++-
     2 files changed, 16 insertions(+), 3 deletions(-)
    
    diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
    index bd5e3b4d5372..625eda4fb196 100644
    --- a/clang/lib/Analysis/CFRefCount.cpp
    +++ b/clang/lib/Analysis/CFRefCount.cpp
    @@ -2356,8 +2356,15 @@ PathDiagnosticPiece* CFRefReport::VisitNode(const ExplodedNode* N,
           os << " returns an Objective-C object with a ";
         }
         
    -    if (CurrV.isOwned())
    -        os << "+1 retain count (owning reference).";
    +    if (CurrV.isOwned()) {
    +      os << "+1 retain count (owning reference).";
    +      
    +      if (static_cast(getBugType()).getTF().isGCEnabled()) {
    +        assert(CurrV.getObjKind() == RetEffect::CF);
    +        os << "  "
    +          "Core Foundation objects are not automatically garbage collected.";
    +      }
    +    }
         else {
           assert (CurrV.isNotOwned());
           os << "+0 retain count (non-owning reference).";
    diff --git a/clang/test/Analysis/CFDateGC.m b/clang/test/Analysis/CFDateGC.m
    index 5ed8ae960937..c405fe24e590 100644
    --- a/clang/test/Analysis/CFDateGC.m
    +++ b/clang/test/Analysis/CFDateGC.m
    @@ -26,6 +26,7 @@ typedef signed char BOOL;
     static __inline__ __attribute__((always_inline)) id NSMakeCollectable(CFTypeRef cf) {}
     @protocol NSObject  - (BOOL)isEqual:(id)object;
     - (oneway void)release;
    +- (id)retain;
     @end
     @class NSArray;
     
    @@ -46,7 +47,7 @@ CFAbsoluteTime f1_use_after_release() {
     
     // The following two test cases verifies that CFMakeCollectable is a no-op
     // in non-GC mode and a "release" in GC mode.
    -CFAbsoluteTime f2_leak() {
    +CFAbsoluteTime f2_use_after_release() {
       CFAbsoluteTime t = CFAbsoluteTimeGetCurrent();
       CFDateRef date = CFDateCreate(0, t);
       CFRetain(date);
    @@ -68,6 +69,11 @@ CFAbsoluteTime f2_noleak() {
       return t;
     }
     
    +void f3_leak_with_gc() {
    +  CFDateRef date = CFDateCreate(0, CFAbsoluteTimeGetCurrent());
    +  [[(id) date retain] release]; // expected-warning{{leak}}
    +}
    +
     // The following test case verifies that we "stop tracking" a retained object
     // when it is passed as an argument to an implicitly defined function.
     CFAbsoluteTime f4() {
    -- 
    GitLab
    
    
    From 5fdc22732677cf351938bb19dcb0425f8794e60a Mon Sep 17 00:00:00 2001
    From: Chris Lattner 
    Date: Wed, 28 Jan 2009 06:31:57 +0000
    Subject: [PATCH 342/682] add some basic file headers
    
    llvm-svn: 63188
    ---
     clang/clang.xcodeproj/project.pbxproj                 | 2 +-
     clang/include/clang/Basic/DiagnosticAST.h             | 9 +++++++++
     clang/include/clang/Basic/DiagnosticASTKinds.def      | 8 ++++++++
     clang/include/clang/Basic/DiagnosticAnalysis.h        | 9 +++++++++
     clang/include/clang/Basic/DiagnosticAnalysisKinds.def | 8 ++++++++
     clang/include/clang/Basic/DiagnosticCommonKinds.def   | 9 +++++++++
     clang/include/clang/Basic/DiagnosticDriver.h          | 9 +++++++++
     clang/include/clang/Basic/DiagnosticLex.h             | 9 +++++++++
     clang/include/clang/Basic/DiagnosticLexKinds.def      | 9 +++++++++
     clang/include/clang/Basic/DiagnosticParse.h           | 9 +++++++++
     clang/include/clang/Basic/DiagnosticParseKinds.def    | 9 +++++++++
     clang/include/clang/Basic/DiagnosticSema.h            | 9 +++++++++
     clang/include/clang/Basic/DiagnosticSemaKinds.def     | 9 +++++++++
     13 files changed, 107 insertions(+), 1 deletion(-)
    
    diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj
    index 5d36c5f653fd..226c4fcdc20b 100644
    --- a/clang/clang.xcodeproj/project.pbxproj
    +++ b/clang/clang.xcodeproj/project.pbxproj
    @@ -1068,13 +1068,13 @@
     			isa = PBXGroup;
     			children = (
     				DED7D7310A524295003AD0FB /* Diagnostic.h */,
    -				DED7D7320A524295003AD0FB /* DiagnosticKinds.def */,
     				DEA099FD0F302C65000C2258 /* DiagnosticAnalysis.h */,
     				DEA099FE0F302C65000C2258 /* DiagnosticAnalysisKinds.def */,
     				DEA099FF0F302C65000C2258 /* DiagnosticAST.h */,
     				DEA09A000F302C65000C2258 /* DiagnosticASTKinds.def */,
     				DEA09A010F302C65000C2258 /* DiagnosticCommonKinds.def */,
     				DEA09A020F302C65000C2258 /* DiagnosticDriver.h */,
    +				DED7D7320A524295003AD0FB /* DiagnosticKinds.def */,
     				DEA09A030F302C65000C2258 /* DiagnosticLex.h */,
     				DEA09A040F302C65000C2258 /* DiagnosticLexKinds.def */,
     				DEA09A050F302C65000C2258 /* DiagnosticParse.h */,
    diff --git a/clang/include/clang/Basic/DiagnosticAST.h b/clang/include/clang/Basic/DiagnosticAST.h
    index 4f8382bdca04..1a140167e6ce 100644
    --- a/clang/include/clang/Basic/DiagnosticAST.h
    +++ b/clang/include/clang/Basic/DiagnosticAST.h
    @@ -1,3 +1,12 @@
    +//===--- DiagnosticAST.h - Diagnostics for the AST library ------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     #ifndef LLVM_CLANG_DIAGNOSTICAST_H
     #define LLVM_CLANG_DIAGNOSTICAST_H
     
    diff --git a/clang/include/clang/Basic/DiagnosticASTKinds.def b/clang/include/clang/Basic/DiagnosticASTKinds.def
    index 6f39559bc086..c57ee6538e97 100644
    --- a/clang/include/clang/Basic/DiagnosticASTKinds.def
    +++ b/clang/include/clang/Basic/DiagnosticASTKinds.def
    @@ -1,3 +1,11 @@
    +//==--- DiagnosticASTKinds.def - libast diagnostics -------------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
     
     #ifdef ASTSTART       
     __ASTSTART      = DIAG_START_AST,
    diff --git a/clang/include/clang/Basic/DiagnosticAnalysis.h b/clang/include/clang/Basic/DiagnosticAnalysis.h
    index fc13eea4c966..9dc008ec138f 100644
    --- a/clang/include/clang/Basic/DiagnosticAnalysis.h
    +++ b/clang/include/clang/Basic/DiagnosticAnalysis.h
    @@ -1,3 +1,12 @@
    +//===--- DiagnosticAnalysis.h - Diagnostics for libanalysis -----*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     #ifndef LLVM_CLANG_DIAGNOSTICANALYSIS_H
     #define LLVM_CLANG_DIAGNOSTICANALYSIS_H
     
    diff --git a/clang/include/clang/Basic/DiagnosticAnalysisKinds.def b/clang/include/clang/Basic/DiagnosticAnalysisKinds.def
    index d8768ba910ab..17897ed90f60 100644
    --- a/clang/include/clang/Basic/DiagnosticAnalysisKinds.def
    +++ b/clang/include/clang/Basic/DiagnosticAnalysisKinds.def
    @@ -1,3 +1,11 @@
    +//==--- DiagnosticAnalysisKinds.def - libanalysis diagnostics ---*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
     
     #ifdef ANALYSISSTART  
     __ANALYSISSTART = DIAG_START_ANALYSIS,
    diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.def b/clang/include/clang/Basic/DiagnosticCommonKinds.def
    index aab81acefc6a..1bdaf6ab3dad 100644
    --- a/clang/include/clang/Basic/DiagnosticCommonKinds.def
    +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.def
    @@ -1,3 +1,12 @@
    +//==--- DiagnosticCommonKinds.def - common diagnostics ----------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     //===----------------------------------------------------------------------===//
     // Common Helpers
     //===----------------------------------------------------------------------===//
    diff --git a/clang/include/clang/Basic/DiagnosticDriver.h b/clang/include/clang/Basic/DiagnosticDriver.h
    index 44e93b4d3cac..60cdfcdb8aed 100644
    --- a/clang/include/clang/Basic/DiagnosticDriver.h
    +++ b/clang/include/clang/Basic/DiagnosticDriver.h
    @@ -1,3 +1,12 @@
    +//===--- DiagnosticDriver.h - Diagnostics for the driver --------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     #ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H
     #define LLVM_CLANG_DIAGNOSTICDRIVER_H
     
    diff --git a/clang/include/clang/Basic/DiagnosticLex.h b/clang/include/clang/Basic/DiagnosticLex.h
    index 90665b5bad4e..5430b730fb1c 100644
    --- a/clang/include/clang/Basic/DiagnosticLex.h
    +++ b/clang/include/clang/Basic/DiagnosticLex.h
    @@ -1,3 +1,12 @@
    +//===--- DiagnosticLex.h - Diagnostics for liblex ---------------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     #ifndef LLVM_CLANG_DIAGNOSTICLEX_H
     #define LLVM_CLANG_DIAGNOSTICLEX_H
     
    diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.def b/clang/include/clang/Basic/DiagnosticLexKinds.def
    index 54394e10709d..696569896446 100644
    --- a/clang/include/clang/Basic/DiagnosticLexKinds.def
    +++ b/clang/include/clang/Basic/DiagnosticLexKinds.def
    @@ -1,3 +1,12 @@
    +//==--- DiagnosticLexKinds.def - liblex diagnostics -------------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     //===----------------------------------------------------------------------===//
     // Lexer Diagnostics
     //===----------------------------------------------------------------------===//
    diff --git a/clang/include/clang/Basic/DiagnosticParse.h b/clang/include/clang/Basic/DiagnosticParse.h
    index 81a073e84153..272f6ef868a4 100644
    --- a/clang/include/clang/Basic/DiagnosticParse.h
    +++ b/clang/include/clang/Basic/DiagnosticParse.h
    @@ -1,3 +1,12 @@
    +//===--- DiagnosticParse.h - Diagnostics for libparse -----------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     #ifndef LLVM_CLANG_DIAGNOSTICPARSE_H
     #define LLVM_CLANG_DIAGNOSTICPARSE_H
     
    diff --git a/clang/include/clang/Basic/DiagnosticParseKinds.def b/clang/include/clang/Basic/DiagnosticParseKinds.def
    index 6b87ff26ab16..a4e2011bee52 100644
    --- a/clang/include/clang/Basic/DiagnosticParseKinds.def
    +++ b/clang/include/clang/Basic/DiagnosticParseKinds.def
    @@ -1,3 +1,12 @@
    +//==--- DiagnosticParseKinds.def - libparse diagnostics ---------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     //===----------------------------------------------------------------------===//
     // Parser Diagnostics
     //===----------------------------------------------------------------------===//
    diff --git a/clang/include/clang/Basic/DiagnosticSema.h b/clang/include/clang/Basic/DiagnosticSema.h
    index 9ed7ca4c6e55..c0644a1d37e7 100644
    --- a/clang/include/clang/Basic/DiagnosticSema.h
    +++ b/clang/include/clang/Basic/DiagnosticSema.h
    @@ -1,3 +1,12 @@
    +//===--- DiagnosticSema.h - Diagnostics for libsema -------------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
    +//===----------------------------------------------------------------------===//
    +
     #ifndef LLVM_CLANG_DIAGNOSTICSEMA_H
     #define LLVM_CLANG_DIAGNOSTICSEMA_H
     
    diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
    index b412bca184ef..f73f6ee23fb4 100644
    --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
    +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def
    @@ -1,5 +1,14 @@
    +//==--- DiagnosticSemaKinds.def - libsema diagnostics -----------*- C++ -*-===//
    +//
    +//                     The LLVM Compiler Infrastructure
    +//
    +// This file is distributed under the University of Illinois Open Source
    +// License. See LICENSE.TXT for details.
    +//
     //===----------------------------------------------------------------------===//
    +//
     // Semantic Analysis
    +//
     //===----------------------------------------------------------------------===//
     
     #ifdef SEMASTART      
    -- 
    GitLab
    
    
    From 22ebe7ba6649431aa047ddcc2b0cb891dc210d70 Mon Sep 17 00:00:00 2001
    From: Chris Lattner 
    Date: Wed, 28 Jan 2009 06:58:19 +0000
    Subject: [PATCH 343/682] long long and double have 64-bit alignment on x86-64.
    
    llvm-svn: 63191
    ---
     clang/lib/Basic/Targets.cpp | 1 +
     1 file changed, 1 insertion(+)
    
    diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
    index f82b0fcdb1bb..c3e1a68d20f9 100644
    --- a/clang/lib/Basic/Targets.cpp
    +++ b/clang/lib/Basic/Targets.cpp
    @@ -662,6 +662,7 @@ class X86_64TargetInfo : public X86TargetInfo {
     public:
       X86_64TargetInfo(const std::string& triple) : X86TargetInfo(triple) {
         LongWidth = LongAlign = PointerWidth = PointerAlign = 64;
    +    DoubleAlign = LongLongAlign = 64;
         LongDoubleWidth = 128;
         LongDoubleAlign = 128;
         DescriptionString = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-"
    -- 
    GitLab
    
    
    From 882214b6765008de0ce4e499db2cfcfb05a18397 Mon Sep 17 00:00:00 2001
    From: Ted Kremenek 
    Date: Wed, 28 Jan 2009 07:10:33 +0000
    Subject: [PATCH 344/682] Update comment.
    
    llvm-svn: 63192
    ---
     clang/include/clang/Basic/IdentifierTable.h | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/clang/include/clang/Basic/IdentifierTable.h b/clang/include/clang/Basic/IdentifierTable.h
    index 56a6f4184852..91a0bf2e8a48 100644
    --- a/clang/include/clang/Basic/IdentifierTable.h
    +++ b/clang/include/clang/Basic/IdentifierTable.h
    @@ -58,7 +58,7 @@ class IdentifierInfo {
       bool IsPoisoned             : 1; // True if identifier is poisoned.
       bool IsCPPOperatorKeyword   : 1; // True if ident is a C++ operator keyword.
       bool NeedsHandleIdentifier  : 1; // See "RecomputeNeedsHandleIdentifier".
    -  // 8 bits left in 32-bit word.
    +  // 9 bits left in 32-bit word.
       void *FETokenInfo;               // Managed by the language front-end.
       llvm::StringMapEntry *Entry;
       
    -- 
    GitLab
    
    
    From 5a685a52c178fd955c0030fa67592e8cb2be2761 Mon Sep 17 00:00:00 2001
    From: Mon P Wang 
    Date: Wed, 28 Jan 2009 08:12:05 +0000
    Subject: [PATCH 345/682] Add shuffle splat pattern for x86 sse shifts.
    
    llvm-svn: 63193
    ---
     llvm/lib/Target/X86/X86ISelLowering.cpp | 42 ++++++++++++++-----------
     1 file changed, 23 insertions(+), 19 deletions(-)
    
    diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
    index 406b2370b1c0..f48d75253df1 100644
    --- a/llvm/lib/Target/X86/X86ISelLowering.cpp
    +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
    @@ -7678,28 +7678,32 @@ static SDValue PerformShiftCombine(SDNode* N, SelectionDAG &DAG,
       if (VT != MVT::v2i64 && VT != MVT::v4i32 && VT != MVT::v8i16)
         return SDValue();
         
    -  SDValue  ShAmtOp = N->getOperand(1);
    -  if (ShAmtOp.getOpcode() != ISD::BUILD_VECTOR)
    -    return SDValue();
    -
    -  unsigned NumElts = VT.getVectorNumElements();
    -  unsigned i = 0;
    +  SDValue ShAmtOp = N->getOperand(1);
    +  MVT EltVT = VT.getVectorElementType();
       SDValue BaseShAmt;
    -  for (; i != NumElts; ++i) {
    -    SDValue Arg = ShAmtOp.getOperand(i);
    -    if (Arg.getOpcode() == ISD::UNDEF) continue;
    -    BaseShAmt = Arg;
    -    break;
    -  }
    -  for (; i != NumElts; ++i) {
    -    SDValue Arg = ShAmtOp.getOperand(i);
    -    if (Arg.getOpcode() == ISD::UNDEF) continue;
    -    if (Arg != BaseShAmt) {
    -      return SDValue();
    +  if (ShAmtOp.getOpcode() == ISD::BUILD_VECTOR) {
    +    unsigned NumElts = VT.getVectorNumElements();
    +    unsigned i = 0;
    +    for (; i != NumElts; ++i) {
    +      SDValue Arg = ShAmtOp.getOperand(i);
    +      if (Arg.getOpcode() == ISD::UNDEF) continue;
    +      BaseShAmt = Arg;
    +      break;
         }
    -  }
    +    for (; i != NumElts; ++i) {
    +      SDValue Arg = ShAmtOp.getOperand(i);
    +      if (Arg.getOpcode() == ISD::UNDEF) continue;
    +      if (Arg != BaseShAmt) {
    +        return SDValue();
    +      }
    +    }
    +  } else if (ShAmtOp.getOpcode() == ISD::VECTOR_SHUFFLE &&
    +             isSplatMask(ShAmtOp.getOperand(2).getNode())) {
    +      BaseShAmt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, ShAmtOp,
    +                              DAG.getIntPtrConstant(0));
    +  } else
    +    return SDValue();
     
    -  MVT EltVT = VT.getVectorElementType();
       if (EltVT.bitsGT(MVT::i32))
         BaseShAmt = DAG.getNode(ISD::TRUNCATE, MVT::i32, BaseShAmt);
       else if (EltVT.bitsLT(MVT::i32))
    -- 
    GitLab
    
    
    From d880efc005fa1572085ac7774691cbfe6509e26a Mon Sep 17 00:00:00 2001
    From: Mon P Wang 
    Date: Wed, 28 Jan 2009 08:13:56 +0000
    Subject: [PATCH 346/682] Added sse test patterns for r62979 and r63193.
    
    llvm-svn: 63194
    ---
     llvm/test/CodeGen/X86/vshift-1.ll | 65 ++++++++++++++++++++++++++++
     llvm/test/CodeGen/X86/vshift-2.ll | 64 ++++++++++++++++++++++++++++
     llvm/test/CodeGen/X86/vshift-3.ll | 54 +++++++++++++++++++++++
     llvm/test/CodeGen/X86/vshift-4.ll | 71 +++++++++++++++++++++++++++++++
     4 files changed, 254 insertions(+)
     create mode 100644 llvm/test/CodeGen/X86/vshift-1.ll
     create mode 100644 llvm/test/CodeGen/X86/vshift-2.ll
     create mode 100644 llvm/test/CodeGen/X86/vshift-3.ll
     create mode 100644 llvm/test/CodeGen/X86/vshift-4.ll
    
    diff --git a/llvm/test/CodeGen/X86/vshift-1.ll b/llvm/test/CodeGen/X86/vshift-1.ll
    new file mode 100644
    index 000000000000..d7a20e46c18e
    --- /dev/null
    +++ b/llvm/test/CodeGen/X86/vshift-1.ll
    @@ -0,0 +1,65 @@
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
    +; RUN: grep psllq  %t | count 2
    +; RUN: grep pslld %t | count 2
    +; RUN: grep psllw %t | count 2
    +
    +; test vector shifts converted to proper SSE2 vector shifts when the shift
    +; amounts are the same.
    +
    +define void @shift1a(<2 x i64> %val, <2 x i64>* %dst) nounwind {
    +entry:
    +  %shl = shl <2 x i64> %val, < i64 32, i64 32 >
    +  store <2 x i64> %shl, <2 x i64>* %dst
    +  ret void
    +}
    +
    +define void @shift1b(<2 x i64> %val, <2 x i64>* %dst, i64 %amt) nounwind {
    +entry:
    +  %0 = insertelement <2 x i64> undef, i64 %amt, i32 0
    +  %1 = insertelement <2 x i64> %0, i64 %amt, i32 1
    +  %shl = shl <2 x i64> %val, %1
    +  store <2 x i64> %shl, <2 x i64>* %dst
    +  ret void
    +}
    +
    +
    +define void @shift2a(<4 x i32> %val, <4 x i32>* %dst) nounwind {
    +entry:
    +  %shl = shl <4 x i32> %val, < i32 5, i32 5, i32 5, i32 5 >
    +  store <4 x i32> %shl, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, i32 %amt) nounwind {
    +entry:
    +  %0 = insertelement <4 x i32> undef, i32 %amt, i32 0
    +  %1 = insertelement <4 x i32> %0, i32 %amt, i32 1
    +  %2 = insertelement <4 x i32> %1, i32 %amt, i32 2
    +  %3 = insertelement <4 x i32> %2, i32 %amt, i32 3
    +  %shl = shl <4 x i32> %val, %3
    +  store <4 x i32> %shl, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift3a(<8 x i16> %val, <8 x i16>* %dst) nounwind {
    +entry:
    +  %shl = shl <8 x i16> %val, < i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5 >
    +  store <8 x i16> %shl, <8 x i16>* %dst
    +  ret void
    +}
    +
    +define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
    +entry:
    +  %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
    +  %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
    +  %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
    +  %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
    +  %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
    +  %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
    +  %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
    +  %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
    +  %shl = shl <8 x i16> %val, %7
    +  store <8 x i16> %shl, <8 x i16>* %dst
    +  ret void
    +}
    +
    diff --git a/llvm/test/CodeGen/X86/vshift-2.ll b/llvm/test/CodeGen/X86/vshift-2.ll
    new file mode 100644
    index 000000000000..0807174420e8
    --- /dev/null
    +++ b/llvm/test/CodeGen/X86/vshift-2.ll
    @@ -0,0 +1,64 @@
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
    +; RUN: grep psrlq  %t | count 2
    +; RUN: grep psrld %t | count 2
    +; RUN: grep psrlw %t | count 2
    +
    +; test vector shifts converted to proper SSE2 vector shifts when the shift
    +; amounts are the same.
    +
    +define void @shift1a(<2 x i64> %val, <2 x i64>* %dst) nounwind {
    +entry:
    +  %lshr = lshr <2 x i64> %val, < i64 32, i64 32 >
    +  store <2 x i64> %lshr, <2 x i64>* %dst
    +  ret void
    +}
    +
    +define void @shift1b(<2 x i64> %val, <2 x i64>* %dst, i64 %amt) nounwind {
    +entry:
    +  %0 = insertelement <2 x i64> undef, i64 %amt, i32 0
    +  %1 = insertelement <2 x i64> %0, i64 %amt, i32 1
    +  %lshr = lshr <2 x i64> %val, %1
    +  store <2 x i64> %lshr, <2 x i64>* %dst
    +  ret void
    +}
    +
    +define void @shift2a(<4 x i32> %val, <4 x i32>* %dst) nounwind {
    +entry:
    +  %lshr = lshr <4 x i32> %val, < i32 17, i32 17, i32 17, i32 17 >
    +  store <4 x i32> %lshr, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, i32 %amt) nounwind {
    +entry:
    +  %0 = insertelement <4 x i32> undef, i32 %amt, i32 0
    +  %1 = insertelement <4 x i32> %0, i32 %amt, i32 1
    +  %2 = insertelement <4 x i32> %1, i32 %amt, i32 2
    +  %3 = insertelement <4 x i32> %2, i32 %amt, i32 3
    +  %lshr = lshr <4 x i32> %val, %3
    +  store <4 x i32> %lshr, <4 x i32>* %dst
    +  ret void
    +}
    +
    +
    +define void @shift3a(<8 x i16> %val, <8 x i16>* %dst) nounwind {
    +entry:
    +  %lshr = lshr <8 x i16> %val, < i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5 >
    +  store <8 x i16> %lshr, <8 x i16>* %dst
    +  ret void
    +}
    +
    +define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
    +entry:
    +  %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
    +  %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
    +  %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
    +  %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
    +  %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
    +  %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
    +  %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
    +  %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
    +  %lshr = lshr <8 x i16> %val, %7
    +  store <8 x i16> %lshr, <8 x i16>* %dst
    +  ret void
    +}
    \ No newline at end of file
    diff --git a/llvm/test/CodeGen/X86/vshift-3.ll b/llvm/test/CodeGen/X86/vshift-3.ll
    new file mode 100644
    index 000000000000..eea8ad1c798e
    --- /dev/null
    +++ b/llvm/test/CodeGen/X86/vshift-3.ll
    @@ -0,0 +1,54 @@
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
    +; RUN: grep psrad %t | count 2
    +; RUN: grep psraw %t | count 2
    +
    +; test vector shifts converted to proper SSE2 vector shifts when the shift
    +; amounts are the same.
    +
    +; Note that x86 does have ashr 
    +define void @shift1a(<2 x i64> %val, <2 x i64>* %dst) nounwind {
    +entry:
    +  %ashr = ashr <2 x i64> %val, < i64 32, i64 32 >
    +  store <2 x i64> %ashr, <2 x i64>* %dst
    +  ret void
    +}
    +
    +define void @shift2a(<4 x i32> %val, <4 x i32>* %dst) nounwind {
    +entry:
    +  %ashr = ashr <4 x i32> %val, < i32 5, i32 5, i32 5, i32 5 >
    +  store <4 x i32> %ashr, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, i32 %amt) nounwind {
    +entry:
    +  %0 = insertelement <4 x i32> undef, i32 %amt, i32 0
    +  %1 = insertelement <4 x i32> %0, i32 %amt, i32 1
    +  %2 = insertelement <4 x i32> %1, i32 %amt, i32 2
    +  %3 = insertelement <4 x i32> %2, i32 %amt, i32 3
    +  %ashr = ashr <4 x i32> %val, %3
    +  store <4 x i32> %ashr, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift3a(<8 x i16> %val, <8 x i16>* %dst) nounwind {
    +entry:
    +  %ashr = ashr <8 x i16> %val, < i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5, i16 5 >
    +  store <8 x i16> %ashr, <8 x i16>* %dst
    +  ret void
    +}
    +
    +define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
    +entry:
    +  %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
    +  %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
    +  %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
    +  %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
    +  %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
    +  %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
    +  %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
    +  %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
    +  %ashr = ashr <8 x i16> %val, %7
    +  store <8 x i16> %ashr, <8 x i16>* %dst
    +  ret void
    +}
    \ No newline at end of file
    diff --git a/llvm/test/CodeGen/X86/vshift-4.ll b/llvm/test/CodeGen/X86/vshift-4.ll
    new file mode 100644
    index 000000000000..03ab95c0e105
    --- /dev/null
    +++ b/llvm/test/CodeGen/X86/vshift-4.ll
    @@ -0,0 +1,71 @@
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -disable-mmx -o %t -f
    +; RUN: grep psllq %t | count 1
    +; RUN: grep pslld %t | count 3
    +; RUN: grep psllw %t | count 2
    +
    +; test vector shifts converted to proper SSE2 vector shifts when the shift
    +; amounts are the same when using a shuffle splat.
    +
    +define void @shift1a(<2 x i64> %val, <2 x i64>* %dst, <2 x i64> %sh) nounwind {
    +entry:
    +  %shamt = shufflevector <2 x i64> %sh, <2 x i64> undef, <2 x i32> 
    +  %shl = shl <2 x i64> %val, %shamt
    +  store <2 x i64> %shl, <2 x i64>* %dst
    +  ret void
    +}
    +
    +define void @shift1b(<2 x i64> %val, <2 x i64>* %dst, <2 x i64> %sh) nounwind {
    +entry:
    +  %shamt = shufflevector <2 x i64> %sh, <2 x i64> undef, <2 x i32> 
    +  %shl = shl <2 x i64> %val, %shamt
    +  store <2 x i64> %shl, <2 x i64>* %dst
    +  ret void
    +}
    +
    +define void @shift2a(<4 x i32> %val, <4 x i32>* %dst, <2 x i32> %amt) nounwind {
    +entry:
    +  %shamt = shufflevector <2 x i32> %amt, <2 x i32> undef, <4 x i32> 
    +  %shl = shl <4 x i32> %val, %shamt
    +  store <4 x i32> %shl, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift2b(<4 x i32> %val, <4 x i32>* %dst, <2 x i32> %amt) nounwind {
    +entry:
    +  %shamt = shufflevector <2 x i32> %amt, <2 x i32> undef, <4 x i32> 
    +  %shl = shl <4 x i32> %val, %shamt
    +  store <4 x i32> %shl, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift2c(<4 x i32> %val, <4 x i32>* %dst, <2 x i32> %amt) nounwind {
    +entry:
    +  %shamt = shufflevector <2 x i32> %amt, <2 x i32> undef, <4 x i32> 
    +  %shl = shl <4 x i32> %val, %shamt
    +  store <4 x i32> %shl, <4 x i32>* %dst
    +  ret void
    +}
    +
    +define void @shift3a(<8 x i16> %val, <8 x i16>* %dst, <8 x i16> %amt) nounwind {
    +entry:
    +  %shamt = shufflevector <8 x i16> %amt, <8 x i16> undef, <8 x i32> 
    +  %shl = shl <8 x i16> %val, %shamt
    +  store <8 x i16> %shl, <8 x i16>* %dst
    +  ret void
    +}
    +
    +define void @shift3b(<8 x i16> %val, <8 x i16>* %dst, i16 %amt) nounwind {
    +entry:
    +  %0 = insertelement <8 x i16> undef, i16 %amt, i32 0
    +  %1 = insertelement <8 x i16> %0, i16 %amt, i32 1
    +  %2 = insertelement <8 x i16> %0, i16 %amt, i32 2
    +  %3 = insertelement <8 x i16> %0, i16 %amt, i32 3
    +  %4 = insertelement <8 x i16> %0, i16 %amt, i32 4
    +  %5 = insertelement <8 x i16> %0, i16 %amt, i32 5
    +  %6 = insertelement <8 x i16> %0, i16 %amt, i32 6
    +  %7 = insertelement <8 x i16> %0, i16 %amt, i32 7
    +  %shl = shl <8 x i16> %val, %7
    +  store <8 x i16> %shl, <8 x i16>* %dst
    +  ret void
    +}
    +
    -- 
    GitLab
    
    
    From f31f2888632fb3533a79299f6491272854636283 Mon Sep 17 00:00:00 2001
    From: Evan Cheng 
    Date: Wed, 28 Jan 2009 08:35:02 +0000
    Subject: [PATCH 347/682] The memory alignment requirement on some of the
     mov{h|l}p{d|s} patterns are 16-byte. That is overly strict. These
     instructions read / write f64 memory locations without alignment requirement.
    
    llvm-svn: 63195
    ---
     llvm/lib/Target/X86/README-SSE.txt |  5 +++++
     llvm/lib/Target/X86/X86InstrSSE.td | 34 ++++++++++++++----------------
     llvm/test/CodeGen/X86/swizzle.ll   | 19 +++++++++++++++++
     3 files changed, 40 insertions(+), 18 deletions(-)
     create mode 100644 llvm/test/CodeGen/X86/swizzle.ll
    
    diff --git a/llvm/lib/Target/X86/README-SSE.txt b/llvm/lib/Target/X86/README-SSE.txt
    index 7110b3148715..bc51b5348243 100644
    --- a/llvm/lib/Target/X86/README-SSE.txt
    +++ b/llvm/lib/Target/X86/README-SSE.txt
    @@ -907,3 +907,8 @@ We should be able to use:
       cvtsi2ss 8($esp), %xmm0
     since we know the stack slot is already zext'd.
     
    +//===---------------------------------------------------------------------===//
    +
    +Consider using movlps instead of movsd to implement (scalar_to_vector (loadf64))
    +when code size is critical. movlps is slower than movsd on core2 but it's one
    +byte shorter.
    diff --git a/llvm/lib/Target/X86/X86InstrSSE.td b/llvm/lib/Target/X86/X86InstrSSE.td
    index b7a959a78332..4fc1044cba96 100644
    --- a/llvm/lib/Target/X86/X86InstrSSE.td
    +++ b/llvm/lib/Target/X86/X86InstrSSE.td
    @@ -3019,62 +3019,60 @@ def : Pat<(v4i32 (vector_shuffle VR128:$src1, (undef),
     let AddedComplexity = 20 in {
     // vector_shuffle v1, (load v2) <4, 5, 2, 3> using MOVLPS
     // vector_shuffle v1, (load v2) <0, 1, 4, 5> using MOVHPS
    -def : Pat<(v4f32 (vector_shuffle VR128:$src1, (memop addr:$src2),
    +def : Pat<(v4f32 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVLP_shuffle_mask)),
               (MOVLPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(v2f64 (vector_shuffle VR128:$src1, (memop addr:$src2),
    +def : Pat<(v2f64 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVLP_shuffle_mask)),
               (MOVLPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
    -def : Pat<(v4f32 (vector_shuffle VR128:$src1, (memop addr:$src2),
    +def : Pat<(v4f32 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVHP_shuffle_mask)),
               (MOVHPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(v2f64 (vector_shuffle VR128:$src1, (memop addr:$src2),
    +def : Pat<(v2f64 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVHP_shuffle_mask)),
               (MOVHPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
     
    -def : Pat<(v4i32 (vector_shuffle VR128:$src1,
    -                                 (bc_v4i32 (memopv2i64 addr:$src2)),
    +def : Pat<(v4i32 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVLP_shuffle_mask)),
               (MOVLPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
    -def : Pat<(v2i64 (vector_shuffle VR128:$src1, (memop addr:$src2),
    +def : Pat<(v2i64 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVLP_shuffle_mask)),
               (MOVLPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
    -def : Pat<(v4i32 (vector_shuffle VR128:$src1,
    -                                 (bc_v4i32 (memopv2i64 addr:$src2)),
    +def : Pat<(v4i32 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVHP_shuffle_mask)),
               (MOVHPSrm VR128:$src1, addr:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(v2i64 (vector_shuffle VR128:$src1, (memop addr:$src2),
    +def : Pat<(v2i64 (vector_shuffle VR128:$src1, (load addr:$src2),
                       MOVHP_shuffle_mask)),
               (MOVHPDrm VR128:$src1, addr:$src2)>, Requires<[HasSSE2]>;
     }
     
     // (store (vector_shuffle (load addr), v2, <4, 5, 2, 3>), addr) using MOVLPS
     // (store (vector_shuffle (load addr), v2, <0, 1, 4, 5>), addr) using MOVHPS
    -def : Pat<(store (v4f32 (vector_shuffle (memop addr:$src1), VR128:$src2,
    +def : Pat<(store (v4f32 (vector_shuffle (load addr:$src1), VR128:$src2,
                              MOVLP_shuffle_mask)), addr:$src1),
               (MOVLPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(store (v2f64 (vector_shuffle (memop addr:$src1), VR128:$src2,
    +def : Pat<(store (v2f64 (vector_shuffle (load addr:$src1), VR128:$src2,
                              MOVLP_shuffle_mask)), addr:$src1),
               (MOVLPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
    -def : Pat<(store (v4f32 (vector_shuffle (memop addr:$src1), VR128:$src2,
    +def : Pat<(store (v4f32 (vector_shuffle (load addr:$src1), VR128:$src2,
                              MOVHP_shuffle_mask)), addr:$src1),
               (MOVHPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(store (v2f64 (vector_shuffle (memop addr:$src1), VR128:$src2,
    +def : Pat<(store (v2f64 (vector_shuffle (load addr:$src1), VR128:$src2,
                              MOVHP_shuffle_mask)), addr:$src1),
               (MOVHPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
     
     def : Pat<(store (v4i32 (vector_shuffle
    -                         (bc_v4i32 (memopv2i64 addr:$src1)), VR128:$src2,
    +                         (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2,
                              MOVLP_shuffle_mask)), addr:$src1),
               (MOVLPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(store (v2i64 (vector_shuffle (memop addr:$src1), VR128:$src2,
    +def : Pat<(store (v2i64 (vector_shuffle (load addr:$src1), VR128:$src2,
                              MOVLP_shuffle_mask)), addr:$src1),
               (MOVLPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
     def : Pat<(store (v4i32 (vector_shuffle
    -                         (bc_v4i32 (memopv2i64 addr:$src1)), VR128:$src2,
    +                         (bc_v4i32 (loadv2i64 addr:$src1)), VR128:$src2,
                              MOVHP_shuffle_mask)), addr:$src1),
               (MOVHPSmr addr:$src1, VR128:$src2)>, Requires<[HasSSE1]>;
    -def : Pat<(store (v2i64 (vector_shuffle (memop addr:$src1), VR128:$src2,
    +def : Pat<(store (v2i64 (vector_shuffle (load addr:$src1), VR128:$src2,
                              MOVHP_shuffle_mask)), addr:$src1),
               (MOVHPDmr addr:$src1, VR128:$src2)>, Requires<[HasSSE2]>;
     
    diff --git a/llvm/test/CodeGen/X86/swizzle.ll b/llvm/test/CodeGen/X86/swizzle.ll
    new file mode 100644
    index 000000000000..d00bb9a0fadb
    --- /dev/null
    +++ b/llvm/test/CodeGen/X86/swizzle.ll
    @@ -0,0 +1,19 @@
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movlps
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | grep movsd
    +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 | not grep movups
    +; rdar://6523650
    +
    +	%struct.vector4_t = type { <4 x float> }
    +
    +define void @swizzle(i8* nocapture %a, %struct.vector4_t* nocapture %b, %struct.vector4_t* nocapture %c) nounwind {
    +entry:
    +	%0 = getelementptr %struct.vector4_t* %b, i32 0, i32 0		; <<4 x float>*> [#uses=2]
    +	%1 = load <4 x float>* %0, align 4		; <<4 x float>> [#uses=1]
    +	%tmp.i = bitcast i8* %a to double*		;  [#uses=1]
    +	%tmp1.i = load double* %tmp.i		;  [#uses=1]
    +	%2 = insertelement <2 x double> undef, double %tmp1.i, i32 0		; <<2 x double>> [#uses=1]
    +	%tmp2.i = bitcast <2 x double> %2 to <4 x float>		; <<4 x float>> [#uses=1]
    +	%3 = shufflevector <4 x float> %1, <4 x float> %tmp2.i, <4 x i32> < i32 4, i32 5, i32 2, i32 3 >		; <<4 x float>> [#uses=1]
    +	store <4 x float> %3, <4 x float>* %0, align 4
    +	ret void
    +}
    -- 
    GitLab
    
    
    From 08e53d041f6b0cb0d6367a2173569a5005114070 Mon Sep 17 00:00:00 2001
    From: Duncan Sands 
    Date: Wed, 28 Jan 2009 11:33:59 +0000
    Subject: [PATCH 348/682] Fix PR3415 (infinite loop in EscapeAnalysis) by
     deleting the escape analysis pass.
    
    llvm-svn: 63197
    ---
     llvm/include/llvm/Analysis/EscapeAnalysis.h |  55 -------
     llvm/include/llvm/LinkAllPasses.h           |   2 -
     llvm/lib/Analysis/CMakeLists.txt            |   1 -
     llvm/lib/Analysis/EscapeAnalysis.cpp        | 158 --------------------
     llvm/win32/Analysis/Analysis.vcproj         |   4 -
     5 files changed, 220 deletions(-)
     delete mode 100644 llvm/include/llvm/Analysis/EscapeAnalysis.h
     delete mode 100644 llvm/lib/Analysis/EscapeAnalysis.cpp
    
    diff --git a/llvm/include/llvm/Analysis/EscapeAnalysis.h b/llvm/include/llvm/Analysis/EscapeAnalysis.h
    deleted file mode 100644
    index 3f4da25310d7..000000000000
    --- a/llvm/include/llvm/Analysis/EscapeAnalysis.h
    +++ /dev/null
    @@ -1,55 +0,0 @@
    -//===------------- EscapeAnalysis.h - Pointer escape analysis -------------===//
    -//
    -//                     The LLVM Compiler Infrastructure
    -//
    -// This file is distributed under the University of Illinois Open Source
    -// License. See LICENSE.TXT for details.
    -//
    -//===----------------------------------------------------------------------===//
    -//
    -// This file defines the interface for the pointer escape analysis.
    -//
    -//===----------------------------------------------------------------------===//
    -
    -#ifndef LLVM_ANALYSIS_ESCAPEANALYSIS_H
    -#define LLVM_ANALYSIS_ESCAPEANALYSIS_H
    -
    -#include "llvm/Pass.h"
    -#include 
    -
    -namespace llvm {
    -
    -class Instruction;
    -class Value;
    -
    -/// EscapeAnalysis - This class determines whether an allocation (a MallocInst 
    -/// or an AllocaInst) can escape from the current function.  It performs some
    -/// precomputation, with the rest of the work happening on-demand.
    -class EscapeAnalysis : public FunctionPass {
    -private:
    -  std::set EscapePoints;
    -
    -public:
    -  static char ID; // Class identification, replacement for typeinfo
    -
    -  EscapeAnalysis() : FunctionPass(intptr_t(&ID)) {}
    -
    -  bool runOnFunction(Function &F);
    -  
    -  void releaseMemory() {
    -    EscapePoints.clear();
    -  }
    -
    -  void getAnalysisUsage(AnalysisUsage &AU) const;
    -
    -  //===---------------------------------------------------------------------
    -  // Client API
    -
    -  /// escapes - returns true if the value, which must have a pointer type,
    -  /// can escape.
    -  bool escapes(Value* A);
    -};
    -
    -} // end llvm namespace
    -
    -#endif
    diff --git a/llvm/include/llvm/LinkAllPasses.h b/llvm/include/llvm/LinkAllPasses.h
    index 4113b16dfffc..18f72ac457b4 100644
    --- a/llvm/include/llvm/LinkAllPasses.h
    +++ b/llvm/include/llvm/LinkAllPasses.h
    @@ -16,7 +16,6 @@
     #define LLVM_LINKALLPASSES_H
     
     #include "llvm/Analysis/AliasSetTracker.h"
    -#include "llvm/Analysis/EscapeAnalysis.h"
     #include "llvm/Analysis/FindUsedTypes.h"
     #include "llvm/Analysis/IntervalPartition.h"
     #include "llvm/Analysis/LoopVR.h"
    @@ -132,7 +131,6 @@ namespace {
           (void)new llvm::FindUsedTypes();
           (void)new llvm::ScalarEvolution();
           (void)new llvm::LoopVR();
    -      (void)new llvm::EscapeAnalysis();
           ((llvm::Function*)0)->viewCFGOnly();
           llvm::AliasSetTracker X(*(llvm::AliasAnalysis*)0);
           X.add((llvm::Value*)0, 0);  // for -print-alias-sets
    diff --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
    index c5dc2cdf0a9b..f63054b60ed0 100644
    --- a/llvm/lib/Analysis/CMakeLists.txt
    +++ b/llvm/lib/Analysis/CMakeLists.txt
    @@ -11,7 +11,6 @@ add_llvm_library(LLVMAnalysis
       ConstantFolding.cpp
       DbgInfoPrinter.cpp
       DebugInfo.cpp
    -  EscapeAnalysis.cpp
       InstCount.cpp
       Interval.cpp
       IntervalPartition.cpp
    diff --git a/llvm/lib/Analysis/EscapeAnalysis.cpp b/llvm/lib/Analysis/EscapeAnalysis.cpp
    deleted file mode 100644
    index c621c9f9abc2..000000000000
    --- a/llvm/lib/Analysis/EscapeAnalysis.cpp
    +++ /dev/null
    @@ -1,158 +0,0 @@
    -//===------------- EscapeAnalysis.h - Pointer escape analysis -------------===//
    -//
    -//                     The LLVM Compiler Infrastructure
    -//
    -// This file is distributed under the University of Illinois Open Source
    -// License. See LICENSE.TXT for details.
    -//
    -//===----------------------------------------------------------------------===//
    -//
    -// This file provides the implementation of the pointer escape analysis.
    -//
    -//===----------------------------------------------------------------------===//
    -
    -#define DEBUG_TYPE "escape-analysis"
    -#include "llvm/Analysis/EscapeAnalysis.h"
    -#include "llvm/Constants.h"
    -#include "llvm/Instructions.h"
    -#include "llvm/Module.h"
    -#include "llvm/Analysis/AliasAnalysis.h"
    -#include "llvm/Support/InstIterator.h"
    -#include "llvm/Target/TargetData.h"
    -#include "llvm/ADT/SmallPtrSet.h"
    -#include 
    -using namespace llvm;
    -
    -char EscapeAnalysis::ID = 0;
    -static RegisterPass X("escape-analysis",
    -                                      "Pointer Escape Analysis", true, true);
    -
    -
    -void EscapeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const {
    -  AU.addRequiredTransitive();
    -  AU.addRequiredTransitive();
    -  AU.setPreservesAll();
    -}
    -
    -/// runOnFunction - Precomputation for escape analysis.  This collects all know
    -/// "escape points" in the def-use graph of the function.  These are 
    -/// instructions which allow their inputs to escape from the current function.  
    -bool EscapeAnalysis::runOnFunction(Function& F) {
    -  EscapePoints.clear();
    -  
    -  TargetData& TD = getAnalysis();
    -  AliasAnalysis& AA = getAnalysis();
    -  Module* M = F.getParent();
    -  
    -  // Walk through all instructions in the function, identifying those that
    -  // may allow their inputs to escape.
    -  for(inst_iterator II = inst_begin(F), IE = inst_end(F); II != IE; ++II) {
    -    Instruction* I = &*II;
    -    
    -    // The most obvious case is stores.  Any store that may write to global
    -    // memory or to a function argument potentially allows its input to escape.
    -    if (StoreInst* S = dyn_cast(I)) {
    -      const Type* StoreType = S->getOperand(0)->getType();
    -      unsigned StoreSize = TD.getTypeStoreSize(StoreType);
    -      Value* Pointer = S->getPointerOperand();
    -      
    -      bool inserted = false;
    -      for (Function::arg_iterator AI = F.arg_begin(), AE = F.arg_end();
    -           AI != AE; ++AI) {
    -        if (!isa(AI->getType())) continue;
    -        AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, AI, ~0U);
    -        if (R != AliasAnalysis::NoAlias) {
    -          EscapePoints.insert(S);
    -          inserted = true;
    -          break;
    -        }
    -      }
    -      
    -      if (inserted)
    -        continue;
    -      
    -      for (Module::global_iterator GI = M->global_begin(), GE = M->global_end();
    -           GI != GE; ++GI) {
    -        AliasAnalysis::AliasResult R = AA.alias(Pointer, StoreSize, GI, ~0U);
    -        if (R != AliasAnalysis::NoAlias) {
    -          EscapePoints.insert(S);
    -          break;
    -        }
    -      }
    -    
    -    // Calls and invokes potentially allow their parameters to escape.
    -    // FIXME: This can and should be refined.  Intrinsics have known escape
    -    // behavior, and alias analysis may be able to tell us more about callees.
    -    } else if (isa(I) || isa(I)) {
    -      EscapePoints.insert(I);
    -    
    -    // Returns allow the return value to escape.  This is mostly important
    -    // for malloc to alloca promotion.
    -    } else if (isa(I)) {
    -      EscapePoints.insert(I);
    -    
    -    // Branching on the value of a pointer may allow the value to escape through
    -    // methods not discoverable via def-use chaining.
    -    } else if(isa(I) || isa(I)) {
    -      EscapePoints.insert(I);
    -    }
    -    
    -    // FIXME: Are there any other possible escape points?
    -  }
    -  
    -  return false;
    -}
    -
    -/// escapes - Determines whether the passed allocation can escape from the 
    -/// current function.  It does this by using a simple worklist algorithm to
    -/// search for a path in the def-use graph from the allocation to an
    -/// escape point.
    -/// FIXME: Once we've discovered a path, it would be a good idea to memoize it,
    -/// and all of its subpaths, to amortize the cost of future queries.
    -bool EscapeAnalysis::escapes(Value* A) {
    -  assert(isa(A->getType()) && 
    -         "Can't do escape analysis on non-pointer types!");
    -  
    -  std::vector worklist;
    -  worklist.push_back(A);
    -  
    -  SmallPtrSet visited;
    -  visited.insert(A);
    -  while (!worklist.empty()) {
    -    Value* curr = worklist.back();
    -    worklist.pop_back();
    -    
    -    if (Instruction* I = dyn_cast(curr))
    -      if (EscapePoints.count(I)) {
    -        BranchInst* B = dyn_cast(I);
    -        if (!B) return true;
    -        Value* condition = B->getCondition();
    -        ICmpInst* C = dyn_cast(condition);
    -        if (!C) return true;
    -        Value* O1 = C->getOperand(0);
    -        Value* O2 = C->getOperand(1);
    -        if (isa(O1->stripPointerCasts())) {
    -          if (!isa(O2)) return true;
    -        } else if(isa(O2->stripPointerCasts())) {
    -          if (!isa(O1)) return true;
    -        } else
    -          return true;
    -      }
    -    
    -    if (StoreInst* S = dyn_cast(curr)) {
    -      // We know this must be an instruction, because constant gep's would
    -      // have been found to alias a global, so stores to them would have
    -      // been in EscapePoints.
    -      if (visited.insert(cast(S->getPointerOperand())))
    -        worklist.push_back(cast(S->getPointerOperand()));
    -    } else {
    -      for (Instruction::use_iterator UI = curr->use_begin(),
    -           UE = curr->use_end(); UI != UE; ++UI)
    -        if (Instruction* U = dyn_cast(UI))
    -          if (visited.insert(U))
    -            worklist.push_back(U);
    -    }
    -  }
    -  
    -  return false;
    -}
    diff --git a/llvm/win32/Analysis/Analysis.vcproj b/llvm/win32/Analysis/Analysis.vcproj
    index 3f5550fe3bff..e116aa384d97 100644
    --- a/llvm/win32/Analysis/Analysis.vcproj
    +++ b/llvm/win32/Analysis/Analysis.vcproj
    @@ -348,10 +348,6 @@
     				RelativePath="..\..\lib\Analysis\DebugInfo.cpp"
     				>
     			
    -			
    -			
     			
    -- 
    GitLab
    
    
    From 5a913d61e3480f0ef825e284c09a7811deef8a1c Mon Sep 17 00:00:00 2001
    From: Duncan Sands 
    Date: Wed, 28 Jan 2009 13:14:17 +0000
    Subject: [PATCH 349/682] Rename getAnalysisToUpdate to getAnalysisIfAvailable.
    
    llvm-svn: 63198
    ---
     llvm/docs/CompilerDriver.html                 |  2 +-
     llvm/docs/WritingAnLLVMPass.html              | 12 ++++++----
     llvm/include/llvm/Pass.h                      | 24 +++++++++----------
     llvm/include/llvm/PassAnalysisSupport.h       | 22 ++++++++---------
     llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp    |  8 +++----
     llvm/lib/CodeGen/BranchFolding.cpp            |  2 +-
     llvm/lib/CodeGen/GCMetadata.cpp               |  2 +-
     llvm/lib/CodeGen/GCStrategy.cpp               |  2 +-
     llvm/lib/CodeGen/MachineModuleInfo.cpp        |  2 +-
     llvm/lib/CodeGen/PHIElimination.cpp           |  2 +-
     llvm/lib/CodeGen/PrologEpilogInserter.cpp     |  2 +-
     .../CodeGen/SelectionDAG/SelectionDAGISel.cpp |  4 ++--
     .../lib/CodeGen/TwoAddressInstructionPass.cpp |  2 +-
     llvm/lib/CodeGen/UnreachableBlockElim.cpp     |  2 +-
     .../Target/ARM/AsmPrinter/ARMAsmPrinter.cpp   |  4 ++--
     .../CellSPU/AsmPrinter/SPUAsmPrinter.cpp      |  4 ++--
     .../PowerPC/AsmPrinter/PPCAsmPrinter.cpp      |  8 +++----
     .../X86/AsmPrinter/X86ATTAsmPrinter.cpp       | 10 ++++----
     llvm/lib/Target/XCore/XCoreAsmPrinter.cpp     |  4 ++--
     llvm/lib/Transforms/IPO/Internalize.cpp       |  2 +-
     llvm/lib/Transforms/Scalar/LoopRotation.cpp   |  6 ++---
     llvm/lib/Transforms/Scalar/LoopUnroll.cpp     |  4 ++--
     llvm/lib/Transforms/Scalar/LoopUnswitch.cpp   |  4 ++--
     llvm/lib/Transforms/Utils/BasicBlockUtils.cpp | 14 +++++------
     .../Transforms/Utils/BreakCriticalEdges.cpp   |  6 ++---
     llvm/lib/Transforms/Utils/CloneLoop.cpp       |  4 ++--
     llvm/lib/Transforms/Utils/LoopSimplify.cpp    |  4 ++--
     llvm/lib/VMCore/Pass.cpp                      |  2 +-
     llvm/lib/VMCore/PassManager.cpp               |  8 +++----
     29 files changed, 87 insertions(+), 85 deletions(-)
    
    diff --git a/llvm/docs/CompilerDriver.html b/llvm/docs/CompilerDriver.html
    index fc687f166751..6338dd247696 100644
    --- a/llvm/docs/CompilerDriver.html
    +++ b/llvm/docs/CompilerDriver.html
    @@ -611,7 +611,7 @@ errors as its status code.

    Mikhail Glushenkov
    LLVM Compiler Infrastructure
    -Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $ +Last modified: $Date$
  • diff --git a/llvm/docs/WritingAnLLVMPass.html b/llvm/docs/WritingAnLLVMPass.html index 0f37ec276c45..04bd9266118b 100644 --- a/llvm/docs/WritingAnLLVMPass.html +++ b/llvm/docs/WritingAnLLVMPass.html @@ -78,7 +78,8 @@
  • The AnalysisUsage::addRequired<> and AnalysisUsage::addRequiredTransitive<> methods
  • The AnalysisUsage::addPreserved<> method
  • Example implementations of getAnalysisUsage
  • -
  • The getAnalysis<> and getAnalysisToUpdate<> methods
  • +
  • The getAnalysis<> and +getAnalysisIfAvailable<> methods
  • Implementing Analysis Groups
      @@ -1131,7 +1132,8 @@ the fact that it hacks on the CFG.
      @@ -1173,12 +1175,12 @@ before returning a reference to the desired pass.

      If your pass is capable of updating analyses if they exist (e.g., BreakCriticalEdges, as described above), you can use the -getAnalysisToUpdate method, which returns a pointer to the analysis if -it is active. For example:

      +getAnalysisIfAvailable method, which returns a pointer to the analysis +if it is active. For example:

         ...
      -  if (DominatorSet *DS = getAnalysisToUpdate<DominatorSet>()) {
      +  if (DominatorSet *DS = getAnalysisIfAvailable<DominatorSet>()) {
           // A DominatorSet is active.  This code will update it.
         }
         ...
      diff --git a/llvm/include/llvm/Pass.h b/llvm/include/llvm/Pass.h
      index dd012da93cfa..0527e0cdbbe4 100644
      --- a/llvm/include/llvm/Pass.h
      +++ b/llvm/include/llvm/Pass.h
      @@ -169,22 +169,22 @@ public:
         // or null if it is not known.
         static const PassInfo *lookupPassInfo(intptr_t TI);
       
      -  /// getAnalysisToUpdate() - This function is used by subclasses
      -  /// to get to the analysis information that might be around that needs to be
      -  /// updated.  This is different than getAnalysis in that it can fail (ie the
      -  /// analysis results haven't been computed), so should only be used if you
      -  /// provide the capability to update an analysis that exists.  This method is
      -  /// often used by transformation APIs to update analysis results for a pass
      -  /// automatically as the transform is performed.
      +  /// getAnalysisIfAvailable() - Subclasses use this function to
      +  /// get analysis information that might be around, for example to update it.
      +  /// This is different than getAnalysis in that it can fail (if the analysis
      +  /// results haven't been computed), so should only be used if you can handle
      +  /// the case when the analysis is not available.  This method is often used by
      +  /// transformation APIs to update analysis results for a pass automatically as
      +  /// the transform is performed.
         ///
      -  template
      -  AnalysisType *getAnalysisToUpdate() const; // Defined in PassAnalysisSupport.h
      +  template AnalysisType *
      +    getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
       
         /// mustPreserveAnalysisID - This method serves the same function as
      -  /// getAnalysisToUpdate, but works if you just have an AnalysisID.  This
      +  /// getAnalysisIfAvailable, but works if you just have an AnalysisID.  This
         /// obviously cannot give you a properly typed instance of the class if you
      -  /// don't have the class name available (use getAnalysisToUpdate if you do),
      -  /// but it can tell you if you need to preserve the pass at least.
      +  /// don't have the class name available (use getAnalysisIfAvailable if you
      +  /// do), but it can tell you if you need to preserve the pass at least.
         ///
         bool mustPreserveAnalysisID(const PassInfo *AnalysisID) const;
       
      diff --git a/llvm/include/llvm/PassAnalysisSupport.h b/llvm/include/llvm/PassAnalysisSupport.h
      index c6ed179af61f..f8b139ecb1a5 100644
      --- a/llvm/include/llvm/PassAnalysisSupport.h
      +++ b/llvm/include/llvm/PassAnalysisSupport.h
      @@ -143,8 +143,8 @@ public:
           AnalysisImpls.push_back(pir);
         }
       
      -  // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
      -  Pass *getAnalysisToUpdate(AnalysisID ID, bool Direction) const;
      +  // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist
      +  Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const;
       
         // AnalysisImpls - This keeps track of which passes implements the interfaces
         // that are required by the current pass (to implement getAnalysis()).
      @@ -157,22 +157,22 @@ private:
         PMDataManager &PM;
       };
       
      -/// getAnalysisToUpdate() - This function is used by subclasses
      -/// to get to the analysis information that might be around that needs to be
      -/// updated.  This is different than getAnalysis in that it can fail (ie the
      -/// analysis results haven't been computed), so should only be used if you
      -/// provide the capability to update an analysis that exists.  This method is
      -/// often used by transformation APIs to update analysis results for a pass
      -/// automatically as the transform is performed.
      +/// getAnalysisIfAvailable() - Subclasses use this function to
      +/// get analysis information that might be around, for example to update it.
      +/// This is different than getAnalysis in that it can fail (if the analysis
      +/// results haven't been computed), so should only be used if you can handle
      +/// the case when the analysis is not available.  This method is often used by
      +/// transformation APIs to update analysis results for a pass automatically as
      +/// the transform is performed.
       ///
       template
      -AnalysisType *Pass::getAnalysisToUpdate() const {
      +AnalysisType *Pass::getAnalysisIfAvailable() const {
         assert(Resolver && "Pass not resident in a PassManager object!");
       
         const PassInfo *PI = getClassPassInfo();
         if (PI == 0) return 0;
         return dynamic_cast
      -    (Resolver->getAnalysisToUpdate(PI, true));
      +    (Resolver->getAnalysisIfAvailable(PI, true));
       }
       
       /// getAnalysis() - This function is used by subclasses to get
      diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
      index 50cd24ba8227..9334f1ef3f2e 100644
      --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
      +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
      @@ -141,7 +141,7 @@ void AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
       bool AsmPrinter::doInitialization(Module &M) {
         Mang = new Mangler(M, TAI->getGlobalPrefix(), TAI->getPrivateGlobalPrefix());
         
      -  GCModuleInfo *MI = getAnalysisToUpdate();
      +  GCModuleInfo *MI = getAnalysisIfAvailable();
         assert(MI && "AsmPrinter didn't require GCModuleInfo?");
       
         if (TAI->hasSingleParameterDotFile()) {
      @@ -163,9 +163,9 @@ bool AsmPrinter::doInitialization(Module &M) {
       
         SwitchToDataSection("");   // Reset back to no section.
         
      -  MachineModuleInfo *MMI = getAnalysisToUpdate();
      +  MachineModuleInfo *MMI = getAnalysisIfAvailable();
         if (MMI) MMI->AnalyzeModule(M);
      -  DW = getAnalysisToUpdate();
      +  DW = getAnalysisIfAvailable();
         return false;
       }
       
      @@ -218,7 +218,7 @@ bool AsmPrinter::doFinalization(Module &M) {
           }
         }
       
      -  GCModuleInfo *MI = getAnalysisToUpdate();
      +  GCModuleInfo *MI = getAnalysisIfAvailable();
         assert(MI && "AsmPrinter didn't require GCModuleInfo?");
         for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
           if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
      diff --git a/llvm/lib/CodeGen/BranchFolding.cpp b/llvm/lib/CodeGen/BranchFolding.cpp
      index 85df7a9d36c1..fe8ce522f065 100644
      --- a/llvm/lib/CodeGen/BranchFolding.cpp
      +++ b/llvm/lib/CodeGen/BranchFolding.cpp
      @@ -198,7 +198,7 @@ bool BranchFolder::runOnMachineFunction(MachineFunction &MF) {
       
         RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
       
      -  MMI = getAnalysisToUpdate();
      +  MMI = getAnalysisIfAvailable();
       
         bool MadeChangeThisIteration = true;
         while (MadeChangeThisIteration) {
      diff --git a/llvm/lib/CodeGen/GCMetadata.cpp b/llvm/lib/CodeGen/GCMetadata.cpp
      index f2978f88882c..4742ad8bbbb9 100644
      --- a/llvm/lib/CodeGen/GCMetadata.cpp
      +++ b/llvm/lib/CodeGen/GCMetadata.cpp
      @@ -205,7 +205,7 @@ bool Deleter::runOnFunction(Function &MF) {
       }
       
       bool Deleter::doFinalization(Module &M) {
      -  GCModuleInfo *GMI = getAnalysisToUpdate();
      +  GCModuleInfo *GMI = getAnalysisIfAvailable();
         assert(GMI && "Deleter didn't require GCModuleInfo?!");
         GMI->clear();
         return false;
      diff --git a/llvm/lib/CodeGen/GCStrategy.cpp b/llvm/lib/CodeGen/GCStrategy.cpp
      index 517b3a7762e7..96b81226bd9f 100644
      --- a/llvm/lib/CodeGen/GCStrategy.cpp
      +++ b/llvm/lib/CodeGen/GCStrategy.cpp
      @@ -144,7 +144,7 @@ bool LowerIntrinsics::doInitialization(Module &M) {
         //        work against the entire module. But this cannot be done at
         //        runFunction time (initializeCustomLowering likely needs to change
         //        the module).
      -  GCModuleInfo *MI = getAnalysisToUpdate();
      +  GCModuleInfo *MI = getAnalysisIfAvailable();
         assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
         for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
           if (!I->isDeclaration() && I->hasGC())
      diff --git a/llvm/lib/CodeGen/MachineModuleInfo.cpp b/llvm/lib/CodeGen/MachineModuleInfo.cpp
      index 724c113b79b9..1c29c7fed350 100644
      --- a/llvm/lib/CodeGen/MachineModuleInfo.cpp
      +++ b/llvm/lib/CodeGen/MachineModuleInfo.cpp
      @@ -320,7 +320,7 @@ char DebugLabelFolder::ID = 0;
       
       bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
         // Get machine module info.
      -  MachineModuleInfo *MMI = getAnalysisToUpdate();
      +  MachineModuleInfo *MMI = getAnalysisIfAvailable();
         if (!MMI) return false;
         
         // Track if change is made.
      diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp
      index bd389db31f3a..147ccab3a1e4 100644
      --- a/llvm/lib/CodeGen/PHIElimination.cpp
      +++ b/llvm/lib/CodeGen/PHIElimination.cpp
      @@ -174,7 +174,7 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB,
         }
       
         // Update live variable information if there is any.
      -  LiveVariables *LV = getAnalysisToUpdate();
      +  LiveVariables *LV = getAnalysisIfAvailable();
         if (LV) {
           MachineInstr *PHICopy = prior(AfterPHIsIt);
       
      diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
      index 4ebf742a4c31..39f96133bd19 100644
      --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp
      +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp
      @@ -56,7 +56,7 @@ namespace {
       
             // Get MachineModuleInfo so that we can track the construction of the
             // frame.
      -      if (MachineModuleInfo *MMI = getAnalysisToUpdate())
      +      if (MachineModuleInfo *MMI = getAnalysisIfAvailable())
               Fn.getFrameInfo()->setMachineModuleInfo(MMI);
       
             // Allow the target machine to make some adjustments to the function
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
      index ca0cd6e8f515..3ae70c850dae 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
      @@ -314,8 +314,8 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) {
         DOUT << "\n\n\n=== " << Fn.getName() << "\n";
       
         FuncInfo->set(Fn, *MF, EnableFastISel);
      -  MachineModuleInfo *MMI = getAnalysisToUpdate();
      -  DwarfWriter *DW = getAnalysisToUpdate();
      +  MachineModuleInfo *MMI = getAnalysisIfAvailable();
      +  DwarfWriter *DW = getAnalysisIfAvailable();
         CurDAG->init(*MF, MMI, DW);
         SDL->init(GFI, *AA);
       
      diff --git a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
      index 5cf2ffd3771b..794f772101e9 100644
      --- a/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
      +++ b/llvm/lib/CodeGen/TwoAddressInstructionPass.cpp
      @@ -379,7 +379,7 @@ bool TwoAddressInstructionPass::runOnMachineFunction(MachineFunction &MF) {
         MRI = &MF.getRegInfo();
         TII = TM.getInstrInfo();
         TRI = TM.getRegisterInfo();
      -  LV = getAnalysisToUpdate();
      +  LV = getAnalysisIfAvailable();
       
         bool MadeChange = false;
       
      diff --git a/llvm/lib/CodeGen/UnreachableBlockElim.cpp b/llvm/lib/CodeGen/UnreachableBlockElim.cpp
      index c597e5fd7db0..c3b213cebe95 100644
      --- a/llvm/lib/CodeGen/UnreachableBlockElim.cpp
      +++ b/llvm/lib/CodeGen/UnreachableBlockElim.cpp
      @@ -105,7 +105,7 @@ const PassInfo *const llvm::UnreachableMachineBlockElimID = &Y;
       bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
         SmallPtrSet Reachable;
       
      -  MMI = getAnalysisToUpdate();
      +  MMI = getAnalysisIfAvailable();
       
         // Mark all reachable blocks.
         for (df_ext_iterator >
      diff --git a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
      index 12e13466d1b3..83df20cc170b 100644
      --- a/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
      +++ b/llvm/lib/Target/ARM/AsmPrinter/ARMAsmPrinter.cpp
      @@ -782,9 +782,9 @@ bool ARMAsmPrinter::doInitialization(Module &M) {
         bool Result = AsmPrinter::doInitialization(M);
       
         // Emit initial debug information.
      -  MMI = getAnalysisToUpdate();
      +  MMI = getAnalysisIfAvailable();
         assert(MMI);
      -  DW = getAnalysisToUpdate();
      +  DW = getAnalysisIfAvailable();
         assert(DW && "Dwarf Writer is not available");
         DW->BeginModule(&M, MMI, O, this, TAI);
       
      diff --git a/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp b/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
      index 62da3b7493c3..e9b3fc2d26b2 100644
      --- a/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
      +++ b/llvm/lib/Target/CellSPU/AsmPrinter/SPUAsmPrinter.cpp
      @@ -491,9 +491,9 @@ bool LinuxAsmPrinter::doInitialization(Module &M) {
         bool Result = AsmPrinter::doInitialization(M);
         SwitchToTextSection("\t.text");
         // Emit initial debug information.
      -  DW = getAnalysisToUpdate();
      +  DW = getAnalysisIfAvailable();
         assert(DW && "Dwarf Writer is not available");
      -  MMI = getAnalysisToUpdate();
      +  MMI = getAnalysisIfAvailable();
         DW->BeginModule(&M, MMI, O, this, TAI);
         return Result;
       }
      diff --git a/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp b/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
      index 5fe77be04000..5f3ba931faf4 100644
      --- a/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
      +++ b/llvm/lib/Target/PowerPC/AsmPrinter/PPCAsmPrinter.cpp
      @@ -641,9 +641,9 @@ bool PPCLinuxAsmPrinter::doInitialization(Module &M) {
         bool Result = AsmPrinter::doInitialization(M);
       
         // Emit initial debug information.
      -  MMI = getAnalysisToUpdate();
      +  MMI = getAnalysisIfAvailable();
         assert(MMI);
      -  DW = getAnalysisToUpdate();
      +  DW = getAnalysisIfAvailable();
         assert(DW && "DwarfWriter is not available");
         DW->BeginModule(&M, MMI, O, this, TAI);
       
      @@ -859,9 +859,9 @@ bool PPCDarwinAsmPrinter::doInitialization(Module &M) {
         // Emit initial debug information.
         // We need this for Personality functions.
         // AsmPrinter::doInitialization should have done this analysis.
      -  MMI = getAnalysisToUpdate();
      +  MMI = getAnalysisIfAvailable();
         assert(MMI);
      -  DW = getAnalysisToUpdate();
      +  DW = getAnalysisIfAvailable();
         assert(DW && "DwarfWriter is not available");
         DW->BeginModule(&M, MMI, O, this, TAI);
       
      diff --git a/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp b/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
      index e09411a51764..9e0afc8d6f23 100644
      --- a/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
      +++ b/llvm/lib/Target/X86/AsmPrinter/X86ATTAsmPrinter.cpp
      @@ -737,8 +737,8 @@ bool X86ATTAsmPrinter::doInitialization(Module &M) {
           // Let PassManager know we need debug information and relay
           // the MachineModuleInfo address on to DwarfWriter.
           // AsmPrinter::doInitialization did this analysis.
      -    MMI = getAnalysisToUpdate();
      -    DW = getAnalysisToUpdate();
      +    MMI = getAnalysisIfAvailable();
      +    DW = getAnalysisIfAvailable();
           DW->BeginModule(&M, MMI, O, this, TAI);
         }
       
      @@ -975,7 +975,7 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
           }
       
           // Emit final debug information.
      -    DwarfWriter *DW = getAnalysisToUpdate();
      +    DwarfWriter *DW = getAnalysisIfAvailable();
           DW->EndModule();
       
           // Funny Darwin hack: This flag tells the linker that no global symbols
      @@ -995,11 +995,11 @@ bool X86ATTAsmPrinter::doFinalization(Module &M) {
           }
       
           // Emit final debug information.
      -    DwarfWriter *DW = getAnalysisToUpdate();
      +    DwarfWriter *DW = getAnalysisIfAvailable();
           DW->EndModule();
         } else if (Subtarget->isTargetELF()) {
           // Emit final debug information.
      -    DwarfWriter *DW = getAnalysisToUpdate();
      +    DwarfWriter *DW = getAnalysisIfAvailable();
           DW->EndModule();
         }
       
      diff --git a/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp b/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp
      index f966d8564d27..9e6e19fe44fd 100644
      --- a/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp
      +++ b/llvm/lib/Target/XCore/XCoreAsmPrinter.cpp
      @@ -441,9 +441,9 @@ bool XCoreAsmPrinter::doInitialization(Module &M) {
         }
       
         // Emit initial debug information.
      -  DW = getAnalysisToUpdate();
      +  DW = getAnalysisIfAvailable();
         assert(DW && "Dwarf Writer is not available");
      -  DW->BeginModule(&M, getAnalysisToUpdate(), 
      +  DW->BeginModule(&M, getAnalysisIfAvailable(),
                         O, this, TAI);
         return Result;
       }
      diff --git a/llvm/lib/Transforms/IPO/Internalize.cpp b/llvm/lib/Transforms/IPO/Internalize.cpp
      index b226d1959a01..5093ae90b5ba 100644
      --- a/llvm/lib/Transforms/IPO/Internalize.cpp
      +++ b/llvm/lib/Transforms/IPO/Internalize.cpp
      @@ -99,7 +99,7 @@ void InternalizePass::LoadFile(const char *Filename) {
       }
       
       bool InternalizePass::runOnModule(Module &M) {
      -  CallGraph *CG = getAnalysisToUpdate();
      +  CallGraph *CG = getAnalysisIfAvailable();
         CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
       
         if (ExternalNames.empty()) {
      diff --git a/llvm/lib/Transforms/Scalar/LoopRotation.cpp b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
      index aed84e2df87f..65b74b4e7ff5 100644
      --- a/llvm/lib/Transforms/Scalar/LoopRotation.cpp
      +++ b/llvm/lib/Transforms/Scalar/LoopRotation.cpp
      @@ -457,7 +457,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
                  "Expected only one incoming value from Original PreHeader");
         }
       
      -  if (DominatorTree *DT = getAnalysisToUpdate()) {
      +  if (DominatorTree *DT = getAnalysisIfAvailable()) {
           DT->addNewBlock(NewPreHeader, OrigPreHeader);
           DT->changeImmediateDominator(L->getHeader(), NewPreHeader);
           DT->changeImmediateDominator(Exit, OrigPreHeader);
      @@ -473,7 +473,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
           DT->changeImmediateDominator(OrigHeader, OrigLatch);
         }
       
      -  if (DominanceFrontier *DF = getAnalysisToUpdate()) {
      +  if (DominanceFrontier *DF = getAnalysisIfAvailable()) {
           // New Preheader's dominance frontier is Exit block.
           DominanceFrontier::DomSetType NewPHSet;
           NewPHSet.insert(Exit);
      @@ -509,7 +509,7 @@ void LoopRotate::preserveCanonicalLoopForm(LPPassManager &LPM) {
           // If a loop block dominates new loop latch then its frontier is
           // new header and Exit.
           BasicBlock *NewLatch = L->getLoopLatch();
      -    DominatorTree *DT = getAnalysisToUpdate();
      +    DominatorTree *DT = getAnalysisIfAvailable();
           for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end();
                BI != BE; ++BI) {
             BasicBlock *B = *BI;
      diff --git a/llvm/lib/Transforms/Scalar/LoopUnroll.cpp b/llvm/lib/Transforms/Scalar/LoopUnroll.cpp
      index 6d685d58f96b..2025fb682885 100644
      --- a/llvm/lib/Transforms/Scalar/LoopUnroll.cpp
      +++ b/llvm/lib/Transforms/Scalar/LoopUnroll.cpp
      @@ -170,10 +170,10 @@ bool LoopUnroll::runOnLoop(Loop *L, LPPassManager &LPM) {
           return false;
       
         // FIXME: Reconstruct dom info, because it is not preserved properly.
      -  DominatorTree *DT = getAnalysisToUpdate();
      +  DominatorTree *DT = getAnalysisIfAvailable();
         if (DT) {
           DT->runOnFunction(*F);
      -    DominanceFrontier *DF = getAnalysisToUpdate();
      +    DominanceFrontier *DF = getAnalysisIfAvailable();
           if (DF)
             DF->runOnFunction(*F);
         }
      diff --git a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
      index 97aa475a67fe..a563c7a9ee92 100644
      --- a/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
      +++ b/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp
      @@ -188,8 +188,8 @@ static Value *FindLIVLoopCondition(Value *Cond, Loop *L, bool &Changed) {
       bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
         LI = &getAnalysis();
         LPM = &LPM_Ref;
      -  DF = getAnalysisToUpdate();
      -  DT = getAnalysisToUpdate();
      +  DF = getAnalysisIfAvailable();
      +  DT = getAnalysisIfAvailable();
         currentLoop = L;
         Function *F = currentLoop->getHeader()->getParent();
         bool Changed = false;
      diff --git a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
      index 431424ee9f39..7b633b20077d 100644
      --- a/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
      +++ b/llvm/lib/Transforms/Utils/BasicBlockUtils.cpp
      @@ -136,7 +136,7 @@ bool llvm::MergeBlockIntoPredecessor(BasicBlock* BB, Pass* P) {
         
         // Finally, erase the old block and update dominator info.
         if (P) {
      -    if (DominatorTree* DT = P->getAnalysisToUpdate()) {
      +    if (DominatorTree* DT = P->getAnalysisIfAvailable()) {
             DomTreeNode* DTN = DT->getNode(BB);
             DomTreeNode* PredDTN = DT->getNode(PredBB);
         
      @@ -299,11 +299,11 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P) {
         BasicBlock *New = Old->splitBasicBlock(SplitIt, Old->getName()+".split");
       
         // The new block lives in whichever loop the old one did.
      -  if (LoopInfo* LI = P->getAnalysisToUpdate())
      +  if (LoopInfo* LI = P->getAnalysisIfAvailable())
           if (Loop *L = LI->getLoopFor(Old))
             L->addBasicBlockToLoop(New, LI->getBase());
       
      -  if (DominatorTree *DT = P->getAnalysisToUpdate()) 
      +  if (DominatorTree *DT = P->getAnalysisIfAvailable())
           {
             // Old dominates New. New node domiantes all other nodes dominated by Old.
             DomTreeNode *OldNode = DT->getNode(Old);
      @@ -319,7 +319,7 @@ BasicBlock *llvm::SplitBlock(BasicBlock *Old, Instruction *SplitPt, Pass *P) {
               DT->changeImmediateDominator(*I, NewNode);
           }
       
      -  if (DominanceFrontier *DF = P->getAnalysisToUpdate())
      +  if (DominanceFrontier *DF = P->getAnalysisIfAvailable())
           DF->splitBlock(Old);
           
         return New;
      @@ -350,12 +350,12 @@ BasicBlock *llvm::SplitBlockPredecessors(BasicBlock *BB,
           Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB);
         
         // Update dominator tree and dominator frontier if available.
      -  DominatorTree *DT = P ? P->getAnalysisToUpdate() : 0;
      +  DominatorTree *DT = P ? P->getAnalysisIfAvailable() : 0;
         if (DT)
           DT->splitBlock(NewBB);
      -  if (DominanceFrontier *DF = P ? P->getAnalysisToUpdate():0)
      +  if (DominanceFrontier *DF = P ? P->getAnalysisIfAvailable():0)
           DF->splitBlock(NewBB);
      -  AliasAnalysis *AA = P ? P->getAnalysisToUpdate() : 0;
      +  AliasAnalysis *AA = P ? P->getAnalysisIfAvailable() : 0;
         
         
         // Insert a new PHI node into NewBB for every PHI node in BB and that new PHI
      diff --git a/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp b/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
      index a32c01671282..c4fd1eae43cd 100644
      --- a/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
      +++ b/llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
      @@ -187,7 +187,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
         bool NewBBDominatesDestBB = true;
         
         // Should we update DominatorTree information?
      -  if (DominatorTree *DT = P->getAnalysisToUpdate()) {
      +  if (DominatorTree *DT = P->getAnalysisIfAvailable()) {
           DomTreeNode *TINode = DT->getNode(TIBB);
       
           // The new block is not the immediate dominator for any other nodes, but
      @@ -218,7 +218,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
         }
       
         // Should we update DominanceFrontier information?
      -  if (DominanceFrontier *DF = P->getAnalysisToUpdate()) {
      +  if (DominanceFrontier *DF = P->getAnalysisIfAvailable()) {
           // If NewBBDominatesDestBB hasn't been computed yet, do so with DF.
           if (!OtherPreds.empty()) {
             // FIXME: IMPLEMENT THIS!
      @@ -252,7 +252,7 @@ bool llvm::SplitCriticalEdge(TerminatorInst *TI, unsigned SuccNum, Pass *P,
         }
         
         // Update LoopInfo if it is around.
      -  if (LoopInfo *LI = P->getAnalysisToUpdate()) {
      +  if (LoopInfo *LI = P->getAnalysisIfAvailable()) {
           // If one or the other blocks were not in a loop, the new block is not
           // either, and thus LI doesn't need to be updated.
           if (Loop *TIL = LI->getLoopFor(TIBB))
      diff --git a/llvm/lib/Transforms/Utils/CloneLoop.cpp b/llvm/lib/Transforms/Utils/CloneLoop.cpp
      index d52d79598f05..a0306ffa5272 100644
      --- a/llvm/lib/Transforms/Utils/CloneLoop.cpp
      +++ b/llvm/lib/Transforms/Utils/CloneLoop.cpp
      @@ -79,8 +79,8 @@ Loop *llvm::CloneLoop(Loop *OrigL, LPPassManager  *LPM, LoopInfo *LI,
         DominatorTree *DT = NULL;
         DominanceFrontier *DF = NULL;
         if (P) {
      -    DT = P->getAnalysisToUpdate();
      -    DF = P->getAnalysisToUpdate();
      +    DT = P->getAnalysisIfAvailable();
      +    DF = P->getAnalysisIfAvailable();
         }
       
         SmallVector NewBlocks;
      diff --git a/llvm/lib/Transforms/Utils/LoopSimplify.cpp b/llvm/lib/Transforms/Utils/LoopSimplify.cpp
      index af41036252b2..03d273d25d79 100644
      --- a/llvm/lib/Transforms/Utils/LoopSimplify.cpp
      +++ b/llvm/lib/Transforms/Utils/LoopSimplify.cpp
      @@ -112,7 +112,7 @@ FunctionPass *llvm::createLoopSimplifyPass() { return new LoopSimplify(); }
       bool LoopSimplify::runOnFunction(Function &F) {
         bool Changed = false;
         LI = &getAnalysis();
      -  AA = getAnalysisToUpdate();
      +  AA = getAnalysisIfAvailable();
         DT = &getAnalysis();
       
         // Check to see that no blocks (other than the header) in loops have
      @@ -595,6 +595,6 @@ void LoopSimplify::InsertUniqueBackedgeBlock(Loop *L) {
       
         // Update dominator information
         DT->splitBlock(BEBlock);
      -  if (DominanceFrontier *DF = getAnalysisToUpdate())
      +  if (DominanceFrontier *DF = getAnalysisIfAvailable())
           DF->splitBlock(BEBlock);
       }
      diff --git a/llvm/lib/VMCore/Pass.cpp b/llvm/lib/VMCore/Pass.cpp
      index 35cbe906b701..6db5d7e24c5e 100644
      --- a/llvm/lib/VMCore/Pass.cpp
      +++ b/llvm/lib/VMCore/Pass.cpp
      @@ -37,7 +37,7 @@ Pass::~Pass() {
       ModulePass::~ModulePass() { }
       
       bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
      -  return Resolver->getAnalysisToUpdate(AnalysisID, true) != 0;
      +  return Resolver->getAnalysisIfAvailable(AnalysisID, true) != 0;
       }
       
       // dumpPassStructure - Implement the -debug-passes=Structure option
      diff --git a/llvm/lib/VMCore/PassManager.cpp b/llvm/lib/VMCore/PassManager.cpp
      index 690c485fe20d..f2bfaefe0f78 100644
      --- a/llvm/lib/VMCore/PassManager.cpp
      +++ b/llvm/lib/VMCore/PassManager.cpp
      @@ -679,7 +679,7 @@ void PMDataManager::verifyDomInfo(Pass &P, Function &F) {
         if (!VerifyDomInfo || !P.getResolver())
           return;
       
      -  DominatorTree *DT = P.getAnalysisToUpdate();
      +  DominatorTree *DT = P.getAnalysisIfAvailable();
         if (!DT)
           return;
       
      @@ -695,7 +695,7 @@ void PMDataManager::verifyDomInfo(Pass &P, Function &F) {
           assert (0 && "Invalid dominator info");
         }
       
      -  DominanceFrontier *DF = P.getAnalysisToUpdate();
      +  DominanceFrontier *DF = P.getAnalysisIfAvailable();
         if (!DF) 
           return;
       
      @@ -1088,8 +1088,8 @@ PMDataManager::~PMDataManager() {
       
       //===----------------------------------------------------------------------===//
       // NOTE: Is this the right place to define this method ?
      -// getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
      -Pass *AnalysisResolver::getAnalysisToUpdate(AnalysisID ID, bool dir) const {
      +// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
      +Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
         return PM.findAnalysisPass(ID, dir);
       }
       
      -- 
      GitLab
      
      
      From ba21b7d57acb6e75712065bb120cebacb77f7150 Mon Sep 17 00:00:00 2001
      From: Duncan Sands 
      Date: Wed, 28 Jan 2009 14:42:54 +0000
      Subject: [PATCH 350/682] Formatting.
      
      llvm-svn: 63199
      ---
       llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 13 +++++--------
       1 file changed, 5 insertions(+), 8 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
      index 982177cf61e5..b543b9e63fd2 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
      @@ -374,12 +374,9 @@ unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) {
       /// larger then ValueVT then AssertOp can be used to specify whether the extra
       /// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT
       /// (ISD::AssertSext).
      -static SDValue getCopyFromParts(SelectionDAG &DAG,
      -                                  const SDValue *Parts,
      -                                  unsigned NumParts,
      -                                  MVT PartVT,
      -                                  MVT ValueVT,
      -                                  ISD::NodeType AssertOp = ISD::DELETED_NODE) {
      +static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts,
      +                                unsigned NumParts, MVT PartVT, MVT ValueVT,
      +                                ISD::NodeType AssertOp = ISD::DELETED_NODE) {
         assert(NumParts > 0 && "No parts to assemble!");
         const TargetLowering &TLI = DAG.getTargetLoweringInfo();
         SDValue Val = Parts[0];
      @@ -587,8 +584,8 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
             unsigned RoundBits = RoundParts * PartBits;
             unsigned OddParts = NumParts - RoundParts;
             SDValue OddVal = DAG.getNode(ISD::SRL, ValueVT, Val,
      -                                     DAG.getConstant(RoundBits,
      -                                                     TLI.getShiftAmountTy()));
      +                                   DAG.getConstant(RoundBits,
      +                                                   TLI.getShiftAmountTy()));
             getCopyToParts(DAG, OddVal, Parts + RoundParts, OddParts, PartVT);
             if (TLI.isBigEndian())
               // The odd parts were reversed by getCopyToParts - unreverse them.
      -- 
      GitLab
      
      
      From cdca288cf8f313fdaf361eac0682021802661e5b Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Wed, 28 Jan 2009 15:05:42 +0000
      Subject: [PATCH 351/682] Updated checker build.
      
      llvm-svn: 63200
      ---
       clang/www/latest_checker.html.incl | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/clang/www/latest_checker.html.incl b/clang/www/latest_checker.html.incl
      index 2600d753b867..52820d065920 100644
      --- a/clang/www/latest_checker.html.incl
      +++ b/clang/www/latest_checker.html.incl
      @@ -1 +1 @@
      -checker-0.145.tar.bz2 (built January 27, 2009)
      +checker-0.146.tar.bz2 (built January 28, 2009)
      -- 
      GitLab
      
      
      From 49f97d7eb2fe5f49956668f10f7a78072b5497e2 Mon Sep 17 00:00:00 2001
      From: Steve Naroff 
      Date: Wed, 28 Jan 2009 15:51:12 +0000
      Subject: [PATCH 352/682] Remove 'enableLazyBuiltinCreation' argument to
       Sema::LookupDecl(). It is unused.
      
      Even though Sema::LookupDecl() is deprecated, it's still used all over the place. Simplifying the interface will make it easier to understand/optimize/convert.
      
      llvm-svn: 63208
      ---
       clang/lib/Sema/Sema.h          |  1 -
       clang/lib/Sema/SemaDecl.cpp    | 12 +++++-------
       clang/lib/Sema/SemaDeclCXX.cpp |  1 -
       3 files changed, 5 insertions(+), 9 deletions(-)
      
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index 5e67084353ca..65b18d2ddf76 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -784,7 +784,6 @@ public:
                                       DeclarationName Name, LookupCriteria Criteria);
         LookupResult LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
                                 const DeclContext *LookupCtx = 0,
      -                          bool enableLazyBuiltinCreation = true,
                                 bool LookInParent = true,
                                 bool NamespaceNameOnly = false);
       
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 41ecf13563ea..7746917e3b9d 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -39,7 +39,7 @@ Sema::TypeTy *Sema::isTypeName(IdentifierInfo &II, Scope *S,
             return 0;
           DC = static_cast(SS->getScopeRep());
         }
      -  LookupResult Result = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC, false);
      +  LookupResult Result = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC);
       
         Decl *IIDecl = 0;
         switch (Result.getKind()) {
      @@ -263,7 +263,6 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
       Sema::LookupResult
       Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
                        const DeclContext *LookupCtx,
      -                 bool enableLazyBuiltinCreation,
                        bool LookInParent,
                        bool NamespaceNameOnly) {
         LookupCriteria::NameKind Kind;
      @@ -344,8 +343,7 @@ NamespaceDecl *Sema::GetStdNamespace() {
         if (!StdNamespace) {
           IdentifierInfo *StdIdent = &PP.getIdentifierTable().get("std");
           DeclContext *Global = Context.getTranslationUnitDecl();
      -    Decl *Std = LookupDecl(StdIdent, Decl::IDNS_Ordinary,
      -                           0, Global, /*enableLazyBuiltinCreation=*/false);
      +    Decl *Std = LookupDecl(StdIdent, Decl::IDNS_Ordinary, 0, Global);
           StdNamespace = dyn_cast_or_null(Std);
         }
         return StdNamespace;
      @@ -782,7 +780,7 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
              F != FEnd; ++F) {
           if ((*F)->getDeclName()) {
             Decl *PrevDecl = LookupDecl((*F)->getDeclName(), Decl::IDNS_Ordinary,
      -                                  S, Owner, false, false, false);
      +                                  S, Owner, false, false);
             if (PrevDecl && !isa(PrevDecl)) {
               // C++ [class.union]p2:
               //   The names of the members of an anonymous union shall be
      @@ -3237,7 +3235,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
       
         if (II) {
           Decl *PrevDecl 
      -      = LookupDecl(II, Decl::IDNS_Member, S, 0, false, false, false);
      +      = LookupDecl(II, Decl::IDNS_Member, S, 0, false, false);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      @@ -3330,7 +3328,7 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S,
         
         if (II) {
           Decl *PrevDecl 
      -      = LookupDecl(II, Decl::IDNS_Member, S, 0, false, false, false);
      +      = LookupDecl(II, Decl::IDNS_Member, S, 0, false, false);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
      index 14a481eb715f..91a282dd953f 100644
      --- a/clang/lib/Sema/SemaDeclCXX.cpp
      +++ b/clang/lib/Sema/SemaDeclCXX.cpp
      @@ -1378,7 +1378,6 @@ Sema::DeclTy *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
       
           Decl *PrevDecl =
             LookupDecl(II, Decl::IDNS_Ordinary, DeclRegionScope, 0,
      -                /*enableLazyBuiltinCreation=*/false, 
                       /*LookupInParent=*/false);
           
           if (NamespaceDecl *OrigNS = dyn_cast_or_null(PrevDecl)) {
      -- 
      GitLab
      
      
      From aec0f37d11069598111997455602144b293f417d Mon Sep 17 00:00:00 2001
      From: Steve Naroff 
      Date: Wed, 28 Jan 2009 16:09:22 +0000
      Subject: [PATCH 353/682] Remove 'NamespaceNameOnly' argument to
       Sema::LookupDecl(). It is unused.
      
      Even though Sema::LookupDecl() is deprecated, it's still used all over the place. Simplifying the interface will make it easier to understand/optimize/convert.
      
      llvm-svn: 63210
      ---
       clang/lib/Sema/Sema.h           |  3 +--
       clang/lib/Sema/SemaDecl.cpp     | 16 ++++++----------
       clang/lib/Sema/SemaExpr.cpp     |  2 +-
       clang/lib/Sema/SemaExprCXX.cpp  |  3 +--
       clang/lib/Sema/SemaExprObjC.cpp |  4 ++--
       5 files changed, 11 insertions(+), 17 deletions(-)
      
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index 65b18d2ddf76..9206dd53c919 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -784,8 +784,7 @@ public:
                                       DeclarationName Name, LookupCriteria Criteria);
         LookupResult LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
                                 const DeclContext *LookupCtx = 0,
      -                          bool LookInParent = true,
      -                          bool NamespaceNameOnly = false);
      +                          bool LookInParent = true);
       
         bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
                                      SourceLocation NameLoc, 
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 7746917e3b9d..e0cb526c6012 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -215,7 +215,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
       ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
         // The third "scope" argument is 0 since we aren't enabling lazy built-in
         // creation from this context.
      -  Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0, false);
      +  Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0);
         
         return dyn_cast_or_null(IDecl);
       }
      @@ -263,14 +263,10 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
       Sema::LookupResult
       Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
                        const DeclContext *LookupCtx,
      -                 bool LookInParent,
      -                 bool NamespaceNameOnly) {
      +                 bool LookInParent) {
         LookupCriteria::NameKind Kind;
         if (NSI == Decl::IDNS_Ordinary) {
      -    if (NamespaceNameOnly)
      -      Kind = LookupCriteria::Namespace;
      -    else
      -      Kind = LookupCriteria::Ordinary;
      +    Kind = LookupCriteria::Ordinary;
         } else if (NSI == Decl::IDNS_Tag) 
           Kind = LookupCriteria::Tag;
         else {
      @@ -780,7 +776,7 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
              F != FEnd; ++F) {
           if ((*F)->getDeclName()) {
             Decl *PrevDecl = LookupDecl((*F)->getDeclName(), Decl::IDNS_Ordinary,
      -                                  S, Owner, false, false);
      +                                  S, Owner, false);
             if (PrevDecl && !isa(PrevDecl)) {
               // C++ [class.union]p2:
               //   The names of the members of an anonymous union shall be
      @@ -3235,7 +3231,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
       
         if (II) {
           Decl *PrevDecl 
      -      = LookupDecl(II, Decl::IDNS_Member, S, 0, false, false);
      +      = LookupDecl(II, Decl::IDNS_Member, S, 0, false);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      @@ -3328,7 +3324,7 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S,
         
         if (II) {
           Decl *PrevDecl 
      -      = LookupDecl(II, Decl::IDNS_Member, S, 0, false, false);
      +      = LookupDecl(II, Decl::IDNS_Member, S, 0, false);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
      index 48d62729dc96..770404d82ac1 100644
      --- a/clang/lib/Sema/SemaExpr.cpp
      +++ b/clang/lib/Sema/SemaExpr.cpp
      @@ -4034,7 +4034,7 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
           FieldDecl *MemberDecl 
             = dyn_cast_or_null(LookupDecl(OC.U.IdentInfo, 
                                                      Decl::IDNS_Ordinary,
      -                                               S, RD, false, false).getAsDecl());
      +                                               S, RD, false).getAsDecl());
           if (!MemberDecl)
             return Diag(BuiltinLoc, diag::err_typecheck_no_member)
              << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd);
      diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
      index ee40a30ff1c2..55317db5024b 100644
      --- a/clang/lib/Sema/SemaExprCXX.cpp
      +++ b/clang/lib/Sema/SemaExprCXX.cpp
      @@ -61,8 +61,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
           return Diag(OpLoc, diag::err_need_header_before_typeid);
         
         IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
      -  Decl *TypeInfoDecl = LookupDecl(TypeInfoII, Decl::IDNS_Tag,
      -                                  0, StdNs, /*createBuiltins=*/false);
      +  Decl *TypeInfoDecl = LookupDecl(TypeInfoII, Decl::IDNS_Tag, 0, StdNs);
         RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null(TypeInfoDecl);
         if (!TypeInfoRecordDecl)
           return Diag(OpLoc, diag::err_need_header_before_typeid);
      diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
      index f0aa3b76a594..eff259d8faf5 100644
      --- a/clang/lib/Sema/SemaExprObjC.cpp
      +++ b/clang/lib/Sema/SemaExprObjC.cpp
      @@ -210,7 +210,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
           } else {
             // 'super' has been used outside a method context. If a variable named
             // 'super' has been declared, redirect. If not, produce a diagnostic.
      -      Decl *SuperDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, S, false);
      +      Decl *SuperDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, S);
             ValueDecl *VD = dyn_cast_or_null(SuperDecl);
             if (VD) {
               ExprResult ReceiverExpr = new DeclRefExpr(VD, VD->getType(), 
      @@ -235,7 +235,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
         //
         // If necessary, the following lookup could move to getObjCInterfaceDecl().
         if (!ClassDecl) {
      -    Decl *IDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, 0, false);
      +    Decl *IDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, 0);
           if (TypedefDecl *OCTD = dyn_cast_or_null(IDecl)) {
             const ObjCInterfaceType *OCIT;
             OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
      -- 
      GitLab
      
      
      From fb034663885239079329e40d57eb59e32e08fa1a Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Wed, 28 Jan 2009 17:15:10 +0000
      Subject: [PATCH 354/682] Complete semantic checking for typedef redeclarations
       in C++. The rules are slightly different than in C, and now we handle both
       dialects properly.
      
      llvm-svn: 63211
      ---
       .../clang/Basic/DiagnosticSemaKinds.def       |  2 +
       clang/lib/Sema/SemaDecl.cpp                   | 57 +++++++++++++++----
       clang/test/SemaCXX/class.cpp                  |  2 +-
       clang/test/SemaCXX/typedef-redecl.cpp         | 25 +++++++-
       clang/www/cxx_status.html                     | 11 +++-
       5 files changed, 80 insertions(+), 17 deletions(-)
      
      diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      index f73f6ee23fb4..6cc23dd427a5 100644
      --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      @@ -468,6 +468,8 @@ DIAG(err_redefinition_different_kind, ERROR,
            "redefinition of %0 as different kind of symbol")
       DIAG(err_redefinition_different_typedef, ERROR,
            "typedef redefinition with different types (%0 vs %1)")
      +DIAG(err_tag_definition_of_typedef, ERROR,
      +     "definition of type %0 conflicts with typedef of the same name")
       DIAG(err_conflicting_types, ERROR,
            "conflicting types for %0")
       DIAG(err_nested_redefinition, ERROR,
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index e0cb526c6012..22650f525dbb 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -384,23 +384,31 @@ TypedefDecl *Sema::MergeTypeDefDecl(TypedefDecl *New, Decl *OldD) {
           }
           // Fall through - the typedef name was not a builtin type.
         }
      -  // Verify the old decl was also a typedef.
      -  TypedefDecl *Old = dyn_cast(OldD);
      +  // Verify the old decl was also a type.
      +  TypeDecl *Old = dyn_cast(OldD);
         if (!Old) {
      -    Diag(New->getLocation(), diag::err_redefinition_different_kind)
      +    Diag(New->getLocation(), diag::err_redefinition_different_kind) 
             << New->getDeclName();
           if (!objc_types)
             Diag(OldD->getLocation(), diag::note_previous_definition);
           return New;
         }
      -  
      +
      +  // Determine the "old" type we'll use for checking and diagnostics.  
      +  QualType OldType;
      +  if (TypedefDecl *OldTypedef = dyn_cast(Old))
      +    OldType = OldTypedef->getUnderlyingType();
      +  else
      +    OldType = Context.getTypeDeclType(Old);
      +
         // If the typedef types are not identical, reject them in all languages and
         // with any extensions enabled.
      -  if (Old->getUnderlyingType() != New->getUnderlyingType() && 
      -      Context.getCanonicalType(Old->getUnderlyingType()) != 
      +
      +  if (OldType != New->getUnderlyingType() && 
      +      Context.getCanonicalType(OldType) != 
             Context.getCanonicalType(New->getUnderlyingType())) {
           Diag(New->getLocation(), diag::err_redefinition_different_typedef)
      -      << New->getUnderlyingType() << Old->getUnderlyingType();
      +      << New->getUnderlyingType() << OldType;
           if (!objc_types)
             Diag(Old->getLocation(), diag::note_previous_definition);
           return New;
      @@ -1276,8 +1284,10 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
       
         // In C++, the previous declaration we find might be a tag type
         // (class or enum). In this case, the new declaration will hide the
      -  // tag type. 
      -  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag)
      +  // tag type. Note that this does does not apply if we're declaring a
      +  // typedef (C++ [dcl.typedef]p4).
      +  if (PrevDecl && PrevDecl->getIdentifierNamespace() == Decl::IDNS_Tag &&
      +      D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef)
           PrevDecl = 0;
       
         QualType R = GetTypeForDeclarator(D, S);
      @@ -2887,8 +2897,6 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
         }
       
         if (PrevDecl) {    
      -    assert((isa(PrevDecl) || isa(PrevDecl)) &&
      -            "unexpected Decl type");
           if (TagDecl *PrevTagDecl = dyn_cast(PrevDecl)) {
             // If this is a use of a previous tag, or if the tag is already declared
             // in the same scope (so that the definition/declaration completes or
      @@ -2955,7 +2963,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
             // is non-NULL, it's a definition of the tag declared by
             // PrevDecl. If it's NULL, we have a new definition.
           } else {
      -      // PrevDecl is a namespace.
      +      // PrevDecl is a namespace, template, or anything else
      +      // that lives in the IDNS_Tag identifier namespace.
             if (isDeclInScope(PrevDecl, SearchDC, S)) {
               // The tag name clashes with a namespace name, issue an error and
               // recover by making this tag be anonymous.
      @@ -3054,6 +3063,30 @@ CreateNewDecl:
             New->addAttr(new PackedAttr(Alignment * 8));
         }
       
      +  if (getLangOptions().CPlusPlus && SS.isEmpty() && Name && !Invalid) {
      +    // C++ [dcl.typedef]p3:
      +    //   [...] Similarly, in a given scope, a class or enumeration
      +    //   shall not be declared with the same name as a typedef-name
      +    //   that is declared in that scope and refers to a type other
      +    //   than the class or enumeration itself.
      +    LookupResult Lookup = LookupName(S, Name, 
      +                                     LookupCriteria(LookupCriteria::Ordinary, 
      +                                                    true, true));
      +    TypedefDecl *PrevTypedef = 0;
      +    if (Lookup.getKind() == LookupResult::Found)
      +      PrevTypedef = dyn_cast(Lookup.getAsDecl());
      +
      +    if (PrevTypedef && isDeclInScope(PrevTypedef, SearchDC, S) &&
      +        Context.getCanonicalType(Context.getTypeDeclType(PrevTypedef)) !=
      +          Context.getCanonicalType(Context.getTypeDeclType(New))) {
      +      Diag(Loc, diag::err_tag_definition_of_typedef)
      +        << Context.getTypeDeclType(New)
      +        << PrevTypedef->getUnderlyingType();
      +      Diag(PrevTypedef->getLocation(), diag::note_previous_definition);
      +      Invalid = true;
      +    }
      +  }
      +
         if (Invalid)
           New->setInvalidDecl();
       
      diff --git a/clang/test/SemaCXX/class.cpp b/clang/test/SemaCXX/class.cpp
      index d739af87dd79..02608faa0f64 100644
      --- a/clang/test/SemaCXX/class.cpp
      +++ b/clang/test/SemaCXX/class.cpp
      @@ -30,7 +30,7 @@ public:
         func btm : 1; // expected-error {{error: bit-field 'btm' with non-integral type}}
         NestedC bc : 1; // expected-error {{error: bit-field 'bc' with non-integral type}}
       
      -  enum E { en1, en2 };
      +  enum E1 { en1, en2 };
       
         int i = 0; // expected-error {{error: 'i' can only be initialized if it is a static const integral data member}}
         static int si = 0; // expected-error {{error: 'si' can only be initialized if it is a static const integral data member}}
      diff --git a/clang/test/SemaCXX/typedef-redecl.cpp b/clang/test/SemaCXX/typedef-redecl.cpp
      index eabcef8b3198..016882feb2be 100644
      --- a/clang/test/SemaCXX/typedef-redecl.cpp
      +++ b/clang/test/SemaCXX/typedef-redecl.cpp
      @@ -1,12 +1,33 @@
       // RUN: clang -fsyntax-only -verify %s 
      -
       typedef int INT;
       typedef INT REALLY_INT; // expected-note {{previous definition is here}}
       typedef REALLY_INT REALLY_REALLY_INT;
       typedef REALLY_INT BOB;
       typedef float REALLY_INT; // expected-error{{typedef redefinition with different types ('float' vs 'INT')}}
       
      -class X {
      +struct X {
         typedef int result_type; // expected-note {{previous definition is here}}
         typedef INT result_type; // expected-error {{redefinition of 'result_type'}}
       };
      +
      +struct Y; // expected-note{{previous definition is here}}
      +typedef int Y;  // expected-error{{typedef redefinition with different types ('int' vs 'struct Y')}}
      +
      +typedef int Y2; // expected-note{{previous definition is here}}
      +struct Y2; // expected-error{{definition of type 'struct Y2' conflicts with typedef of the same name}}
      +
      +void f(); // expected-note{{previous definition is here}}
      +typedef int f; // expected-error{{redefinition of 'f' as different kind of symbol}}
      +
      +typedef int f2; // expected-note{{previous definition is here}}
      +void f2(); // expected-error{{redefinition of 'f2' as different kind of symbol}}
      +
      +typedef struct s s; 
      +typedef int I; 
      +typedef int I; 
      +typedef I I; 
      +
      +struct s { };
      +
      +typedef class st { /* ... */ } st; // expected-note{{previous use is here}}
      +struct st; // expected-error{{use of 'st' with tag type that does not match previous declaration}}
      diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html
      index a83157b193e2..22a419af5eea 100644
      --- a/clang/www/cxx_status.html
      +++ b/clang/www/cxx_status.html
      @@ -944,13 +944,20 @@ welcome!

      ✓ ✓ - I think we handle everything. + 7 [dcl.dcl]   7.1 [dcl.spec]     7.1.1 [dcl.stc]     7.1.2 [dcl.fct.spec] -    7.1.3 [dcl.typedef] + +     7.1.3 [dcl.typedef] + ✓ + ✓ + ✓ + + Typedefs of anonymous tag types do not use the name of the typedef for linkage purposes. +     7.1.4 [dcl.friend]     7.1.5 [dcl.type]       7.1.5.1 [dcl.type.cv] -- GitLab From 4aa1846215adde37dea5b534d5278a96addcc324 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 17:46:25 +0000 Subject: [PATCH 355/682] Make isOperationLegal do what its name suggests, and introduce a new isOperationLegalOrCustom, which does what isOperationLegal previously did. Update a bunch of callers to use isOperationLegalOrCustom instead of isOperationLegal. In some case it wasn't obvious which behavior is desired; when in doubt I changed then to isOperationLegalOrCustom as that preserves their previous behavior. This is for the second half of PR3376. llvm-svn: 63212 --- llvm/include/llvm/Target/TargetLowering.h | 12 ++++- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 32 +++++------ llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 53 ++++++++++--------- .../SelectionDAG/LegalizeIntegerTypes.cpp | 20 +++---- .../SelectionDAG/SelectionDAGBuild.cpp | 4 +- .../CodeGen/SelectionDAG/TargetLowering.cpp | 8 +-- 6 files changed, 72 insertions(+), 57 deletions(-) diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index 23238ad9e053..e6f18ea43f87 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -340,12 +340,20 @@ public: return (LegalizeAction)((OpActions[Op] >> (2*VT.getSimpleVT())) & 3); } + /// isOperationLegalOrCustom - Return true if the specified operation is + /// legal on this target or can be made legal with custom lowering. This + /// is used to help guide high-level lowering decisions. + bool isOperationLegalOrCustom(unsigned Op, MVT VT) const { + return (VT == MVT::Other || isTypeLegal(VT)) && + (getOperationAction(Op, VT) == Legal || + getOperationAction(Op, VT) == Custom); + } + /// isOperationLegal - Return true if the specified operation is legal on this /// target. bool isOperationLegal(unsigned Op, MVT VT) const { return (VT == MVT::Other || isTypeLegal(VT)) && - (getOperationAction(Op, VT) == Legal || - getOperationAction(Op, VT) == Custom); + getOperationAction(Op, VT) == Legal; } /// getLoadExtAction - Return how this load with extension should be treated: diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d4df880d0be5..48e556b2362d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2054,8 +2054,8 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { if (!TLI.isTypeLegal(VT)) return 0; // The target must have at least one rotate flavor. - bool HasROTL = TLI.isOperationLegal(ISD::ROTL, VT); - bool HasROTR = TLI.isOperationLegal(ISD::ROTR, VT); + bool HasROTL = TLI.isOperationLegalOrCustom(ISD::ROTL, VT); + bool HasROTR = TLI.isOperationLegalOrCustom(ISD::ROTR, VT); if (!HasROTL && !HasROTR) return 0; // Match "(X shl/srl V1) & V2" where V2 may not be present. @@ -2541,8 +2541,8 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { // on that type, and the the truncate to that type is both legal and free, // perform the transform. if (ShiftAmt && - TLI.isOperationLegal(ISD::SIGN_EXTEND, TruncVT) && - TLI.isOperationLegal(ISD::TRUNCATE, VT) && + TLI.isOperationLegalOrCustom(ISD::SIGN_EXTEND, TruncVT) && + TLI.isOperationLegalOrCustom(ISD::TRUNCATE, VT) && TLI.isTruncateFree(VT, TruncVT)) { SDValue Amt = DAG.getConstant(ShiftAmt, TLI.getShiftAmountTy()); @@ -2795,7 +2795,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { // Check against MVT::Other for SELECT_CC, which is a workaround for targets // having to say they don't support SELECT_CC on every type the DAG knows // about, since there is no way to mark an opcode illegal at all value types - if (TLI.isOperationLegal(ISD::SELECT_CC, MVT::Other)) + if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) return DAG.getNode(ISD::SELECT_CC, VT, N0.getOperand(0), N0.getOperand(1), N1, N2, N0.getOperand(2)); else @@ -4032,8 +4032,8 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) { // If the input is a legal type, and SINT_TO_FP is not legal on this target, // but UINT_TO_FP is legal on this target, try to convert. - if (!TLI.isOperationLegal(ISD::SINT_TO_FP, OpVT) && - TLI.isOperationLegal(ISD::UINT_TO_FP, OpVT)) { + if (!TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, OpVT) && + TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, OpVT)) { // If the sign bit is known to be zero, we can change this to UINT_TO_FP. if (DAG.SignBitIsZero(N0)) return DAG.getNode(ISD::UINT_TO_FP, VT, N0); @@ -4055,8 +4055,8 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) { // If the input is a legal type, and UINT_TO_FP is not legal on this target, // but SINT_TO_FP is legal on this target, try to convert. - if (!TLI.isOperationLegal(ISD::UINT_TO_FP, OpVT) && - TLI.isOperationLegal(ISD::SINT_TO_FP, OpVT)) { + if (!TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, OpVT) && + TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, OpVT)) { // If the sign bit is known to be zero, we can change this to SINT_TO_FP. if (DAG.SignBitIsZero(N0)) return DAG.getNode(ISD::SINT_TO_FP, VT, N0); @@ -4252,7 +4252,7 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) { // fold a brcond with a setcc condition into a BR_CC node if BR_CC is legal // on the target. if (N1.getOpcode() == ISD::SETCC && - TLI.isOperationLegal(ISD::BR_CC, MVT::Other)) { + TLI.isOperationLegalOrCustom(ISD::BR_CC, MVT::Other)) { return DAG.getNode(ISD::BR_CC, MVT::Other, Chain, N1.getOperand(2), N1.getOperand(0), N1.getOperand(1), N2); } @@ -4726,7 +4726,7 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { getABITypeAlignment(SVT.getTypeForMVT()); if (Align <= OrigAlign && ((!LegalOperations && !ST->isVolatile()) || - TLI.isOperationLegal(ISD::STORE, SVT))) + TLI.isOperationLegalOrCustom(ISD::STORE, SVT))) return DAG.getStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign); } @@ -4747,7 +4747,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { break; case MVT::f32: if (((TLI.isTypeLegal(MVT::i32) || !LegalTypes) && !LegalOperations && - !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, MVT::i32)) { + !ST->isVolatile()) || + TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) { Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF(). bitcastToAPInt().getZExtValue(), MVT::i32); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), @@ -4757,14 +4758,15 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { break; case MVT::f64: if (((TLI.isTypeLegal(MVT::i64) || !LegalTypes) && !LegalOperations && - !ST->isVolatile()) || TLI.isOperationLegal(ISD::STORE, MVT::i64)) { + !ST->isVolatile()) || + TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i64)) { Tmp = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). getZExtValue(), MVT::i64); return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); } else if (!ST->isVolatile() && - TLI.isOperationLegal(ISD::STORE, MVT::i32)) { + TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) { // Many FP stores are not made apparent until after legalize, e.g. for // argument passing. Since this is so common, custom legalize the // 64-bit integer store into two 32-bit stores. @@ -4967,7 +4969,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { // original load. unsigned NewAlign = TLI.getTargetData()-> getABITypeAlignment(LVT.getTypeForMVT()); - if (NewAlign > Align || !TLI.isOperationLegal(ISD::LOAD, LVT)) + if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD, LVT)) return SDValue(); Align = NewAlign; } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 2183431e1aa8..5b8d18ce2141 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1263,8 +1263,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { default: assert(0 && "This action is not supported yet!"); case TargetLowering::Expand: { DwarfWriter *DW = DAG.getDwarfWriter(); - bool useDEBUG_LOC = TLI.isOperationLegal(ISD::DEBUG_LOC, MVT::Other); - bool useLABEL = TLI.isOperationLegal(ISD::DBG_LABEL, MVT::Other); + bool useDEBUG_LOC = TLI.isOperationLegalOrCustom(ISD::DEBUG_LOC, + MVT::Other); + bool useLABEL = TLI.isOperationLegalOrCustom(ISD::DBG_LABEL, MVT::Other); const DbgStopPointSDNode *DSP = cast(Node); GlobalVariable *CU_GV = cast(DSP->getCompileUnit()); @@ -3065,7 +3066,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { "Fell off of the edge of the floating point world"); // If the target supports SETCC of this type, use it. - if (TLI.isOperationLegal(ISD::SETCC, NewInTy)) + if (TLI.isOperationLegalOrCustom(ISD::SETCC, NewInTy)) break; } if (NewInTy.isInteger()) @@ -3228,10 +3229,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // and unsigned forms. If the target supports both SMUL_LOHI and // UMUL_LOHI, form a preference by checking which forms of plain // MULH it supports. - bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, VT); - bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, VT); - bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, VT); - bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, VT); + bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT); + bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT); + bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT); + bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT); unsigned OpToUse = 0; if (HasSMUL_LOHI && !HasMULHS) { OpToUse = ISD::SMUL_LOHI; @@ -3248,25 +3249,25 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { } } if (Node->getOpcode() == ISD::MULHS && - TLI.isOperationLegal(ISD::SMUL_LOHI, VT)) { + TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) { Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, VTs, Tmp1, Tmp2).getNode(), 1); break; } if (Node->getOpcode() == ISD::MULHU && - TLI.isOperationLegal(ISD::UMUL_LOHI, VT)) { + TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) { Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, VTs, Tmp1, Tmp2).getNode(), 1); break; } if (Node->getOpcode() == ISD::SDIV && - TLI.isOperationLegal(ISD::SDIVREM, VT)) { + TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(), 0); break; } if (Node->getOpcode() == ISD::UDIV && - TLI.isOperationLegal(ISD::UDIVREM, VT)) { + TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(), 0); break; @@ -3510,12 +3511,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // See if remainder can be lowered using two-result operations. SDVTList VTs = DAG.getVTList(VT, VT); if (Node->getOpcode() == ISD::SREM && - TLI.isOperationLegal(ISD::SDIVREM, VT)) { + TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(), 1); break; } if (Node->getOpcode() == ISD::UREM && - TLI.isOperationLegal(ISD::UDIVREM, VT)) { + TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(), 1); break; } @@ -4639,8 +4640,8 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not // legal, such as PowerPC. if (Node->getOpcode() == ISD::FP_TO_UINT && - !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && - (TLI.isOperationLegal(ISD::FP_TO_SINT, NVT) || + !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) && + (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT) || TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)){ Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1); } else { @@ -5549,7 +5550,8 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { &MaskVec[0], MaskVec.size()); // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it. - if (TLI.isOperationLegal(ISD::SCALAR_TO_VECTOR, Node->getValueType(0)) && + if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, + Node->getValueType(0)) && isShuffleLegal(Node->getValueType(0), ShuffleMask)) { Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val1); Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val2); @@ -6330,8 +6332,8 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { SDValue Tmp3 = DAG.getNode(ISD::AND, VT, DAG.getNOT(Op, VT), DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT))); // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. - if (!TLI.isOperationLegal(ISD::CTPOP, VT) && - TLI.isOperationLegal(ISD::CTLZ, VT)) + if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && + TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) return DAG.getNode(ISD::SUB, VT, DAG.getConstant(VT.getSizeInBits(), VT), DAG.getNode(ISD::CTLZ, VT, Tmp3)); @@ -6821,8 +6823,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // If ADDC/ADDE are supported and if the shift amount is a constant 1, emit // this X << 1 as X+X. if (ConstantSDNode *ShAmt = dyn_cast(ShiftAmt)) { - if (ShAmt->getAPIntValue() == 1 && TLI.isOperationLegal(ISD::ADDC, NVT) && - TLI.isOperationLegal(ISD::ADDE, NVT)) { + if (ShAmt->getAPIntValue() == 1 && + TLI.isOperationLegalOrCustom(ISD::ADDC, NVT) && + TLI.isOperationLegalOrCustom(ISD::ADDE, NVT)) { SDValue LoOps[2], HiOps[3]; ExpandOp(Node->getOperand(0), LoOps[0], HiOps[0]); SDVTList VTList = DAG.getVTList(LoOps[0].getValueType(), MVT::Flag); @@ -6944,7 +6947,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ bool hasCarry = false; for (unsigned BitSize = NVT.getSizeInBits(); BitSize != 0; BitSize /= 2) { MVT AVT = MVT::getIntegerVT(BitSize); - if (TLI.isOperationLegal(OpV, AVT)) { + if (TLI.isOperationLegalOrCustom(OpV, AVT)) { hasCarry = true; break; } @@ -7041,10 +7044,10 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ } } - bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT); - bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT); - bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT); - bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT); + bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT); + bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT); + bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT); + bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT); if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { SDValue LL, LH, RL, RH; ExpandOp(Node->getOperand(0), LL, LH); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index b5b249a2254b..f3897fad1d05 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -345,8 +345,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { // FP_TO_UINT for small destination sizes on targets where FP_TO_UINT is not // legal, such as PowerPC. if (N->getOpcode() == ISD::FP_TO_UINT && - !TLI.isOperationLegal(ISD::FP_TO_UINT, NVT) && - TLI.isOperationLegal(ISD::FP_TO_SINT, NVT)) + !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) && + TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT)) NewOpc = ISD::FP_TO_SINT; SDValue Res = DAG.getNode(NewOpc, NVT, N->getOperand(0)); @@ -1008,7 +1008,8 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, Lo = DAG.getConstant(0, NVT); Hi = InL; } else if (Amt == 1 && - TLI.isOperationLegal(ISD::ADDC, TLI.getTypeToExpandTo(NVT))) { + TLI.isOperationLegalOrCustom(ISD::ADDC, + TLI.getTypeToExpandTo(NVT))) { // Emit this X << 1 as X+X. SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); SDValue LoOps[2] = { InL, InL }; @@ -1166,8 +1167,9 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, // a carry of type MVT::Flag, but there doesn't seem to be any way to // generate a value of this type in the expanded code sequence. bool hasCarry = - TLI.isOperationLegal(N->getOpcode() == ISD::ADD ? ISD::ADDC : ISD::SUBC, - TLI.getTypeToExpandTo(NVT)); + TLI.isOperationLegalOrCustom(N->getOpcode() == ISD::ADD ? + ISD::ADDC : ISD::SUBC, + TLI.getTypeToExpandTo(NVT)); if (hasCarry) { SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); @@ -1513,10 +1515,10 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); - bool HasMULHS = TLI.isOperationLegal(ISD::MULHS, NVT); - bool HasMULHU = TLI.isOperationLegal(ISD::MULHU, NVT); - bool HasSMUL_LOHI = TLI.isOperationLegal(ISD::SMUL_LOHI, NVT); - bool HasUMUL_LOHI = TLI.isOperationLegal(ISD::UMUL_LOHI, NVT); + bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT); + bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT); + bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, NVT); + bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, NVT); if (HasMULHU || HasMULHS || HasUMUL_LOHI || HasSMUL_LOHI) { SDValue LL, LH, RL, RH; GetExpandedInteger(N->getOperand(0), LL, LH); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index b543b9e63fd2..a0154cb0a0d4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -1588,8 +1588,8 @@ bool SelectionDAGLowering::handleSmallSwitchRange(CaseRec& CR, static inline bool areJTsAllowed(const TargetLowering &TLI) { return !DisableJumpTables && - (TLI.isOperationLegal(ISD::BR_JT, MVT::Other) || - TLI.isOperationLegal(ISD::BRIND, MVT::Other)); + (TLI.isOperationLegalOrCustom(ISD::BR_JT, MVT::Other) || + TLI.isOperationLegalOrCustom(ISD::BRIND, MVT::Other)); } static APInt ComputeRange(const APInt &First, const APInt &Last) { diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index cd5df4ff0911..7245244684d0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -2365,10 +2365,10 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, // Multiply the numerator (operand 0) by the magic value // FIXME: We should support doing a MUL in a wider type SDValue Q; - if (isOperationLegal(ISD::MULHS, VT)) + if (isOperationLegalOrCustom(ISD::MULHS, VT)) Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0), DAG.getConstant(magics.m, VT)); - else if (isOperationLegal(ISD::SMUL_LOHI, VT)) + else if (isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(VT, VT), N->getOperand(0), DAG.getConstant(magics.m, VT)).getNode(), 1); @@ -2423,10 +2423,10 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, // Multiply the numerator (operand 0) by the magic value // FIXME: We should support doing a MUL in a wider type SDValue Q; - if (isOperationLegal(ISD::MULHU, VT)) + if (isOperationLegalOrCustom(ISD::MULHU, VT)) Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), DAG.getConstant(magics.m, VT)); - else if (isOperationLegal(ISD::UMUL_LOHI, VT)) + else if (isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(VT, VT), N->getOperand(0), DAG.getConstant(magics.m, VT)).getNode(), 1); -- GitLab From ff2d99d94b2cc3c167aac92c2dff566fa9d0f39d Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 28 Jan 2009 17:49:03 +0000 Subject: [PATCH 356/682] Enable PACKAGE_VERSION in cmake builds, this unbreaks the clang build with cmake. Patch by Piotr Rak! llvm-svn: 63213 --- llvm/CMakeLists.txt | 3 ++- llvm/include/llvm/Config/config.h.cmake | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt index 2072c703715d..3dcc5e4f7ff0 100644 --- a/llvm/CMakeLists.txt +++ b/llvm/CMakeLists.txt @@ -2,7 +2,8 @@ project(LLVM) cmake_minimum_required(VERSION 2.6.1) set(PACKAGE_NAME llvm) -set(PACKAGE_VERSION svn) +set(PACKAGE_VERSION 2.6svn) +set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvmbugs@cs.uiuc.edu") if( CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE ) diff --git a/llvm/include/llvm/Config/config.h.cmake b/llvm/include/llvm/Config/config.h.cmake index d5e286b7dc98..12846fe8649a 100644 --- a/llvm/include/llvm/Config/config.h.cmake +++ b/llvm/include/llvm/Config/config.h.cmake @@ -507,7 +507,7 @@ #cmakedefine PACKAGE_NAME "${PACKAGE_NAME}" /* Define to the full name and version of this package. */ -#undef PACKAGE_STRING +#cmakedefine PACKAGE_STRING "${PACKAGE_STRING}" /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME -- GitLab From e7d7b0c2fd6af35434678bc097eb981a9aa73a13 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 18:03:09 +0000 Subject: [PATCH 357/682] Delete unnecessary elses. llvm-svn: 63214 --- llvm/include/llvm/CodeGen/DAGISelHeader.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/include/llvm/CodeGen/DAGISelHeader.h b/llvm/include/llvm/CodeGen/DAGISelHeader.h index 28b227772a51..6c040f47f60a 100644 --- a/llvm/include/llvm/CodeGen/DAGISelHeader.h +++ b/llvm/include/llvm/CodeGen/DAGISelHeader.h @@ -31,9 +31,9 @@ SelectionDAG::allnodes_iterator ISelPosition; static bool IsChainCompatible(SDNode *Chain, SDNode *Op) { if (Chain->getOpcode() == ISD::EntryToken) return true; - else if (Chain->getOpcode() == ISD::TokenFactor) + if (Chain->getOpcode() == ISD::TokenFactor) return false; - else if (Chain->getNumOperands() > 0) { + if (Chain->getNumOperands() > 0) { SDValue C0 = Chain->getOperand(0); if (C0.getValueType() == MVT::Other) return C0.getNode() != Op && IsChainCompatible(C0.getNode(), Op); -- GitLab From ed8f2003185cc08916eec500df1d1c0cb88de889 Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Wed, 28 Jan 2009 18:33:18 +0000 Subject: [PATCH 358/682] Implement pointer to member handling in static_cast. Fix a stupid mistake in UnwrapSimilarPointers that made any two member pointers compatible as long as the pointee was the same. Make a few style corrections as suggested by Chris. llvm-svn: 63215 --- .../clang/Basic/DiagnosticSemaKinds.def | 6 +- clang/lib/Sema/SemaInherit.cpp | 9 +- clang/lib/Sema/SemaNamedCast.cpp | 67 ++++++++++++++- clang/lib/Sema/SemaOverload.cpp | 85 +++++++++---------- clang/lib/Sema/SemaType.cpp | 4 +- clang/test/SemaCXX/member-pointer.cpp | 3 + clang/test/SemaCXX/static-cast.cpp | 12 ++- clang/www/cxx_status.html | 4 +- 8 files changed, 133 insertions(+), 57 deletions(-) diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index 6cc23dd427a5..2959f6186b74 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -999,9 +999,9 @@ DIAG(err_duplicate_base_class, ERROR, // FIXME: better way to display derivation? Pass entire thing into diagclient? DIAG(err_ambiguous_derived_to_base_conv, ERROR, "ambiguous conversion from derived class %0 to base class %1:%2") -DIAG(err_ambiguous_base_to_derived_memptr_conv, ERROR, - "ambiguous conversion from pointer to member of base class %0 " - "to pointer to member of derived class %1:%2") +DIAG(err_ambiguous_memptr_conv, ERROR, + "ambiguous conversion from pointer to member of %select{base|derived}0 " + "class %1 to pointer to member of %select{derived|base}0 class %2:%3") DIAG(err_memptr_conv_via_virtual, ERROR, "conversion from pointer to member of class %0 to pointer to member " "of class %1 via virtual base %2 is not allowed") diff --git a/clang/lib/Sema/SemaInherit.cpp b/clang/lib/Sema/SemaInherit.cpp index b5bd8939ad41..307c5275043f 100644 --- a/clang/lib/Sema/SemaInherit.cpp +++ b/clang/lib/Sema/SemaInherit.cpp @@ -218,9 +218,9 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, /*DetectVirtual=*/false); bool DerivationOkay = IsDerivedFrom(Derived, Base, Paths); - assert(DerivationOkay && "Can only be used with a derived-to-base conversion"); - if (!DerivationOkay) - return true; + assert(DerivationOkay && + "Can only be used with a derived-to-base conversion"); + (void)DerivationOkay; if (!Paths.isAmbiguous(Context.getCanonicalType(Base).getUnqualifiedType())) return false; @@ -235,8 +235,7 @@ Sema::CheckDerivedToBaseConversion(QualType Derived, QualType Base, Paths.setRecordingPaths(true); bool StillOkay = IsDerivedFrom(Derived, Base, Paths); assert(StillOkay && "Can only be used with a derived-to-base conversion"); - if (!StillOkay) - return true; + (void)StillOkay; // Build up a textual representation of the ambiguous paths, e.g., // D -> B -> A, that will be used to illustrate the ambiguous diff --git a/clang/lib/Sema/SemaNamedCast.cpp b/clang/lib/Sema/SemaNamedCast.cpp index e88a3b2079f2..cac76b63e4ca 100644 --- a/clang/lib/Sema/SemaNamedCast.cpp +++ b/clang/lib/Sema/SemaNamedCast.cpp @@ -44,6 +44,8 @@ static TryStaticCastResult TryStaticReferenceDowncast( Sema &Self, Expr *SrcExpr, QualType DestType, const SourceRange &OpRange); static TryStaticCastResult TryStaticPointerDowncast( Sema &Self, QualType SrcType, QualType DestType, const SourceRange &OpRange); +static TryStaticCastResult TryStaticMemberPointerUpcast( + Sema &Self, QualType SrcType, QualType DestType, const SourceRange &OpRange); static TryStaticCastResult TryStaticDowncast(Sema &Self, QualType SrcType, QualType DestType, const SourceRange &OpRange, @@ -479,10 +481,13 @@ CheckStaticCast(Sema &Self, Expr *&SrcExpr, QualType DestType, return; } - // Reverse member pointer conversion. C++ 5.11 specifies member pointer + // Reverse member pointer conversion. C++ 4.11 specifies member pointer // conversion. C++ 5.2.9p9 has additional information. // DR54's access restrictions apply here also. - // FIXME: Don't have member pointers yet. + if (TryStaticMemberPointerUpcast(Self, SrcType, DestType, OpRange) + > TSC_NotApplicable) { + return; + } // Reverse pointer conversion to void*. C++ 4.10.p2 specifies conversion to // void*. C++ 5.2.9p10 specifies additional restrictions, which really is @@ -655,6 +660,64 @@ TryStaticDowncast(Sema &Self, QualType SrcType, QualType DestType, return TSC_Success; } +/// TryStaticMemberPointerUpcast - Tests whether a conversion according to +/// C++ 5.2.9p9 is valid: +/// +/// An rvalue of type "pointer to member of D of type cv1 T" can be +/// converted to an rvalue of type "pointer to member of B of type cv2 T", +/// where B is a base class of D [...]. +/// +TryStaticCastResult +TryStaticMemberPointerUpcast(Sema &Self, QualType SrcType, QualType DestType, + const SourceRange &OpRange) +{ + const MemberPointerType *SrcMemPtr = SrcType->getAsMemberPointerType(); + if (!SrcMemPtr) + return TSC_NotApplicable; + const MemberPointerType *DestMemPtr = DestType->getAsMemberPointerType(); + if (!DestMemPtr) + return TSC_NotApplicable; + + // T == T, modulo cv + if (Self.Context.getCanonicalType( + SrcMemPtr->getPointeeType().getUnqualifiedType()) != + Self.Context.getCanonicalType(DestMemPtr->getPointeeType(). + getUnqualifiedType())) + return TSC_NotApplicable; + + // B base of D + QualType SrcClass(SrcMemPtr->getClass(), 0); + QualType DestClass(DestMemPtr->getClass(), 0); + BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, + /*DetectVirtual=*/true); + if (!Self.IsDerivedFrom(SrcClass, DestClass, Paths)) { + return TSC_NotApplicable; + } + + // B is a base of D. But is it an allowed base? If not, it's a hard error. + if (Paths.isAmbiguous(DestClass)) { + Paths.clear(); + Paths.setRecordingPaths(true); + bool StillOkay = Self.IsDerivedFrom(SrcClass, DestClass, Paths); + assert(StillOkay); + StillOkay = StillOkay; + std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths); + Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv) + << 1 << SrcClass << DestClass << PathDisplayStr << OpRange; + return TSC_Failed; + } + + if (const CXXRecordType *VBase = Paths.getDetectedVirtual()) { + Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual) + << SrcClass << DestClass << QualType(VBase, 0) << OpRange; + return TSC_Failed; + } + + // FIXME: Test accessibility. + + return TSC_Success; +} + /// TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 /// is valid: /// diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index b2ae90b4b875..0f9f0cf9c6aa 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -1087,51 +1087,50 @@ bool Sema::IsMemberPointerConversion(Expr *From, QualType FromType, /// otherwise. bool Sema::CheckMemberPointerConversion(Expr *From, QualType ToType) { QualType FromType = From->getType(); + const MemberPointerType *FromPtrType = FromType->getAsMemberPointerType(); + if (!FromPtrType) + return false; - if (const MemberPointerType *FromPtrType = - FromType->getAsMemberPointerType()) { - if (const MemberPointerType *ToPtrType = - ToType->getAsMemberPointerType()) { - QualType FromClass = QualType(FromPtrType->getClass(), 0); - QualType ToClass = QualType(ToPtrType->getClass(), 0); - - // FIXME: What about dependent types? - assert(FromClass->isRecordType() && "Pointer into non-class."); - assert(ToClass->isRecordType() && "Pointer into non-class."); - - BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, - /*DetectVirtual=*/true); - bool DerivationOkay = IsDerivedFrom(ToClass, FromClass, Paths); - assert(DerivationOkay && - "Should not have been called if derivation isn't OK."); - if (!DerivationOkay) - return true; - - if (Paths.isAmbiguous(Context.getCanonicalType(FromClass). - getUnqualifiedType())) { - // Derivation is ambiguous. Redo the check to find the exact paths. - Paths.clear(); - Paths.setRecordingPaths(true); - bool StillOkay = IsDerivedFrom(ToClass, FromClass, Paths); - assert(StillOkay && "Derivation changed due to quantum fluctuation."); - if (!StillOkay) - return true; - - std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); - Diag(From->getExprLoc(), - diag::err_ambiguous_base_to_derived_memptr_conv) - << FromClass << ToClass << PathDisplayStr << From->getSourceRange(); - return true; - } + const MemberPointerType *ToPtrType = ToType->getAsMemberPointerType(); + assert(ToPtrType && "No member pointer cast has a target type " + "that is not a member pointer."); + + QualType FromClass = QualType(FromPtrType->getClass(), 0); + QualType ToClass = QualType(ToPtrType->getClass(), 0); + + // FIXME: What about dependent types? + assert(FromClass->isRecordType() && "Pointer into non-class."); + assert(ToClass->isRecordType() && "Pointer into non-class."); + + BasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/false, + /*DetectVirtual=*/true); + bool DerivationOkay = IsDerivedFrom(ToClass, FromClass, Paths); + assert(DerivationOkay && + "Should not have been called if derivation isn't OK."); + (void)DerivationOkay; + + if (Paths.isAmbiguous(Context.getCanonicalType(FromClass). + getUnqualifiedType())) { + // Derivation is ambiguous. Redo the check to find the exact paths. + Paths.clear(); + Paths.setRecordingPaths(true); + bool StillOkay = IsDerivedFrom(ToClass, FromClass, Paths); + assert(StillOkay && "Derivation changed due to quantum fluctuation."); + (void)StillOkay; + + std::string PathDisplayStr = getAmbiguousPathsDisplayString(Paths); + Diag(From->getExprLoc(), diag::err_ambiguous_memptr_conv) + << 0 << FromClass << ToClass << PathDisplayStr << From->getSourceRange(); + return true; + } - if (const CXXRecordType *VBase = Paths.getDetectedVirtual()) { - Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual) - << FromClass << ToClass << QualType(VBase, 0) - << From->getSourceRange(); - return true; - } - } + if (const CXXRecordType *VBase = Paths.getDetectedVirtual()) { + Diag(From->getExprLoc(), diag::err_memptr_conv_via_virtual) + << FromClass << ToClass << QualType(VBase, 0) + << From->getSourceRange(); + return true; } + return false; } @@ -1148,7 +1147,7 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) // qualification conversion. if (FromType == ToType) return false; - + // (C++ 4.4p4): // A conversion can add cv-qualifiers at levels other than the first // in multi-level pointers, subject to the following rules: [...] diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 60219fe29272..5d54f463ea19 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -662,7 +662,9 @@ bool Sema::UnwrapSimilarPointerTypes(QualType& T1, QualType& T2) const MemberPointerType *T1MPType = T1->getAsMemberPointerType(), *T2MPType = T2->getAsMemberPointerType(); - if (T1MPType && T2MPType) { + if (T1MPType && T2MPType && + Context.getCanonicalType(T1MPType->getClass()) == + Context.getCanonicalType(T2MPType->getClass())) { T1 = T1MPType->getPointeeType(); T2 = T2MPType->getPointeeType(); return true; diff --git a/clang/test/SemaCXX/member-pointer.cpp b/clang/test/SemaCXX/member-pointer.cpp index bcd3dd65e84f..31973c125700 100644 --- a/clang/test/SemaCXX/member-pointer.cpp +++ b/clang/test/SemaCXX/member-pointer.cpp @@ -36,4 +36,7 @@ void f() { // Fail conversion due to ambiguity and virtuality. int F::*pdif = pdi1; // expected-error {{ambiguous conversion from pointer to member of base class 'struct A' to pointer to member of derived class 'struct F'}} expected-error {{incompatible type}} int G::*pdig = pdi1; // expected-error {{conversion from pointer to member of class 'struct A' to pointer to member of class 'struct G' via virtual base 'struct D' is not allowed}} expected-error {{incompatible type}} + + // Conversion to member of base. + pdi1 = pdid; // expected-error {{incompatible type assigning 'int struct D::*', expected 'int struct A::*'}} } diff --git a/clang/test/SemaCXX/static-cast.cpp b/clang/test/SemaCXX/static-cast.cpp index 464ea79aed97..9bbcdf670be9 100644 --- a/clang/test/SemaCXX/static-cast.cpp +++ b/clang/test/SemaCXX/static-cast.cpp @@ -42,6 +42,8 @@ void t_529_2() (void)static_cast(*((C1*)0)); (void)static_cast((D*)0); (void)static_cast(*((D*)0)); + (void)static_cast((int A::*)0); + (void)static_cast((void (A::*)())0); // TODO: User-defined conversions @@ -116,4 +118,12 @@ void t_529_10() (void)static_cast((void*)0); // expected-error {{static_cast from 'void *' to 'void (*)(void)' is not allowed}} } -// TODO: Test member pointers. +// Member pointer upcast. +void t_529_9() +{ + (void)static_cast((int B::*)0); + + // Bad code below + (void)static_cast((int H::*)0); // expected-error {{ambiguous conversion from pointer to member of derived class 'struct H'}} + (void)static_cast((int F::*)0); // expected-error {{conversion from pointer to member of class 'struct F'}} +} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 22a419af5eea..6135b3f49bf4 100644 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -571,10 +571,10 @@ welcome!

          5.2.9 [expr.static.cast] ✓ + ✓ - - Missing member pointer conversions. + Some custom conversions don't work.     5.2.10 [expr.reinterpret.cast] -- GitLab From a15ea78ea6357447f66c64b90732c4984468cd8f Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Wed, 28 Jan 2009 18:53:39 +0000 Subject: [PATCH 359/682] Fixed extract element when the result needs to be promoted and the input widened. llvm-svn: 63217 --- llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f3897fad1d05..f9813b0bdda0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -292,6 +292,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { MVT OldVT = N->getValueType(0); SDValue OldVec = N->getOperand(0); + if (getTypeAction(OldVec.getValueType()) == WidenVector) + OldVec = GetWidenedVector(N->getOperand(0)); unsigned OldElts = OldVec.getValueType().getVectorNumElements(); if (OldElts == 1) { -- GitLab From b042a592303013f18f442db3efb0578905eb828e Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Wed, 28 Jan 2009 19:12:34 +0000 Subject: [PATCH 360/682] Some refactoring of common code. No change in functionality. llvm-svn: 63218 --- clang/lib/CodeGen/CGObjCMac.cpp | 81 +++++++++++++++++++-------------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index f786a4729bed..99c6c04abd37 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -348,6 +348,9 @@ protected: /// name. The return value has type char *. llvm::Constant *GetClassName(IdentifierInfo *Ident); + const RecordDecl *GetFirstIvarInRecord(const ObjCInterfaceDecl *OID, + RecordDecl::field_iterator &FIV, + RecordDecl::field_iterator &PIV); public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { } @@ -401,9 +404,8 @@ private: /// interface ivars will be emitted. The return value has type /// IvarListPtrTy. llvm::Constant *EmitIvarList(const ObjCImplementationDecl *ID, - bool ForClass, - const llvm::Type *InterfaceTy); - + bool ForClass); + /// EmitMetaClass - Emit a forward reference to the class structure /// for the metaclass of the given interface. The return value has /// type ClassPtrTy. @@ -1303,7 +1305,7 @@ void CGObjCMac::GenerateClass(const ObjCImplementationDecl *ID) { Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); - Values[ 6] = EmitIvarList(ID, false, InterfaceTy); + Values[ 6] = EmitIvarList(ID, false); Values[ 7] = EmitMethodList("\01L_OBJC_INSTANCE_METHODS_" + ID->getNameAsString(), "__OBJC,__inst_meth,regular,no_dead_strip", @@ -1363,7 +1365,7 @@ llvm::Constant *CGObjCMac::EmitMetaClass(const ObjCImplementationDecl *ID, Values[ 3] = llvm::ConstantInt::get(ObjCTypes.LongTy, 0); Values[ 4] = llvm::ConstantInt::get(ObjCTypes.LongTy, Flags); Values[ 5] = llvm::ConstantInt::get(ObjCTypes.LongTy, Size); - Values[ 6] = EmitIvarList(ID, true, InterfaceTy); + Values[ 6] = EmitIvarList(ID, true); Values[ 7] = EmitMethodList("\01L_OBJC_CLASS_METHODS_" + ID->getNameAsString(), "__OBJC,__inst_meth,regular,no_dead_strip", @@ -1493,8 +1495,7 @@ static int countInheritedIvars(const ObjCInterfaceDecl *OI) { }; */ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, - bool ForClass, - const llvm::Type *InterfaceTy) { + bool ForClass) { std::vector Ivars, Ivar(3); // When emitting the root class GCC emits ivar entries for the @@ -1504,16 +1505,16 @@ llvm::Constant *CGObjCMac::EmitIvarList(const ObjCImplementationDecl *ID, // for the class. if (ForClass) return llvm::Constant::getNullValue(ObjCTypes.IvarListPtrTy); - + + ObjCInterfaceDecl *OID = + const_cast(ID->getClassInterface()); + const llvm::Type *InterfaceTy = + CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID)); const llvm::StructLayout *Layout = CGM.getTargetData().getStructLayout(cast(InterfaceTy)); - ObjCInterfaceDecl *OID = - const_cast(ID->getClassInterface()); - int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); - const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); - RecordDecl::field_iterator ifield = RD->field_begin(); - while (countSuperClassIvars-- > 0) - ++ifield; + + RecordDecl::field_iterator ifield, pfield; + const RecordDecl *RD = GetFirstIvarInRecord(OID, ifield, pfield); for (RecordDecl::field_iterator e = RD->field_end(); ifield != e; ++ifield) { FieldDecl *Field = *ifield; unsigned Offset = Layout->getElementOffset(CGM.getTypes(). @@ -2341,6 +2342,28 @@ void CGObjCCommonMac::GetNameForMethod(const ObjCMethodDecl *D, NameOut += ']'; } +/// GetFirstIvarInRecord - This routine returns the record for the +/// implementation of the fiven class OID. It also returns field +/// corresponding to the first ivar in the class in FIV. It also +/// returns the one before the first ivar. +/// +const RecordDecl *CGObjCCommonMac::GetFirstIvarInRecord( + const ObjCInterfaceDecl *OID, + RecordDecl::field_iterator &FIV, + RecordDecl::field_iterator &PIV) { + int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); + const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); + RecordDecl::field_iterator ifield = RD->field_begin(); + RecordDecl::field_iterator pfield = RD->field_end(); + while (countSuperClassIvars-- > 0) { + pfield = ifield; + ++ifield; + } + FIV = ifield; + PIV = pfield; + return RD; +} + void CGObjCMac::FinishModule() { EmitModuleInfo(); @@ -3341,25 +3364,18 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { if (ObjCInterfaceDecl *OID = const_cast(ID->getClassInterface())) { // FIXME. Share this with the one in EmitIvarList. - int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); - const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); - RecordDecl::field_iterator firstField = RD->field_begin(); - RecordDecl::field_iterator lastField = RD->field_end(); + const llvm::Type *InterfaceTy = + CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID)); + const llvm::StructLayout *Layout = + CGM.getTargetData().getStructLayout(cast(InterfaceTy)); - while (countSuperClassIvars-- > 0) { - lastField = firstField; - ++firstField; - } + RecordDecl::field_iterator firstField, lastField; + const RecordDecl *RD = GetFirstIvarInRecord(OID, firstField, lastField); for (RecordDecl::field_iterator e = RD->field_end(), ifield = firstField; ifield != e; ++ifield) lastField = ifield; - const llvm::Type *InterfaceTy = - CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType(OID)); - const llvm::StructLayout *Layout = - CGM.getTargetData().getStructLayout(cast(InterfaceTy)); - if (lastField != RD->field_end()) { FieldDecl *Field = *lastField; const llvm::Type *FieldTy = @@ -3587,14 +3603,11 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( const llvm::Type *InterfaceTy = CGM.getTypes().ConvertType(CGM.getContext().getObjCInterfaceType( const_cast(OID))); - const llvm::StructLayout *Layout = CGM.getTargetData().getStructLayout(cast(InterfaceTy)); - int countSuperClassIvars = countInheritedIvars(OID->getSuperClass()); - const RecordDecl *RD = CGM.getContext().addRecordToClass(OID); - RecordDecl::field_iterator i = RD->field_begin(); - while (countSuperClassIvars-- > 0) - ++i; + + RecordDecl::field_iterator i,p; + const RecordDecl *RD = GetFirstIvarInRecord(OID, i,p); ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(); for (RecordDecl::field_iterator e = RD->field_end(); i != e; ++i) { -- GitLab From b04867265cf51530f0038d1b22ffe818bbe1f9a1 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Wed, 28 Jan 2009 19:16:40 +0000 Subject: [PATCH 361/682] Change Parser::ParseFunctionDeclarator() to annotate typename tokens. This removes ~10% of the calls to Sema::isTypeName(), which amount to a little less than a 1% reduction in usertime (for Cocoa.h). llvm-svn: 63219 --- clang/lib/Parse/ParseDecl.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index 89e0f10d741c..dc6768f99936 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -1992,18 +1992,30 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // Alternatively, this parameter list may be an identifier list form for a // K&R-style function: void foo(a,b,c) - if (!getLang().CPlusPlus && Tok.is(tok::identifier) && + if (!getLang().CPlusPlus && Tok.is(tok::identifier)) { + + TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope); + if (TypeRep) { + // This is a typename. Replace the current token in-place with an + // annotation type token. + Tok.setKind(tok::annot_typename); + Tok.setAnnotationValue(TypeRep); + Tok.setAnnotationEndLoc(Tok.getLocation()); + // In case the tokens were cached, have Preprocessor replace + // them with the annotation token. + PP.AnnotateCachedTokens(Tok); + } else { // K&R identifier lists can't have typedefs as identifiers, per // C99 6.7.5.3p11. - !Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope)) { - if (RequiresArg) { - Diag(Tok, diag::err_argument_required_after_attribute); - delete AttrList; + if (RequiresArg) { + Diag(Tok, diag::err_argument_required_after_attribute); + delete AttrList; + } + + // Identifier list. Note that '(' identifier-list ')' is only allowed for + // normal declarators, not for abstract-declarators. + return ParseFunctionDeclaratorIdentifierList(LParenLoc, D); } - - // Identifier list. Note that '(' identifier-list ')' is only allowed for - // normal declarators, not for abstract-declarators. - return ParseFunctionDeclaratorIdentifierList(LParenLoc, D); } // Finally, a normal, non-empty parameter type list. -- GitLab From 36ccb30a3538021a16258b0dbdd14494db317d9e Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 28 Jan 2009 19:26:20 +0000 Subject: [PATCH 362/682] ccc: Support -v; invent a version number for ccc for now, will be shared with clang eventually. llvm-svn: 63220 --- clang/tools/ccc/ccclib/Arguments.py | 6 +++--- clang/tools/ccc/ccclib/Driver.py | 24 ++++++++++++++++++------ clang/utils/CmpDriver | 3 ++- 3 files changed, 23 insertions(+), 10 deletions(-) diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py index 7c5765c28da2..051498f31052 100644 --- a/clang/tools/ccc/ccclib/Arguments.py +++ b/clang/tools/ccc/ccclib/Arguments.py @@ -883,9 +883,9 @@ class OptionParser: # Version control. # FIXME: Figure out what to do about these. - self.BOption = self.addOption(JoinedOrSeparateOption('-B')) - self.addOption(JoinedOrSeparateOption('-V')) - self.addOption(JoinedOrSeparateOption('-b')) + self.BOption = self.addOption(JoinedOrSeparateOption('-B', unsupported=True)) + self.addOption(JoinedOrSeparateOption('-V', unsupported=True)) + self.addOption(JoinedOrSeparateOption('-b', unsupported=True)) # Clang static analyzer options (also see -WA,). self.analyzeOption = self.addOption(FlagOption('--analyze')) diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py index 095745facc65..6749dae13293 100644 --- a/clang/tools/ccc/ccclib/Driver.py +++ b/clang/tools/ccc/ccclib/Driver.py @@ -32,6 +32,9 @@ class Driver(object): self.cccEcho = False self.cccFallback = False + # Certain options suppress the 'no input files' warning. + self.suppressMissingInputWarning = False + # Host queries which can be forcibly over-riden by the user for # testing purposes. # @@ -208,10 +211,11 @@ class Driver(object): raise ValueError,'Encountered unknown job.' sys.exit(0) + vArg = args.getLastArg(self.parser.vOption) for j in jobs.iterjobs(): if isinstance(j, Jobs.Command): - if self.cccEcho: - print >>sys.stderr, ' '.join(map(repr,j.getArgv())) + if vArg or self.cccEcho: + print >>sys.stderr, ' '.join(map(str,j.getArgv())) sys.stderr.flush() res = os.spawnvp(os.P_WAIT, j.executable, j.getArgv()) if res: @@ -220,8 +224,8 @@ class Driver(object): import subprocess procs = [] for sj in j.commands: - if self.cccEcho: - print >> sys.stderr, ' '.join(map(repr,sj.getArgv())) + if vArg or self.cccEcho: + print >> sys.stderr, ' '.join(map(str,sj.getArgv())) sys.stdout.flush() if not procs: @@ -290,6 +294,10 @@ class Driver(object): steps = {} for phase in phases: printPhase(phase, sys.stdout, steps) + + def printVersion(self): + # FIXME: Print default target triple. + print >>sys.stderr,'ccc version 1.0' def handleImmediateOptions(self, args): # FIXME: Some driver Arguments are consumed right off the bat, @@ -307,6 +315,11 @@ class Driver(object): # FIXME: Do we want to report "argument unused" type errors in the # presence of things like -dumpmachine and -print-search-dirs? # Probably not. + if (args.getLastArg(self.parser.vOption) or + args.getLastArg(self.parser.hashHashHashOption)): + self.printVersion() + self.suppressMissingInputWarning = True + arg = (args.getLastArg(self.parser.dumpmachineOption) or args.getLastArg(self.parser.dumpversionOption) or args.getLastArg(self.parser.printSearchDirsOption)) @@ -432,8 +445,7 @@ class Driver(object): if arg: raise Arguments.InvalidArgumentsError("%s: unsupported use of internal gcc option" % ' '.join(args.render(arg))) - if (not inputs and - not args.getLastArg(self.parser.hashHashHashOption)): + if not inputs and not self.suppressMissingInputWarning: raise Arguments.InvalidArgumentsError("no input files") actions = [] diff --git a/clang/utils/CmpDriver b/clang/utils/CmpDriver index 54209843df7f..97c91a820915 100755 --- a/clang/utils/CmpDriver +++ b/clang/utils/CmpDriver @@ -106,7 +106,8 @@ class CompileInfo: ln.startswith('Target: ') or ln.startswith('Configured with: ') or ln.startswith('Thread model: ') or - ln.startswith('gcc version')): + ln.startswith('gcc version') or + ln.startswith('ccc version')): pass elif ln.strip().startswith('"'): self.commands.append(list(splitArgs(ln))) -- GitLab From 1498e62117076dd7e69ac9b676f4453b9bc136b2 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 28 Jan 2009 19:29:30 +0000 Subject: [PATCH 363/682] strengthen this test. llvm-svn: 63222 --- llvm/test/Transforms/ScalarRepl/vector_promote.ll | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/llvm/test/Transforms/ScalarRepl/vector_promote.ll b/llvm/test/Transforms/ScalarRepl/vector_promote.ll index ec22f6464b45..d1d11e229368 100644 --- a/llvm/test/Transforms/ScalarRepl/vector_promote.ll +++ b/llvm/test/Transforms/ScalarRepl/vector_promote.ll @@ -1,6 +1,5 @@ -; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \ -; RUN: not grep alloca -; END. +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {load <4 x float>} define void @test(<4 x float>* %F, float %f) { entry: -- GitLab From ad0d48d3722d8e0dac3d4b630bdbd48d363f3d26 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 28 Jan 2009 19:30:43 +0000 Subject: [PATCH 364/682] Fix test case (for -### printing version) llvm-svn: 63223 --- clang/tools/ccc/test/ccc/integrated-cpp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/clang/tools/ccc/test/ccc/integrated-cpp.c b/clang/tools/ccc/test/ccc/integrated-cpp.c index 56c7764fdfd5..25c740276732 100644 --- a/clang/tools/ccc/test/ccc/integrated-cpp.c +++ b/clang/tools/ccc/test/ccc/integrated-cpp.c @@ -1,3 +1,3 @@ -// RUN: xcc -fsyntax-only -### %s 2>&1 | count 1 && -// RUN: xcc -fsyntax-only -### %s -no-integrated-cpp 2>&1 | count 2 && -// RUN: xcc -fsyntax-only -### %s -save-temps 2>&1 | count 2 +// RUN: xcc -fsyntax-only -### %s 2>&1 | count 2 && +// RUN: xcc -fsyntax-only -### %s -no-integrated-cpp 2>&1 | count 3 && +// RUN: xcc -fsyntax-only -### %s -save-temps 2>&1 | count 3 -- GitLab From 16c8e598ae35c03ab81cd04ec1066d24b12182bd Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Wed, 28 Jan 2009 19:39:02 +0000 Subject: [PATCH 365/682] Name change (isTypeName->getTypeName). Since it doesn't return a bool, is shouldn't be prefixed with 'is'. llvm-svn: 63226 --- clang/docs/InternalsManual.html | 2 +- clang/include/clang/Parse/Action.h | 12 ++++++------ clang/include/clang/Parse/Parser.h | 2 +- clang/lib/Parse/MinimalAction.cpp | 4 ++-- clang/lib/Parse/ParseDecl.cpp | 14 +++++++------- clang/lib/Parse/ParseDeclCXX.cpp | 2 +- clang/lib/Parse/Parser.cpp | 6 +++--- clang/lib/Sema/Sema.h | 4 ++-- clang/lib/Sema/SemaDecl.cpp | 4 ++-- clang/lib/Sema/SemaDeclCXX.cpp | 2 +- 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/clang/docs/InternalsManual.html b/clang/docs/InternalsManual.html index 27232843d31e..f35dcc2de919 100644 --- a/clang/docs/InternalsManual.html +++ b/clang/docs/InternalsManual.html @@ -600,7 +600,7 @@ is. See below for the different valid kinds.
      1. tok::annot_typename: This annotation token represents a resolved typename token that is potentially qualified. The AnnotationValue -field contains a pointer returned by Action::isTypeName(). In the case of the +field contains a pointer returned by Action::getTypeName(). In the case of the Sema actions module, this is a Decl* for the type.
      2. tok::annot_cxxscope: This annotation token represents a C++ scope diff --git a/clang/include/clang/Parse/Action.h b/clang/include/clang/Parse/Action.h index 02948bbbcf70..3daf2d553e23 100644 --- a/clang/include/clang/Parse/Action.h +++ b/clang/include/clang/Parse/Action.h @@ -54,7 +54,7 @@ namespace clang { /// the parser has just done or is about to do when the method is called. They /// are not requests that the actions module do the specified action. /// -/// All of the methods here are optional except isTypeName() and +/// All of the methods here are optional except getTypeName() and /// isCurrentClassName(), which must be specified in order for the /// parse to complete accurately. The MinimalAction class does this /// bare-minimum of tracking to implement this functionality. @@ -130,12 +130,12 @@ public: // Declaration Tracking Callbacks. //===--------------------------------------------------------------------===// - /// isTypeName - Return non-null if the specified identifier is a type name + /// getTypeName - Return non-null if the specified identifier is a type name /// in the current scope. /// An optional CXXScopeSpec can be passed to indicate the C++ scope (class or /// namespace) that the identifier must be a member of. /// i.e. for "foo::bar", 'II' will be "bar" and 'SS' will be "foo::". - virtual TypeTy *isTypeName(IdentifierInfo &II, Scope *S, + virtual TypeTy *getTypeName(IdentifierInfo &II, Scope *S, const CXXScopeSpec *SS = 0) = 0; /// isCurrentClassName - Return true if the specified name is the @@ -1326,10 +1326,10 @@ public: MinimalAction(Preprocessor &pp); ~MinimalAction(); - /// isTypeName - This looks at the IdentifierInfo::FETokenInfo field to + /// getTypeName - This looks at the IdentifierInfo::FETokenInfo field to /// determine whether the name is a typedef or not in this scope. - virtual TypeTy *isTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS); + virtual TypeTy *getTypeName(IdentifierInfo &II, Scope *S, + const CXXScopeSpec *SS); /// isCurrentClassName - Always returns false, because MinimalAction /// does not support C++ classes with constructors. diff --git a/clang/include/clang/Parse/Parser.h b/clang/include/clang/Parse/Parser.h index cf479f000e4c..e2cac8dd90bc 100644 --- a/clang/include/clang/Parse/Parser.h +++ b/clang/include/clang/Parse/Parser.h @@ -693,7 +693,7 @@ private: return false; IdentifierInfo *II = Tok.getIdentifierInfo(); - if (Actions.isTypeName(*II, CurScope)) + if (Actions.getTypeName(*II, CurScope)) return true; return II == Ident_super; diff --git a/clang/lib/Parse/MinimalAction.cpp b/clang/lib/Parse/MinimalAction.cpp index 2b7b335ed440..6fd5fc03152b 100644 --- a/clang/lib/Parse/MinimalAction.cpp +++ b/clang/lib/Parse/MinimalAction.cpp @@ -80,8 +80,8 @@ void MinimalAction::ActOnTranslationUnitScope(SourceLocation Loc, Scope *S) { /// /// FIXME: Use the passed CXXScopeSpec for accurate C++ type checking. Action::TypeTy * -MinimalAction::isTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS) { +MinimalAction::getTypeName(IdentifierInfo &II, Scope *S, + const CXXScopeSpec *SS) { if (TypeNameInfo *TI = II.getFETokenInfo()) if (TI->isTypeName) return TI; diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp index dc6768f99936..eb5cedd5f40e 100644 --- a/clang/lib/Parse/ParseDecl.cpp +++ b/clang/lib/Parse/ParseDecl.cpp @@ -484,8 +484,8 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, GetLookAheadToken(2).is(tok::l_paren)) goto DoneWithDeclSpec; - TypeTy *TypeRep = Actions.isTypeName(*NextToken().getIdentifierInfo(), - CurScope, &SS); + TypeTy *TypeRep = Actions.getTypeName(*NextToken().getIdentifierInfo(), + CurScope, &SS); if (TypeRep == 0) goto DoneWithDeclSpec; @@ -538,7 +538,7 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS, goto DoneWithDeclSpec; // It has to be available as a typedef too! - TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope); + TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), CurScope); if (TypeRep == 0) goto DoneWithDeclSpec; @@ -1736,8 +1736,8 @@ void Parser::ParseDirectDeclarator(Declarator &D) { // If this identifier is the name of the current class, it's a // constructor name. else if (Actions.isCurrentClassName(*Tok.getIdentifierInfo(), CurScope)) - D.setConstructor(Actions.isTypeName(*Tok.getIdentifierInfo(), - CurScope), + D.setConstructor(Actions.getTypeName(*Tok.getIdentifierInfo(), + CurScope), Tok.getLocation()); // This is a normal identifier. else @@ -1994,7 +1994,7 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D, // K&R-style function: void foo(a,b,c) if (!getLang().CPlusPlus && Tok.is(tok::identifier)) { - TypeTy *TypeRep = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope); + TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), CurScope); if (TypeRep) { // This is a typename. Replace the current token in-place with an // annotation type token. @@ -2203,7 +2203,7 @@ void Parser::ParseFunctionDeclaratorIdentifierList(SourceLocation LParenLoc, IdentifierInfo *ParmII = Tok.getIdentifierInfo(); // Reject 'typedef int y; int test(x, y)', but continue parsing. - if (Actions.isTypeName(*ParmII, CurScope)) + if (Actions.getTypeName(*ParmII, CurScope)) Diag(Tok, diag::err_unexpected_typedef_ident) << ParmII; // Verify that the argument identifier has not already been mentioned. diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp index ed4d1dffee8d..27b2d74c8503 100644 --- a/clang/lib/Parse/ParseDeclCXX.cpp +++ b/clang/lib/Parse/ParseDeclCXX.cpp @@ -232,7 +232,7 @@ Parser::TypeTy *Parser::ParseClassName(const CXXScopeSpec *SS) { } // We have an identifier; check whether it is actually a type. - TypeTy *Type = Actions.isTypeName(*Tok.getIdentifierInfo(), CurScope, SS); + TypeTy *Type = Actions.getTypeName(*Tok.getIdentifierInfo(), CurScope, SS); if (!Type) { Diag(Tok, diag::err_expected_class_name); return 0; diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp index 0e1b22202cd4..33ce08ef48fa 100644 --- a/clang/lib/Parse/Parser.cpp +++ b/clang/lib/Parse/Parser.cpp @@ -737,7 +737,7 @@ Parser::OwningExprResult Parser::ParseSimpleAsm() { /// inside expressions to be treated as typenames so it will not be called /// for expressions in C. /// The benefit for C/ObjC is that a typename will be annotated and -/// Actions.isTypeName will not be needed to be called again (e.g. isTypeName +/// Actions.getTypeName will not be needed to be called again (e.g. getTypeName /// will not be called twice, once to check whether we have a declaration /// specifier, and another one to get the actual type inside /// ParseDeclarationSpecifiers). @@ -757,8 +757,8 @@ bool Parser::TryAnnotateTypeOrScopeToken() { if (Tok.is(tok::identifier)) { // Determine whether the identifier is a type name. - if (TypeTy *Ty = Actions.isTypeName(*Tok.getIdentifierInfo(), - CurScope, &SS)) { + if (TypeTy *Ty = Actions.getTypeName(*Tok.getIdentifierInfo(), + CurScope, &SS)) { // This is a typename. Replace the current token in-place with an // annotation type token. Tok.setKind(tok::annot_typename); diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 9206dd53c919..d017e6f9c7bc 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -282,8 +282,8 @@ public: //===--------------------------------------------------------------------===// // Symbol table / Decl tracking callbacks: SemaDecl.cpp. // - virtual TypeTy *isTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS); + virtual TypeTy *getTypeName(IdentifierInfo &II, Scope *S, + const CXXScopeSpec *SS); virtual DeclTy *ActOnDeclarator(Scope *S, Declarator &D, DeclTy *LastInGroup) { return ActOnDeclarator(S, D, LastInGroup, false); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 22650f525dbb..cfbd288aaea9 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -31,8 +31,8 @@ using namespace clang; -Sema::TypeTy *Sema::isTypeName(IdentifierInfo &II, Scope *S, - const CXXScopeSpec *SS) { +Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S, + const CXXScopeSpec *SS) { DeclContext *DC = 0; if (SS) { if (SS->isInvalid()) diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 91a282dd953f..0e08eb3fd802 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -692,7 +692,7 @@ Sema::ActOnMemInitializer(DeclTy *ConstructorD, } // It didn't name a member, so see if it names a class. - TypeTy *BaseTy = isTypeName(*MemberOrBase, S, 0/*SS*/); + TypeTy *BaseTy = getTypeName(*MemberOrBase, S, 0/*SS*/); if (!BaseTy) return Diag(IdLoc, diag::err_mem_init_not_member_or_class) << MemberOrBase << SourceRange(IdLoc, RParenLoc); -- GitLab From df17987c19b07523391ba56410405f631bd4b2e9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Wed, 28 Jan 2009 20:16:43 +0000 Subject: [PATCH 366/682] Fix some issues with volatility, move "CanConvertToScalar" check after the others. llvm-svn: 63227 --- .../Scalar/ScalarReplAggregates.cpp | 54 +++++++++++-------- llvm/test/Transforms/ScalarRepl/volatile.ll | 12 +++++ 2 files changed, 45 insertions(+), 21 deletions(-) create mode 100644 llvm/test/Transforms/ScalarRepl/volatile.ll diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 18716b7e445b..589aa35d9c60 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -123,7 +123,7 @@ namespace { void RewriteStoreUserOfWholeAlloca(StoreInst *SI, AllocationInst *AI, SmallVector &NewElts); void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocationInst *AI, - SmallVector &NewElts); + SmallVector &NewElts); const Type *CanConvertToScalar(Value *V, bool &IsNotTrivial); void ConvertToScalar(AllocationInst *AI, const Type *Ty); @@ -224,16 +224,6 @@ bool SROA::performScalarRepl(Function &F) { continue; } - // If we can turn this aggregate value (potentially with casts) into a - // simple scalar value that can be mem2reg'd into a register value. - bool IsNotTrivial = false; - if (const Type *ActualType = CanConvertToScalar(AI, IsNotTrivial)) - if (IsNotTrivial && ActualType != Type::VoidTy) { - ConvertToScalar(AI, ActualType); - Changed = true; - continue; - } - // Check to see if we can perform the core SROA transformation. We cannot // transform the allocation instruction if it is an array allocation // (allocations OF arrays are ok though), and an allocation of a scalar @@ -278,7 +268,17 @@ bool SROA::performScalarRepl(Function &F) { Changed = true; continue; } - + + // If we can turn this aggregate value (potentially with casts) into a + // simple scalar value that can be mem2reg'd into a register value. + bool IsNotTrivial = false; + if (const Type *ActualType = CanConvertToScalar(AI, IsNotTrivial)) + if (IsNotTrivial && ActualType != Type::VoidTy) { + ConvertToScalar(AI, ActualType); + Changed = true; + continue; + } + // Otherwise, couldn't process this. } @@ -476,11 +476,13 @@ void SROA::isSafeUseOfAllocation(Instruction *User, AllocationInst *AI, if (BitCastInst *C = dyn_cast(User)) return isSafeUseOfBitCastedAllocation(C, AI, Info); - if (isa(User)) - return; // Loads (returning a first class aggregrate) are always rewritable + if (LoadInst *LI = dyn_cast(User)) + if (!LI->isVolatile()) + return;// Loads (returning a first class aggregrate) are always rewritable - if (isa(User) && User->getOperand(0) != AI) - return; // Store is ok if storing INTO the pointer, not storing the pointer + if (StoreInst *SI = dyn_cast(User)) + if (!SI->isVolatile() && SI->getOperand(0) != AI) + return;// Store is ok if storing INTO the pointer, not storing the pointer GetElementPtrInst *GEPI = dyn_cast(User); if (GEPI == 0) @@ -590,6 +592,9 @@ void SROA::isSafeUseOfBitCastedAllocation(BitCastInst *BC, AllocationInst *AI, } else if (MemIntrinsic *MI = dyn_cast(UI)) { isSafeMemIntrinsicOnAllocation(MI, AI, UI.getOperandNo(), Info); } else if (StoreInst *SI = dyn_cast(UI)) { + if (SI->isVolatile()) + return MarkUnsafe(Info); + // If storing the entire alloca in one chunk through a bitcasted pointer // to integer, we can transform it. This happens (for example) when you // cast a {i32,i32}* to i64* and store through it. This is similar to the @@ -602,6 +607,9 @@ void SROA::isSafeUseOfBitCastedAllocation(BitCastInst *BC, AllocationInst *AI, } return MarkUnsafe(Info); } else if (LoadInst *LI = dyn_cast(UI)) { + if (LI->isVolatile()) + return MarkUnsafe(Info); + // If loading the entire alloca in one chunk through a bitcasted pointer // to integer, we can transform it. This happens (for example) when you // cast a {i32,i32}* to i64* and load through it. This is similar to the @@ -1234,6 +1242,9 @@ const Type *SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial) { Instruction *User = cast(*UI); if (LoadInst *LI = dyn_cast(User)) { + if (LI->isVolatile()) + return 0; + // FIXME: Loads of a first class aggregrate value could be converted to a // series of loads and insertvalues if (!LI->getType()->isSingleValueType()) @@ -1246,7 +1257,7 @@ const Type *SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial) { if (StoreInst *SI = dyn_cast(User)) { // Storing the pointer, not into the value? - if (SI->getOperand(0) == V) return 0; + if (SI->getOperand(0) == V || SI->isVolatile()) return 0; // FIXME: Stores of a first class aggregrate value could be converted to a // series of extractvalues and stores @@ -1653,10 +1664,11 @@ static bool PointsToConstantGlobal(Value *V) { static bool isOnlyCopiedFromConstantGlobal(Value *V, Instruction *&TheCopy, bool isOffset) { for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) { - if (isa(*UI)) { - // Ignore loads, they are always ok. - continue; - } + if (LoadInst *LI = dyn_cast(*UI)) + // Ignore non-volatile loads, they are always ok. + if (!LI->isVolatile()) + continue; + if (BitCastInst *BCI = dyn_cast(*UI)) { // If uses of the bitcast are ok, we are ok. if (!isOnlyCopiedFromConstantGlobal(BCI, TheCopy, isOffset)) diff --git a/llvm/test/Transforms/ScalarRepl/volatile.ll b/llvm/test/Transforms/ScalarRepl/volatile.ll new file mode 100644 index 000000000000..5f9fe0d89a5a --- /dev/null +++ b/llvm/test/Transforms/ScalarRepl/volatile.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {volatile load} +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {volatile store} + +define i32 @voltest(i32 %T) { + %A = alloca {i32, i32} + %B = getelementptr {i32,i32}* %A, i32 0, i32 0 + volatile store i32 %T, i32* %B + + %C = getelementptr {i32,i32}* %A, i32 0, i32 1 + %X = volatile load i32* %C + ret i32 %X +} -- GitLab From 3587d0b76230c87182ba99e52298fa247836bad6 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 20:45:37 +0000 Subject: [PATCH 367/682] Tweak doxygen comment. No functionality change. llvm-svn: 63228 --- clang/include/clang/Basic/Diagnostic.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h index d1c045704a6a..c57e1a9a89cf 100644 --- a/clang/include/clang/Basic/Diagnostic.h +++ b/clang/include/clang/Basic/Diagnostic.h @@ -205,9 +205,11 @@ public: Level getDiagnosticLevel(unsigned DiagID) const; - /// Report - Issue the message to the client. DiagID is a member of the - /// diag::kind enum. This actually returns aninstance of DiagnosticBuilder - /// which emits the diagnostics (through ProcessDiag) when it is destroyed. + /// Report - Issue the message to the client. @c DiagID is a member of the + /// @c diag::kind enum. This actually returns aninstance of DiagnosticBuilder + /// which emits the diagnostics (through @c ProcessDiag) when it is destroyed. + /// @c Pos represents the source location associated with the diagnostic, + /// which can be an invalid location if no position information is available. inline DiagnosticBuilder Report(FullSourceLoc Pos, unsigned DiagID); private: -- GitLab From bf16554640037086bec7d6b7a179d8872a4acee9 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 20:46:26 +0000 Subject: [PATCH 368/682] Add method FullSourceLoc::getBufferData(). llvm-svn: 63229 --- clang/include/clang/Basic/SourceLocation.h | 7 ++++++- clang/lib/Basic/SourceLocation.cpp | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/clang/include/clang/Basic/SourceLocation.h b/clang/include/clang/Basic/SourceLocation.h index 31fbc0218bbb..4a6ae1f29d02 100644 --- a/clang/include/clang/Basic/SourceLocation.h +++ b/clang/include/clang/Basic/SourceLocation.h @@ -16,6 +16,7 @@ #include #include "llvm/Bitcode/SerializationFwd.h" +#include namespace llvm { class MemoryBuffer; @@ -178,7 +179,7 @@ public: class FullSourceLoc : public SourceLocation { SourceManager* SrcMgr; public: - // Creates a FullSourceLoc where isValid() returns false. + /// Creates a FullSourceLoc where isValid() returns false. explicit FullSourceLoc() : SrcMgr((SourceManager*) 0) {} explicit FullSourceLoc(SourceLocation Loc, SourceManager &SM) @@ -212,6 +213,10 @@ public: const llvm::MemoryBuffer* getBuffer() const; + /// getBufferData - Return a pointer to the start and end of the source buffer + /// data for the specified FileID. + std::pair getBufferData() const; + bool isInSystemHeader() const; /// Prints information about this FullSourceLoc to stderr. Useful for diff --git a/clang/lib/Basic/SourceLocation.cpp b/clang/lib/Basic/SourceLocation.cpp index 5d484721bd4e..43fa3a13a6f4 100644 --- a/clang/lib/Basic/SourceLocation.cpp +++ b/clang/lib/Basic/SourceLocation.cpp @@ -16,6 +16,8 @@ #include "clang/Basic/SourceManager.h" #include "llvm/Bitcode/Serialize.h" #include "llvm/Bitcode/Deserialize.h" +#include "llvm/Support/MemoryBuffer.h" + using namespace clang; void SourceLocation::Emit(llvm::Serializer& S) const { @@ -122,3 +124,7 @@ const llvm::MemoryBuffer* FullSourceLoc::getBuffer() const { return SrcMgr->getBuffer(SrcMgr->getFileID(*this)); } +std::pair FullSourceLoc::getBufferData() const { + const llvm::MemoryBuffer *Buf = getBuffer(); + return std::make_pair(Buf->getBufferStart(), Buf->getBufferEnd()); +} -- GitLab From 5241832d1dffb02984b839b167f16e563413407c Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 20:47:47 +0000 Subject: [PATCH 369/682] Fix TextDiagnosticPrinter::HandleDiagnostic to handle invalid FullSourceLocs that do not have a SourceManager. llvm-svn: 63230 --- clang/lib/Driver/TextDiagnosticPrinter.cpp | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp index b19d61c160f2..36e2d28d2e33 100644 --- a/clang/lib/Driver/TextDiagnosticPrinter.cpp +++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp @@ -95,12 +95,12 @@ void TextDiagnosticPrinter::HighlightRange(const SourceRange &R, void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, const DiagnosticInfo &Info) { - const SourceManager &SM = Info.getLocation().getManager(); unsigned ColNo = 0; // If the location is specified, print out a file/line/col and include trace // if enabled. if (Info.getLocation().isValid()) { + const SourceManager &SM = Info.getLocation().getManager(); PresumedLoc PLoc = SM.getPresumedLoc(Info.getLocation()); unsigned LineNo = PLoc.getLine(); @@ -142,23 +142,15 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // Inspect the actual instantiation point of the diagnostic, we don't care // about presumed locations anymore. - SourceLocation ILoc = SM.getInstantiationLoc(Info.getLocation()); - - // Get the file and line that we want to highlight. We only draw ranges - // that intersect this. - FileID ILocFID = SM.getFileID(ILoc); - unsigned LineNo = SM.getLineNumber(ILoc); - - // Get the line of the source file. Scan from the location backward and - // forward to find the start/end of the line. - + FullSourceLoc ILoc = Info.getLocation().getInstantiationLoc(); + // Rewind from the current position to the start of the line. - const char *TokInstantiationPtr = SM.getCharacterData(ILoc); + const char *TokInstantiationPtr = ILoc.getCharacterData(); const char *LineStart = TokInstantiationPtr-ColNo+1; // Column # is 1-based. // Compute the line end. Scan forward from the error position to the end of // the line. - const char *BufEnd = SM.getBufferData(ILocFID).second; + const char *BufEnd = ILoc.getBufferData().second; const char *LineEnd = TokInstantiationPtr; while (LineEnd != BufEnd && *LineEnd != '\n' && *LineEnd != '\r') @@ -173,8 +165,8 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level, // Highlight all of the characters covered by Ranges with ~ characters. for (unsigned i = 0; i != Info.getNumRanges(); ++i) - HighlightRange(Info.getRange(i), SM, LineNo, ILocFID, - CaretLine, SourceLine); + HighlightRange(Info.getRange(i), ILoc.getManager(), ILoc.getLineNumber(), + ILoc.getFileID(), CaretLine, SourceLine); // Next, insert the caret itself. if (ColNo-1 < CaretLine.size()) -- GitLab From 3b0589e4b4abc36bc46d5804820dfe8a930be472 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 20:49:33 +0000 Subject: [PATCH 370/682] Enhance PTHManager::Create() to take an optional Diagnostic* argument that can be used to report issues such as a missing PTH file. llvm-svn: 63231 --- clang/Driver/clang.cpp | 2 +- clang/include/clang/Lex/PTHManager.h | 3 ++- clang/lib/Lex/PTHLexer.cpp | 11 +++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index bc548e4e8b84..fba2df13a37a 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -1154,7 +1154,7 @@ public: // Use PTH? if (!TokenCache.empty()) - PTHMgr.reset(PTHManager::Create(TokenCache)); + PTHMgr.reset(PTHManager::Create(TokenCache, &Diags)); // Create the Preprocessor. llvm::OwningPtr PP(new Preprocessor(Diags, LangInfo, Target, diff --git a/clang/include/clang/Lex/PTHManager.h b/clang/include/clang/Lex/PTHManager.h index b77cda1f0b7d..22343e208c27 100644 --- a/clang/include/clang/Lex/PTHManager.h +++ b/clang/include/clang/Lex/PTHManager.h @@ -29,6 +29,7 @@ namespace clang { class FileEntry; class PTHLexer; +class Diagnostic; class PTHManager : public IdentifierInfoLookup { friend class PTHLexer; @@ -107,7 +108,7 @@ public: /// Create - This method creates PTHManager objects. The 'file' argument /// is the name of the PTH file. This method returns NULL upon failure. - static PTHManager *Create(const std::string& file); + static PTHManager *Create(const std::string& file, Diagnostic* Diags = 0); void setPreprocessor(Preprocessor *pp) { PP = pp; } diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index f9f2b2106120..36f509cba648 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -390,13 +390,20 @@ PTHManager::~PTHManager() { free(PerIDCache); } -PTHManager* PTHManager::Create(const std::string& file) { +PTHManager* PTHManager::Create(const std::string& file, Diagnostic* Diags) { // Memory map the PTH file. llvm::OwningPtr File(llvm::MemoryBuffer::getFile(file.c_str())); - if (!File) + if (!File) { + if (Diags) { + unsigned DiagID = Diags->getCustomDiagID(Diagnostic::Note, + "PTH file %0 could not be read"); + Diags->Report(FullSourceLoc(), DiagID) << file; + } + return 0; + } // Get the buffer ranges and check if there are at least three 32-bit // words at the end of the file. -- GitLab From 62224c1d7f4c4fa20d40783343f0e5a07eeff579 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 21:02:43 +0000 Subject: [PATCH 371/682] Add more PTH diagnostics for invalid PTH files, etc. llvm-svn: 63232 --- clang/lib/Lex/PTHLexer.cpp | 40 +++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) diff --git a/clang/lib/Lex/PTHLexer.cpp b/clang/lib/Lex/PTHLexer.cpp index 36f509cba648..8bbf284b32af 100644 --- a/clang/lib/Lex/PTHLexer.cpp +++ b/clang/lib/Lex/PTHLexer.cpp @@ -390,6 +390,13 @@ PTHManager::~PTHManager() { free(PerIDCache); } +static void InvalidPTH(Diagnostic *Diags, const char* Msg = 0) { + if (!Diags) return; + if (!Msg) Msg = "Invalid or corrupted PTH file"; + unsigned DiagID = Diags->getCustomDiagID(Diagnostic::Note, Msg); + Diags->Report(FullSourceLoc(), DiagID); +} + PTHManager* PTHManager::Create(const std::string& file, Diagnostic* Diags) { // Memory map the PTH file. llvm::OwningPtr @@ -412,21 +419,30 @@ PTHManager* PTHManager::Create(const std::string& file, Diagnostic* Diags) { // Check the prologue of the file. if ((BufEnd - BufBeg) < (signed) (sizeof("cfe-pth") + 3 + 4) || - memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) + memcmp(BufBeg, "cfe-pth", sizeof("cfe-pth") - 1) != 0) { + InvalidPTH(Diags); return 0; + } // Read the PTH version. const unsigned char *p = BufBeg + (sizeof("cfe-pth") - 1); unsigned Version = ReadLE32(p); - if (Version != PTHManager::Version) + if (Version != PTHManager::Version) { + InvalidPTH(Diags, + Version < PTHManager::Version + ? "PTH file uses an older PTH format that is no longer supported" + : "PTH file uses a newer PTH format that cannot be read"); return 0; + } // Compute the address of the index table at the end of the PTH file. const unsigned char *EndTable = BufBeg + ReadLE32(p); - if (EndTable >= BufEnd) + if (EndTable >= BufEnd) { + InvalidPTH(Diags); return 0; + } // Construct the file lookup table. This will be used for mapping from // FileEntry*'s to cached tokens. @@ -434,15 +450,17 @@ PTHManager* PTHManager::Create(const std::string& file, Diagnostic* Diags) { const unsigned char* FileTable = BufBeg + ReadLE32(FileTableOffset); if (!(FileTable > BufBeg && FileTable < BufEnd)) { - assert(false && "Invalid PTH file."); + InvalidPTH(Diags); return 0; // FIXME: Proper error diagnostic? } llvm::OwningPtr FL(new PTHFileLookup()); FL->ReadTable(FileTable); - if (FL->isEmpty()) + if (FL->isEmpty()) { + InvalidPTH(Diags, "PTH file contains no cached source data"); return 0; + } // Get the location of the table mapping from persistent ids to the // data needed to reconstruct identifiers. @@ -450,23 +468,23 @@ PTHManager* PTHManager::Create(const std::string& file, Diagnostic* Diags) { const unsigned char* IData = BufBeg + ReadLE32(IDTableOffset); if (!(IData >= BufBeg && IData < BufEnd)) { - assert(false && "Invalid PTH file."); - return 0; // FIXME: Proper error diagnostic? + InvalidPTH(Diags); + return 0; } // Get the location of the lexigraphically-sorted table of persistent IDs. const unsigned char* SortedIdTableOffset = EndTable + sizeof(uint32_t)*2; const unsigned char* SortedIdTable = BufBeg + ReadLE32(SortedIdTableOffset); if (!(SortedIdTable >= BufBeg && SortedIdTable < BufEnd)) { - assert(false && "Invalid PTH file."); - return 0; // FIXME: Proper error diagnostic? + InvalidPTH(Diags); + return 0; } // Get the location of the spelling cache. const unsigned char* spellingBaseOffset = EndTable + sizeof(uint32_t)*4; const unsigned char* spellingBase = BufBeg + ReadLE32(spellingBaseOffset); if (!(spellingBase >= BufBeg && spellingBase < BufEnd)) { - assert(false && "Invalid PTH file."); + InvalidPTH(Diags); return 0; } @@ -481,7 +499,7 @@ PTHManager* PTHManager::Create(const std::string& file, Diagnostic* Diags) { if (NumIds) { PerIDCache = (IdentifierInfo**)calloc(NumIds, sizeof(*PerIDCache)); if (!PerIDCache) { - assert(false && "Could not allocate Persistent ID cache."); + InvalidPTH(Diags, "Could not allocate memory for processing PTH file"); return 0; } } -- GitLab From d7ecb3b661292217cab90ef69518a79f42e5f36c Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Wed, 28 Jan 2009 21:08:20 +0000 Subject: [PATCH 372/682] Do not forget to derived type while constructing an array type. llvm-svn: 63233 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 2 + llvm/test/DebugInfo/2009-01-28-ArrayType.ll | 93 +++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 llvm/test/DebugInfo/2009-01-28-ArrayType.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 63fb68b5ec75..8d668122e551 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1869,6 +1869,8 @@ private: if (CTy->getTag() == DW_TAG_vector_type) AddUInt(&Buffer, DW_AT_GNU_vector, DW_FORM_flag, 1); + // Emit derived type. + AddType(DW_Unit, &Buffer, CTy->getTypeDerivedFrom()); DIArray Elements = CTy->getTypeArray(); // Construct an anonymous type for index type. diff --git a/llvm/test/DebugInfo/2009-01-28-ArrayType.ll b/llvm/test/DebugInfo/2009-01-28-ArrayType.ll new file mode 100644 index 000000000000..9f90c33e5e88 --- /dev/null +++ b/llvm/test/DebugInfo/2009-01-28-ArrayType.ll @@ -0,0 +1,93 @@ +; RUN: llvm-as < %s | llc | grep 0x49 | count 7 +; Count number of DW_AT_Type attributes. + %llvm.dbg.anchor.type = type { i32, i32 } + %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* } + %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i8* } + %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i8*, i8* } + %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, i8*, i8* } + %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, i8*, i8* } + %llvm.dbg.subrange.type = type { i32, i64, i64 } + %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }*, i8*, i8* } +@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1] +@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] +@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] +@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] +@.str4 = internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.basictype5 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] +@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@llvm.dbg.derivedtype6 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@llvm.dbg.array = internal constant [3 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] +@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str7 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str7, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@.str8 = internal constant [5 x i8] c"argc\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([5 x i8]* @.str8, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@.str9 = internal constant [5 x i8] c"argv\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.variable10 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([5 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 5 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1] +@llvm.dbg.array11 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] +@llvm.dbg.composite12 = internal constant %llvm.dbg.composite.type { i32 458753, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 48, i64 8, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*), { }* bitcast ([1 x { }*]* @llvm.dbg.array11 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@.str13 = internal constant [5 x i8] c"str1\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.variable14 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([5 x i8]* @.str13, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite12 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@"\01LC" = internal constant [6 x i8] c"a.out\00" ; <[6 x i8]*> [#uses=6] + +define i32 @main(i32 %argc, i8** %argv) nounwind { +entry: + %argc_addr = alloca i32 ; [#uses=2] + %argv_addr = alloca i8** ; [#uses=2] + %retval = alloca i32 ; [#uses=2] + %str1 = alloca [6 x i8] ; <[6 x i8]*> [#uses=7] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) + %1 = bitcast i32* %argc_addr to { }* ; <{ }*> [#uses=1] + call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) + store i32 %argc, i32* %argc_addr + %2 = bitcast i8*** %argv_addr to { }* ; <{ }*> [#uses=1] + call void @llvm.dbg.declare({ }* %2, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable10 to { }*)) + store i8** %argv, i8*** %argv_addr + %3 = bitcast [6 x i8]* %str1 to { }* ; <{ }*> [#uses=1] + call void @llvm.dbg.declare({ }* %3, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable14 to { }*)) + call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + %4 = getelementptr [6 x i8]* %str1, i32 0, i32 0 ; [#uses=1] + %5 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 0), align 1 ; [#uses=1] + store i8 %5, i8* %4, align 1 + %6 = getelementptr [6 x i8]* %str1, i32 0, i32 1 ; [#uses=1] + %7 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 1), align 1 ; [#uses=1] + store i8 %7, i8* %6, align 1 + %8 = getelementptr [6 x i8]* %str1, i32 0, i32 2 ; [#uses=1] + %9 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 2), align 1 ; [#uses=1] + store i8 %9, i8* %8, align 1 + %10 = getelementptr [6 x i8]* %str1, i32 0, i32 3 ; [#uses=1] + %11 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 3), align 1 ; [#uses=1] + store i8 %11, i8* %10, align 1 + %12 = getelementptr [6 x i8]* %str1, i32 0, i32 4 ; [#uses=1] + %13 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 4), align 1 ; [#uses=1] + store i8 %13, i8* %12, align 1 + %14 = getelementptr [6 x i8]* %str1, i32 0, i32 5 ; [#uses=1] + %15 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 5), align 1 ; [#uses=1] + store i8 %15, i8* %14, align 1 + call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + store i32 0, i32* %0, align 4 + %16 = load i32* %0, align 4 ; [#uses=1] + store i32 %16, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) + ret i32 %retval1 +} + +declare void @llvm.dbg.func.start({ }*) nounwind + +declare void @llvm.dbg.declare({ }*, { }*) nounwind + +declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind + +declare void @llvm.dbg.region.end({ }*) nounwind -- GitLab From 7a1b4538a06bd3fdf07aea49ce62fc867e5588e6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 21:13:08 +0000 Subject: [PATCH 373/682] Add some comments on ISD::NodeType. llvm-svn: 63234 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index c22b90ceedf7..9f496d42afee 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -63,6 +63,13 @@ namespace ISD { /// ISD::NodeType enum - This enum defines all of the operators valid in a /// SelectionDAG. /// + /// These are sometimes called the target-independent operators; targets + /// may also define target-dependent operators. 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. + /// enum NodeType { // DELETED_NODE - This is an illegal flag value that is used to catch // errors. This opcode is not a legal opcode for any node. -- GitLab From 666bf2044170680b6e705211a221d29f19798f01 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Wed, 28 Jan 2009 21:18:29 +0000 Subject: [PATCH 374/682] Add DebugLoc-aware constructors for SDNode derived classes (those that reasonably have a DebugLoc associated with them). llvm-svn: 63236 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 84 +++++++++++++++++++ .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 23 +++++ 2 files changed, 107 insertions(+) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 9f496d42afee..89dea1bf0f9e 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1519,6 +1519,10 @@ public: : SDNode(Opc, VTs) { InitOperands(&Op, X); } + UnarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X) + : SDNode(Opc, dl, VTs) { + InitOperands(&Op, X); + } }; /// BinarySDNode - This class is used for two-operand SDNodes. This is solely @@ -1530,6 +1534,10 @@ public: : SDNode(Opc, VTs) { InitOperands(Ops, X, Y); } + BinarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y) + : SDNode(Opc, dl, VTs) { + InitOperands(Ops, X, Y); + } }; /// TernarySDNode - This class is used for three-operand SDNodes. This is solely @@ -1542,6 +1550,11 @@ public: : SDNode(Opc, VTs) { InitOperands(Ops, X, Y, Z); } + TernarySDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, SDValue X, SDValue Y, + SDValue Z) + : SDNode(Opc, dl, VTs) { + InitOperands(Ops, X, Y, Z); + } }; @@ -1591,6 +1604,14 @@ public: MVT MemoryVT, const Value *srcValue, int SVOff, unsigned alignment, bool isvolatile); + MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT MemoryVT, + const Value *srcValue, int SVOff, + unsigned alignment, bool isvolatile); + + MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, const SDValue *Ops, + unsigned NumOps, MVT MemoryVT, const Value *srcValue, int SVOff, + unsigned alignment, bool isvolatile); + /// Returns alignment and volatility of the memory access unsigned getAlignment() const { return (1u << (Flags >> 1)) >> 1; } bool isVolatile() const { return Flags & 1; } @@ -1669,6 +1690,21 @@ public: Align, /*isVolatile=*/true) { InitOperands(Ops, Chain, Ptr, Val); } + AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT, + SDValue Chain, SDValue Ptr, + SDValue Cmp, SDValue Swp, const Value* SrcVal, + unsigned Align=0) + : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0, + Align, /*isVolatile=*/true) { + InitOperands(Ops, Chain, Ptr, Cmp, Swp); + } + AtomicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTL, MVT MemVT, + SDValue Chain, SDValue Ptr, + SDValue Val, const Value* SrcVal, unsigned Align=0) + : MemSDNode(Opc, dl, VTL, MemVT, SrcVal, /*SVOffset=*/0, + Align, /*isVolatile=*/true) { + InitOperands(Ops, Chain, Ptr, Val); + } const SDValue &getBasePtr() const { return getOperand(1); } const SDValue &getVal() const { return getOperand(2); } @@ -1710,6 +1746,13 @@ public: : MemSDNode(Opc, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol), ReadMem(ReadMem), WriteMem(WriteMem) { } + MemIntrinsicSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, + const SDValue *Ops, unsigned NumOps, + MVT MemoryVT, const Value *srcValue, int SVO, + unsigned Align, bool Vol, bool ReadMem, bool WriteMem) + : MemSDNode(Opc, dl, VTs, Ops, NumOps, MemoryVT, srcValue, SVO, Align, Vol), + ReadMem(ReadMem), WriteMem(WriteMem) { + } bool readMem() const { return ReadMem; } bool writeMem() const { return WriteMem; } @@ -1928,6 +1971,9 @@ protected: explicit BasicBlockSDNode(MachineBasicBlock *mbb) : SDNode(ISD::BasicBlock, getSDVTList(MVT::Other)), MBB(mbb) { } + explicit BasicBlockSDNode(MachineBasicBlock *mbb, DebugLoc dl) + : SDNode(ISD::BasicBlock, dl, getSDVTList(MVT::Other)), MBB(mbb) { + } public: MachineBasicBlock *getBasicBlock() const { return MBB; } @@ -2037,6 +2083,10 @@ protected: : SDNode(NodeTy, getSDVTList(MVT::Other)), LabelID(id) { InitOperands(&Chain, ch); } + LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id) + : SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) { + InitOperands(&Chain, ch); + } public: unsigned getLabelID() const { return LabelID; } @@ -2055,6 +2105,10 @@ protected: : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, getSDVTList(VT)), Symbol(Sym) { } + ExternalSymbolSDNode(bool isTarget, DebugLoc dl, const char *Sym, MVT VT) + : SDNode(isTarget ? ISD::TargetExternalSymbol : ISD::ExternalSymbol, dl, + getSDVTList(VT)), Symbol(Sym) { + } public: const char *getSymbol() const { return Symbol; } @@ -2221,6 +2275,12 @@ protected: : SDNode(ISD::CALL, VTs, Operands, numOperands), CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall), Inreg(isinreg) {} + CallSDNode(unsigned cc, DebugLoc dl, bool isvararg, bool istailcall, + bool isinreg, SDVTList VTs, const SDValue *Operands, + unsigned numOperands) + : SDNode(ISD::CALL, dl, VTs, Operands, numOperands), + CallingConv(cc), IsVarArg(isvararg), IsTailCall(istailcall), + Inreg(isinreg) {} public: unsigned getCallingConv() const { return CallingConv; } unsigned isVarArg() const { return IsVarArg; } @@ -2295,6 +2355,16 @@ public: assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) && "Only indexed loads and stores have a non-undef offset operand"); } + LSBaseSDNode(ISD::NodeType NodeTy, DebugLoc dl, SDValue *Operands, + unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM, + MVT VT, const Value *SV, int SVO, unsigned Align, bool Vol) + : MemSDNode(NodeTy, dl, VTs, VT, SV, SVO, Align, Vol) { + SubclassData = AM; + InitOperands(Ops, Operands, numOperands); + assert(Align != 0 && "Loads and stores should have non-zero aligment"); + assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) && + "Only indexed loads and stores have a non-undef offset operand"); + } const SDValue &getOffset() const { return getOperand(getOpcode() == ISD::LOAD ? 2 : 3); @@ -2331,6 +2401,13 @@ protected: VTs, AM, LVT, SV, O, Align, Vol) { SubclassData |= (unsigned short)ETy << 3; } + LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs, + ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT, + const Value *SV, int O=0, unsigned Align=0, bool Vol=false) + : LSBaseSDNode(ISD::LOAD, dl, ChainPtrOff, 3, + VTs, AM, LVT, SV, O, Align, Vol) { + SubclassData |= (unsigned short)ETy << 3; + } public: /// getExtensionType - Return whether this is a plain node, @@ -2360,6 +2437,13 @@ protected: VTs, AM, SVT, SV, O, Align, Vol) { SubclassData |= (unsigned short)isTrunc << 3; } + StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs, + ISD::MemIndexedMode AM, bool isTrunc, MVT SVT, + const Value *SV, int O=0, unsigned Align=0, bool Vol=false) + : LSBaseSDNode(ISD::STORE, dl, ChainValuePtrOff, 4, + VTs, AM, SVT, SV, O, Align, Vol) { + SubclassData |= (unsigned short)isTrunc << 3; + } public: /// isTruncatingStore - Return true if the op does a truncation before store. diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 63fc97c20a82..49d4975d1276 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -4766,6 +4766,29 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, assert(isVolatile() == vol && "Volatile representation error!"); } +MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT memvt, + const Value *srcValue, int SVO, + unsigned alignment, bool vol) + : SDNode(Opc, dl, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), + Flags(encodeMemSDNodeFlags(vol, alignment)) { + + assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); + assert(getAlignment() == alignment && "Alignment representation error!"); + assert(isVolatile() == vol && "Volatile representation error!"); +} + +MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, + const SDValue *Ops, + unsigned NumOps, MVT memvt, const Value *srcValue, + int SVO, unsigned alignment, bool vol) + : SDNode(Opc, dl, VTs, Ops, NumOps), + MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), + Flags(vol | ((Log2_32(alignment) + 1) << 1)) { + assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); + assert(getAlignment() == alignment && "Alignment representation error!"); + assert(isVolatile() == vol && "Volatile representation error!"); +} + /// getMemOperand - Return a MachineMemOperand object describing the memory /// reference performed by this memory reference. MachineMemOperand MemSDNode::getMemOperand() const { -- GitLab From f675864e3c00b5601f17d8f11d723b12200a1535 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Wed, 28 Jan 2009 21:20:48 +0000 Subject: [PATCH 375/682] Add autorelease test case. llvm-svn: 63237 --- clang/test/Analysis/retain-release.m | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/clang/test/Analysis/retain-release.m b/clang/test/Analysis/retain-release.m index 0ce283ff24d2..66ff991b0976 100644 --- a/clang/test/Analysis/retain-release.m +++ b/clang/test/Analysis/retain-release.m @@ -47,6 +47,7 @@ typedef struct _NSZone NSZone; @protocol NSObject - (BOOL)isEqual:(id)object; - (id)retain; - (oneway void)release; +- (id)autorelease; @end @protocol NSCopying - (id)copyWithZone:(NSZone *)zone; @end @protocol NSCoding - (void)encodeWithCoder:(NSCoder *)aCoder; @end @interface NSObject { @@ -230,3 +231,9 @@ CREATEFUN MyCreateFun; void f12() { CFTypeRef o = MyCreateFun(); // expected-warning {{leak}} } + +void f13_autorelease() { + CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks); + [(id) A autorelease]; // no-warning +} + -- GitLab From 804c0441c2b71bd5a80aa121f39ddc5b1b1cbcee Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Wed, 28 Jan 2009 21:22:12 +0000 Subject: [PATCH 376/682] Handle complex types in ASTContext::mergeTypes llvm-svn: 63238 --- clang/lib/AST/ASTContext.cpp | 3 +++ clang/test/Sema/merge-decls.c | 9 +++++++++ 2 files changed, 12 insertions(+) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 5e2269105992..c43ae78c9f58 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2615,6 +2615,9 @@ QualType ASTContext::mergeTypes(QualType LHS, QualType RHS) { case Type::Builtin: // Only exactly equal builtin types are compatible, which is tested above. return QualType(); + case Type::Complex: + // Distinct complex types are incompatible. + return QualType(); case Type::Vector: if (areCompatVectorTypes(LHS->getAsVectorType(), RHS->getAsVectorType())) return LHS; diff --git a/clang/test/Sema/merge-decls.c b/clang/test/Sema/merge-decls.c index 0d3cce36bdc5..468f3f61428f 100644 --- a/clang/test/Sema/merge-decls.c +++ b/clang/test/Sema/merge-decls.c @@ -20,3 +20,12 @@ int funcdef2() { return 0; } // expected-error {{redefinition of 'funcdef2'}} // PR2502 void (*f)(void); void (*f)() = 0; + +typedef __attribute__(( ext_vector_type(2) )) int Vi2; +typedef __attribute__(( ext_vector_type(2) )) float Vf2; + +Vf2 g0; // expected-note {{previous definition is here}} +Vi2 g0; // expected-error {{redefinition of 'g0'}} + +_Complex int g1; // expected-note {{previous definition is here}} +_Complex float g1; // expected-error {{redefinition of 'g1'}} -- GitLab From f52ac415665a983709eeb9dc69b96a5ecbba5a8b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 21:34:36 +0000 Subject: [PATCH 377/682] Add more comments describing SDNode operator codes. llvm-svn: 63239 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 89dea1bf0f9e..aec6b62650e3 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -60,15 +60,19 @@ struct SDVTList { namespace ISD { //===--------------------------------------------------------------------===// - /// ISD::NodeType enum - This enum defines all of the operators valid in a - /// SelectionDAG. + /// ISD::NodeType enum - This enum defines the target-independent operators + /// for a SelectionDAG. /// - /// These are sometimes called the target-independent operators; targets - /// may also define target-dependent operators. 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. + /// 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 flag value that is used to catch -- GitLab From 511d5ece2b845e265c361a1212b0f8c355413c4a Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 28 Jan 2009 21:36:46 +0000 Subject: [PATCH 378/682] SDOperand has been renamed to SDValue. SDNode::Val is now accessed via SDNode::getNode. llvm-svn: 63240 --- llvm/docs/WritingAnLLVMBackend.html | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/llvm/docs/WritingAnLLVMBackend.html b/llvm/docs/WritingAnLLVMBackend.html index 0f38955f4eef..08da132028d0 100644 --- a/llvm/docs/WritingAnLLVMBackend.html +++ b/llvm/docs/WritingAnLLVMBackend.html @@ -1349,9 +1349,9 @@ ISD::STORE opcode.

      -
      SDNode *SelectCode(SDOperand N) {
      +
      SDNode *SelectCode(SDValue N) {
         ... 
      -  MVT::ValueType NVT = N.Val->getValueType(0);
      +  MVT::ValueType NVT = N.getNode()->getValueType(0);
         switch (N.getOpcode()) {
         case ISD::STORE: {
           switch (NVT) {
      @@ -1372,21 +1372,21 @@ instruction. 

      -
      SDNode *Select_ISD_STORE(const SDOperand &N) {
      -  SDOperand Chain = N.getOperand(0);
      -  if (Predicate_store(N.Val)) {
      -    SDOperand N1 = N.getOperand(1);
      -    SDOperand N2 = N.getOperand(2);
      -    SDOperand CPTmp0;
      -    SDOperand CPTmp1;
      +
      SDNode *Select_ISD_STORE(const SDValue &N) {
      +  SDValue Chain = N.getOperand(0);
      +  if (Predicate_store(N.getNode())) {
      +    SDValue N1 = N.getOperand(1);
      +    SDValue N2 = N.getOperand(2);
      +    SDValue CPTmp0;
      +    SDValue CPTmp1;
        
           // Pattern: (st:void IntRegs:i32:$src, 
           //           ADDRrr:i32:$addr)<<P:Predicate_store>>
           // Emits: (STrr:void ADDRrr:i32:$addr, IntRegs:i32:$src)
           // Pattern complexity = 13  cost = 1  size = 0
           if (SelectADDRrr(N, N2, CPTmp0, CPTmp1) &&
      -        N1.Val->getValueType(0) == MVT::i32 &&
      -        N2.Val->getValueType(0) == MVT::i32) {
      +        N1.getNode()->getValueType(0) == MVT::i32 &&
      +        N2.getNode()->getValueType(0) == MVT::i32) {
             return Emit_22(N, SP::STrr, CPTmp0, CPTmp1);
           }
       ...
      @@ -1520,8 +1520,8 @@ code, an FP_TO_SINT opcode will call the LowerFP_TO_SINT method:

      -
      SDOperand SparcTargetLowering::LowerOperation(
      -                               SDOperand Op, SelectionDAG &DAG) {
      +
      SDValue SparcTargetLowering::LowerOperation(
      +                               SDValue Op, SelectionDAG &DAG) {
         switch (Op.getOpcode()) {
         case ISD::FP_TO_SINT: return LowerFP_TO_SINT(Op, DAG);
         ...
      @@ -1535,7 +1535,7 @@ register to convert the floating-point value to an integer.

      -
      static SDOperand LowerFP_TO_SINT(SDOperand Op, SelectionDAG &DAG) {
      +
      static SDValue LowerFP_TO_SINT(SDValue Op, SelectionDAG &DAG) {
       assert(Op.getValueType() == MVT::i32);
         Op = DAG.getNode(SPISD::FTOI, MVT::f32, Op.getOperand(0));
         return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
      -- 
      GitLab
      
      
      From c78320960513fe9f193104cbb07b0a5711c81ee0 Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Wed, 28 Jan 2009 21:44:40 +0000
      Subject: [PATCH 379/682] retain/release checker: Always generate an
       "autorelease" summary for an "autorelease" message, and have the summary
       processing logic treat it as a no-op in GC mode.  This change is motivated to
       encode more of the semantics in the summaries themselves for eventual better
       diagnostics.
      
      llvm-svn: 63241
      ---
       clang/lib/Analysis/CFRefCount.cpp            | 18 ++---
       clang/test/Analysis/retain-release-gc-only.m | 81 ++++++++++++++++++++
       2 files changed, 90 insertions(+), 9 deletions(-)
       create mode 100644 clang/test/Analysis/retain-release-gc-only.m
      
      diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
      index 625eda4fb196..2d5cb5f5b89e 100644
      --- a/clang/lib/Analysis/CFRefCount.cpp
      +++ b/clang/lib/Analysis/CFRefCount.cpp
      @@ -979,13 +979,11 @@ void RetainSummaryManager::InitializeClassMethodSummaries() {
                       getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::ObjC)));
         
         // Create the [NSAutoreleasePool addObject:] summary.
      -  if (!isGCEnabled()) {    
      -    ScratchArgs.push_back(std::make_pair(0, Autorelease));
      -    addClsMethSummary(&Ctx.Idents.get("NSAutoreleasePool"),
      -                      GetUnarySelector("addObject", Ctx),
      -                      getPersistentSummary(RetEffect::MakeNoRet(),
      -                                           DoNothing, DoNothing));
      -  }
      +  ScratchArgs.push_back(std::make_pair(0, Autorelease));
      +  addClsMethSummary(&Ctx.Idents.get("NSAutoreleasePool"),
      +                    GetUnarySelector("addObject", Ctx),
      +                    getPersistentSummary(RetEffect::MakeNoRet(),
      +                                         DoNothing, DoNothing));
       }
       
       void RetainSummaryManager::InitializeMethodSummaries() {
      @@ -1023,7 +1021,7 @@ void RetainSummaryManager::InitializeMethodSummaries() {
         addNSObjectMethSummary(GetNullarySelector("drain", Ctx), Summ);
       
         // Create the "autorelease" selector.
      -  Summ = getPersistentSummary(E, isGCEnabled() ? DoNothing : Autorelease);
      +  Summ = getPersistentSummary(E, Autorelease);
         addNSObjectMethSummary(GetNullarySelector("autorelease", Ctx), Summ);
         
         // For NSWindow, allocated objects are (initially) self-owned.  
      @@ -2076,7 +2074,9 @@ RefBindings CFRefCount::Update(RefBindings B, SymbolRef sym,
             }      
             return B;
       
      -    case Autorelease:          
      +    case Autorelease:
      +      if (isGCEnabled()) return B;      
      +      // Fall-through.      
           case StopTracking:
             return RefBFactory.Remove(B, sym);
       
      diff --git a/clang/test/Analysis/retain-release-gc-only.m b/clang/test/Analysis/retain-release-gc-only.m
      new file mode 100644
      index 000000000000..7e8164a2cc59
      --- /dev/null
      +++ b/clang/test/Analysis/retain-release-gc-only.m
      @@ -0,0 +1,81 @@
      +// RUN: clang -analyze -checker-cfref -verify -fobjc-gc-only %s &&
      +// RUN: clang -analyze -checker-cfref -analyzer-store-region -fobjc-gc-only -verify %s
      +
      +//===----------------------------------------------------------------------===//
      +// Header stuff.
      +//===----------------------------------------------------------------------===//
      +typedef unsigned int __darwin_natural_t;
      +typedef unsigned long UInt32;
      +typedef signed long CFIndex;
      +typedef const void * CFTypeRef;
      +typedef const struct __CFString * CFStringRef;
      +typedef const struct __CFAllocator * CFAllocatorRef;
      +extern const CFAllocatorRef kCFAllocatorDefault;
      +extern CFTypeRef CFRetain(CFTypeRef cf);
      +extern void CFRelease(CFTypeRef cf);
      +typedef struct {
      +}
      +  CFArrayCallBacks;
      +extern const CFArrayCallBacks kCFTypeArrayCallBacks;
      +typedef const struct __CFArray * CFArrayRef;
      +typedef struct __CFArray * CFMutableArrayRef;
      +extern CFMutableArrayRef CFArrayCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFArrayCallBacks *callBacks);
      +extern const void *CFArrayGetValueAtIndex(CFArrayRef theArray, CFIndex idx);
      +typedef const struct __CFDictionary * CFDictionaryRef;
      +typedef UInt32 CFStringEncoding;
      +enum {
      +kCFStringEncodingMacRoman = 0,     kCFStringEncodingWindowsLatin1 = 0x0500,     kCFStringEncodingISOLatin1 = 0x0201,     kCFStringEncodingNextStepLatin = 0x0B01,     kCFStringEncodingASCII = 0x0600,     kCFStringEncodingUnicode = 0x0100,     kCFStringEncodingUTF8 = 0x08000100,     kCFStringEncodingNonLossyASCII = 0x0BFF      ,     kCFStringEncodingUTF16 = 0x0100,     kCFStringEncodingUTF16BE = 0x10000100,     kCFStringEncodingUTF16LE = 0x14000100,      kCFStringEncodingUTF32 = 0x0c000100,     kCFStringEncodingUTF32BE = 0x18000100,     kCFStringEncodingUTF32LE = 0x1c000100  };
      +extern CFStringRef CFStringCreateWithCString(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding);
      +typedef double CFTimeInterval;
      +typedef CFTimeInterval CFAbsoluteTime;
      +typedef const struct __CFDate * CFDateRef;
      +extern CFDateRef CFDateCreate(CFAllocatorRef allocator, CFAbsoluteTime at);
      +extern CFAbsoluteTime CFDateGetAbsoluteTime(CFDateRef theDate);
      +typedef __darwin_natural_t natural_t;
      +typedef natural_t mach_port_name_t;
      +typedef mach_port_name_t mach_port_t;
      +typedef signed char BOOL;
      +typedef struct _NSZone NSZone;
      +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
      +@protocol NSObject  - (BOOL)isEqual:(id)object;
      +- (id)retain;
      +- (oneway void)release;
      +- (id)autorelease;
      +@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
      +@end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
      +@end    @interface NSObject  {
      +}
      +@end  typedef float CGFloat;
      +typedef double NSTimeInterval;
      +@interface NSDate : NSObject   - (NSTimeInterval)timeIntervalSinceReferenceDate;
      +@end      enum {
      +NSObjCNoType = 0,     NSObjCVoidType = 'v',     NSObjCCharType = 'c',     NSObjCShortType = 's',     NSObjCLongType = 'l',     NSObjCLonglongType = 'q',     NSObjCFloatType = 'f',     NSObjCDoubleType = 'd',      NSObjCBoolType = 'B',      NSObjCSelectorType = ':',     NSObjCObjectType = '@',     NSObjCStructType = '{',     NSObjCPointerType = '^',     NSObjCStringType = '*',     NSObjCArrayType = '[',     NSObjCUnionType = '(',     NSObjCBitfield = 'b' }
      +__attribute__((deprecated));
      +typedef int kern_return_t;
      +typedef kern_return_t mach_error_t;
      +typedef mach_port_t io_object_t;
      +typedef io_object_t io_service_t;
      +typedef struct __DASession * DASessionRef;
      +extern DASessionRef DASessionCreate( CFAllocatorRef allocator );
      +typedef struct __DADisk * DADiskRef;
      +extern DADiskRef DADiskCreateFromBSDName( CFAllocatorRef allocator, DASessionRef session, const char * name );
      +extern DADiskRef DADiskCreateFromIOMedia( CFAllocatorRef allocator, DASessionRef session, io_service_t media );
      +extern CFDictionaryRef DADiskCopyDescription( DADiskRef disk );
      +extern DADiskRef DADiskCopyWholeDisk( DADiskRef disk );
      +@interface NSAppleEventManager : NSObject {
      +}
      +@end enum {
      +kDAReturnSuccess = 0,     kDAReturnError = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x01,     kDAReturnBusy = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x02,     kDAReturnBadArgument = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x03,     kDAReturnExclusiveAccess = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x04,     kDAReturnNoResources = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x05,     kDAReturnNotFound = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x06,     kDAReturnNotMounted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x07,     kDAReturnNotPermitted = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x08,     kDAReturnNotPrivileged = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x09,     kDAReturnNotReady = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0A,     kDAReturnNotWritable = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0B,     kDAReturnUnsupported = (((0x3e)&0x3f)<<26) | (((0x368)&0xfff)<<14) | 0x0C };
      +typedef mach_error_t DAReturn;
      +typedef const struct __DADissenter * DADissenterRef;
      +extern DADissenterRef DADissenterCreate( CFAllocatorRef allocator, DAReturn status, CFStringRef string );
      +
      +//===----------------------------------------------------------------------===//
      +// Test cases.
      +//===----------------------------------------------------------------------===//
      +
      +void f1() {
      +  CFMutableArrayRef A = CFArrayCreateMutable(0, 10, &kCFTypeArrayCallBacks);
      +  id x = [(id) A autorelease];
      +  CFRelease((CFMutableArrayRef) x); // no-warning
      +}
      -- 
      GitLab
      
      
      From 347f7eabb9ae43482f04855cde43f9d164b7b6f0 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Wed, 28 Jan 2009 21:54:33 +0000
      Subject: [PATCH 380/682] Code generation support for C99 designated
       initializers.
      
      The approach I've taken in this patch is relatively straightforward,
      although the code itself is non-trivial. Essentially, as we process
      an initializer list we build up a fully-explicit representation of the
      initializer list, where each of the subobject initializations occurs
      in order. Designators serve to "fill in" subobject initializations in
      a non-linear way. The fully-explicit representation makes initializer
      lists (both with and without designators) easy to grok for codegen and
      later semantic analyses. We keep the syntactic form of the initializer
      list linked into the AST for those clients interested in exactly what
      the user wrote.
      
      Known limitations:
        - Designating a member of a union that isn't the first member may
          result in bogus initialization (we warn about this)
        - GNU array-range designators are not supported (we warn about this)
      
      llvm-svn: 63242
      ---
       clang/Driver/RewriteObjC.cpp                  |   4 +-
       clang/include/clang/AST/Decl.h                |   3 +
       clang/include/clang/AST/Expr.h                | 106 +++--
       clang/include/clang/AST/ExprCXX.h             |   6 +
       .../clang/Basic/DiagnosticSemaKinds.def       |  12 +
       clang/lib/AST/Expr.cpp                        |  28 +-
       clang/lib/AST/StmtPrinter.cpp                 |  33 +-
       clang/lib/CodeGen/CGExprAgg.cpp               |  18 +-
       clang/lib/CodeGen/CGExprConstant.cpp          |   8 +-
       clang/lib/CodeGen/CGExprScalar.cpp            |   5 -
       clang/lib/Sema/Sema.h                         |  50 +-
       clang/lib/Sema/SemaDecl.cpp                   |   9 +
       clang/lib/Sema/SemaExpr.cpp                   |   5 +-
       clang/lib/Sema/SemaInit.cpp                   | 442 ++++++++++++++----
       clang/test/Sema/array-init.c                  |  28 +-
       clang/test/Sema/designated-initializers.c     |  30 +-
       clang/test/Sema/vector-init.c                 |  12 +-
       17 files changed, 620 insertions(+), 179 deletions(-)
      
      diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp
      index 4524920f5a5a..e2ddafe8d192 100644
      --- a/clang/Driver/RewriteObjC.cpp
      +++ b/clang/Driver/RewriteObjC.cpp
      @@ -2310,7 +2310,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
               // (struct objc_super) {  }
               InitListExpr *ILE = new InitListExpr(SourceLocation(), 
                                                    &InitExprs[0], InitExprs.size(), 
      -                                             SourceLocation(), false);
      +                                             SourceLocation());
               SuperRep = new CompoundLiteralExpr(SourceLocation(), superType, ILE,
                                                  false);
               // struct objc_super *
      @@ -2391,7 +2391,7 @@ Stmt *RewriteObjC::SynthMessageExpr(ObjCMessageExpr *Exp) {
               // (struct objc_super) {  }
               InitListExpr *ILE = new InitListExpr(SourceLocation(), 
                                                    &InitExprs[0], InitExprs.size(), 
      -                                             SourceLocation(), false);
      +                                             SourceLocation());
               SuperRep = new CompoundLiteralExpr(SourceLocation(), superType, ILE, false);
             }
             MsgExprs.push_back(SuperRep);
      diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
      index 988a7419a599..18d1c0546791 100644
      --- a/clang/include/clang/AST/Decl.h
      +++ b/clang/include/clang/AST/Decl.h
      @@ -678,6 +678,9 @@ public:
         /// isBitfield - Determines whether this field is a bitfield.
         bool isBitField() const { return BitWidth != NULL; }
       
      +  /// @brief Determines whether this is an unnamed bitfield.
      +  bool isUnnamedBitfield() const { return BitWidth != NULL && !getDeclName(); }
      +
         /// isAnonymousStructOrUnion - Determines whether this field is a
         /// representative for an anonymous struct or union. Such fields are
         /// unnamed and are implicitly generated by the implementation to
      diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
      index 5d768cd9dba3..861ac817ccac 100644
      --- a/clang/include/clang/AST/Expr.h
      +++ b/clang/include/clang/AST/Expr.h
      @@ -185,6 +185,10 @@ public:
         /// initializer, which can be emitted at compile-time.
         bool isConstantInitializer(ASTContext &Ctx) const;
         
      +  /// @brief Determines whether this expression (or any of its
      +  /// subexpressions) has side effects.
      +  bool hasSideEffects(ASTContext &Ctx) const;
      +
         /// EvalResult is a struct with detailed info about an evaluated expression.
         struct EvalResult {
           /// Val - This is the scalar value the expression can be folded to.
      @@ -1619,48 +1623,65 @@ public:
         static VAArgExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C);
       };
         
      -/// InitListExpr - used for struct and array initializers, such as:
      -///    struct foo x = { 1, { 2, 3 } };
      +/// @brief Describes an C or C++ initializer list.
      +///
      +/// InitListExpr describes an initializer list, which can be used to
      +/// initialize objects of different types, including
      +/// struct/class/union types, arrays, and vectors. For example:
      +///
      +/// @code
      +/// struct foo x = { 1, { 2, 3 } };
      +/// @endcode
       ///
      -/// Because C is somewhat loose with braces, the AST does not necessarily
      -/// directly model the C source.  Instead, the semantic analyzer aims to make
      -/// the InitListExprs match up with the type of the decl being initialized.  We
      -/// have the following exceptions:
      +/// Prior to semantic analysis, an initializer list will represent the
      +/// initializer list as written by the user, but will have the
      +/// placeholder type "void". This initializer list is called the
      +/// syntactic form of the initializer, and may contain C99 designated
      +/// initializers (represented as DesignatedInitExprs), initializations
      +/// of subobject members without explicit braces, and so on. Clients
      +/// interested in the original syntax of the initializer list should
      +/// use the syntactic form of the initializer list.
       ///
      -///  1. Elements at the end of the list may be dropped from the initializer.  
      -///     These elements are defined to be initialized to zero.  For example:
      -///         int x[20] = { 1 };
      -///  2. Initializers may have excess initializers which are to be ignored by the
      -///     compiler.  For example:
      -///         int x[1] = { 1, 2 };
      -///  3. Redundant InitListExprs may be present around scalar elements.  These
      -///     always have a single element whose type is the same as the InitListExpr.
      -///     this can only happen for Type::isScalarType() types.
      -///         int x = { 1 };  int y[2] = { {1}, {2} };
      +/// After semantic analysis, the initializer list will represent the
      +/// semantic form of the initializer, where the initializations of all
      +/// subobjects are made explicit with nested InitListExpr nodes and
      +/// C99 designators have been eliminated by placing the designated
      +/// initializations into the subobject they initialize. Additionally,
      +/// any "holes" in the initialization, where no initializer has been
      +/// specified for a particular subobject, will be replaced with
      +/// implicitly-generated CXXZeroInitValueExpr expressions that
      +/// value-initialize the subobjects. Note, however, that the
      +/// initializer lists may still have fewer initializers than there are
      +/// elements to initialize within the object.
       ///
      +/// Given the semantic form of the initializer list, one can retrieve
      +/// the original syntactic form of that initializer list (if it
      +/// exists) using getSyntacticForm(). Since many initializer lists
      +/// have the same syntactic and semantic forms, getSyntacticForm() may
      +/// return NULL, indicating that the current initializer list also
      +/// serves as its syntactic form.
       class InitListExpr : public Expr {
         std::vector InitExprs;
         SourceLocation LBraceLoc, RBraceLoc;
         
      -  /// HadDesignators - Return true if there were any designators in this
      -  /// init list expr.  FIXME: this should be replaced by storing the designators
      -  /// somehow and updating codegen.
      -  bool HadDesignators;
      +  /// Contains the initializer list that describes the syntactic form
      +  /// written in the source code.
      +  InitListExpr *SyntacticForm;
      +
       public:
         InitListExpr(SourceLocation lbraceloc, Expr **initexprs, unsigned numinits,
      -               SourceLocation rbraceloc, bool HadDesignators);
      +               SourceLocation rbraceloc);
         
         unsigned getNumInits() const { return InitExprs.size(); }
      -  bool hadDesignators() const { return HadDesignators; }
         
         const Expr* getInit(unsigned Init) const { 
           assert(Init < getNumInits() && "Initializer access out of range!");
      -    return cast(InitExprs[Init]);
      +    return cast_or_null(InitExprs[Init]);
         }
         
         Expr* getInit(unsigned Init) { 
           assert(Init < getNumInits() && "Initializer access out of range!");
      -    return cast(InitExprs[Init]);
      +    return cast_or_null(InitExprs[Init]);
         }
         
         void setInit(unsigned Init, Expr *expr) { 
      @@ -1668,13 +1689,22 @@ public:
           InitExprs[Init] = expr;
         }
       
      -  // Dynamic removal/addition (for constructing implicit InitExpr's).
      -  void removeInit(unsigned Init) {
      -    InitExprs.erase(InitExprs.begin()+Init);
      -  }
      -  void addInit(unsigned Init, Expr *expr) {
      -    InitExprs.insert(InitExprs.begin()+Init, expr);
      -  }
      +  /// @brief Specify the number of initializers
      +  ///
      +  /// If there are more than @p NumInits initializers, the remaining
      +  /// initializers will be destroyed. If there are fewer than @p
      +  /// NumInits initializers, NULL expressions will be added for the
      +  /// unknown initializers.
      +  void resizeInits(ASTContext &Context, unsigned NumInits);
      +
      +  /// @brief Updates the initializer at index @p Init with the new
      +  /// expression @p expr, and returns the old expression at that
      +  /// location.
      +  ///
      +  /// When @p Init is out of range for this initializer list, the
      +  /// initializer list will be extended with NULL expressions to
      +  /// accomodate the new entry.
      +  Expr *updateInit(unsigned Init, Expr *expr);
       
         // Explicit InitListExpr's originate from source code (and have valid source
         // locations). Implicit InitListExpr's are created by the semantic analyzer.
      @@ -1682,6 +1712,13 @@ public:
           return LBraceLoc.isValid() && RBraceLoc.isValid();
         }
         
      +  /// @brief Retrieve the initializer list that describes the
      +  /// syntactic form of the initializer.
      +  ///
      +  /// 
      +  InitListExpr *getSyntacticForm() const { return SyntacticForm; }
      +  void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
      +
         virtual SourceRange getSourceRange() const {
           return SourceRange(LBraceLoc, RBraceLoc);
         } 
      @@ -1885,6 +1922,13 @@ public:
                    "Only valid on an array-range designator");
             return SourceLocation::getFromRawEncoding(ArrayOrRange.EllipsisLoc);
           }
      +
      +    SourceLocation getStartLocation() const {
      +      if (Kind == FieldDesignator)
      +        return getDotLoc().isInvalid()? getFieldLoc() : getDotLoc();
      +      else
      +        return getLBracketLoc();
      +    }
         };
       
         static DesignatedInitExpr *Create(ASTContext &C, Designator *Designators, 
      diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
      index 669e790b3996..4f48eb3716a9 100644
      --- a/clang/include/clang/AST/ExprCXX.h
      +++ b/clang/include/clang/AST/ExprCXX.h
      @@ -477,6 +477,12 @@ public:
         SourceLocation getTypeBeginLoc() const { return TyBeginLoc; }
         SourceLocation getRParenLoc() const { return RParenLoc; }
       
      +  /// @brief Whether this initialization expression was
      +  /// implicitly-generated.
      +  bool isImplicit() const { 
      +    return TyBeginLoc.isInvalid() && RParenLoc.isInvalid(); 
      +  }
      +
         virtual SourceRange getSourceRange() const {
           return SourceRange(TyBeginLoc, RParenLoc);
         }
      diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      index 2959f6186b74..222e39911b81 100644
      --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      @@ -50,8 +50,20 @@ DIAG(err_field_designator_nonfield, ERROR,
            "field designator %0 does not refer to a non-static data member")
       DIAG(note_field_designator_found, NOTE,
            "field designator refers here")
      +DIAG(err_field_designator_anon_class, ERROR,
      +     "field designator %0 refers to a member of an anonymous %select{struct|class|union}1")
       DIAG(err_designator_for_scalar_init, ERROR,
            "designator in initializer for scalar type %0")
      +DIAG(warn_subobject_initializer_overrides, WARNING,
      +     "subobject initialization overrides initialization of other fields within its enclosing subobject")
      +DIAG(warn_initializer_overrides, WARNING,
      +     "initializer overrides prior initialization of this subobject")
      +DIAG(note_previous_initializer, NOTE,
      +     "previous initialization %select{|with side effects }0is here%select{| (side effects may not occur at run time)}0")
      +DIAG(warn_gnu_array_range_designator_unsupported, WARNING,
      +     "GNU array-range designator extension is unsupported")
      +DIAG(warn_designator_into_union_broken_init, WARNING,
      +     "designated initialization of union member is broken")
       
       // Declarations.
       DIAG(ext_vla, EXTENSION,
      diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
      index 8e43f99b6729..ed73bfae27b2 100644
      --- a/clang/lib/AST/Expr.cpp
      +++ b/clang/lib/AST/Expr.cpp
      @@ -221,13 +221,31 @@ const char *BinaryOperator::getOpcodeStr(Opcode Op) {
       
       InitListExpr::InitListExpr(SourceLocation lbraceloc, 
                                  Expr **initExprs, unsigned numInits,
      -                           SourceLocation rbraceloc, bool hadDesignators)
      +                           SourceLocation rbraceloc)
         : Expr(InitListExprClass, QualType()),
      -    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), HadDesignators(hadDesignators) {
      +    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0) {
       
         InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
       }
       
      +void InitListExpr::resizeInits(ASTContext &Context, unsigned NumInits) {
      +  for (unsigned Idx = NumInits, LastIdx = InitExprs.size(); Idx < LastIdx; ++Idx)
      +    delete InitExprs[Idx];
      +  InitExprs.resize(NumInits, 0);
      +}
      +
      +Expr *InitListExpr::updateInit(unsigned Init, Expr *expr) {
      +  if (Init >= InitExprs.size()) {
      +    InitExprs.insert(InitExprs.end(), Init - InitExprs.size() + 1, 0);
      +    InitExprs.back() = expr;
      +    return 0;
      +  }
      +  
      +  Expr *Result = cast_or_null(InitExprs[Init]);
      +  InitExprs[Init] = expr;
      +  return Result;
      +}
      +
       /// getFunctionType - Return the underlying function type for this block.
       ///
       const FunctionType *BlockExpr::getFunctionType() const {
      @@ -740,6 +758,12 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const {
         return isEvaluatable(Ctx);
       }
       
      +bool Expr::hasSideEffects(ASTContext &Ctx) const {
      +  EvalResult Result;
      +  Evaluate(Result, Ctx);
      +  return Result.HasSideEffects;
      +}
      +
       /// isIntegerConstantExpr - this recursive routine will test if an expression is
       /// an integer constant expression. Note: With the introduction of VLA's in
       /// C99 the result of the sizeof operator is no longer always a constant
      diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
      index 80de5b8ae454..7a558ab8dd7b 100644
      --- a/clang/lib/AST/StmtPrinter.cpp
      +++ b/clang/lib/AST/StmtPrinter.cpp
      @@ -872,13 +872,38 @@ void StmtPrinter::VisitInitListExpr(InitListExpr* Node) {
         OS << "{ ";
         for (unsigned i = 0, e = Node->getNumInits(); i != e; ++i) {
           if (i) OS << ", ";
      -    PrintExpr(Node->getInit(i));
      +    if (Node->getInit(i))
      +      PrintExpr(Node->getInit(i));
      +    else
      +      OS << "0";
         }
         OS << " }";
       }
       
       void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
      -  // FIXME!
      +  for (DesignatedInitExpr::designators_iterator D = Node->designators_begin(),
      +                      DEnd = Node->designators_end();
      +       D != DEnd; ++D) {
      +    if (D->isFieldDesignator()) {
      +      if (D->getDotLoc().isInvalid())
      +        OS << D->getFieldName()->getName() << ":";
      +      else
      +        OS << "." << D->getFieldName()->getName();
      +    } else {
      +      OS << "[";
      +      if (D->isArrayDesignator()) {
      +        PrintExpr(Node->getArrayIndex(*D));
      +      } else {
      +        PrintExpr(Node->getArrayRangeStart(*D));
      +        OS << " ... ";
      +        PrintExpr(Node->getArrayRangeEnd(*D));        
      +      }
      +      OS << "]";
      +    }
      +  }
      +
      +  OS << " = ";
      +  PrintExpr(Node->getInit());
       }
       
       void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
      @@ -1187,7 +1212,9 @@ void StmtPrinter::VisitBlockDeclRefExpr(BlockDeclRefExpr *Node) {
       //===----------------------------------------------------------------------===//
       
       void Stmt::dumpPretty() const {
      -  printPretty(llvm::errs());
      +  llvm::raw_ostream &OS = llvm::errs();
      +  printPretty(OS);
      +  OS.flush();
       }
       
       void Stmt::printPretty(llvm::raw_ostream &OS, PrinterHelper* Helper) const {
      diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
      index 9181bf665450..2534a14cb6c5 100644
      --- a/clang/lib/CodeGen/CGExprAgg.cpp
      +++ b/clang/lib/CodeGen/CGExprAgg.cpp
      @@ -71,7 +71,7 @@ public:
         void VisitArraySubscriptExpr(ArraySubscriptExpr *E) {
           EmitAggLoadOfLValue(E);
         }
      -
      +  
         // Operators.
         //  case Expr::UnaryOperatorClass:
         //  case Expr::CastExprClass: 
      @@ -303,11 +303,6 @@ void AggExprEmitter::VisitVAArgExpr(VAArgExpr *VE) {
       }
       
       void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {
      -  if (E->hadDesignators()) {
      -    CGF.ErrorUnsupported(E, "initializer list with designators");
      -    return;
      -  }
      -  
         const llvm::PointerType *APType =
           cast(DestPtr->getType());
         const llvm::Type *DestType = APType->getElementType();
      @@ -346,6 +341,8 @@ void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
         // FIXME: Are initializers affected by volatile?
         if (E->getType()->isComplexType()) {
           CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
      +  } else if (isa(E)) {
      +    EmitNullInitializationToLValue(LV, E->getType());
         } else if (CGF.hasAggregateLLVMType(E->getType())) {
           CGF.EmitAnyExpr(E, LV.getAddress(), false);
         } else {
      @@ -380,11 +377,6 @@ void AggExprEmitter::EmitNullInitializationToLValue(LValue LV, QualType T) {
       }
       
       void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
      -  if (E->hadDesignators()) {
      -    CGF.ErrorUnsupported(E, "initializer list with designators");
      -    return;
      -  }
      -
       #if 0
         // FIXME: Disabled while we figure out what to do about 
         // test/CodeGen/bitfield.c
      @@ -426,7 +418,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
       
           uint64_t NumArrayElements = AType->getNumElements();
           QualType ElementType = CGF.getContext().getCanonicalType(E->getType());
      -    ElementType =CGF.getContext().getAsArrayType(ElementType)->getElementType();
      +    ElementType = CGF.getContext().getAsArrayType(ElementType)->getElementType();
           
           unsigned CVRqualifier = ElementType.getCVRQualifiers();
       
      @@ -479,7 +471,7 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
           }
       
           // Unions only initialize one field.
      -    // (things can get weird with designators, but they aren't
      +    // (FIXME: things can get weird with designators, but they aren't
           // supported yet.)
           if (isUnion)
             break;
      diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
      index 32d126e5903e..3b6ebb4d56f3 100644
      --- a/clang/lib/CodeGen/CGExprConstant.cpp
      +++ b/clang/lib/CodeGen/CGExprConstant.cpp
      @@ -242,6 +242,8 @@ public:
           const llvm::Type *Ty = ConvertType(ILE->getType());
       
           // Find the field decl we're initializing, if any
      +    // FIXME: C99 designated initializers won't always initialize the 
      +    // first field
           int FieldNo = 0; // Field no in RecordDecl
           FieldDecl* curField = 0;
           for (RecordDecl::field_iterator Field = RD->field_begin(),
      @@ -304,12 +306,6 @@ public:
             return llvm::Constant::getNullValue(RetTy);
           }
           
      -    // FIXME: We don't codegen or sema designators yet.
      -    if (ILE->hadDesignators()) {
      -      CGM.ErrorUnsupported(ILE, "initializer list with designators");
      -      return llvm::UndefValue::get(ConvertType(ILE->getType()));
      -    }
      -
           if (ILE->getType()->isArrayType())
             return EmitArrayInitialization(ILE);
       
      diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
      index 33c5a6124bdc..dd8b30041e70 100644
      --- a/clang/lib/CodeGen/CGExprScalar.cpp
      +++ b/clang/lib/CodeGen/CGExprScalar.cpp
      @@ -176,11 +176,6 @@ public:
           if (!VType) 
             return Visit(E->getInit(0));
           
      -    if (E->hadDesignators()) {
      -      CGF.ErrorUnsupported(E, "initializer list with designators");
      -      return llvm::UndefValue::get(CGF.ConvertType(E->getType()));
      -    }
      -    
           unsigned NumVectorElements = VType->getNumElements();
           const llvm::Type *ElementType = VType->getElementType();
       
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index d017e6f9c7bc..8cf10ff3e2a7 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -28,6 +28,7 @@
       #include "llvm/ADT/OwningPtr.h"
       #include 
       #include 
      +#include 
       
       namespace llvm {
         class APSInt;
      @@ -1835,38 +1836,67 @@ private:
       class InitListChecker {
         Sema *SemaRef;
         bool hadError;
      +  std::map SyntacticToSemantic;
      +  InitListExpr *FullyStructuredList;
         
         void CheckImplicitInitList(InitListExpr *ParentIList, QualType T, 
      -                             unsigned &Index);
      +                             unsigned &Index, InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
         void CheckExplicitInitList(InitListExpr *IList, QualType &T,
      -                             unsigned &Index);
      -
      +                             unsigned &Index, InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
         void CheckListElementTypes(InitListExpr *IList, QualType &DeclType, 
                                    bool SubobjectIsDesignatorContext, 
      -                             unsigned &Index);
      +                             unsigned &Index,
      +                             InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
         void CheckSubElementType(InitListExpr *IList, QualType ElemType, 
      -                           Expr *expr, unsigned &Index);
      +                           Expr *expr, unsigned &Index,
      +                           InitListExpr *StructuredInitList,
      +                           unsigned &StructuredInitIndex);
         // FIXME: Does DeclType need to be a reference type?
         void CheckScalarType(InitListExpr *IList, QualType &DeclType, 
      -                       Expr *expr, unsigned &Index);
      -  void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index);
      +                       Expr *expr, unsigned &Index,
      +                       InitListExpr *StructuredInitList,
      +                       unsigned &StructuredInitIndex);
      +  void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index,
      +                       InitListExpr *StructuredInitList,
      +                       unsigned &StructuredInitIndex);
         void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, 
                                    RecordDecl::field_iterator Field, 
      -                             bool SubobjectIsDesignatorContext, unsigned &Index);
      +                             bool SubobjectIsDesignatorContext, unsigned &Index,
      +                             InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
         void CheckArrayType(InitListExpr *IList, QualType &DeclType, 
                             llvm::APSInt elementIndex, 
      -                      bool SubobjectIsDesignatorContext, unsigned &Index);
      +                      bool SubobjectIsDesignatorContext, unsigned &Index,
      +                      InitListExpr *StructuredInitList,
      +                      unsigned &StructuredInitIndex);
         bool CheckDesignatedInitializer(InitListExpr *IList, DesignatedInitExpr *DIE, 
                                         DesignatedInitExpr::designators_iterator D,
                                         QualType &CurrentObjectType, 
                                         RecordDecl::field_iterator *NextField,
                                         llvm::APSInt *NextElementIndex,
      -                                  unsigned &Index);
      +                                  unsigned &Index,
      +                                  InitListExpr *StructuredList,
      +                                  unsigned &StructuredIndex);
      +  InitListExpr *getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
      +                                           QualType CurrentObjectType,
      +                                           InitListExpr *StructuredList,
      +                                           unsigned StructuredIndex,
      +                                           SourceRange InitRange);
      +  void UpdateStructuredListElement(InitListExpr *StructuredInitList,
      +                                   unsigned &StructuredInitIndex,
      +                                   Expr *expr);
         int numArrayElements(QualType DeclType);
         int numStructUnionElements(QualType DeclType);
       public:
         InitListChecker(Sema *S, InitListExpr *IL, QualType &T);
         bool HadError() { return hadError; }
      +
      +  // @brief Retrieves the fully-structured initializer list used for
      +  // semantic analysis and code generation.
      +  InitListExpr *getFullyStructuredList() const { return FullyStructuredList; }
       };
       
       /// BlockSemaInfo - When a block is being parsed, this contains information
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index cfbd288aaea9..79efc7df9c0c 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -1136,6 +1136,9 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
         }
       
         InitListChecker CheckInitList(this, InitList, DeclType);
      +  if (!CheckInitList.HadError())
      +    Init = CheckInitList.getFullyStructuredList();
      +
         return CheckInitList.HadError();
       }
       
      @@ -2209,6 +2212,12 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
           for (unsigned i = 0; i < numInits; i++) {
             // FIXME: Need to get the type of the declaration for C++,
             // because it could be a reference?
      +
      +      // Implicitly-generated value initializations are okay.
      +      if (isa(Exp->getInit(i)) &&
      +          cast(Exp->getInit(i))->isImplicit()) 
      +        continue;
      +
             if (CheckForConstantInitializer(Exp->getInit(i),
                                             Exp->getInit(i)->getType()))
               return true;
      diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
      index 770404d82ac1..064b8517f7c3 100644
      --- a/clang/lib/Sema/SemaExpr.cpp
      +++ b/clang/lib/Sema/SemaExpr.cpp
      @@ -1985,7 +1985,7 @@ Sema::ActOnInitList(SourceLocation LBraceLoc, MultiExprArg initlist,
         // CheckInitializer() - it requires knowledge of the object being intialized. 
       
         InitListExpr *E = new (Context) InitListExpr(LBraceLoc, InitList, NumInit, 
      -                                    RBraceLoc, Designators.hasAnyDesignators());
      +                                               RBraceLoc);
         E->setType(Context.VoidTy); // FIXME: just a place holder for now.
         return Owned(E);
       }
      @@ -3988,8 +3988,7 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
         // Otherwise, create a compound literal expression as the base, and
         // iteratively process the offsetof designators.
         InitListExpr *IList =
      -      new (Context) InitListExpr(SourceLocation(), 0, 0,
      -                                 SourceLocation(), false);
      +      new (Context) InitListExpr(SourceLocation(), 0, 0, SourceLocation());
         IList->setType(ArgTy);
         Expr *Res =
             new (Context) CompoundLiteralExpr(SourceLocation(), ArgTy, IList, false);
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 041e994bca8f..511a394d8f26 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -15,19 +15,73 @@
       #include "clang/Parse/Designator.h"
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/Expr.h"
      +#include "clang/AST/ExprCXX.h"
       #include "clang/Basic/DiagnosticSema.h"
      -#include  // for std::count_if
      -#include  // for std::mem_fun
      -
       using namespace clang;
       
      +/// Recursively replaces NULL values within the given initializer list
      +/// with expressions that perform value-initialization of the
      +/// appropriate type.
      +static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) {
      +  assert((ILE->getType() != Context.VoidTy) && "Should not have void type");
      +  if (const RecordType *RType = ILE->getType()->getAsRecordType()) {
      +    unsigned Init = 0, NumInits = ILE->getNumInits();
      +    for (RecordDecl::field_iterator Field = RType->getDecl()->field_begin(),
      +                                 FieldEnd = RType->getDecl()->field_end();
      +         Field != FieldEnd; ++Field) {
      +      if (Field->isUnnamedBitfield())
      +        continue;
      +
      +      if (Init >= NumInits)
      +        break;
      +
      +      // FIXME: Check for fields with reference type in C++?
      +      if (!ILE->getInit(Init))
      +        ILE->setInit(Init, 
      +                     new (Context) CXXZeroInitValueExpr(Field->getType(), 
      +                                                        SourceLocation(),
      +                                                        SourceLocation()));
      +      else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init)))
      +        fillInValueInitializations(Context, InnerILE);
      +      ++Init;
      +    }
      +
      +    return;
      +  } 
      +
      +  QualType ElementType;
      +  
      +  if (const ArrayType *AType = Context.getAsArrayType(ILE->getType()))
      +    ElementType = AType->getElementType();
      +  else if (const VectorType *VType = ILE->getType()->getAsVectorType())
      +    ElementType = VType->getElementType();
      +  else 
      +    ElementType = ILE->getType();
      +  
      +  for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; 
      +       ++Init) {
      +    if (!ILE->getInit(Init))
      +      ILE->setInit(Init, new (Context) CXXZeroInitValueExpr(ElementType, 
      +                                                            SourceLocation(),
      +                                                            SourceLocation()));
      +    else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init)))
      +      fillInValueInitializations(Context, InnerILE);
      +  }
      +}
      +
       InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
         hadError = false;
         SemaRef = S;
       
         unsigned newIndex = 0;
      +  unsigned newStructuredIndex = 0;
      +  FullyStructuredList 
      +    = getStructuredSubobjectInit(IL, newIndex, T, 0, 0, SourceRange());
      +  CheckExplicitInitList(IL, T, newIndex, FullyStructuredList, newStructuredIndex);
       
      -  CheckExplicitInitList(IL, T, newIndex);
      +  if (!hadError) {
      +    fillInValueInitializations(SemaRef->Context, FullyStructuredList);
      +  }
       }
       
       int InitListChecker::numArrayElements(QualType DeclType) {
      @@ -42,17 +96,22 @@ int InitListChecker::numArrayElements(QualType DeclType) {
       
       int InitListChecker::numStructUnionElements(QualType DeclType) {
         RecordDecl *structDecl = DeclType->getAsRecordType()->getDecl();
      -  const int InitializableMembers 
      -    = std::count_if(structDecl->field_begin(), structDecl->field_end(),
      -                    std::mem_fun(&FieldDecl::getDeclName));
      +  int InitializableMembers = 0;
      +  for (RecordDecl::field_iterator Field = structDecl->field_begin(),
      +                               FieldEnd = structDecl->field_end();
      +       Field != FieldEnd; ++Field) {
      +    if ((*Field)->getIdentifier() || !(*Field)->isBitField())
      +      ++InitializableMembers;
      +  }
         if (structDecl->isUnion())
           return std::min(InitializableMembers, 1);
         return InitializableMembers - structDecl->hasFlexibleArrayMember();
       }
       
       void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList, 
      -                                            QualType T, unsigned &Index) {
      -  llvm::SmallVector InitExprs;
      +                                            QualType T, unsigned &Index,
      +                                            InitListExpr *StructuredList,
      +                                            unsigned &StructuredIndex) {
         int maxElements = 0;
         
         if (T->isArrayType())
      @@ -64,45 +123,39 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList,
         else
           assert(0 && "CheckImplicitInitList(): Illegal type");
       
      +  // FIXME: Perhaps we should move this warning elsewhere?
         if (maxElements == 0) {
           SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(),
                         diag::err_implicit_empty_initializer);
      +    ++Index;
           hadError = true;
           return;
         }
       
      -  // Check the element types *before* we create the implicit init list;
      -  // otherwise, we might end up taking the wrong number of elements
      -  unsigned NewIndex = Index;
      -  CheckListElementTypes(ParentIList, T, false, NewIndex);
      -
      -  for (int i = 0; i < maxElements; ++i) {
      -    // Don't attempt to go past the end of the init list
      -    if (Index >= ParentIList->getNumInits())
      -      break;
      -    Expr* expr = ParentIList->getInit(Index);
      -    
      -    // Add the expr to the new implicit init list and remove if from the old.
      -    InitExprs.push_back(expr);
      -    ParentIList->removeInit(Index);
      -  }
      -  // Synthesize an "implicit" InitListExpr (marked by the invalid source locs).
      -  InitListExpr *ILE = new InitListExpr(SourceLocation(), 
      -                                       &InitExprs[0], InitExprs.size(), 
      -                                       SourceLocation(),
      -                                       ParentIList->hadDesignators());
      -  ILE->setType(T);
      -
      -  // Modify the parent InitListExpr to point to the implicit InitListExpr.
      -  ParentIList->addInit(Index, ILE);
      +  // Build a structured initializer list corresponding to this subobject.
      +  InitListExpr *StructuredSubobjectInitList
      +    = getStructuredSubobjectInit(ParentIList, Index, T, StructuredList, 
      +                                 StructuredIndex, 
      +                                 ParentIList->getInit(Index)->getSourceRange());
      +  unsigned StructuredSubobjectInitIndex = 0;
      +
      +  // Check the element types and build the structural subobject.
      +  CheckListElementTypes(ParentIList, T, false, Index,
      +                        StructuredSubobjectInitList, 
      +                        StructuredSubobjectInitIndex);
       }
       
       void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
      -                                            unsigned &Index) {
      +                                            unsigned &Index,
      +                                            InitListExpr *StructuredList,
      +                                            unsigned &StructuredIndex) {
         assert(IList->isExplicit() && "Illegal Implicit InitListExpr");
      -
      -  CheckListElementTypes(IList, T, true, Index);
      +  SyntacticToSemantic[IList] = StructuredList;
      +  StructuredList->setSyntacticForm(IList);
      +  CheckListElementTypes(IList, T, true, Index, StructuredList, 
      +                        StructuredIndex);
         IList->setType(T);
      +  StructuredList->setType(T);
         if (hadError)
           return;
       
      @@ -131,27 +184,31 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T,
       void InitListChecker::CheckListElementTypes(InitListExpr *IList,
                                                   QualType &DeclType, 
                                                   bool SubobjectIsDesignatorContext,
      -                                            unsigned &Index) {
      +                                            unsigned &Index,
      +                                            InitListExpr *StructuredList,
      +                                            unsigned &StructuredIndex) {
         if (DeclType->isScalarType()) {
      -    CheckScalarType(IList, DeclType, 0, Index);
      +    CheckScalarType(IList, DeclType, 0, Index, StructuredList, StructuredIndex);
         } else if (DeclType->isVectorType()) {
      -    CheckVectorType(IList, DeclType, Index);
      +    CheckVectorType(IList, DeclType, Index, StructuredList, StructuredIndex);
         } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
           if (DeclType->isStructureType() || DeclType->isUnionType()) {
             RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
             CheckStructUnionTypes(IList, DeclType, RD->field_begin(), 
      -                            SubobjectIsDesignatorContext, Index);
      +                            SubobjectIsDesignatorContext, Index,
      +                            StructuredList, StructuredIndex);
           } else if (DeclType->isArrayType()) {
             llvm::APSInt Zero(
                             SemaRef->Context.getTypeSize(SemaRef->Context.getSizeType()),
                             false);
      -      CheckArrayType(IList, DeclType, Zero, SubobjectIsDesignatorContext, Index);
      +      CheckArrayType(IList, DeclType, Zero, SubobjectIsDesignatorContext, Index,
      +                     StructuredList, StructuredIndex);
           }
           else
      -      assert(0 && "Aggregate that isn't a function or array?!");
      +      assert(0 && "Aggregate that isn't a structure or array?!");
         } else if (DeclType->isVoidType() || DeclType->isFunctionType()) {
           // This type is invalid, issue a diagnostic.
      -    Index++;
      +    ++Index;
           SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type)
             << DeclType;
           hadError = true;
      @@ -165,31 +222,46 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
       void InitListChecker::CheckSubElementType(InitListExpr *IList,
                                                 QualType ElemType, 
                                                 Expr *expr,
      -                                          unsigned &Index) {
      +                                          unsigned &Index,
      +                                          InitListExpr *StructuredList,
      +                                          unsigned &StructuredIndex) {
         if (InitListExpr *SubInitList = dyn_cast(expr)) {
           unsigned newIndex = 0;
      -    CheckExplicitInitList(SubInitList, ElemType, newIndex);
      -    Index++;
      +    unsigned newStructuredIndex = 0;
      +    InitListExpr *newStructuredList 
      +      = getStructuredSubobjectInit(IList, Index, ElemType,
      +                                   StructuredList, StructuredIndex,
      +                                   SubInitList->getSourceRange());
      +    CheckExplicitInitList(SubInitList, ElemType, newIndex, 
      +                          newStructuredList, newStructuredIndex);
      +    ++StructuredIndex;
      +    ++Index;
         } else if (StringLiteral *lit =
                    SemaRef->IsStringLiteralInit(expr, ElemType)) {
           SemaRef->CheckStringLiteralInit(lit, ElemType);
      -    Index++;
      +    UpdateStructuredListElement(StructuredList, StructuredIndex, lit);
      +    ++Index;
         } else if (ElemType->isScalarType()) {
      -    CheckScalarType(IList, ElemType, expr, Index);
      +    CheckScalarType(IList, ElemType, expr, Index, StructuredList, 
      +                    StructuredIndex);
         } else if (expr->getType()->getAsRecordType() &&
                    SemaRef->Context.typesAreCompatible(
                      expr->getType().getUnqualifiedType(),
                      ElemType.getUnqualifiedType())) {
      -    Index++;
      +    UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
      +    ++Index;
           // FIXME: Add checking
         } else {
      -    CheckImplicitInitList(IList, ElemType, Index);
      -    Index++;
      -  }
      +    CheckImplicitInitList(IList, ElemType, Index, StructuredList, 
      +                          StructuredIndex);
      +    ++StructuredIndex;
      + }
       }
       
       void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
      -                                      Expr *expr, unsigned &Index) {
      +                                      Expr *expr, unsigned &Index,
      +                                      InitListExpr *StructuredList,
      +                                      unsigned &StructuredIndex) {
         if (Index < IList->getNumInits()) {
           if (!expr)
             expr = IList->getInit(Index);
      @@ -199,6 +271,7 @@ void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
               << IList->getSourceRange();
             hadError = true;
             ++Index;
      +      ++StructuredIndex;
             return;
           } else if (isa(expr)) {
             SemaRef->Diag(expr->getSourceRange().getBegin(), 
      @@ -206,6 +279,7 @@ void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
               << DeclType << expr->getSourceRange();
             hadError = true;
             ++Index;
      +      ++StructuredIndex;
             return;
           }
       
      @@ -219,18 +293,27 @@ void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
               DIE->setInit(expr);
             else
               IList->setInit(Index, expr);
      +
           }
      +    if (hadError)
      +      ++StructuredIndex;
      +    else
      +      UpdateStructuredListElement(StructuredList, StructuredIndex, expr);
           ++Index;
         } else {
           SemaRef->Diag(IList->getLocStart(), diag::err_empty_scalar_initializer)
             << IList->getSourceRange();
           hadError = true;
      +    ++Index;
      +    ++StructuredIndex;
           return;
         }
       }
       
       void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType, 
      -                                      unsigned &Index) {
      +                                      unsigned &Index,
      +                                      InitListExpr *StructuredList,
      +                                      unsigned &StructuredIndex) {
         if (Index < IList->getNumInits()) {
           const VectorType *VT = DeclType->getAsVectorType();
           int maxElements = VT->getNumElements();
      @@ -240,7 +323,8 @@ void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
             // Don't attempt to go past the end of the init list
             if (Index >= IList->getNumInits())
               break;
      -      CheckSubElementType(IList, elementType, IList->getInit(Index), Index);
      +      CheckSubElementType(IList, elementType, IList->getInit(Index), Index,
      +                          StructuredList, StructuredIndex);
           }
         }
       }
      @@ -248,12 +332,21 @@ void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
       void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType, 
                                            llvm::APSInt elementIndex,
                                            bool SubobjectIsDesignatorContext, 
      -                                     unsigned &Index) {
      +                                     unsigned &Index,
      +                                     InitListExpr *StructuredList,
      +                                     unsigned &StructuredIndex) {
         // Check for the special-case of initializing an array with a string.
         if (Index < IList->getNumInits()) {
           if (StringLiteral *lit = 
               SemaRef->IsStringLiteralInit(IList->getInit(Index), DeclType)) {
             SemaRef->CheckStringLiteralInit(lit, DeclType);
      +      // We place the string literal directly into the resulting
      +      // initializer list. This is the only place where the structure
      +      // of the structured initializer list doesn't match exactly,
      +      // because doing so would involve allocating one character
      +      // constant for each string.
      +      UpdateStructuredListElement(StructuredList, StructuredIndex, lit);
      +      StructuredList->resizeInits(SemaRef->Context, StructuredIndex);
             ++Index;
             return;
           }
      @@ -267,11 +360,14 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
                         diag::err_variable_object_no_init)
             << VAT->getSizeExpr()->getSourceRange();
           hadError = true;
      +    ++Index;
      +    ++StructuredIndex;
           return;
         }
       
         // We might know the maximum number of elements in advance.
      -  llvm::APSInt maxElements(elementIndex.getBitWidth(), elementIndex.isUnsigned());
      +  llvm::APSInt maxElements(elementIndex.getBitWidth(),
      +                           elementIndex.isUnsigned());
         bool maxElementsKnown = false;
         if (const ConstantArrayType *CAT =
               SemaRef->Context.getAsConstantArrayType(DeclType)) {
      @@ -295,7 +391,8 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
             // Handle this designated initializer. elementIndex will be
             // updated to be the next array element we'll initialize.
             if (CheckDesignatedInitializer(IList, DIE, DIE->designators_begin(), 
      -                                     DeclType, 0, &elementIndex, Index)) {
      +                                     DeclType, 0, &elementIndex, Index,
      +                                     StructuredList, StructuredIndex)) {
               hadError = true;
               continue;
             }
      @@ -320,7 +417,8 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
             break;
       
           // Check this element.
      -    CheckSubElementType(IList, elementType, IList->getInit(Index), Index);
      +    CheckSubElementType(IList, elementType, IList->getInit(Index), Index,
      +                        StructuredList, StructuredIndex);
           ++elementIndex;
       
           // If the array is of incomplete type, keep track of the number of
      @@ -348,7 +446,9 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
                                                   QualType DeclType, 
                                                   RecordDecl::field_iterator Field,
                                                   bool SubobjectIsDesignatorContext, 
      -                                            unsigned &Index) {
      +                                            unsigned &Index,
      +                                            InitListExpr *StructuredList,
      +                                            unsigned &StructuredIndex) {
         RecordDecl* structDecl = DeclType->getAsRecordType()->getDecl();
           
         // If the record is invalid, some of it's members are invalid. To avoid
      @@ -376,7 +476,8 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
             // Handle this designated initializer. Field will be updated to
             // the next field that we'll be initializing.
             if (CheckDesignatedInitializer(IList, DIE, DIE->designators_begin(), 
      -                                     DeclType, &Field, 0, Index))
      +                                     DeclType, &Field, 0, Index,
      +                                     StructuredList, StructuredIndex))
               hadError = true;
       
             continue;
      @@ -391,13 +492,14 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
           if (Field->getType()->isIncompleteArrayType())
             break;
       
      -    if (!Field->getIdentifier()) {
      -      // Don't initialize unnamed fields, e.g. "int : 20;"
      +    if (!Field->getIdentifier() && Field->isBitField()) {
      +      // Don't initialize unnamed bitfields, e.g. "int : 20;"
             ++Field;
             continue;
           }
       
      -    CheckSubElementType(IList, Field->getType(), IList->getInit(Index), Index);
      +    CheckSubElementType(IList, Field->getType(), IList->getInit(Index), Index,
      +                        StructuredList, StructuredIndex);
           if (DeclType->isUnionType()) // FIXME: designated initializers?
             break;
       
      @@ -416,8 +518,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
       /// IList, is well-formed for a current object of type @p DeclType
       /// (C99 6.7.8). The actual subobject that this designator refers to
       /// within the current subobject is returned in either 
      -/// @p DesignatedField or @p DesignatedIndex (whichever is
      -/// appropriate).
      +/// @p NextField or @p NextElementIndex (whichever is appropriate).
       ///
       /// @param IList  The initializer list in which this designated
       /// initializer occurs.
      @@ -439,6 +540,10 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
       /// @param Index  Index into @p IList where the designated initializer
       /// @p DIE occurs.
       ///
      +/// @param StructuredList  The initializer list expression that
      +/// describes all of the subobject initializers in the order they'll
      +/// actually be initialized.
      +///
       /// @returns true if there was an error, false otherwise.
       bool 
       InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
      @@ -447,16 +552,30 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
                                             QualType &CurrentObjectType,
                                             RecordDecl::field_iterator *NextField,
                                             llvm::APSInt *NextElementIndex,
      -                                      unsigned &Index) {
      -  bool IsFirstDesignator = (D == DIE->designators_begin());
      -
      +                                      unsigned &Index,
      +                                      InitListExpr *StructuredList,
      +                                      unsigned &StructuredIndex) {
         if (D == DIE->designators_end()) {
           // Check the actual initialization for the designated object type.
           bool prevHadError = hadError;
      -    CheckSubElementType(IList, CurrentObjectType, DIE->getInit(), Index);
      +    CheckSubElementType(IList, CurrentObjectType, DIE->getInit(), Index,
      +                        StructuredList, StructuredIndex);
           return hadError && !prevHadError;
         }
       
      +  bool IsFirstDesignator = (D == DIE->designators_begin());
      +  assert((IsFirstDesignator || StructuredList) && 
      +         "Need a non-designated initializer list to start from");
      +
      +  // Determine the structural initializer list that corresponds to the
      +  // current subobject.
      +  StructuredList = IsFirstDesignator? SyntacticToSemantic[IList]
      +    : getStructuredSubobjectInit(IList, Index, CurrentObjectType, StructuredList,
      +                                 StructuredIndex,
      +                                 SourceRange(D->getStartLocation(),
      +                                             DIE->getSourceRange().getEnd()));
      +  assert(StructuredList && "Expected a structured initializer list");
      +
         if (D->isFieldDesignator()) {
           // C99 6.7.8p7:
           //
      @@ -478,56 +597,95 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
             return true;
           }
       
      +    // Note: we perform a linear search of the fields here, despite
      +    // the fact that we have a faster lookup method, because we always
      +    // need to compute the field's index.
           IdentifierInfo *FieldName = D->getFieldName();
      -    DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
      -    FieldDecl *DesignatedField = 0;
      -    if (Lookup.first == Lookup.second) {
      -      // Lookup did not find anything with this name.
      -      SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
      -        << FieldName << CurrentObjectType;
      -    } else if (isa(*Lookup.first)) {
      -      // Name lookup found a field.
      -      DesignatedField = cast(*Lookup.first);
      -      // FIXME: Make sure this isn't a field in an anonymous
      -      // struct/union.
      -    } else {
      -      // Name lookup found something, but it wasn't a field.
      -      SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
      -        << FieldName;
      -      SemaRef->Diag((*Lookup.first)->getLocation(), 
      -                    diag::note_field_designator_found);
      +    unsigned FieldIndex = 0;
      +    RecordDecl::field_iterator Field = RT->getDecl()->field_begin(),
      +                            FieldEnd = RT->getDecl()->field_end();
      +    for (; Field != FieldEnd; ++Field) {
      +      if (Field->isUnnamedBitfield())
      +        continue;
      +
      +      if (Field->getIdentifier() == FieldName)
      +        break;
      +
      +      ++FieldIndex;
           }
       
      -    if (!DesignatedField) {
      +    if (Field == FieldEnd) {
      +      // We did not find the field we're looking for. Produce a
      +      // suitable diagnostic and return a failure.
      +      DeclContext::lookup_result Lookup = RT->getDecl()->lookup(FieldName);
      +      if (Lookup.first == Lookup.second) {
      +        // Name lookup didn't find anything.
      +        SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_unknown)
      +          << FieldName << CurrentObjectType;
      +      } else {
      +        // Name lookup found something, but it wasn't a field.
      +        SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_nonfield)
      +          << FieldName;
      +        SemaRef->Diag((*Lookup.first)->getLocation(), 
      +                      diag::note_field_designator_found);
      +      }
      +
      +      ++Index;
      +      return true;
      +    } else if (cast((*Field)->getDeclContext())
      +                 ->isAnonymousStructOrUnion()) {
      +      SemaRef->Diag(D->getFieldLoc(), diag::err_field_designator_anon_class)
      +        << FieldName
      +        << (cast((*Field)->getDeclContext())->isUnion()? 2 : 
      +            (int)SemaRef->getLangOptions().CPlusPlus);
      +      SemaRef->Diag((*Field)->getLocation(), diag::note_field_designator_found);
             ++Index;
             return true;
           }
      -        
      +
      +    // All of the fields of a union are located at the same place in
      +    // the initializer list.
      +    // FIXME: Need to tell CodeGen which type to initialize to. ImplicitCastExpr?
      +    if (RT->getDecl()->isUnion() && FieldIndex != 0) {
      +      SemaRef->Diag(D->getStartLocation(), 
      +                    diag::warn_designator_into_union_broken_init)
      +        << SourceRange(D->getStartLocation(), DIE->getSourceRange().getEnd());
      +      FieldIndex = 0;
      +    }
      +
           // Update the designator with the field declaration.
      -    D->setField(DesignatedField);
      +    D->setField(*Field);
             
      +    // Make sure that our non-designated initializer list has space
      +    // for a subobject corresponding to this field.
      +    if (FieldIndex >= StructuredList->getNumInits())
      +      StructuredList->resizeInits(SemaRef->Context, FieldIndex + 1);
      +
           // Recurse to check later designated subobjects.
      -    QualType FieldType = DesignatedField->getType();
      -    if (CheckDesignatedInitializer(IList, DIE, ++D, FieldType, 0, 0, Index))
      +    QualType FieldType = (*Field)->getType();
      +    unsigned newStructuredIndex = FieldIndex;
      +    if (CheckDesignatedInitializer(IList, DIE, ++D, FieldType, 0, 0, Index,
      +                                   StructuredList, newStructuredIndex))
             return true;
       
           // Find the position of the next field to be initialized in this
           // subobject.
      -    RecordDecl::field_iterator Field(DeclContext::decl_iterator(DesignatedField),
      -                                     RT->getDecl()->decls_end());
           ++Field;
      +    ++FieldIndex;
       
           // If this the first designator, our caller will continue checking
           // the rest of this struct/class/union subobject.
           if (IsFirstDesignator) {
             if (NextField)
               *NextField = Field;
      +      StructuredIndex = FieldIndex;
             return false;
           }
       
           // Check the remaining fields within this class/struct/union subobject.
           bool prevHadError = hadError;
      -    CheckStructUnionTypes(IList, CurrentObjectType, Field, false, Index);
      +    CheckStructUnionTypes(IList, CurrentObjectType, Field, false, Index,
      +                          StructuredList, FieldIndex);
           return hadError && !prevHadError;
         }
       
      @@ -561,6 +719,9 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
         else {
           assert(D->isArrayRangeDesignator() && "Need array-range designator");
           IndexExpr = DIE->getArrayRangeEnd(*D);
      +    SemaRef->Diag(D->getEllipsisLoc(), 
      +                  diag::warn_gnu_array_range_designator_unsupported)
      +      << SourceRange(D->getLBracketLoc(), D->getRBracketLoc());
         }
       
         bool ConstExpr 
      @@ -581,28 +742,115 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
           }
         }
         
      +  // Make sure that our non-designated initializer list has space
      +  // for a subobject corresponding to this array element.
      +  unsigned ElementIndex = DesignatedIndex.getZExtValue();
      +  if (ElementIndex >= StructuredList->getNumInits())
      +    StructuredList->resizeInits(SemaRef->Context, ElementIndex + 1);
      +
         // Recurse to check later designated subobjects.
         QualType ElementType = AT->getElementType();
      -  if (CheckDesignatedInitializer(IList, DIE, ++D, ElementType, 0, 0, Index))
      +  if (CheckDesignatedInitializer(IList, DIE, ++D, ElementType, 0, 0, Index,
      +                                 StructuredList, ElementIndex))
           return true;
       
         // Move to the next index in the array that we'll be initializing.
         ++DesignatedIndex;
      +  ElementIndex = DesignatedIndex.getZExtValue();
       
         // If this the first designator, our caller will continue checking
         // the rest of this array subobject.
         if (IsFirstDesignator) {
           if (NextElementIndex)
             *NextElementIndex = DesignatedIndex;
      +    StructuredIndex = ElementIndex;
           return false;
         }
           
         // Check the remaining elements within this array subobject.
         bool prevHadError = hadError;
      -  CheckArrayType(IList, CurrentObjectType, DesignatedIndex, true, Index);
      +  CheckArrayType(IList, CurrentObjectType, DesignatedIndex, true, Index,
      +                 StructuredList, ElementIndex);
         return hadError && !prevHadError;  
       }
       
      +// Get the structured initializer list for a subobject of type
      +// @p CurrentObjectType.
      +InitListExpr *
      +InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
      +                                            QualType CurrentObjectType,
      +                                            InitListExpr *StructuredList,
      +                                            unsigned StructuredIndex,
      +                                            SourceRange InitRange) {
      +  Expr *ExistingInit = 0;
      +  if (!StructuredList)
      +    ExistingInit = SyntacticToSemantic[IList];
      +  else if (StructuredIndex < StructuredList->getNumInits())
      +    ExistingInit = StructuredList->getInit(StructuredIndex);
      +  
      +  if (InitListExpr *Result = dyn_cast_or_null(ExistingInit))
      +    return Result;
      +
      +  if (ExistingInit) {
      +    // We are creating an initializer list that initializes the
      +    // subobjects of the current object, but there was already an
      +    // initialization that completely initialized the current
      +    // subobject, e.g., by a compound literal:
      +    // 
      +    // struct X { int a, b; };
      +    // struct X xs[] = { [0] = (struct X) { 1, 2 }, [0].b = 3 };
      +    // 
      +    // Here, xs[0].a == 0 and xs[0].b == 3, since the second,
      +    // designated initializer re-initializes the whole
      +    // subobject [0], overwriting previous initializers.
      +    SemaRef->Diag(InitRange.getBegin(), diag::warn_subobject_initializer_overrides)
      +      << InitRange;
      +    SemaRef->Diag(ExistingInit->getSourceRange().getBegin(), 
      +                  diag::note_previous_initializer)
      +      << ExistingInit->hasSideEffects(SemaRef->Context)
      +      << ExistingInit->getSourceRange();
      +  }
      +
      +  InitListExpr *Result 
      +    = new (SemaRef->Context) InitListExpr(SourceLocation(), 0, 0, 
      +                                          SourceLocation());
      +  Result->setType(CurrentObjectType);
      +
      +  // Link this new initializer list into the structured initializer
      +  // lists.
      +  if (StructuredList)
      +    StructuredList->updateInit(StructuredIndex, Result);
      +  else {
      +    Result->setSyntacticForm(IList);
      +    SyntacticToSemantic[IList] = Result;
      +  }
      +
      +  return Result;
      +}
      +
      +/// Update the initializer at index @p StructuredIndex within the
      +/// structured initializer list to the value @p expr.
      +void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
      +                                                  unsigned &StructuredIndex,
      +                                                  Expr *expr) {
      +  // No structured initializer list to update
      +  if (!StructuredList)
      +    return;
      +
      +  if (Expr *PrevInit = StructuredList->updateInit(StructuredIndex, expr)) {
      +    // This initializer overwrites a previous initializer. Warn.
      +    SemaRef->Diag(expr->getSourceRange().getBegin(), 
      +                  diag::warn_initializer_overrides)
      +      << expr->getSourceRange();
      +    SemaRef->Diag(PrevInit->getSourceRange().getBegin(), 
      +                  diag::note_previous_initializer)
      +      << (int)PrevInit->hasSideEffects(SemaRef->Context)
      +      << PrevInit->getSourceRange();
      +  }
      +  
      +  ++StructuredIndex;
      +}
      +
       /// Check that the given Index expression is a valid array designator
       /// value. This is essentailly just a wrapper around
       /// Expr::isIntegerConstantExpr that also checks for negative values
      diff --git a/clang/test/Sema/array-init.c b/clang/test/Sema/array-init.c
      index 9d2a942410ae..3d2cf6912744 100644
      --- a/clang/test/Sema/array-init.c
      +++ b/clang/test/Sema/array-init.c
      @@ -1,4 +1,4 @@
      -// RUN: clang -fsyntax-only -verify -pedantic %s
      +// RUN: clang -fsyntax-only -pedantic -verify %s
       
       extern int foof() = 1; // expected-error{{illegal initializer (only variables can be initialized)}}
       
      @@ -101,6 +101,7 @@ void legal() {
           { 2, 3 },
           { 4, 5, 6 }
         };
      +  int q_sizecheck[(sizeof(q) / sizeof(short [3][2])) == 3? 1 : -1];
       }
       
       unsigned char asso_values[] = { 34 };
      @@ -134,15 +135,19 @@ typedef int AryT[];
       void testTypedef()
       {
         AryT a = { 1, 2 }, b = { 3, 4, 5 };
      +  int a_sizecheck[(sizeof(a) / sizeof(int)) == 2? 1 : -1];
      +  int b_sizecheck[(sizeof(b) / sizeof(int)) == 3? 1 : -1];
       }
       
       static char const xx[] = "test";
      +int xx_sizecheck[(sizeof(xx) / sizeof(char)) == 5? 1 : -1];
       static char const yy[5] = "test";
       static char const zz[3] = "test"; // expected-warning{{initializer-string for char array is too long}}
       
       void charArrays()
       {
       	static char const test[] = "test";
      +        int test_sizecheck[(sizeof(test) / sizeof(char)) == 5? 1 : -1];
       	static char const test2[] = { "weird stuff" };
       	static char const test3[] = { "test", "excess stuff" }; // expected-error{{excess elements in char array initializer}}
       
      @@ -171,6 +176,7 @@ void variableArrayInit() {
       float r1[10] = {{7}}; //expected-warning{{braces around scalar initializer}}
       float r2[] = {{8}}; //expected-warning{{braces around scalar initializer}}
       char r3[][5] = {1,2,3,4,5,6};
      +int r3_sizecheck[(sizeof(r3) / sizeof(char[5])) == 2? 1 : -1];
       char r3_2[sizeof r3 == 10 ? 1 : -1];
       float r4[1][2] = {1,{2},3,4}; //expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}}
       char r5[][5] = {"aa", "bbb", "ccccc"};
      @@ -195,7 +201,7 @@ int bar (void) {
         return z.z; 
       } 
       struct s3 {void (*a)(void);} t5 = {autoStructTest};
      -// GCC extension; flexible array init. Once this is implemented, the warning should be removed.
      +// FIXME: GCC extension; flexible array init. Once this is implemented, the warning should be removed.
       // Note that clang objc implementation depends on this extension.
       struct {int a; int b[];} t6 = {1, {1, 2, 3}}; //expected-warning{{excess elements in array initializer}}
       union {char a; int b;} t7[] = {1, 2, 3};
      @@ -238,3 +244,21 @@ struct soft_segment_descriptor gdt_segs[] = {
       
       static void sppp_ipv6cp_up();
       const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-warning{{excess elements in array initializer}}
      +
      +struct _Matrix { union { float m[4][4]; }; }; //expected-warning{{anonymous unions are a GNU extension in C}}
      +typedef struct _Matrix Matrix;
      +void test_matrix() {
      +  const Matrix mat1 = {
      +    { { 1.0f, 2.0f, 3.0f, 4.0f,
      +        5.0f, 6.0f, 7.0f, 8.0f,
      +        9.0f, 10.0f, 11.0f, 12.0f,
      +        13.0f, 14.0f, 15.0f, 16.0f } }
      +  };
      +
      +  const Matrix mat2 = {
      +    1.0f, 2.0f, 3.0f, 4.0f,
      +    5.0f, 6.0f, 7.0f, 8.0f,
      +    9.0f, 10.0f, 11.0f, 12.0f,
      +    13.0f, 14.0f, 15.0f, 16.0f 
      +  };
      +}
      diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c
      index fd4873193cfd..c9a0aa7f05bd 100644
      --- a/clang/test/Sema/designated-initializers.c
      +++ b/clang/test/Sema/designated-initializers.c
      @@ -18,7 +18,8 @@ int iarray2[10] = {
       };
       
       int iarray3[10] = {
      -  [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}
      +  [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}\
      +                // expected-warning{{GNU array-range designator extension is unsupported}}
       };
       
       struct point {
      @@ -44,8 +45,8 @@ struct point array[10] = {
       
       struct point array2[10] = {
         [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
      -  [4 ... 5].y = 2.0,
      -  [4 ... 6] = { .x = 3, .y = 4.0 }
      +  [4 ... 5].y = 2.0, // expected-warning{{GNU array-range designator extension is unsupported}}
      +  [4 ... 6] = { .x = 3, .y = 4.0 } // expected-warning{{GNU array-range designator extension is unsupported}}
       };
       
       struct point array3[10] = {
      @@ -116,4 +117,25 @@ struct disklabel_ops disklabel64_ops = {
       // PR clang/3378
       int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 };
       int a[]= { [sizeof(int)] = 0 };
      -int a2[]= { [0 ... sizeof(int)] = 0 };
      +int a2[]= { [0 ... sizeof(int)] = 0 }; // expected-warning{{GNU array-range designator extension is unsupported}}
      +
      +// Test warnings about initializers overriding previous initializers
      +struct X {
      +  int a, b, c;
      +};
      +
      +int counter = 0;
      +int get8() { ++counter; return 8; }
      +
      +void test() {
      +  struct X xs[] = { 
      +    [0] = (struct X){1, 2}, // expected-note{{previous initialization is here}}
      +    [0].c = 3,  // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}
      +    (struct X) {4, 5, 6}, // expected-note{{previous initialization is here}}
      +    [1].b = get8(), // expected-warning{{subobject initialization overrides initialization of other fields within its enclosing subobject}}
      +    [0].b = 8
      +  };
      +}
      +
      +// FIXME: we need to 
      +union { char c; long l; } u1 = { .l = 0xFFFF }; // expected-warning{{designated initialization of union member is broken}}
      diff --git a/clang/test/Sema/vector-init.c b/clang/test/Sema/vector-init.c
      index 1e2ba012c8f2..6913082228ca 100644
      --- a/clang/test/Sema/vector-init.c
      +++ b/clang/test/Sema/vector-init.c
      @@ -1,5 +1,15 @@
      -// RUN: clang %s -verify -fsyntax-only
      +// RUN: clang %s -fsyntax-only -verify
       
       typedef __attribute__(( ext_vector_type(4) ))  float float4;
      +//typedef float float4 __attribute__((vector_size(16)));
       
       float4 foo = (float4){ 1.0, 2.0, 3.0, 4.0 };
      +
      +float4 array[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0};
      +int array_sizecheck[(sizeof(array) / sizeof(float4)) == 3? 1 : -1];
      +
      +float4 array2[2] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 
      +                     9.0 }; // expected-warning {{excess elements in array initializer}}
      +
      +float4 array3[2] = { {1.0, 2.0, 3.0}, 5.0, 6.0, 7.0, 8.0,
      +                     9.0 }; // expected-warning {{excess elements in array initializer}}
      -- 
      GitLab
      
      
      From 5997644550470f5a5fc25b082ea16b12459595b5 Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Wed, 28 Jan 2009 22:11:38 +0000
      Subject: [PATCH 381/682] Add some comments to GRStateManager.  No
       functionality change.
      
      llvm-svn: 63243
      ---
       .../clang/Analysis/PathSensitive/GRState.h    | 52 +++++++++++++++++++
       1 file changed, 52 insertions(+)
      
      diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h
      index 74cd01f51577..45ad702346c4 100644
      --- a/clang/include/clang/Analysis/PathSensitive/GRState.h
      +++ b/clang/include/clang/Analysis/PathSensitive/GRState.h
      @@ -492,6 +492,25 @@ public:
         bool isEqual(const GRState* state, Expr* Ex, const llvm::APSInt& V);
         bool isEqual(const GRState* state, Expr* Ex, uint64_t);
         
      +  
      +  //==---------------------------------------------------------------------==//
      +  // Generic Data Map methods.
      +  //==---------------------------------------------------------------------==//
      +  //
      +  // GRStateManager and GRState support a "generic data map" that allows
      +  // different clients of GRState objects to embed arbitrary data within a
      +  // GRState object.  The generic data map is essentially an immutable map
      +  // from a "tag" (that acts as the "key" for a client) and opaque values.
      +  // Tags/keys and values are simply void* values.  The typical way that clients
      +  // generate unique tags are by taking the address of a static variable.
      +  // Clients are responsible for ensuring that data values referred to by a
      +  // the data pointer are immutable (and thus are essentially purely functional
      +  // data).
      +  //
      +  // The templated methods below use the GRStateTrait class
      +  // to resolve keys into the GDM and to return data values to clients.
      +  //
      +  
         // Trait based GDM dispatch.  
         template 
         const GRState* set(const GRState* st, typename GRStateTrait::data_type D) {
      @@ -539,6 +558,39 @@ public:
           
           return GRStateTrait::MakeContext(p);
         }
      +  
      +  //==---------------------------------------------------------------------==//
      +  // Constraints on values.
      +  //==---------------------------------------------------------------------==//
      +  //
      +  // Each GRState records constraints on symbolic values.  These constraints
      +  // are managed using the ConstraintManager associated with a GRStateManager.
      +  // As constraints gradually accrue on symbolic values, added constraints
      +  // may conflict and indicate that a state is infeasible (as no real values
      +  // could satisfy all the constraints).  This is the principal mechanism
      +  // for modeling path-sensitivity in GRExprEngine/GRState.
      +  //
      +  // Various "Assume" methods form the interface for adding constraints to
      +  // symbolic values.  A call to "Assume" indicates an assumption being placed
      +  // on one or symbolic values.  Assume methods take the following inputs:
      +  //
      +  //  (1) A GRState object representing the current state.
      +  //
      +  //  (2) The assumed constraint (which is specific to a given "Assume" method).
      +  //
      +  //  (3) A binary value "Assumption" that indicates whether the constraint is
      +  //      assumed to be true or false.
      +  //
      +  // The output of "Assume" are two values:
      +  //
      +  //  (a) "isFeasible" is set to true or false to indicate whether or not
      +  //      the assumption is feasible.
      +  //
      +  //  (b) A new GRState object with the added constraints.
      +  //
      +  // FIXME: (a) should probably disappear since it is redundant with (b).
      +  //  (i.e., (b) could just be set to NULL).
      +  //
       
         const GRState* Assume(const GRState* St, SVal Cond, bool Assumption,
                                  bool& isFeasible) {
      -- 
      GitLab
      
      
      From d21775ae0e9c24962e4a817caf88d921f2f2beaf Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Wed, 28 Jan 2009 22:14:58 +0000
      Subject: [PATCH 382/682] Give this test an explicit target, to make it
       host-independent.
      
      llvm-svn: 63244
      ---
       llvm/test/DebugInfo/2009-01-28-ArrayType.ll | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/llvm/test/DebugInfo/2009-01-28-ArrayType.ll b/llvm/test/DebugInfo/2009-01-28-ArrayType.ll
      index 9f90c33e5e88..cff4fd8a4732 100644
      --- a/llvm/test/DebugInfo/2009-01-28-ArrayType.ll
      +++ b/llvm/test/DebugInfo/2009-01-28-ArrayType.ll
      @@ -1,4 +1,4 @@
      -; RUN: llvm-as < %s | llc | grep 0x49 | count 7
      +; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin | grep 0x49 | count 7
       ; Count number of DW_AT_Type attributes.
       	%llvm.dbg.anchor.type = type { i32, i32 }
       	%llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* }
      -- 
      GitLab
      
      
      From 1b6a3bce82eaf5f17a22c95b5593d04c4279503f Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Wed, 28 Jan 2009 22:17:52 +0000
      Subject: [PATCH 383/682] Add DebugLoc to the getNode() methods.
      
      llvm-svn: 63245
      ---
       llvm/include/llvm/CodeGen/SelectionDAG.h      |  53 +++++-
       .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 175 ++++++++++++++----
       2 files changed, 177 insertions(+), 51 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
      index c04436be277b..739f4d9459d2 100644
      --- a/llvm/include/llvm/CodeGen/SelectionDAG.h
      +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
      @@ -394,35 +394,68 @@ public:
         /// getNode - Gets or creates the specified node.
         ///
         SDValue getNode(unsigned Opcode, MVT VT);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT);
         SDValue getNode(unsigned Opcode, MVT VT, SDValue N);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue N);
         SDValue getNode(unsigned Opcode, MVT VT, SDValue N1, SDValue N2);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue N1, SDValue N2);
         SDValue getNode(unsigned Opcode, MVT VT,
      -                    SDValue N1, SDValue N2, SDValue N3);
      +                  SDValue N1, SDValue N2, SDValue N3);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                  SDValue N1, SDValue N2, SDValue N3);
         SDValue getNode(unsigned Opcode, MVT VT,
      -                    SDValue N1, SDValue N2, SDValue N3, SDValue N4);
      +                  SDValue N1, SDValue N2, SDValue N3, SDValue N4);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                  SDValue N1, SDValue N2, SDValue N3, SDValue N4);
         SDValue getNode(unsigned Opcode, MVT VT,
      -                    SDValue N1, SDValue N2, SDValue N3, SDValue N4,
      -                    SDValue N5);
      +                  SDValue N1, SDValue N2, SDValue N3, SDValue N4,
      +                  SDValue N5);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                  SDValue N1, SDValue N2, SDValue N3, SDValue N4,
      +                  SDValue N5);
         SDValue getNode(unsigned Opcode, MVT VT,
      -                    const SDValue *Ops, unsigned NumOps);
      +                  const SDUse *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                  const SDUse *Ops, unsigned NumOps);
         SDValue getNode(unsigned Opcode, MVT VT,
      -                    const SDUse *Ops, unsigned NumOps);
      +                  const SDValue *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                  const SDValue *Ops, unsigned NumOps);
         SDValue getNode(unsigned Opcode, const std::vector &ResultTys,
      -                    const SDValue *Ops, unsigned NumOps);
      +                  const SDValue *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL,
      +                  const std::vector &ResultTys,
      +                  const SDValue *Ops, unsigned NumOps);
         SDValue getNode(unsigned Opcode, const MVT *VTs, unsigned NumVTs,
      -                    const SDValue *Ops, unsigned NumOps);
      +                  const SDValue *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, const MVT *VTs, unsigned NumVTs,
      +                  const SDValue *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, SDVTList VTs,
      +                  const SDValue *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
      +                  const SDValue *Ops, unsigned NumOps);
      +
         SDValue getNode(unsigned Opcode, SDVTList VTs);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs);
         SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs, SDValue N);
         SDValue getNode(unsigned Opcode, SDVTList VTs, SDValue N1, SDValue N2);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
      +                  SDValue N1, SDValue N2);
         SDValue getNode(unsigned Opcode, SDVTList VTs,
                         SDValue N1, SDValue N2, SDValue N3);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
      +                  SDValue N1, SDValue N2, SDValue N3);
         SDValue getNode(unsigned Opcode, SDVTList VTs,
                         SDValue N1, SDValue N2, SDValue N3, SDValue N4);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
      +                  SDValue N1, SDValue N2, SDValue N3, SDValue N4);
         SDValue getNode(unsigned Opcode, SDVTList VTs,
                         SDValue N1, SDValue N2, SDValue N3, SDValue N4,
                         SDValue N5);
      -  SDValue getNode(unsigned Opcode, SDVTList VTs,
      -                  const SDValue *Ops, unsigned NumOps);
      +  SDValue getNode(unsigned Opcode, DebugLoc DL, SDVTList VTs,
      +                  SDValue N1, SDValue N2, SDValue N3, SDValue N4,
      +                  SDValue N5);
       
         SDValue getMemcpy(SDValue Chain, SDValue Dst, SDValue Src,
                           SDValue Size, unsigned Align, bool AlwaysInline,
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      index 49d4975d1276..a124ebf14f8d 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      @@ -2102,13 +2102,17 @@ SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) {
       /// getNode - Gets or creates the specified node.
       ///
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT) {
         FoldingSetNodeID ID;
         AddNodeIDNode(ID, Opcode, getVTList(VT), 0, 0);
         void *IP = 0;
         if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
           return SDValue(E, 0);
         SDNode *N = NodeAllocator.Allocate();
      -  new (N) SDNode(Opcode, SDNode::getSDVTList(VT));
      +  new (N) SDNode(Opcode, DL, SDNode::getSDVTList(VT));
         CSEMap.InsertNode(N, IP);
         
         AllNodes.push_back(N);
      @@ -2119,6 +2123,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT) {
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, Operand);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
      +                              MVT VT, SDValue Operand) {
         // Constant fold unary operations with an integer constant operand.
         if (ConstantSDNode *C = dyn_cast(Operand.getNode())) {
           const APInt &Val = C->getAPIntValue();
      @@ -2310,11 +2319,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT, SDValue Operand) {
           if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
             return SDValue(E, 0);
           N = NodeAllocator.Allocate();
      -    new (N) UnarySDNode(Opcode, VTs, Operand);
      +    new (N) UnarySDNode(Opcode, DL, VTs, Operand);
           CSEMap.InsertNode(N, IP);
         } else {
           N = NodeAllocator.Allocate();
      -    new (N) UnarySDNode(Opcode, VTs, Operand);
      +    new (N) UnarySDNode(Opcode, DL, VTs, Operand);
         }
       
         AllNodes.push_back(N);
      @@ -2362,6 +2371,11 @@ SDValue SelectionDAG::FoldConstantArithmetic(unsigned Opcode,
       
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
                                     SDValue N1, SDValue N2) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                              SDValue N1, SDValue N2) {
         ConstantSDNode *N1C = dyn_cast(N1.getNode());
         ConstantSDNode *N2C = dyn_cast(N2.getNode());
         switch (Opcode) {
      @@ -2705,11 +2719,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
           if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
             return SDValue(E, 0);
           N = NodeAllocator.Allocate();
      -    new (N) BinarySDNode(Opcode, VTs, N1, N2);
      +    new (N) BinarySDNode(Opcode, DL, VTs, N1, N2);
           CSEMap.InsertNode(N, IP);
         } else {
           N = NodeAllocator.Allocate();
      -    new (N) BinarySDNode(Opcode, VTs, N1, N2);
      +    new (N) BinarySDNode(Opcode, DL, VTs, N1, N2);
         }
       
         AllNodes.push_back(N);
      @@ -2721,6 +2735,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
       
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
                                     SDValue N1, SDValue N2, SDValue N3) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2, N3);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                              SDValue N1, SDValue N2, SDValue N3) {
         // Perform various simplifications.
         ConstantSDNode *N1C = dyn_cast(N1.getNode());
         ConstantSDNode *N2C = dyn_cast(N2.getNode());
      @@ -2787,11 +2806,11 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
           if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
             return SDValue(E, 0);
           N = NodeAllocator.Allocate();
      -    new (N) TernarySDNode(Opcode, VTs, N1, N2, N3);
      +    new (N) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
           CSEMap.InsertNode(N, IP);
         } else {
           N = NodeAllocator.Allocate();
      -    new (N) TernarySDNode(Opcode, VTs, N1, N2, N3);
      +    new (N) TernarySDNode(Opcode, DL, VTs, N1, N2, N3);
         }
         AllNodes.push_back(N);
       #ifndef NDEBUG
      @@ -2803,15 +2822,27 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
                                     SDValue N1, SDValue N2, SDValue N3,
                                     SDValue N4) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2, N3, N4);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                              SDValue N1, SDValue N2, SDValue N3,
      +                              SDValue N4) {
         SDValue Ops[] = { N1, N2, N3, N4 };
      -  return getNode(Opcode, VT, Ops, 4);
      +  return getNode(Opcode, DL, VT, Ops, 4);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
                                     SDValue N1, SDValue N2, SDValue N3,
                                     SDValue N4, SDValue N5) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, N1, N2, N3, N4, N5);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                              SDValue N1, SDValue N2, SDValue N3,
      +                              SDValue N4, SDValue N5) {
         SDValue Ops[] = { N1, N2, N3, N4, N5 };
      -  return getNode(Opcode, VT, Ops, 5);
      +  return getNode(Opcode, DL, VT, Ops, 5);
       }
       
       /// getMemsetValue - Vectorized representation of the memset value
      @@ -3620,27 +3651,37 @@ SDValue SelectionDAG::getVAArg(MVT VT,
       
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
                                     const SDUse *Ops, unsigned NumOps) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, Ops, NumOps);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                              const SDUse *Ops, unsigned NumOps) {
         switch (NumOps) {
      -  case 0: return getNode(Opcode, VT);
      -  case 1: return getNode(Opcode, VT, Ops[0]);
      -  case 2: return getNode(Opcode, VT, Ops[0], Ops[1]);
      -  case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]);
      +  case 0: return getNode(Opcode, DL, VT);
      +  case 1: return getNode(Opcode, DL, VT, Ops[0]);
      +  case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1]);
      +  case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);
         default: break;
         }
       
         // Copy from an SDUse array into an SDValue array for use with
         // the regular getNode logic.
         SmallVector NewOps(Ops, Ops + NumOps);
      -  return getNode(Opcode, VT, &NewOps[0], NumOps);
      +  return getNode(Opcode, DL, VT, &NewOps[0], NumOps);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
                                     const SDValue *Ops, unsigned NumOps) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VT, Ops, NumOps);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                              const SDValue *Ops, unsigned NumOps) {
         switch (NumOps) {
      -  case 0: return getNode(Opcode, VT);
      -  case 1: return getNode(Opcode, VT, Ops[0]);
      -  case 2: return getNode(Opcode, VT, Ops[0], Ops[1]);
      -  case 3: return getNode(Opcode, VT, Ops[0], Ops[1], Ops[2]);
      +  case 0: return getNode(Opcode, DL, VT);
      +  case 1: return getNode(Opcode, DL, VT, Ops[0]);
      +  case 2: return getNode(Opcode, DL, VT, Ops[0], Ops[1]);
      +  case 3: return getNode(Opcode, DL, VT, Ops[0], Ops[1], Ops[2]);
         default: break;
         }
         
      @@ -3667,19 +3708,23 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
         // Memoize nodes.
         SDNode *N;
         SDVTList VTs = getVTList(VT);
      +
         if (VT != MVT::Flag) {
           FoldingSetNodeID ID;
           AddNodeIDNode(ID, Opcode, VTs, Ops, NumOps);
           void *IP = 0;
      +
           if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
             return SDValue(E, 0);
      +
           N = NodeAllocator.Allocate();
      -    new (N) SDNode(Opcode, VTs, Ops, NumOps);
      +    new (N) SDNode(Opcode, DL, VTs, Ops, NumOps);
           CSEMap.InsertNode(N, IP);
         } else {
           N = NodeAllocator.Allocate();
      -    new (N) SDNode(Opcode, VTs, Ops, NumOps);
      +    new (N) SDNode(Opcode, DL, VTs, Ops, NumOps);
         }
      +
         AllNodes.push_back(N);
       #ifndef NDEBUG
         VerifyNode(N);
      @@ -3690,22 +3735,39 @@ SDValue SelectionDAG::getNode(unsigned Opcode, MVT VT,
       SDValue SelectionDAG::getNode(unsigned Opcode,
                                     const std::vector &ResultTys,
                                     const SDValue *Ops, unsigned NumOps) {
      -  return getNode(Opcode, getNodeValueTypes(ResultTys), ResultTys.size(),
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), ResultTys, Ops, NumOps);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
      +                              const std::vector &ResultTys,
      +                              const SDValue *Ops, unsigned NumOps) {
      +  return getNode(Opcode, DL, getNodeValueTypes(ResultTys), ResultTys.size(),
                        Ops, NumOps);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode,
                                     const MVT *VTs, unsigned NumVTs,
                                     const SDValue *Ops, unsigned NumOps) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTs, NumVTs, Ops, NumOps);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL,
      +                              const MVT *VTs, unsigned NumVTs,
      +                              const SDValue *Ops, unsigned NumOps) {
         if (NumVTs == 1)
      -    return getNode(Opcode, VTs[0], Ops, NumOps);
      -  return getNode(Opcode, makeVTList(VTs, NumVTs), Ops, NumOps);
      +    return getNode(Opcode, DL, VTs[0], Ops, NumOps);
      +  return getNode(Opcode, DL, makeVTList(VTs, NumVTs), Ops, NumOps);
       }  
         
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
                                     const SDValue *Ops, unsigned NumOps) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, Ops, NumOps);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
      +                              const SDValue *Ops, unsigned NumOps) {
         if (VTList.NumVTs == 1)
      -    return getNode(Opcode, VTList.VTs[0], Ops, NumOps);
      +    return getNode(Opcode, DL, VTList.VTs[0], Ops, NumOps);
       
         switch (Opcode) {
         // FIXME: figure out how to safely handle things like
      @@ -3717,14 +3779,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
         case ISD::SHL_PARTS:
           if (N3.getOpcode() == ISD::SIGN_EXTEND_INREG &&
               cast(N3.getOperand(1))->getVT() != MVT::i1)
      -      return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
      +      return getNode(Opcode, DL, VT, N1, N2, N3.getOperand(0));
           else if (N3.getOpcode() == ISD::AND)
             if (ConstantSDNode *AndRHS = dyn_cast(N3.getOperand(1))) {
               // If the and is only masking out bits that cannot effect the shift,
               // eliminate the and.
               unsigned NumBits = VT.getSizeInBits()*2;
               if ((AndRHS->getValue() & (NumBits-1)) == NumBits-1)
      -          return getNode(Opcode, VT, N1, N2, N3.getOperand(0));
      +          return getNode(Opcode, DL, VT, N1, N2, N3.getOperand(0));
             }
           break;
       #endif
      @@ -3740,31 +3802,31 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
             return SDValue(E, 0);
           if (NumOps == 1) {
             N = NodeAllocator.Allocate();
      -      new (N) UnarySDNode(Opcode, VTList, Ops[0]);
      +      new (N) UnarySDNode(Opcode, DL, VTList, Ops[0]);
           } else if (NumOps == 2) {
             N = NodeAllocator.Allocate();
      -      new (N) BinarySDNode(Opcode, VTList, Ops[0], Ops[1]);
      +      new (N) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
           } else if (NumOps == 3) {
             N = NodeAllocator.Allocate();
      -      new (N) TernarySDNode(Opcode, VTList, Ops[0], Ops[1], Ops[2]);
      +      new (N) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1], Ops[2]);
           } else {
             N = NodeAllocator.Allocate();
      -      new (N) SDNode(Opcode, VTList, Ops, NumOps);
      +      new (N) SDNode(Opcode, DL, VTList, Ops, NumOps);
           }
           CSEMap.InsertNode(N, IP);
         } else {
           if (NumOps == 1) {
             N = NodeAllocator.Allocate();
      -      new (N) UnarySDNode(Opcode, VTList, Ops[0]);
      +      new (N) UnarySDNode(Opcode, DL, VTList, Ops[0]);
           } else if (NumOps == 2) {
             N = NodeAllocator.Allocate();
      -      new (N) BinarySDNode(Opcode, VTList, Ops[0], Ops[1]);
      +      new (N) BinarySDNode(Opcode, DL, VTList, Ops[0], Ops[1]);
           } else if (NumOps == 3) {
             N = NodeAllocator.Allocate();
      -      new (N) TernarySDNode(Opcode, VTList, Ops[0], Ops[1], Ops[2]);
      +      new (N) TernarySDNode(Opcode, DL, VTList, Ops[0], Ops[1], Ops[2]);
           } else {
             N = NodeAllocator.Allocate();
      -      new (N) SDNode(Opcode, VTList, Ops, NumOps);
      +      new (N) SDNode(Opcode, DL, VTList, Ops, NumOps);
           }
         }
         AllNodes.push_back(N);
      @@ -3775,39 +3837,70 @@ SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList) {
      -  return getNode(Opcode, VTList, 0, 0);
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList); 
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList) {
      +  return getNode(Opcode, DL, VTList, 0, 0);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
      -                                SDValue N1) {
      +                              SDValue N1) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
      +                              SDValue N1) {
         SDValue Ops[] = { N1 };
      -  return getNode(Opcode, VTList, Ops, 1);
      +  return getNode(Opcode, DL, VTList, Ops, 1);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
                                     SDValue N1, SDValue N2) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
      +                              SDValue N1, SDValue N2) {
         SDValue Ops[] = { N1, N2 };
      -  return getNode(Opcode, VTList, Ops, 2);
      +  return getNode(Opcode, DL, VTList, Ops, 2);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
                                     SDValue N1, SDValue N2, SDValue N3) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2, N3);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
      +                              SDValue N1, SDValue N2, SDValue N3) {
         SDValue Ops[] = { N1, N2, N3 };
      -  return getNode(Opcode, VTList, Ops, 3);
      +  return getNode(Opcode, DL, VTList, Ops, 3);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
                                     SDValue N1, SDValue N2, SDValue N3,
                                     SDValue N4) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2, N3, N4);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
      +                              SDValue N1, SDValue N2, SDValue N3,
      +                              SDValue N4) {
         SDValue Ops[] = { N1, N2, N3, N4 };
      -  return getNode(Opcode, VTList, Ops, 4);
      +  return getNode(Opcode, DL, VTList, Ops, 4);
       }
       
       SDValue SelectionDAG::getNode(unsigned Opcode, SDVTList VTList,
                                     SDValue N1, SDValue N2, SDValue N3,
                                     SDValue N4, SDValue N5) {
      +  return getNode(Opcode, DebugLoc::getUnknownLoc(), VTList, N1, N2, N3, N4, N5);
      +}
      +
      +SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, SDVTList VTList,
      +                              SDValue N1, SDValue N2, SDValue N3,
      +                              SDValue N4, SDValue N5) {
         SDValue Ops[] = { N1, N2, N3, N4, N5 };
      -  return getNode(Opcode, VTList, Ops, 5);
      +  return getNode(Opcode, DL, VTList, Ops, 5);
       }
       
       SDVTList SelectionDAG::getVTList(MVT VT) {
      -- 
      GitLab
      
      
      From 066347ec7b882b3f0e82c95270ee4dc46e3557f9 Mon Sep 17 00:00:00 2001
      From: Fariborz Jahanian 
      Date: Wed, 28 Jan 2009 22:18:42 +0000
      Subject: [PATCH 384/682] property metadata for objc2's nonfragile abi
      
      llvm-svn: 63246
      ---
       clang/lib/CodeGen/CGObjCMac.cpp | 45 ++++++++++++++++++++++-----------
       1 file changed, 30 insertions(+), 15 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
      index 99c6c04abd37..acd5315842f4 100644
      --- a/clang/lib/CodeGen/CGObjCMac.cpp
      +++ b/clang/lib/CodeGen/CGObjCMac.cpp
      @@ -351,6 +351,13 @@ protected:
         const RecordDecl *GetFirstIvarInRecord(const ObjCInterfaceDecl *OID,
                                                RecordDecl::field_iterator &FIV,
                                                RecordDecl::field_iterator &PIV);  
      +  /// EmitPropertyList - Emit the given property list. The return
      +  /// value has type PropertyListPtrTy.
      +  llvm::Constant *EmitPropertyList(const std::string &Name,
      +                                   const Decl *Container, 
      +                                   const ObjCContainerDecl *OCD,
      +                                   const ObjCCommonTypesHelper &ObjCTypes);
      +  
       public:
         CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm)
         { }
      @@ -443,12 +450,6 @@ private:
                                            const char *Section,
                                            const ConstantVector &Methods);
       
      -  /// EmitPropertyList - Emit the given property list. The return
      -  /// value has type PropertyListPtrTy.
      -  llvm::Constant *EmitPropertyList(const std::string &Name,
      -                                   const Decl *Container, 
      -                                   const ObjCContainerDecl *OCD);
      -
         /// GetOrEmitProtocol - Get the protocol object for the given
         /// declaration, emitting it if necessary. The return value has type
         /// ProtocolPtrTy.
      @@ -954,7 +955,7 @@ CGObjCMac::EmitProtocolExtension(const ObjCProtocolDecl *PD,
                              OptClassMethods);
         Values[3] = EmitPropertyList("\01L_OBJC_$_PROP_PROTO_LIST_" + 
                                          PD->getNameAsString(),
      -                               0, PD);
      +                               0, PD, ObjCTypes);
       
         // Return null if no extension bits are used.
         if (Values[1]->isNullValue() && Values[2]->isNullValue() && 
      @@ -1030,9 +1031,10 @@ CGObjCMac::EmitProtocolList(const std::string &Name,
           struct _objc_property[prop_count];
         };
       */
      -llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
      -                                            const Decl *Container,
      -                                            const ObjCContainerDecl *OCD) {
      +llvm::Constant *CGObjCCommonMac::EmitPropertyList(const std::string &Name,
      +                                      const Decl *Container,
      +                                      const ObjCContainerDecl *OCD,
      +                                      const ObjCCommonTypesHelper &ObjCTypes) {
         std::vector Properties, Prop(2);
         for (ObjCContainerDecl::prop_iterator I = OCD->prop_begin(), 
              E = OCD->prop_end(); I != E; ++I) {
      @@ -1063,6 +1065,8 @@ llvm::Constant *CGObjCMac::EmitPropertyList(const std::string &Name,
                                    Init,
                                    Name,
                                    &CGM.getModule());
      +  if (ObjCABI == 2)
      +    GV->setSection("__DATA, __objc_const");
         // No special section on property lists?
         UsedGlobals.push_back(GV);
         return llvm::ConstantExpr::getBitCast(GV, 
      @@ -1172,7 +1176,7 @@ void CGObjCMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) {
         // If there is no category @interface then there can be no properties.
         if (Category) {
           Values[6] = EmitPropertyList(std::string("\01L_OBJC_$_PROP_LIST_") + ExtName,
      -                                 OCD, Category);
      +                                 OCD, Category, ObjCTypes);
         } else {
           Values[6] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
         }
      @@ -1447,7 +1451,7 @@ CGObjCMac::EmitClassExtension(const ObjCImplementationDecl *ID) {
         // FIXME: Output weak_ivar_layout string.
         Values[1] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
         Values[2] = EmitPropertyList("\01L_OBJC_$_PROP_LIST_" + ID->getNameAsString(),
      -                               ID, ID->getClassInterface());
      +                               ID, ID->getClassInterface(), ObjCTypes);
       
         // Return null if no extension bits are used.
         if (Values[1]->isNullValue() && Values[2]->isNullValue())
      @@ -3195,7 +3199,13 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
         else
           Values[ 7] = EmitIvarList(ID);
         Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
      -  Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
      +  if (flags & CLS_META)
      +    Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
      +  else
      +    Values[ 9] = 
      +      EmitPropertyList(
      +                       "\01l_OBJC_$_PROP_LIST_" + ID->getNameAsString(),
      +                       ID, ID->getClassInterface(), ObjCTypes);
         llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ClassRonfABITy,
                                                          Values);
         llvm::GlobalVariable *CLASS_RO_GV =
      @@ -3461,8 +3471,13 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD)
                                    "__DATA, __objc_const", 
                                    Methods);
         Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
      -  Values[5] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
      -  
      +  const ObjCCategoryDecl *Category = 
      +    Interface->FindCategoryDeclaration(OCD->getIdentifier());
      +  std::string ExtName(Interface->getNameAsString() + "_$_" +
      +                      OCD->getNameAsString());
      +  Values[5] =
      +    EmitPropertyList(std::string("\01l_OBJC_$_PROP_LIST_") + ExtName,
      +                                OCD, Category, ObjCTypes);
         llvm::Constant *Init = 
           llvm::ConstantStruct::get(ObjCTypes.CategorynfABITy, 
                                     Values);
      -- 
      GitLab
      
      
      From 42b63bc175831ed75143c593b40ded58f4446309 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Wed, 28 Jan 2009 22:20:56 +0000
      Subject: [PATCH 385/682] Make test platform agnostic.
      
      llvm-svn: 63247
      ---
       llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll | 4 +---
       1 file changed, 1 insertion(+), 3 deletions(-)
      
      diff --git a/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll b/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll
      index 0b087d00e238..b0c27d8903e7 100644
      --- a/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll
      +++ b/llvm/test/CodeGen/X86/2009-01-27-NullStrings.ll
      @@ -1,6 +1,4 @@
      -; RUN: llvm-as < %s | llc -march=x86 | grep {\\.cstring} | count 1
      -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
      -target triple = "i386-apple-darwin9.6"
      +; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin | grep {\\.cstring} | count 1
       	%struct.A = type {  }
       	%struct.NSString = type opaque
       	%struct.__builtin_CFString = type { i32*, i32, i8*, i32 }
      -- 
      GitLab
      
      
      From f50e60b23a6178bb79ab3faa2e7992b29b1026c6 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Wed, 28 Jan 2009 22:24:07 +0000
      Subject: [PATCH 386/682] Implement basic _Complex integer constant folding.  -
       Merged into single ComplexEvaluator, these share too much logic to    be
       worth splitting for float/int (IMHO). Will split on request.
      
      llvm-svn: 63248
      ---
       clang/lib/AST/ExprConstant.cpp       | 100 ++++++++++++++++++---------
       clang/lib/CodeGen/CGExprConstant.cpp |  12 +++-
       clang/test/CodeGen/const-init.c      |   3 +
       3 files changed, 81 insertions(+), 34 deletions(-)
      
      diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
      index 66261045a5b6..af50de6f9481 100644
      --- a/clang/lib/AST/ExprConstant.cpp
      +++ b/clang/lib/AST/ExprConstant.cpp
      @@ -55,8 +55,7 @@ static bool EvaluateLValue(const Expr *E, APValue &Result, EvalInfo &Info);
       static bool EvaluatePointer(const Expr *E, APValue &Result, EvalInfo &Info);
       static bool EvaluateInteger(const Expr *E, APSInt  &Result, EvalInfo &Info);
       static bool EvaluateFloat(const Expr *E, APFloat &Result, EvalInfo &Info);
      -static bool EvaluateComplexFloat(const Expr *E, APValue &Result, 
      -                                 EvalInfo &Info);
      +static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info);
       
       //===----------------------------------------------------------------------===//
       // Misc utilities
      @@ -1228,16 +1227,16 @@ bool FloatExprEvaluator::VisitCXXZeroInitValueExpr(CXXZeroInitValueExpr *E) {
       }
       
       //===----------------------------------------------------------------------===//
      -// Complex Float Evaluation
      +// Complex Evaluation (for float and integer)
       //===----------------------------------------------------------------------===//
       
       namespace {
      -class VISIBILITY_HIDDEN ComplexFloatExprEvaluator
      -  : public StmtVisitor {
      +class VISIBILITY_HIDDEN ComplexExprEvaluator
      +  : public StmtVisitor {
         EvalInfo &Info;
         
       public:
      -  ComplexFloatExprEvaluator(EvalInfo &info) : Info(info) {}
      +  ComplexExprEvaluator(EvalInfo &info) : Info(info) {}
         
         //===--------------------------------------------------------------------===//
         //                            Visitor Methods
      @@ -1250,12 +1249,28 @@ public:
         APValue VisitParenExpr(ParenExpr *E) { return Visit(E->getSubExpr()); }
       
         APValue VisitImaginaryLiteral(ImaginaryLiteral *E) {
      -    APFloat Result(0.0);
      -    if (!EvaluateFloat(E->getSubExpr(), Result, Info))
      -      return APValue();
      +    Expr* SubExpr = E->getSubExpr();
      +
      +    if (SubExpr->getType()->isRealFloatingType()) {
      +      APFloat Result(0.0);
      +
      +      if (!EvaluateFloat(SubExpr, Result, Info))
      +        return APValue();
           
      -    return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), 
      -                   Result);
      +      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), 
      +                     Result);
      +    } else {
      +      assert(SubExpr->getType()->isIntegerType() && 
      +             "Unexpected imaginary literal.");
      +
      +      llvm::APSInt Result;
      +      if (!EvaluateInteger(SubExpr, Result, Info))
      +        return APValue();
      +      
      +      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
      +      Zero = 0;
      +      return APValue(Zero, Result);
      +    }
         }
       
         APValue VisitCastExpr(CastExpr *E) {
      @@ -1269,6 +1284,15 @@ public:
             
             return APValue(Result, 
                            APFloat(Result.getSemantics(), APFloat::fcZero));
      +    } else if (SubExpr->getType()->isIntegerType()) {
      +      APSInt Result;
      +                     
      +      if (!EvaluateInteger(SubExpr, Result, Info))
      +        return APValue();
      +      
      +      llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
      +      Zero = 0;
      +      return APValue(Result, Zero);
           }
       
           // FIXME: Handle more casts.
      @@ -1280,38 +1304,48 @@ public:
       };
       } // end anonymous namespace
       
      -static bool EvaluateComplexFloat(const Expr *E, APValue &Result, EvalInfo &Info)
      +static bool EvaluateComplex(const Expr *E, APValue &Result, EvalInfo &Info)
       {
      -  Result = ComplexFloatExprEvaluator(Info).Visit(const_cast(E));
      -  if (Result.isComplexFloat())
      -    assert(&Result.getComplexFloatReal().getSemantics() == 
      -           &Result.getComplexFloatImag().getSemantics() && 
      -           "Invalid complex evaluation.");
      -  return Result.isComplexFloat();
      +  Result = ComplexExprEvaluator(Info).Visit(const_cast(E));
      +  assert((!Result.isComplexFloat() ||
      +          (&Result.getComplexFloatReal().getSemantics() == 
      +           &Result.getComplexFloatImag().getSemantics())) && 
      +         "Invalid complex evaluation.");
      +  return Result.isComplexFloat() || Result.isComplexInt();
       }
       
      -APValue ComplexFloatExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
      +APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
       {
         APValue Result, RHS;
         
      -  if (!EvaluateComplexFloat(E->getLHS(), Result, Info))
      +  if (!EvaluateComplex(E->getLHS(), Result, Info))
           return APValue();
         
      -  if (!EvaluateComplexFloat(E->getRHS(), RHS, Info))
      +  if (!EvaluateComplex(E->getRHS(), RHS, Info))
           return APValue();
      -  
      +
         switch (E->getOpcode()) {
         default: return APValue();
         case BinaryOperator::Add:
      -    Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
      -                                     APFloat::rmNearestTiesToEven);
      -    Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
      -                                     APFloat::rmNearestTiesToEven);
      +    if (Result.isComplexFloat()) {
      +      Result.getComplexFloatReal().add(RHS.getComplexFloatReal(),
      +                                       APFloat::rmNearestTiesToEven);
      +      Result.getComplexFloatImag().add(RHS.getComplexFloatImag(),
      +                                       APFloat::rmNearestTiesToEven);
      +    } else {
      +      Result.getComplexIntReal() += RHS.getComplexIntReal();
      +      Result.getComplexIntImag() += RHS.getComplexIntImag();
      +    }
         case BinaryOperator::Sub:
      -    Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
      -                                          APFloat::rmNearestTiesToEven);
      -    Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
      -                                          APFloat::rmNearestTiesToEven);
      +    if (Result.isComplexFloat()) {
      +      Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
      +                                            APFloat::rmNearestTiesToEven);
      +      Result.getComplexFloatImag().subtract(RHS.getComplexFloatImag(),
      +                                            APFloat::rmNearestTiesToEven);
      +    } else {
      +      Result.getComplexIntReal() -= RHS.getComplexIntReal();
      +      Result.getComplexIntImag() -= RHS.getComplexIntImag();
      +    }
         }
       
         return Result;
      @@ -1346,10 +1380,10 @@ bool Expr::Evaluate(EvalResult &Result, ASTContext &Ctx) const {
             return false;
           
           Result.Val = APValue(f);
      -  } else if (getType()->isComplexType()) {
      -    if (!EvaluateComplexFloat(this, Result.Val, Info))
      +  } else if (getType()->isAnyComplexType()) {
      +    if (!EvaluateComplex(this, Result.Val, Info))
             return false;
      -  }  else
      +  } else
           return false;
       
         return true;
      diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
      index 3b6ebb4d56f3..87868ed347a8 100644
      --- a/clang/lib/CodeGen/CGExprConstant.cpp
      +++ b/clang/lib/CodeGen/CGExprConstant.cpp
      @@ -597,7 +597,9 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
           assert(!Result.HasSideEffects && 
                  "Constant expr should not have any side effects!");
           switch (Result.Val.getKind()) {
      -    default: assert(0 && "unhandled value kind!");
      +    case APValue::Uninitialized:
      +      assert(0 && "Constant expressions should be uninitialized.");
      +      return llvm::UndefValue::get(getTypes().ConvertType(type));
           case APValue::LValue: {
             llvm::Constant *Offset = 
               llvm::ConstantInt::get(llvm::Type::Int64Ty, 
      @@ -631,6 +633,14 @@ llvm::Constant *CodeGenModule::EmitConstantExpr(const Expr *E,
             }
             return C;
           }
      +    case APValue::ComplexInt: {
      +      llvm::Constant *Complex[2];
      +      
      +      Complex[0] = llvm::ConstantInt::get(Result.Val.getComplexIntReal());
      +      Complex[1] = llvm::ConstantInt::get(Result.Val.getComplexIntImag());
      +      
      +      return llvm::ConstantStruct::get(Complex, 2);
      +    }
           case APValue::Float:
             return llvm::ConstantFP::get(Result.Val.getFloat());
           case APValue::ComplexFloat: {
      diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c
      index bded2e0a3f6f..3aabcfe60894 100644
      --- a/clang/test/CodeGen/const-init.c
      +++ b/clang/test/CodeGen/const-init.c
      @@ -21,3 +21,6 @@ union s2 {
       };
       
       int g0 = (int)(&(((union s2 *) 0)->f0.f0) - 0);
      +
      +_Complex int g1 = 1 + 10i;
      +_Complex double g2 = 1.0 + 10.0i;
      -- 
      GitLab
      
      
      From 2e561dd4911b3d092f50a6cdcf5a89512249c8dd Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Wed, 28 Jan 2009 22:27:59 +0000
      Subject: [PATCH 387/682] Remove method 'AddNE' from the public interface of
       ConstraintManager.
      
      llvm-svn: 63249
      ---
       .../clang/Analysis/PathSensitive/ConstraintManager.h |  2 --
       clang/include/clang/Analysis/PathSensitive/GRState.h | 12 ++++--------
       clang/lib/Analysis/BasicConstraintManager.cpp        |  2 +-
       clang/lib/Analysis/CFRefCount.cpp                    |  7 +++++--
       4 files changed, 10 insertions(+), 13 deletions(-)
      
      diff --git a/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h b/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h
      index 4cded5ce6915..6b69a1020cde 100644
      --- a/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h
      +++ b/clang/include/clang/Analysis/PathSensitive/ConstraintManager.h
      @@ -38,8 +38,6 @@ public:
                                              SVal UpperBound, bool Assumption,
                                              bool& isFeasible) = 0;
       
      -  virtual const GRState* AddNE(const GRState* St, SymbolRef sym, 
      -                               const llvm::APSInt& V) = 0;
         virtual const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) = 0;
       
         virtual bool isEqual(const GRState* St, SymbolRef sym, 
      diff --git a/clang/include/clang/Analysis/PathSensitive/GRState.h b/clang/include/clang/Analysis/PathSensitive/GRState.h
      index 45ad702346c4..b227f91a78f0 100644
      --- a/clang/include/clang/Analysis/PathSensitive/GRState.h
      +++ b/clang/include/clang/Analysis/PathSensitive/GRState.h
      @@ -603,10 +603,6 @@ public:
                                               isFeasible);
         }
       
      -  const GRState* AddNE(const GRState* St, SymbolRef sym, const llvm::APSInt& V) {
      -    return ConstraintMgr->AddNE(St, sym, V);
      -  }
      -
         const llvm::APSInt* getSymVal(const GRState* St, SymbolRef sym) {
           return ConstraintMgr->getSymVal(St, sym);
         }
      @@ -671,10 +667,6 @@ public:
           return GRStateRef(Mgr->Unbind(St, LV), *Mgr);
         }
         
      -  GRStateRef AddNE(SymbolRef sym, const llvm::APSInt& V) {
      -    return GRStateRef(Mgr->AddNE(St, sym, V), *Mgr);
      -  }
      -  
         // Trait based GDM dispatch.
         template
         typename GRStateTrait::data_type get() const {
      @@ -735,6 +727,10 @@ public:
         SVal GetLValue(const VarDecl* VD) {
           return Mgr->GetLValue(St, VD);
         }
      +    
      +  GRStateRef Assume(SVal Cond, bool Assumption, bool& isFeasible) {
      +    return GRStateRef(Mgr->Assume(St, Cond, Assumption, isFeasible), *Mgr);  
      +  }
         
         // Pretty-printing.
         void print(std::ostream& Out, const char* nl = "\n",
      diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp
      index 7496c5f5aac2..f14ada7aed63 100644
      --- a/clang/lib/Analysis/BasicConstraintManager.cpp
      +++ b/clang/lib/Analysis/BasicConstraintManager.cpp
      @@ -72,7 +72,7 @@ public:
                                     const SymIntConstraint& C, bool& isFeasible);
       
         const GRState* AssumeSymNE(const GRState* St, SymbolRef sym,
      -                                const llvm::APSInt& V, bool& isFeasible);
      +                             const llvm::APSInt& V, bool& isFeasible);
       
         const GRState* AssumeSymEQ(const GRState* St, SymbolRef sym,
                                       const llvm::APSInt& V, bool& isFeasible);
      diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
      index 2d5cb5f5b89e..6f1b1036b309 100644
      --- a/clang/lib/Analysis/CFRefCount.cpp
      +++ b/clang/lib/Analysis/CFRefCount.cpp
      @@ -1678,8 +1678,11 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
       #endif 
       
             // FIXME: Add a flag to the checker where allocations are allowed to fail.      
      -      if (RE.getKind() == RetEffect::OwnedAllocatedSymbol)
      -        state = state.AddNE(Sym, Eng.getBasicVals().getZeroWithPtrWidth());
      +      if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) {
      +        bool isFeasible;
      +        state = state.Assume(loc::SymbolVal(Sym), true, isFeasible);
      +        assert(isFeasible && "Cannot assume fresh symbol is non-null.");        
      +      }
             
             break;
           }
      -- 
      GitLab
      
      
      From b4dd3f8685f5a15446cde1bc550bfc13335b62b8 Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Wed, 28 Jan 2009 22:35:55 +0000
      Subject: [PATCH 388/682] Remove '#if 0' code.
      
      llvm-svn: 63250
      ---
       clang/lib/Analysis/CFRefCount.cpp | 5 -----
       1 file changed, 5 deletions(-)
      
      diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
      index 6f1b1036b309..35b7ee7b805a 100644
      --- a/clang/lib/Analysis/CFRefCount.cpp
      +++ b/clang/lib/Analysis/CFRefCount.cpp
      @@ -1672,11 +1672,6 @@ void CFRefCount::EvalSummary(ExplodedNodeSet& Dst,
               state.set(Sym, RefVal::makeOwned(RE.getObjKind(), RetT));      
             state = state.BindExpr(Ex, loc::SymbolVal(Sym), false);
       
      -#if 0
      -      RefBindings B = GetRefBindings(StImpl);
      -      SetRefBindings(StImpl, RefBFactory.Add(B, Sym, RefVal::makeOwned(RetT)));
      -#endif 
      -
             // FIXME: Add a flag to the checker where allocations are allowed to fail.      
             if (RE.getKind() == RetEffect::OwnedAllocatedSymbol) {
               bool isFeasible;
      -- 
      GitLab
      
      
      From d27a820ae237766c2f3b92e189ba70cdd471c276 Mon Sep 17 00:00:00 2001
      From: Fariborz Jahanian 
      Date: Wed, 28 Jan 2009 22:46:49 +0000
      Subject: [PATCH 389/682] Add setter/getter methods to the list of methods of
       class's meta-data (related to objc2 nonfragile abi).
      
      llvm-svn: 63251
      ---
       clang/lib/CodeGen/CGObjCMac.cpp | 15 +++++++++++++++
       1 file changed, 15 insertions(+)
      
      diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
      index acd5315842f4..8ffed61857f3 100644
      --- a/clang/lib/CodeGen/CGObjCMac.cpp
      +++ b/clang/lib/CodeGen/CGObjCMac.cpp
      @@ -3189,6 +3189,21 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
             // Instance methods should always be defined.
             Methods.push_back(GetMethodConstant(*i));
           }
      +    for (ObjCImplementationDecl::propimpl_iterator i = ID->propimpl_begin(),
      +         e = ID->propimpl_end(); i != e; ++i) {
      +      ObjCPropertyImplDecl *PID = *i;
      +      
      +      if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize){
      +        ObjCPropertyDecl *PD = PID->getPropertyDecl();
      +        
      +        if (ObjCMethodDecl *MD = PD->getGetterMethodDecl())
      +          if (llvm::Constant *C = GetMethodConstant(MD))
      +            Methods.push_back(C);
      +        if (ObjCMethodDecl *MD = PD->getSetterMethodDecl())
      +          if (llvm::Constant *C = GetMethodConstant(MD))
      +            Methods.push_back(C);
      +      }
      +    }
         }
         // FIXME. Section may always be .data
         Values[ 5] = EmitMethodList(MethodListName, 
      -- 
      GitLab
      
      
      From 9150f735fa3180c3985c12456856a7cede64b82e Mon Sep 17 00:00:00 2001
      From: Mon P Wang 
      Date: Wed, 28 Jan 2009 23:11:14 +0000
      Subject: [PATCH 390/682] Fixed lowering of v816 shuffles.
      
      llvm-svn: 63252
      ---
       llvm/lib/Target/X86/X86ISelLowering.cpp |  2 +-
       llvm/test/CodeGen/X86/vec_shuffle-29.ll | 14 ++++++++++++++
       2 files changed, 15 insertions(+), 1 deletion(-)
       create mode 100644 llvm/test/CodeGen/X86/vec_shuffle-29.ll
      
      diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
      index f48d75253df1..6ec97e2db60e 100644
      --- a/llvm/lib/Target/X86/X86ISelLowering.cpp
      +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
      @@ -3677,7 +3677,7 @@ SDValue LowerVECTOR_SHUFFLEv8i16(SDValue V1, SDValue V2,
             ++V2InOrder;
           } else if (EltIdx < 8) {
             V1Elts.push_back(Elt);
      -      V2Elts.push_back(DAG.getConstant(i+8, MaskEVT));
      +      V2Elts.push_back(DAG.getConstant(EltIdx+8, MaskEVT));
             ++V1FromV1;
           } else {
             V1Elts.push_back(Elt);
      diff --git a/llvm/test/CodeGen/X86/vec_shuffle-29.ll b/llvm/test/CodeGen/X86/vec_shuffle-29.ll
      new file mode 100644
      index 000000000000..aac63c3bbec6
      --- /dev/null
      +++ b/llvm/test/CodeGen/X86/vec_shuffle-29.ll
      @@ -0,0 +1,14 @@
      +; RUN: llvm-as < %s | llc -march=x86 -mattr=sse41 -disable-mmx -o %t -f
      +; RUN: not grep pextrw %t
      +; RUN: grep pinsrw %t
      +
      +; Test for v8xi16 lowering where we extract the first element of the vector and
      +; placed it in the second element of the result.
      +
      +define void @test_cl(<8 x i16> addrspace(1)* %dest, <8 x i16> addrspace(1)* %old) nounwind {
      +entry:
      +	%tmp3 = load <8 x i16> addrspace(1)* %old		; <<8 x i16>> [#uses=1]
      +	%tmp6 = shufflevector <8 x i16> %tmp3, <8 x i16> < i16 0, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef, i16 undef >, <8 x i32> < i32 8, i32 0, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef, i32 undef  >		; <<8 x i16>> [#uses=1]
      +	store <8 x i16> %tmp6, <8 x i16> addrspace(1)* %dest
      +	ret void
      +}
      \ No newline at end of file
      -- 
      GitLab
      
      
      From 17bd094a6b0bffdb578a8ab19cd92e8cdaba8f61 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Wed, 28 Jan 2009 23:36:17 +0000
      Subject: [PATCH 391/682] Improvements to code-generation and semantic analysis
       of designated initializers.
      
        - We now initialize unions properly when a member other than the
          first is named by a designated initializer.
        - We now provide proper semantic analysis and code generation for
          GNU array-range designators *except* that side effects will occur
          more than once. We warn about this.
      
      llvm-svn: 63253
      ---
       .../clang/Basic/DiagnosticSemaKinds.def       |   6 +-
       clang/lib/CodeGen/CGExprAgg.cpp               |  15 ++-
       clang/lib/CodeGen/CGExprConstant.cpp          |  12 +-
       clang/lib/CodeGen/CodeGenTypes.cpp            |   1 +
       clang/lib/Sema/Sema.h                         |   3 +-
       clang/lib/Sema/SemaInit.cpp                   | 112 ++++++++++++------
       clang/test/Sema/designated-initializers.c     |  10 +-
       7 files changed, 106 insertions(+), 53 deletions(-)
      
      diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      index 222e39911b81..6276d61211f3 100644
      --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      @@ -60,10 +60,8 @@ DIAG(warn_initializer_overrides, WARNING,
            "initializer overrides prior initialization of this subobject")
       DIAG(note_previous_initializer, NOTE,
            "previous initialization %select{|with side effects }0is here%select{| (side effects may not occur at run time)}0")
      -DIAG(warn_gnu_array_range_designator_unsupported, WARNING,
      -     "GNU array-range designator extension is unsupported")
      -DIAG(warn_designator_into_union_broken_init, WARNING,
      -     "designated initialization of union member is broken")
      +DIAG(warn_gnu_array_range_designator_side_effects, WARNING,
      +     "side effects due to the GNU array-range designator extension may occur multiple times")
       
       // Declarations.
       DIAG(ext_vla, EXTENSION,
      diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
      index 2534a14cb6c5..075a12c57e1b 100644
      --- a/clang/lib/CodeGen/CGExprAgg.cpp
      +++ b/clang/lib/CodeGen/CGExprAgg.cpp
      @@ -454,10 +454,17 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
           if (Field->getType()->isIncompleteArrayType())
             break;
       
      -    if (Field->getIdentifier() == 0) {
      -      // Initializers can't initialize unnamed fields, e.g. "int : 20;"
      +    if (Field->isUnnamedBitfield())
             continue;
      -    }
      +
      +    // When we're coping with C99 designated initializers into a
      +    // union, find the field that has the same type as the expression
      +    // we're initializing the union with.
      +    if (isUnion && CurInitVal < NumInitElements && 
      +        (CGF.getContext().getCanonicalType(Field->getType()) != 
      +           CGF.getContext().getCanonicalType(E->getInit(CurInitVal)->getType())))
      +      continue;
      +
           // FIXME: volatility
           LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, isUnion,0);
           if (CurInitVal < NumInitElements) {
      @@ -471,8 +478,6 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
           }
       
           // Unions only initialize one field.
      -    // (FIXME: things can get weird with designators, but they aren't
      -    // supported yet.)
           if (isUnion)
             break;
         }
      diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
      index 87868ed347a8..b05048c94609 100644
      --- a/clang/lib/CodeGen/CGExprConstant.cpp
      +++ b/clang/lib/CodeGen/CGExprConstant.cpp
      @@ -246,12 +246,22 @@ public:
           // first field
           int FieldNo = 0; // Field no in RecordDecl
           FieldDecl* curField = 0;
      +    bool sawAnyFields = false;
           for (RecordDecl::field_iterator Field = RD->field_begin(),
                                        FieldEnd = RD->field_end();
                Field != FieldEnd; ++Field) {
             curField = *Field;
             FieldNo++;
      -      if (curField->getIdentifier())
      +
      +      if (curField->isUnnamedBitfield())
      +        continue;
      +
      +      // If we have an initializer, find the field whose type is the
      +      // same as that initializer. This 
      +      sawAnyFields = true;
      +      if (ILE->getNumInits() > 0 &&
      +          CGM.getContext().getCanonicalType(curField->getType()) ==
      +            CGM.getContext().getCanonicalType(ILE->getInit(0)->getType()))
               break;
           }
       
      diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
      index aac6e8d64406..edd16087fd43 100644
      --- a/clang/lib/CodeGen/CodeGenTypes.cpp
      +++ b/clang/lib/CodeGen/CodeGenTypes.cpp
      @@ -518,6 +518,7 @@ void RecordOrganizer::layoutUnionFields(const ASTRecordLayout &RL) {
              Field != FieldEnd; ++Field) {
           // The offset should usually be zero, but bitfields could be strange
           uint64_t offset = RL.getFieldOffset(curField);
      +    CGT.ConvertTypeRecursive(Field->getType());
       
           if (Field->isBitField()) {
             Expr *BitWidth = Field->getBitWidth();
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index 8cf10ff3e2a7..9a4ab868719b 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -1879,7 +1879,8 @@ class InitListChecker {
                                         llvm::APSInt *NextElementIndex,
                                         unsigned &Index,
                                         InitListExpr *StructuredList,
      -                                  unsigned &StructuredIndex);
      +                                  unsigned &StructuredIndex,
      +                                  bool FinishSubobjectInit = true);
         InitListExpr *getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
                                                  QualType CurrentObjectType,
                                                  InitListExpr *StructuredList,
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 511a394d8f26..a3c858d0897d 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -500,7 +500,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
       
           CheckSubElementType(IList, Field->getType(), IList->getInit(Index), Index,
                               StructuredList, StructuredIndex);
      -    if (DeclType->isUnionType()) // FIXME: designated initializers?
      +    if (DeclType->isUnionType())
             break;
       
           ++Field;
      @@ -554,7 +554,8 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
                                             llvm::APSInt *NextElementIndex,
                                             unsigned &Index,
                                             InitListExpr *StructuredList,
      -                                      unsigned &StructuredIndex) {
      +                                      unsigned &StructuredIndex,
      +                                      bool FinishSubobjectInit) {
         if (D == DIE->designators_end()) {
           // Check the actual initialization for the designated object type.
           bool prevHadError = hadError;
      @@ -645,13 +646,8 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
       
           // All of the fields of a union are located at the same place in
           // the initializer list.
      -    // FIXME: Need to tell CodeGen which type to initialize to. ImplicitCastExpr?
      -    if (RT->getDecl()->isUnion() && FieldIndex != 0) {
      -      SemaRef->Diag(D->getStartLocation(), 
      -                    diag::warn_designator_into_union_broken_init)
      -        << SourceRange(D->getStartLocation(), DIE->getSourceRange().getEnd());
      +    if (RT->getDecl()->isUnion())
             FieldIndex = 0;
      -    }
       
           // Update the designator with the field declaration.
           D->setField(*Field);
      @@ -682,6 +678,9 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
             return false;
           }
       
      +    if (!FinishSubobjectInit)
      +      return false;
      +
           // Check the remaining fields within this class/struct/union subobject.
           bool prevHadError = hadError;
           CheckStructUnionTypes(IList, CurrentObjectType, Field, false, Index,
      @@ -713,63 +712,102 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
         }
       
         Expr *IndexExpr = 0;
      -  llvm::APSInt DesignatedIndex;
      -  if (D->isArrayDesignator())
      +  llvm::APSInt DesignatedStartIndex, DesignatedEndIndex;
      +  if (D->isArrayDesignator()) {
           IndexExpr = DIE->getArrayIndex(*D);
      -  else {
      +    
      +    bool ConstExpr 
      +      = IndexExpr->isIntegerConstantExpr(DesignatedStartIndex, SemaRef->Context);
      +    assert(ConstExpr && "Expression must be constant"); (void)ConstExpr;
      +    
      +    DesignatedEndIndex = DesignatedStartIndex;
      +  } else {
           assert(D->isArrayRangeDesignator() && "Need array-range designator");
      +    
      +    bool StartConstExpr
      +      = DIE->getArrayRangeStart(*D)->isIntegerConstantExpr(DesignatedStartIndex,
      +                                                           SemaRef->Context);
      +    assert(StartConstExpr && "Expression must be constant"); (void)StartConstExpr;
      +
      +    bool EndConstExpr
      +      = DIE->getArrayRangeEnd(*D)->isIntegerConstantExpr(DesignatedEndIndex,
      +                                                         SemaRef->Context);
      +    assert(EndConstExpr && "Expression must be constant"); (void)EndConstExpr;
      +    
           IndexExpr = DIE->getArrayRangeEnd(*D);
      -    SemaRef->Diag(D->getEllipsisLoc(), 
      -                  diag::warn_gnu_array_range_designator_unsupported)
      -      << SourceRange(D->getLBracketLoc(), D->getRBracketLoc());
      +
      +    if (DesignatedStartIndex.getZExtValue() != DesignatedEndIndex.getZExtValue())
      +      SemaRef->Diag(D->getEllipsisLoc(), 
      +                    diag::warn_gnu_array_range_designator_side_effects)
      +        << SourceRange(D->getLBracketLoc(), D->getRBracketLoc());
         }
       
      -  bool ConstExpr 
      -    = IndexExpr->isIntegerConstantExpr(DesignatedIndex, SemaRef->Context);
      -  assert(ConstExpr && "Expression must be constant"); (void)ConstExpr;
      -  
         if (isa(AT)) {
           llvm::APSInt MaxElements(cast(AT)->getSize(), false);
      -    DesignatedIndex.extOrTrunc(MaxElements.getBitWidth());
      -    DesignatedIndex.setIsUnsigned(MaxElements.isUnsigned());
      -    if (DesignatedIndex >= MaxElements) {
      +    DesignatedStartIndex.extOrTrunc(MaxElements.getBitWidth());
      +    DesignatedStartIndex.setIsUnsigned(MaxElements.isUnsigned());
      +    DesignatedEndIndex.extOrTrunc(MaxElements.getBitWidth());
      +    DesignatedEndIndex.setIsUnsigned(MaxElements.isUnsigned());
      +    if (DesignatedEndIndex >= MaxElements) {
             SemaRef->Diag(IndexExpr->getSourceRange().getBegin(),
                           diag::err_array_designator_too_large)
      -        << DesignatedIndex.toString(10) << MaxElements.toString(10)
      +        << DesignatedEndIndex.toString(10) << MaxElements.toString(10)
               << IndexExpr->getSourceRange();
             ++Index;
             return true;
           }
      +  } else {
      +    // Make sure the bit-widths and signedness match.
      +    if (DesignatedStartIndex.getBitWidth() > DesignatedEndIndex.getBitWidth())
      +      DesignatedEndIndex.extend(DesignatedStartIndex.getBitWidth());
      +    else if (DesignatedStartIndex.getBitWidth() < DesignatedEndIndex.getBitWidth())
      +      DesignatedStartIndex.extend(DesignatedEndIndex.getBitWidth());
      +    DesignatedStartIndex.setIsUnsigned(true);
      +    DesignatedEndIndex.setIsUnsigned(true);
         }
         
         // Make sure that our non-designated initializer list has space
         // for a subobject corresponding to this array element.
      -  unsigned ElementIndex = DesignatedIndex.getZExtValue();
      -  if (ElementIndex >= StructuredList->getNumInits())
      -    StructuredList->resizeInits(SemaRef->Context, ElementIndex + 1);
      -
      -  // Recurse to check later designated subobjects.
      -  QualType ElementType = AT->getElementType();
      -  if (CheckDesignatedInitializer(IList, DIE, ++D, ElementType, 0, 0, Index,
      -                                 StructuredList, ElementIndex))
      -    return true;
      +  if (DesignatedEndIndex.getZExtValue() >= StructuredList->getNumInits())
      +    StructuredList->resizeInits(SemaRef->Context, 
      +                                DesignatedEndIndex.getZExtValue() + 1);
      +
      +  // Repeatedly perform subobject initializations in the range
      +  // [DesignatedStartIndex, DesignatedEndIndex].
      +
      +  // Move to the next designator
      +  unsigned ElementIndex = DesignatedStartIndex.getZExtValue();
      +  unsigned OldIndex = Index;
      +  ++D;
      +  while (DesignatedStartIndex <= DesignatedEndIndex) {
      +    // Recurse to check later designated subobjects.
      +    QualType ElementType = AT->getElementType();
      +    Index = OldIndex;
      +    if (CheckDesignatedInitializer(IList, DIE, D, ElementType, 0, 0, Index,
      +                                   StructuredList, ElementIndex,
      +                                   (DesignatedStartIndex == DesignatedEndIndex)))
      +      return true;
       
      -  // Move to the next index in the array that we'll be initializing.
      -  ++DesignatedIndex;
      -  ElementIndex = DesignatedIndex.getZExtValue();
      +    // Move to the next index in the array that we'll be initializing.
      +    ++DesignatedStartIndex;
      +    ElementIndex = DesignatedStartIndex.getZExtValue();
      +  }
       
         // If this the first designator, our caller will continue checking
         // the rest of this array subobject.
         if (IsFirstDesignator) {
           if (NextElementIndex)
      -      *NextElementIndex = DesignatedIndex;
      +      *NextElementIndex = DesignatedStartIndex;
           StructuredIndex = ElementIndex;
           return false;
         }
      -    
      +  
      +  if (!FinishSubobjectInit)
      +    return false;
      +
         // Check the remaining elements within this array subobject.
         bool prevHadError = hadError;
      -  CheckArrayType(IList, CurrentObjectType, DesignatedIndex, true, Index,
      +  CheckArrayType(IList, CurrentObjectType, DesignatedStartIndex, true, Index,
                        StructuredList, ElementIndex);
         return hadError && !prevHadError;  
       }
      diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c
      index c9a0aa7f05bd..db099dd178ba 100644
      --- a/clang/test/Sema/designated-initializers.c
      +++ b/clang/test/Sema/designated-initializers.c
      @@ -19,7 +19,7 @@ int iarray2[10] = {
       
       int iarray3[10] = {
         [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}\
      -                // expected-warning{{GNU array-range designator extension is unsupported}}
      +                // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
       };
       
       struct point {
      @@ -45,8 +45,8 @@ struct point array[10] = {
       
       struct point array2[10] = {
         [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
      -  [4 ... 5].y = 2.0, // expected-warning{{GNU array-range designator extension is unsupported}}
      -  [4 ... 6] = { .x = 3, .y = 4.0 } // expected-warning{{GNU array-range designator extension is unsupported}}
      +  [4 ... 5].y = 2.0, // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
      +  [4 ... 6] = { .x = 3, .y = 4.0 } // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
       };
       
       struct point array3[10] = {
      @@ -117,7 +117,7 @@ struct disklabel_ops disklabel64_ops = {
       // PR clang/3378
       int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 };
       int a[]= { [sizeof(int)] = 0 };
      -int a2[]= { [0 ... sizeof(int)] = 0 }; // expected-warning{{GNU array-range designator extension is unsupported}}
      +int a2[]= { [0 ... sizeof(int)] = 0 }; // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
       
       // Test warnings about initializers overriding previous initializers
       struct X {
      @@ -138,4 +138,4 @@ void test() {
       }
       
       // FIXME: we need to 
      -union { char c; long l; } u1 = { .l = 0xFFFF }; // expected-warning{{designated initialization of union member is broken}}
      +union { char c; long l; } u1 = { .l = 0xFFFF };
      -- 
      GitLab
      
      
      From e6af7a028c7c44de0fc73a288aa606f09df2c335 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Wed, 28 Jan 2009 23:43:32 +0000
      Subject: [PATCH 392/682] Remove Expr::hasSideEffects. It doesn't work anyway
      
      llvm-svn: 63254
      ---
       clang/include/clang/AST/Expr.h | 4 ----
       clang/lib/AST/Expr.cpp         | 6 ------
       clang/lib/Sema/SemaInit.cpp    | 4 ++--
       3 files changed, 2 insertions(+), 12 deletions(-)
      
      diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
      index 861ac817ccac..54c764099921 100644
      --- a/clang/include/clang/AST/Expr.h
      +++ b/clang/include/clang/AST/Expr.h
      @@ -185,10 +185,6 @@ public:
         /// initializer, which can be emitted at compile-time.
         bool isConstantInitializer(ASTContext &Ctx) const;
         
      -  /// @brief Determines whether this expression (or any of its
      -  /// subexpressions) has side effects.
      -  bool hasSideEffects(ASTContext &Ctx) const;
      -
         /// EvalResult is a struct with detailed info about an evaluated expression.
         struct EvalResult {
           /// Val - This is the scalar value the expression can be folded to.
      diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
      index ed73bfae27b2..d96f734bf419 100644
      --- a/clang/lib/AST/Expr.cpp
      +++ b/clang/lib/AST/Expr.cpp
      @@ -758,12 +758,6 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const {
         return isEvaluatable(Ctx);
       }
       
      -bool Expr::hasSideEffects(ASTContext &Ctx) const {
      -  EvalResult Result;
      -  Evaluate(Result, Ctx);
      -  return Result.HasSideEffects;
      -}
      -
       /// isIntegerConstantExpr - this recursive routine will test if an expression is
       /// an integer constant expression. Note: With the introduction of VLA's in
       /// C99 the result of the sizeof operator is no longer always a constant
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index a3c858d0897d..66b938ff0713 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -845,7 +845,7 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
             << InitRange;
           SemaRef->Diag(ExistingInit->getSourceRange().getBegin(), 
                         diag::note_previous_initializer)
      -      << ExistingInit->hasSideEffects(SemaRef->Context)
      +      << /*FIXME:has side effects=*/0
             << ExistingInit->getSourceRange();
         }
       
      @@ -882,7 +882,7 @@ void InitListChecker::UpdateStructuredListElement(InitListExpr *StructuredList,
             << expr->getSourceRange();
           SemaRef->Diag(PrevInit->getSourceRange().getBegin(), 
                         diag::note_previous_initializer)
      -      << (int)PrevInit->hasSideEffects(SemaRef->Context)
      +      << /*FIXME:has side effects=*/0
             << PrevInit->getSourceRange();
         }
         
      -- 
      GitLab
      
      
      From 55ca1d38ea83d4be2349c2ddab4855e38ca16454 Mon Sep 17 00:00:00 2001
      From: Evan Cheng 
      Date: Thu, 29 Jan 2009 00:06:09 +0000
      Subject: [PATCH 393/682] Fix comment about removeRange.
      
      llvm-svn: 63255
      ---
       llvm/include/llvm/CodeGen/LiveInterval.h | 2 +-
       llvm/lib/CodeGen/LiveInterval.cpp        | 2 +-
       2 files changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h
      index 86aada3b80a7..4966a614d37f 100644
      --- a/llvm/include/llvm/CodeGen/LiveInterval.h
      +++ b/llvm/include/llvm/CodeGen/LiveInterval.h
      @@ -378,7 +378,7 @@ namespace llvm {
                     SmallVector &NewVNInfo);
       
           /// removeRange - Remove the specified range from this interval.  Note that
      -    /// the range must already be in this interval in its entirety.
      +    /// the range must be a single LiveRange in its entirety.
           void removeRange(unsigned Start, unsigned End, bool RemoveDeadValNo = false);
       
           void removeRange(LiveRange LR, bool RemoveDeadValNo = false) {
      diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp
      index ff430d71c7d7..4392652438ce 100644
      --- a/llvm/lib/CodeGen/LiveInterval.cpp
      +++ b/llvm/lib/CodeGen/LiveInterval.cpp
      @@ -246,7 +246,7 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) {
       
       
       /// removeRange - Remove the specified range from this interval.  Note that
      -/// the range must already be in this interval in its entirety.
      +/// the range must be in a single LiveRange in its entirety.
       void LiveInterval::removeRange(unsigned Start, unsigned End,
                                      bool RemoveDeadValNo) {
         // Find the LiveRange containing this span.
      -- 
      GitLab
      
      
      From dcfe56d489f9921a1d50b84b9fe7c3d49782eb1d Mon Sep 17 00:00:00 2001
      From: Steve Naroff 
      Date: Thu, 29 Jan 2009 00:07:50 +0000
      Subject: [PATCH 394/682] Refactor Sema::LookupDecl() into 2 functions:
       LookupDeclInScope() and LookupDeclInContext().
      
      The previous interface was very confusing. This is much more explicit, which will be easier to understand/optimize/convert.
      
      The plan is to eventually deprecate both of these functions. For now, I'm focused on performance.
      
      llvm-svn: 63256
      ---
       clang/lib/Sema/Sema.h           |  6 ++-
       clang/lib/Sema/SemaDecl.cpp     | 72 ++++++++++++++++++++-------------
       clang/lib/Sema/SemaDeclCXX.cpp  |  7 ++--
       clang/lib/Sema/SemaDeclObjC.cpp | 16 ++++----
       clang/lib/Sema/SemaExpr.cpp     |  8 ++--
       clang/lib/Sema/SemaExprCXX.cpp  |  2 +-
       clang/lib/Sema/SemaExprObjC.cpp |  6 +--
       clang/lib/Sema/SemaTemplate.cpp |  9 +++--
       8 files changed, 73 insertions(+), 53 deletions(-)
      
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index 9a4ab868719b..406eb2645075 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -783,8 +783,10 @@ public:
                                          LookupCriteria Criteria);
         LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS, 
                                       DeclarationName Name, LookupCriteria Criteria);
      -  LookupResult LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
      -                          const DeclContext *LookupCtx = 0,
      +  LookupResult LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
      +                                 bool LookInParent = true);
      +  LookupResult LookupDeclInContext(DeclarationName Name, unsigned NSI,
      +                          const DeclContext *LookupCtx,
                                 bool LookInParent = true);
       
         bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 79efc7df9c0c..54f84cf40ee5 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -34,13 +34,16 @@ using namespace clang;
       Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S,
                                       const CXXScopeSpec *SS) {
         DeclContext *DC = 0;
      +  
         if (SS) {
           if (SS->isInvalid())
             return 0;
           DC = static_cast(SS->getScopeRep());
         }
      -  LookupResult Result = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC);
      -
      +  LookupResult Result = DC ? 
      +                 LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
      +                 LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
      +                   
         Decl *IIDecl = 0;
         switch (Result.getKind()) {
         case LookupResult::NotFound:
      @@ -215,7 +218,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
       ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
         // The third "scope" argument is 0 since we aren't enabling lazy built-in
         // creation from this context.
      -  Decl *IDecl = LookupDecl(Id, Decl::IDNS_Ordinary, 0);
      +  Decl *IDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, 0);
         
         return dyn_cast_or_null(IDecl);
       }
      @@ -252,7 +255,7 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
         return S;
       }
       
      -/// LookupDecl - Look up the inner-most declaration in the specified
      +/// LookupDeclInScope - Look up the inner-most declaration in the specified
       /// namespace. NamespaceNameOnly - during lookup only namespace names
       /// are considered as required in C++ [basic.lookup.udir] 3.4.6.p1
       /// 'When looking up a namespace-name in a using-directive or
      @@ -261,9 +264,8 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
       /// Note: The use of this routine is deprecated. Please use
       /// LookupName, LookupQualifiedName, or LookupParsedName instead.
       Sema::LookupResult
      -Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
      -                 const DeclContext *LookupCtx,
      -                 bool LookInParent) {
      +Sema::LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
      +                        bool LookInParent) {
         LookupCriteria::NameKind Kind;
         if (NSI == Decl::IDNS_Ordinary) {
           Kind = LookupCriteria::Ordinary;
      @@ -273,24 +275,37 @@ Sema::LookupDecl(DeclarationName Name, unsigned NSI, Scope *S,
           assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
           Kind = LookupCriteria::Member;
         }
      -  
      -  if (LookupCtx)
      -    return LookupQualifiedName(const_cast(LookupCtx), Name, 
      -                               LookupCriteria(Kind, !LookInParent,
      -                                              getLangOptions().CPlusPlus));
      -
         // Unqualified lookup
         return LookupName(S, Name, 
                           LookupCriteria(Kind, !LookInParent,
                                          getLangOptions().CPlusPlus));
       }
       
      +Sema::LookupResult
      +Sema::LookupDeclInContext(DeclarationName Name, unsigned NSI,
      +                          const DeclContext *LookupCtx,
      +                          bool LookInParent) {
      +  assert(LookupCtx && "LookupDeclInContext(): Missing DeclContext");
      +  LookupCriteria::NameKind Kind;
      +  if (NSI == Decl::IDNS_Ordinary) {
      +    Kind = LookupCriteria::Ordinary;
      +  } else if (NSI == Decl::IDNS_Tag) 
      +    Kind = LookupCriteria::Tag;
      +  else {
      +    assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
      +    Kind = LookupCriteria::Member;
      +  }
      +  return LookupQualifiedName(const_cast(LookupCtx), Name, 
      +                             LookupCriteria(Kind, !LookInParent,
      +                                            getLangOptions().CPlusPlus));
      +}
      +
       void Sema::InitBuiltinVaListType() {
         if (!Context.getBuiltinVaListType().isNull())
           return;
         
         IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
      -  Decl *VaDecl = LookupDecl(VaIdent, Decl::IDNS_Ordinary, TUScope);
      +  Decl *VaDecl = LookupDeclInScope(VaIdent, Decl::IDNS_Ordinary, TUScope);
         TypedefDecl *VaTypedef = cast(VaDecl);
         Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
       }
      @@ -339,7 +354,7 @@ NamespaceDecl *Sema::GetStdNamespace() {
         if (!StdNamespace) {
           IdentifierInfo *StdIdent = &PP.getIdentifierTable().get("std");
           DeclContext *Global = Context.getTranslationUnitDecl();
      -    Decl *Std = LookupDecl(StdIdent, Decl::IDNS_Ordinary, 0, Global);
      +    Decl *Std = LookupDeclInContext(StdIdent, Decl::IDNS_Ordinary, Global);
           StdNamespace = dyn_cast_or_null(Std);
         }
         return StdNamespace;
      @@ -783,8 +798,8 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
                                      FEnd = AnonRecord->field_end();
              F != FEnd; ++F) {
           if ((*F)->getDeclName()) {
      -      Decl *PrevDecl = LookupDecl((*F)->getDeclName(), Decl::IDNS_Ordinary,
      -                                  S, Owner, false);
      +      Decl *PrevDecl = LookupDeclInContext((*F)->getDeclName(), 
      +                         Decl::IDNS_Ordinary, Owner, false);
             if (PrevDecl && !isa(PrevDecl)) {
               // C++ [class.union]p2:
               //   The names of the members of an anonymous union shall be
      @@ -1235,10 +1250,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
         // See if this is a redefinition of a variable in the same scope.
         if (!D.getCXXScopeSpec().isSet()) {
           DC = CurContext;
      -    PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S);
      +    PrevDecl = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
         } else { // Something like "int foo::x;"
           DC = static_cast(D.getCXXScopeSpec().getScopeRep());
      -    PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
      +    PrevDecl = DC ? LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC)
      +                  : LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
       
           // C++ 7.3.1.2p2:
           // Members (including explicit specializations of templates) of a named
      @@ -1727,7 +1743,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
               << D.getCXXScopeSpec().getRange();
             InvalidDecl = true;
               
      -      PrevDecl = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
      +      PrevDecl = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC);
             if (!PrevDecl) {
               // Nothing to suggest.
             } else if (OverloadedFunctionDecl *Ovl 
      @@ -2582,7 +2598,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
         // among each other.  Here they can only shadow globals, which is ok.
         IdentifierInfo *II = D.getIdentifier();
         if (II) {
      -    if (Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S)) {
      +    if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) {
             if (PrevDecl->isTemplateParameter()) {
               // Maybe we will complain about the shadowed template parameter.
               DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
      @@ -2873,8 +2889,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
       
           DC = static_cast(SS.getScopeRep());
           // Look-up name inside 'foo::'.
      -    PrevDecl = dyn_cast_or_null(LookupDecl(Name, Decl::IDNS_Tag,S,DC)
      -                                           .getAsDecl());
      +    PrevDecl = dyn_cast_or_null(
      +                 LookupDeclInContext(Name, Decl::IDNS_Tag, DC).getAsDecl());
       
           // A tag 'foo::bar' must already exist.
           if (PrevDecl == 0) {
      @@ -2885,7 +2901,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
         } else if (Name) {
           // If this is a named struct, check to see if there was a previous forward
           // declaration or definition.
      -    PrevDecl = dyn_cast_or_null(LookupDecl(Name, Decl::IDNS_Tag,S)
      +    PrevDecl = dyn_cast_or_null(LookupDeclInScope(Name, 
      +                                                             Decl::IDNS_Tag,S)
                                                  .getAsDecl());
       
           if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
      @@ -3273,7 +3290,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
       
         if (II) {
           Decl *PrevDecl 
      -      = LookupDecl(II, Decl::IDNS_Member, S, 0, false);
      +      = LookupDeclInScope(II, Decl::IDNS_Member, S, false);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      @@ -3365,8 +3382,7 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S,
                                                    (Expr *)BitfieldWidth);
         
         if (II) {
      -    Decl *PrevDecl 
      -      = LookupDecl(II, Decl::IDNS_Member, S, 0, false);
      +    Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Member, S, false);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      @@ -3542,7 +3558,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
         
         // Verify that there isn't already something declared with this name in this
         // scope.
      -  Decl *PrevDecl = LookupDecl(Id, Decl::IDNS_Ordinary, S);
      +  Decl *PrevDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, S);
         if (PrevDecl && PrevDecl->isTemplateParameter()) {
           // Maybe we will complain about the shadowed template parameter.
           DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
      diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
      index 0e08eb3fd802..a61184f66938 100644
      --- a/clang/lib/Sema/SemaDeclCXX.cpp
      +++ b/clang/lib/Sema/SemaDeclCXX.cpp
      @@ -1376,9 +1376,8 @@ Sema::DeclTy *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
           // original-namespace-definition is the name of the namespace. Subsequently
           // in that declarative region, it is treated as an original-namespace-name.
       
      -    Decl *PrevDecl =
      -      LookupDecl(II, Decl::IDNS_Ordinary, DeclRegionScope, 0,
      -                /*LookupInParent=*/false);
      +    Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, DeclRegionScope, 
      +                                       /*LookupInParent=*/false);
           
           if (NamespaceDecl *OrigNS = dyn_cast_or_null(PrevDecl)) {
             // This is an extended namespace definition.
      @@ -2181,7 +2180,7 @@ Sema::DeclTy *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D)
         // FIXME: Need to check for abstract classes.
       
         IdentifierInfo *II = D.getIdentifier();
      -  if (Decl *PrevDecl = LookupDecl(II, Decl::IDNS_Ordinary, S)) {
      +  if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) {
           // The scope should be freshly made just for us. There is just no way
           // it contains any previous declaration.
           assert(!S->isDeclScope(PrevDecl));
      diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
      index b636e2994557..fcf9a92acab2 100644
      --- a/clang/lib/Sema/SemaDeclObjC.cpp
      +++ b/clang/lib/Sema/SemaDeclObjC.cpp
      @@ -65,7 +65,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
         assert(ClassName && "Missing class identifier");
         
         // Check for another declaration kind with the same name.
      -  Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
         if (PrevDecl && PrevDecl->isTemplateParameter()) {
           // Maybe we will complain about the shadowed template parameter.
           DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
      @@ -108,7 +108,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
         if (SuperName) {
           ObjCInterfaceDecl* SuperClassEntry = 0;
           // Check if a different kind of symbol declared in this scope.
      -    PrevDecl = LookupDecl(SuperName, Decl::IDNS_Ordinary, TUScope);
      +    PrevDecl = LookupDeclInScope(SuperName, Decl::IDNS_Ordinary, TUScope);
           if (PrevDecl && !isa(PrevDecl)) {
             Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
             Diag(PrevDecl->getLocation(), diag::note_previous_definition);
      @@ -150,7 +150,7 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
                                                  IdentifierInfo *ClassName,
                                                  SourceLocation ClassLocation) {
         // Look for previous declaration of alias name
      -  Decl *ADecl = LookupDecl(AliasName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *ADecl = LookupDeclInScope(AliasName, Decl::IDNS_Ordinary, TUScope);
         if (ADecl) {
           if (isa(ADecl))
             Diag(AliasLocation, diag::warn_previous_alias_decl);
      @@ -160,13 +160,13 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
           return 0;
         }
         // Check for class declaration
      -  Decl *CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
         if (const TypedefDecl *TDecl = dyn_cast_or_null(CDeclU)) {
           QualType T = TDecl->getUnderlyingType();
           if (T->isObjCInterfaceType()) {
             if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) {
               ClassName = IDecl->getIdentifier();
      -        CDeclU = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
      +        CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
             }
           }
         }
      @@ -536,7 +536,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
                             SourceLocation SuperClassLoc) {
         ObjCInterfaceDecl* IDecl = 0;
         // Check for another declaration kind with the same name.
      -  Decl *PrevDecl = LookupDecl(ClassName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
         if (PrevDecl && !isa(PrevDecl)) {
           Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
           Diag(PrevDecl->getLocation(), diag::note_previous_definition);
      @@ -552,7 +552,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
         ObjCInterfaceDecl* SDecl = 0;
         if (SuperClassname) {
           // Check if a different kind of symbol declared in this scope.
      -    PrevDecl = LookupDecl(SuperClassname, Decl::IDNS_Ordinary, TUScope);
      +    PrevDecl = LookupDeclInScope(SuperClassname, Decl::IDNS_Ordinary, TUScope);
           if (PrevDecl && !isa(PrevDecl)) {
             Diag(SuperClassLoc, diag::err_redefinition_different_kind)
               << SuperClassname;
      @@ -910,7 +910,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
         
         for (unsigned i = 0; i != NumElts; ++i) {
           // Check for another declaration kind with the same name.
      -    Decl *PrevDecl = LookupDecl(IdentList[i], Decl::IDNS_Ordinary, TUScope);
      +    Decl *PrevDecl = LookupDeclInScope(IdentList[i], Decl::IDNS_Ordinary, TUScope);
           if (PrevDecl && PrevDecl->isTemplateParameter()) {
             // Maybe we will complain about the shadowed template parameter.
             DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
      diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
      index 064b8517f7c3..2eb4605623bb 100644
      --- a/clang/lib/Sema/SemaExpr.cpp
      +++ b/clang/lib/Sema/SemaExpr.cpp
      @@ -561,9 +561,9 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
           DeclContext *DC = static_cast(SS->getScopeRep());
           if (DC == 0)
             return ExprError();
      -    Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S, DC);
      +    Lookup = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC);
         } else
      -    Lookup = LookupDecl(Name, Decl::IDNS_Ordinary, S);
      +    Lookup = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
       
         if (Lookup.isAmbiguous()) {
           DiagnoseAmbiguousLookup(Lookup, Name, Loc,
      @@ -4031,9 +4031,9 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
           // Get the decl corresponding to this.
           RecordDecl *RD = RC->getDecl();
           FieldDecl *MemberDecl 
      -      = dyn_cast_or_null(LookupDecl(OC.U.IdentInfo, 
      +      = dyn_cast_or_null(LookupDeclInContext(OC.U.IdentInfo, 
                                                      Decl::IDNS_Ordinary,
      -                                               S, RD, false).getAsDecl());
      +                                               RD, false).getAsDecl());
           if (!MemberDecl)
             return Diag(BuiltinLoc, diag::err_typecheck_no_member)
              << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd);
      diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
      index 55317db5024b..743fa12b1868 100644
      --- a/clang/lib/Sema/SemaExprCXX.cpp
      +++ b/clang/lib/Sema/SemaExprCXX.cpp
      @@ -61,7 +61,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
           return Diag(OpLoc, diag::err_need_header_before_typeid);
         
         IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
      -  Decl *TypeInfoDecl = LookupDecl(TypeInfoII, Decl::IDNS_Tag, 0, StdNs);
      +  Decl *TypeInfoDecl = LookupDeclInContext(TypeInfoII, Decl::IDNS_Tag, StdNs);
         RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null(TypeInfoDecl);
         if (!TypeInfoRecordDecl)
           return Diag(OpLoc, diag::err_need_header_before_typeid);
      diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
      index eff259d8faf5..a19a1d16d0e6 100644
      --- a/clang/lib/Sema/SemaExprObjC.cpp
      +++ b/clang/lib/Sema/SemaExprObjC.cpp
      @@ -53,7 +53,7 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
           // Initialize the constant string interface lazily. This assumes
           // the NSConstantString interface is seen in this translation unit.
           IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
      -    Decl *IFace = LookupDecl(NSIdent, Decl::IDNS_Ordinary, TUScope);
      +    Decl *IFace = LookupDeclInScope(NSIdent, Decl::IDNS_Ordinary, TUScope);
           ObjCInterfaceDecl *strIFace = dyn_cast_or_null(IFace);
           if (strIFace)
             Context.setObjCConstantStringInterface(strIFace);
      @@ -210,7 +210,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
           } else {
             // 'super' has been used outside a method context. If a variable named
             // 'super' has been declared, redirect. If not, produce a diagnostic.
      -      Decl *SuperDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, S);
      +      Decl *SuperDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, S);
             ValueDecl *VD = dyn_cast_or_null(SuperDecl);
             if (VD) {
               ExprResult ReceiverExpr = new DeclRefExpr(VD, VD->getType(), 
      @@ -235,7 +235,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
         //
         // If necessary, the following lookup could move to getObjCInterfaceDecl().
         if (!ClassDecl) {
      -    Decl *IDecl = LookupDecl(receiverName, Decl::IDNS_Ordinary, 0);
      +    Decl *IDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, 0);
           if (TypedefDecl *OCTD = dyn_cast_or_null(IDecl)) {
             const ObjCInterfaceType *OCIT;
             OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
      diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
      index f448664615ad..7ecac0027707 100644
      --- a/clang/lib/Sema/SemaTemplate.cpp
      +++ b/clang/lib/Sema/SemaTemplate.cpp
      @@ -26,12 +26,15 @@ using namespace clang;
       Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S,
                                          const CXXScopeSpec *SS) {
         DeclContext *DC = 0;
      +  
         if (SS) {
           if (SS->isInvalid())
             return 0;
           DC = static_cast(SS->getScopeRep());
         }
      -  Decl *IIDecl = LookupDecl(&II, Decl::IDNS_Ordinary, S, DC, false);
      +  Decl *IIDecl = DC ? 
      +                 LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC, false) :
      +                 LookupDeclInScope(&II, Decl::IDNS_Ordinary, S, false);
       
         if (IIDecl) {
           // FIXME: We need to represent templates via some kind of
      @@ -93,7 +96,7 @@ Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
         bool Invalid = false;
       
         if (ParamName) {
      -    Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
      +    Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S);
           if (PrevDecl && PrevDecl->isTemplateParameter())
             Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
       							   PrevDecl);
      @@ -129,7 +132,7 @@ Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
       
         IdentifierInfo *ParamName = D.getIdentifier();
         if (ParamName) {
      -    Decl *PrevDecl = LookupDecl(ParamName, Decl::IDNS_Tag, S);
      +    Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S);
           if (PrevDecl && PrevDecl->isTemplateParameter())
             Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
       							   PrevDecl);
      -- 
      GitLab
      
      
      From f6d2752f1272a679378ddd6416810144b3225ad7 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 00:39:20 +0000
      Subject: [PATCH 395/682] Eliminate infinite looping in a wacky case with
       designated initializers. Simplifies (somewhat) the actually checking of the
       initializer expression following the designators
      
      llvm-svn: 63257
      ---
       clang/lib/Sema/Sema.h                     |  4 +--
       clang/lib/Sema/SemaInit.cpp               | 41 +++++++++++++----------
       clang/test/Sema/designated-initializers.c | 10 +++++-
       3 files changed, 35 insertions(+), 20 deletions(-)
      
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index 406eb2645075..ad21e7d271c6 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -1853,12 +1853,12 @@ class InitListChecker {
                                    InitListExpr *StructuredInitList,
                                    unsigned &StructuredInitIndex);
         void CheckSubElementType(InitListExpr *IList, QualType ElemType, 
      -                           Expr *expr, unsigned &Index,
      +                           unsigned &Index,
                                  InitListExpr *StructuredInitList,
                                  unsigned &StructuredInitIndex);
         // FIXME: Does DeclType need to be a reference type?
         void CheckScalarType(InitListExpr *IList, QualType &DeclType, 
      -                       Expr *expr, unsigned &Index,
      +                       unsigned &Index,
                              InitListExpr *StructuredInitList,
                              unsigned &StructuredInitIndex);
         void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index,
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 66b938ff0713..b78fc7b1e629 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -188,7 +188,7 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
                                                   InitListExpr *StructuredList,
                                                   unsigned &StructuredIndex) {
         if (DeclType->isScalarType()) {
      -    CheckScalarType(IList, DeclType, 0, Index, StructuredList, StructuredIndex);
      +    CheckScalarType(IList, DeclType, Index, StructuredList, StructuredIndex);
         } else if (DeclType->isVectorType()) {
           CheckVectorType(IList, DeclType, Index, StructuredList, StructuredIndex);
         } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
      @@ -221,10 +221,10 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
       
       void InitListChecker::CheckSubElementType(InitListExpr *IList,
                                                 QualType ElemType, 
      -                                          Expr *expr,
                                                 unsigned &Index,
                                                 InitListExpr *StructuredList,
                                                 unsigned &StructuredIndex) {
      +  Expr *expr = IList->getInit(Index);
         if (InitListExpr *SubInitList = dyn_cast(expr)) {
           unsigned newIndex = 0;
           unsigned newStructuredIndex = 0;
      @@ -242,8 +242,7 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList,
           UpdateStructuredListElement(StructuredList, StructuredIndex, lit);
           ++Index;
         } else if (ElemType->isScalarType()) {
      -    CheckScalarType(IList, ElemType, expr, Index, StructuredList, 
      -                    StructuredIndex);
      +    CheckScalarType(IList, ElemType, Index, StructuredList, StructuredIndex);
         } else if (expr->getType()->getAsRecordType() &&
                    SemaRef->Context.typesAreCompatible(
                      expr->getType().getUnqualifiedType(),
      @@ -259,12 +258,11 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList,
       }
       
       void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
      -                                      Expr *expr, unsigned &Index,
      +                                      unsigned &Index,
                                             InitListExpr *StructuredList,
                                             unsigned &StructuredIndex) {
         if (Index < IList->getNumInits()) {
      -    if (!expr)
      -      expr = IList->getInit(Index);
      +    Expr *expr = IList->getInit(Index);
           if (isa(expr)) {
             SemaRef->Diag(IList->getLocStart(),
                           diag::err_many_braces_around_scalar_init)
      @@ -288,12 +286,7 @@ void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType,
             hadError = true; // types weren't compatible.
           else if (savExpr != expr) {
             // The type was promoted, update initializer list.
      -      if (DesignatedInitExpr *DIE 
      -            = dyn_cast(IList->getInit(Index)))
      -        DIE->setInit(expr);
      -      else
      -        IList->setInit(Index, expr);
      -
      +      IList->setInit(Index, expr);
           }
           if (hadError)
             ++StructuredIndex;
      @@ -323,7 +316,7 @@ void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType,
             // Don't attempt to go past the end of the init list
             if (Index >= IList->getNumInits())
               break;
      -      CheckSubElementType(IList, elementType, IList->getInit(Index), Index,
      +      CheckSubElementType(IList, elementType, Index,
                                 StructuredList, StructuredIndex);
           }
         }
      @@ -417,7 +410,7 @@ void InitListChecker::CheckArrayType(InitListExpr *IList, QualType &DeclType,
             break;
       
           // Check this element.
      -    CheckSubElementType(IList, elementType, IList->getInit(Index), Index,
      +    CheckSubElementType(IList, elementType, Index,
                               StructuredList, StructuredIndex);
           ++elementIndex;
       
      @@ -498,7 +491,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
             continue;
           }
       
      -    CheckSubElementType(IList, Field->getType(), IList->getInit(Index), Index,
      +    CheckSubElementType(IList, Field->getType(), Index,
                               StructuredList, StructuredIndex);
           if (DeclType->isUnionType())
             break;
      @@ -559,8 +552,22 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
         if (D == DIE->designators_end()) {
           // Check the actual initialization for the designated object type.
           bool prevHadError = hadError;
      -    CheckSubElementType(IList, CurrentObjectType, DIE->getInit(), Index,
      +
      +    // Temporarily remove the designator expression from the
      +    // initializer list that the child calls see, so that we don't try
      +    // to re-process the designator.
      +    unsigned OldIndex = Index;
      +    IList->setInit(OldIndex, DIE->getInit());
      +
      +    CheckSubElementType(IList, CurrentObjectType, Index,
                               StructuredList, StructuredIndex);
      +
      +    // Restore the designated initializer expression in the syntactic
      +    // form of the initializer list.
      +    if (IList->getInit(OldIndex) != DIE->getInit())
      +      DIE->setInit(IList->getInit(OldIndex));
      +    IList->setInit(OldIndex, DIE);
      +
           return hadError && !prevHadError;
         }
       
      diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c
      index db099dd178ba..5c61faa66794 100644
      --- a/clang/test/Sema/designated-initializers.c
      +++ b/clang/test/Sema/designated-initializers.c
      @@ -137,5 +137,13 @@ void test() {
         };
       }
       
      -// FIXME: we need to 
      +// FIXME: How do we test that this initializes the long properly?
       union { char c; long l; } u1 = { .l = 0xFFFF };
      +
      +extern float global_float;
      +
      +struct XX { int a, *b; };
      +struct XY { int before; struct XX xx, *xp; float* after; } xy[] = {
      +  0, 0, &xy[0].xx.a, &xy[0].xx, &global_float,
      +  [1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float
      +};
      -- 
      GitLab
      
      
      From 85df8d82c74c5d59e11e2e764a7a5ca4bb3f1bcc Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 00:45:39 +0000
      Subject: [PATCH 396/682] Move InitListChecker out of Sema.h
      
      llvm-svn: 63258
      ---
       clang/lib/Sema/Sema.h       | 70 +---------------------------------
       clang/lib/Sema/SemaDecl.cpp |  8 ++--
       clang/lib/Sema/SemaInit.cpp | 76 +++++++++++++++++++++++++++++++++++++
       3 files changed, 80 insertions(+), 74 deletions(-)
      
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index ad21e7d271c6..f14aba6a4f5f 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -19,7 +19,6 @@
       #include "CXXFieldCollector.h"
       #include "SemaOverload.h"
       #include "clang/AST/DeclBase.h"
      -#include "clang/AST/Expr.h"
       #include "clang/Parse/Action.h"
       #include "clang/Basic/DiagnosticSema.h"
       #include "llvm/ADT/SmallVector.h"
      @@ -28,7 +27,6 @@
       #include "llvm/ADT/OwningPtr.h"
       #include 
       #include 
      -#include 
       
       namespace llvm {
         class APSInt;
      @@ -1720,6 +1718,7 @@ public:
         bool CheckInitializerTypes(Expr *&simpleInit_or_initList, QualType &declType,
                                    SourceLocation InitLoc,DeclarationName InitEntity,
                                    bool DirectInit);
      +  bool CheckInitList(InitListExpr *&InitList, QualType &DeclType);
         bool CheckSingleInitializer(Expr *&simpleInit, QualType declType,
                                     bool DirectInit);
         bool CheckForConstantInitializer(Expr *e, QualType t);
      @@ -1835,73 +1834,6 @@ private:
         void CheckFloatComparison(SourceLocation loc, Expr* lex, Expr* rex);
       };
       
      -class InitListChecker {
      -  Sema *SemaRef;
      -  bool hadError;
      -  std::map SyntacticToSemantic;
      -  InitListExpr *FullyStructuredList;
      -  
      -  void CheckImplicitInitList(InitListExpr *ParentIList, QualType T, 
      -                             unsigned &Index, InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      -  void CheckExplicitInitList(InitListExpr *IList, QualType &T,
      -                             unsigned &Index, InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      -  void CheckListElementTypes(InitListExpr *IList, QualType &DeclType, 
      -                             bool SubobjectIsDesignatorContext, 
      -                             unsigned &Index,
      -                             InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      -  void CheckSubElementType(InitListExpr *IList, QualType ElemType, 
      -                           unsigned &Index,
      -                           InitListExpr *StructuredInitList,
      -                           unsigned &StructuredInitIndex);
      -  // FIXME: Does DeclType need to be a reference type?
      -  void CheckScalarType(InitListExpr *IList, QualType &DeclType, 
      -                       unsigned &Index,
      -                       InitListExpr *StructuredInitList,
      -                       unsigned &StructuredInitIndex);
      -  void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index,
      -                       InitListExpr *StructuredInitList,
      -                       unsigned &StructuredInitIndex);
      -  void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, 
      -                             RecordDecl::field_iterator Field, 
      -                             bool SubobjectIsDesignatorContext, unsigned &Index,
      -                             InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      -  void CheckArrayType(InitListExpr *IList, QualType &DeclType, 
      -                      llvm::APSInt elementIndex, 
      -                      bool SubobjectIsDesignatorContext, unsigned &Index,
      -                      InitListExpr *StructuredInitList,
      -                      unsigned &StructuredInitIndex);
      -  bool CheckDesignatedInitializer(InitListExpr *IList, DesignatedInitExpr *DIE, 
      -                                  DesignatedInitExpr::designators_iterator D,
      -                                  QualType &CurrentObjectType, 
      -                                  RecordDecl::field_iterator *NextField,
      -                                  llvm::APSInt *NextElementIndex,
      -                                  unsigned &Index,
      -                                  InitListExpr *StructuredList,
      -                                  unsigned &StructuredIndex,
      -                                  bool FinishSubobjectInit = true);
      -  InitListExpr *getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
      -                                           QualType CurrentObjectType,
      -                                           InitListExpr *StructuredList,
      -                                           unsigned StructuredIndex,
      -                                           SourceRange InitRange);
      -  void UpdateStructuredListElement(InitListExpr *StructuredInitList,
      -                                   unsigned &StructuredInitIndex,
      -                                   Expr *expr);
      -  int numArrayElements(QualType DeclType);
      -  int numStructUnionElements(QualType DeclType);
      -public:
      -  InitListChecker(Sema *S, InitListExpr *IL, QualType &T);
      -  bool HadError() { return hadError; }
      -
      -  // @brief Retrieves the fully-structured initializer list used for
      -  // semantic analysis and code generation.
      -  InitListExpr *getFullyStructuredList() const { return FullyStructuredList; }
      -};
      -
       /// BlockSemaInfo - When a block is being parsed, this contains information
       /// about the block.  It is pointed to from Sema::CurBlock.
       struct BlockSemaInfo {
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 54f84cf40ee5..77f99e848f19 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -1150,11 +1150,9 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
           }
         }
       
      -  InitListChecker CheckInitList(this, InitList, DeclType);
      -  if (!CheckInitList.HadError())
      -    Init = CheckInitList.getFullyStructuredList();
      -
      -  return CheckInitList.HadError();
      +  bool hadError = CheckInitList(InitList, DeclType);
      +  Init = InitList;
      +  return hadError;
       }
       
       /// GetNameForDeclarator - Determine the full declaration name for the
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index b78fc7b1e629..c2539913ce39 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -17,8 +17,76 @@
       #include "clang/AST/Expr.h"
       #include "clang/AST/ExprCXX.h"
       #include "clang/Basic/DiagnosticSema.h"
      +#include 
       using namespace clang;
       
      +class InitListChecker {
      +  Sema *SemaRef;
      +  bool hadError;
      +  std::map SyntacticToSemantic;
      +  InitListExpr *FullyStructuredList;
      +  
      +  void CheckImplicitInitList(InitListExpr *ParentIList, QualType T, 
      +                             unsigned &Index, InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
      +  void CheckExplicitInitList(InitListExpr *IList, QualType &T,
      +                             unsigned &Index, InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
      +  void CheckListElementTypes(InitListExpr *IList, QualType &DeclType, 
      +                             bool SubobjectIsDesignatorContext, 
      +                             unsigned &Index,
      +                             InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
      +  void CheckSubElementType(InitListExpr *IList, QualType ElemType, 
      +                           unsigned &Index,
      +                           InitListExpr *StructuredInitList,
      +                           unsigned &StructuredInitIndex);
      +  // FIXME: Does DeclType need to be a reference type?
      +  void CheckScalarType(InitListExpr *IList, QualType &DeclType, 
      +                       unsigned &Index,
      +                       InitListExpr *StructuredInitList,
      +                       unsigned &StructuredInitIndex);
      +  void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index,
      +                       InitListExpr *StructuredInitList,
      +                       unsigned &StructuredInitIndex);
      +  void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, 
      +                             RecordDecl::field_iterator Field, 
      +                             bool SubobjectIsDesignatorContext, unsigned &Index,
      +                             InitListExpr *StructuredInitList,
      +                             unsigned &StructuredInitIndex);
      +  void CheckArrayType(InitListExpr *IList, QualType &DeclType, 
      +                      llvm::APSInt elementIndex, 
      +                      bool SubobjectIsDesignatorContext, unsigned &Index,
      +                      InitListExpr *StructuredInitList,
      +                      unsigned &StructuredInitIndex);
      +  bool CheckDesignatedInitializer(InitListExpr *IList, DesignatedInitExpr *DIE, 
      +                                  DesignatedInitExpr::designators_iterator D,
      +                                  QualType &CurrentObjectType, 
      +                                  RecordDecl::field_iterator *NextField,
      +                                  llvm::APSInt *NextElementIndex,
      +                                  unsigned &Index,
      +                                  InitListExpr *StructuredList,
      +                                  unsigned &StructuredIndex,
      +                                  bool FinishSubobjectInit = true);
      +  InitListExpr *getStructuredSubobjectInit(InitListExpr *IList, unsigned Index,
      +                                           QualType CurrentObjectType,
      +                                           InitListExpr *StructuredList,
      +                                           unsigned StructuredIndex,
      +                                           SourceRange InitRange);
      +  void UpdateStructuredListElement(InitListExpr *StructuredInitList,
      +                                   unsigned &StructuredInitIndex,
      +                                   Expr *expr);
      +  int numArrayElements(QualType DeclType);
      +  int numStructUnionElements(QualType DeclType);
      +public:
      +  InitListChecker(Sema *S, InitListExpr *IL, QualType &T);
      +  bool HadError() { return hadError; }
      +
      +  // @brief Retrieves the fully-structured initializer list used for
      +  // semantic analysis and code generation.
      +  InitListExpr *getFullyStructuredList() const { return FullyStructuredList; }
      +};
      +
       /// Recursively replaces NULL values within the given initializer list
       /// with expressions that perform value-initialization of the
       /// appropriate type.
      @@ -1003,3 +1071,11 @@ Sema::OwningExprResult Sema::ActOnDesignatedInitializer(Designation &Desig,
                                        static_cast(Init.release()));
         return Owned(DIE);
       }
      +
      +bool Sema::CheckInitList(InitListExpr *&InitList, QualType &DeclType) {
      +  InitListChecker CheckInitList(this, InitList, DeclType);
      +  if (!CheckInitList.HadError())
      +    InitList = CheckInitList.getFullyStructuredList();
      +
      +  return CheckInitList.HadError();
      +}
      -- 
      GitLab
      
      
      From 839acbb0896fbd2f7e3daade672bc058cd4b7b46 Mon Sep 17 00:00:00 2001
      From: Dale Johannesen 
      Date: Thu, 29 Jan 2009 00:47:48 +0000
      Subject: [PATCH 397/682] Add DebugLoc-sensitive versions of many node creation
       functions.  Currently omitted:  memcpy, memmove, memset.
      
      llvm-svn: 63259
      ---
       llvm/include/llvm/CodeGen/SelectionDAG.h      |  89 ++++
       .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 458 ++++++++++++++++++
       2 files changed, 547 insertions(+)
      
      diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
      index 739f4d9459d2..a06158a39b2d 100644
      --- a/llvm/include/llvm/CodeGen/SelectionDAG.h
      +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
      @@ -307,14 +307,19 @@ public:
           return getConstantPool(C, VT, Align, Offset, true);
         }
         SDValue getBasicBlock(MachineBasicBlock *MBB);
      +  SDValue getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl);
         SDValue getExternalSymbol(const char *Sym, MVT VT);
      +  SDValue getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
         SDValue getTargetExternalSymbol(const char *Sym, MVT VT);
      +  SDValue getTargetExternalSymbol(const char *Sym, DebugLoc dl, MVT VT);
         SDValue getArgFlags(ISD::ArgFlagsTy Flags);
         SDValue getValueType(MVT);
         SDValue getRegister(unsigned Reg, MVT VT);
         SDValue getDbgStopPoint(SDValue Root, unsigned Line, unsigned Col,
                                 Value *CU);
         SDValue getLabel(unsigned Opcode, SDValue Root, unsigned LabelID);
      +  SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root, 
      +                   unsigned LabelID);
       
         SDValue getCopyToReg(SDValue Chain, unsigned Reg, SDValue N) {
           return getNode(ISD::CopyToReg, MVT::Other, Chain,
      @@ -506,12 +511,18 @@ public:
         SDValue getAtomic(unsigned Opcode, MVT MemVT, SDValue Chain, SDValue Ptr, 
                           SDValue Cmp, SDValue Swp, const Value* PtrVal,
                           unsigned Alignment=0);
      +  SDValue getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDValue Chain, 
      +                    SDValue Ptr, SDValue Cmp, SDValue Swp, const Value* PtrVal,
      +                    unsigned Alignment=0);
       
         /// getAtomic - Gets a node for an atomic op, produces result and chain and
         /// takes 2 operands.
         SDValue getAtomic(unsigned Opcode, MVT MemVT, SDValue Chain, SDValue Ptr, 
                           SDValue Val, const Value* PtrVal,
                           unsigned Alignment = 0);
      +  SDValue getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDValue Chain,
      +                    SDValue Ptr, SDValue Val, const Value* PtrVal,
      +                    unsigned Alignment = 0);
       
         /// getMemIntrinsicNode - Creates a MemIntrinsicNode that may produce a
         /// result and takes a list of operands.
      @@ -521,12 +532,23 @@ public:
                                     MVT MemVT, const Value *srcValue, int SVOff,
                                     unsigned Align = 0, bool Vol = false,
                                     bool ReadMem = true, bool WriteMem = true);
      +  SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl,
      +                              const MVT *VTs, unsigned NumVTs,
      +                              const SDValue *Ops, unsigned NumOps,
      +                              MVT MemVT, const Value *srcValue, int SVOff,
      +                              unsigned Align = 0, bool Vol = false,
      +                              bool ReadMem = true, bool WriteMem = true);
       
         SDValue getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
                                     const SDValue *Ops, unsigned NumOps,
                                     MVT MemVT, const Value *srcValue, int SVOff,
                                     unsigned Align = 0, bool Vol = false,
                                     bool ReadMem = true, bool WriteMem = true);
      +  SDValue getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
      +                              const SDValue *Ops, unsigned NumOps,
      +                              MVT MemVT, const Value *srcValue, int SVOff,
      +                              unsigned Align = 0, bool Vol = false,
      +                              bool ReadMem = true, bool WriteMem = true);
       
         /// getMergeValues - Create a MERGE_VALUES node from the given operands.
         SDValue getMergeValues(const SDValue *Ops, unsigned NumOps);
      @@ -536,6 +558,9 @@ public:
         SDValue getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
                         bool isInreg, SDVTList VTs, const SDValue *Operands, 
                         unsigned NumOperands);
      +  SDValue getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
      +                  bool IsTailCall, bool isInreg, SDVTList VTs,
      +                  const SDValue *Operands, unsigned NumOperands);
       
         /// getLoad - Loads are not normal binary operators: their result type is not
         /// determined by their operands, and they produce a value AND a token chain.
      @@ -543,28 +568,50 @@ public:
         SDValue getLoad(MVT VT, SDValue Chain, SDValue Ptr,
                           const Value *SV, int SVOffset, bool isVolatile=false,
                           unsigned Alignment=0);
      +  SDValue getLoad(MVT VT, DebugLoc dl, SDValue Chain, SDValue Ptr,
      +                    const Value *SV, int SVOffset, bool isVolatile=false,
      +                    unsigned Alignment=0);
         SDValue getExtLoad(ISD::LoadExtType ExtType, MVT VT,
                              SDValue Chain, SDValue Ptr, const Value *SV,
                              int SVOffset, MVT EVT, bool isVolatile=false,
                              unsigned Alignment=0);
      +  SDValue getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, MVT VT,
      +                       SDValue Chain, SDValue Ptr, const Value *SV,
      +                       int SVOffset, MVT EVT, bool isVolatile=false,
      +                       unsigned Alignment=0);
         SDValue getIndexedLoad(SDValue OrigLoad, SDValue Base,
                                  SDValue Offset, ISD::MemIndexedMode AM);
      +  SDValue getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
      +                           SDValue Offset, ISD::MemIndexedMode AM);
         SDValue getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
                           MVT VT, SDValue Chain,
                           SDValue Ptr, SDValue Offset,
                           const Value *SV, int SVOffset, MVT EVT,
                           bool isVolatile=false, unsigned Alignment=0);
      +  SDValue getLoad(ISD::MemIndexedMode AM, DebugLoc dl, ISD::LoadExtType ExtType,
      +                    MVT VT, SDValue Chain,
      +                    SDValue Ptr, SDValue Offset,
      +                    const Value *SV, int SVOffset, MVT EVT,
      +                    bool isVolatile=false, unsigned Alignment=0);
       
         /// getStore - Helper function to build ISD::STORE nodes.
         ///
         SDValue getStore(SDValue Chain, SDValue Val, SDValue Ptr,
                            const Value *SV, int SVOffset, bool isVolatile=false,
                            unsigned Alignment=0);
      +  SDValue getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
      +                     const Value *SV, int SVOffset, bool isVolatile=false,
      +                     unsigned Alignment=0);
         SDValue getTruncStore(SDValue Chain, SDValue Val, SDValue Ptr,
                                 const Value *SV, int SVOffset, MVT TVT,
                                 bool isVolatile=false, unsigned Alignment=0);
      +  SDValue getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ptr,
      +                          const Value *SV, int SVOffset, MVT TVT,
      +                          bool isVolatile=false, unsigned Alignment=0);
         SDValue getIndexedStore(SDValue OrigStoe, SDValue Base,
                                  SDValue Offset, ISD::MemIndexedMode AM);
      +  SDValue getIndexedStore(SDValue OrigStoe, DebugLoc dl, SDValue Base,
      +                           SDValue Offset, ISD::MemIndexedMode AM);
       
         /// getSrcValue - Construct a node to track a Value* through the backend.
         SDValue getSrcValue(const Value *v);
      @@ -652,30 +699,72 @@ public:
         /// node of the specified opcode and operands, it returns that node instead of
         /// the current one.
         SDNode *getTargetNode(unsigned Opcode, MVT VT);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1, SDValue Op2);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1, 
      +                        SDValue Op2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                        SDValue Op1, SDValue Op2, SDValue Op3);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT,
                               const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                        const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, SDValue Op1);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, 
      +                        SDValue Op1);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                        MVT VT2, SDValue Op1, SDValue Op2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                        MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
                               const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
      +                        const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +                        SDValue Op1, SDValue Op2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +                        SDValue Op1, SDValue Op2, SDValue Op3);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +                        const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, MVT VT4,
                               const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +                        MVT VT4, const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, const std::vector &ResultTys,
                               const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl,
      +                        const std::vector &ResultTys, const SDValue *Ops,
      +                        unsigned NumOps);
       
         /// getNodeIfExists - Get the specified node if it's already available, or
         /// else return NULL.
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      index a124ebf14f8d..ab2c8323002b 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      @@ -1068,6 +1068,20 @@ SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB) {
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getBasicBlock(MachineBasicBlock *MBB, DebugLoc dl) {
      +  FoldingSetNodeID ID;
      +  AddNodeIDNode(ID, ISD::BasicBlock, getVTList(MVT::Other), 0, 0);
      +  ID.AddPointer(MBB);
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) BasicBlockSDNode(MBB, dl);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getArgFlags(ISD::ArgFlagsTy Flags) {
         FoldingSetNodeID ID;
         AddNodeIDNode(ID, ISD::ARG_FLAGS, getVTList(MVT::Other), 0, 0);
      @@ -1105,6 +1119,15 @@ SDValue SelectionDAG::getExternalSymbol(const char *Sym, MVT VT) {
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getExternalSymbol(const char *Sym, DebugLoc dl, MVT VT) {
      +  SDNode *&N = ExternalSymbols[Sym];
      +  if (N) return SDValue(N, 0);
      +  N = NodeAllocator.Allocate();
      +  new (N) ExternalSymbolSDNode(false, dl, Sym, VT);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT VT) {
         SDNode *&N = TargetExternalSymbols[Sym];
         if (N) return SDValue(N, 0);
      @@ -1114,6 +1137,16 @@ SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, MVT VT) {
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getTargetExternalSymbol(const char *Sym, DebugLoc dl, 
      +                                              MVT VT) {
      +  SDNode *&N = TargetExternalSymbols[Sym];
      +  if (N) return SDValue(N, 0);
      +  N = NodeAllocator.Allocate();
      +  new (N) ExternalSymbolSDNode(true, dl, Sym, VT);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getCondCode(ISD::CondCode Cond) {
         if ((unsigned)Cond >= CondCodeNodes.size())
           CondCodeNodes.resize(Cond+1);
      @@ -1186,6 +1219,23 @@ SDValue SelectionDAG::getLabel(unsigned Opcode,
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getLabel(unsigned Opcode, DebugLoc dl,
      +                               SDValue Root,
      +                               unsigned LabelID) {
      +  FoldingSetNodeID ID;
      +  SDValue Ops[] = { Root };
      +  AddNodeIDNode(ID, Opcode, getVTList(MVT::Other), &Ops[0], 1);
      +  ID.AddInteger(LabelID);
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) LabelSDNode(Opcode, dl, Root, LabelID);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getSrcValue(const Value *V) {
         assert((!V || isa(V->getType())) &&
                "SrcValue is not a pointer?");
      @@ -3353,6 +3403,34 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT,
      +                                SDValue Chain,
      +                                SDValue Ptr, SDValue Cmp, 
      +                                SDValue Swp, const Value* PtrVal,
      +                                unsigned Alignment) {
      +  assert(Opcode == ISD::ATOMIC_CMP_SWAP && "Invalid Atomic Op");
      +  assert(Cmp.getValueType() == Swp.getValueType() && "Invalid Atomic Op Types");
      +
      +  MVT VT = Cmp.getValueType();
      +
      +  if (Alignment == 0)  // Ensure that codegen never sees alignment 0
      +    Alignment = getMVTAlignment(MemVT);
      +
      +  SDVTList VTs = getVTList(VT, MVT::Other);
      +  FoldingSetNodeID ID;
      +  SDValue Ops[] = {Chain, Ptr, Cmp, Swp};
      +  AddNodeIDNode(ID, Opcode, VTs, Ops, 4);
      +  void* IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode* N = NodeAllocator.Allocate();
      +  new (N) AtomicSDNode(Opcode, dl, VTs, MemVT,
      +                       Chain, Ptr, Cmp, Swp, PtrVal, Alignment);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
                                       SDValue Chain,
                                       SDValue Ptr, SDValue Val, 
      @@ -3391,6 +3469,44 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT,
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT,
      +                                SDValue Chain,
      +                                SDValue Ptr, SDValue Val, 
      +                                const Value* PtrVal,
      +                                unsigned Alignment) {
      +  assert((Opcode == ISD::ATOMIC_LOAD_ADD ||
      +          Opcode == ISD::ATOMIC_LOAD_SUB ||
      +          Opcode == ISD::ATOMIC_LOAD_AND ||
      +          Opcode == ISD::ATOMIC_LOAD_OR ||
      +          Opcode == ISD::ATOMIC_LOAD_XOR ||
      +          Opcode == ISD::ATOMIC_LOAD_NAND ||
      +          Opcode == ISD::ATOMIC_LOAD_MIN || 
      +          Opcode == ISD::ATOMIC_LOAD_MAX ||
      +          Opcode == ISD::ATOMIC_LOAD_UMIN || 
      +          Opcode == ISD::ATOMIC_LOAD_UMAX ||
      +          Opcode == ISD::ATOMIC_SWAP) &&
      +         "Invalid Atomic Op");
      +
      +  MVT VT = Val.getValueType();
      +
      +  if (Alignment == 0)  // Ensure that codegen never sees alignment 0
      +    Alignment = getMVTAlignment(MemVT);
      +
      +  SDVTList VTs = getVTList(VT, MVT::Other);
      +  FoldingSetNodeID ID;
      +  SDValue Ops[] = {Chain, Ptr, Val};
      +  AddNodeIDNode(ID, Opcode, VTs, Ops, 3);
      +  void* IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode* N = NodeAllocator.Allocate();
      +  new (N) AtomicSDNode(Opcode, dl, VTs, MemVT,
      +                       Chain, Ptr, Val, PtrVal, Alignment);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       /// getMergeValues - Create a MERGE_VALUES node from the given operands.
       /// Allowed to return something different (and simpler) if Simplify is true.
       SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps) {
      @@ -3416,6 +3532,18 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode,
                                    ReadMem, WriteMem);
       }
       
      +SDValue
      +SelectionDAG::getMemIntrinsicNode(unsigned Opcode, DebugLoc dl,
      +                                  const MVT *VTs, unsigned NumVTs,
      +                                  const SDValue *Ops, unsigned NumOps,
      +                                  MVT MemVT, const Value *srcValue, int SVOff,
      +                                  unsigned Align, bool Vol,
      +                                  bool ReadMem, bool WriteMem) {
      +  return getMemIntrinsicNode(Opcode, dl, makeVTList(VTs, NumVTs), Ops, NumOps,
      +                             MemVT, srcValue, SVOff, Align, Vol,
      +                             ReadMem, WriteMem);
      +}
      +
       SDValue
       SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
                                         const SDValue *Ops, unsigned NumOps,
      @@ -3444,6 +3572,34 @@ SelectionDAG::getMemIntrinsicNode(unsigned Opcode, SDVTList VTList,
         return SDValue(N, 0);
       }
       
      +SDValue
      +SelectionDAG::getMemIntrinsicNode(unsigned Opcode, DebugLoc dl, SDVTList VTList,
      +                                  const SDValue *Ops, unsigned NumOps,
      +                                  MVT MemVT, const Value *srcValue, int SVOff,
      +                                  unsigned Align, bool Vol,
      +                                  bool ReadMem, bool WriteMem) {
      +  // Memoize the node unless it returns a flag.
      +  MemIntrinsicSDNode *N;
      +  if (VTList.VTs[VTList.NumVTs-1] != MVT::Flag) {
      +    FoldingSetNodeID ID;
      +    AddNodeIDNode(ID, Opcode, VTList, Ops, NumOps);
      +    void *IP = 0;
      +    if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +      return SDValue(E, 0);
      +    
      +    N = NodeAllocator.Allocate();
      +    new (N) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps, MemVT,
      +                               srcValue, SVOff, Align, Vol, ReadMem, WriteMem);
      +    CSEMap.InsertNode(N, IP);
      +  } else {
      +    N = NodeAllocator.Allocate();
      +    new (N) MemIntrinsicSDNode(Opcode, dl, VTList, Ops, NumOps, MemVT,
      +                               srcValue, SVOff, Align, Vol, ReadMem, WriteMem);
      +  }
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue
       SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
                             bool IsInreg, SDVTList VTs,
      @@ -3469,6 +3625,31 @@ SelectionDAG::getCall(unsigned CallingConv, bool IsVarArgs, bool IsTailCall,
         return SDValue(N, 0);
       }
       
      +SDValue
      +SelectionDAG::getCall(unsigned CallingConv, DebugLoc dl, bool IsVarArgs,
      +                      bool IsTailCall, bool IsInreg, SDVTList VTs,
      +                      const SDValue *Operands, unsigned NumOperands) {
      +  // Do not include isTailCall in the folding set profile.
      +  FoldingSetNodeID ID;
      +  AddNodeIDNode(ID, ISD::CALL, VTs, Operands, NumOperands);
      +  ID.AddInteger(CallingConv);
      +  ID.AddInteger(IsVarArgs);
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) {
      +    // Instead of including isTailCall in the folding set, we just
      +    // set the flag of the existing node.
      +    if (!IsTailCall)
      +      cast(E)->setNotTailCall();
      +    return SDValue(E, 0);
      +  }
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) CallSDNode(CallingConv, dl, IsVarArgs, IsTailCall, IsInreg,
      +                     VTs, Operands, NumOperands);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue
       SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
                             MVT VT, SDValue Chain,
      @@ -3520,6 +3701,57 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType,
         return SDValue(N, 0);
       }
       
      +SDValue
      +SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl, 
      +                      ISD::LoadExtType ExtType, MVT VT, SDValue Chain,
      +                      SDValue Ptr, SDValue Offset,
      +                      const Value *SV, int SVOffset, MVT EVT,
      +                      bool isVolatile, unsigned Alignment) {
      +  if (Alignment == 0)  // Ensure that codegen never sees alignment 0
      +    Alignment = getMVTAlignment(VT);
      +
      +  if (VT == EVT) {
      +    ExtType = ISD::NON_EXTLOAD;
      +  } else if (ExtType == ISD::NON_EXTLOAD) {
      +    assert(VT == EVT && "Non-extending load from different memory type!");
      +  } else {
      +    // Extending load.
      +    if (VT.isVector())
      +      assert(EVT.getVectorNumElements() == VT.getVectorNumElements() &&
      +             "Invalid vector extload!");
      +    else
      +      assert(EVT.bitsLT(VT) &&
      +             "Should only be an extending load, not truncating!");
      +    assert((ExtType == ISD::EXTLOAD || VT.isInteger()) &&
      +           "Cannot sign/zero extend a FP/Vector load!");
      +    assert(VT.isInteger() == EVT.isInteger() &&
      +           "Cannot convert from FP to Int or Int -> FP!");
      +  }
      +
      +  bool Indexed = AM != ISD::UNINDEXED;
      +  assert((Indexed || Offset.getOpcode() == ISD::UNDEF) &&
      +         "Unindexed load with an offset!");
      +
      +  SDVTList VTs = Indexed ?
      +    getVTList(VT, Ptr.getValueType(), MVT::Other) : getVTList(VT, MVT::Other);
      +  SDValue Ops[] = { Chain, Ptr, Offset };
      +  FoldingSetNodeID ID;
      +  AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3);
      +  ID.AddInteger(AM);
      +  ID.AddInteger(ExtType);
      +  ID.AddInteger(EVT.getRawBits());
      +  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) LoadSDNode(Ops, dl, VTs, AM, ExtType, EVT, SV, SVOffset,
      +                     Alignment, isVolatile);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getLoad(MVT VT,
                                     SDValue Chain, SDValue Ptr,
                                     const Value *SV, int SVOffset,
      @@ -3529,6 +3761,15 @@ SDValue SelectionDAG::getLoad(MVT VT,
                        SV, SVOffset, VT, isVolatile, Alignment);
       }
       
      +SDValue SelectionDAG::getLoad(MVT VT, DebugLoc dl,
      +                              SDValue Chain, SDValue Ptr,
      +                              const Value *SV, int SVOffset,
      +                              bool isVolatile, unsigned Alignment) {
      +  SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
      +  return getLoad(ISD::UNINDEXED, dl, ISD::NON_EXTLOAD, VT, Chain, Ptr, Undef,
      +                 SV, SVOffset, VT, isVolatile, Alignment);
      +}
      +
       SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT VT,
                                        SDValue Chain, SDValue Ptr,
                                        const Value *SV,
      @@ -3539,6 +3780,16 @@ SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, MVT VT,
                        SV, SVOffset, EVT, isVolatile, Alignment);
       }
       
      +SDValue SelectionDAG::getExtLoad(ISD::LoadExtType ExtType, DebugLoc dl, MVT VT,
      +                                 SDValue Chain, SDValue Ptr,
      +                                 const Value *SV,
      +                                 int SVOffset, MVT EVT,
      +                                 bool isVolatile, unsigned Alignment) {
      +  SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
      +  return getLoad(ISD::UNINDEXED, dl, ExtType, VT, Chain, Ptr, Undef,
      +                 SV, SVOffset, EVT, isVolatile, Alignment);
      +}
      +
       SDValue
       SelectionDAG::getIndexedLoad(SDValue OrigLoad, SDValue Base,
                                    SDValue Offset, ISD::MemIndexedMode AM) {
      @@ -3551,6 +3802,18 @@ SelectionDAG::getIndexedLoad(SDValue OrigLoad, SDValue Base,
                        LD->isVolatile(), LD->getAlignment());
       }
       
      +SDValue
      +SelectionDAG::getIndexedLoad(SDValue OrigLoad, DebugLoc dl, SDValue Base,
      +                             SDValue Offset, ISD::MemIndexedMode AM) {
      +  LoadSDNode *LD = cast(OrigLoad);
      +  assert(LD->getOffset().getOpcode() == ISD::UNDEF &&
      +         "Load is already a indexed load!");
      +  return getLoad(AM, dl, LD->getExtensionType(), OrigLoad.getValueType(),
      +                 LD->getChain(), Base, Offset, LD->getSrcValue(),
      +                 LD->getSrcValueOffset(), LD->getMemoryVT(),
      +                 LD->isVolatile(), LD->getAlignment());
      +}
      +
       SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val,
                                      SDValue Ptr, const Value *SV, int SVOffset,
                                      bool isVolatile, unsigned Alignment) {
      @@ -3579,6 +3842,34 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val,
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val,
      +                               SDValue Ptr, const Value *SV, int SVOffset,
      +                               bool isVolatile, unsigned Alignment) {
      +  MVT VT = Val.getValueType();
      +
      +  if (Alignment == 0)  // Ensure that codegen never sees alignment 0
      +    Alignment = getMVTAlignment(VT);
      +
      +  SDVTList VTs = getVTList(MVT::Other);
      +  SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
      +  SDValue Ops[] = { Chain, Val, Ptr, Undef };
      +  FoldingSetNodeID ID;
      +  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
      +  ID.AddInteger(ISD::UNINDEXED);
      +  ID.AddInteger(false);
      +  ID.AddInteger(VT.getRawBits());
      +  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED, false,
      +                      VT, SV, SVOffset, Alignment, isVolatile);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val,
                                           SDValue Ptr, const Value *SV,
                                           int SVOffset, MVT SVT,
      @@ -3615,6 +3906,42 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val,
         return SDValue(N, 0);
       }
       
      +SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val,
      +                                    SDValue Ptr, const Value *SV,
      +                                    int SVOffset, MVT SVT,
      +                                    bool isVolatile, unsigned Alignment) {
      +  MVT VT = Val.getValueType();
      +
      +  if (VT == SVT)
      +    return getStore(Chain, dl, Val, Ptr, SV, SVOffset, isVolatile, Alignment);
      +
      +  assert(VT.bitsGT(SVT) && "Not a truncation?");
      +  assert(VT.isInteger() == SVT.isInteger() &&
      +         "Can't do FP-INT conversion!");
      +
      +  if (Alignment == 0)  // Ensure that codegen never sees alignment 0
      +    Alignment = getMVTAlignment(VT);
      +
      +  SDVTList VTs = getVTList(MVT::Other);
      +  SDValue Undef = getNode(ISD::UNDEF, Ptr.getValueType());
      +  SDValue Ops[] = { Chain, Val, Ptr, Undef };
      +  FoldingSetNodeID ID;
      +  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
      +  ID.AddInteger(ISD::UNINDEXED);
      +  ID.AddInteger(1);
      +  ID.AddInteger(SVT.getRawBits());
      +  ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment));
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) StoreSDNode(Ops, dl, VTs, ISD::UNINDEXED, true,
      +                      SVT, SV, SVOffset, Alignment, isVolatile);
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue
       SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base,
                                     SDValue Offset, ISD::MemIndexedMode AM) {
      @@ -3642,6 +3969,33 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base,
         return SDValue(N, 0);
       }
       
      +SDValue
      +SelectionDAG::getIndexedStore(SDValue OrigStore, DebugLoc dl, SDValue Base,
      +                              SDValue Offset, ISD::MemIndexedMode AM) {
      +  StoreSDNode *ST = cast(OrigStore);
      +  assert(ST->getOffset().getOpcode() == ISD::UNDEF &&
      +         "Store is already a indexed store!");
      +  SDVTList VTs = getVTList(Base.getValueType(), MVT::Other);
      +  SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset };
      +  FoldingSetNodeID ID;
      +  AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4);
      +  ID.AddInteger(AM);
      +  ID.AddInteger(ST->isTruncatingStore());
      +  ID.AddInteger(ST->getMemoryVT().getRawBits());
      +  ID.AddInteger(ST->getRawFlags());
      +  void *IP = 0;
      +  if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
      +    return SDValue(E, 0);
      +  SDNode *N = NodeAllocator.Allocate();
      +  new (N) StoreSDNode(Ops, dl, VTs, AM,
      +                      ST->isTruncatingStore(), ST->getMemoryVT(),
      +                      ST->getSrcValue(), ST->getSrcValueOffset(),
      +                      ST->getAlignment(), ST->isVolatile());
      +  CSEMap.InsertNode(N, IP);
      +  AllNodes.push_back(N);
      +  return SDValue(N, 0);
      +}
      +
       SDValue SelectionDAG::getVAArg(MVT VT,
                                      SDValue Chain, SDValue Ptr,
                                      SDValue SV) {
      @@ -4395,32 +4749,70 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT) {
         return getNode(~Opcode, VT).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT) {
      +  return getNode(~Opcode, dl, VT).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT, SDValue Op1) {
         return getNode(~Opcode, VT, Op1).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                                    SDValue Op1) {
      +  return getNode(~Opcode, dl, VT, Op1).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           SDValue Op1, SDValue Op2) {
         return getNode(~Opcode, VT, Op1, Op2).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                                    SDValue Op1, SDValue Op2) {
      +  return getNode(~Opcode, dl, VT, Op1, Op2).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           SDValue Op1, SDValue Op2,
                                           SDValue Op3) {
         return getNode(~Opcode, VT, Op1, Op2, Op3).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                                    SDValue Op1, SDValue Op2,
      +                                    SDValue Op3) {
      +  return getNode(~Opcode, dl, VT, Op1, Op2, Op3).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           const SDValue *Ops, unsigned NumOps) {
         return getNode(~Opcode, VT, Ops, NumOps).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                                    const SDValue *Ops, unsigned NumOps) {
      +  return getNode(~Opcode, dl, VT, Ops, NumOps).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Op;
         return getNode(~Opcode, VTs, 2, &Op, 0).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, 
      +                                    MVT VT1, MVT VT2) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  SDValue Op;
      +  return getNode(~Opcode, dl, VTs, 2, &Op, 0).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         return getNode(~Opcode, VTs, 2, &Op1, 1).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                                    MVT VT2, SDValue Op1) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  return getNode(~Opcode, dl, VTs, 2, &Op1, 1).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1,
                                           SDValue Op2) {
      @@ -4428,6 +4820,14 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
         SDValue Ops[] = { Op1, Op2 };
         return getNode(~Opcode, VTs, 2, Ops, 2).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                                    MVT VT2, SDValue Op1,
      +                                    SDValue Op2) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  SDValue Ops[] = { Op1, Op2 };
      +  return getNode(~Opcode, dl, VTs, 2, Ops, 2).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1,
                                           SDValue Op2, SDValue Op3) {
      @@ -4435,17 +4835,40 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
         SDValue Ops[] = { Op1, Op2, Op3 };
         return getNode(~Opcode, VTs, 2, Ops, 3).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                                    MVT VT2, SDValue Op1,
      +                                    SDValue Op2, SDValue Op3) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  SDValue Ops[] = { Op1, Op2, Op3 };
      +  return getNode(~Opcode, dl, VTs, 2, Ops, 3).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         return getNode(~Opcode, VTs, 2, Ops, NumOps).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, 
      +                                    MVT VT1, MVT VT2,
      +                                    const SDValue *Ops, unsigned NumOps) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  return getNode(~Opcode, dl, VTs, 2, Ops, NumOps).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                                           SDValue Op1, SDValue Op2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
         SDValue Ops[] = { Op1, Op2 };
         return getNode(~Opcode, VTs, 3, Ops, 2).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +                                    MVT VT1, MVT VT2, MVT VT3,
      +                                    SDValue Op1, SDValue Op2) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      +  SDValue Ops[] = { Op1, Op2 };
      +  return getNode(~Opcode, dl, VTs, 3, Ops, 2).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                                           SDValue Op1, SDValue Op2,
                                           SDValue Op3) {
      @@ -4453,11 +4876,27 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
         SDValue Ops[] = { Op1, Op2, Op3 };
         return getNode(~Opcode, VTs, 3, Ops, 3).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +                                    MVT VT1, MVT VT2, MVT VT3,
      +                                    SDValue Op1, SDValue Op2,
      +                                    SDValue Op3) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      +  SDValue Ops[] = { Op1, Op2, Op3 };
      +  return getNode(~Opcode, dl, VTs, 3, Ops, 3).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
         return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +                                    MVT VT1, MVT VT2, MVT VT3,
      +                                    const SDValue *Ops, unsigned NumOps) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      +  return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, MVT VT3, MVT VT4,
                                           const SDValue *Ops, unsigned NumOps) {
      @@ -4469,6 +4908,18 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
         const MVT *VTs = getNodeValueTypes(VTList);
         return getNode(~Opcode, VTs, 4, Ops, NumOps).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                                    MVT VT2, MVT VT3, MVT VT4,
      +                                    const SDValue *Ops, unsigned NumOps) {
      +  std::vector VTList;
      +  VTList.push_back(VT1);
      +  VTList.push_back(VT2);
      +  VTList.push_back(VT3);
      +  VTList.push_back(VT4);
      +  const MVT *VTs = getNodeValueTypes(VTList);
      +  return getNode(~Opcode, dl, VTs, 4, Ops, NumOps).getNode();
      +}
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
                                           const std::vector &ResultTys,
                                           const SDValue *Ops, unsigned NumOps) {
      @@ -4476,6 +4927,13 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
         return getNode(~Opcode, VTs, ResultTys.size(),
                        Ops, NumOps).getNode();
       }
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +                                    const std::vector &ResultTys,
      +                                    const SDValue *Ops, unsigned NumOps) {
      +  const MVT *VTs = getNodeValueTypes(ResultTys);
      +  return getNode(~Opcode, dl, VTs, ResultTys.size(),
      +                 Ops, NumOps).getNode();
      +}
       
       /// getNodeIfExists - Get the specified node if it's already available, or
       /// else return NULL.
      -- 
      GitLab
      
      
      From cde232f7f031dfdb7b0692d1af7204a6488066ac Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 01:05:33 +0000
      Subject: [PATCH 398/682] Better documentation for our initialization checker
      
      llvm-svn: 63261
      ---
       clang/lib/Sema/SemaInit.cpp | 67 ++++++++++++++++++++++++++-----------
       1 file changed, 48 insertions(+), 19 deletions(-)
      
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index c2539913ce39..f810a8625031 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -7,7 +7,9 @@
       //
       //===----------------------------------------------------------------------===//
       //
      -//  This file implements semantic analysis for initializers.
      +//  This file implements semantic analysis for initializers. The entry
      +//  point is Sema::CheckInitList(), but all of the work is performed
      +//  within the InitListChecker class.
       //
       //===----------------------------------------------------------------------===//
       
      @@ -20,6 +22,33 @@
       #include 
       using namespace clang;
       
      +/// @brief Semantic checking for initializer lists.
      +///
      +/// The InitListChecker class contains a set of routines that each
      +/// handle the initialization of a certain kind of entity, e.g.,
      +/// arrays, vectors, struct/union types, scalars, etc. The
      +/// InitListChecker itself performs a recursive walk of the subobject
      +/// structure of the type to be initialized, while stepping through
      +/// the initializer list one element at a time. The IList and Index
      +/// parameters to each of the Check* routines contain the active
      +/// (syntactic) initializer list and the index into that initializer
      +/// list that represents the current initializer. Each routine is
      +/// responsible for moving that Index forward as it consumes elements.
      +///
      +/// Each Check* routine also has a StructuredList/StructuredIndex
      +/// arguments, which contains the current the "structured" (semantic)
      +/// initializer list and the index into that initializer list where we
      +/// are copying initializers as we map them over to the semantic
      +/// list. Once we have completed our recursive walk of the subobject
      +/// structure, we will have constructed a full semantic initializer
      +/// list.
      +///
      +/// C99 designators cause changes in the initializer list traversal,
      +/// because they make the initialization "jump" into a specific
      +/// subobject and then continue the initialization from that
      +/// point. CheckDesignatedInitializer() recursively steps into the
      +/// designated subobject and manages backing out the recursion to
      +/// initialize the subobjects after the one designated.
       class InitListChecker {
         Sema *SemaRef;
         bool hadError;
      @@ -27,38 +56,38 @@ class InitListChecker {
         InitListExpr *FullyStructuredList;
         
         void CheckImplicitInitList(InitListExpr *ParentIList, QualType T, 
      -                             unsigned &Index, InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      +                             unsigned &Index, InitListExpr *StructuredList,
      +                             unsigned &StructuredIndex);
         void CheckExplicitInitList(InitListExpr *IList, QualType &T,
      -                             unsigned &Index, InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      +                             unsigned &Index, InitListExpr *StructuredList,
      +                             unsigned &StructuredIndex);
         void CheckListElementTypes(InitListExpr *IList, QualType &DeclType, 
                                    bool SubobjectIsDesignatorContext, 
                                    unsigned &Index,
      -                             InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      +                             InitListExpr *StructuredList,
      +                             unsigned &StructuredIndex);
         void CheckSubElementType(InitListExpr *IList, QualType ElemType, 
                                  unsigned &Index,
      -                           InitListExpr *StructuredInitList,
      -                           unsigned &StructuredInitIndex);
      +                           InitListExpr *StructuredList,
      +                           unsigned &StructuredIndex);
         // FIXME: Does DeclType need to be a reference type?
         void CheckScalarType(InitListExpr *IList, QualType &DeclType, 
                              unsigned &Index,
      -                       InitListExpr *StructuredInitList,
      -                       unsigned &StructuredInitIndex);
      +                       InitListExpr *StructuredList,
      +                       unsigned &StructuredIndex);
         void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index,
      -                       InitListExpr *StructuredInitList,
      -                       unsigned &StructuredInitIndex);
      +                       InitListExpr *StructuredList,
      +                       unsigned &StructuredIndex);
         void CheckStructUnionTypes(InitListExpr *IList, QualType DeclType, 
                                    RecordDecl::field_iterator Field, 
                                    bool SubobjectIsDesignatorContext, unsigned &Index,
      -                             InitListExpr *StructuredInitList,
      -                             unsigned &StructuredInitIndex);
      +                             InitListExpr *StructuredList,
      +                             unsigned &StructuredIndex);
         void CheckArrayType(InitListExpr *IList, QualType &DeclType, 
                             llvm::APSInt elementIndex, 
                             bool SubobjectIsDesignatorContext, unsigned &Index,
      -                      InitListExpr *StructuredInitList,
      -                      unsigned &StructuredInitIndex);
      +                      InitListExpr *StructuredList,
      +                      unsigned &StructuredIndex);
         bool CheckDesignatedInitializer(InitListExpr *IList, DesignatedInitExpr *DIE, 
                                         DesignatedInitExpr::designators_iterator D,
                                         QualType &CurrentObjectType, 
      @@ -73,8 +102,8 @@ class InitListChecker {
                                                  InitListExpr *StructuredList,
                                                  unsigned StructuredIndex,
                                                  SourceRange InitRange);
      -  void UpdateStructuredListElement(InitListExpr *StructuredInitList,
      -                                   unsigned &StructuredInitIndex,
      +  void UpdateStructuredListElement(InitListExpr *StructuredList,
      +                                   unsigned &StructuredIndex,
                                          Expr *expr);
         int numArrayElements(QualType DeclType);
         int numStructUnionElements(QualType DeclType);
      -- 
      GitLab
      
      
      From 35a52fabf405371189e2d614a6e28d0c00e640c0 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 01:10:11 +0000
      Subject: [PATCH 399/682] Add another devilish testcase for designated
       initializers
      
      llvm-svn: 63262
      ---
       clang/test/Sema/designated-initializers.c | 7 ++++++-
       1 file changed, 6 insertions(+), 1 deletion(-)
      
      diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c
      index 5c61faa66794..efd0d406511b 100644
      --- a/clang/test/Sema/designated-initializers.c
      +++ b/clang/test/Sema/designated-initializers.c
      @@ -145,5 +145,10 @@ extern float global_float;
       struct XX { int a, *b; };
       struct XY { int before; struct XX xx, *xp; float* after; } xy[] = {
         0, 0, &xy[0].xx.a, &xy[0].xx, &global_float,
      -  [1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float
      +  [1].xx = 0, &xy[1].xx.a, &xy[1].xx, &global_float,
      +  0, // expected-note{{previous initialization is here}}
      +  0, // expected-note{{previous initialization is here}}
      +  [2].before = 0, // expected-warning{{initializer overrides prior initialization of this subobject}}
      +  0, // expected-warning{{initializer overrides prior initialization of this subobject}}
      +  &xy[2].xx.a, &xy[2].xx, &global_float
       };
      -- 
      GitLab
      
      
      From 89ba5949756886a5fa6c5db72b2dd07a62fdd0bd Mon Sep 17 00:00:00 2001
      From: Evan Cheng 
      Date: Thu, 29 Jan 2009 01:13:00 +0000
      Subject: [PATCH 400/682] A slight compile time optimization. If the caller
       knows there isn't a free register getReg() should not call getFreeReg().
      
      llvm-svn: 63263
      ---
       llvm/lib/CodeGen/RegAllocLocal.cpp | 12 ++++++------
       1 file changed, 6 insertions(+), 6 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/RegAllocLocal.cpp b/llvm/lib/CodeGen/RegAllocLocal.cpp
      index acd3ddeccf29..174e394774bd 100644
      --- a/llvm/lib/CodeGen/RegAllocLocal.cpp
      +++ b/llvm/lib/CodeGen/RegAllocLocal.cpp
      @@ -220,10 +220,10 @@ namespace {
           /// getReg - Find a physical register to hold the specified virtual
           /// register.  If all compatible physical registers are used, this method
           /// spills the last used virtual register to the stack, and uses that
      -    /// register.
      -    ///
      +    /// register. If NoFree is true, that means the caller knows there isn't
      +    /// a free register, do not call getFreeReg().
           unsigned getReg(MachineBasicBlock &MBB, MachineInstr *MI,
      -                    unsigned VirtReg);
      +                    unsigned VirtReg, bool NoFree = false);
       
           /// reloadVirtReg - This method transforms the specified specified virtual
           /// register use to refer to a physical register.  This method may do this
      @@ -398,11 +398,11 @@ unsigned RALocal::getFreeReg(const TargetRegisterClass *RC) {
       /// the last used virtual register to the stack, and uses that register.
       ///
       unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I,
      -                         unsigned VirtReg) {
      +                         unsigned VirtReg, bool NoFree) {
         const TargetRegisterClass *RC = MF->getRegInfo().getRegClass(VirtReg);
       
         // First check to see if we have a free register of the requested type...
      -  unsigned PhysReg = getFreeReg(RC);
      +  unsigned PhysReg = NoFree ? 0 : getFreeReg(RC);
       
         // If we didn't find an unused register, scavenge one now!
         if (PhysReg == 0) {
      @@ -498,7 +498,7 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
         } else {         // No registers available.
           // Force some poor hapless value out of the register file to
           // make room for the new register, and reload it.
      -    PhysReg = getReg(MBB, MI, VirtReg);
      +    PhysReg = getReg(MBB, MI, VirtReg, true);
         }
       
         markVirtRegModified(VirtReg, false);   // Note that this reg was just reloaded
      -- 
      GitLab
      
      
      From 0aa2606190b2b4861f55a967cb49e4e50569ca8f Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 01:32:56 +0000
      Subject: [PATCH 401/682] Add folding for complex mul and fix some major bugs
       in complex float evaluation (alternate part of real/imag init was being set
       to 3 not 0 because the wrong APFloat constructor was being called).  - Test
       cases coming once some more support is in.
      
      llvm-svn: 63264
      ---
       clang/lib/AST/ExprConstant.cpp | 39 ++++++++++++++++++++++++++++++++--
       1 file changed, 37 insertions(+), 2 deletions(-)
      
      diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
      index af50de6f9481..c444a199f6c3 100644
      --- a/clang/lib/AST/ExprConstant.cpp
      +++ b/clang/lib/AST/ExprConstant.cpp
      @@ -1257,7 +1257,7 @@ public:
             if (!EvaluateFloat(SubExpr, Result, Info))
               return APValue();
           
      -      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero), 
      +      return APValue(APFloat(Result.getSemantics(), APFloat::fcZero, false), 
                            Result);
           } else {
             assert(SubExpr->getType()->isIntegerType() && 
      @@ -1283,7 +1283,7 @@ public:
               return APValue();
             
             return APValue(Result, 
      -                     APFloat(Result.getSemantics(), APFloat::fcZero));
      +                     APFloat(Result.getSemantics(), APFloat::fcZero, false));
           } else if (SubExpr->getType()->isIntegerType()) {
             APSInt Result;
                            
      @@ -1324,6 +1324,8 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
         if (!EvaluateComplex(E->getRHS(), RHS, Info))
           return APValue();
       
      +  assert(Result.isComplexFloat() == RHS.isComplexFloat() &&
      +         "Invalid operands to binary operator.");
         switch (E->getOpcode()) {
         default: return APValue();
         case BinaryOperator::Add:
      @@ -1336,6 +1338,7 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
             Result.getComplexIntReal() += RHS.getComplexIntReal();
             Result.getComplexIntImag() += RHS.getComplexIntImag();
           }
      +    break;
         case BinaryOperator::Sub:
           if (Result.isComplexFloat()) {
             Result.getComplexFloatReal().subtract(RHS.getComplexFloatReal(),
      @@ -1346,6 +1349,38 @@ APValue ComplexExprEvaluator::VisitBinaryOperator(const BinaryOperator *E)
             Result.getComplexIntReal() -= RHS.getComplexIntReal();
             Result.getComplexIntImag() -= RHS.getComplexIntImag();
           }
      +    break;
      +  case BinaryOperator::Mul:
      +    if (Result.isComplexFloat()) {
      +      APValue LHS = Result;
      +      APFloat &LHS_r = LHS.getComplexFloatReal();
      +      APFloat &LHS_i = LHS.getComplexFloatImag();
      +      APFloat &RHS_r = RHS.getComplexFloatReal();
      +      APFloat &RHS_i = RHS.getComplexFloatImag();
      +      
      +      APFloat Tmp = LHS_r;
      +      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
      +      Result.getComplexFloatReal() = Tmp;
      +      Tmp = LHS_i;
      +      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
      +      Result.getComplexFloatReal().subtract(Tmp, APFloat::rmNearestTiesToEven);
      +
      +      Tmp = LHS_r;
      +      Tmp.multiply(RHS_i, APFloat::rmNearestTiesToEven);
      +      Result.getComplexFloatImag() = Tmp;
      +      Tmp = LHS_i;
      +      Tmp.multiply(RHS_r, APFloat::rmNearestTiesToEven);
      +      Result.getComplexFloatImag().add(Tmp, APFloat::rmNearestTiesToEven);
      +    } else {
      +      APValue LHS = Result;
      +      Result.getComplexIntReal() = 
      +        (LHS.getComplexIntReal() * RHS.getComplexIntReal() -
      +         LHS.getComplexIntImag() * RHS.getComplexIntImag());
      +      Result.getComplexIntImag() = 
      +        (LHS.getComplexIntReal() * RHS.getComplexIntImag() +
      +         LHS.getComplexIntImag() * RHS.getComplexIntReal());
      +    }
      +    break;
         }
       
         return Result;
      -- 
      GitLab
      
      
      From 84f0165273706e25e3780b3a717ca85474708d8f Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Thu, 29 Jan 2009 01:37:18 +0000
      Subject: [PATCH 402/682] Move the code that starts printing the Select_*
       functions after the code that sorts the patterns. This doesn't affect the
       output, but it makes the code a little easier to follow.
      
      llvm-svn: 63265
      ---
       llvm/utils/TableGen/DAGISelEmitter.cpp | 6 +++---
       1 file changed, 3 insertions(+), 3 deletions(-)
      
      diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp
      index 9f028ed4956c..d6bcce2703f8 100644
      --- a/llvm/utils/TableGen/DAGISelEmitter.cpp
      +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp
      @@ -1825,9 +1825,6 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
             } else
               OpVTI->second.push_back(OpVTStr);
       
      -      OS << "SDNode *Select_" << getLegalCName(OpName)
      -         << OpVTStr << "(const SDValue &N) {\n";    
      -
             // We want to emit all of the matching code now.  However, we want to emit
             // the matches in order of minimal cost.  Sort the patterns so the least
             // cost one is at the start.
      @@ -1869,6 +1866,9 @@ void DAGISelEmitter::EmitInstructionSelector(std::ostream &OS) {
             // Next, reverse the list of patterns itself for the same reason.
             std::reverse(CodeForPatterns.begin(), CodeForPatterns.end());
           
      +      OS << "SDNode *Select_" << getLegalCName(OpName)
      +         << OpVTStr << "(const SDValue &N) {\n";    
      +
             // Emit all of the patterns now, grouped together to share code.
             EmitPatterns(CodeForPatterns, 2, OS);
           
      -- 
      GitLab
      
      
      From e58ab79f33ef1ba33c81d93ff183789605ed4f00 Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Thu, 29 Jan 2009 01:59:02 +0000
      Subject: [PATCH 403/682] Make x86's BT instruction matching more thorough, and
       add some dagcombines that help it match in several more cases. Add several
       more cases to test/CodeGen/X86/bt.ll. This doesn't yet include matching for
       BT with an immediate operand, it just covers more register+register cases.
      
      llvm-svn: 63266
      ---
       llvm/include/llvm/Target/TargetLowering.h     |   2 +
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp |  50 ++-
       .../CodeGen/SelectionDAG/TargetLowering.cpp   |  43 +-
       llvm/lib/Target/X86/X86ISelLowering.cpp       |  70 ++-
       llvm/test/CodeGen/X86/bt.ll                   | 420 +++++++++++++++++-
       llvm/test/CodeGen/X86/commute-cmov.ll         |  17 +-
       6 files changed, 562 insertions(+), 40 deletions(-)
      
      diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h
      index e6f18ea43f87..4ec7d3f62793 100644
      --- a/llvm/include/llvm/Target/TargetLowering.h
      +++ b/llvm/include/llvm/Target/TargetLowering.h
      @@ -780,6 +780,8 @@ public:
           SDValue CombineTo(SDNode *N, const std::vector &To);
           SDValue CombineTo(SDNode *N, SDValue Res);
           SDValue CombineTo(SDNode *N, SDValue Res0, SDValue Res1);
      +
      +    void CommitTargetLoweringOpt(const TargetLoweringOpt &TLO);
         };
       
         /// SimplifySetCC - Try to simplify a setcc built with the specified operands 
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 48e556b2362d..848051940f7e 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -102,6 +102,8 @@ namespace {
             SDValue To[] = { Res0, Res1 };
             return CombineTo(N, To, 2, AddTo);
           }
      +
      +    void CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO);
           
         private:    
           
      @@ -298,6 +300,10 @@ CombineTo(SDNode *N, SDValue Res0, SDValue Res1) {
         return ((DAGCombiner*)DC)->CombineTo(N, Res0, Res1);
       }
       
      +void TargetLowering::DAGCombinerInfo::
      +CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &TLO) {
      +  return ((DAGCombiner*)DC)->CommitTargetLoweringOpt(TLO);
      +}
       
       //===----------------------------------------------------------------------===//
       // Helper Functions
      @@ -539,29 +545,14 @@ SDValue DAGCombiner::CombineTo(SDNode *N, const SDValue *To, unsigned NumTo,
         return SDValue(N, 0);
       }
       
      -/// SimplifyDemandedBits - Check the specified integer node value to see if
      -/// it can be simplified or if things it uses can be simplified by bit
      -/// propagation.  If so, return true.
      -bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
      -  TargetLowering::TargetLoweringOpt TLO(DAG);
      -  APInt KnownZero, KnownOne;
      -  if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
      -    return false;
      -  
      -  // Revisit the node.
      -  AddToWorkList(Op.getNode());
      -  
      -  // Replace the old value with the new one.
      -  ++NodesCombined;
      -  DOUT << "\nReplacing.2 "; DEBUG(TLO.Old.getNode()->dump(&DAG));
      -  DOUT << "\nWith: "; DEBUG(TLO.New.getNode()->dump(&DAG));
      -  DOUT << '\n';
      -  
      +void
      +DAGCombiner::CommitTargetLoweringOpt(const TargetLowering::TargetLoweringOpt &
      +                                                                          TLO) {
         // Replace all uses.  If any nodes become isomorphic to other nodes and 
         // are deleted, make sure to remove them from our worklist.
         WorkListRemover DeadNodes(*this);
         DAG.ReplaceAllUsesOfValueWith(TLO.Old, TLO.New, &DeadNodes);
      -  
      +
         // Push the new node and any (possibly new) users onto the worklist.
         AddToWorkList(TLO.New.getNode());
         AddUsersToWorkList(TLO.New.getNode());
      @@ -580,6 +571,27 @@ bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
           
           DAG.DeleteNode(TLO.Old.getNode());
         }
      +}
      +
      +/// SimplifyDemandedBits - Check the specified integer node value to see if
      +/// it can be simplified or if things it uses can be simplified by bit
      +/// propagation.  If so, return true.
      +bool DAGCombiner::SimplifyDemandedBits(SDValue Op, const APInt &Demanded) {
      +  TargetLowering::TargetLoweringOpt TLO(DAG);
      +  APInt KnownZero, KnownOne;
      +  if (!TLI.SimplifyDemandedBits(Op, Demanded, KnownZero, KnownOne, TLO))
      +    return false;
      +  
      +  // Revisit the node.
      +  AddToWorkList(Op.getNode());
      +  
      +  // Replace the old value with the new one.
      +  ++NodesCombined;
      +  DOUT << "\nReplacing.2 "; DEBUG(TLO.Old.getNode()->dump(&DAG));
      +  DOUT << "\nWith: "; DEBUG(TLO.New.getNode()->dump(&DAG));
      +  DOUT << '\n';
      +  
      +  CommitTargetLoweringOpt(TLO);
         return true;
       }
       
      diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
      index 7245244684d0..e479e05bdd71 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
      @@ -724,7 +724,7 @@ TargetLowering::isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const {
       bool TargetLowering::TargetLoweringOpt::ShrinkDemandedConstant(SDValue Op, 
                                                               const APInt &Demanded) {
         // FIXME: ISD::SELECT, ISD::SELECT_CC
      -  switch(Op.getOpcode()) {
      +  switch (Op.getOpcode()) {
         default: break;
         case ISD::AND:
         case ISD::OR:
      @@ -1054,6 +1054,14 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op,
           }
           break;
         case ISD::SRA:
      +    // If this is an arithmetic shift right and only the low-bit is set, we can
      +    // always convert this into a logical shr, even if the shift amount is
      +    // variable.  The low bit of the shift cannot be an input sign bit unless
      +    // the shift amount is >= the size of the datatype, which is undefined.
      +    if (DemandedMask == 1)
      +      return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, Op.getValueType(),
      +                                               Op.getOperand(0), Op.getOperand(1)));
      +
           if (ConstantSDNode *SA = dyn_cast(Op.getOperand(1))) {
             MVT VT = Op.getValueType();
             unsigned ShAmt = SA->getZExtValue();
      @@ -1332,6 +1340,21 @@ unsigned TargetLowering::ComputeNumSignBitsForTargetNode(SDValue Op,
         return 1;
       }
       
      +static bool ValueHasAtMostOneBitSet(SDValue Val, const SelectionDAG &DAG) {
      +  // Logical shift right or left won't ever introduce new set bits.
      +  // We check for this case because we don't care which bits are
      +  // set, but ComputeMaskedBits won't know anything unless it can
      +  // determine which specific bits may be set.
      +  if (Val.getOpcode() == ISD::SHL || Val.getOpcode() == ISD::SRL)
      +    return ValueHasAtMostOneBitSet(Val.getOperand(0), DAG);
      +
      +  MVT OpVT = Val.getValueType();
      +  unsigned BitWidth = OpVT.getSizeInBits();
      +  APInt Mask = APInt::getAllOnesValue(BitWidth);
      +  APInt KnownZero, KnownOne;
      +  DAG.ComputeMaskedBits(Val, Mask, KnownZero, KnownOne);
      +  return KnownZero.countPopulation() == BitWidth - 1;
      +}
       
       /// SimplifySetCC - Try to simplify a setcc built with the specified operands 
       /// and cc. If it is unable to simplify it, return a null SDValue.
      @@ -1791,6 +1814,24 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
               }
             }
           }
      +
      +    // Simpify x&y == y to x&y == 0 if y has exactly one bit set.
      +    if (N0.getOpcode() == ISD::AND)
      +      if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
      +        if (ValueHasAtMostOneBitSet(N1, DAG)) {
      +          Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
      +          SDValue Zero = DAG.getConstant(0, N1.getValueType());
      +          return DAG.getSetCC(VT, N0, Zero, Cond);
      +        }
      +      }
      +    if (N1.getOpcode() == ISD::AND)
      +      if (N1.getOperand(0) == N0 || N1.getOperand(1) == N0) {
      +        if (ValueHasAtMostOneBitSet(N0, DAG)) {
      +          Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true);
      +          SDValue Zero = DAG.getConstant(0, N0.getValueType());
      +          return DAG.getSetCC(VT, N1, Zero, Cond);
      +        }
      +      }
         }
       
         // Fold away ALL boolean setcc's.
      diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
      index 6ec97e2db60e..bf7c704b9ba0 100644
      --- a/llvm/lib/Target/X86/X86ISelLowering.cpp
      +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
      @@ -5114,22 +5114,39 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
         SDValue Op1 = Op.getOperand(1);
         ISD::CondCode CC = cast(Op.getOperand(2))->get();
         
      -  // Lower (X & (1 << N)) == 0 to BT.
      -  // Lower ((X >>u N) & 1) != 0 to BT.
      -  // Lower ((X >>s N) & 1) != 0 to BT.
      +  // Lower (X & (1 << N)) == 0 to BT(X, N).
      +  // Lower ((X >>u N) & 1) != 0 to BT(X, N).
      +  // Lower ((X >>s N) & 1) != 0 to BT(X, N).
         if (Op0.getOpcode() == ISD::AND &&
             Op0.hasOneUse() &&
             Op1.getOpcode() == ISD::Constant &&
      -      Op0.getOperand(1).getOpcode() == ISD::Constant &&
      +      cast(Op1)->getZExtValue() == 0 &&
             (CC == ISD::SETEQ || CC == ISD::SETNE)) {
      -    ConstantSDNode *AndRHS = cast(Op0.getOperand(1));
      -    ConstantSDNode *CmpRHS = cast(Op1);
      -    SDValue AndLHS = Op0.getOperand(0);
      -    if (CmpRHS->getZExtValue() == 0 && AndRHS->getZExtValue() == 1 &&
      -        AndLHS.getOpcode() == ISD::SRL) {
      -      SDValue LHS = AndLHS.getOperand(0);
      -      SDValue RHS = AndLHS.getOperand(1);
      +    SDValue LHS, RHS;
      +    if (Op0.getOperand(1).getOpcode() == ISD::SHL) {
      +      if (ConstantSDNode *Op010C =
      +            dyn_cast(Op0.getOperand(1).getOperand(0)))
      +        if (Op010C->getZExtValue() == 1) {
      +          LHS = Op0.getOperand(0);
      +          RHS = Op0.getOperand(1).getOperand(1);
      +        }
      +    } else if (Op0.getOperand(0).getOpcode() == ISD::SHL) {
      +      if (ConstantSDNode *Op000C =
      +            dyn_cast(Op0.getOperand(0).getOperand(0)))
      +        if (Op000C->getZExtValue() == 1) {
      +          LHS = Op0.getOperand(1);
      +          RHS = Op0.getOperand(0).getOperand(1);
      +        }
      +    } else if (Op0.getOperand(1).getOpcode() == ISD::Constant) {
      +      ConstantSDNode *AndRHS = cast(Op0.getOperand(1));
      +      SDValue AndLHS = Op0.getOperand(0);
      +      if (AndRHS->getZExtValue() == 1 && AndLHS.getOpcode() == ISD::SRL) {
      +        LHS = AndLHS.getOperand(0);
      +        RHS = AndLHS.getOperand(1);
      +      }
      +    }
       
      +    if (LHS.getNode()) {
             // If LHS is i8, promote it to i16 with any_extend.  There is no i8 BT
             // instruction.  Since the shift amount is in-range-or-undefined, we know
             // that doing a bittest on the i16 value is ok.  We extend to i32 because
      @@ -5141,10 +5158,10 @@ SDValue X86TargetLowering::LowerSETCC(SDValue Op, SelectionDAG &DAG) {
             // BT ignores high bits (like shifts) we can use anyextend.
             if (LHS.getValueType() != RHS.getValueType())
               RHS = DAG.getNode(ISD::ANY_EXTEND, LHS.getValueType(), RHS);
      -      
      +
             SDValue BT = DAG.getNode(X86ISD::BT, MVT::i32, LHS, RHS);
             unsigned Cond = CC == ISD::SETEQ ? X86::COND_AE : X86::COND_B;
      -      return DAG.getNode(X86ISD::SETCC, MVT::i8, 
      +      return DAG.getNode(X86ISD::SETCC, MVT::i8,
                                DAG.getConstant(Cond, MVT::i8), BT);
           }
         }
      @@ -5295,7 +5312,7 @@ SDValue X86TargetLowering::LowerSELECT(SDValue Op, SelectionDAG &DAG) {
               !isScalarFPTypeInSSEReg(VT))  // FPStack?
             IllegalFPCMov = !hasFPCMov(cast(CC)->getSExtValue());
           
      -    if (isX86LogicalCmp(Opc) && !IllegalFPCMov) {
      +    if ((isX86LogicalCmp(Opc) && !IllegalFPCMov) || Opc == X86ISD::BT) { // FIXME
             Cond = Cmp;
             addTest = false;
           }
      @@ -7547,6 +7564,7 @@ static SDValue PerformShuffleCombine(SDNode *N, SelectionDAG &DAG,
       
       /// PerformBuildVectorCombine - build_vector 0,(load i64 / f64) -> movq / movsd.
       static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
      +                                         TargetLowering::DAGCombinerInfo &DCI,
                                                const X86Subtarget *Subtarget,
                                                const TargetLowering &TLI) {
         unsigned NumOps = N->getNumOperands();
      @@ -7587,7 +7605,9 @@ static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
         SDVTList Tys = DAG.getVTList(VT, MVT::Other);
         SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
         SDValue ResNode = DAG.getNode(X86ISD::VZEXT_LOAD, Tys, Ops, 2);
      -  DAG.ReplaceAllUsesOfValueWith(SDValue(Base, 1), ResNode.getValue(1));
      +  TargetLowering::TargetLoweringOpt TLO(DAG);
      +  TLO.CombineTo(SDValue(Base, 1), ResNode.getValue(1));
      +  DCI.CommitTargetLoweringOpt(TLO);
         return ResNode;
       }                                           
       
      @@ -7875,6 +7895,23 @@ static SDValue PerformFANDCombine(SDNode *N, SelectionDAG &DAG) {
         return SDValue();
       }
       
      +static SDValue PerformBTCombine(SDNode *N,
      +                                SelectionDAG &DAG,
      +                                TargetLowering::DAGCombinerInfo &DCI) {
      +  // BT ignores high bits in the bit index operand.
      +  SDValue Op1 = N->getOperand(1);
      +  if (Op1.hasOneUse()) {
      +    unsigned BitWidth = Op1.getValueSizeInBits();
      +    APInt DemandedMask = APInt::getLowBitsSet(BitWidth, Log2_32(BitWidth));
      +    APInt KnownZero, KnownOne;
      +    TargetLowering::TargetLoweringOpt TLO(DAG);
      +    TargetLowering &TLI = DAG.getTargetLoweringInfo();
      +    if (TLO.ShrinkDemandedConstant(Op1, DemandedMask) ||
      +        TLI.SimplifyDemandedBits(Op1, DemandedMask, KnownZero, KnownOne, TLO))
      +      DCI.CommitTargetLoweringOpt(TLO);
      +  }
      +  return SDValue();
      +}
       
       SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
                                                    DAGCombinerInfo &DCI) const {
      @@ -7883,7 +7920,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
         default: break;
         case ISD::VECTOR_SHUFFLE: return PerformShuffleCombine(N, DAG, *this);
         case ISD::BUILD_VECTOR:
      -    return PerformBuildVectorCombine(N, DAG, Subtarget, *this);
      +    return PerformBuildVectorCombine(N, DAG, DCI, Subtarget, *this);
         case ISD::SELECT:         return PerformSELECTCombine(N, DAG, Subtarget);
         case ISD::SHL:
         case ISD::SRA:
      @@ -7892,6 +7929,7 @@ SDValue X86TargetLowering::PerformDAGCombine(SDNode *N,
         case X86ISD::FXOR:
         case X86ISD::FOR:         return PerformFORCombine(N, DAG);
         case X86ISD::FAND:        return PerformFANDCombine(N, DAG);
      +  case X86ISD::BT:          return PerformBTCombine(N, DAG, DCI);
         }
       
         return SDValue();
      diff --git a/llvm/test/CodeGen/X86/bt.ll b/llvm/test/CodeGen/X86/bt.ll
      index 86254d3295b0..f91130dd69a8 100644
      --- a/llvm/test/CodeGen/X86/bt.ll
      +++ b/llvm/test/CodeGen/X86/bt.ll
      @@ -1,4 +1,4 @@
      -; RUN: llvm-as < %s | llc | grep btl
      +; RUN: llvm-as < %s | llc -march=x86 | grep btl | count 28
       ; RUN: llvm-as < %s | llc -mcpu=pentium4 | grep btl | not grep esp
       ; RUN: llvm-as < %s | llc -mcpu=penryn   | grep btl | not grep esp
       ; PR3253
      @@ -7,8 +7,17 @@
       ; pentium4, however it is currently disabled due to the register+memory
       ; form having different semantics than the register+register form.
       
      -target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
      -target triple = "i386-apple-darwin8"
      +; Test these patterns:
      +;    (X & (1 << N))  != 0  -->  BT(X, N).
      +;    ((X >>u N) & 1) != 0  -->  BT(X, N).
      +; as well as several variations:
      +;    - The second form can use an arithmetic shift.
      +;    - Either form can use == instead of !=.
      +;    - Either form can compare with an operand of the &
      +;      instead of with 0.
      +;    - The comparison can be commuted (only cases where neither
      +;      operand is constant are included).
      +;    - The and can be commuted.
       
       define void @test2(i32 %x, i32 %n) nounwind {
       entry:
      @@ -25,4 +34,409 @@ UnifiedReturnBlock:		; preds = %entry
       	ret void
       }
       
      +define void @test2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp eq i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @atest2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp eq i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @atest2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp eq i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @test3(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, %x		;  [#uses=1]
      +	%tmp4 = icmp eq i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @test3b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %x, %tmp29
      +	%tmp4 = icmp eq i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @testne2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @testne2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp ne i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @atestne2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @atestne2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp ne i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @testne3(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, %x		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @testne3b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %x, %tmp29
      +	%tmp4 = icmp ne i32 %tmp3, 0		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @query2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp eq i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @query2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp eq i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @aquery2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp eq i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @aquery2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp eq i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @query3(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, %x		;  [#uses=1]
      +	%tmp4 = icmp eq i32 %tmp3, %tmp29		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @query3b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %x, %tmp29
      +	%tmp4 = icmp eq i32 %tmp3, %tmp29		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @query3x(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, %x		;  [#uses=1]
      +	%tmp4 = icmp eq i32 %tmp29, %tmp3		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @query3bx(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %x, %tmp29
      +	%tmp4 = icmp eq i32 %tmp29, %tmp3		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @queryne2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @queryne2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = lshr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp ne i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @aqueryne2(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, 1		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @aqueryne2b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = ashr i32 %x, %n		;  [#uses=1]
      +	%tmp3 = and i32 1, %tmp29
      +	%tmp4 = icmp ne i32 %tmp3, 1		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @queryne3(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, %x		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp3, %tmp29		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @queryne3b(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %x, %tmp29
      +	%tmp4 = icmp ne i32 %tmp3, %tmp29		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @queryne3x(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %tmp29, %x		;  [#uses=1]
      +	%tmp4 = icmp ne i32 %tmp29, %tmp3		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
      +define void @queryne3bx(i32 %x, i32 %n) nounwind {
      +entry:
      +	%tmp29 = shl i32 1, %n		;  [#uses=1]
      +	%tmp3 = and i32 %x, %tmp29
      +	%tmp4 = icmp ne i32 %tmp29, %tmp3		;  [#uses=1]
      +	br i1 %tmp4, label %bb, label %UnifiedReturnBlock
      +
      +bb:		; preds = %entry
      +	call void @foo()
      +	ret void
      +
      +UnifiedReturnBlock:		; preds = %entry
      +	ret void
      +}
      +
       declare void @foo()
      diff --git a/llvm/test/CodeGen/X86/commute-cmov.ll b/llvm/test/CodeGen/X86/commute-cmov.ll
      index 24398dc12570..ac0e4ef3e577 100644
      --- a/llvm/test/CodeGen/X86/commute-cmov.ll
      +++ b/llvm/test/CodeGen/X86/commute-cmov.ll
      @@ -1,5 +1,20 @@
      -; RUN: llvm-as < %s | llc -march=x86 | grep {cmove	16(%esp)}
      +; RUN: llvm-as < %s | llc -march=x86 > %t
      +; RUN: grep btl %t | count 2
      +; RUN: grep cmov %t | count 2
      +; RUN: not grep test %t
      +; RUN: not grep set %t
      +; RUN: not grep j %t
      +; RUN: not grep cmovne %t
      +; RUN: not grep cmove %t
       
      +define i32 @foo(i32 %x, i32 %n, i32 %w, i32 %v) nounwind readnone {
      +entry:
      +	%0 = lshr i32 %x, %n		;  [#uses=1]
      +	%1 = and i32 %0, 1		;  [#uses=1]
      +	%toBool = icmp eq i32 %1, 0		;  [#uses=1]
      +	%.0 = select i1 %toBool, i32 %v, i32 12		;  [#uses=1]
      +	ret i32 %.0
      +}
       define i32 @bar(i32 %x, i32 %n, i32 %w, i32 %v) nounwind readnone {
       entry:
       	%0 = lshr i32 %x, %n		;  [#uses=1]
      -- 
      GitLab
      
      
      From 76a2736c74561ee13a8b3eadc92766fa555eee49 Mon Sep 17 00:00:00 2001
      From: Evan Cheng 
      Date: Thu, 29 Jan 2009 02:20:59 +0000
      Subject: [PATCH 404/682] Exit with nice warnings when register allocator run
       out of registers.
      
      llvm-svn: 63267
      ---
       llvm/include/llvm/CodeGen/LiveInterval.h  |   4 +
       llvm/lib/CodeGen/LiveInterval.cpp         |  10 +++
       llvm/lib/CodeGen/LiveIntervalAnalysis.cpp |  14 ++-
       llvm/lib/CodeGen/RegAllocLocal.cpp        | 105 +++++++++++++---------
       llvm/test/CodeGen/X86/illegal-asm.ll      |  32 +++++++
       5 files changed, 124 insertions(+), 41 deletions(-)
       create mode 100644 llvm/test/CodeGen/X86/illegal-asm.ll
      
      diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h
      index 4966a614d37f..7bcc4c7cb88f 100644
      --- a/llvm/include/llvm/CodeGen/LiveInterval.h
      +++ b/llvm/include/llvm/CodeGen/LiveInterval.h
      @@ -377,6 +377,10 @@ namespace llvm {
                     const int *RHSValNoAssignments,
                     SmallVector &NewVNInfo);
       
      +    /// isInOneLiveRange - Return true if the range specified is entirely in the
      +    /// a single LiveRange of the live interval.
      +    bool isInOneLiveRange(unsigned Start, unsigned End);
      +
           /// removeRange - Remove the specified range from this interval.  Note that
           /// the range must be a single LiveRange in its entirety.
           void removeRange(unsigned Start, unsigned End, bool RemoveDeadValNo = false);
      diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp
      index 4392652438ce..6341b9cd5071 100644
      --- a/llvm/lib/CodeGen/LiveInterval.cpp
      +++ b/llvm/lib/CodeGen/LiveInterval.cpp
      @@ -244,6 +244,16 @@ LiveInterval::addRangeFrom(LiveRange LR, iterator From) {
         return ranges.insert(it, LR);
       }
       
      +/// isInOneLiveRange - Return true if the range specified is entirely in the
      +/// a single LiveRange of the live interval.
      +bool LiveInterval::isInOneLiveRange(unsigned Start, unsigned End) {
      +  Ranges::iterator I = std::upper_bound(ranges.begin(), ranges.end(), Start);
      +  if (I == ranges.begin())
      +    return false;
      +  --I;
      +  return I->contains(Start) && I->contains(End-1);
      +}
      +
       
       /// removeRange - Remove the specified range from this interval.  Note that
       /// the range must be in a single LiveRange in its entirety.
      diff --git a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
      index 8cd82a694bfc..8e8e8ff6d0ca 100644
      --- a/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
      +++ b/llvm/lib/CodeGen/LiveIntervalAnalysis.cpp
      @@ -2228,7 +2228,19 @@ void LiveIntervals::spillPhysRegAroundRegDefsUses(const LiveInterval &li,
           unsigned Index = getInstructionIndex(MI);
           if (pli.liveAt(Index)) {
             vrm.addEmergencySpill(SpillReg, MI);
      -      pli.removeRange(getLoadIndex(Index), getStoreIndex(Index)+1);
      +      unsigned StartIdx = getLoadIndex(Index);
      +      unsigned EndIdx = getStoreIndex(Index)+1;
      +      if (pli.isInOneLiveRange(StartIdx, EndIdx))
      +        pli.removeRange(StartIdx, EndIdx);
      +      else {
      +        cerr << "Ran out of registers during register allocation!\n";
      +        if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
      +          cerr << "Please check your inline asm statement for invalid "
      +               << "constraints:\n";
      +          MI->print(cerr.stream(), tm_);
      +        }
      +        exit(1);
      +      }
             for (const unsigned* AS = tri_->getSubRegisters(SpillReg); *AS; ++AS) {
               if (!hasInterval(*AS))
                 continue;
      diff --git a/llvm/lib/CodeGen/RegAllocLocal.cpp b/llvm/lib/CodeGen/RegAllocLocal.cpp
      index 174e394774bd..9fc5f738b4e4 100644
      --- a/llvm/lib/CodeGen/RegAllocLocal.cpp
      +++ b/llvm/lib/CodeGen/RegAllocLocal.cpp
      @@ -27,6 +27,7 @@
       #include "llvm/Support/Compiler.h"
       #include "llvm/ADT/DenseMap.h"
       #include "llvm/ADT/IndexedMap.h"
      +#include "llvm/ADT/SmallSet.h"
       #include "llvm/ADT/SmallVector.h"
       #include "llvm/ADT/Statistic.h"
       #include "llvm/ADT/STLExtras.h"
      @@ -237,7 +238,7 @@ namespace {
           /// value.  This method returns the modified instruction.
           ///
           MachineInstr *reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
      -                                unsigned OpNum);
      +                                unsigned OpNum, SmallSet &RRegs);
       
           /// ComputeLocalLiveness - Computes liveness of registers within a basic
           /// block, setting the killed/dead flags as appropriate.
      @@ -475,7 +476,8 @@ unsigned RALocal::getReg(MachineBasicBlock &MBB, MachineInstr *I,
       /// modified instruction.
       ///
       MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
      -                                     unsigned OpNum) {
      +                                     unsigned OpNum,
      +                                     SmallSet &ReloadedRegs) {
         unsigned VirtReg = MI->getOperand(OpNum).getReg();
       
         // If the virtual register is already available, just update the instruction
      @@ -513,6 +515,29 @@ MachineInstr *RALocal::reloadVirtReg(MachineBasicBlock &MBB, MachineInstr *MI,
         MF->getRegInfo().setPhysRegUsed(PhysReg);
         MI->getOperand(OpNum).setReg(PhysReg);  // Assign the input register
         getVirtRegLastUse(VirtReg) = std::make_pair(MI, OpNum);
      +
      +  if (!ReloadedRegs.insert(PhysReg)) {
      +    cerr << "Ran out of registers during register allocation!\n";
      +    if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
      +      cerr << "Please check your inline asm statement for invalid "
      +           << "constraints:\n";
      +      MI->print(cerr.stream(), TM);
      +    }
      +    exit(1);
      +  }
      +  for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
      +       *SubRegs; ++SubRegs) {
      +    if (!ReloadedRegs.insert(*SubRegs)) {
      +      cerr << "Ran out of registers during register allocation!\n";
      +      if (MI->getOpcode() == TargetInstrInfo::INLINEASM) {
      +        cerr << "Please check your inline asm statement for invalid "
      +             << "constraints:\n";
      +        MI->print(cerr.stream(), TM);
      +      }
      +      exit(1);
      +    }
      +  }
      +
         return MI;
       }
       
      @@ -581,17 +606,16 @@ void RALocal::ComputeLocalLiveness(MachineBasicBlock& MBB) {
               
               if (TargetRegisterInfo::isVirtualRegister(MO.getReg())) continue;
               
      -        const unsigned* subregs = TRI->getAliasSet(MO.getReg());
      -        if (subregs) {
      -          while (*subregs) {
      +        const unsigned* Aliases = TRI->getAliasSet(MO.getReg());
      +        if (Aliases) {
      +          while (*Aliases) {
                   DenseMap >::iterator
      -              alias = LastUseDef.find(*subregs);
      +              alias = LastUseDef.find(*Aliases);
                   
      -            if (alias != LastUseDef.end() &&
      -                alias->second.first != I)
      -              LastUseDef[*subregs] = std::make_pair(I, i);
      +            if (alias != LastUseDef.end() && alias->second.first != I)
      +              LastUseDef[*Aliases] = std::make_pair(I, i);
                   
      -            ++subregs;
      +            ++Aliases;
                 }
               }
             }
      @@ -695,12 +719,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
             MF->getRegInfo().setPhysRegUsed(Reg);
             PhysRegsUsed[Reg] = 0;            // It is free and reserved now
             AddToPhysRegsUseOrder(Reg); 
      -      for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
      -           *AliasSet; ++AliasSet) {
      -        if (PhysRegsUsed[*AliasSet] != -2) {
      -          AddToPhysRegsUseOrder(*AliasSet); 
      -          PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
      -          MF->getRegInfo().setPhysRegUsed(*AliasSet);
      +      for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
      +           *SubRegs; ++SubRegs) {
      +        if (PhysRegsUsed[*SubRegs] != -2) {
      +          AddToPhysRegsUseOrder(*SubRegs); 
      +          PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
      +          MF->getRegInfo().setPhysRegUsed(*SubRegs);
               }
             }
           }    
      @@ -778,12 +802,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
                   PhysRegsUsed[Reg] = 0;            // It is free and reserved now
                   AddToPhysRegsUseOrder(Reg); 
       
      -            for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
      -                 *AliasSet; ++AliasSet) {
      -              if (PhysRegsUsed[*AliasSet] != -2) {
      -                MF->getRegInfo().setPhysRegUsed(*AliasSet);
      -                PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
      -                AddToPhysRegsUseOrder(*AliasSet); 
      +            for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
      +                 *SubRegs; ++SubRegs) {
      +              if (PhysRegsUsed[*SubRegs] != -2) {
      +                MF->getRegInfo().setPhysRegUsed(*SubRegs);
      +                PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
      +                AddToPhysRegsUseOrder(*SubRegs); 
                     }
                   }
                 }
      @@ -797,12 +821,13 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
           // physical register is referenced by the instruction, that it is guaranteed
           // to be live-in, or the input is badly hosed.
           //
      +    SmallSet ReloadedRegs;
           for (unsigned i = 0; i != MI->getNumOperands(); ++i) {
             MachineOperand& MO = MI->getOperand(i);
             // here we are looking for only used operands (never def&use)
             if (MO.isReg() && !MO.isDef() && MO.getReg() && !MO.isImplicit() &&
                 TargetRegisterInfo::isVirtualRegister(MO.getReg()))
      -        MI = reloadVirtReg(MBB, MI, i);
      +        MI = reloadVirtReg(MBB, MI, i, ReloadedRegs);
           }
       
           // If this instruction is the last user of this register, kill the
      @@ -830,13 +855,13 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
               DOUT << "  Last use of " << TRI->getName(PhysReg)
                    << "[%reg" << VirtReg <<"], removing it from live set\n";
               removePhysReg(PhysReg);
      -        for (const unsigned *AliasSet = TRI->getSubRegisters(PhysReg);
      -             *AliasSet; ++AliasSet) {
      -          if (PhysRegsUsed[*AliasSet] != -2) {
      +        for (const unsigned *SubRegs = TRI->getSubRegisters(PhysReg);
      +             *SubRegs; ++SubRegs) {
      +          if (PhysRegsUsed[*SubRegs] != -2) {
                   DOUT  << "  Last use of "
      -                  << TRI->getName(*AliasSet)
      +                  << TRI->getName(*SubRegs)
                         << "[%reg" << VirtReg <<"], removing it from live set\n";
      -            removePhysReg(*AliasSet);
      +            removePhysReg(*SubRegs);
                 }
               }
             }
      @@ -861,12 +886,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
               PhysRegsUsed[Reg] = 0;            // It is free and reserved now
               AddToPhysRegsUseOrder(Reg); 
       
      -        for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
      -             *AliasSet; ++AliasSet) {
      -          if (PhysRegsUsed[*AliasSet] != -2) {
      -            MF->getRegInfo().setPhysRegUsed(*AliasSet);
      -            PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
      -            AddToPhysRegsUseOrder(*AliasSet); 
      +        for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
      +             *SubRegs; ++SubRegs) {
      +          if (PhysRegsUsed[*SubRegs] != -2) {
      +            MF->getRegInfo().setPhysRegUsed(*SubRegs);
      +            PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
      +            AddToPhysRegsUseOrder(*SubRegs); 
                 }
               }
             }
      @@ -883,12 +908,12 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
                 PhysRegsUsed[Reg] = 0;            // It is free and reserved now
               }
               MF->getRegInfo().setPhysRegUsed(Reg);
      -        for (const unsigned *AliasSet = TRI->getSubRegisters(Reg);
      -             *AliasSet; ++AliasSet) {
      -          if (PhysRegsUsed[*AliasSet] != -2) {
      -            AddToPhysRegsUseOrder(*AliasSet); 
      -            PhysRegsUsed[*AliasSet] = 0;  // It is free and reserved now
      -            MF->getRegInfo().setPhysRegUsed(*AliasSet);
      +        for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
      +             *SubRegs; ++SubRegs) {
      +          if (PhysRegsUsed[*SubRegs] != -2) {
      +            AddToPhysRegsUseOrder(*SubRegs); 
      +            PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
      +            MF->getRegInfo().setPhysRegUsed(*SubRegs);
                 }
               }
             }
      diff --git a/llvm/test/CodeGen/X86/illegal-asm.ll b/llvm/test/CodeGen/X86/illegal-asm.ll
      new file mode 100644
      index 000000000000..0e7dc59eb52a
      --- /dev/null
      +++ b/llvm/test/CodeGen/X86/illegal-asm.ll
      @@ -0,0 +1,32 @@
      +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin -disable-fp-elim
      +; XFAIL: *
      +; Expected to run out of registers during allocation.
      +; rdar://6251720
      +
      +	%struct.CABACContext = type { i32, i32, i8* }
      +	%struct.H264Context = type { %struct.CABACContext, [460 x i8] }
      +@coeff_abs_level_m1_offset = common global [6 x i32] zeroinitializer		; <[6 x i32]*> [#uses=1]
      +@coeff_abs_level1_ctx = common global [8 x i8] zeroinitializer		; <[8 x i8]*> [#uses=1]
      +
      +define i32 @decode_cabac_residual(%struct.H264Context* %h, i32 %cat) nounwind {
      +entry:
      +	%0 = getelementptr [6 x i32]* @coeff_abs_level_m1_offset, i32 0, i32 %cat		;  [#uses=1]
      +	%1 = load i32* %0, align 4		;  [#uses=1]
      +	%2 = load i8* getelementptr ([8 x i8]* @coeff_abs_level1_ctx, i32 0, i32 0), align 1		;  [#uses=1]
      +	%3 = zext i8 %2 to i32		;  [#uses=1]
      +	%.sum = add i32 %3, %1		;  [#uses=1]
      +	%4 = getelementptr %struct.H264Context* %h, i32 0, i32 1, i32 %.sum		;  [#uses=2]
      +	%5 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 0		;  [#uses=2]
      +	%6 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 1		;  [#uses=2]
      +	%7 = getelementptr %struct.H264Context* %h, i32 0, i32 0, i32 2		;  [#uses=2]
      +	%8 = load i32* %5, align 4		;  [#uses=1]
      +	%9 = load i32* %6, align 4		;  [#uses=1]
      +	%10 = load i8* %4, align 4		;  [#uses=1]
      +	%asmtmp = tail call { i32, i32, i32, i32 } asm sideeffect "#$0 $1 $2 $3 $4 $5", "=&{di},=r,=r,=*m,=&q,=*imr,1,2,*m,5,~{dirflag},~{fpsr},~{flags},~{cx}"(i8** %7, i8* %4, i32 %8, i32 %9, i8** %7, i8 %10) nounwind		; <{ i32, i32, i32, i32 }> [#uses=3]
      +	%asmresult = extractvalue { i32, i32, i32, i32 } %asmtmp, 0		;  [#uses=1]
      +	%asmresult1 = extractvalue { i32, i32, i32, i32 } %asmtmp, 1		;  [#uses=1]
      +	store i32 %asmresult1, i32* %5
      +	%asmresult2 = extractvalue { i32, i32, i32, i32 } %asmtmp, 2		;  [#uses=1]
      +	store i32 %asmresult2, i32* %6
      +	ret i32 %asmresult
      +}
      -- 
      GitLab
      
      
      From c0474013cb3fc200e5087d126d6cbf9b08aab45a Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 04:43:42 +0000
      Subject: [PATCH 405/682] Fix PR3424, a static constructor ordering issue. 
       Patch by Robert Schuster!
      
      llvm-svn: 63269
      ---
       llvm/lib/System/DynamicLibrary.cpp | 11 +++++++----
       1 file changed, 7 insertions(+), 4 deletions(-)
      
      diff --git a/llvm/lib/System/DynamicLibrary.cpp b/llvm/lib/System/DynamicLibrary.cpp
      index 970266f34387..3bf172c22b3f 100644
      --- a/llvm/lib/System/DynamicLibrary.cpp
      +++ b/llvm/lib/System/DynamicLibrary.cpp
      @@ -18,11 +18,14 @@
       #include 
       
       // Collection of symbol name/value pairs to be searched prior to any libraries.
      -static std::map g_symbols;
      +std::map &g_symbols() {
      +  static std::map symbols;
      +  return symbols;
      +}
       
       void llvm::sys::DynamicLibrary::AddSymbol(const char* symbolName,
                                                 void *symbolValue) {
      -  g_symbols[symbolName] = symbolValue;
      +  g_symbols()[symbolName] = symbolValue;
       }
       
       // It is not possible to use ltdl.c on VC++ builds as the terms of its LGPL
      @@ -76,8 +79,8 @@ void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
         //  check_ltdl_initialization();
       
         // First check symbols added via AddSymbol().
      -  std::map::iterator I = g_symbols.find(symbolName);
      -  if (I != g_symbols.end())
      +  std::map::iterator I = g_symbols().find(symbolName);
      +  if (I != g_symbols().end())
           return I->second;
       
         // Now search the libraries.
      -- 
      GitLab
      
      
      From d9ae05ba501f338d45dd903dff5484110ab399f5 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 05:10:57 +0000
      Subject: [PATCH 406/682] fix an absolutely inscrutible gcc 4.0 error:
      MIME-Version: 1.0
      Content-Type: text/plain; charset=UTF-8
      Content-Transfer-Encoding: 8bit
      
      llvm[0]: Compiling SemaInit.cpp for Debug build
      SemaInit.cpp:171: error: ‘InitListChecker’ has not been declared
      SemaInit.cpp:171: error: ISO C++ forbids declaration of ‘InitListChecker’ with no type
      SemaInit.cpp: In function ‘int InitListChecker(clang::Sema*, clang::InitListExpr*, clang::QualType&)’:
      SemaInit.cpp:172: error: ‘hadError’ was not declared in this scope
      SemaInit.cpp:173: error: ‘SemaRef’ was not declared in this scope
      SemaInit.cpp:177: error: ‘FullyStructuredList’ was not declared in this scope
      
      llvm-svn: 63270
      ---
       clang/lib/Sema/SemaInit.cpp | 6 +++++-
       1 file changed, 5 insertions(+), 1 deletion(-)
      
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index f810a8625031..bb523e179b8a 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -49,6 +49,7 @@ using namespace clang;
       /// point. CheckDesignatedInitializer() recursively steps into the
       /// designated subobject and manages backing out the recursion to
       /// initialize the subobjects after the one designated.
      +namespace clang {
       class InitListChecker {
         Sema *SemaRef;
         bool hadError;
      @@ -115,6 +116,8 @@ public:
         // semantic analysis and code generation.
         InitListExpr *getFullyStructuredList() const { return FullyStructuredList; }
       };
      +}
      +
       
       /// Recursively replaces NULL values within the given initializer list
       /// with expressions that perform value-initialization of the
      @@ -161,11 +164,12 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) {
             ILE->setInit(Init, new (Context) CXXZeroInitValueExpr(ElementType, 
                                                                   SourceLocation(),
                                                                   SourceLocation()));
      -    else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init)))
      +    else if (InitListExpr *InnerILE =dyn_cast(ILE->getInit(Init)))
             fillInValueInitializations(Context, InnerILE);
         }
       }
       
      +
       InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) {
         hadError = false;
         SemaRef = S;
      -- 
      GitLab
      
      
      From 60f36223a935b2f02949f0dad574b37d3caa2e4c Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 05:15:15 +0000
      Subject: [PATCH 407/682] move library-specific diagnostic headers into library
       private dirs.  Reduce redundant #includes.  Patch by Anders Johnsen!
      
      llvm-svn: 63271
      ---
       clang/Driver/clang.cpp                        |  2 +-
       .../DiagnosticAST.h => AST/ASTDiagnostic.h}   |  6 +-
       .../AnalysisDiagnostic.h}                     |  4 +-
       clang/include/clang/Basic/DiagnosticDriver.h  | 57 -------------------
       clang/include/clang/Driver/DriverDiagnostic.h | 26 +++++++++
       .../DiagnosticLex.h => Lex/LexDiagnostic.h}   |  4 +-
       .../ParseDiagnostic.h}                        |  4 +-
       .../SemaDiagnostic.h}                         |  4 +-
       clang/lib/AST/ExprConstant.cpp                |  2 +-
       clang/lib/Analysis/UninitializedValues.cpp    |  2 +-
       clang/lib/Lex/Lexer.cpp                       |  2 +-
       clang/lib/Lex/LiteralSupport.cpp              |  2 +-
       clang/lib/Lex/MacroArgs.cpp                   |  2 +-
       clang/lib/Lex/PPDirectives.cpp                |  2 +-
       clang/lib/Lex/PPExpressions.cpp               |  2 +-
       clang/lib/Lex/PPLexerChange.cpp               |  2 +-
       clang/lib/Lex/PPMacroExpansion.cpp            |  2 +-
       clang/lib/Lex/Pragma.cpp                      |  2 +-
       clang/lib/Lex/Preprocessor.cpp                |  2 +-
       clang/lib/Lex/PreprocessorLexer.cpp           |  2 +-
       clang/lib/Lex/TokenLexer.cpp                  |  2 +-
       clang/lib/Parse/DeclSpec.cpp                  |  2 +-
       clang/lib/Parse/ExtensionRAIIObject.h         |  2 +-
       clang/lib/Parse/ParseCXXInlineMethods.cpp     |  2 +-
       clang/lib/Parse/ParseDecl.cpp                 |  2 +-
       clang/lib/Parse/ParseDeclCXX.cpp              |  2 +-
       clang/lib/Parse/ParseExprCXX.cpp              |  2 +-
       clang/lib/Parse/ParseInit.cpp                 |  2 +-
       clang/lib/Parse/ParseObjc.cpp                 |  2 +-
       clang/lib/Parse/ParsePragma.cpp               |  2 +-
       clang/lib/Parse/ParseTemplate.cpp             |  2 +-
       clang/lib/Parse/ParseTentative.cpp            |  2 +-
       clang/lib/Parse/Parser.cpp                    |  2 +-
       clang/lib/Sema/Sema.cpp                       |  1 -
       clang/lib/Sema/Sema.h                         |  2 +-
       clang/lib/Sema/SemaCXXScopeSpec.cpp           |  1 -
       clang/lib/Sema/SemaChecking.cpp               |  1 -
       clang/lib/Sema/SemaDecl.cpp                   |  1 -
       clang/lib/Sema/SemaDeclAttr.cpp               |  1 -
       clang/lib/Sema/SemaDeclCXX.cpp                |  1 -
       clang/lib/Sema/SemaDeclObjC.cpp               |  1 -
       clang/lib/Sema/SemaExpr.cpp                   |  1 -
       clang/lib/Sema/SemaExprCXX.cpp                |  1 -
       clang/lib/Sema/SemaExprObjC.cpp               |  1 -
       clang/lib/Sema/SemaInherit.cpp                |  1 -
       clang/lib/Sema/SemaInit.cpp                   |  1 -
       clang/lib/Sema/SemaNamedCast.cpp              |  1 -
       clang/lib/Sema/SemaStmt.cpp                   |  1 -
       clang/lib/Sema/SemaType.cpp                   |  1 -
       49 files changed, 64 insertions(+), 110 deletions(-)
       rename clang/include/clang/{Basic/DiagnosticAST.h => AST/ASTDiagnostic.h} (82%)
       rename clang/include/clang/{Basic/DiagnosticAnalysis.h => Analysis/AnalysisDiagnostic.h} (87%)
       delete mode 100644 clang/include/clang/Basic/DiagnosticDriver.h
       create mode 100644 clang/include/clang/Driver/DriverDiagnostic.h
       rename clang/include/clang/{Basic/DiagnosticLex.h => Lex/LexDiagnostic.h} (87%)
       rename clang/include/clang/{Basic/DiagnosticParse.h => Parse/ParseDiagnostic.h} (87%)
       rename clang/include/clang/{Basic/DiagnosticSema.h => Sema/SemaDiagnostic.h} (87%)
      
      diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
      index fba2df13a37a..f5bb058d0884 100644
      --- a/clang/Driver/clang.cpp
      +++ b/clang/Driver/clang.cpp
      @@ -29,6 +29,7 @@
       #include "clang/Driver/InitHeaderSearch.h"
       #include "clang/Driver/TextDiagnosticBuffer.h"
       #include "clang/Driver/TextDiagnosticPrinter.h"
      +#include "clang/Driver/DriverDiagnostic.h"
       #include "clang/Analysis/PathDiagnostic.h"
       #include "clang/AST/Decl.h"
       #include "clang/AST/TranslationUnit.h"
      @@ -40,7 +41,6 @@
       #include "clang/Basic/FileManager.h"
       #include "clang/Basic/SourceManager.h"
       #include "clang/Basic/TargetInfo.h"
      -#include "clang/Basic/DiagnosticDriver.h"
       #include "llvm/ADT/OwningPtr.h"
       #include "llvm/ADT/SmallPtrSet.h"
       #include "llvm/ADT/StringExtras.h"
      diff --git a/clang/include/clang/Basic/DiagnosticAST.h b/clang/include/clang/AST/ASTDiagnostic.h
      similarity index 82%
      rename from clang/include/clang/Basic/DiagnosticAST.h
      rename to clang/include/clang/AST/ASTDiagnostic.h
      index 1a140167e6ce..8adc2cd0a22b 100644
      --- a/clang/include/clang/Basic/DiagnosticAST.h
      +++ b/clang/include/clang/AST/ASTDiagnostic.h
      @@ -10,15 +10,15 @@
       #ifndef LLVM_CLANG_DIAGNOSTICAST_H
       #define LLVM_CLANG_DIAGNOSTICAST_H
       
      -#include "clang/Basic/DiagnosticAST.h"
      +#include "clang/Basic/Diagnostic.h"
       
       namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      +#include "clang/Basic/DiagnosticCommonKinds.def"
       #define ASTSTART
      -#include "DiagnosticASTKinds.def"
      +#include "clang/Basic/DiagnosticASTKinds.def"
             NUM_BUILTIN_AST_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Basic/DiagnosticAnalysis.h b/clang/include/clang/Analysis/AnalysisDiagnostic.h
      similarity index 87%
      rename from clang/include/clang/Basic/DiagnosticAnalysis.h
      rename to clang/include/clang/Analysis/AnalysisDiagnostic.h
      index 9dc008ec138f..75d39e1d036b 100644
      --- a/clang/include/clang/Basic/DiagnosticAnalysis.h
      +++ b/clang/include/clang/Analysis/AnalysisDiagnostic.h
      @@ -16,9 +16,9 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      +#include "clang/Basic/DiagnosticCommonKinds.def"
       #define ANALYSISSTART
      -#include "DiagnosticAnalysisKinds.def"
      +#include "clang/Basic/DiagnosticAnalysisKinds.def"
             NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Basic/DiagnosticDriver.h b/clang/include/clang/Basic/DiagnosticDriver.h
      deleted file mode 100644
      index 60cdfcdb8aed..000000000000
      --- a/clang/include/clang/Basic/DiagnosticDriver.h
      +++ /dev/null
      @@ -1,57 +0,0 @@
      -//===--- DiagnosticDriver.h - Diagnostics for the driver --------*- C++ -*-===//
      -//
      -//                     The LLVM Compiler Infrastructure
      -//
      -// This file is distributed under the University of Illinois Open Source
      -// License. See LICENSE.TXT for details.
      -//
      -//===----------------------------------------------------------------------===//
      -
      -#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H
      -#define LLVM_CLANG_DIAGNOSTICDRIVER_H
      -
      -#include "clang/Basic/Diagnostic.h"
      -
      -namespace clang {
      -  namespace diag { 
      -    enum {
      -#define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      -      NUM_BUILTIN_DRIVER_DIAGNOSTICS
      -    };
      -  }  // end namespace diag
      -}  // end namespace clang
      -
      -#endif
      -#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H
      -#define LLVM_CLANG_DIAGNOSTICDRIVER_H
      -
      -#include "clang/Basic/Diagnostic.h"
      -
      -namespace clang {
      -  namespace diag { 
      -    enum {
      -#define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      -      NUM_BUILTIN_DRIVER_DIAGNOSTICS
      -    };
      -  }  // end namespace diag
      -}  // end namespace clang
      -
      -#endif
      -#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H
      -#define LLVM_CLANG_DIAGNOSTICDRIVER_H
      -
      -#include "clang/Basic/Diagnostic.h"
      -
      -namespace clang {
      -  namespace diag { 
      -    enum {
      -#define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      -      NUM_BUILTIN_DRIVER_DIAGNOSTICS
      -    };
      -  }  // end namespace diag
      -}  // end namespace clang
      -
      -#endif
      diff --git a/clang/include/clang/Driver/DriverDiagnostic.h b/clang/include/clang/Driver/DriverDiagnostic.h
      new file mode 100644
      index 000000000000..4afe5b23e8df
      --- /dev/null
      +++ b/clang/include/clang/Driver/DriverDiagnostic.h
      @@ -0,0 +1,26 @@
      +//===--- DiagnosticDriver.h - Diagnostics for the driver --------*- C++ -*-===//
      +//
      +//                     The LLVM Compiler Infrastructure
      +//
      +// This file is distributed under the University of Illinois Open Source
      +// License. See LICENSE.TXT for details.
      +//
      +//===----------------------------------------------------------------------===//
      +
      +#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H
      +#define LLVM_CLANG_DIAGNOSTICDRIVER_H
      +
      +#include "clang/Basic/Diagnostic.h"
      +
      +namespace clang {
      +  namespace diag { 
      +    enum {
      +#define DIAG(ENUM,FLAGS,DESC) ENUM,
      +#include "clang/Basic/DiagnosticCommonKinds.def"
      +      NUM_BUILTIN_DRIVER_DIAGNOSTICS
      +    };
      +  }  // end namespace diag
      +}  // end namespace clang
      +
      +#endif
      +
      diff --git a/clang/include/clang/Basic/DiagnosticLex.h b/clang/include/clang/Lex/LexDiagnostic.h
      similarity index 87%
      rename from clang/include/clang/Basic/DiagnosticLex.h
      rename to clang/include/clang/Lex/LexDiagnostic.h
      index 5430b730fb1c..3d285cd6b5ca 100644
      --- a/clang/include/clang/Basic/DiagnosticLex.h
      +++ b/clang/include/clang/Lex/LexDiagnostic.h
      @@ -16,9 +16,9 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      +#include "clang/Basic/DiagnosticCommonKinds.def"
       #define LEXSTART
      -#include "DiagnosticLexKinds.def"
      +#include "clang/Basic/DiagnosticLexKinds.def"
             NUM_BUILTIN_LEX_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Basic/DiagnosticParse.h b/clang/include/clang/Parse/ParseDiagnostic.h
      similarity index 87%
      rename from clang/include/clang/Basic/DiagnosticParse.h
      rename to clang/include/clang/Parse/ParseDiagnostic.h
      index 272f6ef868a4..12a4b2534fa6 100644
      --- a/clang/include/clang/Basic/DiagnosticParse.h
      +++ b/clang/include/clang/Parse/ParseDiagnostic.h
      @@ -16,9 +16,9 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      +#include "clang/Basic/DiagnosticCommonKinds.def"
       #define PARSESTART
      -#include "DiagnosticParseKinds.def"
      +#include "clang/Basic/DiagnosticParseKinds.def"
             NUM_BUILTIN_PARSE_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Basic/DiagnosticSema.h b/clang/include/clang/Sema/SemaDiagnostic.h
      similarity index 87%
      rename from clang/include/clang/Basic/DiagnosticSema.h
      rename to clang/include/clang/Sema/SemaDiagnostic.h
      index c0644a1d37e7..52fa696218db 100644
      --- a/clang/include/clang/Basic/DiagnosticSema.h
      +++ b/clang/include/clang/Sema/SemaDiagnostic.h
      @@ -16,9 +16,9 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "DiagnosticCommonKinds.def"
      +#include "clang/Basic/DiagnosticCommonKinds.def"
       #define SEMASTART
      -#include "DiagnosticSemaKinds.def"
      +#include "clang/Basic/DiagnosticSemaKinds.def"
             NUM_BUILTIN_SEMA_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
      index c444a199f6c3..f07df0a187eb 100644
      --- a/clang/lib/AST/ExprConstant.cpp
      +++ b/clang/lib/AST/ExprConstant.cpp
      @@ -15,7 +15,7 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/RecordLayout.h"
       #include "clang/AST/StmtVisitor.h"
      -#include "clang/Basic/DiagnosticAST.h"
      +#include "clang/AST/ASTDiagnostic.h"
       #include "clang/Basic/TargetInfo.h"
       #include "llvm/Support/Compiler.h"
       using namespace clang;
      diff --git a/clang/lib/Analysis/UninitializedValues.cpp b/clang/lib/Analysis/UninitializedValues.cpp
      index 3947803ee888..9ff99f1fa1fc 100644
      --- a/clang/lib/Analysis/UninitializedValues.cpp
      +++ b/clang/lib/Analysis/UninitializedValues.cpp
      @@ -14,7 +14,7 @@
       #include "clang/Analysis/Analyses/UninitializedValues.h"
       #include "clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h"
       #include "clang/Analysis/LocalCheckers.h"
      -#include "clang/Basic/DiagnosticAnalysis.h"
      +#include "clang/Analysis/AnalysisDiagnostic.h"
       #include "clang/AST/ASTContext.h"
       #include "clang/Analysis/FlowSensitive/DataflowSolver.h"
       #include "llvm/Support/Compiler.h"
      diff --git a/clang/lib/Lex/Lexer.cpp b/clang/lib/Lex/Lexer.cpp
      index 2bf9300e9168..72715c9eedaa 100644
      --- a/clang/lib/Lex/Lexer.cpp
      +++ b/clang/lib/Lex/Lexer.cpp
      @@ -26,7 +26,7 @@
       
       #include "clang/Lex/Lexer.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/SourceManager.h"
       #include "llvm/Support/Compiler.h"
       #include "llvm/Support/MemoryBuffer.h"
      diff --git a/clang/lib/Lex/LiteralSupport.cpp b/clang/lib/Lex/LiteralSupport.cpp
      index b06f9a4cf29c..93b653aae6f2 100644
      --- a/clang/lib/Lex/LiteralSupport.cpp
      +++ b/clang/lib/Lex/LiteralSupport.cpp
      @@ -14,7 +14,7 @@
       
       #include "clang/Lex/LiteralSupport.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/TargetInfo.h"
       #include "llvm/ADT/StringExtras.h"
       using namespace clang;
      diff --git a/clang/lib/Lex/MacroArgs.cpp b/clang/lib/Lex/MacroArgs.cpp
      index 63086ad27473..2646a61e51af 100644
      --- a/clang/lib/Lex/MacroArgs.cpp
      +++ b/clang/lib/Lex/MacroArgs.cpp
      @@ -14,7 +14,7 @@
       #include "MacroArgs.h"
       #include "clang/Lex/MacroInfo.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       using namespace clang;
       
       /// MacroArgs ctor function - This destroys the vector passed in.
      diff --git a/clang/lib/Lex/PPDirectives.cpp b/clang/lib/Lex/PPDirectives.cpp
      index 0ddd2292209f..1ff469b8258e 100644
      --- a/clang/lib/Lex/PPDirectives.cpp
      +++ b/clang/lib/Lex/PPDirectives.cpp
      @@ -15,7 +15,7 @@
       #include "clang/Lex/LiteralSupport.h"
       #include "clang/Lex/HeaderSearch.h"
       #include "clang/Lex/MacroInfo.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/SourceManager.h"
       #include "llvm/ADT/APInt.h"
       using namespace clang;
      diff --git a/clang/lib/Lex/PPExpressions.cpp b/clang/lib/Lex/PPExpressions.cpp
      index 73d677fe15b0..3cba06f46034 100644
      --- a/clang/lib/Lex/PPExpressions.cpp
      +++ b/clang/lib/Lex/PPExpressions.cpp
      @@ -20,7 +20,7 @@
       #include "clang/Lex/MacroInfo.h"
       #include "clang/Lex/LiteralSupport.h"
       #include "clang/Basic/TargetInfo.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "llvm/ADT/APSInt.h"
       using namespace clang;
       
      diff --git a/clang/lib/Lex/PPLexerChange.cpp b/clang/lib/Lex/PPLexerChange.cpp
      index f00283bfbda9..3e02fbd63892 100644
      --- a/clang/lib/Lex/PPLexerChange.cpp
      +++ b/clang/lib/Lex/PPLexerChange.cpp
      @@ -15,7 +15,7 @@
       #include "clang/Lex/Preprocessor.h"
       #include "clang/Lex/HeaderSearch.h"
       #include "clang/Lex/MacroInfo.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/SourceManager.h"
       #include "llvm/Support/MemoryBuffer.h"
       
      diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
      index fb7d22a5813e..776754372d3d 100644
      --- a/clang/lib/Lex/PPMacroExpansion.cpp
      +++ b/clang/lib/Lex/PPMacroExpansion.cpp
      @@ -17,7 +17,7 @@
       #include "clang/Lex/MacroInfo.h"
       #include "clang/Basic/SourceManager.h"
       #include "clang/Basic/FileManager.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include 
       using namespace clang;
       
      diff --git a/clang/lib/Lex/Pragma.cpp b/clang/lib/Lex/Pragma.cpp
      index ad467630b163..87410f9ff4ab 100644
      --- a/clang/lib/Lex/Pragma.cpp
      +++ b/clang/lib/Lex/Pragma.cpp
      @@ -16,7 +16,7 @@
       #include "clang/Lex/HeaderSearch.h"
       #include "clang/Lex/LiteralSupport.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/FileManager.h"
       #include "clang/Basic/SourceManager.h"
       using namespace clang;
      diff --git a/clang/lib/Lex/Preprocessor.cpp b/clang/lib/Lex/Preprocessor.cpp
      index c265c2c75d4b..3861e7d320ee 100644
      --- a/clang/lib/Lex/Preprocessor.cpp
      +++ b/clang/lib/Lex/Preprocessor.cpp
      @@ -30,7 +30,7 @@
       #include "clang/Lex/MacroInfo.h"
       #include "clang/Lex/Pragma.h"
       #include "clang/Lex/ScratchBuffer.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/SourceManager.h"
       #include "clang/Basic/TargetInfo.h"
       #include "llvm/ADT/APFloat.h"
      diff --git a/clang/lib/Lex/PreprocessorLexer.cpp b/clang/lib/Lex/PreprocessorLexer.cpp
      index f75ce429c65d..f9dfad9c808e 100644
      --- a/clang/lib/Lex/PreprocessorLexer.cpp
      +++ b/clang/lib/Lex/PreprocessorLexer.cpp
      @@ -13,7 +13,7 @@
       
       #include "clang/Lex/PreprocessorLexer.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "clang/Basic/SourceManager.h"
       using namespace clang;
       
      diff --git a/clang/lib/Lex/TokenLexer.cpp b/clang/lib/Lex/TokenLexer.cpp
      index eaa49f36b9e2..3ca0fcfa05de 100644
      --- a/clang/lib/Lex/TokenLexer.cpp
      +++ b/clang/lib/Lex/TokenLexer.cpp
      @@ -16,7 +16,7 @@
       #include "clang/Lex/MacroInfo.h"
       #include "clang/Lex/Preprocessor.h"
       #include "clang/Basic/SourceManager.h"
      -#include "clang/Basic/DiagnosticLex.h"
      +#include "clang/Lex/LexDiagnostic.h"
       #include "llvm/ADT/SmallVector.h"
       using namespace clang;
       
      diff --git a/clang/lib/Parse/DeclSpec.cpp b/clang/lib/Parse/DeclSpec.cpp
      index f75e3ea8b8b1..32b00117683c 100644
      --- a/clang/lib/Parse/DeclSpec.cpp
      +++ b/clang/lib/Parse/DeclSpec.cpp
      @@ -12,7 +12,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "clang/Parse/DeclSpec.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Basic/LangOptions.h"
       #include "llvm/ADT/STLExtras.h"
       using namespace clang;
      diff --git a/clang/lib/Parse/ExtensionRAIIObject.h b/clang/lib/Parse/ExtensionRAIIObject.h
      index 4593dcff44e7..928d443b74ca 100644
      --- a/clang/lib/Parse/ExtensionRAIIObject.h
      +++ b/clang/lib/Parse/ExtensionRAIIObject.h
      @@ -14,7 +14,7 @@
       #ifndef LLVM_CLANG_PARSE_EXTENSION_RAII_OBJECT_H
       #define LLVM_CLANG_PARSE_EXTENSION_RAII_OBJECT_H
       
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       
       namespace clang {
       
      diff --git a/clang/lib/Parse/ParseCXXInlineMethods.cpp b/clang/lib/Parse/ParseCXXInlineMethods.cpp
      index bf9b3b2fb50a..4aa923ca009f 100644
      --- a/clang/lib/Parse/ParseCXXInlineMethods.cpp
      +++ b/clang/lib/Parse/ParseCXXInlineMethods.cpp
      @@ -11,7 +11,7 @@
       //
       //===----------------------------------------------------------------------===//
       
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Parse/Parser.h"
       #include "clang/Parse/DeclSpec.h"
       #include "clang/Parse/Scope.h"
      diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
      index eb5cedd5f40e..7b6d8f818522 100644
      --- a/clang/lib/Parse/ParseDecl.cpp
      +++ b/clang/lib/Parse/ParseDecl.cpp
      @@ -12,7 +12,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "clang/Parse/Parser.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Parse/Scope.h"
       #include "ExtensionRAIIObject.h"
       #include "AstGuard.h"
      diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
      index 27b2d74c8503..628331fd1d4d 100644
      --- a/clang/lib/Parse/ParseDeclCXX.cpp
      +++ b/clang/lib/Parse/ParseDeclCXX.cpp
      @@ -12,7 +12,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "clang/Parse/Parser.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Parse/DeclSpec.h"
       #include "clang/Parse/Scope.h"
       #include "AstGuard.h"
      diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
      index 6a2ef36a37e7..f434cfb1f719 100644
      --- a/clang/lib/Parse/ParseExprCXX.cpp
      +++ b/clang/lib/Parse/ParseExprCXX.cpp
      @@ -11,7 +11,7 @@
       //
       //===----------------------------------------------------------------------===//
       
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Parse/Parser.h"
       #include "clang/Parse/DeclSpec.h"
       #include "AstGuard.h"
      diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp
      index 1e14dd6741ad..c654a750ddd6 100644
      --- a/clang/lib/Parse/ParseInit.cpp
      +++ b/clang/lib/Parse/ParseInit.cpp
      @@ -14,7 +14,7 @@
       #include "clang/Parse/Designator.h"
       #include "clang/Parse/Parser.h"
       #include "AstGuard.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "llvm/ADT/SmallString.h"
       using namespace clang;
       
      diff --git a/clang/lib/Parse/ParseObjc.cpp b/clang/lib/Parse/ParseObjc.cpp
      index 2cbb56417b41..5d7d7f100057 100644
      --- a/clang/lib/Parse/ParseObjc.cpp
      +++ b/clang/lib/Parse/ParseObjc.cpp
      @@ -15,7 +15,7 @@
       #include "clang/Parse/DeclSpec.h"
       #include "clang/Parse/Scope.h"
       #include "AstGuard.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "llvm/ADT/SmallVector.h"
       using namespace clang;
       
      diff --git a/clang/lib/Parse/ParsePragma.cpp b/clang/lib/Parse/ParsePragma.cpp
      index 279038c37ef6..01496b31f75f 100644
      --- a/clang/lib/Parse/ParsePragma.cpp
      +++ b/clang/lib/Parse/ParsePragma.cpp
      @@ -12,7 +12,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "ParsePragma.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Lex/Preprocessor.h"
       #include "clang/Parse/Action.h"
       using namespace clang;
      diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
      index ea54e7ed3020..b9a55147b85c 100644
      --- a/clang/lib/Parse/ParseTemplate.cpp
      +++ b/clang/lib/Parse/ParseTemplate.cpp
      @@ -12,7 +12,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "clang/Parse/Parser.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Parse/DeclSpec.h"
       #include "clang/Parse/Scope.h"
       
      diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
      index 5b242d82e754..445dd8b6eff7 100644
      --- a/clang/lib/Parse/ParseTentative.cpp
      +++ b/clang/lib/Parse/ParseTentative.cpp
      @@ -13,7 +13,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "clang/Parse/Parser.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       using namespace clang;
       
       /// isCXXDeclarationStatement - C++-specialized function that disambiguates
      diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
      index 33ce08ef48fa..8685a599d2fd 100644
      --- a/clang/lib/Parse/Parser.cpp
      +++ b/clang/lib/Parse/Parser.cpp
      @@ -12,7 +12,7 @@
       //===----------------------------------------------------------------------===//
       
       #include "clang/Parse/Parser.h"
      -#include "clang/Basic/DiagnosticParse.h"
      +#include "clang/Parse/ParseDiagnostic.h"
       #include "clang/Parse/DeclSpec.h"
       #include "clang/Parse/Scope.h"
       #include "ExtensionRAIIObject.h"
      diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
      index 4f659b6beb80..604173624299 100644
      --- a/clang/lib/Sema/Sema.cpp
      +++ b/clang/lib/Sema/Sema.cpp
      @@ -17,7 +17,6 @@
       #include "clang/AST/DeclObjC.h"
       #include "clang/AST/Expr.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticSema.h"
       using namespace clang;
       
       /// ConvertQualTypeToStringFn - This function is used to pretty print the 
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index f14aba6a4f5f..4a81f71dea39 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -20,7 +20,7 @@
       #include "SemaOverload.h"
       #include "clang/AST/DeclBase.h"
       #include "clang/Parse/Action.h"
      -#include "clang/Basic/DiagnosticSema.h"
      +#include "clang/Sema/SemaDiagnostic.h"
       #include "llvm/ADT/SmallVector.h"
       #include "llvm/ADT/DenseSet.h"
       #include "llvm/ADT/SmallPtrSet.h"
      diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
      index 357dcd7b60cf..cf93571eb231 100644
      --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
      +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
      @@ -14,7 +14,6 @@
       #include "Sema.h"
       #include "clang/AST/ASTContext.h"
       #include "clang/Parse/DeclSpec.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "llvm/ADT/STLExtras.h"
       using namespace clang;
       
      diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
      index 5b15a1a5be56..92cad1029b76 100644
      --- a/clang/lib/Sema/SemaChecking.cpp
      +++ b/clang/lib/Sema/SemaChecking.cpp
      @@ -18,7 +18,6 @@
       #include "clang/AST/ExprCXX.h"
       #include "clang/AST/ExprObjC.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "SemaUtil.h"
       using namespace clang;
       
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 77f99e848f19..7572560be195 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -18,7 +18,6 @@
       #include "clang/AST/DeclObjC.h"
       #include "clang/AST/ExprCXX.h"
       #include "clang/Parse/DeclSpec.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Basic/TargetInfo.h"
       #include "clang/Basic/SourceManager.h"
       // FIXME: layering (ideally, Sema shouldn't be dependent on Lex API's)
      diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
      index c87483dd0c95..bf4549d05bca 100644
      --- a/clang/lib/Sema/SemaDeclAttr.cpp
      +++ b/clang/lib/Sema/SemaDeclAttr.cpp
      @@ -15,7 +15,6 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/DeclObjC.h"
       #include "clang/AST/Expr.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Basic/TargetInfo.h"
       #include "clang/Parse/DeclSpec.h"
       #include 
      diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
      index a61184f66938..1870a8fdd39b 100644
      --- a/clang/lib/Sema/SemaDeclCXX.cpp
      +++ b/clang/lib/Sema/SemaDeclCXX.cpp
      @@ -18,7 +18,6 @@
       #include "clang/AST/TypeOrdering.h"
       #include "clang/AST/StmtVisitor.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Parse/DeclSpec.h"
       #include "llvm/ADT/STLExtras.h"
       #include "llvm/Support/Compiler.h"
      diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
      index fcf9a92acab2..3371e3ea6e20 100644
      --- a/clang/lib/Sema/SemaDeclObjC.cpp
      +++ b/clang/lib/Sema/SemaDeclObjC.cpp
      @@ -14,7 +14,6 @@
       #include "Sema.h"
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/DeclObjC.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Parse/DeclSpec.h"
       
       using namespace clang;
      diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
      index 2eb4605623bb..5ebec0270b50 100644
      --- a/clang/lib/Sema/SemaExpr.cpp
      +++ b/clang/lib/Sema/SemaExpr.cpp
      @@ -18,7 +18,6 @@
       #include "clang/AST/ExprObjC.h"
       #include "clang/Lex/Preprocessor.h"
       #include "clang/Lex/LiteralSupport.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Basic/SourceManager.h"
       #include "clang/Basic/TargetInfo.h"
       #include "clang/Parse/DeclSpec.h"
      diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
      index 743fa12b1868..d0ceb97b3ae9 100644
      --- a/clang/lib/Sema/SemaExprCXX.cpp
      +++ b/clang/lib/Sema/SemaExprCXX.cpp
      @@ -16,7 +16,6 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/Parse/DeclSpec.h"
       #include "clang/Lex/Preprocessor.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Basic/TargetInfo.h"
       #include "llvm/ADT/STLExtras.h"
       using namespace clang;
      diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
      index a19a1d16d0e6..f436e61ee912 100644
      --- a/clang/lib/Sema/SemaExprObjC.cpp
      +++ b/clang/lib/Sema/SemaExprObjC.cpp
      @@ -15,7 +15,6 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/DeclObjC.h"
       #include "clang/AST/ExprObjC.h"
      -#include "clang/Basic/DiagnosticSema.h"
       using namespace clang;
       
       Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs, 
      diff --git a/clang/lib/Sema/SemaInherit.cpp b/clang/lib/Sema/SemaInherit.cpp
      index 307c5275043f..cb58063d840e 100644
      --- a/clang/lib/Sema/SemaInherit.cpp
      +++ b/clang/lib/Sema/SemaInherit.cpp
      @@ -19,7 +19,6 @@
       #include "clang/AST/DeclCXX.h"
       #include "clang/AST/Type.h"
       #include "clang/AST/TypeOrdering.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include 
       #include 
       #include 
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index bb523e179b8a..5dc57751ffb3 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -18,7 +18,6 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/Expr.h"
       #include "clang/AST/ExprCXX.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include 
       using namespace clang;
       
      diff --git a/clang/lib/Sema/SemaNamedCast.cpp b/clang/lib/Sema/SemaNamedCast.cpp
      index cac76b63e4ca..e2137b300129 100644
      --- a/clang/lib/Sema/SemaNamedCast.cpp
      +++ b/clang/lib/Sema/SemaNamedCast.cpp
      @@ -15,7 +15,6 @@
       #include "SemaInherit.h"
       #include "clang/AST/ExprCXX.h"
       #include "clang/AST/ASTContext.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "llvm/ADT/SmallVector.h"
       #include 
       using namespace clang;
      diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
      index c01eceb4ba9e..cf26b90bc477 100644
      --- a/clang/lib/Sema/SemaStmt.cpp
      +++ b/clang/lib/Sema/SemaStmt.cpp
      @@ -17,7 +17,6 @@
       #include "clang/AST/DeclObjC.h"
       #include "clang/AST/Expr.h"
       #include "clang/Basic/TargetInfo.h"
      -#include "clang/Basic/DiagnosticSema.h"
       using namespace clang;
       
       Sema::OwningStmtResult Sema::ActOnExprStmt(ExprArg expr) {
      diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
      index 5d54f463ea19..43f8baae507d 100644
      --- a/clang/lib/Sema/SemaType.cpp
      +++ b/clang/lib/Sema/SemaType.cpp
      @@ -15,7 +15,6 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/DeclObjC.h"
       #include "clang/AST/Expr.h"
      -#include "clang/Basic/DiagnosticSema.h"
       #include "clang/Parse/DeclSpec.h"
       using namespace clang;
       
      -- 
      GitLab
      
      
      From 0f65a585bacb6de5b9979c34d02bf5b7c6f14415 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 05:23:19 +0000
      Subject: [PATCH 408/682] Fix a wart that existed from before we had EXTWARN.
      
      llvm-svn: 63272
      ---
       clang/Driver/clang.cpp                              | 9 ---------
       clang/include/clang/Basic/DiagnosticCommonKinds.def | 4 ++--
       2 files changed, 2 insertions(+), 11 deletions(-)
      
      diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
      index f5bb058d0884..ca91fc682ba3 100644
      --- a/clang/Driver/clang.cpp
      +++ b/clang/Driver/clang.cpp
      @@ -730,15 +730,6 @@ static void InitializeDiagnostics(Diagnostic &Diags) {
         if (!WarnImplicitFunctionDeclaration)
           Diags.setDiagnosticMapping(diag::warn_implicit_function_decl,
                                      diag::MAP_IGNORE);
      -  
      -  // If -pedantic-errors is set, turn extensions that warn by default into
      -  // errors. 
      -  if (ErrorOnExtensions) {
      -    Diags.setDiagnosticMapping(diag::warn_hex_escape_too_large,
      -                               diag::MAP_ERROR);
      -    Diags.setDiagnosticMapping(diag::warn_octal_escape_too_large,
      -                               diag::MAP_ERROR);
      -  }
       }
       
       //===----------------------------------------------------------------------===//
      diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.def b/clang/include/clang/Basic/DiagnosticCommonKinds.def
      index 1bdaf6ab3dad..73863215370f 100644
      --- a/clang/include/clang/Basic/DiagnosticCommonKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.def
      @@ -75,9 +75,9 @@ DIAG(warn_implicit_function_decl, WARNING,
            "implicit declaration of function %0")
       DIAG(err_pp_I_dash_not_supported, ERROR,
            "-I- not supported, please use -iquote instead")
      -DIAG(warn_octal_escape_too_large, WARNING,
      +DIAG(warn_octal_escape_too_large, EXTWARN,
            "octal escape sequence out of range")
      -DIAG(warn_hex_escape_too_large, WARNING,
      +DIAG(warn_hex_escape_too_large, EXTWARN,
            "hex escape sequence out of range")
       DIAG(warn_pp_undef_identifier, WARNING,
            "%0 is not defined, evaluates to 0")
      -- 
      GitLab
      
      
      From 50338007b953759cf8c5b9277d0e0aa91489f096 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Thu, 29 Jan 2009 05:27:31 +0000
      Subject: [PATCH 409/682] - Add DebugLoc to getTargetNode(). - Modify TableGen
       to add the DebugLoc when calling getTargetNode.
      
      (The light-weight wrappers are only temporary. The non-DebugLoc version will be
      removed once the whole debug info stuff is finished with.)
      
      llvm-svn: 63273
      ---
       llvm/include/llvm/CodeGen/SelectionDAG.h      |  56 +++---
       .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 173 ++++++++----------
       llvm/utils/TableGen/DAGISelEmitter.cpp        |   3 +
       3 files changed, 97 insertions(+), 135 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
      index a06158a39b2d..86487cf4a41d 100644
      --- a/llvm/include/llvm/CodeGen/SelectionDAG.h
      +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
      @@ -699,72 +699,60 @@ public:
         /// node of the specified opcode and operands, it returns that node instead of
         /// the current one.
         SDNode *getTargetNode(unsigned Opcode, MVT VT);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT);
      -
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT);
         SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1);
      -
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue Op1);
         SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1, SDValue Op2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1, 
      -                        SDValue Op2);
      -
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                        SDValue Op1, SDValue Op2);
         SDNode *getTargetNode(unsigned Opcode, MVT VT,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
                               const SDValue *Ops, unsigned NumOps);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2);
      -
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2);
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, SDValue Op1);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, 
      -                        SDValue Op1);
      -
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      +                        MVT VT2, SDValue Op1);
         SDNode *getTargetNode(unsigned Opcode, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2,
                               const SDValue *Ops, unsigned NumOps);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL,
      +                        MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2, MVT VT3,
                               const SDValue *Ops, unsigned NumOps);
      -
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, MVT VT4,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      -                        MVT VT4, const SDValue *Ops, unsigned NumOps);
      -
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL,
      +                        MVT VT1, MVT VT2, MVT VT3, MVT VT4,
      +                        const SDValue *Ops, unsigned NumOps);
         SDNode *getTargetNode(unsigned Opcode, const std::vector &ResultTys,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl,
      -                        const std::vector &ResultTys, const SDValue *Ops,
      -                        unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL,
      +                        const std::vector &ResultTys,
      +                        const SDValue *Ops, unsigned NumOps);
       
         /// getNodeIfExists - Get the specified node if it's already available, or
         /// else return NULL.
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      index ab2c8323002b..523518886253 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      @@ -4747,169 +4747,142 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
       /// node of the specified opcode and operands, it returns that node instead of
       /// the current one.
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT) {
      -  return getNode(~Opcode, VT).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT) {
      -  return getNode(~Opcode, dl, VT).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT) {
      +  return getNode(~Opcode, DL, VT).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT, SDValue Op1) {
      -  return getNode(~Opcode, VT, Op1).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Op1);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      -                                    SDValue Op1) {
      -  return getNode(~Opcode, dl, VT, Op1).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +                                    MVT VT, SDValue Op1) {
      +  return getNode(~Opcode, DL, VT, Op1).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           SDValue Op1, SDValue Op2) {
      -  return getNode(~Opcode, VT, Op1, Op2).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Op1, Op2);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
                                           SDValue Op1, SDValue Op2) {
      -  return getNode(~Opcode, dl, VT, Op1, Op2).getNode();
      +  return getNode(~Opcode, DL, VT, Op1, Op2).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
      -                                    SDValue Op1, SDValue Op2,
      -                                    SDValue Op3) {
      -  return getNode(~Opcode, VT, Op1, Op2, Op3).getNode();
      +                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Op1, Op2, Op3);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      -                                    SDValue Op1, SDValue Op2,
      -                                    SDValue Op3) {
      -  return getNode(~Opcode, dl, VT, Op1, Op2, Op3).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      +  return getNode(~Opcode, DL, VT, Op1, Op2, Op3).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getNode(~Opcode, VT, Ops, NumOps).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Ops, NumOps);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getNode(~Opcode, dl, VT, Ops, NumOps).getNode();
      +  return getNode(~Opcode, DL, VT, Ops, NumOps).getNode();
       }
      -
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  SDValue Op;
      -  return getNode(~Opcode, VTs, 2, &Op, 0).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      +                                    MVT VT1, MVT VT2) {
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, 
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
                                           MVT VT1, MVT VT2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Op;
      -  return getNode(~Opcode, dl, VTs, 2, &Op, 0).getNode();
      +  return getNode(~Opcode, DL, VTs, 2, &Op, 0).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  return getNode(~Opcode, VTs, 2, &Op1, 1).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, Op1);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
                                           MVT VT2, SDValue Op1) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  return getNode(~Opcode, dl, VTs, 2, &Op1, 1).getNode();
      +  return getNode(~Opcode, DL, VTs, 2, &Op1, 1).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
      -                                    MVT VT2, SDValue Op1,
      -                                    SDValue Op2) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  SDValue Ops[] = { Op1, Op2 };
      -  return getNode(~Opcode, VTs, 2, Ops, 2).getNode();
      +                                    MVT VT2, SDValue Op1, SDValue Op2) {
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, Op1, Op2);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      -                                    MVT VT2, SDValue Op1,
      -                                    SDValue Op2) {
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      +                                    MVT VT2, SDValue Op1, SDValue Op2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Ops[] = { Op1, Op2 };
      -  return getNode(~Opcode, dl, VTs, 2, Ops, 2).getNode();
      +  return getNode(~Opcode, DL, VTs, 2, Ops, 2).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1,
                                           SDValue Op2, SDValue Op3) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  SDValue Ops[] = { Op1, Op2, Op3 };
      -  return getNode(~Opcode, VTs, 2, Ops, 3).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2,
      +                       Op1, Op2, Op3);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
                                           MVT VT2, SDValue Op1,
                                           SDValue Op2, SDValue Op3) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Ops[] = { Op1, Op2, Op3 };
      -  return getNode(~Opcode, dl, VTs, 2, Ops, 3).getNode();
      +  return getNode(~Opcode, DL, VTs, 2, Ops, 3).getNode();
       }
      -
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      +                                    MVT VT1, MVT VT2,
                                           const SDValue *Ops, unsigned NumOps) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  return getNode(~Opcode, VTs, 2, Ops, NumOps).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2,
      +                       Ops, NumOps);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, 
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
                                           MVT VT1, MVT VT2,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  return getNode(~Opcode, dl, VTs, 2, Ops, NumOps).getNode();
      +  return getNode(~Opcode, DL, VTs, 2, Ops, NumOps).getNode();
       }
      -
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      +                                    MVT VT1, MVT VT2, MVT VT3,
                                           SDValue Op1, SDValue Op2) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      -  SDValue Ops[] = { Op1, Op2 };
      -  return getNode(~Opcode, VTs, 3, Ops, 2).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, VT3,
      +                       Op1, Op2);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
                                           MVT VT1, MVT VT2, MVT VT3,
                                           SDValue Op1, SDValue Op2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
         SDValue Ops[] = { Op1, Op2 };
      -  return getNode(~Opcode, dl, VTs, 3, Ops, 2).getNode();
      +  return getNode(~Opcode, DL, VTs, 3, Ops, 2).getNode();
       }
      -
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
      -                                    SDValue Op1, SDValue Op2,
      -                                    SDValue Op3) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      -  SDValue Ops[] = { Op1, Op2, Op3 };
      -  return getNode(~Opcode, VTs, 3, Ops, 3).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      +                                    MVT VT1, MVT VT2, MVT VT3,
      +                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, VT3,
      +                       Op1, Op2, Op3);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
                                           MVT VT1, MVT VT2, MVT VT3,
      -                                    SDValue Op1, SDValue Op2,
      -                                    SDValue Op3) {
      +                                    SDValue Op1, SDValue Op2, SDValue Op3) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
         SDValue Ops[] = { Op1, Op2, Op3 };
      -  return getNode(~Opcode, dl, VTs, 3, Ops, 3).getNode();
      +  return getNode(~Opcode, DL, VTs, 3, Ops, 3).getNode();
       }
      -
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      +                                    MVT VT1, MVT VT2, MVT VT3,
                                           const SDValue *Ops, unsigned NumOps) {
      -  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      -  return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, VT3,
      +                       Ops, NumOps);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
                                           MVT VT1, MVT VT2, MVT VT3,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      -  return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
      +  return getNode(~Opcode, DL, VTs, 3, Ops, NumOps).getNode();
       }
      -
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
      -                                    MVT VT2, MVT VT3, MVT VT4,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      +                                    MVT VT1, MVT VT2, MVT VT3, MVT VT4,
                                           const SDValue *Ops, unsigned NumOps) {
      -  std::vector VTList;
      -  VTList.push_back(VT1);
      -  VTList.push_back(VT2);
      -  VTList.push_back(VT3);
      -  VTList.push_back(VT4);
      -  const MVT *VTs = getNodeValueTypes(VTList);
      -  return getNode(~Opcode, VTs, 4, Ops, NumOps).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(),
      +                       VT1, VT2, VT3, VT4, Ops, NumOps);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      -                                    MVT VT2, MVT VT3, MVT VT4,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +                                    MVT VT1, MVT VT2, MVT VT3, MVT VT4,
                                           const SDValue *Ops, unsigned NumOps) {
         std::vector VTList;
         VTList.push_back(VT1);
      @@ -4917,21 +4890,19 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
         VTList.push_back(VT3);
         VTList.push_back(VT4);
         const MVT *VTs = getNodeValueTypes(VTList);
      -  return getNode(~Opcode, dl, VTs, 4, Ops, NumOps).getNode();
      +  return getNode(~Opcode, DL, VTs, 4, Ops, NumOps).getNode();
       }
      -
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
                                           const std::vector &ResultTys,
                                           const SDValue *Ops, unsigned NumOps) {
      -  const MVT *VTs = getNodeValueTypes(ResultTys);
      -  return getNode(~Opcode, VTs, ResultTys.size(),
      -                 Ops, NumOps).getNode();
      +  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(),
      +                       ResultTys, Ops, NumOps);
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
                                           const std::vector &ResultTys,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(ResultTys);
      -  return getNode(~Opcode, dl, VTs, ResultTys.size(),
      +  return getNode(~Opcode, DL, VTs, ResultTys.size(),
                        Ops, NumOps).getNode();
       }
       
      diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp
      index d6bcce2703f8..ace15e5180de 100644
      --- a/llvm/utils/TableGen/DAGISelEmitter.cpp
      +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp
      @@ -1059,6 +1059,9 @@ public:
       
             std::string Code = "Opc" + utostr(OpcNo);
       
      +      if (!isRoot || (InputHasChain && !NodeHasChain))
      +        Code += ", N.getDebugLoc()";
      +
             emitOpcode(II.Namespace + "::" + II.TheDef->getName());
       
             // Output order: results, chain, flags
      -- 
      GitLab
      
      
      From b05ce78c5145f76d55fa08741270b712078de279 Mon Sep 17 00:00:00 2001
      From: Owen Anderson 
      Date: Thu, 29 Jan 2009 05:28:55 +0000
      Subject: [PATCH 410/682] Add support for aggressive load-use-store folding. 
       This takes care of the vast majority of code size regressions introduced by
       pre-alloc-splitting.
      
      llvm-svn: 63274
      ---
       llvm/lib/CodeGen/PreAllocSplitting.cpp | 104 ++++++++++++++++++++-----
       1 file changed, 85 insertions(+), 19 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      index 2a009b0aef81..f4540889f6aa 100644
      --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp
      +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      @@ -37,8 +37,9 @@
       using namespace llvm;
       
       static cl::opt PreSplitLimit("pre-split-limit", cl::init(-1), cl::Hidden);
      +static cl::opt DeadSplitLimit("dead-split-limit", cl::init(-1), cl::Hidden);
       
      -STATISTIC(NumTotalSplits, "Number of intervals split");
      +STATISTIC(NumSplits, "Number of intervals split");
       STATISTIC(NumRemats, "Number of intervals split by rematerialization");
       STATISTIC(NumFolds, "Number of intervals split with spill folding");
       STATISTIC(NumRenumbers, "Number of intervals renumbered into new registers");
      @@ -77,8 +78,6 @@ namespace {
       
           // Def2SpillMap - A map from a def instruction index to spill index.
           DenseMap Def2SpillMap;
      -    
      -    unsigned NumSplits;
       
         public:
           static char ID;
      @@ -162,8 +161,8 @@ namespace {
           void RenumberValno(VNInfo* VN);
           void ReconstructLiveInterval(LiveInterval* LI);
           bool removeDeadSpills(SmallPtrSet& split);
      -    unsigned getNumberOfSpills(SmallPtrSet& MIs,
      -                               unsigned Reg, int FrameIndex);
      +    unsigned getNumberOfNonSpills(SmallPtrSet& MIs,
      +                               unsigned Reg, int FrameIndex, bool& TwoAddr);
           VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use,
                                          MachineBasicBlock* MBB,
                                          LiveInterval* LI,
      @@ -789,6 +788,10 @@ void PreAllocSplitting::RenumberValno(VNInfo* VN) {
           MO.setReg(NewVReg);
         }
         
      +  // The renumbered vreg shares a stack slot with the old register.
      +  if (IntervalSSMap.count(CurrLI->reg))
      +    IntervalSSMap[NewVReg] = IntervalSSMap[CurrLI->reg];
      +  
         NumRenumbers++;
       }
       
      @@ -1042,19 +1045,24 @@ PreAllocSplitting::SplitRegLiveIntervals(const TargetRegisterClass **RCs,
         return Change;
       }
       
      -unsigned PreAllocSplitting::getNumberOfSpills(
      +unsigned PreAllocSplitting::getNumberOfNonSpills(
                                         SmallPtrSet& MIs,
      -                                  unsigned Reg, int FrameIndex) {
      -  unsigned Spills = 0;
      +                                  unsigned Reg, int FrameIndex,
      +                                  bool& FeedsTwoAddr) {
      +  unsigned NonSpills = 0;
         for (SmallPtrSet::iterator UI = MIs.begin(), UE = MIs.end();
      -       UI != UI; ++UI) {
      +       UI != UE; ++UI) {
           int StoreFrameIndex;
           unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
      -    if (StoreVReg == Reg && StoreFrameIndex == FrameIndex)
      -      Spills++;
      +    if (StoreVReg != Reg || StoreFrameIndex != FrameIndex)
      +      NonSpills++;
      +    
      +    int DefIdx = (*UI)->findRegisterDefOperandIdx(Reg);
      +    if (DefIdx != -1 && (*UI)->isRegReDefinedByTwoAddr(DefIdx))
      +      FeedsTwoAddr = true;
         }
         
      -  return Spills;
      +  return NonSpills;
       }
       
       /// removeDeadSpills - After doing splitting, filter through all intervals we've
      @@ -1077,6 +1085,10 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
           
           for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(),
                VE = (*LI)->vni_end(); VI != VE; ++VI) {
      +      
      +      if (DeadSplitLimit != -1 && (int)NumDeadSpills == DeadSplitLimit) 
      +        return changed;
      +      
             VNInfo* CurrVN = *VI;
             if (CurrVN->hasPHIKill) continue;
             
      @@ -1096,9 +1108,67 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               continue;
             }
             
      -      unsigned SpillCount = getNumberOfSpills(VNUseCount[CurrVN],
      -                                              (*LI)->reg, FrameIndex);
      -      if (SpillCount != VNUseCount[CurrVN].size()) continue;
      +      bool FeedsTwoAddr = false;
      +      unsigned NonSpillCount = getNumberOfNonSpills(VNUseCount[CurrVN],
      +                                                    (*LI)->reg, FrameIndex,
      +                                                    FeedsTwoAddr);
      +      
      +      if (NonSpillCount == 1 && !FeedsTwoAddr) {
      +        SmallPtrSet::iterator UI = VNUseCount[CurrVN].begin();
      +        int StoreFrameIndex;
      +        unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
      +        while (UI != VNUseCount[CurrVN].end() &&
      +               (StoreVReg == (*LI)->reg && StoreFrameIndex == FrameIndex)) {
      +          ++UI;
      +          if (UI != VNUseCount[CurrVN].end())
      +            StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
      +        }
      +        
      +        if (UI == VNUseCount[CurrVN].end()) continue;
      +        
      +        MachineInstr* use = *UI;
      +        
      +        int OpIdx = use->findRegisterUseOperandIdx((*LI)->reg, false);
      +        if (OpIdx == -1) continue;
      +
      +        SmallVector Ops;
      +        Ops.push_back(OpIdx);
      +
      +        if (!TII->canFoldMemoryOperand(use, Ops)) continue;
      +
      +        MachineInstr* NewMI =
      +                          TII->foldMemoryOperand(*use->getParent()->getParent(),  
      +                                                 use, Ops, FrameIndex);
      +
      +        if (!NewMI) continue;
      +
      +        LIs->RemoveMachineInstrFromMaps(DefMI);
      +        LIs->ReplaceMachineInstrInMaps(use, NewMI);
      +        (*LI)->removeValNo(CurrVN);
      +
      +        DefMI->eraseFromParent();
      +        MachineBasicBlock* MBB = use->getParent();
      +        NewMI = MBB->insert(MBB->erase(use), NewMI);
      +        VNUseCount[CurrVN].erase(use);
      +        
      +        for (SmallPtrSet::iterator II = 
      +             VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end();
      +             II != IE; ++II) {
      +          LIs->RemoveMachineInstrFromMaps(*II);
      +          (*II)->eraseFromParent();
      +        }
      +
      +        for (DenseMap >::iterator
      +             VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
      +          if (VI->second.erase(use))
      +            VI->second.insert(NewMI);
      +
      +        NumDeadSpills++;
      +        changed = true;
      +        continue;
      +      }
      +      
      +      if (NonSpillCount) continue;
               
             for (SmallPtrSet::iterator UI = 
                  VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end();
      @@ -1193,7 +1263,6 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
         LSs    = &getAnalysis();
       
         bool MadeChange = false;
      -  NumSplits = 0;
       
         // Make sure blocks are numbered in order.
         MF.RenumberBlocks();
      @@ -1220,9 +1289,6 @@ bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
         }
       
         MadeChange |= removeDeadSpills(Split);
      -  
      -  if (NumSplits)
      -    NumTotalSplits += NumSplits;
       
         return MadeChange;
       }
      -- 
      GitLab
      
      
      From 4f7a5dafceb00dba451d8033285fa31d2bcfa9d9 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 05:30:38 +0000
      Subject: [PATCH 411/682] update the project file for headers moving
      
      llvm-svn: 63275
      ---
       clang/clang.xcodeproj/project.pbxproj | 26 ++++++++++++++------------
       1 file changed, 14 insertions(+), 12 deletions(-)
      
      diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj
      index 226c4fcdc20b..f4be191e7894 100644
      --- a/clang/clang.xcodeproj/project.pbxproj
      +++ b/clang/clang.xcodeproj/project.pbxproj
      @@ -533,18 +533,19 @@
       		DE928B7E0C0A615600231DA4 /* CodeGenModule.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenModule.cpp; path = lib/CodeGen/CodeGenModule.cpp; sourceTree = ""; tabWidth = 2; };
       		DE928B800C0A615B00231DA4 /* CodeGenFunction.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = CodeGenFunction.h; path = lib/CodeGen/CodeGenFunction.h; sourceTree = ""; tabWidth = 2; usesTabs = 0; };
       		DE928B820C0A616000231DA4 /* CodeGenFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = CodeGenFunction.cpp; path = lib/CodeGen/CodeGenFunction.cpp; sourceTree = ""; tabWidth = 2; };
      -		DEA099FD0F302C65000C2258 /* DiagnosticAnalysis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticAnalysis.h; sourceTree = ""; };
       		DEA099FE0F302C65000C2258 /* DiagnosticAnalysisKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticAnalysisKinds.def; sourceTree = ""; };
      -		DEA099FF0F302C65000C2258 /* DiagnosticAST.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticAST.h; sourceTree = ""; };
       		DEA09A000F302C65000C2258 /* DiagnosticASTKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticASTKinds.def; sourceTree = ""; };
       		DEA09A010F302C65000C2258 /* DiagnosticCommonKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticCommonKinds.def; sourceTree = ""; };
      -		DEA09A020F302C65000C2258 /* DiagnosticDriver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticDriver.h; sourceTree = ""; };
      -		DEA09A030F302C65000C2258 /* DiagnosticLex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLex.h; sourceTree = ""; };
       		DEA09A040F302C65000C2258 /* DiagnosticLexKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticLexKinds.def; sourceTree = ""; };
      -		DEA09A050F302C65000C2258 /* DiagnosticParse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticParse.h; sourceTree = ""; };
       		DEA09A060F302C65000C2258 /* DiagnosticParseKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticParseKinds.def; sourceTree = ""; };
      -		DEA09A070F302C65000C2258 /* DiagnosticSema.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticSema.h; sourceTree = ""; };
       		DEA09A080F302C65000C2258 /* DiagnosticSemaKinds.def */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = DiagnosticSemaKinds.def; sourceTree = ""; };
      +		DEA09A6E0F31756F000C2258 /* ASTDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASTDiagnostic.h; path = clang/AST/ASTDiagnostic.h; sourceTree = ""; };
      +		DEA09A710F317594000C2258 /* CompileOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CompileOptions.h; path = clang/Driver/CompileOptions.h; sourceTree = ""; };
      +		DEA09A720F317594000C2258 /* DriverDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DriverDiagnostic.h; path = clang/Driver/DriverDiagnostic.h; sourceTree = ""; };
      +		DEA09A730F317594000C2258 /* ManagerRegistry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ManagerRegistry.h; path = clang/Driver/ManagerRegistry.h; sourceTree = ""; };
      +		DEA09A830F3175BF000C2258 /* LexDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LexDiagnostic.h; sourceTree = ""; };
      +		DEA09A860F3175CA000C2258 /* ParseDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ParseDiagnostic.h; path = clang/Parse/ParseDiagnostic.h; sourceTree = ""; };
      +		DEA09A890F3175D9000C2258 /* SemaDiagnostic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SemaDiagnostic.h; path = clang/Sema/SemaDiagnostic.h; sourceTree = ""; };
       		DEA0EBD90DD2D3C8007A02A9 /* RewriteMacros.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteMacros.cpp; path = Driver/RewriteMacros.cpp; sourceTree = ""; };
       		DEAEE98A0A5A2B970045101B /* MultipleIncludeOpt.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = MultipleIncludeOpt.h; sourceTree = ""; };
       		DEAEED4A0A5AF89A0045101B /* NOTES.txt */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = NOTES.txt; sourceTree = ""; };
      @@ -747,6 +748,9 @@
       		3596033E0E49493700C6282B /* Driver */ = {
       			isa = PBXGroup;
       			children = (
      +				DEA09A710F317594000C2258 /* CompileOptions.h */,
      +				DEA09A720F317594000C2258 /* DriverDiagnostic.h */,
      +				DEA09A730F317594000C2258 /* ManagerRegistry.h */,
       				355BD0420EBFAEC7001A9DFF /* PathDiagnosticClients.h */,
       				350F4B490E5F36EE00A21EA9 /* InitHeaderSearch.h */,
       				3596033F0E49494D00C6282B /* TextDiagnosticBuffer.h */,
      @@ -814,6 +818,7 @@
       				DE06E8130A8FF9330050E87E /* Action.h */,
       				DE17336F0B068DC60080B521 /* DeclSpec.h */,
       				DE3B92230EB5152000D01046 /* Designator.h */,
      +				DEA09A860F3175CA000C2258 /* ParseDiagnostic.h */,
       				DE1F22020A7D852A00FBF588 /* Parser.h */,
       				DE06BECA0A854E4B0050E87E /* Scope.h */,
       			);
      @@ -908,6 +913,7 @@
       			isa = PBXGroup;
       			children = (
       				DE67E7270C02109800F66BC5 /* ParseAST.h */,
      +				DEA09A890F3175D9000C2258 /* SemaDiagnostic.h */,
       			);
       			name = Sema;
       			sourceTree = "";
      @@ -985,6 +991,7 @@
       				DEC8D9A30A94346E00353FCA /* AST.h */,
       				35BFBD2B0C9EDE1E006CB644 /* ASTConsumer.h */,
       				DE75ED280B044DC90020CF81 /* ASTContext.h */,
      +				DEA09A6E0F31756F000C2258 /* ASTDiagnostic.h */,
       				1A72BEAC0D641E9400B085E9 /* Attr.h */,
       				DED676D00B6C786700AAD4A3 /* Builtins.def */,
       				DED676F90B6C797B00AAD4A3 /* Builtins.h */,
      @@ -1068,18 +1075,12 @@
       			isa = PBXGroup;
       			children = (
       				DED7D7310A524295003AD0FB /* Diagnostic.h */,
      -				DEA099FD0F302C65000C2258 /* DiagnosticAnalysis.h */,
       				DEA099FE0F302C65000C2258 /* DiagnosticAnalysisKinds.def */,
      -				DEA099FF0F302C65000C2258 /* DiagnosticAST.h */,
       				DEA09A000F302C65000C2258 /* DiagnosticASTKinds.def */,
       				DEA09A010F302C65000C2258 /* DiagnosticCommonKinds.def */,
      -				DEA09A020F302C65000C2258 /* DiagnosticDriver.h */,
       				DED7D7320A524295003AD0FB /* DiagnosticKinds.def */,
      -				DEA09A030F302C65000C2258 /* DiagnosticLex.h */,
       				DEA09A040F302C65000C2258 /* DiagnosticLexKinds.def */,
      -				DEA09A050F302C65000C2258 /* DiagnosticParse.h */,
       				DEA09A060F302C65000C2258 /* DiagnosticParseKinds.def */,
      -				DEA09A070F302C65000C2258 /* DiagnosticSema.h */,
       				DEA09A080F302C65000C2258 /* DiagnosticSemaKinds.def */,
       				DED7D7330A524295003AD0FB /* FileManager.h */,
       				DE3986EF0CB8D4B300223765 /* IdentifierTable.h */,
      @@ -1103,6 +1104,7 @@
       				DE3450D60AEB543100DBC861 /* DirectoryLookup.h */,
       				DE704BD10D1647E7009C7762 /* HeaderMap.h */,
       				DE344AB70AE5DF6D00DBC861 /* HeaderSearch.h */,
      +				DEA09A830F3175BF000C2258 /* LexDiagnostic.h */,
       				DED7D73B0A524295003AD0FB /* Lexer.h */,
       				1A869A6E0BA2164C008DA07A /* LiteralSupport.h */,
       				DED7D73E0A524295003AD0FB /* MacroInfo.h */,
      -- 
      GitLab
      
      
      From a590802ed6ae47134b8dd3ececf28428040ff729 Mon Sep 17 00:00:00 2001
      From: Owen Anderson 
      Date: Thu, 29 Jan 2009 05:41:02 +0000
      Subject: [PATCH 412/682] Comments are good. :-)
      
      llvm-svn: 63276
      ---
       llvm/lib/CodeGen/PreAllocSplitting.cpp | 33 +++++++++++++++++++++++---
       1 file changed, 30 insertions(+), 3 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      index f4540889f6aa..44819aabbab7 100644
      --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp
      +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      @@ -1070,10 +1070,14 @@ unsigned PreAllocSplitting::getNumberOfNonSpills(
       bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
         bool changed = false;
         
      +  // Walk over all of the live intervals that were touched by the splitter,
      +  // and see if we can do any DCE and/or folding.
         for (SmallPtrSet::iterator LI = split.begin(),
              LE = split.end(); LI != LE; ++LI) {
           DenseMap > VNUseCount;
           
      +    // First, collect all the uses of the vreg, and sort them by their
      +    // reaching definition (VNInfo).
           for (MachineRegisterInfo::use_iterator UI = MRI->use_begin((*LI)->reg),
                UE = MRI->use_end(); UI != UE; ++UI) {
             unsigned index = LIs->getInstructionIndex(&*UI);
      @@ -1083,6 +1087,8 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
             VNUseCount[LR->valno].insert(&*UI);
           }
           
      +    // Now, take the definitions (VNInfo's) one at a time and try to DCE 
      +    // and/or fold them away.
           for (LiveInterval::vni_iterator VI = (*LI)->vni_begin(),
                VE = (*LI)->vni_end(); VI != VE; ++VI) {
             
      @@ -1090,15 +1096,24 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               return changed;
             
             VNInfo* CurrVN = *VI;
      +      
      +      // We don't currently try to handle definitions with PHI kills, because
      +      // it would involve processing more than one VNInfo at once.
             if (CurrVN->hasPHIKill) continue;
             
      +      // We also don't try to handle the results of PHI joins, since there's
      +      // no defining instruction to analyze.
             unsigned DefIdx = CurrVN->def;
             if (DefIdx == ~0U || DefIdx == ~1U) continue;
           
      +      // We're only interested in eliminating cruft introduced by the splitter,
      +      // is of the form load-use or load-use-store.  First, check that the
      +      // definition is a load, and remember what stack slot we loaded it from.
             MachineInstr* DefMI = LIs->getInstructionFromIndex(DefIdx);
             int FrameIndex;
             if (!TII->isLoadFromStackSlot(DefMI, FrameIndex)) continue;
             
      +      // If the definition has no uses at all, just DCE it.
             if (VNUseCount[CurrVN].size() == 0) {
               LIs->RemoveMachineInstrFromMaps(DefMI);
               (*LI)->removeValNo(CurrVN);
      @@ -1108,12 +1123,17 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               continue;
             }
             
      +      // Second, get the number of non-store uses of the definition, as well as
      +      // a flag indicating whether it feeds into a later two-address definition.
             bool FeedsTwoAddr = false;
             unsigned NonSpillCount = getNumberOfNonSpills(VNUseCount[CurrVN],
                                                           (*LI)->reg, FrameIndex,
                                                           FeedsTwoAddr);
             
      +      // If there's one non-store use and it doesn't feed a two-addr, then
      +      // this is a load-use-store case that we can try to fold.
             if (NonSpillCount == 1 && !FeedsTwoAddr) {
      +        // Start by finding the non-store use MachineInstr.
               SmallPtrSet::iterator UI = VNUseCount[CurrVN].begin();
               int StoreFrameIndex;
               unsigned StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
      @@ -1123,17 +1143,15 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
                 if (UI != VNUseCount[CurrVN].end())
                   StoreVReg = TII->isStoreToStackSlot(*UI, StoreFrameIndex);
               }
      -        
               if (UI == VNUseCount[CurrVN].end()) continue;
               
               MachineInstr* use = *UI;
               
      +        // Attempt to fold it away!
               int OpIdx = use->findRegisterUseOperandIdx((*LI)->reg, false);
               if (OpIdx == -1) continue;
      -
               SmallVector Ops;
               Ops.push_back(OpIdx);
      -
               if (!TII->canFoldMemoryOperand(use, Ops)) continue;
       
               MachineInstr* NewMI =
      @@ -1142,6 +1160,7 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
       
               if (!NewMI) continue;
       
      +        // Update relevant analyses.
               LIs->RemoveMachineInstrFromMaps(DefMI);
               LIs->ReplaceMachineInstrInMaps(use, NewMI);
               (*LI)->removeValNo(CurrVN);
      @@ -1151,9 +1170,14 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               NewMI = MBB->insert(MBB->erase(use), NewMI);
               VNUseCount[CurrVN].erase(use);
               
      +        // Remove deleted instructions.  Note that we need to remove them from 
      +        // the VNInfo->use map as well, just to be safe.
               for (SmallPtrSet::iterator II = 
                    VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end();
                    II != IE; ++II) {
      +          for (DenseMap >::iterator
      +               VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
      +            VI->second.erase(*II);
                 LIs->RemoveMachineInstrFromMaps(*II);
                 (*II)->eraseFromParent();
               }
      @@ -1168,8 +1192,11 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               continue;
             }
             
      +      // If there's more than one non-store instruction, we can't profitably
      +      // fold it, so bail.
             if (NonSpillCount) continue;
               
      +      // Otherwise, this is a load-store case, so DCE them.
             for (SmallPtrSet::iterator UI = 
                  VNUseCount[CurrVN].begin(), UE = VNUseCount[CurrVN].end();
                  UI != UI; ++UI) {
      -- 
      GitLab
      
      
      From df49b7cf2f0c6fc01509446e72181efca2a28023 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 06:12:22 +0000
      Subject: [PATCH 413/682] ccc: Honor -ccc-clang for generic GCC toolchain.
      
      llvm-svn: 63277
      ---
       clang/tools/ccc/ccclib/ToolChain.py | 17 ++++++++++++++++-
       clang/tools/ccc/ccclib/Tools.py     | 14 ++++++++------
       2 files changed, 24 insertions(+), 7 deletions(-)
      
      diff --git a/clang/tools/ccc/ccclib/ToolChain.py b/clang/tools/ccc/ccclib/ToolChain.py
      index 564b6173facc..73b0127e1448 100644
      --- a/clang/tools/ccc/ccclib/ToolChain.py
      +++ b/clang/tools/ccc/ccclib/ToolChain.py
      @@ -205,9 +205,10 @@ class Generic_GCC_ToolChain(ToolChain):
           def __init__(self, driver):
               super(Generic_GCC_ToolChain, self).__init__(driver)
               cc = Tools.GCC_CompileTool()
      +        self.clangTool = Tools.Clang_CompileTool(self)
               self.toolMap = {
                   Phases.PreprocessPhase : Tools.GCC_PreprocessTool(),
      -            Phases.AnalyzePhase : Tools.Clang_CompileTool(self),
      +            Phases.AnalyzePhase : self.clangTool,
                   Phases.SyntaxOnlyPhase : cc,
                   Phases.EmitLLVMPhase : cc,
                   Phases.CompilePhase : cc,
      @@ -218,4 +219,18 @@ class Generic_GCC_ToolChain(ToolChain):
       
           def selectTool(self, action):
               assert isinstance(action, Phases.JobAction)
      +
      +        if self.driver.cccClang:
      +            if (action.inputs[0].type in (Types.CType, Types.CTypeNoPP,
      +                                          Types.ObjCType, Types.ObjCTypeNoPP) and
      +                (isinstance(action.phase, Phases.PreprocessPhase) or
      +                 isinstance(action.phase, Phases.CompilePhase) or
      +                 isinstance(action.phase, Phases.SyntaxOnlyPhase) or
      +                 isinstance(action.phase, Phases.EmitLLVMPhase))):
      +                return self.clangTool
      +            elif (action.inputs[0].type in (Types.CHeaderType, Types.CHeaderNoPPType,
      +                                            Types.ObjCHeaderType, Types.ObjCHeaderNoPPType) and
      +                  isinstance(action.phase, Phases.PrecompilePhase)):
      +                return self.clangTool
      +
               return self.toolMap[action.phase.__class__]
      diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py
      index 62720624cb1c..a24255c652f6 100644
      --- a/clang/tools/ccc/ccclib/Tools.py
      +++ b/clang/tools/ccc/ccclib/Tools.py
      @@ -247,12 +247,14 @@ class Clang_CompileTool(Tool):
                                 not arglist.getLastArg(arglist.parser.staticOption) and
                                 not arglist.getLastArg(arglist.parser.m_dynamicNoPicOption)))
       
      -            archName = arglist.getValue(arch)
      -            if (archName == 'x86_64' or 
      -                picEnabled):
      -                cmd_args.append('--relocation-model=pic')
      -            elif not arglist.getLastArg(arglist.parser.m_dynamicNoPicOption):
      -                cmd_args.append('--relocation-model=static')
      +            # FIXME: This needs to tie into a platform hook.
      +            if arch:
      +                archName = arglist.getValue(arch)
      +                if (archName == 'x86_64' or 
      +                    picEnabled):
      +                    cmd_args.append('--relocation-model=pic')
      +                elif not arglist.getLastArg(arglist.parser.m_dynamicNoPicOption):
      +                    cmd_args.append('--relocation-model=static')
       
                   if arglist.getLastArg(arglist.parser.f_timeReportOption):
                       cmd_args.append('--time-passes')
      -- 
      GitLab
      
      
      From b6f953e22a8321dcd31b648e9f7be80d74448f76 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 06:16:07 +0000
      Subject: [PATCH 414/682] Evaluate casts to complex.  - Lift (int,float) ->
       (int,float) conversion into separate routines.
      
       - Fix handling of, e.g., char -> _Complex int, which was producing a
         _Complex char value instead.
      
      llvm-svn: 63278
      ---
       clang/lib/AST/ExprConstant.cpp | 133 +++++++++++++++++++++++++--------
       1 file changed, 103 insertions(+), 30 deletions(-)
      
      diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
      index f07df0a187eb..eae3f64ac963 100644
      --- a/clang/lib/AST/ExprConstant.cpp
      +++ b/clang/lib/AST/ExprConstant.cpp
      @@ -87,6 +87,49 @@ static bool HandleConversionToBool(Expr* E, bool& Result, EvalInfo &Info) {
         return false;
       }
       
      +static APSInt HandleFloatToIntCast(QualType DestType, QualType SrcType, 
      +                                   APFloat &Value, ASTContext &Ctx) {
      +  unsigned DestWidth = Ctx.getIntWidth(DestType);
      +  // Determine whether we are converting to unsigned or signed.
      +  bool DestSigned = DestType->isSignedIntegerType();
      +  
      +  // FIXME: Warning for overflow.
      +  uint64_t Space[4];
      +  bool ignored;
      +  (void)Value.convertToInteger(Space, DestWidth, DestSigned,
      +                               llvm::APFloat::rmTowardZero, &ignored);
      +  return APSInt(llvm::APInt(DestWidth, 4, Space), !DestSigned);
      +}
      +
      +static APFloat HandleFloatToFloatCast(QualType DestType, QualType SrcType, 
      +                                      APFloat &Value, ASTContext &Ctx) {
      +  bool ignored;
      +  APFloat Result = Value;
      +  Result.convert(Ctx.getFloatTypeSemantics(DestType), 
      +                 APFloat::rmNearestTiesToEven, &ignored);
      +  return Result;
      +}
      +
      +static APSInt HandleIntToIntCast(QualType DestType, QualType SrcType, 
      +                                 APSInt &Value, ASTContext &Ctx) {
      +  unsigned DestWidth = Ctx.getIntWidth(DestType);
      +  APSInt Result = Value;
      +  // Figure out if this is a truncate, extend or noop cast.
      +  // If the input is signed, do a sign extend, noop, or truncate.
      +  Result.extOrTrunc(DestWidth);
      +  Result.setIsUnsigned(DestType->isUnsignedIntegerType());
      +  return Result;
      +}
      +
      +static APFloat HandleIntToFloatCast(QualType DestType, QualType SrcType, 
      +                                    APSInt &Value, ASTContext &Ctx) {
      +
      +  APFloat Result(Ctx.getFloatTypeSemantics(DestType), 1);
      +  Result.convertFromAPInt(Value, Value.isSigned(),
      +                          APFloat::rmNearestTiesToEven);
      +  return Result;
      +}
      +
       //===----------------------------------------------------------------------===//
       // LValue Evaluation
       //===----------------------------------------------------------------------===//
      @@ -484,9 +527,7 @@ public:
         bool VisitUnaryOperator(const UnaryOperator *E);
         bool VisitConditionalOperator(const ConditionalOperator *E);
       
      -  bool VisitCastExpr(CastExpr* E) {
      -    return HandleCast(E);
      -  }
      +  bool VisitCastExpr(CastExpr* E);
         bool VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E);
       
         bool VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *E) {
      @@ -515,7 +556,6 @@ public:
         }
       
       private:
      -  bool HandleCast(CastExpr* E);
         unsigned GetAlignOfExpr(const Expr *E);
         unsigned GetAlignOfType(QualType T);
       };
      @@ -996,7 +1036,7 @@ bool IntExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
         
       /// HandleCast - This is used to evaluate implicit or explicit casts where the
       /// result type is integer.
      -bool IntExprEvaluator::HandleCast(CastExpr *E) {
      +bool IntExprEvaluator::VisitCastExpr(CastExpr *E) {
         Expr *SubExpr = E->getSubExpr();
         QualType DestType = E->getType();
       
      @@ -1016,11 +1056,8 @@ bool IntExprEvaluator::HandleCast(CastExpr *E) {
         if (SubExpr->getType()->isIntegralType()) {
           if (!Visit(SubExpr))
             return false;
      -    
      -    // Figure out if this is a truncate, extend or noop cast.
      -    // If the input is signed, do a sign extend, noop, or truncate.
      -    Result.extOrTrunc(DestWidth);
      -    Result.setIsUnsigned(DestType->isUnsignedIntegerType());
      +
      +    Result = HandleIntToIntCast(DestType, SubExpr->getType(), Result, Info.Ctx);
           return true;
         }
         
      @@ -1046,16 +1083,7 @@ bool IntExprEvaluator::HandleCast(CastExpr *E) {
         if (!EvaluateFloat(SubExpr, F, Info))
           return Error(E->getExprLoc(), diag::note_invalid_subexpr_in_ice, E);
         
      -  // Determine whether we are converting to unsigned or signed.
      -  bool DestSigned = DestType->isSignedIntegerType();
      -  
      -  // FIXME: Warning for overflow.
      -  uint64_t Space[4];
      -  bool ignored;
      -  (void)F.convertToInteger(Space, DestWidth, DestSigned,
      -                           llvm::APFloat::rmTowardZero, &ignored);
      -  Result = llvm::APInt(DestWidth, 4, Space);
      -  Result.setIsUnsigned(!DestSigned);
      +  Result = HandleFloatToIntCast(DestType, SubExpr->getType(), F, Info.Ctx);
         return true;
       }
       
      @@ -1199,22 +1227,19 @@ bool FloatExprEvaluator::VisitFloatingLiteral(const FloatingLiteral *E) {
       bool FloatExprEvaluator::VisitCastExpr(CastExpr *E) {
         Expr* SubExpr = E->getSubExpr();
         
      -  const llvm::fltSemantics& destSemantics =
      -      Info.Ctx.getFloatTypeSemantics(E->getType());
         if (SubExpr->getType()->isIntegralType()) {
           APSInt IntResult;
           if (!EvaluateInteger(E, IntResult, Info))
             return false;
      -    Result = APFloat(destSemantics, 1);
      -    Result.convertFromAPInt(IntResult, IntResult.isSigned(),
      -                            APFloat::rmNearestTiesToEven);
      +    Result = HandleIntToFloatCast(E->getType(), SubExpr->getType(), 
      +                                  IntResult, Info.Ctx);
           return true;
         }
         if (SubExpr->getType()->isRealFloatingType()) {
           if (!Visit(SubExpr))
             return false;
      -    bool ignored;
      -    Result.convert(destSemantics, APFloat::rmNearestTiesToEven, &ignored);
      +    Result = HandleFloatToFloatCast(E->getType(), SubExpr->getType(),
      +                                    Result, Info.Ctx);
           return true;
         }
       
      @@ -1275,24 +1300,72 @@ public:
       
         APValue VisitCastExpr(CastExpr *E) {
           Expr* SubExpr = E->getSubExpr();
      +    QualType EltType = E->getType()->getAsComplexType()->getElementType();
      +    QualType SubType = SubExpr->getType();
       
      -    if (SubExpr->getType()->isRealFloatingType()) {
      +    if (SubType->isRealFloatingType()) {
             APFloat Result(0.0);
                            
             if (!EvaluateFloat(SubExpr, Result, Info))
               return APValue();
             
      +      // Apply float conversion if necessary.
      +      Result = HandleFloatToFloatCast(EltType, SubType, Result, Info.Ctx);
             return APValue(Result, 
                            APFloat(Result.getSemantics(), APFloat::fcZero, false));
      -    } else if (SubExpr->getType()->isIntegerType()) {
      +    } else if (SubType->isIntegerType()) {
             APSInt Result;
                            
             if (!EvaluateInteger(SubExpr, Result, Info))
               return APValue();
      -      
      +
      +      // Apply integer conversion if necessary.
      +      Result = HandleIntToIntCast(EltType, SubType, Result, Info.Ctx);
             llvm::APSInt Zero(Result.getBitWidth(), !Result.isSigned());
             Zero = 0;
             return APValue(Result, Zero);
      +    } else if (const ComplexType *CT = SubType->getAsComplexType()) {
      +      APValue Src;
      +                     
      +      if (!EvaluateComplex(SubExpr, Src, Info))
      +        return APValue();
      +
      +      QualType SrcType = CT->getElementType();
      +
      +      if (Src.isComplexFloat()) {
      +        if (EltType->isRealFloatingType()) {
      +          return APValue(HandleFloatToFloatCast(EltType, SrcType, 
      +                                                Src.getComplexFloatReal(),
      +                                                Info.Ctx),
      +                         HandleFloatToFloatCast(EltType, SrcType, 
      +                                                Src.getComplexFloatImag(),
      +                                                Info.Ctx));
      +        } else {
      +          return APValue(HandleFloatToIntCast(EltType, SrcType,
      +                                              Src.getComplexFloatReal(),
      +                                              Info.Ctx),
      +                         HandleFloatToIntCast(EltType, SrcType, 
      +                                              Src.getComplexFloatImag(),
      +                                              Info.Ctx)); 
      +        }
      +      } else {
      +        assert(Src.isComplexInt() && "Invalid evaluate result.");
      +        if (EltType->isRealFloatingType()) {
      +          return APValue(HandleIntToFloatCast(EltType, SrcType, 
      +                                              Src.getComplexIntReal(),
      +                                              Info.Ctx),
      +                         HandleIntToFloatCast(EltType, SrcType, 
      +                                              Src.getComplexIntImag(),
      +                                              Info.Ctx));
      +        } else {
      +          return APValue(HandleIntToIntCast(EltType, SrcType,
      +                                            Src.getComplexIntReal(),
      +                                            Info.Ctx),
      +                         HandleIntToIntCast(EltType, SrcType, 
      +                                            Src.getComplexIntImag(),
      +                                            Info.Ctx)); 
      +        }
      +      }
           }
       
           // FIXME: Handle more casts.
      -- 
      GitLab
      
      
      From 7bb8dfae53e949e0431b355a3ebd0f2c36fdaae7 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 06:20:19 +0000
      Subject: [PATCH 415/682] Use xcc (instead of clang directly).
      
      llvm-svn: 63279
      ---
       clang/utils/ABITest/return-types/Makefile | 11 +++++------
       1 file changed, 5 insertions(+), 6 deletions(-)
      
      diff --git a/clang/utils/ABITest/return-types/Makefile b/clang/utils/ABITest/return-types/Makefile
      index 1a993b741be9..c2c8bc11085e 100644
      --- a/clang/utils/ABITest/return-types/Makefile
      +++ b/clang/utils/ABITest/return-types/Makefile
      @@ -12,8 +12,8 @@ CFLAGS := -std=gnu99
       
       X_COMPILER := llvm-gcc
       X_LL_CFLAGS := -emit-llvm -S
      -Y_COMPILER := clang
      -Y_LL_CFLAGS := -emit-llvm
      +Y_COMPILER := xcc -ccc-clang
      +Y_LL_CFLAGS := -emit-llvm -S
       CC := gcc
       
       X_CFLAGS := -m32
      @@ -81,15 +81,14 @@ test.%.x.o: test.%.c
       	$(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $<
       .PRECIOUS: test.%.y.o
       test.%.y.o: test.%.c
      -	$(Y_COMPILER) -S $(CFLAGS) $(Y_CFLAGS) -o $@.s $<
      -	as $(Y_CFLAGS) -o $@ $@.s
      +	$(Y_COMPILER) -c $(CFLAGS) $(Y_CFLAGS) -o $@ $<
       
       .PRECIOUS: test.%.x.defs
       test.%.x.defs: test.%.a.x.ll
      -	grep '^define ' $< > $@
      +	-grep '^define ' $< > $@
       .PRECIOUS: test.%.y.defs
       test.%.y.defs: test.%.a.y.ll
      -	grep '^define ' $< > $@
      +	-grep '^define ' $< > $@
       
       .PRECIOUS: test.%.a.x.ll
       test.%.a.x.ll: test.%.a.c
      -- 
      GitLab
      
      
      From 74f2425b899f228fcb5c19acbf8e2598006e4878 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 06:43:41 +0000
      Subject: [PATCH 416/682] Evaluate ==,!= for complex types.
      
      llvm-svn: 63280
      ---
       clang/lib/AST/ExprConstant.cpp  | 44 +++++++++++++++++++++++++++++++++
       clang/test/CodeGen/const-init.c | 31 ++++++++++++++++++++---
       2 files changed, 72 insertions(+), 3 deletions(-)
      
      diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
      index eae3f64ac963..97985205077b 100644
      --- a/clang/lib/AST/ExprConstant.cpp
      +++ b/clang/lib/AST/ExprConstant.cpp
      @@ -729,6 +729,50 @@ bool IntExprEvaluator::VisitBinaryOperator(const BinaryOperator *E) {
       
         QualType LHSTy = E->getLHS()->getType();
         QualType RHSTy = E->getRHS()->getType();
      +
      +  if (LHSTy->isAnyComplexType()) {
      +    assert(RHSTy->isAnyComplexType() && "Invalid comparison");
      +    APValue LHS, RHS;
      +
      +    if (!EvaluateComplex(E->getLHS(), LHS, Info))
      +      return false;
      +
      +    if (!EvaluateComplex(E->getRHS(), RHS, Info))
      +      return false;
      +
      +    if (LHS.isComplexFloat()) {
      +      APFloat::cmpResult CR_r = 
      +        LHS.getComplexFloatReal().compare(RHS.getComplexFloatReal());
      +      APFloat::cmpResult CR_i = 
      +        LHS.getComplexFloatImag().compare(RHS.getComplexFloatImag());
      +
      +      Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
      +      if (E->getOpcode() == BinaryOperator::EQ)
      +        Result = (CR_r == APFloat::cmpEqual &&
      +                  CR_i == APFloat::cmpEqual);
      +      else if (E->getOpcode() == BinaryOperator::NE)
      +        Result = ((CR_r == APFloat::cmpGreaterThan || 
      +                   CR_r == APFloat::cmpLessThan) &&
      +                  (CR_i == APFloat::cmpGreaterThan || 
      +                   CR_i == APFloat::cmpLessThan));
      +      else
      +        assert(0 && "Invalid complex compartison.");
      +      Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
      +      return true;
      +    } else {
      +      Result.zextOrTrunc(getIntTypeSizeInBits(E->getType()));
      +      if (E->getOpcode() == BinaryOperator::EQ)
      +        Result = (LHS.getComplexIntReal() == RHS.getComplexIntReal() &&
      +                  LHS.getComplexIntImag() == RHS.getComplexIntImag());
      +      else if (E->getOpcode() == BinaryOperator::NE)
      +        Result = (LHS.getComplexIntReal() != RHS.getComplexIntReal() ||
      +                  LHS.getComplexIntImag() != RHS.getComplexIntImag());
      +      else
      +        assert(0 && "Invalid complex compartison.");
      +      Result.setIsUnsigned(E->getType()->isUnsignedIntegerType());
      +      return true;
      +    }
      +  }
         
         if (LHSTy->isRealFloatingType() &&
             RHSTy->isRealFloatingType()) {
      diff --git a/clang/test/CodeGen/const-init.c b/clang/test/CodeGen/const-init.c
      index 3aabcfe60894..c98cfd4ca229 100644
      --- a/clang/test/CodeGen/const-init.c
      +++ b/clang/test/CodeGen/const-init.c
      @@ -1,4 +1,4 @@
      -// RUN: clang -verify -emit-llvm -o %t %s
      +// RUN: clang -verify -emit-llvm -o %t %s &&
       
       #include 
       
      @@ -22,5 +22,30 @@ union s2 {
       
       int g0 = (int)(&(((union s2 *) 0)->f0.f0) - 0);
       
      -_Complex int g1 = 1 + 10i;
      -_Complex double g2 = 1.0 + 10.0i;
      +// RUN: grep '@g1x = global { double, double } { double 1.000000e+00, double 0.000000e+00 }' %t &&
      +_Complex double g1x = 1.0f;
      +// RUN: grep '@g1y = global { double, double } { double 0.000000e+00, double 1.000000e+00 }' %t &&
      +_Complex double g1y = 1.0fi;
      +// RUN: grep '@g1 = global { i8, i8 } { i8 1, i8 10 }' %t &&
      +_Complex char g1 = (char) 1 + (char) 10 * 1i;
      +// RUN: grep '@g2 = global { i32, i32 } { i32 1, i32 10 }' %t &&
      +_Complex int g2 = 1 + 10i;
      +// RUN: grep '@g3 = global { float, float } { float 1.000000e+00, float 1.000000e+01 }' %t &&
      +_Complex float g3 = 1.0 + 10.0i;
      +// RUN: grep '@g4 = global { double, double } { double 1.000000e+00, double 1.000000e+01 }' %t &&
      +_Complex double g4 = 1.0 + 10.0i;
      +// RUN: grep '@g5 = global { i32, i32 } zeroinitializer' %t &&
      +_Complex int g5 = (2 + 3i) == (5 + 7i);
      +// RUN: grep '@g6 = global { double, double } { double -1.100000e+01, double 2.900000e+01 }' %t &&
      +_Complex double g6 = (2.0 + 3.0i) * (5.0 + 7.0i);
      +// RUN: grep '@g7 = global i32 1' %t &&
      +int g7 = (2 + 3i) * (5 + 7i) == (-11 + 29i);
      +// RUN: grep '@g8 = global i32 1' %t &&
      +int g8 = (2.0 + 3.0i) * (5.0 + 7.0i) == (-11.0 + 29.0i);
      +// RUN: grep '@g9 = global i32 0' %t &&
      +int g9 = (2 + 3i) * (5 + 7i) != (-11 + 29i);
      +// RUN: grep '@g10 = global i32 0' %t &&
      +int g10 = (2.0 + 3.0i) * (5.0 + 7.0i) != (-11.0 + 29.0i);
      +
      +
      +// RUN: true
      -- 
      GitLab
      
      
      From dc8b4b059460580d79bda91a8be6edffe1f052e5 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 06:44:03 +0000
      Subject: [PATCH 417/682] Fix typo
      
      llvm-svn: 63281
      ---
       clang/lib/CodeGen/CGExprComplex.cpp | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
      index ab6dc31a93e5..73fceedee5fe 100644
      --- a/clang/lib/CodeGen/CGExprComplex.cpp
      +++ b/clang/lib/CodeGen/CGExprComplex.cpp
      @@ -269,7 +269,7 @@ ComplexPairTy ComplexExprEmitter::EmitComplexToComplexCast(ComplexPairTy Val,
         SrcType = SrcType->getAsComplexType()->getElementType();
         DestType = DestType->getAsComplexType()->getElementType();
       
      -  // C99 6.3.1.6: When a value of complextype is converted to another
      +  // C99 6.3.1.6: When a value of complex type is converted to another
         // complex type, both the real and imaginary parts follow the conversion
         // rules for the corresponding real types.
         Val.first = CGF.EmitScalarConversion(Val.first, SrcType, DestType);
      -- 
      GitLab
      
      
      From 36790cf29a4cae524feac7f6f72f26f0173c9704 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 06:55:46 +0000
      Subject: [PATCH 418/682] Fix -Wimplicit-function-declaration, which required
       some refactoring and changes in various diagnostics code.
      
      llvm-svn: 63282
      ---
       clang/Driver/clang.cpp                        |  6 ++-
       clang/include/clang/AST/ASTDiagnostic.h       |  1 -
       .../clang/Analysis/AnalysisDiagnostic.h       |  1 -
       clang/include/clang/Basic/Diagnostic.h        |  8 ++++
       clang/include/clang/Driver/DriverDiagnostic.h |  3 +-
       clang/include/clang/Lex/LexDiagnostic.h       |  1 -
       clang/include/clang/Parse/ParseDiagnostic.h   |  1 -
       clang/include/clang/Sema/SemaDiagnostic.h     |  2 +-
       clang/lib/Basic/Diagnostic.cpp                | 37 +++++--------------
       9 files changed, 25 insertions(+), 35 deletions(-)
      
      diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
      index ca91fc682ba3..77d5ef7082ad 100644
      --- a/clang/Driver/clang.cpp
      +++ b/clang/Driver/clang.cpp
      @@ -35,6 +35,7 @@
       #include "clang/AST/TranslationUnit.h"
       #include "clang/CodeGen/ModuleBuilder.h"
       #include "clang/Sema/ParseAST.h"
      +#include "clang/Sema/SemaDiagnostic.h"
       #include "clang/AST/ASTConsumer.h"
       #include "clang/Parse/Parser.h"
       #include "clang/Lex/HeaderSearch.h"
      @@ -727,7 +728,10 @@ static void InitializeDiagnostics(Diagnostic &Diags) {
         if (!WarnUndefMacros)
           Diags.setDiagnosticMapping(diag::warn_pp_undef_identifier,diag::MAP_IGNORE);
           
      -  if (!WarnImplicitFunctionDeclaration)
      +  if (WarnImplicitFunctionDeclaration)
      +    Diags.setDiagnosticMapping(diag::ext_implicit_function_decl,
      +                               diag::MAP_WARNING);
      +  else
           Diags.setDiagnosticMapping(diag::warn_implicit_function_decl,
                                      diag::MAP_IGNORE);
       }
      diff --git a/clang/include/clang/AST/ASTDiagnostic.h b/clang/include/clang/AST/ASTDiagnostic.h
      index 8adc2cd0a22b..ddb5b404e4ad 100644
      --- a/clang/include/clang/AST/ASTDiagnostic.h
      +++ b/clang/include/clang/AST/ASTDiagnostic.h
      @@ -16,7 +16,6 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "clang/Basic/DiagnosticCommonKinds.def"
       #define ASTSTART
       #include "clang/Basic/DiagnosticASTKinds.def"
             NUM_BUILTIN_AST_DIAGNOSTICS
      diff --git a/clang/include/clang/Analysis/AnalysisDiagnostic.h b/clang/include/clang/Analysis/AnalysisDiagnostic.h
      index 75d39e1d036b..1f2f08910056 100644
      --- a/clang/include/clang/Analysis/AnalysisDiagnostic.h
      +++ b/clang/include/clang/Analysis/AnalysisDiagnostic.h
      @@ -16,7 +16,6 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "clang/Basic/DiagnosticCommonKinds.def"
       #define ANALYSISSTART
       #include "clang/Basic/DiagnosticAnalysisKinds.def"
             NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
      diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
      index c57e1a9a89cf..d9d32bcc5d2f 100644
      --- a/clang/include/clang/Basic/Diagnostic.h
      +++ b/clang/include/clang/Basic/Diagnostic.h
      @@ -43,6 +43,14 @@ namespace clang {
           /// diag::kind - All of the diagnostics that can be emitted by the frontend.
           typedef unsigned kind;
       
      +    // Get typedefs for common diagnostics.
      +    enum {
      +#define DIAG(ENUM,FLAGS,DESC) ENUM,
      +#include "clang/Basic/DiagnosticCommonKinds.def"
      +      NUM_BUILTIN_COMMON_DIAGNOSTICS
      +#undef DIAG
      +    };
      +      
           /// Enum values that allow the client to map NOTEs, WARNINGs, and EXTENSIONs
           /// to either MAP_IGNORE (nothing), MAP_WARNING (emit a warning), MAP_ERROR
           /// (emit as an error), or MAP_DEFAULT (handle the default way).
      diff --git a/clang/include/clang/Driver/DriverDiagnostic.h b/clang/include/clang/Driver/DriverDiagnostic.h
      index 4afe5b23e8df..459d17da4e47 100644
      --- a/clang/include/clang/Driver/DriverDiagnostic.h
      +++ b/clang/include/clang/Driver/DriverDiagnostic.h
      @@ -15,8 +15,7 @@
       namespace clang {
         namespace diag { 
           enum {
      -#define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "clang/Basic/DiagnosticCommonKinds.def"
      +// FIXME: REMOVE??
             NUM_BUILTIN_DRIVER_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Lex/LexDiagnostic.h b/clang/include/clang/Lex/LexDiagnostic.h
      index 3d285cd6b5ca..202605fe5ce5 100644
      --- a/clang/include/clang/Lex/LexDiagnostic.h
      +++ b/clang/include/clang/Lex/LexDiagnostic.h
      @@ -16,7 +16,6 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "clang/Basic/DiagnosticCommonKinds.def"
       #define LEXSTART
       #include "clang/Basic/DiagnosticLexKinds.def"
             NUM_BUILTIN_LEX_DIAGNOSTICS
      diff --git a/clang/include/clang/Parse/ParseDiagnostic.h b/clang/include/clang/Parse/ParseDiagnostic.h
      index 12a4b2534fa6..52a89e89041e 100644
      --- a/clang/include/clang/Parse/ParseDiagnostic.h
      +++ b/clang/include/clang/Parse/ParseDiagnostic.h
      @@ -16,7 +16,6 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "clang/Basic/DiagnosticCommonKinds.def"
       #define PARSESTART
       #include "clang/Basic/DiagnosticParseKinds.def"
             NUM_BUILTIN_PARSE_DIAGNOSTICS
      diff --git a/clang/include/clang/Sema/SemaDiagnostic.h b/clang/include/clang/Sema/SemaDiagnostic.h
      index 52fa696218db..2819641ac939 100644
      --- a/clang/include/clang/Sema/SemaDiagnostic.h
      +++ b/clang/include/clang/Sema/SemaDiagnostic.h
      @@ -16,9 +16,9 @@ namespace clang {
         namespace diag { 
           enum {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#include "clang/Basic/DiagnosticCommonKinds.def"
       #define SEMASTART
       #include "clang/Basic/DiagnosticSemaKinds.def"
      +#undef DIAG
             NUM_BUILTIN_SEMA_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
      index ee0345b18d8a..6e39beb0c89e 100644
      --- a/clang/lib/Basic/Diagnostic.cpp
      +++ b/clang/lib/Basic/Diagnostic.cpp
      @@ -36,21 +36,6 @@ enum {
         class_mask = 0x07
       };
       
      -namespace clang {
      -  namespace diag {
      -    enum _kind{
      -#define DIAG(ENUM,FLAGS,DESC) ENUM,
      -#define LEXSTART
      -#define PARSESTART
      -#define ASTSTART
      -#define SEMASTART
      -#define ANALYSISSTART
      -#include "clang/Basic/DiagnosticKinds.def"
      -      NUM_BUILTIN_DIAGNOSTICS = DIAG_UPPER_LIMIT
      -    };
      -  }
      -}
      -
       /// DiagnosticFlags - A set of flags, or'd together, that describe the
       /// diagnostic.
       #define DIAG(ENUM,FLAGS,DESC) FLAGS,
      @@ -83,7 +68,7 @@ static unsigned char DiagnosticFlagsAnalysis[] = {
       /// getDiagClass - Return the class field of the diagnostic.
       ///
       static unsigned getBuiltinDiagClass(unsigned DiagID) {
      -  assert(DiagID < diag::NUM_BUILTIN_DIAGNOSTICS &&
      +  assert(DiagID < DIAG_UPPER_LIMIT &&
                "Diagnostic ID out of range!");
         unsigned res;
         if (DiagID < DIAG_START_LEX)
      @@ -145,16 +130,16 @@ namespace clang {
             /// getDescription - Return the description of the specified custom
             /// diagnostic.
             const char *getDescription(unsigned DiagID) const {
      -        assert(this && DiagID-diag::NUM_BUILTIN_DIAGNOSTICS < DiagInfo.size() &&
      +        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
                      "Invalid diagnosic ID");
      -        return DiagInfo[DiagID-diag::NUM_BUILTIN_DIAGNOSTICS].second.c_str();
      +        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].second.c_str();
             }
             
             /// getLevel - Return the level of the specified custom diagnostic.
             Diagnostic::Level getLevel(unsigned DiagID) const {
      -        assert(this && DiagID-diag::NUM_BUILTIN_DIAGNOSTICS < DiagInfo.size() &&
      +        assert(this && DiagID-DIAG_UPPER_LIMIT < DiagInfo.size() &&
                      "Invalid diagnosic ID");
      -        return DiagInfo[DiagID-diag::NUM_BUILTIN_DIAGNOSTICS].first;
      +        return DiagInfo[DiagID-DIAG_UPPER_LIMIT].first;
             }
             
             unsigned getOrCreateDiagID(Diagnostic::Level L, const char *Message,
      @@ -166,7 +151,7 @@ namespace clang {
                 return I->second;
               
               // If not, assign a new ID.
      -        unsigned ID = DiagInfo.size()+diag::NUM_BUILTIN_DIAGNOSTICS;
      +        unsigned ID = DiagInfo.size()+DIAG_UPPER_LIMIT;
               DiagIDs.insert(std::make_pair(D, ID));
               DiagInfo.push_back(D);
       
      @@ -231,16 +216,14 @@ unsigned Diagnostic::getCustomDiagID(Level L, const char *Message) {
       /// level of the specified diagnostic ID is a Note, Warning, or Extension.
       /// Note that this only works on builtin diagnostics, not custom ones.
       bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) {
      -  return DiagID < diag::NUM_BUILTIN_DIAGNOSTICS && 
      -         getBuiltinDiagClass(DiagID) < ERROR;
      +  return DiagID < DIAG_UPPER_LIMIT && getBuiltinDiagClass(DiagID) < ERROR;
       }
       
       
       /// getDescription - Given a diagnostic ID, return a description of the
       /// issue.
       const char *Diagnostic::getDescription(unsigned DiagID) const {
      -  if (DiagID < diag::NUM_BUILTIN_DIAGNOSTICS)
      -  {
      +  if (DiagID < DIAG_UPPER_LIMIT) {
           if (DiagID < DIAG_START_LEX)
             return DiagnosticTextCommon[DiagID];
           else if (DiagID < DIAG_START_PARSE)
      @@ -263,7 +246,7 @@ const char *Diagnostic::getDescription(unsigned DiagID) const {
       /// the DiagnosticClient.
       Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
         // Handle custom diagnostics, which cannot be mapped.
      -  if (DiagID >= diag::NUM_BUILTIN_DIAGNOSTICS)
      +  if (DiagID >= DIAG_UPPER_LIMIT)
           return CustomDiagInfo->getLevel(DiagID);
         
         unsigned DiagClass = getBuiltinDiagClass(DiagID);
      @@ -324,7 +307,7 @@ void Diagnostic::ProcessDiag() {
         // ignore extensions and warnings in -Werror and -pedantic-errors modes,
         // which *map* warnings/extensions to errors.
         if (SuppressSystemWarnings &&
      -      Info.getID() < diag::NUM_BUILTIN_DIAGNOSTICS &&
      +      Info.getID() < DIAG_UPPER_LIMIT &&
             getBuiltinDiagClass(Info.getID()) != ERROR &&
             Info.getLocation().isValid() &&
             Info.getLocation().getSpellingLoc().isInSystemHeader())
      -- 
      GitLab
      
      
      From 8e6652affceeb34237bf9470296ff22be3ee9891 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 07:22:20 +0000
      Subject: [PATCH 419/682] x86_64 ABI: Classify _Complex ints as integer.
      
      llvm-svn: 63283
      ---
       clang/lib/CodeGen/CGCall.cpp | 8 +++++++-
       1 file changed, 7 insertions(+), 1 deletion(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index 72ba7f879af5..6d21622b166f 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -471,7 +471,13 @@ void X86_64ABIInfo::classify(QualType Ty,
         } else if (const ComplexType *CT = Ty->getAsComplexType()) {
           QualType ET = CT->getElementType();
           
      -    if (ET == Context.FloatTy) 
      +    if (ET->isIntegerType()) {
      +      unsigned Size = Context.getTypeSize(Ty);
      +      if (Size <= 64)
      +        Lo = Integer;
      +      else if (Size <= 128)
      +        Lo = Hi = Integer;
      +    } else if (ET == Context.FloatTy) 
             Lo = SSE;
           else if (ET == Context.DoubleTy)
             Lo = Hi = SSE;
      -- 
      GitLab
      
      
      From 227e1a77ff53c141af3ed3921ecd5761ea089316 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 07:36:07 +0000
      Subject: [PATCH 420/682] x86_64: Support cases which map to returning multiple
       values in LLVM (e.g., _Complex double -> { double, double } return).
      
      llvm-svn: 63285
      ---
       clang/lib/CodeGen/CGCall.cpp | 9 +++++----
       1 file changed, 5 insertions(+), 4 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index 6d21622b166f..dcff31739e03 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -155,7 +155,6 @@ public:
           return ABIArgInfo(Ignore);
         }
         static ABIArgInfo getCoerce(const llvm::Type *T) { 
      -    assert(T->isSingleValueType() && "Can only coerce to simple types");
           return ABIArgInfo(Coerce, T);
         }
         static ABIArgInfo getByVal(unsigned Alignment) {
      @@ -541,9 +540,11 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
       
         case NoClass: break;
         case Integer:
      -    assert(0 && "FIXME: Implement MRV"); break;
      +    ResType = llvm::StructType::get(ResType, llvm::Type::Int64Ty, NULL);
      +    break;
         case SSE:    
      -    assert(0 && "FIXME: Implement MRV"); break;
      +    ResType = llvm::StructType::get(ResType, llvm::Type::DoubleTy, NULL);
      +    break;
       
           // AMD64-ABI 3.2.3p4: Rule 5. If the class is SSEUP, the eightbyte
           // is passed in the upper half of the last used SSE register.
      @@ -555,7 +556,7 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
           break;
       
           // AMD64-ABI 3.2.3p4: Rule 7. If the class is X87UP, the value is
      -    // returned together with the previos X87 value in %st0.
      +    // returned together with the previous X87 value in %st0.
           //
           // X87UP should always be preceeded by X87, so we don't need to do
           // anything here.
      -- 
      GitLab
      
      
      From 676fdd81d5e98e88fe831bd241c95da4b7208d8f Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 07:36:46 +0000
      Subject: [PATCH 421/682] ABITest: Fix test value generation for unions.
      
      llvm-svn: 63286
      ---
       clang/utils/ABITest/ABITestGen.py | 9 ++++++++-
       1 file changed, 8 insertions(+), 1 deletion(-)
      
      diff --git a/clang/utils/ABITest/ABITestGen.py b/clang/utils/ABITest/ABITestGen.py
      index 8f922d7e52f3..5b9756b54509 100755
      --- a/clang/utils/ABITest/ABITestGen.py
      +++ b/clang/utils/ABITest/ABITestGen.py
      @@ -193,9 +193,16 @@ class TypePrinter:
                       yield '(%s) -1'%(t.name,)
                       yield '(%s) 1'%(t.name,)
               elif isinstance(t, RecordType):
      -            fieldValues = [list(self.getTestValues(f)) for f in t.fields]
                   if not t.fields:
                       yield '{ }'
      +                return
      +            # FIXME: Use designated initializers to access non-first
      +            # fields of unions.
      +            if t.isUnion:
      +                for v in self.getTestValues(t.fields[0]):
      +                    yield '{ %s }' % v
      +                return
      +            fieldValues = [list(self.getTestValues(f)) for f in t.fields]
                   for i,values in enumerate(fieldValues):
                       for v in values:
                           elements = map(random.choice,fieldValues)
      -- 
      GitLab
      
      
      From 17aa9415347445e54294d961ed4480ccae38d9dd Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 08:13:58 +0000
      Subject: [PATCH 422/682] x86_64 ABI: Implement classification for records.  -
       This is my best initial guess at what the "spec" means, although it is not   
       particularly clear on a number of points. Will refine through testing.
      
      llvm-svn: 63292
      ---
       clang/lib/CodeGen/CGCall.cpp | 103 +++++++++++++++++++++++++++++++++++
       1 file changed, 103 insertions(+)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index dcff31739e03..ee854f6ccee7 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -19,6 +19,7 @@
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/Decl.h"
       #include "clang/AST/DeclObjC.h"
      +#include "clang/AST/RecordLayout.h"
       #include "llvm/ADT/StringExtras.h"
       #include "llvm/Attributes.h"
       #include "llvm/Support/CommandLine.h"
      @@ -482,6 +483,108 @@ void X86_64ABIInfo::classify(QualType Ty,
             Lo = Hi = SSE;
           else if (ET == Context.LongDoubleTy)
             Lo = ComplexX87;
      +  } else if (const RecordType *RT = Ty->getAsRecordType()) {
      +    unsigned Size = Context.getTypeSize(Ty);
      +    
      +    // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
      +    // than two eightbytes, ..., it has class MEMORY.
      +    if (Size > 128)
      +      return;
      +
      +    const RecordDecl *RD = RT->getDecl();
      +
      +    // Assume variable sized types are passed in memory.
      +    if (RD->hasFlexibleArrayMember())
      +      return;
      +
      +    const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
      +    
      +    // Reset Lo class, this will be recomputed.
      +    Lo = NoClass;
      +    unsigned idx = 0;
      +    for (RecordDecl::field_iterator i = RD->field_begin(), 
      +           e = RD->field_end(); i != e; ++i, ++idx) {
      +      unsigned Offset = Layout.getFieldOffset(idx);
      +
      +      //  AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
      +      //  fields, it has class MEMORY.
      +      if (Offset % Context.getTypeAlign(i->getType())) {
      +        Lo = Memory;
      +        return;
      +      }
      +
      +      // Determine which half of the structure we are classifying.
      +      //
      +      // AMD64-ABI 3.2.3p2: Rule 3. f the size of the aggregate
      +      // exceeds a single eightbyte, each is classified
      +      // separately. Each eightbyte gets initialized to class
      +      // NO_CLASS.
      +      Class &Target = Offset < 64 ? Lo : Hi;
      +
      +      // Classify this field.
      +      Class FieldLo, FieldHi;
      +      classify(i->getType(), Context, FieldLo, FieldHi);
      +      
      +      // Merge the lo field classifcation.
      +      //
      +      // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is
      +      // classified recursively so that always two fields are
      +      // considered. The resulting class is calculated according to
      +      // the classes of the fields in the eightbyte:
      +      //
      +      // (a) If both classes are equal, this is the resulting class.
      +      //
      +      // (b) If one of the classes is NO_CLASS, the resulting class is
      +      // the other class.
      +      //
      +      // (c) If one of the classes is MEMORY, the result is the MEMORY
      +      // class.
      +      //
      +      // (d) If one of the classes is INTEGER, the result is the
      +      // INTEGER.
      +      //
      +      // (e) If one of the classes is X87, X87UP, COMPLEX_X87 class,
      +      // MEMORY is used as class.
      +      //
      +      // (f) Otherwise class SSE is used.
      +      if (Target == FieldLo || FieldLo == NoClass) ;
      +      else if (Target == NoClass)
      +        Target = FieldLo;
      +      else if (FieldLo == Memory) {
      +        // Memory is never over-ridden, just bail.
      +        Lo = Memory;
      +        return;
      +      } 
      +      else if (Target == Integer || FieldLo == Integer) 
      +        Target = Integer;
      +      else if (FieldLo == X87 || FieldLo == X87Up || FieldLo == ComplexX87) {
      +        // As before, just bail once we generate a memory class.
      +        Lo = Memory;
      +        return;
      +      } else
      +        Target = SSE;
      +
      +      // It isn't clear from the ABI spec what the role of the high
      +      // classification is here, but since this should only happen
      +      // when we have a struct with a two eightbyte member, we can
      +      // just push the field high class into the overall high class.
      +      if (FieldHi != NoClass)
      +        Hi = FieldHi;
      +    }
      +
      +    // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
      +    //
      +    // (a) If one of the classes is MEMORY, the whole argument is
      +    // passed in memory.
      +    //
      +    // (b) If SSEUP is not preceeded by SSE, it is converted to SSE.
      +
      +    // The first of these conditions is guaranteed by how we implement
      +    // the merge (just bail). I don't believe the second is actually
      +    // possible at all.
      +    assert(Lo != Memory && "Unexpected memory classification.");
      +    if (Hi == SSEUp && Lo != SSE)
      +        Hi = SSE;
         }
       }
       
      -- 
      GitLab
      
      
      From c0924a0632c842e18cf089172cf9ca7aadc96d5a Mon Sep 17 00:00:00 2001
      From: Owen Anderson 
      Date: Thu, 29 Jan 2009 08:22:06 +0000
      Subject: [PATCH 423/682] Fix an issue where restores could be inserted after a
       terminator instruction, and an iterator invalidation issue.
      
      FreeBench/pifft no longer miscompiles with these fixes!
      
      llvm-svn: 63293
      ---
       llvm/lib/CodeGen/PreAllocSplitting.cpp | 16 ++++++++++++----
       1 file changed, 12 insertions(+), 4 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      index 44819aabbab7..4dc8b82972a0 100644
      --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp
      +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      @@ -277,7 +277,7 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI,
           MII = ++MII;
           // FIXME: Limit the number of instructions to examine to reduce
           // compile time?
      -    while (MII != MBB->end()) {
      +    while (MII != MBB->getFirstTerminator()) {
             unsigned Index = LIs->getInstructionIndex(MII);
             if (Index > LastIdx)
               break;
      @@ -486,7 +486,8 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction(
                  IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) {
               I->second->hasPHIKill = true;
               unsigned KillIndex = LIs->getMBBEndIdx(I->first);
      -        LI->addKill(I->second, KillIndex);
      +        if (!LiveInterval::isKill(I->second, KillIndex))
      +          LI->addKill(I->second, KillIndex);
             }
             
             unsigned EndIndex = 0;
      @@ -1118,6 +1119,7 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               LIs->RemoveMachineInstrFromMaps(DefMI);
               (*LI)->removeValNo(CurrVN);
               DefMI->eraseFromParent();
      +        VNUseCount.erase(CurrVN);
               NumDeadSpills++;
               changed = true;
               continue;
      @@ -1176,11 +1178,15 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
                    VNUseCount[CurrVN].begin(), IE = VNUseCount[CurrVN].end();
                    II != IE; ++II) {
                 for (DenseMap >::iterator
      -               VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
      -            VI->second.erase(*II);
      +               VNI = VNUseCount.begin(), VNE = VNUseCount.end(); VNI != VNE; 
      +               ++VNI)
      +            if (VNI->first != CurrVN)
      +              VNI->second.erase(*II);
                 LIs->RemoveMachineInstrFromMaps(*II);
                 (*II)->eraseFromParent();
               }
      +        
      +        VNUseCount.erase(CurrVN);
       
               for (DenseMap >::iterator
                    VI = VNUseCount.begin(), VE = VNUseCount.end(); VI != VE; ++VI)
      @@ -1204,6 +1210,8 @@ bool PreAllocSplitting::removeDeadSpills(SmallPtrSet& split) {
               (*UI)->eraseFromParent();
             }
               
      +      VNUseCount.erase(CurrVN);
      +        
             LIs->RemoveMachineInstrFromMaps(DefMI);
             (*LI)->removeValNo(CurrVN);
             DefMI->eraseFromParent();
      -- 
      GitLab
      
      
      From 012468aa7f03884270d831c6452cc50bf05f14f8 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 08:24:57 +0000
      Subject: [PATCH 424/682] ABI: When emitting calls which return an ignored
       argument, make sure to still return an RValue of the correct type.
      
      llvm-svn: 63294
      ---
       clang/lib/CodeGen/CGCall.cpp | 9 ++++++++-
       1 file changed, 8 insertions(+), 1 deletion(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index ee854f6ccee7..6ffe8c328ca2 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -1256,7 +1256,14 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee,
           return RValue::get(RetTy->isVoidType() ? 0 : CI);
       
         case ABIArgInfo::Ignore:
      -    return RValue::get(0);
      +    if (RetTy->isVoidType())
      +      return RValue::get(0);
      +    if (CodeGenFunction::hasAggregateLLVMType(RetTy)) {
      +      llvm::Value *Res =
      +        llvm::UndefValue::get(llvm::PointerType::getUnqual(ConvertType(RetTy)));
      +      return RValue::getAggregate(Res);
      +    }
      +    return RValue::get(llvm::UndefValue::get(ConvertType(RetTy)));
       
         case ABIArgInfo::Coerce: {
           llvm::Value *V = CreateTempAlloca(ConvertType(RetTy), "coerce");
      -- 
      GitLab
      
      
      From 7cd7d47c5cd091b93af801974bdabbd572a184f5 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 08:35:40 +0000
      Subject: [PATCH 425/682] x86_64 ABI: Tweak merging algorithm so that we always
       bail early when we see a Memory classification.
      
      llvm-svn: 63295
      ---
       clang/lib/CodeGen/CGCall.cpp | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index 6ffe8c328ca2..afdf57a76509 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -548,13 +548,13 @@ void X86_64ABIInfo::classify(QualType Ty,
             //
             // (f) Otherwise class SSE is used.
             if (Target == FieldLo || FieldLo == NoClass) ;
      -      else if (Target == NoClass)
      -        Target = FieldLo;
             else if (FieldLo == Memory) {
               // Memory is never over-ridden, just bail.
               Lo = Memory;
               return;
             } 
      +      else if (Target == NoClass)
      +        Target = FieldLo;
             else if (Target == Integer || FieldLo == Integer) 
               Target = Integer;
             else if (FieldLo == X87 || FieldLo == X87Up || FieldLo == ComplexX87) {
      -- 
      GitLab
      
      
      From d0c901c5a65dc636b7684a06b1eca27ba23dbfdc Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 08:48:06 +0000
      Subject: [PATCH 426/682] ABITest: Fix access to array test values.
      
      llvm-svn: 63296
      ---
       clang/utils/ABITest/ABITestGen.py | 5 ++++-
       1 file changed, 4 insertions(+), 1 deletion(-)
      
      diff --git a/clang/utils/ABITest/ABITestGen.py b/clang/utils/ABITest/ABITestGen.py
      index 5b9756b54509..bdf0be4f1d90 100755
      --- a/clang/utils/ABITest/ABITestGen.py
      +++ b/clang/utils/ABITest/ABITestGen.py
      @@ -263,7 +263,10 @@ class TypePrinter:
                   for i in range(t.numElements):
                       # Access in this fashion as a hackish way to portably
                       # access vectors.
      -                self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)                            
      +                if t.isVector:
      +                    self.printValueOfType(prefix, '((%s*) &%s)[%d]'%(t.elementType,name,i), t.elementType, output=output,indent=indent)
      +                else:
      +                    self.printValueOfType(prefix, '%s[%d]'%(name,i), t.elementType, output=output,indent=indent)                    
               else:
                   raise NotImplementedError,'Cannot print value of type: "%s"'%(t,)
       
      -- 
      GitLab
      
      
      From 45799abe61e7f7649a46e90644ecb2b22c8df40a Mon Sep 17 00:00:00 2001
      From: Evan Cheng 
      Date: Thu, 29 Jan 2009 08:59:46 +0000
      Subject: [PATCH 427/682] Add a test case for Chris lvalue alignment fixes.
      
      llvm-svn: 63300
      ---
       llvm/test/FrontendC/union-align.c | 17 +++++++++++++++++
       1 file changed, 17 insertions(+)
       create mode 100644 llvm/test/FrontendC/union-align.c
      
      diff --git a/llvm/test/FrontendC/union-align.c b/llvm/test/FrontendC/union-align.c
      new file mode 100644
      index 000000000000..f99a76080569
      --- /dev/null
      +++ b/llvm/test/FrontendC/union-align.c
      @@ -0,0 +1,17 @@
      +// RUN: %llvmgcc -S %s -o - | grep load | grep "4 x float" | not grep "align 4"
      +// RUN: %llvmgcc -S %s -o - | grep load | grep "4 x float" | grep "align 16"
      +// PR3432
      +// rdar://6536377
      +
      +typedef float __m128 __attribute__ ((__vector_size__ (16)));
      +
      +typedef union
      +{
      +  int i[4];
      +  float f[4];
      +  __m128 v;
      +} u_t;
      +
      +__m128 t(u_t *a) {
      +  return a->v;
      +}
      -- 
      GitLab
      
      
      From a434d930ffb7ba31a82900fe9feb8aa45c78a804 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Thu, 29 Jan 2009 09:01:55 +0000
      Subject: [PATCH 428/682] Revert r63273. This was already implemented by Dale.
       There's no need for my change.
      
      llvm-svn: 63301
      ---
       llvm/include/llvm/CodeGen/SelectionDAG.h      |  56 +++---
       .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 173 ++++++++++--------
       2 files changed, 135 insertions(+), 94 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
      index 86487cf4a41d..a06158a39b2d 100644
      --- a/llvm/include/llvm/CodeGen/SelectionDAG.h
      +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
      @@ -699,60 +699,72 @@ public:
         /// node of the specified opcode and operands, it returns that node instead of
         /// the current one.
         SDNode *getTargetNode(unsigned Opcode, MVT VT);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT, SDValue Op1);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT, SDValue Op1, SDValue Op2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      -                        SDValue Op1, SDValue Op2);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT, SDValue Op1, 
      +                        SDValue Op2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
                               const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, SDValue Op1);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      -                        MVT VT2, SDValue Op1);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, 
      +                        SDValue Op1);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
                               MVT VT2, SDValue Op1, SDValue Op2, SDValue Op3);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2,
                               const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL,
      -                        MVT VT1, MVT VT2, MVT VT3,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2, MVT VT3,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
                               SDValue Op1, SDValue Op2, SDValue Op3);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1, MVT VT2, MVT VT3,
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
                               const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3, MVT VT4,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL,
      -                        MVT VT1, MVT VT2, MVT VT3, MVT VT4,
      -                        const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3,
      +                        MVT VT4, const SDValue *Ops, unsigned NumOps);
      +
         SDNode *getTargetNode(unsigned Opcode, const std::vector &ResultTys,
                               const SDValue *Ops, unsigned NumOps);
      -  SDNode *getTargetNode(unsigned Opcode, DebugLoc DL,
      -                        const std::vector &ResultTys,
      -                        const SDValue *Ops, unsigned NumOps);
      +  SDNode *getTargetNode(unsigned Opcode, DebugLoc dl,
      +                        const std::vector &ResultTys, const SDValue *Ops,
      +                        unsigned NumOps);
       
         /// getNodeIfExists - Get the specified node if it's already available, or
         /// else return NULL.
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      index 523518886253..ab2c8323002b 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      @@ -4747,142 +4747,169 @@ SDNode *SelectionDAG::MorphNodeTo(SDNode *N, unsigned Opc,
       /// node of the specified opcode and operands, it returns that node instead of
       /// the current one.
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT);
      +  return getNode(~Opcode, VT).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT) {
      -  return getNode(~Opcode, DL, VT).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT) {
      +  return getNode(~Opcode, dl, VT).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT, SDValue Op1) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Op1);
      +  return getNode(~Opcode, VT, Op1).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      -                                    MVT VT, SDValue Op1) {
      -  return getNode(~Opcode, DL, VT, Op1).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                                    SDValue Op1) {
      +  return getNode(~Opcode, dl, VT, Op1).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           SDValue Op1, SDValue Op2) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Op1, Op2);
      +  return getNode(~Opcode, VT, Op1, Op2).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
                                           SDValue Op1, SDValue Op2) {
      -  return getNode(~Opcode, DL, VT, Op1, Op2).getNode();
      +  return getNode(~Opcode, dl, VT, Op1, Op2).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
      -                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Op1, Op2, Op3);
      +                                    SDValue Op1, SDValue Op2,
      +                                    SDValue Op3) {
      +  return getNode(~Opcode, VT, Op1, Op2, Op3).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      -                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      -  return getNode(~Opcode, DL, VT, Op1, Op2, Op3).getNode();
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
      +                                    SDValue Op1, SDValue Op2,
      +                                    SDValue Op3) {
      +  return getNode(~Opcode, dl, VT, Op1, Op2, Op3).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT, Ops, NumOps);
      +  return getNode(~Opcode, VT, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getNode(~Opcode, DL, VT, Ops, NumOps).getNode();
      +  return getNode(~Opcode, dl, VT, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      -                                    MVT VT1, MVT VT2) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2);
      +
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  SDValue Op;
      +  return getNode(~Opcode, VTs, 2, &Op, 0).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, 
                                           MVT VT1, MVT VT2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Op;
      -  return getNode(~Opcode, DL, VTs, 2, &Op, 0).getNode();
      +  return getNode(~Opcode, dl, VTs, 2, &Op, 0).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, Op1);
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  return getNode(~Opcode, VTs, 2, &Op1, 1).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
                                           MVT VT2, SDValue Op1) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  return getNode(~Opcode, DL, VTs, 2, &Op1, 1).getNode();
      +  return getNode(~Opcode, dl, VTs, 2, &Op1, 1).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
      -                                    MVT VT2, SDValue Op1, SDValue Op2) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, Op1, Op2);
      +                                    MVT VT2, SDValue Op1,
      +                                    SDValue Op2) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  SDValue Ops[] = { Op1, Op2 };
      +  return getNode(~Opcode, VTs, 2, Ops, 2).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      -                                    MVT VT2, SDValue Op1, SDValue Op2) {
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                                    MVT VT2, SDValue Op1,
      +                                    SDValue Op2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Ops[] = { Op1, Op2 };
      -  return getNode(~Opcode, DL, VTs, 2, Ops, 2).getNode();
      +  return getNode(~Opcode, dl, VTs, 2, Ops, 2).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
                                           MVT VT2, SDValue Op1,
                                           SDValue Op2, SDValue Op3) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2,
      -                       Op1, Op2, Op3);
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  SDValue Ops[] = { Op1, Op2, Op3 };
      +  return getNode(~Opcode, VTs, 2, Ops, 3).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL, MVT VT1,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
                                           MVT VT2, SDValue Op1,
                                           SDValue Op2, SDValue Op3) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
         SDValue Ops[] = { Op1, Op2, Op3 };
      -  return getNode(~Opcode, DL, VTs, 2, Ops, 3).getNode();
      +  return getNode(~Opcode, dl, VTs, 2, Ops, 3).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      -                                    MVT VT1, MVT VT2,
      +
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2,
      -                       Ops, NumOps);
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2);
      +  return getNode(~Opcode, VTs, 2, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, 
                                           MVT VT1, MVT VT2,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2);
      -  return getNode(~Opcode, DL, VTs, 2, Ops, NumOps).getNode();
      +  return getNode(~Opcode, dl, VTs, 2, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      -                                    MVT VT1, MVT VT2, MVT VT3,
      +
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                                           SDValue Op1, SDValue Op2) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, VT3,
      -                       Op1, Op2);
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      +  SDValue Ops[] = { Op1, Op2 };
      +  return getNode(~Opcode, VTs, 3, Ops, 2).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
                                           MVT VT1, MVT VT2, MVT VT3,
                                           SDValue Op1, SDValue Op2) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
         SDValue Ops[] = { Op1, Op2 };
      -  return getNode(~Opcode, DL, VTs, 3, Ops, 2).getNode();
      +  return getNode(~Opcode, dl, VTs, 3, Ops, 2).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      -                                    MVT VT1, MVT VT2, MVT VT3,
      -                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, VT3,
      -                       Op1, Op2, Op3);
      +
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
      +                                    SDValue Op1, SDValue Op2,
      +                                    SDValue Op3) {
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      +  SDValue Ops[] = { Op1, Op2, Op3 };
      +  return getNode(~Opcode, VTs, 3, Ops, 3).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
                                           MVT VT1, MVT VT2, MVT VT3,
      -                                    SDValue Op1, SDValue Op2, SDValue Op3) {
      +                                    SDValue Op1, SDValue Op2,
      +                                    SDValue Op3) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
         SDValue Ops[] = { Op1, Op2, Op3 };
      -  return getNode(~Opcode, DL, VTs, 3, Ops, 3).getNode();
      +  return getNode(~Opcode, dl, VTs, 3, Ops, 3).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      -                                    MVT VT1, MVT VT2, MVT VT3,
      +
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, MVT VT2, MVT VT3,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(), VT1, VT2, VT3,
      -                       Ops, NumOps);
      +  const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      +  return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
                                           MVT VT1, MVT VT2, MVT VT3,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3);
      -  return getNode(~Opcode, DL, VTs, 3, Ops, NumOps).getNode();
      +  return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
      -                                    MVT VT1, MVT VT2, MVT VT3, MVT VT4,
      +
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1,
      +                                    MVT VT2, MVT VT3, MVT VT4,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(),
      -                       VT1, VT2, VT3, VT4, Ops, NumOps);
      +  std::vector VTList;
      +  VTList.push_back(VT1);
      +  VTList.push_back(VT2);
      +  VTList.push_back(VT3);
      +  VTList.push_back(VT4);
      +  const MVT *VTs = getNodeValueTypes(VTList);
      +  return getNode(~Opcode, VTs, 4, Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      -                                    MVT VT1, MVT VT2, MVT VT3, MVT VT4,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1,
      +                                    MVT VT2, MVT VT3, MVT VT4,
                                           const SDValue *Ops, unsigned NumOps) {
         std::vector VTList;
         VTList.push_back(VT1);
      @@ -4890,19 +4917,21 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
         VTList.push_back(VT3);
         VTList.push_back(VT4);
         const MVT *VTs = getNodeValueTypes(VTList);
      -  return getNode(~Opcode, DL, VTs, 4, Ops, NumOps).getNode();
      +  return getNode(~Opcode, dl, VTs, 4, Ops, NumOps).getNode();
       }
      +
       SDNode *SelectionDAG::getTargetNode(unsigned Opcode,
                                           const std::vector &ResultTys,
                                           const SDValue *Ops, unsigned NumOps) {
      -  return getTargetNode(Opcode, DebugLoc::getUnknownLoc(),
      -                       ResultTys, Ops, NumOps);
      +  const MVT *VTs = getNodeValueTypes(ResultTys);
      +  return getNode(~Opcode, VTs, ResultTys.size(),
      +                 Ops, NumOps).getNode();
       }
      -SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc DL,
      +SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl,
                                           const std::vector &ResultTys,
                                           const SDValue *Ops, unsigned NumOps) {
         const MVT *VTs = getNodeValueTypes(ResultTys);
      -  return getNode(~Opcode, DL, VTs, ResultTys.size(),
      +  return getNode(~Opcode, dl, VTs, ResultTys.size(),
                        Ops, NumOps).getNode();
       }
       
      -- 
      GitLab
      
      
      From a115859df0a758b4713ac14863dd564ae1038047 Mon Sep 17 00:00:00 2001
      From: Evan Cheng 
      Date: Thu, 29 Jan 2009 09:31:54 +0000
      Subject: [PATCH 429/682] Add a always_inline test case.
      
      llvm-svn: 63304
      ---
       llvm/test/FrontendC/always-inline.c | 12 ++++++++++++
       1 file changed, 12 insertions(+)
       create mode 100644 llvm/test/FrontendC/always-inline.c
      
      diff --git a/llvm/test/FrontendC/always-inline.c b/llvm/test/FrontendC/always-inline.c
      new file mode 100644
      index 000000000000..22f6c7a20ef2
      --- /dev/null
      +++ b/llvm/test/FrontendC/always-inline.c
      @@ -0,0 +1,12 @@
      +// RUN: %llvmgcc -S %s -o - | grep call | not grep foo
      +
      +void bar() {
      +}
      +
      +inline void __attribute__((__always_inline__)) foo() {
      +  bar();
      +}
      +
      +void i_want_bar() {
      +  foo();
      +}
      -- 
      GitLab
      
      
      From 5537b8bc6cf3b00811580cdae7fb65ef516103e3 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 09:42:07 +0000
      Subject: [PATCH 430/682] x86_64 ABI: Handle fields / complex components which
       straddle eightbyte boundaries.  - Getting harder to test now that we handle
       cases gcc & llvm-gcc get    wrong ( { _Complex char; _Complex int; } is a
       good example). :)
      
      llvm-svn: 63305
      ---
       clang/lib/CodeGen/CGCall.cpp | 19 +++++++++++++++----
       1 file changed, 15 insertions(+), 4 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index afdf57a76509..77863fb091bc 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -411,6 +411,9 @@ class X86_64ABIInfo : public ABIInfo {
         ///
         /// \param Lo - The classification for the low word of the type.
         /// \param Hi - The classification for the high word of the type.
      +  /// \param OffsetBase - The byte position of the type in the root
      +  /// structure. Some parameters are classified different depending on
      +  /// whether they straddle an eightbyte boundary.
         ///
         /// If a word is unused its result will be NoClass; if a type should
         /// be passed in Memory then at least the classification of \arg Lo
      @@ -420,7 +423,7 @@ class X86_64ABIInfo : public ABIInfo {
         ///
         /// If the \arg Lo class is ComplexX87, then the \arg Hi class will
         /// be NoClass.
      -  void classify(QualType T, ASTContext &Context,
      +  void classify(QualType T, ASTContext &Context, unsigned OffsetBase,
                       Class &Lo, Class &Hi) const;
       
       public:
      @@ -434,6 +437,7 @@ public:
       
       void X86_64ABIInfo::classify(QualType Ty,
                                    ASTContext &Context,
      +                             unsigned OffsetBase,
                                    Class &Lo, Class &Hi) const {
         Lo = Memory;
         Hi = NoClass;
      @@ -483,6 +487,13 @@ void X86_64ABIInfo::classify(QualType Ty,
             Lo = Hi = SSE;
           else if (ET == Context.LongDoubleTy)
             Lo = ComplexX87;
      +
      +    // If this complex type crosses an eightbyte boundary then it
      +    // should be split.
      +    unsigned EB_Real = (OffsetBase) >> 3;
      +    unsigned EB_Imag = (OffsetBase + Context.getTypeSize(ET)) >> 3;
      +    if (Hi == NoClass && EB_Real != EB_Imag)
      +      Hi = Lo;
         } else if (const RecordType *RT = Ty->getAsRecordType()) {
           unsigned Size = Context.getTypeSize(Ty);
           
      @@ -504,7 +515,7 @@ void X86_64ABIInfo::classify(QualType Ty,
           unsigned idx = 0;
           for (RecordDecl::field_iterator i = RD->field_begin(), 
                  e = RD->field_end(); i != e; ++i, ++idx) {
      -      unsigned Offset = Layout.getFieldOffset(idx);
      +      unsigned Offset = OffsetBase + Layout.getFieldOffset(idx);
       
             //  AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
             //  fields, it has class MEMORY.
      @@ -523,7 +534,7 @@ void X86_64ABIInfo::classify(QualType Ty,
       
             // Classify this field.
             Class FieldLo, FieldHi;
      -      classify(i->getType(), Context, FieldLo, FieldHi);
      +      classify(i->getType(), Context, Offset, FieldLo, FieldHi);
             
             // Merge the lo field classifcation.
             //
      @@ -593,7 +604,7 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy,
         // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the
         // classification algorithm.
         X86_64ABIInfo::Class Lo, Hi;
      -  classify(RetTy, Context, Lo, Hi);
      +  classify(RetTy, Context, 0, Lo, Hi);
       
         const llvm::Type *ResType = 0;
         switch (Lo) {
      -- 
      GitLab
      
      
      From 4f5a889dc6fbd6d413010a8fe0c7dc5f382be79e Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 16:09:46 +0000
      Subject: [PATCH 431/682] Suppress a warning
      
      llvm-svn: 63310
      ---
       clang/lib/Sema/SemaDeclObjC.cpp | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
      index 3371e3ea6e20..5677bc5e0920 100644
      --- a/clang/lib/Sema/SemaDeclObjC.cpp
      +++ b/clang/lib/Sema/SemaDeclObjC.cpp
      @@ -1432,8 +1432,8 @@ void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
                                 "copy" : "retain";
                                
           Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 
      -                 diag::err_objc_property_attr_mutually_exclusive :
      -                 diag::warn_objc_property_attr_mutually_exclusive)
      +                 (unsigned)diag::err_objc_property_attr_mutually_exclusive :
      +                 (unsigned)diag::warn_objc_property_attr_mutually_exclusive)
             << "readonly" << which;
         }
       
      -- 
      GitLab
      
      
      From ef04ed547782dc21b44fe1c01779b86eb6892bf4 Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Thu, 29 Jan 2009 16:10:46 +0000
      Subject: [PATCH 432/682] In the case of an extractelement on an insertelement
       value, the element indices may be equal if either one is not a constant.
      
      llvm-svn: 63311
      ---
       .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp |  6 ++++-
       llvm/test/CodeGen/X86/vec_ins_extract-1.ll    | 25 +++++++++++++++++++
       2 files changed, 30 insertions(+), 1 deletion(-)
       create mode 100644 llvm/test/CodeGen/X86/vec_ins_extract-1.ll
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      index ab2c8323002b..16f17e56f465 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
      @@ -2597,9 +2597,13 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT,
           // EXTRACT_VECTOR_ELT of INSERT_VECTOR_ELT is often formed when vector
           // operations are lowered to scalars.
           if (N1.getOpcode() == ISD::INSERT_VECTOR_ELT) {
      +      // If the indices are the same, return the inserted element.
             if (N1.getOperand(2) == N2)
               return N1.getOperand(1);
      -      else
      +      // If the indices are known different, extract the element from
      +      // the original vector.
      +      else if (isa(N1.getOperand(2)) &&
      +               isa(N2))
               return getNode(ISD::EXTRACT_VECTOR_ELT, VT, N1.getOperand(0), N2);
           }
           break;
      diff --git a/llvm/test/CodeGen/X86/vec_ins_extract-1.ll b/llvm/test/CodeGen/X86/vec_ins_extract-1.ll
      new file mode 100644
      index 000000000000..44ae03938480
      --- /dev/null
      +++ b/llvm/test/CodeGen/X86/vec_ins_extract-1.ll
      @@ -0,0 +1,25 @@
      +; RUN: llvm-as < %s | llc -march=x86 | grep {(%esp,%eax,4)} | count 4
      +
      +; Inserts and extracts with variable indices must be lowered
      +; to memory accesses.
      +
      +define i32 @t0(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
      +  %t13 = insertelement <4 x i32> %t8, i32 76, i32 %t7
      +  %t9 = extractelement <4 x i32> %t13, i32 0
      +  ret i32 %t9
      +}
      +define i32 @t1(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
      +  %t13 = insertelement <4 x i32> %t8, i32 76, i32 0
      +  %t9 = extractelement <4 x i32> %t13, i32 %t7
      +  ret i32 %t9
      +}
      +define <4 x i32> @t2(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
      +  %t9 = extractelement <4 x i32> %t8, i32 %t7
      +  %t13 = insertelement <4 x i32> %t8, i32 %t9, i32 0
      +  ret <4 x i32> %t13
      +}
      +define <4 x i32> @t3(i32 inreg %t7, <4 x i32> inreg %t8) nounwind {
      +  %t9 = extractelement <4 x i32> %t8, i32 0
      +  %t13 = insertelement <4 x i32> %t8, i32 %t9, i32 %t7
      +  ret <4 x i32> %t13
      +}
      -- 
      GitLab
      
      
      From 8b437ccbbe976a2fea162ad6b9b9e1c34e385196 Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Thu, 29 Jan 2009 16:18:12 +0000
      Subject: [PATCH 433/682] Fix two typos that Duncan spotted in a comment.
      
      llvm-svn: 63312
      ---
       llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
      index e479e05bdd71..1f9d9cf9a72e 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp
      @@ -1815,7 +1815,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1,
             }
           }
       
      -    // Simpify x&y == y to x&y == 0 if y has exactly one bit set.
      +    // Simplify x&y == y to x&y != 0 if y has exactly one bit set.
           if (N0.getOpcode() == ISD::AND)
             if (N0.getOperand(0) == N1 || N0.getOperand(1) == N1) {
               if (ValueHasAtMostOneBitSet(N1, DAG)) {
      -- 
      GitLab
      
      
      From 5169570e28a556cb9af0951eac1697442d26fa19 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 16:53:55 +0000
      Subject: [PATCH 434/682] Clean up designated initialization of unions, so that
       CodeGen doesn't have to try to guess which member is being initialized.
      
      llvm-svn: 63315
      ---
       clang/include/clang/AST/Expr.h       | 13 ++++++++
       clang/lib/AST/Expr.cpp               |  3 +-
       clang/lib/CodeGen/CGExprAgg.cpp      | 49 +++++++++++++++++++---------
       clang/lib/CodeGen/CGExprConstant.cpp | 45 ++++++++++++-------------
       clang/lib/Sema/SemaInit.cpp          | 17 ++++++++--
       5 files changed, 83 insertions(+), 44 deletions(-)
      
      diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
      index 54c764099921..10b877ac891f 100644
      --- a/clang/include/clang/AST/Expr.h
      +++ b/clang/include/clang/AST/Expr.h
      @@ -1664,6 +1664,10 @@ class InitListExpr : public Expr {
         /// written in the source code.
         InitListExpr *SyntacticForm;
       
      +  /// If this initializer list initializes a union, specifies which
      +  /// field within the union will be initialized.
      +  FieldDecl *UnionFieldInit;
      +
       public:
         InitListExpr(SourceLocation lbraceloc, Expr **initexprs, unsigned numinits,
                      SourceLocation rbraceloc);
      @@ -1702,6 +1706,15 @@ public:
         /// accomodate the new entry.
         Expr *updateInit(unsigned Init, Expr *expr);
       
      +  /// \brief If this initializes a union, specifies which field in the
      +  /// union to initialize.
      +  ///
      +  /// Typically, this field is the first named field within the
      +  /// union. However, a designated initializer can specify the
      +  /// initialization of a different field within the union.
      +  FieldDecl *getInitializedFieldInUnion() { return UnionFieldInit; }
      +  void setInitializedFieldInUnion(FieldDecl *FD) { UnionFieldInit = FD; }
      +
         // Explicit InitListExpr's originate from source code (and have valid source
         // locations). Implicit InitListExpr's are created by the semantic analyzer.
         bool isExplicit() {
      diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
      index d96f734bf419..c1c8084cd599 100644
      --- a/clang/lib/AST/Expr.cpp
      +++ b/clang/lib/AST/Expr.cpp
      @@ -223,7 +223,8 @@ InitListExpr::InitListExpr(SourceLocation lbraceloc,
                                  Expr **initExprs, unsigned numInits,
                                  SourceLocation rbraceloc)
         : Expr(InitListExprClass, QualType()),
      -    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0) {
      +    LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), 
      +    UnionFieldInit(0) {
       
         InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
       }
      diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
      index 075a12c57e1b..b487bacc7110 100644
      --- a/clang/lib/CodeGen/CGExprAgg.cpp
      +++ b/clang/lib/CodeGen/CGExprAgg.cpp
      @@ -443,7 +443,38 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
         unsigned NumInitElements = E->getNumInits();
         RecordDecl *SD = E->getType()->getAsRecordType()->getDecl();
         unsigned CurInitVal = 0;
      -  bool isUnion = E->getType()->isUnionType();
      +
      +  if (E->getType()->isUnionType()) {
      +    // Only initialize one field of a union. The field itself is
      +    // specified by the initializer list.
      +    if (!E->getInitializedFieldInUnion()) {
      +      // Empty union; we have nothing to do.
      +      
      +#ifndef NDEBUG
      +      // Make sure that it's really an empty and not a failure of
      +      // semantic analysis.
      +      for (RecordDecl::field_iterator Field = SD->field_begin(),
      +                                   FieldEnd = SD->field_end();
      +           Field != FieldEnd; ++Field)
      +        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
      +#endif
      +      return;
      +    }
      +
      +    // FIXME: volatility
      +    FieldDecl *Field = E->getInitializedFieldInUnion();
      +    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, Field, true, 0);
      +
      +    if (NumInitElements) {
      +      // Store the initializer into the field
      +      EmitInitializationToLValue(E->getInit(0), FieldLoc);
      +    } else {
      +      // Default-initialize to null
      +      EmitNullInitializationToLValue(FieldLoc, Field->getType());
      +    }
      +
      +    return;
      +  }
         
         // Here we iterate over the fields; this makes it simpler to both
         // default-initialize fields and skip over unnamed fields.
      @@ -457,29 +488,15 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
           if (Field->isUnnamedBitfield())
             continue;
       
      -    // When we're coping with C99 designated initializers into a
      -    // union, find the field that has the same type as the expression
      -    // we're initializing the union with.
      -    if (isUnion && CurInitVal < NumInitElements && 
      -        (CGF.getContext().getCanonicalType(Field->getType()) != 
      -           CGF.getContext().getCanonicalType(E->getInit(CurInitVal)->getType())))
      -      continue;
      -
           // FIXME: volatility
      -    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, isUnion,0);
      +    LValue FieldLoc = CGF.EmitLValueForField(DestPtr, *Field, false, 0);
           if (CurInitVal < NumInitElements) {
             // Store the initializer into the field
      -      // This will probably have to get a bit smarter when we support
      -      // designators in initializers
             EmitInitializationToLValue(E->getInit(CurInitVal++), FieldLoc);
           } else {
             // We're out of initalizers; default-initialize to null
             EmitNullInitializationToLValue(FieldLoc, Field->getType());
           }
      -
      -    // Unions only initialize one field.
      -    if (isUnion)
      -      break;
         }
       }
       
      diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
      index b05048c94609..e523ab3acf2e 100644
      --- a/clang/lib/CodeGen/CGExprConstant.cpp
      +++ b/clang/lib/CodeGen/CGExprConstant.cpp
      @@ -241,32 +241,29 @@ public:
           RecordDecl *RD = ILE->getType()->getAsRecordType()->getDecl();
           const llvm::Type *Ty = ConvertType(ILE->getType());
       
      -    // Find the field decl we're initializing, if any
      -    // FIXME: C99 designated initializers won't always initialize the 
      -    // first field
      -    int FieldNo = 0; // Field no in RecordDecl
      -    FieldDecl* curField = 0;
      -    bool sawAnyFields = false;
      -    for (RecordDecl::field_iterator Field = RD->field_begin(),
      -                                 FieldEnd = RD->field_end();
      -         Field != FieldEnd; ++Field) {
      -      curField = *Field;
      -      FieldNo++;
      -
      -      if (curField->isUnnamedBitfield())
      -        continue;
      -
      -      // If we have an initializer, find the field whose type is the
      -      // same as that initializer. This 
      -      sawAnyFields = true;
      -      if (ILE->getNumInits() > 0 &&
      -          CGM.getContext().getCanonicalType(curField->getType()) ==
      -            CGM.getContext().getCanonicalType(ILE->getInit(0)->getType()))
      -        break;
      -    }
      +    // If this is an empty initializer list, we value-initialize the
      +    // union.
      +    if (ILE->getNumInits() == 0)
      +      return llvm::Constant::getNullValue(Ty);
       
      -    if (!curField || !curField->getIdentifier() || ILE->getNumInits() == 0)
      +    FieldDecl* curField = ILE->getInitializedFieldInUnion();
      +    if (!curField) {
      +#ifndef NDEBUG
      +#endif
      +    }
      +
      +    if (!curField) {
      +      // There's no field to initialize, so value-initialize the union.
      +#ifndef NDEBUG
      +      // Make sure that it's really an empty and not a failure of
      +      // semantic analysis.
      +      for (RecordDecl::field_iterator Field = RD->field_begin(),
      +                                   FieldEnd = RD->field_end();
      +           Field != FieldEnd; ++Field)
      +        assert(Field->isUnnamedBitfield() && "Only unnamed bitfields allowed");
      +#endif
             return llvm::Constant::getNullValue(Ty);
      +    }
       
           if (curField->isBitField()) {
             // Create a dummy struct for bit-field insertion
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 5dc57751ffb3..527f965dc3f6 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -573,6 +573,11 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
                                            StructuredList, StructuredIndex))
               hadError = true;
       
      +      // Abort early for unions: the designator handled the
      +      // initialization of the appropriate field.
      +      if (DeclType->isUnionType())
      +        break;
      +
             continue;
           }
       
      @@ -585,7 +590,7 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
           if (Field->getType()->isIncompleteArrayType())
             break;
       
      -    if (!Field->getIdentifier() && Field->isBitField()) {
      +    if (Field->isUnnamedBitfield()) {
             // Don't initialize unnamed bitfields, e.g. "int : 20;"
             ++Field;
             continue;
      @@ -593,8 +598,12 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
       
           CheckSubElementType(IList, Field->getType(), Index,
                               StructuredList, StructuredIndex);
      -    if (DeclType->isUnionType())
      +
      +    if (DeclType->isUnionType()) {
      +      // Initialize the first field within the union.
      +      StructuredList->setInitializedFieldInUnion(*Field);
             break;
      +    }
       
           ++Field;
         }
      @@ -753,8 +762,10 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
       
           // All of the fields of a union are located at the same place in
           // the initializer list.
      -    if (RT->getDecl()->isUnion())
      +    if (RT->getDecl()->isUnion()) {
             FieldIndex = 0;
      +      StructuredList->setInitializedFieldInUnion(*Field);
      +    }
       
           // Update the designator with the field declaration.
           D->setField(*Field);
      -- 
      GitLab
      
      
      From 0202cb406ee64be15636ba7b9435a9a83f9d4996 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 17:44:32 +0000
      Subject: [PATCH 435/682] Introduce a new expression node,
       ImplicitValueInitExpr, that represents an implicit value-initialization of a
       subobject of a particular type. This replaces the (ab)use of
       CXXZeroValueInitExpr within initializer lists for the "holes" that occur due
       to the use of C99 designated initializers.
      
      The new test case is currently XFAIL'd, because CodeGen's
      ConstExprEmitter (in lib/CodeGen/CGExprConstant.cpp) needs to be
      taught to value-initialize when it sees ImplicitValueInitExprs.
      
      llvm-svn: 63317
      ---
       clang/include/clang/AST/Expr.h               | 27 ++++++++++++++++++-
       clang/include/clang/AST/StmtNodes.def        |  1 +
       clang/lib/AST/Expr.cpp                       | 13 ++++++++-
       clang/lib/AST/StmtPrinter.cpp                |  4 +++
       clang/lib/CodeGen/CGExprAgg.cpp              |  6 ++---
       clang/lib/CodeGen/CGExprComplex.cpp          |  6 +++++
       clang/lib/CodeGen/CGExprConstant.cpp         |  5 ----
       clang/lib/CodeGen/CGExprScalar.cpp           |  3 +++
       clang/lib/Sema/SemaDecl.cpp                  | 10 +++----
       clang/lib/Sema/SemaInit.cpp                  | 28 ++++++++++++++------
       clang/test/CodeGen/designated-initializers.c | 17 ++++++++++++
       11 files changed, 97 insertions(+), 23 deletions(-)
       create mode 100644 clang/test/CodeGen/designated-initializers.c
      
      diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
      index 10b877ac891f..c6ac007a1316 100644
      --- a/clang/include/clang/AST/Expr.h
      +++ b/clang/include/clang/AST/Expr.h
      @@ -1645,7 +1645,7 @@ public:
       /// initializations into the subobject they initialize. Additionally,
       /// any "holes" in the initialization, where no initializer has been
       /// specified for a particular subobject, will be replaced with
      -/// implicitly-generated CXXZeroInitValueExpr expressions that
      +/// implicitly-generated ImplicitValueInitExpr expressions that
       /// value-initialize the subobjects. Note, however, that the
       /// initializer lists may still have fewer initializers than there are
       /// elements to initialize within the object.
      @@ -1987,6 +1987,31 @@ public:
         virtual child_iterator child_end(); 
       };
       
      +/// \brief Represents an implicitly-generated value initialization of
      +/// an object of a given type.
      +///
      +/// Implicit value initializations occur within semantic initialize
      +/// list expressions (\see InitListExpr) as placeholders for subobject
      +/// initializations not explicitly specified by the user.
      +class ImplicitValueInitExpr : public Expr { 
      +public:
      +  explicit ImplicitValueInitExpr(QualType ty) 
      +    : Expr(ImplicitValueInitExprClass, ty) { }
      +
      +  static bool classof(const Stmt *T) { 
      +    return T->getStmtClass() == ImplicitValueInitExprClass;
      +  }
      +  static bool classof(const ImplicitValueInitExpr *) { return true; }
      +
      +  virtual SourceRange getSourceRange() const {
      +    return SourceRange();
      +  }
      +
      +  // Iterators
      +  virtual child_iterator child_begin();
      +  virtual child_iterator child_end(); 
      +};
      +
       //===----------------------------------------------------------------------===//
       // Clang Extensions
       //===----------------------------------------------------------------------===//
      diff --git a/clang/include/clang/AST/StmtNodes.def b/clang/include/clang/AST/StmtNodes.def
      index e8d4a56c5075..18b8dbebfede 100644
      --- a/clang/include/clang/AST/StmtNodes.def
      +++ b/clang/include/clang/AST/StmtNodes.def
      @@ -86,6 +86,7 @@ STMT(CompoundLiteralExpr   , Expr)
       STMT(ExtVectorElementExpr  , Expr)
       STMT(InitListExpr          , Expr)
       STMT(DesignatedInitExpr    , Expr)
      +STMT(ImplicitValueInitExpr , Expr)
       STMT(VAArgExpr             , Expr)
       
       // GNU Extensions.
      diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
      index c1c8084cd599..8a041982936c 100644
      --- a/clang/lib/AST/Expr.cpp
      +++ b/clang/lib/AST/Expr.cpp
      @@ -735,6 +735,8 @@ bool Expr::isConstantInitializer(ASTContext &Ctx) const {
           }
           return true;
         }
      +  case ImplicitValueInitExprClass:
      +    return true;
         case ParenExprClass: {
           return cast(this)->getSubExpr()->isConstantInitializer(Ctx);
         }
      @@ -1672,7 +1674,7 @@ Stmt::child_iterator InitListExpr::child_end() {
         return InitExprs.size() ? &InitExprs[0] + InitExprs.size() : 0;
       }
       
      -/// DesignatedInitExpr
      +// DesignatedInitExpr
       Stmt::child_iterator DesignatedInitExpr::child_begin() {
         char* Ptr = static_cast(static_cast(this));
         Ptr += sizeof(DesignatedInitExpr);
      @@ -1683,6 +1685,15 @@ Stmt::child_iterator DesignatedInitExpr::child_end() {
         return child_iterator(&*child_begin() + NumSubExprs);
       }
       
      +// ImplicitValueInitExpr
      +Stmt::child_iterator ImplicitValueInitExpr::child_begin() { 
      +  return child_iterator(); 
      +}
      +
      +Stmt::child_iterator ImplicitValueInitExpr::child_end() { 
      +  return child_iterator(); 
      +}
      +
       // ObjCStringLiteral
       Stmt::child_iterator ObjCStringLiteral::child_begin() { 
         return child_iterator();
      diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
      index 7a558ab8dd7b..27bab206a4e8 100644
      --- a/clang/lib/AST/StmtPrinter.cpp
      +++ b/clang/lib/AST/StmtPrinter.cpp
      @@ -906,6 +906,10 @@ void StmtPrinter::VisitDesignatedInitExpr(DesignatedInitExpr *Node) {
         PrintExpr(Node->getInit());
       }
       
      +void StmtPrinter::VisitImplicitValueInitExpr(ImplicitValueInitExpr *Node) {
      +  OS << "/*implicit*/" << Node->getType().getAsString() << "()";
      +}
      +
       void StmtPrinter::VisitVAArgExpr(VAArgExpr *Node) {
         OS << "va_arg(";
         PrintExpr(Node->getSubExpr());
      diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
      index b487bacc7110..f985763b5c39 100644
      --- a/clang/lib/CodeGen/CGExprAgg.cpp
      +++ b/clang/lib/CodeGen/CGExprAgg.cpp
      @@ -339,10 +339,10 @@ void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {
       
       void AggExprEmitter::EmitInitializationToLValue(Expr* E, LValue LV) {
         // FIXME: Are initializers affected by volatile?
      -  if (E->getType()->isComplexType()) {
      -    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
      -  } else if (isa(E)) {
      +  if (isa(E)) {
           EmitNullInitializationToLValue(LV, E->getType());
      +  } else if (E->getType()->isComplexType()) {
      +    CGF.EmitComplexExprIntoAddr(E, LV.getAddress(), false);
         } else if (CGF.hasAggregateLLVMType(E->getType())) {
           CGF.EmitAnyExpr(E, LV.getAddress(), false);
         } else {
      diff --git a/clang/lib/CodeGen/CGExprComplex.cpp b/clang/lib/CodeGen/CGExprComplex.cpp
      index 73fceedee5fe..387635cb064a 100644
      --- a/clang/lib/CodeGen/CGExprComplex.cpp
      +++ b/clang/lib/CodeGen/CGExprComplex.cpp
      @@ -130,6 +130,12 @@ public:
           llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
           return ComplexPairTy(Null, Null);
         }
      +  ComplexPairTy VisitImplicitValueInitExpr(ImplicitValueInitExpr *E) {
      +    assert(E->getType()->isAnyComplexType() && "Expected complex type!");
      +    QualType Elem = E->getType()->getAsComplexType()->getElementType();
      +    llvm::Constant *Null = llvm::Constant::getNullValue(CGF.ConvertType(Elem));
      +    return ComplexPairTy(Null, Null);
      +  }
         
         struct BinOpInfo {
           ComplexPairTy LHS;
      diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
      index e523ab3acf2e..3aedf9bc7f78 100644
      --- a/clang/lib/CodeGen/CGExprConstant.cpp
      +++ b/clang/lib/CodeGen/CGExprConstant.cpp
      @@ -248,11 +248,6 @@ public:
       
           FieldDecl* curField = ILE->getInitializedFieldInUnion();
           if (!curField) {
      -#ifndef NDEBUG
      -#endif
      -    }
      -
      -    if (!curField) {
             // There's no field to initialize, so value-initialize the union.
       #ifndef NDEBUG
             // Make sure that it's really an empty and not a failure of
      diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
      index dd8b30041e70..f855e23ba03f 100644
      --- a/clang/lib/CodeGen/CGExprScalar.cpp
      +++ b/clang/lib/CodeGen/CGExprScalar.cpp
      @@ -200,6 +200,9 @@ public:
           return V;
         }
         
      +  Value *VisitImplicitValueInitExpr(const ImplicitValueInitExpr *E) {
      +    return llvm::Constant::getNullValue(ConvertType(E->getType()));
      +  }
         Value *VisitImplicitCastExpr(const ImplicitCastExpr *E);
         Value *VisitCastExpr(const CastExpr *E) { 
           return EmitCastExpr(E->getSubExpr(), E->getType());
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 7572560be195..1559213fcb8e 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -2220,17 +2220,17 @@ bool Sema::CheckForConstantInitializer(Expr *Init, QualType DclT) {
         if (CompoundLiteralExpr *e = dyn_cast(Init))
           return CheckForConstantInitializer(e->getInitializer(), DclT);
       
      +  if (isa(Init)) {
      +    // FIXME: In C++, check for non-POD types.
      +    return false;
      +  }
      +
         if (InitListExpr *Exp = dyn_cast(Init)) {
           unsigned numInits = Exp->getNumInits();
           for (unsigned i = 0; i < numInits; i++) {
             // FIXME: Need to get the type of the declaration for C++,
             // because it could be a reference?
       
      -      // Implicitly-generated value initializations are okay.
      -      if (isa(Exp->getInit(i)) &&
      -          cast(Exp->getInit(i))->isImplicit()) 
      -        continue;
      -
             if (CheckForConstantInitializer(Exp->getInit(i),
                                             Exp->getInit(i)->getType()))
               return true;
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 527f965dc3f6..5d7f705edb12 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -17,7 +17,6 @@
       #include "clang/Parse/Designator.h"
       #include "clang/AST/ASTContext.h"
       #include "clang/AST/Expr.h"
      -#include "clang/AST/ExprCXX.h"
       #include 
       using namespace clang;
       
      @@ -137,10 +136,9 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) {
             // FIXME: Check for fields with reference type in C++?
             if (!ILE->getInit(Init))
               ILE->setInit(Init, 
      -                     new (Context) CXXZeroInitValueExpr(Field->getType(), 
      -                                                        SourceLocation(),
      -                                                        SourceLocation()));
      -      else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init)))
      +                     new (Context) ImplicitValueInitExpr(Field->getType()));
      +      else if (InitListExpr *InnerILE 
      +                 = dyn_cast(ILE->getInit(Init)))
               fillInValueInitializations(Context, InnerILE);
             ++Init;
           }
      @@ -160,9 +158,7 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) {
         for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; 
              ++Init) {
           if (!ILE->getInit(Init))
      -      ILE->setInit(Init, new (Context) CXXZeroInitValueExpr(ElementType, 
      -                                                            SourceLocation(),
      -                                                            SourceLocation()));
      +      ILE->setInit(Init, new (Context) ImplicitValueInitExpr(ElementType));
           else if (InitListExpr *InnerILE =dyn_cast(ILE->getInit(Init)))
             fillInValueInitializations(Context, InnerILE);
         }
      @@ -550,6 +546,22 @@ void InitListChecker::CheckStructUnionTypes(InitListExpr *IList,
           hadError = true;
           return;
         }    
      +
      +  if (DeclType->isUnionType() && IList->getNumInits() == 0) {
      +    // Value-initialize the first named member of the union.
      +    RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
      +    for (RecordDecl::field_iterator FieldEnd = RD->field_end();
      +         Field != FieldEnd; ++Field) {
      +      if (Field->getDeclName()) {
      +        StructuredList->setInitializedFieldInUnion(*Field);
      +        break;
      +      }
      +    }
      +    return;
      +  }
      +
      +
      +
         // If structDecl is a forward declaration, this loop won't do
         // anything except look at designated initializers; That's okay,
         // because an error should get printed out elsewhere. It might be
      diff --git a/clang/test/CodeGen/designated-initializers.c b/clang/test/CodeGen/designated-initializers.c
      new file mode 100644
      index 000000000000..0605b24b1c50
      --- /dev/null
      +++ b/clang/test/CodeGen/designated-initializers.c
      @@ -0,0 +1,17 @@
      +// RUN: clang %s -emit-llvm -o -
      +// XFAIL
      +struct foo {
      +    void *a;
      +    int b;
      +};
      +
      +union { int i; float f; } u = { };
      +
      +int main(int argc, char **argv)
      +{
      +  union { int i; float f; } u2 = { };
      +    static struct foo foo = {
      +        .b = 1024,
      +    };
      +}
      +
      -- 
      GitLab
      
      
      From 4b6713ef2012b725dcb8681f860470d1eca5cc09 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 17:46:13 +0000
      Subject: [PATCH 436/682] next round of diagnostics cleanups, moving some diags
       around, eliminating #defines, etc.  Patch by Anders Johnsen!
      
      llvm-svn: 63318
      ---
       clang/Driver/clang.cpp                        |  1 -
       clang/include/clang/AST/ASTDiagnostic.h       |  1 +
       .../clang/Analysis/AnalysisDiagnostic.h       |  1 +
       clang/include/clang/Basic/Diagnostic.h        | 21 ++++----
       .../clang/Basic/DiagnosticCommonKinds.def     | 12 -----
       clang/include/clang/Basic/DiagnosticKinds.def | 33 ------------
       .../clang/Basic/DiagnosticLexKinds.def        |  4 ++
       .../clang/Basic/DiagnosticSemaKinds.def       |  8 +++
       clang/include/clang/Driver/DriverDiagnostic.h | 25 ---------
       clang/include/clang/Lex/LexDiagnostic.h       |  1 +
       clang/include/clang/Parse/ParseDiagnostic.h   |  1 +
       clang/lib/Basic/Diagnostic.cpp                | 52 +++++++++----------
       12 files changed, 54 insertions(+), 106 deletions(-)
      
      diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
      index 77d5ef7082ad..d29579f60000 100644
      --- a/clang/Driver/clang.cpp
      +++ b/clang/Driver/clang.cpp
      @@ -29,7 +29,6 @@
       #include "clang/Driver/InitHeaderSearch.h"
       #include "clang/Driver/TextDiagnosticBuffer.h"
       #include "clang/Driver/TextDiagnosticPrinter.h"
      -#include "clang/Driver/DriverDiagnostic.h"
       #include "clang/Analysis/PathDiagnostic.h"
       #include "clang/AST/Decl.h"
       #include "clang/AST/TranslationUnit.h"
      diff --git a/clang/include/clang/AST/ASTDiagnostic.h b/clang/include/clang/AST/ASTDiagnostic.h
      index ddb5b404e4ad..f08cb33e37a2 100644
      --- a/clang/include/clang/AST/ASTDiagnostic.h
      +++ b/clang/include/clang/AST/ASTDiagnostic.h
      @@ -18,6 +18,7 @@ namespace clang {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
       #define ASTSTART
       #include "clang/Basic/DiagnosticASTKinds.def"
      +#undef DIAG
             NUM_BUILTIN_AST_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Analysis/AnalysisDiagnostic.h b/clang/include/clang/Analysis/AnalysisDiagnostic.h
      index 1f2f08910056..f01170a9256d 100644
      --- a/clang/include/clang/Analysis/AnalysisDiagnostic.h
      +++ b/clang/include/clang/Analysis/AnalysisDiagnostic.h
      @@ -18,6 +18,7 @@ namespace clang {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
       #define ANALYSISSTART
       #include "clang/Basic/DiagnosticAnalysisKinds.def"
      +#undef DIAG
             NUM_BUILTIN_ANALYSIS_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Basic/Diagnostic.h b/clang/include/clang/Basic/Diagnostic.h
      index d9d32bcc5d2f..2f3184c46b72 100644
      --- a/clang/include/clang/Basic/Diagnostic.h
      +++ b/clang/include/clang/Basic/Diagnostic.h
      @@ -18,13 +18,6 @@
       #include 
       #include 
       
      -#define DIAG_START_LEX                              300
      -#define DIAG_START_PARSE    (DIAG_START_LEX      +  300)
      -#define DIAG_START_AST      (DIAG_START_PARSE    +  300)
      -#define DIAG_START_SEMA     (DIAG_START_AST      +  100)
      -#define DIAG_START_ANALYSIS (DIAG_START_SEMA     + 1000)
      -#define DIAG_UPPER_LIMIT    (DIAG_START_ANALYSIS +  100)
      -
       namespace llvm {
         template  class SmallVectorImpl;
       }
      @@ -38,6 +31,16 @@ namespace clang {
         
         // Import the diagnostic enums themselves.
         namespace diag {
      +    // Start position for diagnostics.
      +    enum {
      +      DIAG_START_LEX      =                        300,
      +      DIAG_START_PARSE    = DIAG_START_LEX      +  300,
      +      DIAG_START_AST      = DIAG_START_PARSE    +  300,
      +      DIAG_START_SEMA     = DIAG_START_AST      +  100,
      +      DIAG_START_ANALYSIS = DIAG_START_SEMA     + 1000,
      +      DIAG_UPPER_LIMIT    = DIAG_START_ANALYSIS +  100
      +    };
      +
           class CustomDiagInfo;
           
           /// diag::kind - All of the diagnostics that can be emitted by the frontend.
      @@ -93,7 +96,7 @@ private:
       
         /// DiagMappings - Mapping information for diagnostics.  Mapping info is
         /// packed into two bits per diagnostic.
      -  unsigned char DiagMappings[DIAG_UPPER_LIMIT/4];
      +  unsigned char DiagMappings[diag::DIAG_UPPER_LIMIT/4];
         
         /// ErrorOccurred - This is set to true when an error is emitted, and is
         /// sticky.
      @@ -155,7 +158,7 @@ public:
         /// setDiagnosticMapping - This allows the client to specify that certain
         /// warnings are ignored.  Only NOTEs, WARNINGs, and EXTENSIONs can be mapped.
         void setDiagnosticMapping(diag::kind Diag, diag::Mapping Map) {
      -    assert(Diag < DIAG_UPPER_LIMIT &&
      +    assert(Diag < diag::DIAG_UPPER_LIMIT &&
                  "Can only map builtin diagnostics");
           assert(isBuiltinNoteWarningOrExtension(Diag) && "Cannot map errors!");
           unsigned char &Slot = DiagMappings[Diag/4];
      diff --git a/clang/include/clang/Basic/DiagnosticCommonKinds.def b/clang/include/clang/Basic/DiagnosticCommonKinds.def
      index 73863215370f..019e9c0de80a 100644
      --- a/clang/include/clang/Basic/DiagnosticCommonKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticCommonKinds.def
      @@ -65,19 +65,7 @@ DIAG(note_invalid_subexpr_in_ice, NOTE,
       // Driver
       DIAG(pp_macro_not_used, WARNING,    // -Wunused-macros
            "macro is not used")
      -DIAG(warn_floatingpoint_eq, WARNING,
      -  "comparing floating point with == or != is unsafe")
      -DIAG(warn_objc_property_attr_mutually_exclusive, WARNING,
      -     "property attributes '%0' and '%1' are mutually exclusive")
      -DIAG(warn_printf_not_string_constant, WARNING,
      -     "format string is not a string literal (potentially insecure)")
      -DIAG(warn_implicit_function_decl, WARNING,
      -     "implicit declaration of function %0")
       DIAG(err_pp_I_dash_not_supported, ERROR,
            "-I- not supported, please use -iquote instead")
      -DIAG(warn_octal_escape_too_large, EXTWARN,
      -     "octal escape sequence out of range")
      -DIAG(warn_hex_escape_too_large, EXTWARN,
      -     "hex escape sequence out of range")
       DIAG(warn_pp_undef_identifier, WARNING,
            "%0 is not defined, evaluates to 0")
      diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
      index 70a4821ea170..e69de29bb2d1 100644
      --- a/clang/include/clang/Basic/DiagnosticKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticKinds.def
      @@ -1,33 +0,0 @@
      -//===-- DiagnosticKinds.def - C Family Diagnostic Kind Database -*- 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 the DiagnosticKind database.
      -//
      -//===----------------------------------------------------------------------===//
      -
      -// Flags for diagnostic:
      -//
      -//   DIAG_TYPE - Allows one of:
      -//     NOTE      - Informational message.
      -//     WARNING   - Warning.
      -//     EXTENSION - Notification that an extension to the language is being used.
      -//     EXTWARN   - Warning for behaviour that is supported as an extension. This 
      -//                 differs from EXTENSION in that the warning is always emitted
      -//                 by default.
      -//     ERROR     - Error, compilation will stop after parsing completes.
      -
      -
      -#include "clang/Basic/DiagnosticCommonKinds.def"
      -#include "clang/Basic/DiagnosticLexKinds.def"
      -#include "clang/Basic/DiagnosticParseKinds.def"
      -#include "clang/Basic/DiagnosticASTKinds.def"
      -#include "clang/Basic/DiagnosticSemaKinds.def"
      -#include "clang/Basic/DiagnosticAnalysisKinds.def"
      -
      -#undef DIAG
      diff --git a/clang/include/clang/Basic/DiagnosticLexKinds.def b/clang/include/clang/Basic/DiagnosticLexKinds.def
      index 696569896446..8c9a82688a7c 100644
      --- a/clang/include/clang/Basic/DiagnosticLexKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticLexKinds.def
      @@ -98,6 +98,10 @@ DIAG(ext_binary_literal, EXTENSION,
            "binary integer literals are an extension")
       DIAG(err_pascal_string_too_long, ERROR,
           "Pascal string is too long")
      +DIAG(warn_octal_escape_too_large, EXTWARN,
      +     "octal escape sequence out of range")
      +DIAG(warn_hex_escape_too_large, EXTWARN,
      +     "hex escape sequence out of range")
       
       //===----------------------------------------------------------------------===//
       // Preprocessor Diagnostics
      diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      index 6276d61211f3..63955adc13e6 100644
      --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      @@ -74,6 +74,8 @@ DIAG(err_parameter_name_omitted, ERROR,
            "parameter name omitted")
       DIAG(warn_decl_in_param_list, WARNING,
            "declaration of %0 will not be visible outside of this function")
      +DIAG(warn_implicit_function_decl, WARNING,
      +     "implicit declaration of function %0")
       
       DIAG(err_declarator_need_ident, ERROR,
            "declarator requires an identifier")
      @@ -196,6 +198,8 @@ DIAG(error_duplicate_ivar_use, ERROR,
            "synthesized properties %0 and %1 both claim ivar %2")
       DIAG(error_property_implemented, ERROR,
            "property %0 is already implemented")
      +DIAG(warn_objc_property_attr_mutually_exclusive, WARNING,
      +     "property attributes '%0' and '%1' are mutually exclusive")
       
       // C++ class members
       DIAG(err_storageclass_invalid_for_member, ERROR,
      @@ -624,6 +628,8 @@ DIAG(err_offsetof_array_type, ERROR,
            "offsetof requires array type, %0 invalid")
       DIAG(ext_offsetof_extended_field_designator, EXTENSION,
            "using extended field designator is an extension")
      +DIAG(warn_floatingpoint_eq, WARNING,
      +  "comparing floating point with == or != is unsafe")
            
       DIAG(err_typecheck_subscript_value, ERROR,
            "subscripted value is neither array nor pointer")
      @@ -721,6 +727,8 @@ DIAG(err_builtin_direct_init_more_than_one_arg, ERROR,
            "initializer of a builtin type can only take one argument")
       DIAG(err_value_init_for_array_type, ERROR,
            "array types cannot be value-initialized")
      +DIAG(warn_printf_not_string_constant, WARNING,
      +     "format string is not a string literal (potentially insecure)")
       
       DIAG(err_unexpected_interface, ERROR,
            "unexpected interface name %0: expected expression")
      diff --git a/clang/include/clang/Driver/DriverDiagnostic.h b/clang/include/clang/Driver/DriverDiagnostic.h
      index 459d17da4e47..e69de29bb2d1 100644
      --- a/clang/include/clang/Driver/DriverDiagnostic.h
      +++ b/clang/include/clang/Driver/DriverDiagnostic.h
      @@ -1,25 +0,0 @@
      -//===--- DiagnosticDriver.h - Diagnostics for the driver --------*- C++ -*-===//
      -//
      -//                     The LLVM Compiler Infrastructure
      -//
      -// This file is distributed under the University of Illinois Open Source
      -// License. See LICENSE.TXT for details.
      -//
      -//===----------------------------------------------------------------------===//
      -
      -#ifndef LLVM_CLANG_DIAGNOSTICDRIVER_H
      -#define LLVM_CLANG_DIAGNOSTICDRIVER_H
      -
      -#include "clang/Basic/Diagnostic.h"
      -
      -namespace clang {
      -  namespace diag { 
      -    enum {
      -// FIXME: REMOVE??
      -      NUM_BUILTIN_DRIVER_DIAGNOSTICS
      -    };
      -  }  // end namespace diag
      -}  // end namespace clang
      -
      -#endif
      -
      diff --git a/clang/include/clang/Lex/LexDiagnostic.h b/clang/include/clang/Lex/LexDiagnostic.h
      index 202605fe5ce5..8e79e15f6d02 100644
      --- a/clang/include/clang/Lex/LexDiagnostic.h
      +++ b/clang/include/clang/Lex/LexDiagnostic.h
      @@ -18,6 +18,7 @@ namespace clang {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
       #define LEXSTART
       #include "clang/Basic/DiagnosticLexKinds.def"
      +#undef DIAG
             NUM_BUILTIN_LEX_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/include/clang/Parse/ParseDiagnostic.h b/clang/include/clang/Parse/ParseDiagnostic.h
      index 52a89e89041e..1856b0670bbf 100644
      --- a/clang/include/clang/Parse/ParseDiagnostic.h
      +++ b/clang/include/clang/Parse/ParseDiagnostic.h
      @@ -18,6 +18,7 @@ namespace clang {
       #define DIAG(ENUM,FLAGS,DESC) ENUM,
       #define PARSESTART
       #include "clang/Basic/DiagnosticParseKinds.def"
      +#undef DIAG
             NUM_BUILTIN_PARSE_DIAGNOSTICS
           };
         }  // end namespace diag
      diff --git a/clang/lib/Basic/Diagnostic.cpp b/clang/lib/Basic/Diagnostic.cpp
      index 6e39beb0c89e..5b1145f70b8f 100644
      --- a/clang/lib/Basic/Diagnostic.cpp
      +++ b/clang/lib/Basic/Diagnostic.cpp
      @@ -68,21 +68,21 @@ static unsigned char DiagnosticFlagsAnalysis[] = {
       /// getDiagClass - Return the class field of the diagnostic.
       ///
       static unsigned getBuiltinDiagClass(unsigned DiagID) {
      -  assert(DiagID < DIAG_UPPER_LIMIT &&
      +  assert(DiagID < diag::DIAG_UPPER_LIMIT &&
                "Diagnostic ID out of range!");
         unsigned res;
      -  if (DiagID < DIAG_START_LEX)
      +  if (DiagID < diag::DIAG_START_LEX)
           res = DiagnosticFlagsCommon[DiagID];
      -  else if (DiagID < DIAG_START_PARSE)
      -    res = DiagnosticFlagsLex[DiagID - DIAG_START_LEX - 1];
      -  else if (DiagID < DIAG_START_AST)
      -    res = DiagnosticFlagsParse[DiagID - DIAG_START_PARSE - 1];
      -  else if (DiagID < DIAG_START_SEMA)
      -    res = DiagnosticFlagsAST[DiagID - DIAG_START_AST - 1];
      -  else if (DiagID < DIAG_START_ANALYSIS)
      -    res = DiagnosticFlagsSema[DiagID - DIAG_START_SEMA - 1];
      +  else if (DiagID < diag::DIAG_START_PARSE)
      +    res = DiagnosticFlagsLex[DiagID - diag::DIAG_START_LEX - 1];
      +  else if (DiagID < diag::DIAG_START_AST)
      +    res = DiagnosticFlagsParse[DiagID - diag::DIAG_START_PARSE - 1];
      +  else if (DiagID < diag::DIAG_START_SEMA)
      +    res = DiagnosticFlagsAST[DiagID - diag::DIAG_START_AST - 1];
      +  else if (DiagID < diag::DIAG_START_ANALYSIS)
      +    res = DiagnosticFlagsSema[DiagID - diag::DIAG_START_SEMA - 1];
         else
      -    res = DiagnosticFlagsAnalysis[DiagID - DIAG_START_ANALYSIS - 1];
      +    res = DiagnosticFlagsAnalysis[DiagID - diag::DIAG_START_ANALYSIS - 1];
         return res & class_mask;
       }
       
      @@ -216,26 +216,26 @@ unsigned Diagnostic::getCustomDiagID(Level L, const char *Message) {
       /// level of the specified diagnostic ID is a Note, Warning, or Extension.
       /// Note that this only works on builtin diagnostics, not custom ones.
       bool Diagnostic::isBuiltinNoteWarningOrExtension(unsigned DiagID) {
      -  return DiagID < DIAG_UPPER_LIMIT && getBuiltinDiagClass(DiagID) < ERROR;
      +  return DiagID < diag::DIAG_UPPER_LIMIT && getBuiltinDiagClass(DiagID) < ERROR;
       }
       
       
       /// getDescription - Given a diagnostic ID, return a description of the
       /// issue.
       const char *Diagnostic::getDescription(unsigned DiagID) const {
      -  if (DiagID < DIAG_UPPER_LIMIT) {
      -    if (DiagID < DIAG_START_LEX)
      +  if (DiagID < diag::DIAG_UPPER_LIMIT) {
      +    if (DiagID < diag::DIAG_START_LEX)
             return DiagnosticTextCommon[DiagID];
      -    else if (DiagID < DIAG_START_PARSE)
      -      return DiagnosticTextLex[DiagID - DIAG_START_LEX - 1];
      -    else if (DiagID < DIAG_START_AST)
      -      return DiagnosticTextParse[DiagID - DIAG_START_PARSE - 1];
      -    else if (DiagID < DIAG_START_SEMA)
      -      return DiagnosticTextAST[DiagID - DIAG_START_AST - 1];
      -    else if (DiagID < DIAG_START_ANALYSIS)
      -      return DiagnosticTextSema[DiagID - DIAG_START_SEMA - 1];
      -    else if (DiagID < DIAG_UPPER_LIMIT)
      -      return DiagnosticTextAnalysis[DiagID - DIAG_START_ANALYSIS - 1];
      +    else if (DiagID < diag::DIAG_START_PARSE)
      +      return DiagnosticTextLex[DiagID - diag::DIAG_START_LEX - 1];
      +    else if (DiagID < diag::DIAG_START_AST)
      +      return DiagnosticTextParse[DiagID - diag::DIAG_START_PARSE - 1];
      +    else if (DiagID < diag::DIAG_START_SEMA)
      +      return DiagnosticTextAST[DiagID - diag::DIAG_START_AST - 1];
      +    else if (DiagID < diag::DIAG_START_ANALYSIS)
      +      return DiagnosticTextSema[DiagID - diag::DIAG_START_SEMA - 1];
      +    else if (DiagID < diag::DIAG_UPPER_LIMIT)
      +      return DiagnosticTextAnalysis[DiagID - diag::DIAG_START_ANALYSIS - 1];
         }
          
         return CustomDiagInfo->getDescription(DiagID);
      @@ -246,7 +246,7 @@ const char *Diagnostic::getDescription(unsigned DiagID) const {
       /// the DiagnosticClient.
       Diagnostic::Level Diagnostic::getDiagnosticLevel(unsigned DiagID) const {
         // Handle custom diagnostics, which cannot be mapped.
      -  if (DiagID >= DIAG_UPPER_LIMIT)
      +  if (DiagID >= diag::DIAG_UPPER_LIMIT)
           return CustomDiagInfo->getLevel(DiagID);
         
         unsigned DiagClass = getBuiltinDiagClass(DiagID);
      @@ -307,7 +307,7 @@ void Diagnostic::ProcessDiag() {
         // ignore extensions and warnings in -Werror and -pedantic-errors modes,
         // which *map* warnings/extensions to errors.
         if (SuppressSystemWarnings &&
      -      Info.getID() < DIAG_UPPER_LIMIT &&
      +      Info.getID() < diag::DIAG_UPPER_LIMIT &&
             getBuiltinDiagClass(Info.getID()) != ERROR &&
             Info.getLocation().isValid() &&
             Info.getLocation().getSpellingLoc().isInSystemHeader())
      -- 
      GitLab
      
      
      From 1cb12da1689ed6e9a43a611c302655d71b74ccdf Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 17:46:42 +0000
      Subject: [PATCH 437/682] remove two empty files
      
      llvm-svn: 63319
      ---
       clang/include/clang/Basic/DiagnosticKinds.def | 0
       clang/include/clang/Driver/DriverDiagnostic.h | 0
       2 files changed, 0 insertions(+), 0 deletions(-)
       delete mode 100644 clang/include/clang/Basic/DiagnosticKinds.def
       delete mode 100644 clang/include/clang/Driver/DriverDiagnostic.h
      
      diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
      deleted file mode 100644
      index e69de29bb2d1..000000000000
      diff --git a/clang/include/clang/Driver/DriverDiagnostic.h b/clang/include/clang/Driver/DriverDiagnostic.h
      deleted file mode 100644
      index e69de29bb2d1..000000000000
      -- 
      GitLab
      
      
      From d25adc945e6a019372df8a83af93d2b1a668c781 Mon Sep 17 00:00:00 2001
      From: Steve Naroff 
      Date: Thu, 29 Jan 2009 18:09:31 +0000
      Subject: [PATCH 438/682] Hack Sema::LookupDeclInScope() to avoid calling
       Sema::LookupName() when parsing C/ObjC.
      
      This results in a 1.7% improvement for "Cocoa.h". If we can figure out how to return a "Decl *", rather than a Sema::LookupResult(), we will likely bump the speedup from 1.7%->2.5%. I verified this, however couldn't get it to work without breaking a fair number of C++ test cases. Will discuss with Doug offline.
      
      llvm-svn: 63320
      ---
       clang/lib/Sema/Sema.h       |   2 +-
       clang/lib/Sema/SemaDecl.cpp | 138 ++++++++++++++++++++++++++----------
       2 files changed, 103 insertions(+), 37 deletions(-)
      
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index 4a81f71dea39..fe2b9de79e10 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -782,7 +782,7 @@ public:
         LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS, 
                                       DeclarationName Name, LookupCriteria Criteria);
         LookupResult LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
      -                                 bool LookInParent = true);
      +                          bool LookInParent = true);
         LookupResult LookupDeclInContext(DeclarationName Name, unsigned NSI,
                                 const DeclContext *LookupCtx,
                                 bool LookInParent = true);
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index 1559213fcb8e..cf71d394ce97 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -39,31 +39,32 @@ Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S,
             return 0;
           DC = static_cast(SS->getScopeRep());
         }
      -  LookupResult Result = DC ? 
      -                 LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
      -                 LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
      -                   
         Decl *IIDecl = 0;
      +  
      +  LookupResult Result =  DC ? LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
      +                              LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
      +                 
         switch (Result.getKind()) {
      -  case LookupResult::NotFound:
      -  case LookupResult::FoundOverloaded:
      -  case LookupResult::AmbiguousBaseSubobjectTypes:
      -  case LookupResult::AmbiguousBaseSubobjects:
      -    // FIXME: In the event of an ambiguous lookup, we could visit all of
      -    // the entities found to determine whether they are all types. This
      -    // might provide better diagnostics.
      -    return 0;
      -
      -  case LookupResult::Found:
      -    IIDecl = Result.getAsDecl();
      -    break;
      +    case LookupResult::NotFound:
      +    case LookupResult::FoundOverloaded:
      +    case LookupResult::AmbiguousBaseSubobjectTypes:
      +    case LookupResult::AmbiguousBaseSubobjects:
      +      // FIXME: In the event of an ambiguous lookup, we could visit all of
      +      // the entities found to determine whether they are all types. This
      +      // might provide better diagnostics.
      +      return 0;
      +    case LookupResult::Found:
      +      IIDecl = Result.getAsDecl();
      +      break;
         }
       
      -  if (isa(IIDecl) || 
      -      isa(IIDecl) ||
      -      isa(IIDecl) ||
      -      isa(IIDecl))
      -    return IIDecl;
      +  if (IIDecl) {
      +    if (isa(IIDecl) || 
      +        isa(IIDecl) ||
      +        isa(IIDecl) ||
      +        isa(IIDecl))
      +      return IIDecl;
      +  }
         return 0;
       }
       
      @@ -265,19 +266,85 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
       Sema::LookupResult
       Sema::LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
                               bool LookInParent) {
      -  LookupCriteria::NameKind Kind;
      -  if (NSI == Decl::IDNS_Ordinary) {
      -    Kind = LookupCriteria::Ordinary;
      -  } else if (NSI == Decl::IDNS_Tag) 
      -    Kind = LookupCriteria::Tag;
      -  else {
      -    assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
      -    Kind = LookupCriteria::Member;
      +  if (getLangOptions().CPlusPlus) {
      +    LookupCriteria::NameKind Kind;
      +    if (NSI == Decl::IDNS_Ordinary) {
      +      Kind = LookupCriteria::Ordinary;
      +    } else if (NSI == Decl::IDNS_Tag) 
      +      Kind = LookupCriteria::Tag;
      +    else {
      +      assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
      +      Kind = LookupCriteria::Member;
      +    }
      +    // Unqualified lookup
      +    return LookupName(S, Name, 
      +                      LookupCriteria(Kind, !LookInParent,
      +                                     getLangOptions().CPlusPlus));
      +  }
      +  // Fast path for C/ObjC.
      +  
      +  // Unqualified name lookup in C/Objective-C is purely lexical, so
      +  // search in the declarations attached to the name.
      +
      +  // For the purposes of unqualified name lookup, structs and unions
      +  // don't have scopes at all. For example:
      +  //
      +  //   struct X {
      +  //     struct T { int i; } x;
      +  //   };
      +  //
      +  //   void f() {
      +  //     struct T t; // okay: T is defined lexically within X, but
      +  //                 // semantically at global scope
      +  //   };
      +  //
      +  // FIXME: Is there a better way to deal with this?
      +  DeclContext *SearchCtx = CurContext;
      +  while (isa(SearchCtx) || isa(SearchCtx))
      +    SearchCtx = SearchCtx->getParent();
      +  IdentifierResolver::iterator I
      +    = IdResolver.begin(Name, SearchCtx, LookInParent);
      +  
      +  // Scan up the scope chain looking for a decl that matches this
      +  // identifier that is in the appropriate namespace.  This search
      +  // should not take long, as shadowing of names is uncommon, and
      +  // deep shadowing is extremely uncommon.
      +  for (; I != IdResolver.end(); ++I) {
      +    switch (NSI) {
      +      case Decl::IDNS_Ordinary:
      +      case Decl::IDNS_Tag:
      +      case Decl::IDNS_Member:
      +        if ((*I)->isInIdentifierNamespace(NSI))
      +          return LookupResult::CreateLookupResult(Context, *I);
      +        break;
      +      default:
      +        assert(0 && "Unable to grok LookupDecl NSI argument");
      +    }
         }
      -  // Unqualified lookup
      -  return LookupName(S, Name, 
      -                    LookupCriteria(Kind, !LookInParent,
      -                                   getLangOptions().CPlusPlus));
      +  if (NSI == Decl::IDNS_Ordinary) {
      +    IdentifierInfo *II = Name.getAsIdentifierInfo();
      +    if (II) {
      +      // If this is a builtin on this (or all) targets, create the decl.
      +      if (unsigned BuiltinID = II->getBuiltinID())
      +        return LookupResult::CreateLookupResult(Context,
      +                            LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
      +                                                S));
      +    }
      +    if (getLangOptions().ObjC1 && II) {
      +      // @interface and @compatibility_alias introduce typedef-like names.
      +      // Unlike typedef's, they can only be introduced at file-scope (and are 
      +      // therefore not scoped decls). They can, however, be shadowed by
      +      // other names in IDNS_Ordinary.
      +      ObjCInterfaceDeclsTy::iterator IDI = ObjCInterfaceDecls.find(II);
      +      if (IDI != ObjCInterfaceDecls.end())
      +        return LookupResult::CreateLookupResult(Context, IDI->second);
      +      ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
      +      if (I != ObjCAliasDecls.end())
      +        return LookupResult::CreateLookupResult(Context, 
      +                                                I->second->getClassInterface());
      +    }
      +  }
      +  return LookupResult::CreateLookupResult(Context, 0);
       }
       
       Sema::LookupResult
      @@ -2898,9 +2965,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
         } else if (Name) {
           // If this is a named struct, check to see if there was a previous forward
           // declaration or definition.
      -    PrevDecl = dyn_cast_or_null(LookupDeclInScope(Name, 
      -                                                             Decl::IDNS_Tag,S)
      -                                           .getAsDecl());
      +    Decl *D = LookupDeclInScope(Name, Decl::IDNS_Tag, S);
      +    PrevDecl = dyn_cast_or_null(D);
       
           if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
             // FIXME: This makes sure that we ignore the contexts associated
      -- 
      GitLab
      
      
      From a160d4af827c29a08387f6dfb1b4a6cf5efa69a6 Mon Sep 17 00:00:00 2001
      From: Evan Cheng 
      Date: Thu, 29 Jan 2009 18:37:30 +0000
      Subject: [PATCH 439/682] Local register allocator shouldn't assume only the
       entry and landing pad basic blocks have live-ins.
      
      llvm-svn: 63323
      ---
       llvm/lib/CodeGen/RegAllocLocal.cpp            | 29 +++++++-------
       .../X86/2009-01-29-LocalRegAllocBug.ll        | 38 +++++++++++++++++++
       2 files changed, 51 insertions(+), 16 deletions(-)
       create mode 100644 llvm/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll
      
      diff --git a/llvm/lib/CodeGen/RegAllocLocal.cpp b/llvm/lib/CodeGen/RegAllocLocal.cpp
      index 9fc5f738b4e4..a8c69008c24a 100644
      --- a/llvm/lib/CodeGen/RegAllocLocal.cpp
      +++ b/llvm/lib/CodeGen/RegAllocLocal.cpp
      @@ -710,24 +710,21 @@ void RALocal::AllocateBasicBlock(MachineBasicBlock &MBB) {
         DEBUG(const BasicBlock *LBB = MBB.getBasicBlock();
               if (LBB) DOUT << "\nStarting RegAlloc of BB: " << LBB->getName());
       
      -  // If this is the first basic block in the machine function, add live-in
      -  // registers as active.
      -  if (&MBB == &*MF->begin() || MBB.isLandingPad()) {
      -    for (MachineBasicBlock::livein_iterator I = MBB.livein_begin(),
      +  // Add live-in registers as active.
      +  for (MachineBasicBlock::livein_iterator I = MBB.livein_begin(),
                E = MBB.livein_end(); I != E; ++I) {
      -      unsigned Reg = *I;
      -      MF->getRegInfo().setPhysRegUsed(Reg);
      -      PhysRegsUsed[Reg] = 0;            // It is free and reserved now
      -      AddToPhysRegsUseOrder(Reg); 
      -      for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
      -           *SubRegs; ++SubRegs) {
      -        if (PhysRegsUsed[*SubRegs] != -2) {
      -          AddToPhysRegsUseOrder(*SubRegs); 
      -          PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
      -          MF->getRegInfo().setPhysRegUsed(*SubRegs);
      -        }
      +    unsigned Reg = *I;
      +    MF->getRegInfo().setPhysRegUsed(Reg);
      +    PhysRegsUsed[Reg] = 0;            // It is free and reserved now
      +    AddToPhysRegsUseOrder(Reg); 
      +    for (const unsigned *SubRegs = TRI->getSubRegisters(Reg);
      +         *SubRegs; ++SubRegs) {
      +      if (PhysRegsUsed[*SubRegs] != -2) {
      +        AddToPhysRegsUseOrder(*SubRegs); 
      +        PhysRegsUsed[*SubRegs] = 0;  // It is free and reserved now
      +        MF->getRegInfo().setPhysRegUsed(*SubRegs);
             }
      -    }    
      +    }
         }
         
         ComputeLocalLiveness(MBB);
      diff --git a/llvm/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll b/llvm/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll
      new file mode 100644
      index 000000000000..b7f37c9d3102
      --- /dev/null
      +++ b/llvm/test/CodeGen/X86/2009-01-29-LocalRegAllocBug.ll
      @@ -0,0 +1,38 @@
      +; RUN: llvm-as < %s | llc -mtriple=i386-apple-darwin9.6 -regalloc=local -disable-fp-elim
      +; rdar://6538384
      +
      +	%struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
      +	%struct.Lit = type { i32 }
      +	%struct.StreamBuffer = type { %struct.FILE*, [1048576 x i8], i32, i32 }
      +	%struct.__sFILEX = type opaque
      +	%struct.__sbuf = type { i8*, i32 }
      +
      +declare fastcc i32 @_Z8parseIntI12StreamBufferEiRT_(%struct.StreamBuffer*)
      +
      +declare i8* @llvm.eh.exception() nounwind
      +
      +define i32 @main(i32 %argc, i8** nocapture %argv) noreturn {
      +entry:
      +	%0 = invoke fastcc i32 @_Z8parseIntI12StreamBufferEiRT_(%struct.StreamBuffer* null)
      +			to label %bb1.i16.i.i unwind label %lpad.i.i		;  [#uses=0]
      +
      +bb1.i16.i.i:		; preds = %entry
      +	br i1 false, label %bb.i.i.i.i, label %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i
      +
      +bb.i.i.i.i:		; preds = %bb1.i16.i.i
      +	br label %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i
      +
      +_ZN3vecI3LitE4pushERKS0_.exit.i.i.i:		; preds = %bb.i.i.i.i, %bb1.i16.i.i
      +	%lits.i.i.0.0 = phi %struct.Lit* [ null, %bb1.i16.i.i ], [ null, %bb.i.i.i.i ]		; <%struct.Lit*> [#uses=1]
      +	%1 = invoke fastcc i32 @_Z8parseIntI12StreamBufferEiRT_(%struct.StreamBuffer* null)
      +			to label %.noexc21.i.i unwind label %lpad.i.i		;  [#uses=0]
      +
      +.noexc21.i.i:		; preds = %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i
      +	unreachable
      +
      +lpad.i.i:		; preds = %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i, %entry
      +	%lits.i.i.0.3 = phi %struct.Lit* [ %lits.i.i.0.0, %_ZN3vecI3LitE4pushERKS0_.exit.i.i.i ], [ null, %entry ]		; <%struct.Lit*> [#uses=1]
      +	%eh_ptr.i.i = call i8* @llvm.eh.exception()		;  [#uses=0]
      +	free %struct.Lit* %lits.i.i.0.3
      +	unreachable
      +}
      -- 
      GitLab
      
      
      From 409f555400f9402638d846e1af17505da92581dd Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 18:49:48 +0000
      Subject: [PATCH 440/682] diags moved, so these casts are no longer needed.
      
      llvm-svn: 63324
      ---
       clang/lib/Sema/SemaDeclObjC.cpp | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
      index 5677bc5e0920..3371e3ea6e20 100644
      --- a/clang/lib/Sema/SemaDeclObjC.cpp
      +++ b/clang/lib/Sema/SemaDeclObjC.cpp
      @@ -1432,8 +1432,8 @@ void Sema::CheckObjCPropertyAttributes(QualType PropertyTy,
                                 "copy" : "retain";
                                
           Diag(Loc, (Attributes & (ObjCDeclSpec::DQ_PR_readwrite)) ? 
      -                 (unsigned)diag::err_objc_property_attr_mutually_exclusive :
      -                 (unsigned)diag::warn_objc_property_attr_mutually_exclusive)
      +                 diag::err_objc_property_attr_mutually_exclusive :
      +                 diag::warn_objc_property_attr_mutually_exclusive)
             << "readonly" << which;
         }
       
      -- 
      GitLab
      
      
      From dfb6735385d32d555d1aea436dc3129d41b1961e Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Thu, 29 Jan 2009 18:53:28 +0000
      Subject: [PATCH 441/682] Fix windows build, patch by Marius Wachtler!
      
      llvm-svn: 63325
      ---
       llvm/lib/System/Win32/DynamicLibrary.inc | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/llvm/lib/System/Win32/DynamicLibrary.inc b/llvm/lib/System/Win32/DynamicLibrary.inc
      index c76032f62d06..210eb2128d59 100644
      --- a/llvm/lib/System/Win32/DynamicLibrary.inc
      +++ b/llvm/lib/System/Win32/DynamicLibrary.inc
      @@ -156,8 +156,8 @@ bool DynamicLibrary::LoadLibraryPermanently(const char *filename,
       
       void* DynamicLibrary::SearchForAddressOfSymbol(const char* symbolName) {
         // First check symbols added via AddSymbol().
      -  std::map::iterator I = g_symbols.find(symbolName);
      -  if (I != g_symbols.end())
      +  std::map::iterator I = g_symbols().find(symbolName);
      +  if (I != g_symbols().end())
           return I->second;
       
         // Now search the libraries.
      -- 
      GitLab
      
      
      From 56b3b77c7d347d32075d46805145ad5806dff7df Mon Sep 17 00:00:00 2001
      From: Fariborz Jahanian 
      Date: Thu, 29 Jan 2009 19:24:30 +0000
      Subject: [PATCH 442/682] Protocol meta-data for objc2's non-fragile abi. Lot
       more to do in this area.
      
      llvm-svn: 63326
      ---
       clang/lib/CodeGen/CGObjCMac.cpp | 254 +++++++++++++++++++++++++++++---
       1 file changed, 233 insertions(+), 21 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
      index 8ffed61857f3..67db5fa7e6ca 100644
      --- a/clang/lib/CodeGen/CGObjCMac.cpp
      +++ b/clang/lib/CodeGen/CGObjCMac.cpp
      @@ -358,6 +358,11 @@ protected:
                                          const ObjCContainerDecl *OCD,
                                          const ObjCCommonTypesHelper &ObjCTypes);
         
      +  /// GetProtocolRef - Return a reference to the internal protocol
      +  /// description, creating an empty one if it has not been
      +  /// defined. The return value has type ProtocolPtrTy.
      +  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
      +  
       public:
         CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm)
         { }
      @@ -366,6 +371,19 @@ public:
         
         virtual llvm::Function *GenerateMethod(const ObjCMethodDecl *OMD,
                                                const ObjCContainerDecl *CD=0);
      +  
      +  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
      +  
      +  /// GetOrEmitProtocol - Get the protocol object for the given
      +  /// declaration, emitting it if necessary. The return value has type
      +  /// ProtocolPtrTy.
      +  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD)=0;
      +  
      +  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
      +  /// object for the given declaration, emitting it if needed. These
      +  /// forward references will be filled in with empty bodies if no
      +  /// definition is seen. The return value has type ProtocolPtrTy.
      +  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD)=0;
       };
         
       class CGObjCMac : public CGObjCCommonMac {
      @@ -453,13 +471,13 @@ private:
         /// GetOrEmitProtocol - Get the protocol object for the given
         /// declaration, emitting it if necessary. The return value has type
         /// ProtocolPtrTy.
      -  llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
      +  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
       
         /// GetOrEmitProtocolRef - Get a forward reference to the protocol
         /// object for the given declaration, emitting it if needed. These
         /// forward references will be filled in with empty bodies if no
         /// definition is seen. The return value has type ProtocolPtrTy.
      -  llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
      +  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
       
         /// EmitProtocolExtension - Generate the protocol extension
         /// structure used to store optional instance and class methods, and
      @@ -480,12 +498,7 @@ private:
         /// for the given selector.
         llvm::Value *EmitSelector(CGBuilderTy &Builder, Selector Sel);
         
      -  /// GetProtocolRef - Return a reference to the internal protocol
      -  /// description, creating an empty one if it has not been
      -  /// defined. The return value has type ProtocolPtrTy.
      -  llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD);
      -
      -public:
      +  public:
         CGObjCMac(CodeGen::CodeGenModule &cgm);
       
         virtual llvm::Function *ModuleInitFunction();
      @@ -517,9 +530,7 @@ public:
       
         virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder,
                                                  const ObjCProtocolDecl *PD);
      -
      -  virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
      -
      +    
         virtual llvm::Function *GetPropertyGetFunction();
         virtual llvm::Function *GetPropertySetFunction();
         virtual llvm::Function *EnumerationMutationFunction();
      @@ -577,6 +588,23 @@ private:
                                           const ObjCIvarDecl *Ivar,
                                           unsigned long int offset);
         
      +  /// GetOrEmitProtocol - Get the protocol object for the given
      +  /// declaration, emitting it if necessary. The return value has type
      +  /// ProtocolPtrTy.
      +  virtual llvm::Constant *GetOrEmitProtocol(const ObjCProtocolDecl *PD);
      +    
      +  /// GetOrEmitProtocolRef - Get a forward reference to the protocol
      +  /// object for the given declaration, emitting it if needed. These
      +  /// forward references will be filled in with empty bodies if no
      +  /// definition is seen. The return value has type ProtocolPtrTy.
      +  virtual llvm::Constant *GetOrEmitProtocolRef(const ObjCProtocolDecl *PD);
      +    
      +  /// EmitProtocolList - Generate the list of referenced
      +  /// protocols. The return value has type ProtocolListPtrTy.
      +  llvm::Constant *EmitProtocolList(const std::string &Name,
      +                                   ObjCProtocolDecl::protocol_iterator begin,
      +                                   ObjCProtocolDecl::protocol_iterator end);  
      +  
       public:
         CGObjCNonFragileABIMac(CodeGen::CodeGenModule &cgm);
         // FIXME. All stubs for now!
      @@ -613,8 +641,6 @@ public:
                                                  const ObjCProtocolDecl *PD)
           { return 0; }
         
      -  virtual void GenerateProtocol(const ObjCProtocolDecl *PD){ return; }
      -  
         virtual llvm::Function *GetPropertyGetFunction(){ return 0; }
         virtual llvm::Function *GetPropertySetFunction()
           { return 0; }
      @@ -795,7 +821,7 @@ llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder,
                                               ObjCTypes.ExternalProtocolPtrTy);
       }
       
      -void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
      +void CGObjCCommonMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
         // FIXME: We shouldn't need this, the protocol decl should contain
         // enough information to tell us whether this was a declaration or a
         // definition.
      @@ -808,7 +834,7 @@ void CGObjCMac::GenerateProtocol(const ObjCProtocolDecl *PD) {
           GetOrEmitProtocol(PD);
       }
       
      -llvm::Constant *CGObjCMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
      +llvm::Constant *CGObjCCommonMac::GetProtocolRef(const ObjCProtocolDecl *PD) {
         if (DefinedProtocols.count(PD->getIdentifier()))
           return GetOrEmitProtocol(PD);
         return GetOrEmitProtocolRef(PD);
      @@ -2984,7 +3010,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
         CGM.getModule().addTypeName("struct._protocol_t",
                                     ProtocolnfABITy);
         
      -  // struct _objc_protocol_list {
      +  // struct _protocol_list_t {
         //   long protocol_count;   // Note, this is 32/64 bit
         //   struct _protocol_t[protocol_count];
         // }
      @@ -3153,7 +3179,7 @@ enum MetaDataDlags {
       ///   const uint8_t * const ivarLayout;
       ///   const char *const name;
       ///   const struct _method_list_t * const baseMethods;
      -///   const struct _objc_protocol_list *const baseProtocols;
      +///   const struct _protocol_list_t *const baseProtocols;
       ///   const struct _ivar_list_t *const ivars;
       ///   const uint8_t * const weakIvarLayout;
       ///   const struct _prop_list_t * const properties;
      @@ -3170,6 +3196,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
         Values[ 1] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceStart);
         Values[ 2] = llvm::ConstantInt::get(ObjCTypes.IntTy, InstanceSize);
         // FIXME. For 64bit targets add 0 here.
      +  // FIXME. ivarLayout is currently null!
         Values[ 3] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
         Values[ 4] = GetClassName(ID->getIdentifier());
         // const struct _method_list_t * const baseMethods;
      @@ -3205,14 +3232,21 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer(
             }
           }
         }
      -  // FIXME. Section may always be .data
         Values[ 5] = EmitMethodList(MethodListName, 
                      "__DATA, __objc_const", Methods);
      -  Values[ 6] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
      +  
      +  const ObjCInterfaceDecl *OID = ID->getClassInterface();
      +  assert(OID && "CGObjCNonFragileABIMac::BuildClassRoTInitializer");
      +  Values[ 6] = EmitProtocolList("\01l_OBJC_CLASS_PROTOCOLS_$_" 
      +                                + OID->getNameAsString(),
      +                                OID->protocol_begin(),
      +                                OID->protocol_end());
      +  
         if (flags & CLS_META)
           Values[ 7] = llvm::Constant::getNullValue(ObjCTypes.IvarListnfABIPtrTy);
         else
           Values[ 7] = EmitIvarList(ID);
      +  // FIXME. weakIvarLayout is currently null.
         Values[ 8] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
         if (flags & CLS_META)
           Values[ 9] = llvm::Constant::getNullValue(ObjCTypes.PropertyListPtrTy);
      @@ -3485,7 +3519,11 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD)
         Values[3] = EmitMethodList(MethodListName, 
                                    "__DATA, __objc_const", 
                                    Methods);
      -  Values[4] = llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
      +  Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 
      +                               + Interface->getNameAsString(),
      +                                Interface->protocol_begin(),
      +                                Interface->protocol_end());
      +  
         const ObjCCategoryDecl *Category = 
           Interface->FindCategoryDeclaration(OCD->getIdentifier());
         std::string ExtName(Interface->getNameAsString() + "_$_" +
      @@ -3692,7 +3730,181 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList(
         UsedGlobals.push_back(GV);
         return llvm::ConstantExpr::getBitCast(GV,
                                               ObjCTypes.IvarListnfABIPtrTy);
      -}  
      +}
      +
      +llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef(
      +                                                  const ObjCProtocolDecl *PD) {
      +  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
      +  
      +  if (!Entry) {
      +    // We use the initializer as a marker of whether this is a forward
      +    // reference or not. At module finalization we add the empty
      +    // contents for protocols which were referenced but never defined.
      +    Entry = 
      +    new llvm::GlobalVariable(ObjCTypes.ProtocolnfABITy, false,
      +                             llvm::GlobalValue::ExternalLinkage,
      +                             0,
      +                             "\01l_OBJC_PROTOCOL_$_" + PD->getNameAsString(),
      +                             &CGM.getModule());
      +    Entry->setSection("__DATA,__datacoal_nt,coalesced");
      +    UsedGlobals.push_back(Entry);
      +    // FIXME: Is this necessary? Why only for protocol?
      +    Entry->setAlignment(4);
      +  }
      +  
      +  return Entry;
      +}
      +
      +/// GetOrEmitProtocol - Generate the protocol meta-data:
      +/// @code
      +/// struct _protocol_t {
      +///   id isa;  // NULL
      +///   const char * const protocol_name;
      +///   const struct _protocol_list_t * protocol_list; // super protocols
      +///   const struct method_list_t * const instance_methods;
      +///   const struct method_list_t * const class_methods;
      +///   const struct method_list_t *optionalInstanceMethods;
      +///   const struct method_list_t *optionalClassMethods;
      +///   const struct _prop_list_t * properties;
      +///   const uint32_t size;  // sizeof(struct _protocol_t)
      +///   const uint32_t flags;  // = 0
      +/// }
      +/// @endcode
      +///
      +
      +llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
      +                                                  const ObjCProtocolDecl *PD) {
      +  llvm::GlobalVariable *&Entry = Protocols[PD->getIdentifier()];
      +  
      +  // Early exit if a defining object has already been generated.
      +  if (Entry && Entry->hasInitializer())
      +    return Entry;
      +
      +  const char *ProtocolName = PD->getNameAsCString();
      +  
      +  // Construct method lists.
      +  std::vector InstanceMethods, ClassMethods;
      +  std::vector OptInstanceMethods, OptClassMethods;
      +  for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
      +       e = PD->instmeth_end(); i != e; ++i) {
      +    ObjCMethodDecl *MD = *i;
      +    llvm::Constant *C = GetMethodConstant(MD);
      +    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
      +      OptInstanceMethods.push_back(C);
      +    } else {
      +      InstanceMethods.push_back(C);
      +    }      
      +  }
      +  
      +  for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
      +       e = PD->classmeth_end(); i != e; ++i) {
      +    ObjCMethodDecl *MD = *i;
      +    llvm::Constant *C = GetMethodConstant(MD);
      +    if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
      +      OptClassMethods.push_back(C);
      +    } else {
      +      ClassMethods.push_back(C);
      +    }      
      +  }
      +  
      +  std::vector Values(10);
      +  // isa is NULL
      +  Values[0] = llvm::Constant::getNullValue(ObjCTypes.ObjectPtrTy);
      +  Values[1] = GetClassName(PD->getIdentifier());
      +  Values[2] = EmitProtocolList(
      +                          "\01l_OBJC_$_PROTOCOL_REFS_" + PD->getNameAsString(),
      +                          PD->protocol_begin(),
      +                          PD->protocol_end());
      +  
      +  Values[3] = EmitMethodList("\01l_OBJC_$_INSTANCE_METHODS_"
      +                             + PD->getNameAsString(),
      +                             "__DATA, __objc_const",
      +                             InstanceMethods);
      +  Values[4] = EmitMethodList("\01l_OBJC_$_CLASS_METHODS_" 
      +                             + PD->getNameAsString(),
      +                             "__DATA, __objc_const",
      +                             ClassMethods);
      +  Values[5] = EmitMethodList("\01l_OBJC_$_INSTANCE_METHODS_OPT_"
      +                             + PD->getNameAsString(),
      +                             "__DATA, __objc_const",
      +                             OptInstanceMethods);
      +  Values[6] = EmitMethodList("\01l_OBJC_$_CLASS_METHODS_OPT_" 
      +                             + PD->getNameAsString(),
      +                             "__DATA, __objc_const",
      +                             OptClassMethods);
      +  Values[7] = EmitPropertyList("\01l_OBJC_$_PROP_LIST_" + PD->getNameAsString(),
      +                               0, PD, ObjCTypes);
      +  uint32_t Size = 
      +    CGM.getTargetData().getTypePaddedSize(ObjCTypes.ProtocolnfABITy);
      +  Values[8] = llvm::ConstantInt::get(ObjCTypes.IntTy, Size);
      +  Values[9] = llvm::Constant::getNullValue(ObjCTypes.IntTy);
      +  llvm::Constant *Init = llvm::ConstantStruct::get(ObjCTypes.ProtocolnfABITy,
      +                                                   Values);
      +  
      +  if (Entry) {
      +    // Already created, fix the linkage and update the initializer.
      +    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
      +    Entry->setInitializer(Init);
      +  } else {
      +    Entry = 
      +    new llvm::GlobalVariable(ObjCTypes.ProtocolnfABITy, false,
      +                             llvm::GlobalValue::InternalLinkage,
      +                             Init, 
      +                             std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName,
      +                             &CGM.getModule());
      +    Entry->setSection("__DATA,__datacoal_nt,coalesced");
      +    // FIXME: Is this necessary? Why only for protocol?
      +    Entry->setAlignment(4);
      +  }
      +  return Entry;
      +}
      +
      +/// EmitProtocolList - Generate protocol list meta-data:
      +/// @code
      +/// struct _protocol_list_t {
      +///   long protocol_count;   // Note, this is 32/64 bit
      +///   struct _protocol_t[protocol_count];
      +/// }
      +/// @endcode
      +///
      +llvm::Constant *
      +CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name,
      +                            ObjCProtocolDecl::protocol_iterator begin,
      +                            ObjCProtocolDecl::protocol_iterator end) {
      +  std::vector ProtocolRefs;
      +  
      +  for (; begin != end; ++begin)
      +    ProtocolRefs.push_back(GetProtocolRef(*begin));  // Implemented???
      +  
      +  // Just return null for empty protocol lists
      +  if (ProtocolRefs.empty()) 
      +    return llvm::Constant::getNullValue(ObjCTypes.ProtocolListnfABIPtrTy);
      +  
      +  llvm::GlobalVariable *GV = CGM.getModule().getGlobalVariable(Name, true);
      +  if (GV)
      +    return GV;
      +  // This list is null terminated.
      +  ProtocolRefs.push_back(llvm::Constant::getNullValue(
      +                                            ObjCTypes.ProtocolListnfABIPtrTy));
      +  
      +  std::vector Values(2);
      +  Values[0] = llvm::ConstantInt::get(ObjCTypes.LongTy, ProtocolRefs.size() - 1);
      +  Values[1] = 
      +    llvm::ConstantArray::get(llvm::ArrayType::get(ObjCTypes.ProtocolListnfABIPtrTy, 
      +                                                  ProtocolRefs.size()), 
      +                                                  ProtocolRefs);
      +  
      +  llvm::Constant *Init = llvm::ConstantStruct::get(Values);
      +  GV = new llvm::GlobalVariable(Init->getType(), false,
      +                                llvm::GlobalValue::InternalLinkage,
      +                                Init,
      +                                Name,
      +                                &CGM.getModule());
      +  GV->setSection("__DATA, __objc_const");
      +  UsedGlobals.push_back(GV);
      +  return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
      +}
      +
       /* *** */
       
       CodeGen::CGObjCRuntime *
      -- 
      GitLab
      
      
      From bf7207a11f336ee575ea7661fa973db9ce34cc20 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Thu, 29 Jan 2009 19:42:23 +0000
      Subject: [PATCH 443/682] Make CodeGen produce an error if we come across a
       non-constant initializer list that involves the GNU array-range designator
       extension
      
      llvm-svn: 63327
      ---
       clang/include/clang/AST/Expr.h                    | 9 +++++++++
       clang/include/clang/Basic/DiagnosticSemaKinds.def | 2 --
       clang/lib/AST/Expr.cpp                            | 2 +-
       clang/lib/CodeGen/CGExprAgg.cpp                   | 8 ++++++++
       clang/lib/CodeGen/CGExprScalar.cpp                | 4 ++++
       clang/lib/Sema/SemaInit.cpp                       | 4 +---
       clang/test/Sema/designated-initializers.c         | 9 ++++-----
       7 files changed, 27 insertions(+), 11 deletions(-)
      
      diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
      index c6ac007a1316..94beaf31e2c7 100644
      --- a/clang/include/clang/AST/Expr.h
      +++ b/clang/include/clang/AST/Expr.h
      @@ -1668,6 +1668,10 @@ class InitListExpr : public Expr {
         /// field within the union will be initialized.
         FieldDecl *UnionFieldInit;
       
      +  /// Whether this initializer list originally had a GNU array-range
      +  /// designator in it. This is a temporary marker used by CodeGen.
      +  bool HadArrayRangeDesignator;
      +
       public:
         InitListExpr(SourceLocation lbraceloc, Expr **initexprs, unsigned numinits,
                      SourceLocation rbraceloc);
      @@ -1728,6 +1732,11 @@ public:
         InitListExpr *getSyntacticForm() const { return SyntacticForm; }
         void setSyntacticForm(InitListExpr *Init) { SyntacticForm = Init; }
       
      +  bool hadArrayRangeDesignator() const { return HadArrayRangeDesignator; }
      +  void sawArrayRangeDesignator() { 
      +    HadArrayRangeDesignator = true;
      +  }
      +
         virtual SourceRange getSourceRange() const {
           return SourceRange(LBraceLoc, RBraceLoc);
         } 
      diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      index 63955adc13e6..8cafa318f0e4 100644
      --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def
      +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def
      @@ -60,8 +60,6 @@ DIAG(warn_initializer_overrides, WARNING,
            "initializer overrides prior initialization of this subobject")
       DIAG(note_previous_initializer, NOTE,
            "previous initialization %select{|with side effects }0is here%select{| (side effects may not occur at run time)}0")
      -DIAG(warn_gnu_array_range_designator_side_effects, WARNING,
      -     "side effects due to the GNU array-range designator extension may occur multiple times")
       
       // Declarations.
       DIAG(ext_vla, EXTENSION,
      diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
      index 8a041982936c..35384d880c9f 100644
      --- a/clang/lib/AST/Expr.cpp
      +++ b/clang/lib/AST/Expr.cpp
      @@ -224,7 +224,7 @@ InitListExpr::InitListExpr(SourceLocation lbraceloc,
                                  SourceLocation rbraceloc)
         : Expr(InitListExprClass, QualType()),
           LBraceLoc(lbraceloc), RBraceLoc(rbraceloc), SyntacticForm(0), 
      -    UnionFieldInit(0) {
      +    UnionFieldInit(0), HadArrayRangeDesignator(false) {
       
         InitExprs.insert(InitExprs.end(), initExprs, initExprs+numInits);
       }
      diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
      index f985763b5c39..bf80b94d21e6 100644
      --- a/clang/lib/CodeGen/CGExprAgg.cpp
      +++ b/clang/lib/CodeGen/CGExprAgg.cpp
      @@ -307,6 +307,10 @@ void AggExprEmitter::EmitNonConstInit(InitListExpr *E) {
           cast(DestPtr->getType());
         const llvm::Type *DestType = APType->getElementType();
       
      +  if (E->hadArrayRangeDesignator()) {
      +    CGF.ErrorUnsupported(E, "GNU array range designator extension");
      +  }
      +
         if (const llvm::ArrayType *AType = dyn_cast(DestType)) {
           unsigned NumInitElements = E->getNumInits();
       
      @@ -397,6 +401,10 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
           return;
         }
       #endif
      +  if (E->hadArrayRangeDesignator()) {
      +    CGF.ErrorUnsupported(E, "GNU array range designator extension");
      +  }
      +
         // Handle initialization of an array.
         if (E->getType()->isArrayType()) {
           const llvm::PointerType *APType =
      diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
      index f855e23ba03f..1d389b6049c2 100644
      --- a/clang/lib/CodeGen/CGExprScalar.cpp
      +++ b/clang/lib/CodeGen/CGExprScalar.cpp
      @@ -169,6 +169,10 @@ public:
         Value *VisitInitListExpr(InitListExpr *E) {
           unsigned NumInitElements = E->getNumInits();
           
      +    if (E->hadArrayRangeDesignator()) {
      +      CGF.ErrorUnsupported(E, "GNU array range designator extension");
      +    }
      +
           const llvm::VectorType *VType = 
             dyn_cast(ConvertType(E->getType()));
           
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 5d7f705edb12..77679ee36f98 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -867,9 +867,7 @@ InitListChecker::CheckDesignatedInitializer(InitListExpr *IList,
           IndexExpr = DIE->getArrayRangeEnd(*D);
       
           if (DesignatedStartIndex.getZExtValue() != DesignatedEndIndex.getZExtValue())
      -      SemaRef->Diag(D->getEllipsisLoc(), 
      -                    diag::warn_gnu_array_range_designator_side_effects)
      -        << SourceRange(D->getLBracketLoc(), D->getRBracketLoc());
      +      FullyStructuredList->sawArrayRangeDesignator();
         }
       
         if (isa(AT)) {
      diff --git a/clang/test/Sema/designated-initializers.c b/clang/test/Sema/designated-initializers.c
      index efd0d406511b..53da306c4c32 100644
      --- a/clang/test/Sema/designated-initializers.c
      +++ b/clang/test/Sema/designated-initializers.c
      @@ -18,8 +18,7 @@ int iarray2[10] = {
       };
       
       int iarray3[10] = {
      -  [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}\
      -                // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
      +  [5 ... 12] = 2 // expected-error{{array designator index (12) exceeds array bounds (10)}}
       };
       
       struct point {
      @@ -45,8 +44,8 @@ struct point array[10] = {
       
       struct point array2[10] = {
         [10].x = 2.0, // expected-error{{array designator index (10) exceeds array bounds (10)}}
      -  [4 ... 5].y = 2.0, // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
      -  [4 ... 6] = { .x = 3, .y = 4.0 } // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
      +  [4 ... 5].y = 2.0,
      +  [4 ... 6] = { .x = 3, .y = 4.0 }
       };
       
       struct point array3[10] = {
      @@ -117,7 +116,7 @@ struct disklabel_ops disklabel64_ops = {
       // PR clang/3378
       int bitwidth[] = { [(long long int)1] = 5, [(short int)2] = 2 };
       int a[]= { [sizeof(int)] = 0 };
      -int a2[]= { [0 ... sizeof(int)] = 0 }; // expected-warning{{side effects due to the GNU array-range designator extension may occur multiple times}}
      +int a2[]= { [0 ... sizeof(int)] = 0 };
       
       // Test warnings about initializers overriding previous initializers
       struct X {
      -- 
      GitLab
      
      
      From 60d6844aa83e92e8aecc20dbb18ca76bdac4d71a Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Thu, 29 Jan 2009 19:49:27 +0000
      Subject: [PATCH 444/682] Make a few things const, fix some comments, and
       simplify some assertions.
      
      llvm-svn: 63328
      ---
       .../SelectionDAG/ScheduleDAGRRList.cpp        | 24 +++++++------------
       1 file changed, 8 insertions(+), 16 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
      index bd786daedb7e..5eaf596c3d89 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGRRList.cpp
      @@ -91,7 +91,7 @@ public:
           return Topo.IsReachable(SU, TargetSU);
         }
       
      -  /// willCreateCycle - Returns true if adding an edge from SU to TargetSU will
      +  /// WillCreateCycle - Returns true if adding an edge from SU to TargetSU will
         /// create a cycle.
         bool WillCreateCycle(SUnit *SU, SUnit *TargetSU) {
           return Topo.WillCreateCycle(SU, TargetSU);
      @@ -114,8 +114,8 @@ public:
         }
       
       private:
      -  void ReleasePred(SUnit *SU, SDep *PredEdge);
      -  void ReleaseSucc(SUnit *SU, SDep *SuccEdge);
      +  void ReleasePred(SUnit *SU, const SDep *PredEdge);
      +  void ReleaseSucc(SUnit *SU, const SDep *SuccEdge);
         void CapturePred(SDep *PredEdge);
         void ScheduleNodeBottomUp(SUnit*, unsigned);
         void ScheduleNodeTopDown(SUnit*, unsigned);
      @@ -192,7 +192,7 @@ void ScheduleDAGRRList::Schedule() {
       
       /// ReleasePred - Decrement the NumSuccsLeft count of a predecessor. Add it to
       /// the AvailableQueue if the count reaches zero. Also update its cycle bound.
      -void ScheduleDAGRRList::ReleasePred(SUnit *SU, SDep *PredEdge) {
      +void ScheduleDAGRRList::ReleasePred(SUnit *SU, const SDep *PredEdge) {
         SUnit *PredSU = PredEdge->getSUnit();
         --PredSU->NumSuccsLeft;
         
      @@ -312,8 +312,7 @@ void ScheduleDAGRRList::UnscheduleNodeBottomUp(SUnit *SU) {
       }
       
       /// BacktrackBottomUp - Backtrack scheduling to a previous cycle specified in
      -/// BTCycle in order to schedule a specific node. Returns the last unscheduled
      -/// SUnit. Also returns if a successor is unscheduled in the process.
      +/// BTCycle in order to schedule a specific node.
       void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
                                                 unsigned &CurCycle) {
         SUnit *OldSU = NULL;
      @@ -327,11 +326,7 @@ void ScheduleDAGRRList::BacktrackBottomUp(SUnit *SU, unsigned BtCycle,
           --CurCycle;
         }
       
      -      
      -  if (SU->isSucc(OldSU)) {
      -    assert(false && "Something is wrong!");
      -    abort();
      -  }
      +  assert(!SU->isSucc(OldSU) && "Something is wrong!");
       
         ++NumBacktracks;
       }
      @@ -751,10 +746,7 @@ void ScheduleDAGRRList::ListScheduleBottomUp() {
               CurSU = NewDef;
             }
       
      -      if (!CurSU) {
      -        assert(false && "Unable to resolve live physical register dependencies!");
      -        abort();
      -      }
      +      assert(CurSU && "Unable to resolve live physical register dependencies!");
           }
       
           // Add the nodes that aren't ready back onto the available list.
      @@ -785,7 +777,7 @@ void ScheduleDAGRRList::ListScheduleBottomUp() {
       
       /// ReleaseSucc - Decrement the NumPredsLeft count of a successor. Add it to
       /// the AvailableQueue if the count reaches zero. Also update its cycle bound.
      -void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, SDep *SuccEdge) {
      +void ScheduleDAGRRList::ReleaseSucc(SUnit *SU, const SDep *SuccEdge) {
         SUnit *SuccSU = SuccEdge->getSUnit();
         --SuccSU->NumPredsLeft;
         
      -- 
      GitLab
      
      
      From 61cd4b56c3da8d1c2d87aef676818e382bb4403b Mon Sep 17 00:00:00 2001
      From: Fariborz Jahanian 
      Date: Thu, 29 Jan 2009 20:10:59 +0000
      Subject: [PATCH 445/682] Set protocol linkage and visibility correctly and
       build protocol translation table meta-data (objc2 non-fragile abi).
      
      llvm-svn: 63329
      ---
       clang/lib/CodeGen/CGObjCMac.cpp | 19 +++++++++++++++++--
       1 file changed, 17 insertions(+), 2 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
      index 67db5fa7e6ca..09987a291e8b 100644
      --- a/clang/lib/CodeGen/CGObjCMac.cpp
      +++ b/clang/lib/CodeGen/CGObjCMac.cpp
      @@ -3843,12 +3843,12 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
         
         if (Entry) {
           // Already created, fix the linkage and update the initializer.
      -    Entry->setLinkage(llvm::GlobalValue::InternalLinkage);
      +    Entry->setLinkage(llvm::GlobalValue::WeakLinkage);
           Entry->setInitializer(Init);
         } else {
           Entry = 
           new llvm::GlobalVariable(ObjCTypes.ProtocolnfABITy, false,
      -                             llvm::GlobalValue::InternalLinkage,
      +                             llvm::GlobalValue::WeakLinkage,
                                    Init, 
                                    std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName,
                                    &CGM.getModule());
      @@ -3856,6 +3856,21 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
           // FIXME: Is this necessary? Why only for protocol?
           Entry->setAlignment(4);
         }
      +  Entry->setVisibility(llvm::GlobalValue::HiddenVisibility);
      +  
      +  // Use this protocol meta-data to build protocol list table in section
      +  // __DATA, __objc_protolist
      +  llvm::Type *ptype = llvm::PointerType::getUnqual(ObjCTypes.ProtocolnfABITy);
      +  llvm::GlobalVariable *PTGV = new llvm::GlobalVariable(
      +                                      ptype, false,
      +                                      llvm::GlobalValue::WeakLinkage,
      +                                      Entry, 
      +                                      std::string("\01l_OBJC_LABEL_PROTOCOL_$_")
      +                                                  +ProtocolName,
      +                                      &CGM.getModule());
      +  PTGV->setSection("__DATA, __objc_protolist");
      +  PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility);
      +  UsedGlobals.push_back(PTGV);
         return Entry;
       }
       
      -- 
      GitLab
      
      
      From 506374cc59baebafc79c4d468366264be07049a5 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 20:36:50 +0000
      Subject: [PATCH 446/682] ABITest: Makefile tweaks
      
      llvm-svn: 63330
      ---
       clang/utils/ABITest/layout/Makefile       |  2 +-
       clang/utils/ABITest/return-types/Makefile | 74 ++++++++++++++++-------
       2 files changed, 52 insertions(+), 24 deletions(-)
      
      diff --git a/clang/utils/ABITest/layout/Makefile b/clang/utils/ABITest/layout/Makefile
      index f93a74e5920b..fa76f18c243d 100644
      --- a/clang/utils/ABITest/layout/Makefile
      +++ b/clang/utils/ABITest/layout/Makefile
      @@ -5,7 +5,7 @@
       # to 'make clean' after changing either of these parameters.
       
       ABITESTGEN := ../ABITestGen.py
      -TESTARGS := --max-args 0 --no-complex --no-vector --no-union --test-layout
      +TESTARGS := --max-args 0 --test-layout
       COUNT := 1000
       TIMEOUT := 5
       
      diff --git a/clang/utils/ABITest/return-types/Makefile b/clang/utils/ABITest/return-types/Makefile
      index c2c8bc11085e..1fbc092fcd1e 100644
      --- a/clang/utils/ABITest/return-types/Makefile
      +++ b/clang/utils/ABITest/return-types/Makefile
      @@ -5,8 +5,9 @@
       # to 'make clean' after changing either of these parameters.
       
       ABITESTGEN := ../ABITestGen.py
      -TESTARGS := --max-args 0 --no-vector --no-complex --no-union
      -COUNT := 100
      +TESTARGS := --max-args 0
      +COUNT := 1
      +TIMEOUT := 5
       
       CFLAGS := -std=gnu99
       
      @@ -16,15 +17,42 @@ Y_COMPILER := xcc -ccc-clang
       Y_LL_CFLAGS := -emit-llvm -S
       CC := gcc
       
      +ifeq (0, 1)
       X_CFLAGS := -m32
      -Y_CFLAGS := -arch i386
      +Y_CFLAGS := -m32
       CC_CFLAGS := -m32
      +else
      +X_CFLAGS := -m64
      +Y_CFLAGS := -m64
      +CC_CFLAGS := -m64
      +endif
      +
      +ifndef VERBOSE
      +  Verb := @
      +endif
       
       .PHONY: test.%.report
       test.%.report: test.%.xx.diff test.%.xy.diff test.%.yx.diff test.%.yy.diff
      +	@ok=1;\
      +	for t in $^; do \
      +		if [ -s $$t ]; then \
      +			echo "TEST $*: $$t failed"; \
      +			ok=0;\
      +		fi; \
      +	done; \
      +	if [ $$ok == 1 ]; then \
      +		echo "TEST $*: OK"; \
      +	else \
      +		false; \
      +	fi
      +
      +
      +.PHONY: test.%.defs-report
      +test.%.defs-report: test.%.defs.diff
       	@for t in $^; do \
       		if [ -s $$t ]; then \
       			echo "TEST $*: $$t failed"; \
      +			cat $$t; \
       		fi; \
       	done
       
      @@ -36,72 +64,72 @@ test.%.build: test.%.ref test.%.xx test.%.xy test.%.yx test.%.yy test.%.x.defs t
       
       .PRECIOUS: test.%.xx.diff
       test.%.xx.diff: test.%.ref.out test.%.xx.out
      -	-diff $^ > $@
      +	$(Verb) diff $^ > $@ || true
       .PRECIOUS: test.%.xy.diff
       test.%.xy.diff: test.%.ref.out test.%.xy.out
      -	-diff $^ > $@
      +	$(Verb) diff $^ > $@ || true
       .PRECIOUS: test.%.yx.diff
       test.%.yx.diff: test.%.ref.out test.%.yx.out
      -	-diff $^ > $@
      +	$(Verb) diff $^ > $@ || true
       .PRECIOUS: test.%.yy.diff
       test.%.yy.diff: test.%.ref.out test.%.yy.out
      -	-diff $^ > $@
      +	$(Verb) diff $^ > $@ || true
       .PRECIOUS: test.%.defs.diff
       test.%.defs.diff: test.%.x.defs test.%.y.defs
      -	zipdifflines \
      +	$(Verb) zipdifflines \
       	  --replace "%struct.T[0-9]+" "%struct.s" \
       	  --replace "byval align [0-9]+" "byval" \
       	  $^ > $@
       
       .PRECIOUS: test.%.out
       test.%.out: test.%
      -	-./$< > $@
      +	$(Verb) -RunSafely.sh $(TIMEOUT) 1 /dev/null $@ ./$<
       
       .PRECIOUS: test.%.ref
       test.%.ref: test.%.driver.ref.o test.%.a.ref.o test.%.b.ref.o
      -	$(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
      +	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
       .PRECIOUS: test.%.xx
       test.%.xx: test.%.driver.ref.o test.%.a.x.o test.%.b.x.o
      -	$(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
      +	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
       .PRECIOUS: test.%.xy
       test.%.xy: test.%.driver.ref.o test.%.a.x.o test.%.b.y.o
      -	$(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
      +	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
       .PRECIOUS: test.%.yx
       test.%.yx: test.%.driver.ref.o test.%.a.y.o test.%.b.x.o
      -	$(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
      +	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
       .PRECIOUS: test.%.yy
       test.%.yy: test.%.driver.ref.o test.%.a.y.o test.%.b.y.o
      -	$(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
      +	$(Verb) $(CC) $(CFLAGS) $(CC_CFLAGS) -o $@ $^
       
       .PRECIOUS: test.%.ref.o
       test.%.ref.o: test.%.c
      -	$(CC) -c $(CFLAGS) $(CC_CFLAGS) -o $@ $<
      +	$(Verb) $(CC) -c $(CFLAGS) $(CC_CFLAGS) -o $@ $<
       .PRECIOUS: test.%.x.o
       test.%.x.o: test.%.c
      -	$(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $<
      +	$(Verb) $(X_COMPILER) -c $(CFLAGS) $(X_CFLAGS) -o $@ $<
       .PRECIOUS: test.%.y.o
       test.%.y.o: test.%.c
      -	$(Y_COMPILER) -c $(CFLAGS) $(Y_CFLAGS) -o $@ $<
      +	$(Verb) $(Y_COMPILER) -c $(CFLAGS) $(Y_CFLAGS) -o $@ $<
       
       .PRECIOUS: test.%.x.defs
       test.%.x.defs: test.%.a.x.ll
      -	-grep '^define ' $< > $@
      +	-$(Verb) -grep '^define ' $< > $@
       .PRECIOUS: test.%.y.defs
       test.%.y.defs: test.%.a.y.ll
      -	-grep '^define ' $< > $@
      +	-$(Verb) -grep '^define ' $< > $@
       
       .PRECIOUS: test.%.a.x.ll
       test.%.a.x.ll: test.%.a.c
      -	$(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $<
      +	$(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $<
       .PRECIOUS: test.%.b.x.ll
       test.%.b.x.ll: test.%.b.c
      -	$(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $<
      +	$(Verb) $(X_COMPILER) $(CFLAGS) $(X_LL_CFLAGS) $(X_CFLAGS) -o $@ $<
       .PRECIOUS: test.%.a.y.ll
       test.%.a.y.ll: test.%.a.c
      -	$(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $<
      +	$(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $<
       .PRECIOUS: test.%.b.y.ll
       test.%.b.y.ll: test.%.b.c
      -	$(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $<
      +	$(Verb) $(Y_COMPILER) $(CFLAGS) $(Y_LL_CFLAGS) $(Y_CFLAGS) -o $@ $<
       
       .PHONY: test.%.top
       test.%.top: test.%.a.c test.%.b.c test.%.driver.c
      -- 
      GitLab
      
      
      From 14d55f0a5c6cad9a2fe0ad2ca7532f380c524630 Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Thu, 29 Jan 2009 21:02:43 +0000
      Subject: [PATCH 447/682] Explicitly add PseudoSourceValue information when
       lowering BUILD_VECTOR and conversions to stack operations.
      
      llvm-svn: 63333
      ---
       llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 21 ++++++++++---------
       1 file changed, 11 insertions(+), 10 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
      index 5b8d18ce2141..eba252f18496 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp
      @@ -5375,7 +5375,8 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
         
         FrameIndexSDNode *StackPtrFI = cast(FIPtr);
         int SPFI = StackPtrFI->getIndex();
      -  
      +  const Value *SV = PseudoSourceValue::getFixedStack(SPFI);
      +
         unsigned SrcSize = SrcOp.getValueType().getSizeInBits();
         unsigned SlotSize = SlotVT.getSizeInBits();
         unsigned DestSize = DestVT.getSizeInBits();
      @@ -5388,21 +5389,19 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp,
         
         if (SrcSize > SlotSize)
           Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr,
      -                              PseudoSourceValue::getFixedStack(SPFI), 0,
      -                              SlotVT, false, SrcAlign);
      +                              SV, 0, SlotVT, false, SrcAlign);
         else {
           assert(SrcSize == SlotSize && "Invalid store");
           Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr,
      -                         PseudoSourceValue::getFixedStack(SPFI), 0,
      -                         false, SrcAlign);
      +                         SV, 0, false, SrcAlign);
         }
         
         // Result is a load from the stack slot.
         if (SlotSize == DestSize)
      -    return DAG.getLoad(DestVT, Store, FIPtr, NULL, 0, false, DestAlign);
      +    return DAG.getLoad(DestVT, Store, FIPtr, SV, 0, false, DestAlign);
         
         assert(SlotSize < DestSize && "Unknown extension!");
      -  return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, NULL, 0, SlotVT,
      +  return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, SV, 0, SlotVT,
                               false, DestAlign);
       }
       
      @@ -5568,7 +5567,9 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
         MVT VT = Node->getValueType(0);
         // Create the stack frame object.
         SDValue FIPtr = DAG.CreateStackTemporary(VT);
      -  
      +  int FI = cast(FIPtr.getNode())->getIndex();
      +  const Value *SV = PseudoSourceValue::getFixedStack(FI);
      +
         // Emit a store of each element to the stack slot.
         SmallVector Stores;
         unsigned TypeByteSize = Node->getOperand(0).getValueType().getSizeInBits()/8;
      @@ -5583,7 +5584,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
           Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx);
           
           Stores.push_back(DAG.getStore(DAG.getEntryNode(), Node->getOperand(i), Idx, 
      -                                  NULL, 0));
      +                                  SV, Offset));
         }
         
         SDValue StoreChain;
      @@ -5594,7 +5595,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) {
           StoreChain = DAG.getEntryNode();
         
         // Result is a load from the stack slot.
      -  return DAG.getLoad(VT, StoreChain, FIPtr, NULL, 0);
      +  return DAG.getLoad(VT, StoreChain, FIPtr, SV, 0);
       }
       
       void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp,
      -- 
      GitLab
      
      
      From bf77d2eb9d3e703211d19fa58650cde274e899df Mon Sep 17 00:00:00 2001
      From: Owen Anderson 
      Date: Thu, 29 Jan 2009 22:13:06 +0000
      Subject: [PATCH 448/682] Correct the algorithms for choosing spill and restore
       points so that we don't try to insert loads/stores between call frame setup
       and the actual call.
      
      This fixes the last known failure for the pre-alloc-splitter.
      
      llvm-svn: 63339
      ---
       llvm/lib/CodeGen/PreAllocSplitting.cpp | 25 +++++++++++++++++++++++--
       1 file changed, 23 insertions(+), 2 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      index 4dc8b82972a0..1180dee7b793 100644
      --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp
      +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp
      @@ -50,6 +50,7 @@ namespace {
           MachineFunction       *CurrMF;
           const TargetMachine   *TM;
           const TargetInstrInfo *TII;
      +    const TargetRegisterInfo* TRI;
           MachineFrameInfo      *MFI;
           MachineRegisterInfo   *MRI;
           LiveIntervals         *LIs;
      @@ -223,12 +224,21 @@ PreAllocSplitting::findSpillPoint(MachineBasicBlock *MBB, MachineInstr *MI,
               Pt = MII;
               SpillIndex = Gap;
               break;
      -      }
      +      
      +      // We can't insert the spill between the barrier (a call), and its
      +      // corresponding call frame setup.
      +      } else if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode() &&
      +                 MII == MachineBasicBlock::iterator(MI))
      +        break;
           } while (MII != EndPt);
         } else {
           MachineBasicBlock::iterator MII = MI;
           MachineBasicBlock::iterator EndPt = DefMI
             ? MachineBasicBlock::iterator(DefMI) : MBB->begin();
      +    
      +    // We can't insert the spill between the barrier (a call), and its
      +    // corresponding call frame setup.
      +    if (prior(MII)->getOpcode() == TRI->getCallFrameSetupOpcode()) --MII;
           while (MII != EndPt && !RefsInMBB.count(MII)) {
             unsigned Index = LIs->getInstructionIndex(MII);
             if (LIs->hasGapBeforeInstr(Index)) {
      @@ -269,12 +279,22 @@ PreAllocSplitting::findRestorePoint(MachineBasicBlock *MBB, MachineInstr *MI,
               Pt = MII;
               RestoreIndex = Gap;
               break;
      -      }
      +      
      +      // We can't insert a restore between the barrier (a call) and its 
      +      // corresponding call frame teardown.
      +      } else if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode() &&
      +                 prior(MII) == MachineBasicBlock::iterator(MI))
      +        break;
             --MII;
           } while (MII != EndPt);
         } else {
           MachineBasicBlock::iterator MII = MI;
           MII = ++MII;
      +    // We can't insert a restore between the barrier (a call) and its 
      +    // corresponding call frame teardown.
      +    if (MII->getOpcode() == TRI->getCallFrameDestroyOpcode())
      +      ++MII;
      +    
           // FIXME: Limit the number of instructions to examine to reduce
           // compile time?
           while (MII != MBB->getFirstTerminator()) {
      @@ -1291,6 +1311,7 @@ bool PreAllocSplitting::createsNewJoin(LiveRange* LR,
       bool PreAllocSplitting::runOnMachineFunction(MachineFunction &MF) {
         CurrMF = &MF;
         TM     = &MF.getTarget();
      +  TRI    = TM->getRegisterInfo();
         TII    = TM->getInstrInfo();
         MFI    = MF.getFrameInfo();
         MRI    = &MF.getRegInfo();
      -- 
      GitLab
      
      
      From ad89c410e6d2a725712f55f7d28a7a6c42ba64c6 Mon Sep 17 00:00:00 2001
      From: Owen Anderson 
      Date: Thu, 29 Jan 2009 22:27:56 +0000
      Subject: [PATCH 449/682] XFAIL this test.  It only worked before because of a
       bug in the spill point selection code.  Not deleting because it should be
       possible to enhance the selection code to handle this in the future.
      
      llvm-svn: 63340
      ---
       llvm/test/CodeGen/X86/pre-split1.ll | 1 +
       1 file changed, 1 insertion(+)
      
      diff --git a/llvm/test/CodeGen/X86/pre-split1.ll b/llvm/test/CodeGen/X86/pre-split1.ll
      index f99ac8981dd7..99a46b6e5fd2 100644
      --- a/llvm/test/CodeGen/X86/pre-split1.ll
      +++ b/llvm/test/CodeGen/X86/pre-split1.ll
      @@ -1,5 +1,6 @@
       ; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse2 -pre-alloc-split -stats |& \
       ; RUN:   grep {pre-alloc-split} | grep {Number of intervals split} | grep 1
      +; XFAIL: *
       
       define void @test(double* %P, i32 %cond) nounwind {
       entry:
      -- 
      GitLab
      
      
      From ed90de4caaeb1454740bdd53d14c7d11a8d4ed4d Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Thu, 29 Jan 2009 22:45:13 +0000
      Subject: [PATCH 450/682] retain/release checker: When generating summaries for
       CF/CG functions, allow arguments to "escape" if they are passed to a function
       containing the terms "InsertValue", "SetValue", or "AddValue".  This fixes
       .
      
      llvm-svn: 63341
      ---
       clang/lib/Analysis/CFRefCount.cpp  | 27 ++++++++++++++++++++------
       clang/test/Analysis/rdar-6539791.c | 31 ++++++++++++++++++++++++++++++
       2 files changed, 52 insertions(+), 6 deletions(-)
       create mode 100644 clang/test/Analysis/rdar-6539791.c
      
      diff --git a/clang/lib/Analysis/CFRefCount.cpp b/clang/lib/Analysis/CFRefCount.cpp
      index 35b7ee7b805a..ab9d409dd21d 100644
      --- a/clang/lib/Analysis/CFRefCount.cpp
      +++ b/clang/lib/Analysis/CFRefCount.cpp
      @@ -809,12 +809,27 @@ RetainSummary* RetainSummaryManager::getSummary(FunctionDecl* FD) {
             if (isRelease(FD, FName+2))
               S = getUnarySummary(FT, cfrelease);
             else {
      -        // For CoreFoundation and CoreGraphics functions we assume they
      -        // follow the ownership idiom strictly and thus do not cause
      -        // ownership to "escape".
      -        assert (ScratchArgs.empty());  
      -        S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, 
      -                                 DoNothing);
      +        assert (ScratchArgs.empty());
      +        // Remaining CoreFoundation and CoreGraphics functions.
      +        // We use to assume that they all strictly followed the ownership idiom
      +        // and that ownership cannot be transferred.  While this is technically
      +        // correct, many methods allow a tracked object to escape.  For example:
      +        //
      +        //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);        
      +        //   CFDictionaryAddValue(y, key, x);
      +        //   CFRelease(x); 
      +        //   ... it is okay to use 'x' since 'y' has a reference to it
      +        //
      +        // We handle this and similar cases with the follow heuristic.  If the
      +        // function name contains "InsertValue", "SetValue" or "AddValue" then
      +        // we assume that arguments may "escape."
      +        //
      +        ArgEffect E = (CStrInCStrNoCase(FName, "InsertValue") ||
      +                       CStrInCStrNoCase(FName, "AddValue") ||
      +                       CStrInCStrNoCase(FName, "SetValue"))
      +                      ? MayEscape : DoNothing;
      +        
      +        S = getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);
             }
           }
         }
      diff --git a/clang/test/Analysis/rdar-6539791.c b/clang/test/Analysis/rdar-6539791.c
      new file mode 100644
      index 000000000000..0d0b675d945b
      --- /dev/null
      +++ b/clang/test/Analysis/rdar-6539791.c
      @@ -0,0 +1,31 @@
      +// RUN: clang -analyze -checker-cfref -analyzer-store-basic -verify %s &&
      +// RUN: clang -analyze -checker-cfref -analyzer-store-region -verify %s
      +
      +typedef const struct __CFAllocator * CFAllocatorRef;
      +typedef struct __CFDictionary * CFMutableDictionaryRef;
      +typedef signed long CFIndex;
      +typedef CFIndex CFNumberType;
      +typedef const void * CFTypeRef;
      +typedef struct {} CFDictionaryKeyCallBacks, CFDictionaryValueCallBacks;
      +typedef const struct __CFNumber * CFNumberRef;
      +extern const CFAllocatorRef kCFAllocatorDefault;
      +extern const CFDictionaryKeyCallBacks kCFTypeDictionaryKeyCallBacks;
      +extern const CFDictionaryValueCallBacks kCFTypeDictionaryValueCallBacks;
      +enum { kCFNumberSInt32Type = 3 };
      +CFMutableDictionaryRef CFDictionaryCreateMutable(CFAllocatorRef allocator, CFIndex capacity, const CFDictionaryKeyCallBacks *keyCallBacks, const CFDictionaryValueCallBacks *valueCallBacks);
      +void CFDictionaryAddValue(CFMutableDictionaryRef theDict, const void *key, const void *value);
      +void CFRelease(CFTypeRef cf);
      +extern CFNumberRef CFNumberCreate(CFAllocatorRef allocator, CFNumberType theType, const void *valuePtr);
      +
      +void f(CFMutableDictionaryRef y, void* key, void* val_key) {
      +  CFMutableDictionaryRef x = CFDictionaryCreateMutable(kCFAllocatorDefault, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
      +  CFDictionaryAddValue(y, key, x);
      +  CFRelease(x); // the dictionary keeps a reference, so the object isn't deallocated yet
      +  signed z = 1;
      +  CFNumberRef value = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &z);
      +  if (value) {
      +    CFDictionaryAddValue(x, val_key, value); // no-warning
      +    CFRelease(value);
      +    CFDictionaryAddValue(y, val_key, value); // no-warning
      +  }
      +}
      -- 
      GitLab
      
      
      From 33dddf3235b255a72723e57ec40a6d5c70730976 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Thu, 29 Jan 2009 23:19:43 +0000
      Subject: [PATCH 451/682] Explain why this is here.
      
      llvm-svn: 63342
      ---
       llvm/utils/TableGen/DAGISelEmitter.cpp | 1 +
       1 file changed, 1 insertion(+)
      
      diff --git a/llvm/utils/TableGen/DAGISelEmitter.cpp b/llvm/utils/TableGen/DAGISelEmitter.cpp
      index ace15e5180de..773b06aa3946 100644
      --- a/llvm/utils/TableGen/DAGISelEmitter.cpp
      +++ b/llvm/utils/TableGen/DAGISelEmitter.cpp
      @@ -1060,6 +1060,7 @@ public:
             std::string Code = "Opc" + utostr(OpcNo);
       
             if (!isRoot || (InputHasChain && !NodeHasChain))
      +        // For call to "getTargetNode()".
               Code += ", N.getDebugLoc()";
       
             emitOpcode(II.Namespace + "::" + II.TheDef->getName());
      -- 
      GitLab
      
      
      From 34fe8806483b3e7ad62f56d1cbe22f697ded0b86 Mon Sep 17 00:00:00 2001
      From: Fariborz Jahanian 
      Date: Thu, 29 Jan 2009 23:23:06 +0000
      Subject: [PATCH 452/682] Random bug fix related to protocl metadata in
       categories in non-fragile abi.
      
      llvm-svn: 63343
      ---
       clang/lib/CodeGen/CGObjCMac.cpp | 11 ++++++-----
       1 file changed, 6 insertions(+), 5 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
      index 09987a291e8b..3f3ea9e2201d 100644
      --- a/clang/lib/CodeGen/CGObjCMac.cpp
      +++ b/clang/lib/CodeGen/CGObjCMac.cpp
      @@ -3519,13 +3519,14 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD)
         Values[3] = EmitMethodList(MethodListName, 
                                    "__DATA, __objc_const", 
                                    Methods);
      -  Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_" 
      -                               + Interface->getNameAsString(),
      -                                Interface->protocol_begin(),
      -                                Interface->protocol_end());
      -  
         const ObjCCategoryDecl *Category = 
           Interface->FindCategoryDeclaration(OCD->getIdentifier());
      +  Values[4] = EmitProtocolList("\01l_OBJC_CATEGORY_PROTOCOLS_$_"
      +                               + Interface->getNameAsString() + "_$_"
      +                               + Category->getNameAsString(),
      +                                Category->protocol_begin(),
      +                                Category->protocol_end());
      +  
         std::string ExtName(Interface->getNameAsString() + "_$_" +
                             OCD->getNameAsString());
         Values[5] =
      -- 
      GitLab
      
      
      From 38b9c05f1c39aac215e9a41afd1e8f645f2474d3 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 23:50:47 +0000
      Subject: [PATCH 453/682] Fix name of -x option for C preprocessed input; it
       should be cpp-output, not c-cpp-output.
      
      llvm-svn: 63345
      ---
       clang/Driver/clang.cpp | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
      index d29579f60000..4e79733043f0 100644
      --- a/clang/Driver/clang.cpp
      +++ b/clang/Driver/clang.cpp
      @@ -281,7 +281,7 @@ BaseLang("x", llvm::cl::desc("Base language to compile"),
                           clEnumValN(langkind_cxx,   "c++",          "C++"),
                           clEnumValN(langkind_objc,  "objective-c",  "Objective C"),
                           clEnumValN(langkind_objcxx,"objective-c++","Objective C++"),
      -                    clEnumValN(langkind_c_cpp,     "c-cpp-output",
      +                    clEnumValN(langkind_c_cpp,     "cpp-output",
                                      "Preprocessed C"),
                           clEnumValN(langkind_asm_cpp,     "assembler-with-cpp",
                                      "Preprocessed asm"),
      -- 
      GitLab
      
      
      From 711e882c1bc0a59893e491f114e8917607242ea5 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Thu, 29 Jan 2009 23:54:06 +0000
      Subject: [PATCH 454/682] ccc: Embrace destiny as a clang compiler driver.
      
      This redoes the default mode that ccc runs in w.r.t. using clang. Now
      ccc defaults to always using clang for any task clang can
      handle. However, the following options exist to tweak this behavior:
      
       -ccc-no-clang: Don't use clang at all for compilation (still used for
        static analysis).
      
       -ccc-no-clang-cxx: Don't use clang for C++ and Objective-C++ inputs.
      
       -ccc-no-clang-cpp: Don't use clang as a preprocessor.
      
       -ccc-clang-archs : If present, only use clang for the given
        comma separated list of architectures. This only works on Darwin for
        now.
      
      Note that all -ccc options must be first on the command line.
      
      llvm-svn: 63346
      ---
       clang/tools/ccc/ccclib/Driver.py           | 25 +++++----
       clang/tools/ccc/ccclib/ToolChain.py        | 61 ++++++++++++++--------
       clang/tools/ccc/ccclib/Tools.py            |  3 ++
       clang/tools/ccc/ccclib/Types.py            | 16 ++++++
       clang/tools/ccc/test/ccc/Xarch.c           |  2 +-
       clang/tools/ccc/test/ccc/aliases.c         |  8 +--
       clang/tools/ccc/test/ccc/darwin-hello.m    |  8 +--
       clang/tools/ccc/test/ccc/darwin-x86-cc1.m  |  8 +--
       clang/tools/ccc/test/ccc/hello.c           |  6 +--
       clang/tools/ccc/test/ccc/hello.m           |  4 +-
       clang/tools/ccc/test/ccc/universal-hello.c |  4 +-
       11 files changed, 93 insertions(+), 52 deletions(-)
      
      diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py
      index 6749dae13293..bdcdcb731cfe 100644
      --- a/clang/tools/ccc/ccclib/Driver.py
      +++ b/clang/tools/ccc/ccclib/Driver.py
      @@ -28,9 +28,10 @@ class Driver(object):
               self.cccHostBits = self.cccHostMachine = None
               self.cccHostSystem = self.cccHostRelease = None
               self.cccCXX = False
      -        self.cccClang = False
               self.cccEcho = False
               self.cccFallback = False
      +        self.cccNoClang = self.cccNoClangCXX = self.cccNoClangPreprocessor = False
      +        self.cccClangArchs = None
       
               # Certain options suppress the 'no input files' warning.
               self.suppressMissingInputWarning = False
      @@ -115,12 +116,10 @@ class Driver(object):
       
               # FIXME: How to handle override of host? ccc specific options?
               # Abuse -b?
      -        if self.getenvBool('CCC_CLANG'):
      -            self.cccClang = True
      -        if self.getenvBool('CCC_ECHO'):
      -            self.cccEcho = True
      -        if self.getenvBool('CCC_FALLBACK'):
      -            self.cccFallback = True
      +        arg = os.getenv('CCC_ADD_ARGS')
      +        if arg:
      +            args = filter(None, map(str.strip, arg.split(',')))
      +            argv = args + argv
       
               while argv and argv[0].startswith('-ccc-'):
                   fullOpt,argv = argv[0],argv[1:]
      @@ -132,12 +131,20 @@ class Driver(object):
                       cccPrintPhases = True
                   elif opt == 'cxx':
                       self.cccCXX = True
      -            elif opt == 'clang':
      -                self.cccClang = True
                   elif opt == 'echo':
                       self.cccEcho = True
                   elif opt == 'fallback':
                       self.cccFallback = True
      +
      +            elif opt == 'no-clang':
      +                self.cccNoClang = True
      +            elif opt == 'no-clang-cxx':
      +                self.cccNoClangCXX = True
      +            elif opt == 'no-clang-cpp':
      +                self.cccNoClangPreprocessor = True
      +            elif opt == 'clang-archs':
      +                self.cccClangArchs,argv = argv[0].split(','),argv[1:]
      +
                   elif opt == 'host-bits':
                       self.cccHostBits,argv = argv[0],argv[1:]
                   elif opt == 'host-machine':
      diff --git a/clang/tools/ccc/ccclib/ToolChain.py b/clang/tools/ccc/ccclib/ToolChain.py
      index 73b0127e1448..6ce6ebc341fa 100644
      --- a/clang/tools/ccc/ccclib/ToolChain.py
      +++ b/clang/tools/ccc/ccclib/ToolChain.py
      @@ -54,6 +54,28 @@ class ToolChain(object):
               else:
                   return args
       
      +    def shouldUseClangCompiler(self, action):
      +        # If user requested no clang, or this isn't a "compile" phase,
      +        # or this isn't a C family option, then don't use clang.
      +        if (self.driver.cccNoClang or 
      +            not isinstance(action.phase, (Phases.PreprocessPhase,
      +                                          Phases.CompilePhase,
      +                                          Phases.SyntaxOnlyPhase,
      +                                          Phases.EmitLLVMPhase,
      +                                          Phases.PrecompilePhase)) or
      +            action.inputs[0].type not in Types.cTypesSet):
      +            return False
      +
      +        if self.driver.cccNoClangPreprocessor:
      +            if isinstance(action.phase, Phases.PreprocessPhase):
      +                return False
      +
      +        if self.driver.cccNoClangCXX:
      +            if action.inputs[0].type in Types.cxxTypesSet:
      +                return False
      +
      +        return True
      +        
       class Darwin_X86_ToolChain(ToolChain):
           def __init__(self, driver, darwinVersion, gccVersion, archName):
               super(Darwin_X86_ToolChain, self).__init__(driver)
      @@ -106,20 +128,23 @@ class Darwin_X86_ToolChain(ToolChain):
               major,minor,minorminor = self.darwinVersion
               return '%d.%d.%d' % (10, major-4, minor)
       
      +    def shouldUseClangCompiler(self, action):
      +        if not super(Darwin_X86_ToolChain, self).shouldUseClangCompiler(action):
      +            return False
      +        
      +        # Only use clang if user didn't override archs, or this is one
      +        # of the ones they provided.
      +        if (not self.driver.cccClangArchs or 
      +            self.archName in self.driver.cccClangArchs):
      +            return True
      +        
      +        return False
      +
           def selectTool(self, action):
               assert isinstance(action, Phases.JobAction)
               
      -        if self.driver.cccClang and self.archName == 'i386':
      -            if (action.inputs[0].type in (Types.CType, Types.CTypeNoPP,
      -                                          Types.ObjCType, Types.ObjCTypeNoPP) and
      -                (isinstance(action.phase, Phases.CompilePhase) or
      -                 isinstance(action.phase, Phases.SyntaxOnlyPhase) or
      -                 isinstance(action.phase, Phases.EmitLLVMPhase))):
      -                return self.clangTool
      -            elif (action.inputs[0].type in (Types.CHeaderType, Types.CHeaderNoPPType,
      -                                            Types.ObjCHeaderType, Types.ObjCHeaderNoPPType) and
      -                  isinstance(action.phase, Phases.PrecompilePhase)):
      -                return self.clangTool
      +        if self.shouldUseClangCompiler(action):
      +            return self.clangTool
       
               return self.toolMap[action.phase.__class__]
       
      @@ -220,17 +245,7 @@ class Generic_GCC_ToolChain(ToolChain):
           def selectTool(self, action):
               assert isinstance(action, Phases.JobAction)
       
      -        if self.driver.cccClang:
      -            if (action.inputs[0].type in (Types.CType, Types.CTypeNoPP,
      -                                          Types.ObjCType, Types.ObjCTypeNoPP) and
      -                (isinstance(action.phase, Phases.PreprocessPhase) or
      -                 isinstance(action.phase, Phases.CompilePhase) or
      -                 isinstance(action.phase, Phases.SyntaxOnlyPhase) or
      -                 isinstance(action.phase, Phases.EmitLLVMPhase))):
      -                return self.clangTool
      -            elif (action.inputs[0].type in (Types.CHeaderType, Types.CHeaderNoPPType,
      -                                            Types.ObjCHeaderType, Types.ObjCHeaderNoPPType) and
      -                  isinstance(action.phase, Phases.PrecompilePhase)):
      -                return self.clangTool
      +        if self.shouldUseClangCompiler(action):
      +            return self.clangTool
       
               return self.toolMap[action.phase.__class__]
      diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py
      index a24255c652f6..61d6a24d3429 100644
      --- a/clang/tools/ccc/ccclib/Tools.py
      +++ b/clang/tools/ccc/ccclib/Tools.py
      @@ -190,6 +190,9 @@ class Clang_CompileTool(Tool):
                   cmd_args.append('-emit-llvm-bc')
               elif outputType is Types.AsmTypeNoPP:
                   cmd_args.append('-S')
      +        elif (inputs[0].type.preprocess and 
      +              outputType is inputs[0].type.preprocess):
      +            cmd_args.append('-E')
               elif outputType is Types.PCHType:
                   # No special option needed, driven by -x. However, we
                   # patch the output name to try and not conflict with gcc.
      diff --git a/clang/tools/ccc/ccclib/Types.py b/clang/tools/ccc/ccclib/Types.py
      index 4af076791446..1dd3ed90118b 100644
      --- a/clang/tools/ccc/ccclib/Types.py
      +++ b/clang/tools/ccc/ccclib/Types.py
      @@ -146,6 +146,22 @@ kTypeSpecifierMap = {
           'treelang' : TreelangType,
       }
       
      +# Set of C family types.
      +cTypesSet = set([CType, CTypeNoPP, 
      +                 ObjCType, ObjCTypeNoPP,
      +                 CXXType, CXXTypeNoPP,
      +                 ObjCXXType, ObjCXXTypeNoPP,
      +                 CHeaderType, CHeaderNoPPType,
      +                 ObjCHeaderType, ObjCHeaderNoPPType,
      +                 CXXHeaderType, CXXHeaderNoPPType,
      +                 ObjCXXHeaderType, ObjCXXHeaderNoPPType])
      +
      +# Set of C++ family types.
      +cxxTypesSet = set([CXXType, CXXTypeNoPP,
      +                   ObjCXXType, ObjCXXTypeNoPP,
      +                   CXXHeaderType, CXXHeaderNoPPType,
      +                   ObjCXXHeaderType, ObjCXXHeaderNoPPType])
      +
       # Check that the type specifier map at least matches what the types
       # believe to be true.
       assert not [name for name,type in kTypeSpecifierMap.items()
      diff --git a/clang/tools/ccc/test/ccc/Xarch.c b/clang/tools/ccc/test/ccc/Xarch.c
      index 0c0eee012194..5c3a1f954dbb 100644
      --- a/clang/tools/ccc/test/ccc/Xarch.c
      +++ b/clang/tools/ccc/test/ccc/Xarch.c
      @@ -1,4 +1,4 @@
      -// RUN: xcc -### -fsyntax-only -Xarch_i386 -Wall -Xarch_ppc -Wunused -arch i386 -arch ppc %s &> %t &&
      +// RUN: xcc -ccc-no-clang -### -fsyntax-only -Xarch_i386 -Wall -Xarch_ppc -Wunused -arch i386 -arch ppc %s &> %t &&
       // RUN: grep '"-Xarch"' %t | count 0 &&
       // RUN: grep '"-Wall"' %t | count 1 &&
       // RUN: grep 'i686-apple' %t | grep -v '"-m64"' | count 1 &&
      diff --git a/clang/tools/ccc/test/ccc/aliases.c b/clang/tools/ccc/test/ccc/aliases.c
      index f9b89a14d4b9..101c4e7a255e 100644
      --- a/clang/tools/ccc/test/ccc/aliases.c
      +++ b/clang/tools/ccc/test/ccc/aliases.c
      @@ -1,13 +1,13 @@
      -// RUN: xcc -### -S --all-warnings %s &> %t &&
      +// RUN: xcc -ccc-no-clang -### -S --all-warnings %s &> %t &&
       // RUN: grep -- '"-Wall"' %t &&
       
      -// RUN: xcc -### -S --ansi %s &> %t &&
      +// RUN: xcc -ccc-no-clang -### -S --ansi %s &> %t &&
       // RUN: grep -- '"-ansi"' %t &&
       
      -// RUN: xcc -### -S --assert foo --assert=foo %s &> %t &&
      +// RUN: xcc -ccc-no-clang -### -S --assert foo --assert=foo %s &> %t &&
       // RUN: grep -- '"-A" "foo" "-A" "foo"' %t &&
       
      -// RUN: xcc -### -S --classpath foo --classpath=foo %s &> %t &&
      +// RUN: xcc -ccc-no-clang -### -S --classpath foo --classpath=foo %s &> %t &&
       // RUN: grep -- '"-fclasspath=foo" "-fclasspath=foo"' %t &&
       
       // RUN: true
      diff --git a/clang/tools/ccc/test/ccc/darwin-hello.m b/clang/tools/ccc/test/ccc/darwin-hello.m
      index 73289e99cf89..51dea654dcbf 100644
      --- a/clang/tools/ccc/test/ccc/darwin-hello.m
      +++ b/clang/tools/ccc/test/ccc/darwin-hello.m
      @@ -1,11 +1,11 @@
       // Check that object files compiled with -mdynamic-no-pic can be
       // linked.
       // 
      -// RUN: xcc -ccc-clang -m32 -mdynamic-no-pic %s -c -o %t.o &&
      -// RUN: xcc -ccc-clang -m32 %t.o -o %t &&
      +// RUN: xcc -m32 -mdynamic-no-pic %s -c -o %t.o &&
      +// RUN: xcc -m32 %t.o -o %t &&
       // RUN: %t | grep "Hello, World" &&
      -// RUN: xcc -ccc-clang -m64 -mdynamic-no-pic %s -c -o %t.o &&
      -// RUN: xcc -ccc-clang -m64 %t.o -o %t &&
      +// RUN: xcc -m64 -mdynamic-no-pic %s -c -o %t.o &&
      +// RUN: xcc -m64 %t.o -o %t &&
       // RUN: %t | grep "Hello, World" &&
       // RUN: true
       
      diff --git a/clang/tools/ccc/test/ccc/darwin-x86-cc1.m b/clang/tools/ccc/test/ccc/darwin-x86-cc1.m
      index 6c097d3a744d..d00f85554fe4 100644
      --- a/clang/tools/ccc/test/ccc/darwin-x86-cc1.m
      +++ b/clang/tools/ccc/test/ccc/darwin-x86-cc1.m
      @@ -1,14 +1,14 @@
      -// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c -arch i386 -fmessage-length=0 -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -DUSER_DEFINE_0 -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -IINCLUDE_PATH_0 -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wno-four-char-constants -Wno-unknown-pragmas -Wno-format-y2k -Wpointer-arith -Wreturn-type -Wwrite-strings -Wswitch -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wint-to-pointer-cast -Wpointer-to-int-cast -Wshorten-64-to-32 -FFRAMEWORK_0 -IINCLUDE_PATH_1 -FFRAMEWORK_1 -include USER_INCLUDE_0 -c %s -o %t.out &> %t.opts &&
      +// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c -arch i386 -fmessage-length=0 -Wno-trigraphs -fpascal-strings -fasm-blocks -Os -mdynamic-no-pic -DUSER_DEFINE_0 -fvisibility=hidden -mmacosx-version-min=10.5 -gdwarf-2 -IINCLUDE_PATH_0 -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -Wno-four-char-constants -Wno-unknown-pragmas -Wno-format-y2k -Wpointer-arith -Wreturn-type -Wwrite-strings -Wswitch -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wint-to-pointer-cast -Wpointer-to-int-cast -Wshorten-64-to-32 -FFRAMEWORK_0 -IINCLUDE_PATH_1 -FFRAMEWORK_1 -include USER_INCLUDE_0 -c %s -o %t.out &> %t.opts &&
       // RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-quiet" "-IINCLUDE_PATH_0" "-FFRAMEWORK_0" "-IINCLUDE_PATH_1" "-FFRAMEWORK_1" "-D__DYNAMIC__" "-DUSER_DEFINE_0" "-include" "USER_INCLUDE_0" ".*" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mpascal-strings" "-mdynamic-no-pic" "-mmacosx-version-min=10.5" "-mtune=core2" "-auxbase-strip" ".*" "-gdwarf-2" "-Os" "-Wno-trigraphs" "-Wall" "-Wextra" "-Wno-missing-field-initializers" "-Wno-unused-parameter" "-Wno-four-char-constants" "-Wno-unknown-pragmas" "-Wno-format-y2k" "-Wpointer-arith" "-Wreturn-type" "-Wwrite-strings" "-Wswitch" "-Wcast-align" "-Wchar-subscripts" "-Winline" "-Wnested-externs" "-Wint-to-pointer-cast" "-Wpointer-to-int-cast" "-Wshorten-64-to-32" "-fmessage-length=0" "-fasm-blocks" "-fvisibility=hidden" "-o"' %t.opts &&
       // RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/as" "-arch" "i386" "-force_cpusubtype_ALL" "-o"' %t.opts &&
       
      -// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -v -E -dM -arch i386 -xobjective-c -c %s &> %t.opts &&
      +// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -v -E -dM -arch i386 -xobjective-c -c %s &> %t.opts &&
       // RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-E" "-quiet" "-v" "-D__DYNAMIC__" ".*" "-fPIC" "-mmacosx-version-min=10.6.5" "-mtune=core2" "-dM"' %t.opts && 
       
      -// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -m32 -S -x cpp-output %s &> %t.opts &&
      +// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -m32 -S -x cpp-output %s &> %t.opts &&
       // RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1" "-fpreprocessed" ".*darwin-x86-cc1.m" "-fPIC" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mmacosx-version-min=10.6.5" "-m32" "-mtune=core2" "-auxbase" "darwin-x86-cc1" "-o" ".*"' %t.opts &&
       
      -// RUN: xcc -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c-header %s -o /tmp/x.gch &> %t.opts &&
      +// RUN: xcc -ccc-no-clang -ccc-host-bits 32 -ccc-host-machine i386 -ccc-host-system darwin -ccc-host-release 10.5.0 -### -x objective-c-header %s -o /tmp/x.gch &> %t.opts &&
       // RUN: grep ' "/usr/libexec/gcc/i686-apple-darwin10/4.2.1/cc1obj" "-quiet" "-D__DYNAMIC__" ".*darwin-x86-cc1.m" "-fPIC" "-quiet" "-dumpbase" "darwin-x86-cc1.m" "-mmacosx-version-min=10.6.5" "-mtune=core2" "-auxbase" ".*" "-o" "/dev/null" "--output-pch=" "/tmp/x.gch"' %t.opts &&
       
       // RUN: true
      diff --git a/clang/tools/ccc/test/ccc/hello.c b/clang/tools/ccc/test/ccc/hello.c
      index 6b857b519a4b..120db1a63038 100644
      --- a/clang/tools/ccc/test/ccc/hello.c
      +++ b/clang/tools/ccc/test/ccc/hello.c
      @@ -1,8 +1,8 @@
      -// RUN: xcc %s -o %t &&
      +// RUN: xcc -ccc-no-clang %s -o %t &&
       // RUN: %t | grep "Hello, World" &&
      -// RUN: xcc %s -o %t -pipe &&
      +// RUN: xcc -ccc-no-clang %s -o %t -pipe &&
       // RUN: %t | grep "Hello, World" &&
      -// RUN: xcc -ccc-clang %s -o %t &&
      +// RUN: xcc %s -o %t &&
       // RUN: %t | grep "Hello, World"
       
       int main() {
      diff --git a/clang/tools/ccc/test/ccc/hello.m b/clang/tools/ccc/test/ccc/hello.m
      index 9563fd04fe01..b1bcaeb2516e 100644
      --- a/clang/tools/ccc/test/ccc/hello.m
      +++ b/clang/tools/ccc/test/ccc/hello.m
      @@ -1,6 +1,6 @@
      -// RUN: xcc %s -o %t &&
      +// RUN: xcc -ccc-no-clang %s -o %t &&
       // RUN: %t | grep "Hello, World" &&
      -// RUN: xcc -ccc-clang %s -o %t &&
      +// RUN: xcc %s -o %t &&
       // RUN: %t | grep "Hello, World"
       
       int main() {
      diff --git a/clang/tools/ccc/test/ccc/universal-hello.c b/clang/tools/ccc/test/ccc/universal-hello.c
      index 7702b38229c2..654c43507a1f 100644
      --- a/clang/tools/ccc/test/ccc/universal-hello.c
      +++ b/clang/tools/ccc/test/ccc/universal-hello.c
      @@ -1,7 +1,7 @@
      -// RUN: xcc -arch ppc -arch i386 -arch x86_64 %s -o %t &&
      +// RUN: xcc -ccc-no-clang -arch ppc -arch i386 -arch x86_64 %s -o %t &&
       // RUN: %t | grep "Hello, World" &&
       
      -// RUN: xcc -pipe -arch ppc -arch i386 -arch x86_64 %s -o %t &&
      +// RUN: xcc -ccc-no-clang -pipe -arch ppc -arch i386 -arch x86_64 %s -o %t &&
       // RUN: %t | grep "Hello, World" &&
       
       // Check that multiple archs are handled properly.
      -- 
      GitLab
      
      
      From 7594e2a59a5ffc4abd80fea5d00d9be2496fe3fa Mon Sep 17 00:00:00 2001
      From: Ted Kremenek 
      Date: Fri, 30 Jan 2009 00:08:43 +0000
      Subject: [PATCH 455/682] Fix a couple bugs: - NonLoc::MakeVal() would use
       sizeof(unsigned) (literally) instead of consulting   ASTContext for the size
       (in bits) of 'int'. While it worked, it was a   conflation of concepts and
       using ASTContext.IntTy is 100% correct. - RegionStore::getSizeInElements() no
       longer assumes that a VarRegion has the   type "ConstantArray", and handles
       the case when uses use ordinary variables   as if they were arrays. - Fixed
       ElementRegion::getRValueType() to just return the rvalue type of its   "array
       region" in the case the array didn't have ArrayType. - All of this fixes
       
      
      llvm-svn: 63347
      ---
       .../PathSensitive/BasicValueFactory.h         |  5 ++++
       .../clang/Analysis/PathSensitive/MemRegion.h  |  8 +++++
       .../clang/Analysis/PathSensitive/SVals.h      |  4 +--
       clang/lib/Analysis/MemRegion.cpp              |  5 ++--
       clang/lib/Analysis/RegionStore.cpp            | 29 ++++++++++++-------
       clang/lib/Analysis/SVals.cpp                  |  7 ++---
       clang/test/Analysis/rdar-6541136-region.c     | 19 ++++++++++++
       clang/test/Analysis/rdar-6541136.c            | 20 +++++++++++++
       8 files changed, 78 insertions(+), 19 deletions(-)
       create mode 100644 clang/test/Analysis/rdar-6541136-region.c
       create mode 100644 clang/test/Analysis/rdar-6541136.c
      
      diff --git a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h b/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h
      index bf6bb8c80774..1e08fb9a0266 100644
      --- a/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h
      +++ b/clang/include/clang/Analysis/PathSensitive/BasicValueFactory.h
      @@ -76,6 +76,11 @@ public:
         const llvm::APSInt& getValue(uint64_t X, unsigned BitWidth, bool isUnsigned);
         const llvm::APSInt& getValue(uint64_t X, QualType T);
       
      +  const llvm::APSInt& getIntValue(uint64_t X, bool isUnsigned) {
      +    QualType T = isUnsigned ? Ctx.UnsignedIntTy : Ctx.IntTy;
      +    return getValue(X, T);
      +  }
      +
         inline const llvm::APSInt& getZeroWithPtrWidth(bool isUnsigned = true) {
           return getValue(0, Ctx.getTypeSize(Ctx.VoidPtrTy), isUnsigned);
         }
      diff --git a/clang/include/clang/Analysis/PathSensitive/MemRegion.h b/clang/include/clang/Analysis/PathSensitive/MemRegion.h
      index 80efac4dbf01..8a62eff7a996 100644
      --- a/clang/include/clang/Analysis/PathSensitive/MemRegion.h
      +++ b/clang/include/clang/Analysis/PathSensitive/MemRegion.h
      @@ -173,6 +173,14 @@ public:
           // FIXME: We can possibly optimize this later to cache this value.
           return C.getPointerType(getRValueType(C));
         }
      +  
      +  QualType getDesugaredRValueType(ASTContext& C) const {
      +    return getRValueType(C)->getDesugaredType();
      +  }
      +  
      +  QualType getDesugaredLValueType(ASTContext& C) const {
      +    return getLValueType(C)->getDesugaredType();
      +  }
       
         static bool classof(const MemRegion* R) {
           unsigned k = R->getKind();
      diff --git a/clang/include/clang/Analysis/PathSensitive/SVals.h b/clang/include/clang/Analysis/PathSensitive/SVals.h
      index dbeba45c833a..a0bc3ed186b5 100644
      --- a/clang/include/clang/Analysis/PathSensitive/SVals.h
      +++ b/clang/include/clang/Analysis/PathSensitive/SVals.h
      @@ -171,8 +171,8 @@ public:
       
         static NonLoc MakeVal(SymbolRef sym);
       
      -  static NonLoc MakeVal(BasicValueFactory& BasicVals, unsigned X, 
      -                        bool isUnsigned);
      +  static NonLoc MakeIntVal(BasicValueFactory& BasicVals, uint64_t X, 
      +                           bool isUnsigned);
       
         static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, 
                               unsigned BitWidth, bool isUnsigned);
      diff --git a/clang/lib/Analysis/MemRegion.cpp b/clang/lib/Analysis/MemRegion.cpp
      index 55c6935b8e85..82f442354192 100644
      --- a/clang/lib/Analysis/MemRegion.cpp
      +++ b/clang/lib/Analysis/MemRegion.cpp
      @@ -114,8 +114,9 @@ QualType ElementRegion::getRValueType(ASTContext& C) const {
         if (ArrayType* AT = dyn_cast(T.getTypePtr()))
           return AT->getElementType();
       
      -  PointerType* PtrT = cast(T.getTypePtr());
      -  return C.getCanonicalType(PtrT->getPointeeType());
      +  // If the RValueType of the array region isn't an ArrayType, then essentially
      +  // the element's  
      +  return T;
       }
       
       //===----------------------------------------------------------------------===//
      diff --git a/clang/lib/Analysis/RegionStore.cpp b/clang/lib/Analysis/RegionStore.cpp
      index e50b0abb61e6..8d36d10a8a51 100644
      --- a/clang/lib/Analysis/RegionStore.cpp
      +++ b/clang/lib/Analysis/RegionStore.cpp
      @@ -403,20 +403,27 @@ SVal RegionStoreManager::getSizeInElements(const GRState* St,
                                                  const MemRegion* R) {
         if (const VarRegion* VR = dyn_cast(R)) {
           // Get the type of the variable.
      -    QualType T = VR->getRValueType(getContext());
      +    QualType T = VR->getDesugaredRValueType(getContext());
       
      -    // It must be of array type. 
      -    const ConstantArrayType* CAT = cast(T.getTypePtr());
      -
      -    // return the size as signed integer.
      -    return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false);
      +    // FIXME: Handle variable-length arrays.
      +    if (isa(T))
      +      return UnknownVal();
      +    
      +    if (const ConstantArrayType* CAT = dyn_cast(T)) {
      +      // return the size as signed integer.
      +      return NonLoc::MakeVal(getBasicVals(), CAT->getSize(), false);
      +    }
      +    
      +    // Clients can use ordinary variables as if they were arrays.  These
      +    // essentially are arrays of size 1.
      +    return NonLoc::MakeIntVal(getBasicVals(), 1, false);
         }
       
         if (const StringRegion* SR = dyn_cast(R)) {
           const StringLiteral* Str = SR->getStringLiteral();
           // We intentionally made the size value signed because it participates in 
           // operations with signed indices.
      -    return NonLoc::MakeVal(getBasicVals(), Str->getByteLength() + 1, false);
      +    return NonLoc::MakeIntVal(getBasicVals(), Str->getByteLength()+1, false);
         }
       
         if (const AnonTypedRegion* ATR = dyn_cast(R)) {
      @@ -880,8 +887,8 @@ const GRState* RegionStoreManager::BindArray(const GRState* St,
       
         // When we are binding the whole array, it always has default value 0.
         GRStateRef state(St, StateMgr);
      -  St = state.set(R, NonLoc::MakeVal(getBasicVals(), 0, 
      -                                                        false));
      +  St = state.set(R, NonLoc::MakeIntVal(getBasicVals(), 0, 
      +                                                           false));
       
         Store store = St->getStore();
       
      @@ -961,8 +968,8 @@ RegionStoreManager::BindStruct(const GRState* St, const TypedRegion* R, SVal V){
           // struct decl. In this case, mark the region as having default value.
           if (VI == VE) {
             GRStateRef state(St, StateMgr);
      -      St = state.set(R, NonLoc::MakeVal(getBasicVals(), 0, 
      -                                                            false));
      +      const NonLoc& Idx = NonLoc::MakeIntVal(getBasicVals(), 0, false);
      +      St = state.set(R, Idx);
             break;
           }
       
      diff --git a/clang/lib/Analysis/SVals.cpp b/clang/lib/Analysis/SVals.cpp
      index 6847764871d1..824d7229a33a 100644
      --- a/clang/lib/Analysis/SVals.cpp
      +++ b/clang/lib/Analysis/SVals.cpp
      @@ -247,10 +247,9 @@ NonLoc NonLoc::MakeVal(SymbolRef sym) {
         return nonloc::SymbolVal(sym);
       }
       
      -NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, unsigned X, 
      -                       bool isUnsigned) {
      -  return nonloc::ConcreteInt(BasicVals.getValue(X, sizeof(unsigned)*8, 
      -                                                isUnsigned));
      +NonLoc NonLoc::MakeIntVal(BasicValueFactory& BasicVals, uint64_t X, 
      +                          bool isUnsigned) {
      +  return nonloc::ConcreteInt(BasicVals.getIntValue(X, isUnsigned));
       }
       
       NonLoc NonLoc::MakeVal(BasicValueFactory& BasicVals, uint64_t X, 
      diff --git a/clang/test/Analysis/rdar-6541136-region.c b/clang/test/Analysis/rdar-6541136-region.c
      new file mode 100644
      index 000000000000..4fd2214daa5a
      --- /dev/null
      +++ b/clang/test/Analysis/rdar-6541136-region.c
      @@ -0,0 +1,19 @@
      +// RUN: clang -verify -analyze -checker-cfref -analyzer-store-region %s
      +
      +struct tea_cheese { unsigned magic; };
      +typedef struct tea_cheese kernel_tea_cheese_t;
      +extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
      +
      +// This test case exercises the ElementRegion::getRValueType() logic.
      +
      +
      +void foo( void )
      +{
      +  kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
      +  struct load_wine *cmd = (void*) &wonky[1];
      +  cmd = cmd;
      +  char *p = (void*) &wonky[1];
      +  *p = 1;
      +  kernel_tea_cheese_t *q = &wonky[1];
      +  kernel_tea_cheese_t r = *q; // expected-warning{{out-of-bound memory position}}
      +}
      diff --git a/clang/test/Analysis/rdar-6541136.c b/clang/test/Analysis/rdar-6541136.c
      new file mode 100644
      index 000000000000..919a21dc21c1
      --- /dev/null
      +++ b/clang/test/Analysis/rdar-6541136.c
      @@ -0,0 +1,20 @@
      +// clang -verify -analyze -checker-cfref -analyzer-store-basic %s
      +
      +struct tea_cheese { unsigned magic; };
      +typedef struct tea_cheese kernel_tea_cheese_t;
      +extern kernel_tea_cheese_t _wonky_gesticulate_cheese;
      +
      +// This test case exercises the ElementRegion::getRValueType() logic.
      +// All it tests is that it does not crash or do anything weird.
      +// The out-of-bounds-access on line 19 is caught using the region store variant.
      +
      +void foo( void )
      +{
      +  kernel_tea_cheese_t *wonky = &_wonky_gesticulate_cheese;
      +  struct load_wine *cmd = (void*) &wonky[1];
      +  cmd = cmd;
      +  char *p = (void*) &wonky[1];
      +  *p = 1;
      +  kernel_tea_cheese_t *q = &wonky[1];
      +  kernel_tea_cheese_t r = *q; // no-warning
      +}
      -- 
      GitLab
      
      
      From b6e6a513c21ae4b13b99801353dca125debb6c11 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Fri, 30 Jan 2009 00:12:29 +0000
      Subject: [PATCH 456/682] ccc: Mark -combine option as unsupported.
      
      llvm-svn: 63348
      ---
       clang/tools/ccc/ccclib/Arguments.py | 2 +-
       clang/tools/ccc/ccclib/Driver.py    | 4 ----
       2 files changed, 1 insertion(+), 5 deletions(-)
      
      diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py
      index 051498f31052..bb259137f594 100644
      --- a/clang/tools/ccc/ccclib/Arguments.py
      +++ b/clang/tools/ccc/ccclib/Arguments.py
      @@ -520,7 +520,7 @@ class OptionParser:
               self.EOption = self.addOption(FlagOption('-E'))
               self.SOption = self.addOption(FlagOption('-S'))
               self.cOption = self.addOption(FlagOption('-c'))
      -        self.combineOption = self.addOption(FlagOption('-combine'))
      +        self.combineOption = self.addOption(FlagOption('-combine', unsupported=True))
               self.noIntegratedCPPOption = self.addOption(FlagOption('-no-integrated-cpp'))
               self.pipeOption = self.addOption(FlagOption('-pipe'))
               self.saveTempsOption = self.addOption(FlagOption('-save-temps'))
      diff --git a/clang/tools/ccc/ccclib/Driver.py b/clang/tools/ccc/ccclib/Driver.py
      index bdcdcb731cfe..2f4cc14066ad 100644
      --- a/clang/tools/ccc/ccclib/Driver.py
      +++ b/clang/tools/ccc/ccclib/Driver.py
      @@ -443,10 +443,6 @@ class Driver(object):
               if finalPhaseOpt:
                   self.claim(finalPhaseOpt)
       
      -        # FIXME: Support -combine.
      -        if hasCombine:
      -            raise NotImplementedError,"-combine is not yet supported"
      -        
               # Reject -Z* at the top level for now.
               arg = args.getLastArg(self.parser.ZOption)
               if arg:
      -- 
      GitLab
      
      
      From 3fc8ea64c9a3ae5653f291c4f477e610c7d479be Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Fri, 30 Jan 2009 00:24:16 +0000
      Subject: [PATCH 457/682] ccc: Add -Xclang option, rename -WA, to -Xanalyzer. 
       - -Xclang always forwards to clang
      
       - -Xanalyzer replaces -WA,; it seems like the cleaner mechanism and
          is more readable.
      
      llvm-svn: 63349
      ---
       clang/tools/ccc/ccclib/Arguments.py | 3 ++-
       clang/tools/ccc/ccclib/Tools.py     | 9 ++++++---
       clang/tools/ccc/test/ccc/Xclang.c   | 1 +
       clang/tools/ccc/test/ccc/analyze.c  | 5 ++++-
       4 files changed, 13 insertions(+), 5 deletions(-)
       create mode 100644 clang/tools/ccc/test/ccc/Xclang.c
      
      diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py
      index bb259137f594..1ff76eccd9f3 100644
      --- a/clang/tools/ccc/ccclib/Arguments.py
      +++ b/clang/tools/ccc/ccclib/Arguments.py
      @@ -549,7 +549,8 @@ class OptionParser:
       
               # Blanket pass-through options.
       
      -        self.WAOption = self.addOption(CommaJoinedOption('-WA,'))        
      +        self.XanalyzerOption = self.addOption(SeparateOption('-Xanalyzer'))
      +        self.XclangOption = self.addOption(SeparateOption('-Xclang'))
       
               self.WaOption = self.addOption(CommaJoinedOption('-Wa,'))
               self.XassemblerOption = self.addOption(SeparateOption('-Xassembler'))
      diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py
      index 61d6a24d3429..ed138141b26a 100644
      --- a/clang/tools/ccc/ccclib/Tools.py
      +++ b/clang/tools/ccc/ccclib/Tools.py
      @@ -225,9 +225,9 @@ class Clang_CompileTool(Tool):
                   
                   cmd_args.append('-analyzer-output-plist')
       
      -            # Add -WA, arguments when running as analyzer.
      -            for arg in arglist.getArgs(arglist.parser.WAOption):
      -                cmd_args.extend(arglist.renderAsInput(arg))
      +            # Add -Xanalyzer arguments when running as analyzer.
      +            for arg in arglist.getArgs(arglist.parser.XanalyzerOption):
      +                cmd_args.extend(arglist.getValues(arg))
               else:
                   # Perform argument translation for LLVM backend. This
                   # takes some care in reconciling with llvm-gcc. The
      @@ -325,6 +325,9 @@ class Clang_CompileTool(Tool):
               arglist.addLastArg(cmd_args, arglist.parser.f_pascalStringsOption)
               arglist.addLastArg(cmd_args, arglist.parser.f_writableStringsOption)
       
      +        for arg in arglist.getArgs(arglist.parser.XclangOption):
      +            cmd_args.extend(arglist.getValues(arg))
      +
               if arch is not None:
                   cmd_args.extend(arglist.render(arch))
       
      diff --git a/clang/tools/ccc/test/ccc/Xclang.c b/clang/tools/ccc/test/ccc/Xclang.c
      new file mode 100644
      index 000000000000..39da6a81982b
      --- /dev/null
      +++ b/clang/tools/ccc/test/ccc/Xclang.c
      @@ -0,0 +1 @@
      +// RUN: xcc -fsyntax-only -Xclang --help %s | grep 'OVERVIEW:  llvm clang cfe'
      diff --git a/clang/tools/ccc/test/ccc/analyze.c b/clang/tools/ccc/test/ccc/analyze.c
      index b03c6af9c1c8..6693c7666760 100644
      --- a/clang/tools/ccc/test/ccc/analyze.c
      +++ b/clang/tools/ccc/test/ccc/analyze.c
      @@ -1,5 +1,8 @@
       // RUN: xcc --analyze %s -o %t &&
      -// RUN: grep 'Dereference of null pointer.' %t
      +// RUN: grep 'Dereference of null pointer.' %t &&
      +
      +// RUN: xcc -### --analyze %s -Xanalyzer -check-that-program-halts &> %t &&
      +// RUN: grep 'check-that-program-halts' %t
       
       void f(int *p) {
         if (!p) 
      -- 
      GitLab
      
      
      From f6d0aff0bd71da33640fec807236858b27c40f79 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 00:45:56 +0000
      Subject: [PATCH 458/682] Add DebugLoc propagation to some of the methods in
       DAG combiner.
      
      llvm-svn: 63350
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 61 +++++++++++--------
       1 file changed, 34 insertions(+), 27 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 848051940f7e..13256e0e79f1 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -196,7 +196,7 @@ namespace {
           SDValue visitVECTOR_SHUFFLE(SDNode *N);
       
           SDValue XformToShuffleWithZero(SDNode *N);
      -    SDValue ReassociateOps(unsigned Opc, SDValue LHS, SDValue RHS);
      +    SDValue ReassociateOps(unsigned Opc, DebugLoc DL, SDValue LHS, SDValue RHS);
           
           SDValue visitShiftByConstant(SDNode *N, unsigned Amt);
       
      @@ -390,12 +390,12 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
           
           // -(A+B) -> -A - B
           if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1))
      -      return DAG.getNode(ISD::FSUB, Op.getValueType(),
      +      return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(),
                                GetNegatedExpression(Op.getOperand(0), DAG, 
                                                     LegalOperations, Depth+1),
                                Op.getOperand(1));
           // -(A+B) -> -B - A
      -    return DAG.getNode(ISD::FSUB, Op.getValueType(),
      +    return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(),
                              GetNegatedExpression(Op.getOperand(1), DAG, 
                                                   LegalOperations, Depth+1),
                              Op.getOperand(0));
      @@ -409,8 +409,8 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
               return Op.getOperand(1);
           
           // -(A-B) -> B-A
      -    return DAG.getNode(ISD::FSUB, Op.getValueType(), Op.getOperand(1),
      -                       Op.getOperand(0));
      +    return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(),
      +                       Op.getOperand(1), Op.getOperand(0));
           
         case ISD::FMUL:
         case ISD::FDIV:
      @@ -418,24 +418,24 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG,
           
           // -(X*Y) -> -X * Y
           if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1))
      -      return DAG.getNode(Op.getOpcode(), Op.getValueType(),
      +      return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(),
                                GetNegatedExpression(Op.getOperand(0), DAG, 
                                                     LegalOperations, Depth+1),
                                Op.getOperand(1));
             
           // -(X*Y) -> X * -Y
      -    return DAG.getNode(Op.getOpcode(), Op.getValueType(),
      +    return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(),
                              Op.getOperand(0),
                              GetNegatedExpression(Op.getOperand(1), DAG,
                                                   LegalOperations, Depth+1));
           
         case ISD::FP_EXTEND:
         case ISD::FSIN:
      -    return DAG.getNode(Op.getOpcode(), Op.getValueType(),
      +    return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(),
                              GetNegatedExpression(Op.getOperand(0), DAG, 
                                                   LegalOperations, Depth+1));
         case ISD::FP_ROUND:
      -      return DAG.getNode(ISD::FP_ROUND, Op.getValueType(),
      +      return DAG.getNode(ISD::FP_ROUND, Op.getDebugLoc(), Op.getValueType(),
                                GetNegatedExpression(Op.getOperand(0), DAG, 
                                                     LegalOperations, Depth+1),
                                Op.getOperand(1));
      @@ -479,34 +479,41 @@ static bool isOneUseSetCC(SDValue N) {
         return false;
       }
       
      -SDValue DAGCombiner::ReassociateOps(unsigned Opc, SDValue N0, SDValue N1){
      +SDValue DAGCombiner::ReassociateOps(unsigned Opc, DebugLoc DL,
      +                                    SDValue N0, SDValue N1) {
         MVT VT = N0.getValueType();
      -  // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
      -  // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
         if (N0.getOpcode() == Opc && isa(N0.getOperand(1))) {
           if (isa(N1)) {
      -      SDValue OpNode = DAG.getNode(Opc, VT, N0.getOperand(1), N1);
      +      // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
      +      SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
      +                                   N0.getOperand(1), N1);
             AddToWorkList(OpNode.getNode());
      -      return DAG.getNode(Opc, VT, OpNode, N0.getOperand(0));
      +      return DAG.getNode(Opc, DL, VT, OpNode, N0.getOperand(0));
           } else if (N0.hasOneUse()) {
      -      SDValue OpNode = DAG.getNode(Opc, VT, N0.getOperand(0), N1);
      +      // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
      +      SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
      +                                   N0.getOperand(0), N1);
             AddToWorkList(OpNode.getNode());
      -      return DAG.getNode(Opc, VT, OpNode, N0.getOperand(1));
      +      return DAG.getNode(Opc, DL, VT, OpNode, N0.getOperand(1));
           }
         }
      -  // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
      -  // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
      +
         if (N1.getOpcode() == Opc && isa(N1.getOperand(1))) {
           if (isa(N0)) {
      -      SDValue OpNode = DAG.getNode(Opc, VT, N1.getOperand(1), N0);
      +      // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2))
      +      SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT,
      +                                   N1.getOperand(1), N0);
             AddToWorkList(OpNode.getNode());
      -      return DAG.getNode(Opc, VT, OpNode, N1.getOperand(0));
      +      return DAG.getNode(Opc, DL, VT, OpNode, N1.getOperand(0));
           } else if (N1.hasOneUse()) {
      -      SDValue OpNode = DAG.getNode(Opc, VT, N1.getOperand(0), N0);
      +      // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
      +      SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT,
      +                                   N1.getOperand(0), N0);
             AddToWorkList(OpNode.getNode());
      -      return DAG.getNode(Opc, VT, OpNode, N1.getOperand(1));
      +      return DAG.getNode(Opc, DL, VT, OpNode, N1.getOperand(1));
           }
         }
      +
         return SDValue();
       }
       
      @@ -1021,7 +1028,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
                                                N0C->getAPIntValue(), VT),
                                N0.getOperand(1));
         // reassociate add
      -  SDValue RADD = ReassociateOps(ISD::ADD, N0, N1);
      +  SDValue RADD = ReassociateOps(ISD::ADD, N->getDebugLoc(), N0, N1);
         if (RADD.getNode() != 0)
           return RADD;
         // fold ((0-A) + B) -> B-A
      @@ -1329,7 +1336,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
         }
         
         // reassociate mul
      -  SDValue RMUL = ReassociateOps(ISD::MUL, N0, N1);
      +  SDValue RMUL = ReassociateOps(ISD::MUL, N->getDebugLoc(), N0, N1);
         if (RMUL.getNode() != 0)
           return RMUL;
       
      @@ -1752,7 +1759,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) {
                                          APInt::getAllOnesValue(BitWidth)))
           return DAG.getConstant(0, VT);
         // reassociate and
      -  SDValue RAND = ReassociateOps(ISD::AND, N0, N1);
      +  SDValue RAND = ReassociateOps(ISD::AND, N->getDebugLoc(), N0, N1);
         if (RAND.getNode() != 0)
           return RAND;
         // fold (and (or x, 0xFFFF), 0xFF) -> 0xFF
      @@ -1952,7 +1959,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) {
         if (N1C && DAG.MaskedValueIsZero(N0, ~N1C->getAPIntValue()))
           return N1;
         // reassociate or
      -  SDValue ROR = ReassociateOps(ISD::OR, N0, N1);
      +  SDValue ROR = ReassociateOps(ISD::OR, N->getDebugLoc(), N0, N1);
         if (ROR.getNode() != 0)
           return ROR;
         // Canonicalize (or (and X, c1), c2) -> (and (or X, c2), c1|c2)
      @@ -2244,7 +2251,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) {
         if (N1C && N1C->isNullValue())
           return N0;
         // reassociate xor
      -  SDValue RXOR = ReassociateOps(ISD::XOR, N0, N1);
      +  SDValue RXOR = ReassociateOps(ISD::XOR, N->getDebugLoc(), N0, N1);
         if (RXOR.getNode() != 0)
           return RXOR;
       
      -- 
      GitLab
      
      
      From d9c28b808bcff307c2447bc41de36fd93b4f48d4 Mon Sep 17 00:00:00 2001
      From: Fariborz Jahanian 
      Date: Fri, 30 Jan 2009 00:46:37 +0000
      Subject: [PATCH 459/682] Bug fixing involving method-list in protocol
       meta-data (objc2 nonfragile-abi).
      
      llvm-svn: 63351
      ---
       clang/lib/CodeGen/CGObjCMac.cpp | 31 +++++++++++++++++++++++++------
       1 file changed, 25 insertions(+), 6 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
      index 3f3ea9e2201d..526a95a96366 100644
      --- a/clang/lib/CodeGen/CGObjCMac.cpp
      +++ b/clang/lib/CodeGen/CGObjCMac.cpp
      @@ -572,6 +572,8 @@ private:
         
         llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD);
         
      +  llvm::Constant *GetMethodDescriptionConstant(const ObjCMethodDecl *MD);
      +  
         /// EmitMethodList - Emit the method list for the given
         /// implementation. The return value has type MethodListnfABITy.
         llvm::Constant *EmitMethodList(const std::string &Name,
      @@ -3789,7 +3791,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
         for (ObjCProtocolDecl::instmeth_iterator i = PD->instmeth_begin(),
              e = PD->instmeth_end(); i != e; ++i) {
           ObjCMethodDecl *MD = *i;
      -    llvm::Constant *C = GetMethodConstant(MD);
      +    llvm::Constant *C = GetMethodDescriptionConstant(MD);
           if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
             OptInstanceMethods.push_back(C);
           } else {
      @@ -3800,7 +3802,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
         for (ObjCProtocolDecl::classmeth_iterator i = PD->classmeth_begin(),
              e = PD->classmeth_end(); i != e; ++i) {
           ObjCMethodDecl *MD = *i;
      -    llvm::Constant *C = GetMethodConstant(MD);
      +    llvm::Constant *C = GetMethodDescriptionConstant(MD);
           if (MD->getImplementationControl() == ObjCMethodDecl::Optional) {
             OptClassMethods.push_back(C);
           } else {
      @@ -3817,19 +3819,19 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol(
                                 PD->protocol_begin(),
                                 PD->protocol_end());
         
      -  Values[3] = EmitMethodList("\01l_OBJC_$_INSTANCE_METHODS_"
      +  Values[3] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_"
                                    + PD->getNameAsString(),
                                    "__DATA, __objc_const",
                                    InstanceMethods);
      -  Values[4] = EmitMethodList("\01l_OBJC_$_CLASS_METHODS_" 
      +  Values[4] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_" 
                                    + PD->getNameAsString(),
                                    "__DATA, __objc_const",
                                    ClassMethods);
      -  Values[5] = EmitMethodList("\01l_OBJC_$_INSTANCE_METHODS_OPT_"
      +  Values[5] = EmitMethodList("\01l_OBJC_$_PROTOCOL_INSTANCE_METHODS_OPT_"
                                    + PD->getNameAsString(),
                                    "__DATA, __objc_const",
                                    OptInstanceMethods);
      -  Values[6] = EmitMethodList("\01l_OBJC_$_CLASS_METHODS_OPT_" 
      +  Values[6] = EmitMethodList("\01l_OBJC_$_PROTOCOL_CLASS_METHODS_OPT_" 
                                    + PD->getNameAsString(),
                                    "__DATA, __objc_const",
                                    OptClassMethods);
      @@ -3921,6 +3923,23 @@ CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name,
         return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy);
       }
       
      +/// GetMethodDescriptionConstant - This routine build following meta-data:
      +/// struct _objc_method {
      +///   SEL _cmd;
      +///   char *method_type;
      +///   char *_imp;
      +/// }
      +
      +llvm::Constant *
      +CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) {
      +  std::vector Desc(3);
      +  Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()),
      +                                           ObjCTypes.SelectorPtrTy);
      +  Desc[1] = GetMethodVarType(MD);
      +  // FIXME. This is really always NULL?
      +  Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy);
      +  return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc);
      +}
       /* *** */
       
       CodeGen::CGObjCRuntime *
      -- 
      GitLab
      
      
      From 62dc51c3950bad9c089d2f18c8d848abb117e56f Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Fri, 30 Jan 2009 00:47:38 +0000
      Subject: [PATCH 460/682] Use uint64_t not unsigned for type sizes/offsets.
      
      llvm-svn: 63352
      ---
       clang/lib/CodeGen/CGCall.cpp | 22 +++++++++++-----------
       1 file changed, 11 insertions(+), 11 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index 77863fb091bc..65d70385f089 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -423,7 +423,7 @@ class X86_64ABIInfo : public ABIInfo {
         ///
         /// If the \arg Lo class is ComplexX87, then the \arg Hi class will
         /// be NoClass.
      -  void classify(QualType T, ASTContext &Context, unsigned OffsetBase,
      +  void classify(QualType T, ASTContext &Context, uint64_t OffsetBase,
                       Class &Lo, Class &Hi) const;
       
       public:
      @@ -437,7 +437,7 @@ public:
       
       void X86_64ABIInfo::classify(QualType Ty,
                                    ASTContext &Context,
      -                             unsigned OffsetBase,
      +                             uint64_t OffsetBase,
                                    Class &Lo, Class &Hi) const {
         Lo = Memory;
         Hi = NoClass;
      @@ -462,7 +462,7 @@ void X86_64ABIInfo::classify(QualType Ty,
                    Ty->isObjCQualifiedInterfaceType()) {
           Lo = Integer;
         } else if (const VectorType *VT = Ty->getAsVectorType()) {
      -    unsigned Size = Context.getTypeSize(VT);
      +    uint64_t Size = Context.getTypeSize(VT);
           if (Size == 64) {
             // FIXME: For some reason, gcc appears to be treating <1 x
             // double> as INTEGER; this seems wrong, but we will match for
      @@ -476,7 +476,7 @@ void X86_64ABIInfo::classify(QualType Ty,
           QualType ET = CT->getElementType();
           
           if (ET->isIntegerType()) {
      -      unsigned Size = Context.getTypeSize(Ty);
      +      uint64_t Size = Context.getTypeSize(Ty);
             if (Size <= 64)
               Lo = Integer;
             else if (Size <= 128)
      @@ -490,12 +490,12 @@ void X86_64ABIInfo::classify(QualType Ty,
       
           // If this complex type crosses an eightbyte boundary then it
           // should be split.
      -    unsigned EB_Real = (OffsetBase) >> 3;
      -    unsigned EB_Imag = (OffsetBase + Context.getTypeSize(ET)) >> 3;
      +    uint64_t EB_Real = (OffsetBase) >> 3;
      +    uint64_t EB_Imag = (OffsetBase + Context.getTypeSize(ET)) >> 3;
           if (Hi == NoClass && EB_Real != EB_Imag)
             Hi = Lo;
         } else if (const RecordType *RT = Ty->getAsRecordType()) {
      -    unsigned Size = Context.getTypeSize(Ty);
      +    uint64_t Size = Context.getTypeSize(Ty);
           
           // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
           // than two eightbytes, ..., it has class MEMORY.
      @@ -1080,8 +1080,8 @@ static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr,
                                             CodeGenFunction &CGF) {
         const llvm::Type *SrcTy = 
           cast(SrcPtr->getType())->getElementType();
      -  unsigned SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy);
      -  unsigned DstSize = CGF.CGM.getTargetData().getTypePaddedSize(Ty);
      +  uint64_t SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy);
      +  uint64_t DstSize = CGF.CGM.getTargetData().getTypePaddedSize(Ty);
       
         // If load is legal, just bitcase the src pointer.
         if (SrcSize == DstSize) {
      @@ -1113,8 +1113,8 @@ static void CreateCoercedStore(llvm::Value *Src,
         const llvm::Type *DstTy = 
           cast(DstPtr->getType())->getElementType();
       
      -  unsigned SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy);
      -  unsigned DstSize = CGF.CGM.getTargetData().getTypePaddedSize(DstTy);
      +  uint64_t SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy);
      +  uint64_t DstSize = CGF.CGM.getTargetData().getTypePaddedSize(DstTy);
       
         // If store is legal, just bitcase the src pointer.
         if (SrcSize == DstSize) {
      -- 
      GitLab
      
      
      From 199740651ce754663b3d488e0a25eada7153ebcc Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 01:03:10 +0000
      Subject: [PATCH 461/682] Add dump() routines to help debug debug info :)
      
      llvm-svn: 63353
      ---
       llvm/include/llvm/Analysis/DebugInfo.h |  27 +++++++
       llvm/lib/Analysis/DebugInfo.cpp        | 101 +++++++++++++++++++++++++
       2 files changed, 128 insertions(+)
      
      diff --git a/llvm/include/llvm/Analysis/DebugInfo.h b/llvm/include/llvm/Analysis/DebugInfo.h
      index 336d816bc144..310c1acf08fa 100644
      --- a/llvm/include/llvm/Analysis/DebugInfo.h
      +++ b/llvm/include/llvm/Analysis/DebugInfo.h
      @@ -114,6 +114,9 @@ namespace llvm {
       
           /// Verify - Verify that a compile unit is well formed.
           bool Verify() const;
      +
      +    /// dump - print compile unit.
      +    void dump() const;
         };
       
         /// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
      @@ -189,6 +192,9 @@ namespace llvm {
             assert (0 && "Invalid DIDescriptor");
             return "";
           }
      +
      +    /// dump - print type.
      +    void dump() const;
         };
       
         /// DIBasicType - A basic type, like 'int' or 'float'.
      @@ -199,6 +205,9 @@ namespace llvm {
           unsigned getEncoding() const { return getUnsignedField(9); }
           std::string getFilename() const { return getStringField(10); }
           std::string getDirectory() const { return getStringField(11); }
      +
      +    /// dump - print basic type.
      +    void dump() const;
         };
       
         /// DIDerivedType - A simple derived type, like a const qualified type,
      @@ -213,6 +222,9 @@ namespace llvm {
           DIType getTypeDerivedFrom() const { return getFieldAs(9); }
           std::string getFilename() const { return getStringField(10); }
           std::string getDirectory() const { return getStringField(11); }
      +
      +    /// dump - print derived type.
      +    void dump() const;
         };
       
         /// DICompositeType - This descriptor holds a type that can refer to multiple
      @@ -228,6 +240,9 @@ namespace llvm {
       
           /// Verify - Verify that a composite type descriptor is well formed.
           bool Verify() const;
      +
      +    /// dump - print composite type.
      +    void dump() const;
         };
       
         /// DIGlobal - This is a common class for global variables and subprograms.
      @@ -273,6 +288,9 @@ namespace llvm {
             assert (0 && "Invalid DIDescriptor");
             return "";
           }
      +    
      +    /// dump - print global.
      +    void dump() const;
         };
       
         /// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
      @@ -285,6 +303,9 @@ namespace llvm {
       
           /// Verify - Verify that a subprogram descriptor is well formed.
           bool Verify() const;
      +
      +    /// dump - print subprogram.
      +    void dump() const;
         };
       
         /// DIGlobalVariable - This is a wrapper for a global variable.
      @@ -298,6 +319,9 @@ namespace llvm {
       
           /// Verify - Verify that a global variable descriptor is well formed.
           bool Verify() const;
      +
      +    /// dump - print global variable.
      +    void dump() const;
         };
       
         /// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
      @@ -319,6 +343,9 @@ namespace llvm {
       
           /// Verify - Verify that a variable descriptor is well formed.
           bool Verify() const;
      +
      +    /// dump - print variable.
      +    void dump() const;
         };
       
         /// DIBlock - This is a wrapper for a block (e.g. a function, scope, etc).
      diff --git a/llvm/lib/Analysis/DebugInfo.cpp b/llvm/lib/Analysis/DebugInfo.cpp
      index 2f336572a1df..e5bbbd5aab09 100644
      --- a/llvm/lib/Analysis/DebugInfo.cpp
      +++ b/llvm/lib/Analysis/DebugInfo.cpp
      @@ -20,6 +20,7 @@
       #include "llvm/Instructions.h"
       #include "llvm/Module.h"
       #include "llvm/Analysis/ValueTracking.h"
      +#include "llvm/Support/Streams.h"
       using namespace llvm;
       
       //===----------------------------------------------------------------------===//
      @@ -870,3 +871,103 @@ namespace llvm {
         }
       }
       
      +/// dump - print compile unit.
      +void DICompileUnit::dump() const {
      +  cerr << " [" << dwarf::LanguageString(getLanguage()) << "] ";
      +  cerr << " [" << getDirectory() << "/" << getFilename() << " ]";
      +}
      +
      +/// dump - print type.
      +void DIType::dump() const {
      +  if (isNull()) return;
      +  if (!getName().empty())
      +    cerr << " [" << getName() << "] ";
      +  unsigned Tag = getTag();
      +  cerr << " [" << dwarf::TagString(Tag) << "] ";
      +  // TODO : Print context
      +  getCompileUnit().dump();
      +  cerr << " [" 
      +       << getLineNumber() << ", " 
      +       << getSizeInBits() << ", "
      +       << getAlignInBits() << ", "
      +       << getOffsetInBits() 
      +       << "] ";
      +  if (isPrivate()) 
      +    cerr << " [private] ";
      +  else if (isProtected())
      +    cerr << " [protected] ";
      +  if (isForwardDecl())
      +    cerr << " [fwd] ";
      +
      +  if (isBasicType(Tag))
      +    DIBasicType(GV).dump();
      +  else if (isDerivedType(Tag))
      +    DIDerivedType(GV).dump();
      +  else if (isCompositeType(Tag))
      +    DICompositeType(GV).dump();
      +  else {
      +    cerr << "Invalid DIType\n";
      +    return;
      +  }
      +  cerr << "\n";
      +}
      +
      +/// dump - print basic type.
      +void DIBasicType::dump() const {
      +  cerr << " [" << dwarf::AttributeEncodingString(getEncoding()) << "] ";
      +
      +}
      +
      +/// dump - print derived type.
      +void DIDerivedType::dump() const {
      +  cerr << "\n\t Derived From: "; getTypeDerivedFrom().dump();
      +}
      +
      +/// dump - print composite type.
      +void DICompositeType::dump() const {
      +  DIArray A = getTypeArray();
      +  if (A.isNull())
      +    return;
      +  cerr << " [" << A.getNumElements() << " elements]";
      +}
      +
      +/// dump - print global.
      +void DIGlobal::dump() const {
      +
      +  if (!getName().empty())
      +    cerr << " [" << getName() << "] ";
      +  unsigned Tag = getTag();
      +  cerr << " [" << dwarf::TagString(Tag) << "] ";
      +  // TODO : Print context
      +  getCompileUnit().dump();
      +  cerr << " [" << getLineNumber() << "] ";
      +  if (isLocalToUnit())
      +    cerr << " [local] ";
      +  if (isDefinition())
      +    cerr << " [def] ";
      +
      +  if (isGlobalVariable(Tag))
      +    DIGlobalVariable(GV).dump();
      +
      +  cerr << "\n";
      +}
      +
      +/// dump - print subprogram.
      +void DISubprogram::dump() const {
      +  DIGlobal::dump();
      +}
      +
      +/// dump - print global variable.
      +void DIGlobalVariable::dump() const {
      +  cerr << " ["; getGlobal()->dump(); cerr << "] ";
      +}
      +
      +/// dump - print variable.
      +void DIVariable::dump() const {
      +  if (!getName().empty())
      +    cerr << " [" << getName() << "] ";
      +  getCompileUnit().dump();
      +  cerr << " [" << getLineNumber() << "] ";
      +  getType().dump();
      +  cerr << "\n";
      +}
      -- 
      GitLab
      
      
      From ed8f2887082bbc5c696e7a71217482f9089ce0c2 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Fri, 30 Jan 2009 01:04:22 +0000
      Subject: [PATCH 462/682] Eliminated LookupCriteria, whose creation was causing
       a bottleneck for LookupName et al. Instead, use an enum and a bool to
       describe its contents.
      
      Optimized the C/Objective-C path through LookupName, eliminating any
      unnecessarily C++isms. Simplify IdentifierResolver::iterator, removing
      some code and arguments that are no longer used.
      
      Eliminated LookupDeclInScope/LookupDeclInContext, moving all callers
      over to LookupName, LookupQualifiedName, or LookupParsedName, as
      appropriate.
      
      All together, I'm seeing a 0.2% speedup on Cocoa.h with PTH and
      -disable-free. Plus, we're down to three name-lookup routines.
      
      llvm-svn: 63354
      ---
       clang/lib/Sema/IdentifierResolver.cpp |  26 +---
       clang/lib/Sema/IdentifierResolver.h   |  36 +++--
       clang/lib/Sema/Sema.h                 | 121 +++++++---------
       clang/lib/Sema/SemaCXXScopeSpec.cpp   |  10 +-
       clang/lib/Sema/SemaDecl.cpp           | 175 +++--------------------
       clang/lib/Sema/SemaDeclCXX.cpp        |  15 +-
       clang/lib/Sema/SemaDeclObjC.cpp       |  16 +--
       clang/lib/Sema/SemaExpr.cpp           |  21 +--
       clang/lib/Sema/SemaExprCXX.cpp        |   4 +-
       clang/lib/Sema/SemaExprObjC.cpp       |   6 +-
       clang/lib/Sema/SemaInherit.cpp        |   3 +-
       clang/lib/Sema/SemaInherit.h          |  10 +-
       clang/lib/Sema/SemaLookup.cpp         | 196 ++++++++++++--------------
       clang/lib/Sema/SemaOverload.cpp       |   5 +-
       clang/lib/Sema/SemaTemplate.cpp       |   8 +-
       15 files changed, 222 insertions(+), 430 deletions(-)
      
      diff --git a/clang/lib/Sema/IdentifierResolver.cpp b/clang/lib/Sema/IdentifierResolver.cpp
      index 4e9d085a75b2..781d89a0e99a 100644
      --- a/clang/lib/Sema/IdentifierResolver.cpp
      +++ b/clang/lib/Sema/IdentifierResolver.cpp
      @@ -225,14 +225,9 @@ void IdentifierResolver::RemoveDecl(NamedDecl *D) {
         return toIdDeclInfo(Ptr)->RemoveDecl(D);
       }
       
      -/// begin - Returns an iterator for decls with name 'Name', starting at
      -/// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
      -/// decls of parent declaration contexts too.
      +/// begin - Returns an iterator for decls with name 'Name'.
       IdentifierResolver::iterator
      -IdentifierResolver::begin(DeclarationName Name, const DeclContext *Ctx,
      -                          bool LookInParentCtx) {
      -  assert(Ctx && "null param passed");
      -
      +IdentifierResolver::begin(DeclarationName Name) {
         void *Ptr = Name.getFETokenInfo();
         if (!Ptr) return end();
       
      @@ -245,26 +240,11 @@ IdentifierResolver::begin(DeclarationName Name, const DeclContext *Ctx,
       
         IdDeclInfo::DeclsTy::iterator I = IDI->decls_end();
         if (I != IDI->decls_begin())
      -    return iterator(I-1, LookInParentCtx);
      +    return iterator(I-1);
         else // No decls found.
           return end();
       }
       
      -/// PreIncIter - Do a preincrement when 'Ptr' is a BaseIter.
      -void IdentifierResolver::iterator::PreIncIter() {
      -  NamedDecl *D = **this;
      -  void *InfoPtr = D->getDeclName().getFETokenInfo();
      -  assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
      -  IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
      -
      -  BaseIter I = getIterator();
      -  if (I != Info->decls_begin())
      -    *this = iterator(I-1, LookInParentCtx());
      -  else // No more decls.
      -    *this = end();
      -}
      -
      -
       //===----------------------------------------------------------------------===//
       // IdDeclInfoMap Implementation
       //===----------------------------------------------------------------------===//
      diff --git a/clang/lib/Sema/IdentifierResolver.h b/clang/lib/Sema/IdentifierResolver.h
      index a44323e1b0da..50b894a7259f 100644
      --- a/clang/lib/Sema/IdentifierResolver.h
      +++ b/clang/lib/Sema/IdentifierResolver.h
      @@ -136,19 +136,12 @@ public:
           }
           /// A IdDeclInfo::DeclsTy::iterator that walks or not the parent declaration
           /// contexts depending on 'LookInParentCtx'.
      -    iterator(BaseIter I, bool LookInParentCtx) {
      +    iterator(BaseIter I) {
             Ptr = reinterpret_cast(I) | 0x1;
      -      assert((Ptr & 0x2) == 0 && "Invalid Ptr!");
      -      if (LookInParentCtx) Ptr |= 0x2;
           }
       
           bool isIterator() const { return (Ptr & 0x1); }
       
      -    bool LookInParentCtx() const {
      -      assert(isIterator() && "Ptr not an iterator!");
      -      return (Ptr & 0x2) != 0;
      -    }
      -
           BaseIter getIterator() const {
             assert(isIterator() && "Ptr not an iterator!");
             return reinterpret_cast(Ptr & ~0x3);
      @@ -176,29 +169,32 @@ public:
           iterator& operator++() {
             if (!isIterator()) // common case.
               Ptr = 0;
      -      else
      -        PreIncIter();
      +      else {
      +        NamedDecl *D = **this;
      +        void *InfoPtr = D->getDeclName().getFETokenInfo();
      +        assert(!isDeclPtr(InfoPtr) && "Decl with wrong id ?");
      +        IdDeclInfo *Info = toIdDeclInfo(InfoPtr);
      +        
      +        BaseIter I = getIterator();
      +        if (I != Info->decls_begin())
      +          *this = iterator(I-1);
      +        else // No more decls.
      +          *this = iterator();
      +      }
             return *this;
           }
       
           uintptr_t getAsOpaqueValue() const { return Ptr; }
           
           static iterator getFromOpaqueValue(uintptr_t P) {
      -      iterator Result(0);
      +      iterator Result;
             Result.Ptr = P;
             return Result;
           }
      -    
      -  private:
      -    void PreIncIter();
         };
       
      -  /// begin - Returns an iterator for decls with the name 'Name', starting at
      -  /// declaration context 'Ctx'. If 'LookInParentCtx' is true, it will walk the
      -  /// decls of parent declaration contexts too.
      -  /// Default for 'LookInParentCtx is true.
      -  static iterator begin(DeclarationName Name, const DeclContext *Ctx,
      -                        bool LookInParentCtx = true);
      +  /// begin - Returns an iterator for decls with the name 'Name'.
      +  static iterator begin(DeclarationName Name);
       
         /// end - Returns an iterator that has 'finished'.
         static iterator end() {
      diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h
      index fe2b9de79e10..6e3a55268644 100644
      --- a/clang/lib/Sema/Sema.h
      +++ b/clang/lib/Sema/Sema.h
      @@ -559,7 +559,7 @@ public:
         /// for capturing language semantics (certain lookups will ignore
         /// certain names, for example) and for performance, since name
         /// lookup is often a bottleneck in the compilation of C++. Name
      -  /// lookup criteria is specified via the LookupCriteria class.
      +  /// lookup criteria is specified via the LookupCriteria enumeration.
         ///
         /// The results of name lookup can vary based on the kind of name
         /// lookup performed, the current language, and the translation
      @@ -571,65 +571,26 @@ public:
         /// the ability to distinguish among them.
         //@{
       
      -  /// @brief Describes the criteria by which name lookup will
      -  /// determine whether a given name will be found.
      -  ///
      -  /// The LookupCriteria class captures the information required to
      -  /// direct name lookup to find the appropriate kind of name. It
      -  /// includes information about which kinds of names to consider
      -  /// (ordinary names, tag names, class/struct/union member names,
      -  /// namespace names, etc.) and where to look for those
      -  /// names. LookupCriteria is used throughout semantic analysis to
      -  /// specify how to search for a name, e.g., with the LookupName and
      -  /// LookupQualifiedName functions.
      -  struct LookupCriteria {
      -    /// NameKind - The kinds of names that we are looking for. 
      -    enum NameKind {
      -      /// Ordinary - Ordinary name lookup, which finds ordinary names
      -      /// (functions, variables, typedefs, etc.) in C and most kinds
      -      /// of names (functions, variables, members, types, etc.) in
      -      /// C++.
      -      Ordinary,
      -      /// Tag - Tag name lookup, which finds the names of enums,
      -      /// classes, structs, and unions.
      -      Tag,
      -      /// Member - Member name lookup, which finds the names of
      -      /// class/struct/union members.
      -      Member,
      -      /// NestedNameSpecifier - Look up of a name that precedes the
      -      /// '::' scope resolution operator in C++. This lookup
      -      /// completely ignores operator, function, and enumerator names
      -      /// (C++ [basic.lookup.qual]p1).
      -      NestedNameSpecifier,
      -      /// Namespace - Look up a namespace name within a C++
      -      /// using directive or namespace alias definition, ignoring
      -      /// non-namespace names (C++ [basic.lookup.udir]p1).
      -      Namespace
      -    } Kind;
      -
      -    /// AllowLazyBuiltinCreation - If true, permits name lookup to
      -    /// lazily build declarations for built-in names, e.g.,
      -    /// __builtin_expect.
      -    bool AllowLazyBuiltinCreation;
      -
      -    /// RedeclarationOnly - If true, the lookup will only
      -    /// consider entities within the scope where the lookup
      -    /// began. Entities that might otherwise meet the lookup criteria
      -    /// but are not within the original lookup scope will be ignored.
      -    bool RedeclarationOnly;
      -
      -    /// IDNS - Bitwise OR of the appropriate Decl::IDNS_* flags that
      -    /// describe the namespaces where we should look for names. This
      -    /// field is determined by the kind of name we're searching for.
      -    unsigned IDNS;
      -
      -    LookupCriteria() 
      -      : Kind(Ordinary), AllowLazyBuiltinCreation(true), 
      -        RedeclarationOnly(false), IDNS(Decl::IDNS_Ordinary) { }
      -
      -    LookupCriteria(NameKind K, bool RedeclarationOnly, bool CPlusPlus);
      -    
      -    bool isLookupResult(Decl *D) const;
      +  /// @brief Describes the kind of name lookup to perform.
      +  enum LookupNameKind {
      +    /// Ordinary name lookup, which finds ordinary names (functions,
      +    /// variables, typedefs, etc.) in C and most kinds of names
      +    /// (functions, variables, members, types, etc.) in C++.
      +    LookupOrdinaryName = 0,
      +    /// Tag name lookup, which finds the names of enums, classes,
      +    /// structs, and unions.
      +    LookupTagName,
      +    /// Member name lookup, which finds the names of
      +    /// class/struct/union members.
      +    LookupMemberName,
      +    /// Look up of a name that precedes the '::' scope resolution
      +    /// operator in C++. This lookup completely ignores operator,
      +    /// function, and enumerator names (C++ [basic.lookup.qual]p1).
      +    LookupNestedNameSpecifierName,
      +    /// Look up a namespace name within a C++ using directive or
      +    /// namespace alias definition, ignoring non-namespace names (C++
      +    /// [basic.lookup.udir]p1).
      +    LookupNamespaceName
         };
       
         /// @brief Represents the results of name lookup.
      @@ -775,18 +736,38 @@ public:
           BasePaths *getBasePaths() const;
         };
       
      +  /// Determines whether D is a suitable lookup result according to the
      +  /// lookup criteria.
      +  bool isAcceptableLookupResult(Decl *D, LookupNameKind NameKind,
      +                                unsigned IDNS) const {
      +    switch (NameKind) {
      +    case Sema::LookupOrdinaryName:
      +    case Sema::LookupTagName:
      +    case Sema::LookupMemberName:
      +      return D->isInIdentifierNamespace(IDNS);
      +      
      +    case Sema::LookupNestedNameSpecifierName:
      +      return isa(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
      +      
      +    case Sema::LookupNamespaceName:
      +      return isa(D);
      +    }
      +    
      +    assert(false && 
      +           "isNameAcceptableLookupResult always returns before this point");
      +    return false;
      +  }
      +
         LookupResult LookupName(Scope *S, DeclarationName Name, 
      -                          LookupCriteria Criteria);
      +                          LookupNameKind NameKind, 
      +                          bool RedeclarationOnly = false);
         LookupResult LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
      -                                   LookupCriteria Criteria);
      -  LookupResult LookupParsedName(Scope *S, const CXXScopeSpec &SS, 
      -                                DeclarationName Name, LookupCriteria Criteria);
      -  LookupResult LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
      -                          bool LookInParent = true);
      -  LookupResult LookupDeclInContext(DeclarationName Name, unsigned NSI,
      -                          const DeclContext *LookupCtx,
      -                          bool LookInParent = true);
      -
      +                                   LookupNameKind NameKind, 
      +                                   bool RedeclarationOnly = false);
      +  LookupResult LookupParsedName(Scope *S, const CXXScopeSpec *SS, 
      +                                DeclarationName Name,
      +                                LookupNameKind NameKind, 
      +                                bool RedeclarationOnly = false);
         bool DiagnoseAmbiguousLookup(LookupResult &Result, DeclarationName Name,
                                      SourceLocation NameLoc, 
                                      SourceRange LookupRange = SourceRange());
      diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
      index cf93571eb231..c77325f42d87 100644
      --- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
      +++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
      @@ -36,10 +36,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
                                                           SourceLocation IdLoc,
                                                           SourceLocation CCLoc,
                                                           IdentifierInfo &II) {
      -  Decl *SD = LookupParsedName(S, SS, &II,
      -                              LookupCriteria(LookupCriteria::NestedNameSpecifier, 
      -                                             /*RedeclarationOnly=*/false, 
      -                                             /*CPlusPlus=*/true));
      +  Decl *SD = LookupParsedName(S, &SS, &II, LookupNestedNameSpecifierName);
       
         if (SD) {
           if (TypedefDecl *TD = dyn_cast(SD)) {
      @@ -60,10 +57,7 @@ Sema::CXXScopeTy *Sema::ActOnCXXNestedNameSpecifier(Scope *S,
         // ordinary name lookup, which can help us produce better error
         // messages.
         if (!SD)
      -    SD = LookupParsedName(S, SS, &II,
      -                          LookupCriteria(LookupCriteria::Ordinary,
      -                                         /*RedeclarationOnly=*/false, 
      -                                         /*CPlusPlus=*/true));
      +    SD = LookupParsedName(S, &SS, &II, LookupOrdinaryName);
         unsigned DiagID;
         if (SD)
           DiagID = diag::err_expected_class_or_namespace;
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index cf71d394ce97..ad6a7197718d 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -32,18 +32,8 @@ using namespace clang;
       
       Sema::TypeTy *Sema::getTypeName(IdentifierInfo &II, Scope *S,
                                       const CXXScopeSpec *SS) {
      -  DeclContext *DC = 0;
      -  
      -  if (SS) {
      -    if (SS->isInvalid())
      -      return 0;
      -    DC = static_cast(SS->getScopeRep());
      -  }
         Decl *IIDecl = 0;
      -  
      -  LookupResult Result =  DC ? LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC) :
      -                              LookupDeclInScope(&II, Decl::IDNS_Ordinary, S);
      -                 
      +  LookupResult Result = LookupParsedName(S, SS, &II, LookupOrdinaryName, false);
         switch (Result.getKind()) {
           case LookupResult::NotFound:
           case LookupResult::FoundOverloaded:
      @@ -139,8 +129,7 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
             // We're pushing the tag into the current context, which might
             // require some reshuffling in the identifier resolver.
             IdentifierResolver::iterator
      -        I = IdResolver.begin(TD->getDeclName(), CurContext, 
      -                             false/*LookInParentCtx*/),
      +        I = IdResolver.begin(TD->getDeclName()),
               IEnd = IdResolver.end();
             if (I != IEnd && isDeclInScope(*I, CurContext, S)) {
               NamedDecl *PrevDecl = *I;
      @@ -175,10 +164,8 @@ void Sema::PushOnScopeChains(NamedDecl *D, Scope *S) {
           // We are pushing the name of a function, which might be an
           // overloaded name.
           FunctionDecl *FD = cast(D);
      -    DeclContext *DC = FD->getDeclContext()->getLookupContext();
           IdentifierResolver::iterator Redecl
      -      = std::find_if(IdResolver.begin(FD->getDeclName(), DC, 
      -                                      false/*LookInParentCtx*/),
      +      = std::find_if(IdResolver.begin(FD->getDeclName()),
                            IdResolver.end(),
                            std::bind1st(std::mem_fun(&NamedDecl::declarationReplaces),
                                         FD));
      @@ -218,7 +205,7 @@ void Sema::ActOnPopScope(SourceLocation Loc, Scope *S) {
       ObjCInterfaceDecl *Sema::getObjCInterfaceDecl(IdentifierInfo *Id) {
         // The third "scope" argument is 0 since we aren't enabling lazy built-in
         // creation from this context.
      -  Decl *IDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, 0);
      +  Decl *IDecl = LookupName(TUScope, Id, LookupOrdinaryName);
         
         return dyn_cast_or_null(IDecl);
       }
      @@ -255,123 +242,12 @@ Scope *Sema::getNonFieldDeclScope(Scope *S) {
         return S;
       }
       
      -/// LookupDeclInScope - Look up the inner-most declaration in the specified
      -/// namespace. NamespaceNameOnly - during lookup only namespace names
      -/// are considered as required in C++ [basic.lookup.udir] 3.4.6.p1
      -/// 'When looking up a namespace-name in a using-directive or
      -/// namespace-alias-definition, only namespace names are considered.'
      -///
      -/// Note: The use of this routine is deprecated. Please use
      -/// LookupName, LookupQualifiedName, or LookupParsedName instead.
      -Sema::LookupResult
      -Sema::LookupDeclInScope(DeclarationName Name, unsigned NSI, Scope *S,
      -                        bool LookInParent) {
      -  if (getLangOptions().CPlusPlus) {
      -    LookupCriteria::NameKind Kind;
      -    if (NSI == Decl::IDNS_Ordinary) {
      -      Kind = LookupCriteria::Ordinary;
      -    } else if (NSI == Decl::IDNS_Tag) 
      -      Kind = LookupCriteria::Tag;
      -    else {
      -      assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
      -      Kind = LookupCriteria::Member;
      -    }
      -    // Unqualified lookup
      -    return LookupName(S, Name, 
      -                      LookupCriteria(Kind, !LookInParent,
      -                                     getLangOptions().CPlusPlus));
      -  }
      -  // Fast path for C/ObjC.
      -  
      -  // Unqualified name lookup in C/Objective-C is purely lexical, so
      -  // search in the declarations attached to the name.
      -
      -  // For the purposes of unqualified name lookup, structs and unions
      -  // don't have scopes at all. For example:
      -  //
      -  //   struct X {
      -  //     struct T { int i; } x;
      -  //   };
      -  //
      -  //   void f() {
      -  //     struct T t; // okay: T is defined lexically within X, but
      -  //                 // semantically at global scope
      -  //   };
      -  //
      -  // FIXME: Is there a better way to deal with this?
      -  DeclContext *SearchCtx = CurContext;
      -  while (isa(SearchCtx) || isa(SearchCtx))
      -    SearchCtx = SearchCtx->getParent();
      -  IdentifierResolver::iterator I
      -    = IdResolver.begin(Name, SearchCtx, LookInParent);
      -  
      -  // Scan up the scope chain looking for a decl that matches this
      -  // identifier that is in the appropriate namespace.  This search
      -  // should not take long, as shadowing of names is uncommon, and
      -  // deep shadowing is extremely uncommon.
      -  for (; I != IdResolver.end(); ++I) {
      -    switch (NSI) {
      -      case Decl::IDNS_Ordinary:
      -      case Decl::IDNS_Tag:
      -      case Decl::IDNS_Member:
      -        if ((*I)->isInIdentifierNamespace(NSI))
      -          return LookupResult::CreateLookupResult(Context, *I);
      -        break;
      -      default:
      -        assert(0 && "Unable to grok LookupDecl NSI argument");
      -    }
      -  }
      -  if (NSI == Decl::IDNS_Ordinary) {
      -    IdentifierInfo *II = Name.getAsIdentifierInfo();
      -    if (II) {
      -      // If this is a builtin on this (or all) targets, create the decl.
      -      if (unsigned BuiltinID = II->getBuiltinID())
      -        return LookupResult::CreateLookupResult(Context,
      -                            LazilyCreateBuiltin((IdentifierInfo *)II, BuiltinID,
      -                                                S));
      -    }
      -    if (getLangOptions().ObjC1 && II) {
      -      // @interface and @compatibility_alias introduce typedef-like names.
      -      // Unlike typedef's, they can only be introduced at file-scope (and are 
      -      // therefore not scoped decls). They can, however, be shadowed by
      -      // other names in IDNS_Ordinary.
      -      ObjCInterfaceDeclsTy::iterator IDI = ObjCInterfaceDecls.find(II);
      -      if (IDI != ObjCInterfaceDecls.end())
      -        return LookupResult::CreateLookupResult(Context, IDI->second);
      -      ObjCAliasTy::iterator I = ObjCAliasDecls.find(II);
      -      if (I != ObjCAliasDecls.end())
      -        return LookupResult::CreateLookupResult(Context, 
      -                                                I->second->getClassInterface());
      -    }
      -  }
      -  return LookupResult::CreateLookupResult(Context, 0);
      -}
      -
      -Sema::LookupResult
      -Sema::LookupDeclInContext(DeclarationName Name, unsigned NSI,
      -                          const DeclContext *LookupCtx,
      -                          bool LookInParent) {
      -  assert(LookupCtx && "LookupDeclInContext(): Missing DeclContext");
      -  LookupCriteria::NameKind Kind;
      -  if (NSI == Decl::IDNS_Ordinary) {
      -    Kind = LookupCriteria::Ordinary;
      -  } else if (NSI == Decl::IDNS_Tag) 
      -    Kind = LookupCriteria::Tag;
      -  else {
      -    assert(NSI == Decl::IDNS_Member &&"Unable to grok LookupDecl NSI argument");
      -    Kind = LookupCriteria::Member;
      -  }
      -  return LookupQualifiedName(const_cast(LookupCtx), Name, 
      -                             LookupCriteria(Kind, !LookInParent,
      -                                            getLangOptions().CPlusPlus));
      -}
      -
       void Sema::InitBuiltinVaListType() {
         if (!Context.getBuiltinVaListType().isNull())
           return;
         
         IdentifierInfo *VaIdent = &Context.Idents.get("__builtin_va_list");
      -  Decl *VaDecl = LookupDeclInScope(VaIdent, Decl::IDNS_Ordinary, TUScope);
      +  Decl *VaDecl = LookupName(TUScope, VaIdent, LookupOrdinaryName);
         TypedefDecl *VaTypedef = cast(VaDecl);
         Context.setBuiltinVaListType(Context.getTypedefType(VaTypedef));
       }
      @@ -420,7 +296,7 @@ NamespaceDecl *Sema::GetStdNamespace() {
         if (!StdNamespace) {
           IdentifierInfo *StdIdent = &PP.getIdentifierTable().get("std");
           DeclContext *Global = Context.getTranslationUnitDecl();
      -    Decl *Std = LookupDeclInContext(StdIdent, Decl::IDNS_Ordinary, Global);
      +    Decl *Std = LookupQualifiedName(Global, StdIdent, LookupNamespaceName);
           StdNamespace = dyn_cast_or_null(Std);
         }
         return StdNamespace;
      @@ -689,10 +565,9 @@ void Sema::CheckForFileScopedRedefinitions(Scope *S, VarDecl *VD) {
         
         // FIXME: I don't think this will actually see all of the
         // redefinitions. Can't we check this property on-the-fly?
      -  for (IdentifierResolver::iterator
      -       I = IdResolver.begin(VD->getIdentifier(), 
      -                            VD->getDeclContext(), false/*LookInParentCtx*/), 
      -       E = IdResolver.end(); I != E; ++I) {
      +  for (IdentifierResolver::iterator I = IdResolver.begin(VD->getIdentifier()), 
      +                                    E = IdResolver.end(); 
      +       I != E; ++I) {
           if (*I != VD && isDeclInScope(*I, VD->getDeclContext(), S)) {
             VarDecl *OldDecl = dyn_cast(*I);
             
      @@ -864,8 +739,8 @@ bool Sema::InjectAnonymousStructOrUnionMembers(Scope *S, DeclContext *Owner,
                                      FEnd = AnonRecord->field_end();
              F != FEnd; ++F) {
           if ((*F)->getDeclName()) {
      -      Decl *PrevDecl = LookupDeclInContext((*F)->getDeclName(), 
      -                         Decl::IDNS_Ordinary, Owner, false);
      +      Decl *PrevDecl = LookupQualifiedName(Owner, (*F)->getDeclName(),
      +                                           LookupOrdinaryName, true);
             if (PrevDecl && !isa(PrevDecl)) {
               // C++ [class.union]p2:
               //   The names of the members of an anonymous union shall be
      @@ -1312,13 +1187,12 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl,
         bool InvalidDecl = false;
        
         // See if this is a redefinition of a variable in the same scope.
      -  if (!D.getCXXScopeSpec().isSet()) {
      +  if (!D.getCXXScopeSpec().isSet() && !D.getCXXScopeSpec().isInvalid()) {
           DC = CurContext;
      -    PrevDecl = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
      +    PrevDecl = LookupName(S, Name, LookupOrdinaryName);
         } else { // Something like "int foo::x;"
           DC = static_cast(D.getCXXScopeSpec().getScopeRep());
      -    PrevDecl = DC ? LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC)
      -                  : LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
      +    PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName);
       
           // C++ 7.3.1.2p2:
           // Members (including explicit specializations of templates) of a named
      @@ -1807,7 +1681,7 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC,
               << D.getCXXScopeSpec().getRange();
             InvalidDecl = true;
               
      -      PrevDecl = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC);
      +      PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName);
             if (!PrevDecl) {
               // Nothing to suggest.
             } else if (OverloadedFunctionDecl *Ovl 
      @@ -2662,7 +2536,7 @@ Sema::ActOnParamDeclarator(Scope *S, Declarator &D) {
         // among each other.  Here they can only shadow globals, which is ok.
         IdentifierInfo *II = D.getIdentifier();
         if (II) {
      -    if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) {
      +    if (Decl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
             if (PrevDecl->isTemplateParameter()) {
               // Maybe we will complain about the shadowed template parameter.
               DiagnoseTemplateParameterShadow(D.getIdentifierLoc(), PrevDecl);
      @@ -2954,7 +2828,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
           DC = static_cast(SS.getScopeRep());
           // Look-up name inside 'foo::'.
           PrevDecl = dyn_cast_or_null(
      -                 LookupDeclInContext(Name, Decl::IDNS_Tag, DC).getAsDecl());
      +                     LookupQualifiedName(DC, Name, LookupTagName).getAsDecl());
       
           // A tag 'foo::bar' must already exist.
           if (PrevDecl == 0) {
      @@ -2965,14 +2839,14 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK,
         } else if (Name) {
           // If this is a named struct, check to see if there was a previous forward
           // declaration or definition.
      -    Decl *D = LookupDeclInScope(Name, Decl::IDNS_Tag, S);
      +    Decl *D = LookupName(S, Name, LookupTagName);
           PrevDecl = dyn_cast_or_null(D);
       
           if (!getLangOptions().CPlusPlus && TK != TK_Reference) {
             // FIXME: This makes sure that we ignore the contexts associated
             // with C structs, unions, and enums when looking for a matching
             // tag declaration or definition. See the similar lookup tweak
      -      // in Sema::LookupDecl; is there a better way to deal with this?
      +      // in Sema::LookupName; is there a better way to deal with this?
             while (isa(SearchDC) || isa(SearchDC))
               SearchDC = SearchDC->getParent();
           }
      @@ -3158,9 +3032,7 @@ CreateNewDecl:
           //   shall not be declared with the same name as a typedef-name
           //   that is declared in that scope and refers to a type other
           //   than the class or enumeration itself.
      -    LookupResult Lookup = LookupName(S, Name, 
      -                                     LookupCriteria(LookupCriteria::Ordinary, 
      -                                                    true, true));
      +    LookupResult Lookup = LookupName(S, Name, LookupOrdinaryName, true);
           TypedefDecl *PrevTypedef = 0;
           if (Lookup.getKind() == LookupResult::Found)
             PrevTypedef = dyn_cast(Lookup.getAsDecl());
      @@ -3352,8 +3224,7 @@ Sema::DeclTy *Sema::ActOnField(Scope *S, DeclTy *TagD,
                                     DeclSpec::SCS_mutable);
       
         if (II) {
      -    Decl *PrevDecl 
      -      = LookupDeclInScope(II, Decl::IDNS_Member, S, false);
      +    Decl *PrevDecl = LookupName(S, II, LookupMemberName, true);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      @@ -3445,7 +3316,7 @@ Sema::DeclTy *Sema::ActOnIvar(Scope *S,
                                                    (Expr *)BitfieldWidth);
         
         if (II) {
      -    Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Member, S, false);
      +    Decl *PrevDecl = LookupName(S, II, LookupMemberName, true);
           if (PrevDecl && isDeclInScope(PrevDecl, CurContext, S)
               && !isa(PrevDecl)) {
             Diag(Loc, diag::err_duplicate_member) << II;
      @@ -3621,7 +3492,7 @@ Sema::DeclTy *Sema::ActOnEnumConstant(Scope *S, DeclTy *theEnumDecl,
         
         // Verify that there isn't already something declared with this name in this
         // scope.
      -  Decl *PrevDecl = LookupDeclInScope(Id, Decl::IDNS_Ordinary, S);
      +  Decl *PrevDecl = LookupName(S, Id, LookupOrdinaryName);
         if (PrevDecl && PrevDecl->isTemplateParameter()) {
           // Maybe we will complain about the shadowed template parameter.
           DiagnoseTemplateParameterShadow(IdLoc, PrevDecl);
      diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
      index 1870a8fdd39b..24f753164d90 100644
      --- a/clang/lib/Sema/SemaDeclCXX.cpp
      +++ b/clang/lib/Sema/SemaDeclCXX.cpp
      @@ -1375,8 +1375,8 @@ Sema::DeclTy *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
           // original-namespace-definition is the name of the namespace. Subsequently
           // in that declarative region, it is treated as an original-namespace-name.
       
      -    Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, DeclRegionScope, 
      -                                       /*LookupInParent=*/false);
      +    Decl *PrevDecl = LookupName(DeclRegionScope, II, LookupOrdinaryName,
      +                                true);
           
           if (NamespaceDecl *OrigNS = dyn_cast_or_null(PrevDecl)) {
             // This is an extended namespace definition.
      @@ -1437,14 +1437,7 @@ Sema::DeclTy *Sema::ActOnUsingDirective(Scope *S,
         // FIXME: This still requires lot more checks, and AST support.
       
         // Lookup namespace name.
      -  LookupCriteria Criteria(LookupCriteria::Namespace, /*RedeclarationOnly=*/false, 
      -                          /*CPlusPlus=*/true);
      -  Decl *NS = 0;
      -  if (SS.isSet())
      -    NS = LookupQualifiedName(static_cast(SS.getScopeRep()), 
      -                             NamespcName, Criteria);
      -  else
      -    NS = LookupName(S, NamespcName, Criteria);
      +  Decl *NS = LookupParsedName(S, &SS, NamespcName, LookupNamespaceName, false);
       
         if (NS) {
           assert(isa(NS) && "expected namespace decl");
      @@ -2179,7 +2172,7 @@ Sema::DeclTy *Sema::ActOnExceptionDeclarator(Scope *S, Declarator &D)
         // FIXME: Need to check for abstract classes.
       
         IdentifierInfo *II = D.getIdentifier();
      -  if (Decl *PrevDecl = LookupDeclInScope(II, Decl::IDNS_Ordinary, S)) {
      +  if (Decl *PrevDecl = LookupName(S, II, LookupOrdinaryName)) {
           // The scope should be freshly made just for us. There is just no way
           // it contains any previous declaration.
           assert(!S->isDeclScope(PrevDecl));
      diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
      index 3371e3ea6e20..c3519f8f010e 100644
      --- a/clang/lib/Sema/SemaDeclObjC.cpp
      +++ b/clang/lib/Sema/SemaDeclObjC.cpp
      @@ -64,7 +64,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
         assert(ClassName && "Missing class identifier");
         
         // Check for another declaration kind with the same name.
      -  Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
         if (PrevDecl && PrevDecl->isTemplateParameter()) {
           // Maybe we will complain about the shadowed template parameter.
           DiagnoseTemplateParameterShadow(ClassLoc, PrevDecl);
      @@ -107,7 +107,7 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc,
         if (SuperName) {
           ObjCInterfaceDecl* SuperClassEntry = 0;
           // Check if a different kind of symbol declared in this scope.
      -    PrevDecl = LookupDeclInScope(SuperName, Decl::IDNS_Ordinary, TUScope);
      +    PrevDecl = LookupName(TUScope, SuperName, LookupOrdinaryName);
           if (PrevDecl && !isa(PrevDecl)) {
             Diag(SuperLoc, diag::err_redefinition_different_kind) << SuperName;
             Diag(PrevDecl->getLocation(), diag::note_previous_definition);
      @@ -149,7 +149,7 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
                                                  IdentifierInfo *ClassName,
                                                  SourceLocation ClassLocation) {
         // Look for previous declaration of alias name
      -  Decl *ADecl = LookupDeclInScope(AliasName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *ADecl = LookupName(TUScope, AliasName, LookupOrdinaryName);
         if (ADecl) {
           if (isa(ADecl))
             Diag(AliasLocation, diag::warn_previous_alias_decl);
      @@ -159,13 +159,13 @@ Sema::DeclTy *Sema::ActOnCompatiblityAlias(SourceLocation AtLoc,
           return 0;
         }
         // Check for class declaration
      -  Decl *CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
         if (const TypedefDecl *TDecl = dyn_cast_or_null(CDeclU)) {
           QualType T = TDecl->getUnderlyingType();
           if (T->isObjCInterfaceType()) {
             if (NamedDecl *IDecl = T->getAsObjCInterfaceType()->getDecl()) {
               ClassName = IDecl->getIdentifier();
      -        CDeclU = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
      +        CDeclU = LookupName(TUScope, ClassName, LookupOrdinaryName);
             }
           }
         }
      @@ -535,7 +535,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
                             SourceLocation SuperClassLoc) {
         ObjCInterfaceDecl* IDecl = 0;
         // Check for another declaration kind with the same name.
      -  Decl *PrevDecl = LookupDeclInScope(ClassName, Decl::IDNS_Ordinary, TUScope);
      +  Decl *PrevDecl = LookupName(TUScope, ClassName, LookupOrdinaryName);
         if (PrevDecl && !isa(PrevDecl)) {
           Diag(ClassLoc, diag::err_redefinition_different_kind) << ClassName;
           Diag(PrevDecl->getLocation(), diag::note_previous_definition);
      @@ -551,7 +551,7 @@ Sema::DeclTy *Sema::ActOnStartClassImplementation(
         ObjCInterfaceDecl* SDecl = 0;
         if (SuperClassname) {
           // Check if a different kind of symbol declared in this scope.
      -    PrevDecl = LookupDeclInScope(SuperClassname, Decl::IDNS_Ordinary, TUScope);
      +    PrevDecl = LookupName(TUScope, SuperClassname, LookupOrdinaryName);
           if (PrevDecl && !isa(PrevDecl)) {
             Diag(SuperClassLoc, diag::err_redefinition_different_kind)
               << SuperClassname;
      @@ -909,7 +909,7 @@ Sema::ActOnForwardClassDeclaration(SourceLocation AtClassLoc,
         
         for (unsigned i = 0; i != NumElts; ++i) {
           // Check for another declaration kind with the same name.
      -    Decl *PrevDecl = LookupDeclInScope(IdentList[i], Decl::IDNS_Ordinary, TUScope);
      +    Decl *PrevDecl = LookupName(TUScope, IdentList[i], LookupOrdinaryName);
           if (PrevDecl && PrevDecl->isTemplateParameter()) {
             // Maybe we will complain about the shadowed template parameter.
             DiagnoseTemplateParameterShadow(AtClassLoc, PrevDecl);
      diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
      index 5ebec0270b50..129967a14b62 100644
      --- a/clang/lib/Sema/SemaExpr.cpp
      +++ b/clang/lib/Sema/SemaExpr.cpp
      @@ -555,14 +555,9 @@ Sema::ActOnDeclarationNameExpr(Scope *S, SourceLocation Loc,
       
         // Could be enum-constant, value decl, instance variable, etc.
         Decl *D = 0;
      -  LookupResult Lookup;
      -  if (SS && !SS->isEmpty()) {
      -    DeclContext *DC = static_cast(SS->getScopeRep());
      -    if (DC == 0)
      -      return ExprError();
      -    Lookup = LookupDeclInContext(Name, Decl::IDNS_Ordinary, DC);
      -  } else
      -    Lookup = LookupDeclInScope(Name, Decl::IDNS_Ordinary, S);
      +  if (SS && SS->isInvalid())
      +    return ExprError();
      +  LookupResult Lookup = LookupParsedName(S, SS, Name, LookupOrdinaryName);
       
         if (Lookup.isAmbiguous()) {
           DiagnoseAmbiguousLookup(Lookup, Name, Loc,
      @@ -1519,9 +1514,7 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
           // than this.
           LookupResult Result
             = LookupQualifiedName(RDecl, DeclarationName(&Member), 
      -                            LookupCriteria(LookupCriteria::Member,
      -                                           /*RedeclarationOnly=*/false, 
      -                                           getLangOptions().CPlusPlus));
      +                            LookupMemberName, false);
       
           Decl *MemberDecl = 0;
           if (!Result)
      @@ -4030,9 +4023,9 @@ Sema::ExprResult Sema::ActOnBuiltinOffsetOf(Scope *S,
           // Get the decl corresponding to this.
           RecordDecl *RD = RC->getDecl();
           FieldDecl *MemberDecl 
      -      = dyn_cast_or_null(LookupDeclInContext(OC.U.IdentInfo, 
      -                                               Decl::IDNS_Ordinary,
      -                                               RD, false).getAsDecl());
      +      = dyn_cast_or_null(LookupQualifiedName(RD, OC.U.IdentInfo, 
      +                                                        LookupMemberName)
      +                                      .getAsDecl());
           if (!MemberDecl)
             return Diag(BuiltinLoc, diag::err_typecheck_no_member)
              << OC.U.IdentInfo << SourceRange(OC.LocStart, OC.LocEnd);
      diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
      index d0ceb97b3ae9..3c8184d24d83 100644
      --- a/clang/lib/Sema/SemaExprCXX.cpp
      +++ b/clang/lib/Sema/SemaExprCXX.cpp
      @@ -55,12 +55,12 @@ Sema::ActOnCXXOperatorFunctionIdExpr(Scope *S, SourceLocation OperatorLoc,
       Action::ExprResult
       Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
                            bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
      -  const NamespaceDecl *StdNs = GetStdNamespace();
      +  NamespaceDecl *StdNs = GetStdNamespace();
         if (!StdNs)
           return Diag(OpLoc, diag::err_need_header_before_typeid);
         
         IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
      -  Decl *TypeInfoDecl = LookupDeclInContext(TypeInfoII, Decl::IDNS_Tag, StdNs);
      +  Decl *TypeInfoDecl = LookupQualifiedName(StdNs, TypeInfoII, LookupTagName);
         RecordDecl *TypeInfoRecordDecl = dyn_cast_or_null(TypeInfoDecl);
         if (!TypeInfoRecordDecl)
           return Diag(OpLoc, diag::err_need_header_before_typeid);
      diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
      index f436e61ee912..f893f1eec533 100644
      --- a/clang/lib/Sema/SemaExprObjC.cpp
      +++ b/clang/lib/Sema/SemaExprObjC.cpp
      @@ -52,7 +52,7 @@ Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation *AtLocs,
           // Initialize the constant string interface lazily. This assumes
           // the NSConstantString interface is seen in this translation unit.
           IdentifierInfo *NSIdent = &Context.Idents.get("NSConstantString");
      -    Decl *IFace = LookupDeclInScope(NSIdent, Decl::IDNS_Ordinary, TUScope);
      +    Decl *IFace = LookupName(TUScope, NSIdent, LookupOrdinaryName);
           ObjCInterfaceDecl *strIFace = dyn_cast_or_null(IFace);
           if (strIFace)
             Context.setObjCConstantStringInterface(strIFace);
      @@ -209,7 +209,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
           } else {
             // 'super' has been used outside a method context. If a variable named
             // 'super' has been declared, redirect. If not, produce a diagnostic.
      -      Decl *SuperDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, S);
      +      Decl *SuperDecl = LookupName(S, receiverName, LookupOrdinaryName);
             ValueDecl *VD = dyn_cast_or_null(SuperDecl);
             if (VD) {
               ExprResult ReceiverExpr = new DeclRefExpr(VD, VD->getType(), 
      @@ -234,7 +234,7 @@ Sema::ExprResult Sema::ActOnClassMessage(
         //
         // If necessary, the following lookup could move to getObjCInterfaceDecl().
         if (!ClassDecl) {
      -    Decl *IDecl = LookupDeclInScope(receiverName, Decl::IDNS_Ordinary, 0);
      +    Decl *IDecl = LookupName(TUScope, receiverName, LookupOrdinaryName);
           if (TypedefDecl *OCTD = dyn_cast_or_null(IDecl)) {
             const ObjCInterfaceType *OCIT;
             OCIT = OCTD->getUnderlyingType()->getAsObjCInterfaceType();
      diff --git a/clang/lib/Sema/SemaInherit.cpp b/clang/lib/Sema/SemaInherit.cpp
      index cb58063d840e..0772bc3c1e84 100644
      --- a/clang/lib/Sema/SemaInherit.cpp
      +++ b/clang/lib/Sema/SemaInherit.cpp
      @@ -153,7 +153,8 @@ bool Sema::LookupInBases(CXXRecordDecl *Class,
           } else {
             Paths.ScratchPath.Decls = BaseRecord->lookup(Criteria.Name);
             while (Paths.ScratchPath.Decls.first != Paths.ScratchPath.Decls.second) {
      -        if (Criteria.Criteria.isLookupResult(*Paths.ScratchPath.Decls.first)) {
      +        if (isAcceptableLookupResult(*Paths.ScratchPath.Decls.first,
      +                                     Criteria.NameKind, Criteria.IDNS)) {
                 FoundPathToThisBase = true;
                 break;
               }
      diff --git a/clang/lib/Sema/SemaInherit.h b/clang/lib/Sema/SemaInherit.h
      index 87a4a663aeb4..eb169a2982bb 100644
      --- a/clang/lib/Sema/SemaInherit.h
      +++ b/clang/lib/Sema/SemaInherit.h
      @@ -193,8 +193,9 @@ namespace clang {
           /// MemberLookupCriteria - Constructs member lookup criteria to
           /// search for a class member with the given Name.
           explicit MemberLookupCriteria(DeclarationName Name, 
      -                                  Sema::LookupCriteria Criteria) 
      -      : LookupBase(false), Name(Name), Criteria(Criteria) { }
      +                                  Sema::LookupNameKind NameKind,
      +                                  unsigned IDNS) 
      +      : LookupBase(false), Name(Name), NameKind(NameKind), IDNS(IDNS) { }
       
           /// LookupBase - True if we are looking for a base class (whose
           /// type is Base). If false, we are looking for a named member of
      @@ -209,9 +210,8 @@ namespace clang {
           /// LookupBase is false.
           DeclarationName Name;
       
      -    /// Criteria - The criteria by which we evaluate a named member,
      -    /// if LookupBase is false.
      -    Sema::LookupCriteria Criteria;
      +    Sema::LookupNameKind NameKind;
      +    unsigned IDNS;
         };
       }
       
      diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
      index 7353bc37e4b5..abb265da49be 100644
      --- a/clang/lib/Sema/SemaLookup.cpp
      +++ b/clang/lib/Sema/SemaLookup.cpp
      @@ -31,8 +31,8 @@ using namespace clang;
       /// OverloadeFunctionDecl that represents the overloaded functions in
       /// [I, IEnd). 
       ///
      -/// The existance of this routine is temporary; LookupDecl should
      -/// probably be able to return multiple results, to deal with cases of
      +/// The existance of this routine is temporary; users of LookupResult
      +/// should be able to handle multiple results, to deal with cases of
       /// ambiguity and overloaded functions without needing to create a
       /// Decl node.
       template
      @@ -69,64 +69,6 @@ MaybeConstructOverloadSet(ASTContext &Context,
         return *I;
       }
       
      -/// @brief Constructs name lookup criteria.
      -///
      -/// @param K The kind of name that we're searching for.
      -///
      -/// @param RedeclarationOnly If true, then name lookup will only look
      -/// into the current scope for names, not in parent scopes. This
      -/// option should be set when we're looking to introduce a new
      -/// declaration into scope.
      -///
      -/// @param CPlusPlus Whether we are performing C++ name lookup or not.
      -Sema::LookupCriteria::LookupCriteria(NameKind K, bool RedeclarationOnly,
      -                                     bool CPlusPlus)  
      -  : Kind(K), AllowLazyBuiltinCreation(K == Ordinary), 
      -    RedeclarationOnly(RedeclarationOnly) { 
      -  switch (Kind) {
      -  case Ordinary:
      -    IDNS = Decl::IDNS_Ordinary;
      -    if (CPlusPlus)
      -      IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member;
      -    break;
      -
      -  case Tag:
      -    IDNS = Decl::IDNS_Tag;
      -    break;
      -
      -  case Member:
      -    IDNS = Decl::IDNS_Member;
      -    if (CPlusPlus)
      -      IDNS |= Decl::IDNS_Tag | Decl::IDNS_Ordinary;    
      -    break;
      -
      -  case NestedNameSpecifier:
      -  case Namespace:
      -    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member;
      -    break;
      -  }
      -}
      -
      -/// isLookupResult - Determines whether D is a suitable lookup result
      -/// according to the lookup criteria.
      -bool Sema::LookupCriteria::isLookupResult(Decl *D) const {
      -  switch (Kind) {
      -  case Ordinary:
      -  case Tag:
      -  case Member:
      -    return D->isInIdentifierNamespace(IDNS);
      -
      -  case NestedNameSpecifier:
      -    return isa(D) || D->isInIdentifierNamespace(Decl::IDNS_Tag);
      -
      -  case Namespace:
      -    return isa(D);
      -  }
      -
      -  assert(false && "isLookupResult always returns before this point");
      -  return false;
      -}
      -
       /// @brief Moves the name-lookup results from Other to this LookupResult.
       Sema::LookupResult
       Sema::LookupResult::CreateLookupResult(ASTContext &Context, 
      @@ -239,6 +181,37 @@ BasePaths *Sema::LookupResult::getBasePaths() const {
         return reinterpret_cast(First);
       }
       
      +// Retrieve the set of identifier namespaces that correspond to a
      +// specific kind of name lookup.
      +inline unsigned 
      +getIdentifierNamespacesFromLookupNameKind(Sema::LookupNameKind NameKind, 
      +                                          bool CPlusPlus) {
      +  unsigned IDNS = 0;
      +  switch (NameKind) {
      +  case Sema::LookupOrdinaryName:
      +    IDNS = Decl::IDNS_Ordinary;
      +    if (CPlusPlus)
      +      IDNS |= Decl::IDNS_Tag | Decl::IDNS_Member;
      +    break;
      +
      +  case Sema::LookupTagName:
      +    IDNS = Decl::IDNS_Tag;
      +    break;
      +
      +  case Sema::LookupMemberName:
      +    IDNS = Decl::IDNS_Member;
      +    if (CPlusPlus)
      +      IDNS |= Decl::IDNS_Tag | Decl::IDNS_Ordinary;    
      +    break;
      +
      +  case Sema::LookupNestedNameSpecifierName:
      +  case Sema::LookupNamespaceName:
      +    IDNS = Decl::IDNS_Ordinary | Decl::IDNS_Tag | Decl::IDNS_Member;
      +    break;
      +  }
      +  return IDNS;
      +}
      +
       /// @brief Perform unqualified name lookup starting from a given
       /// scope.
       ///
      @@ -276,52 +249,58 @@ BasePaths *Sema::LookupResult::getBasePaths() const {
       /// declarations and possibly additional information used to diagnose
       /// ambiguities.
       Sema::LookupResult 
      -Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
      +Sema::LookupName(Scope *S, DeclarationName Name, LookupNameKind NameKind,
      +                 bool RedeclarationOnly) {
         if (!Name) return LookupResult::CreateLookupResult(Context, 0);
       
         if (!getLangOptions().CPlusPlus) {
           // Unqualified name lookup in C/Objective-C is purely lexical, so
           // search in the declarations attached to the name.
      +    unsigned IDNS = 0;
      +    switch (NameKind) {
      +    case Sema::LookupOrdinaryName:
      +      IDNS = Decl::IDNS_Ordinary;
      +      break;
      +
      +    case Sema::LookupTagName:
      +      IDNS = Decl::IDNS_Tag;
      +      break;
      +
      +    case Sema::LookupMemberName:
      +      IDNS = Decl::IDNS_Member;
      +      break;
      +
      +    case Sema::LookupNestedNameSpecifierName:
      +    case Sema::LookupNamespaceName:
      +      assert(false && "C does not perform these kinds of name lookup");
      +      break;
      +    }
       
      -    // For the purposes of unqualified name lookup, structs and unions
      -    // don't have scopes at all. For example:
      -    //
      -    //   struct X {
      -    //     struct T { int i; } x;
      -    //   };
      -    //
      -    //   void f() {
      -    //     struct T t; // okay: T is defined lexically within X, but
      -    //                 // semantically at global scope
      -    //   };
      -    //
      -    // FIXME: Is there a better way to deal with this?
      -    DeclContext *SearchCtx = CurContext;
      -    while (isa(SearchCtx) || isa(SearchCtx))
      -      SearchCtx = SearchCtx->getParent();
      -    IdentifierResolver::iterator I
      -      = IdResolver.begin(Name, SearchCtx, !Criteria.RedeclarationOnly);
      -    
           // Scan up the scope chain looking for a decl that matches this
           // identifier that is in the appropriate namespace.  This search
           // should not take long, as shadowing of names is uncommon, and
           // deep shadowing is extremely uncommon.
      -    for (; I != IdResolver.end(); ++I)
      -      if (Criteria.isLookupResult(*I))
      +    for (IdentifierResolver::iterator I = IdResolver.begin(Name),
      +                                   IEnd = IdResolver.end(); 
      +         I != IEnd; ++I)
      +      if ((*I)->isInIdentifierNamespace(IDNS))
               return LookupResult::CreateLookupResult(Context, *I);
         } else {
      +    unsigned IDNS 
      +      = getIdentifierNamespacesFromLookupNameKind(NameKind, 
      +                                                  getLangOptions().CPlusPlus);
      +
           // Unqualified name lookup in C++ requires looking into scopes
           // that aren't strictly lexical, and therefore we walk through the
           // context as well as walking through the scopes.
       
           // FIXME: does "true" for LookInParentCtx actually make sense?
      -    IdentifierResolver::iterator 
      -      I = IdResolver.begin(Name, CurContext, true/*LookInParentCtx*/),
      -      IEnd = IdResolver.end();
      +    IdentifierResolver::iterator I = IdResolver.begin(Name),
      +                              IEnd = IdResolver.end();
           for (; S; S = S->getParent()) {
             // Check whether the IdResolver has anything in this scope.
             for (; I != IEnd && S->isDeclScope(*I); ++I) {
      -        if (Criteria.isLookupResult(*I)) {
      +        if (isAcceptableLookupResult(*I, NameKind, IDNS)) {
                 // We found something.  Look for anything else in our scope
                 // with this same name and in an acceptable identifier
                 // namespace, so that we can construct an overload set if we
      @@ -356,10 +335,11 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
               Ctx = Ctx->getParent();
             while (Ctx && (Ctx->isNamespace() || Ctx->isRecord())) {
               // Look for declarations of this name in this scope.
      -        if (LookupResult Result = LookupQualifiedName(Ctx, Name, Criteria))
      +        if (LookupResult Result = LookupQualifiedName(Ctx, Name, NameKind, 
      +                                                      RedeclarationOnly))
                 return Result;
               
      -        if (Criteria.RedeclarationOnly && !Ctx->isTransparentContext())
      +        if (RedeclarationOnly && !Ctx->isTransparentContext())
                 return LookupResult::CreateLookupResult(Context, 0);
       
               Ctx = Ctx->getParent();
      @@ -370,9 +350,9 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
         // If we didn't find a use of this identifier, and if the identifier
         // corresponds to a compiler builtin, create the decl object for the builtin
         // now, injecting it into translation unit scope, and return it.
      -  if (Criteria.Kind == LookupCriteria::Ordinary) {
      +  if (NameKind == LookupOrdinaryName) {
           IdentifierInfo *II = Name.getAsIdentifierInfo();
      -    if (Criteria.AllowLazyBuiltinCreation && II) {
      +    if (II) {
             // If this is a builtin on this (or all) targets, create the decl.
             if (unsigned BuiltinID = II->getBuiltinID())
               return LookupResult::CreateLookupResult(Context,
      @@ -428,25 +408,28 @@ Sema::LookupName(Scope *S, DeclarationName Name, LookupCriteria Criteria) {
       /// ambiguities.
       Sema::LookupResult
       Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
      -                          LookupCriteria Criteria) {
      +                          LookupNameKind NameKind, bool RedeclarationOnly) {
         assert(LookupCtx && "Sema::LookupQualifiedName requires a lookup context");
         
         if (!Name) return LookupResult::CreateLookupResult(Context, 0);
       
         // If we're performing qualified name lookup (e.g., lookup into a
         // struct), find fields as part of ordinary name lookup.
      -  if (Criteria.Kind == LookupCriteria::Ordinary)
      -    Criteria.IDNS |= Decl::IDNS_Member;
      +  unsigned IDNS
      +    = getIdentifierNamespacesFromLookupNameKind(NameKind, 
      +                                                getLangOptions().CPlusPlus);
      +  if (NameKind == LookupOrdinaryName)
      +    IDNS |= Decl::IDNS_Member;
       
         // Perform qualified name lookup into the LookupCtx.
         DeclContext::lookup_iterator I, E;
         for (llvm::tie(I, E) = LookupCtx->lookup(Name); I != E; ++I)
      -    if (Criteria.isLookupResult(*I))
      +    if (isAcceptableLookupResult(*I, NameKind, IDNS))
             return LookupResult::CreateLookupResult(Context, I, E);
       
         // If this isn't a C++ class or we aren't allowed to look into base
         // classes, we're done.
      -  if (Criteria.RedeclarationOnly || !isa(LookupCtx))
      +  if (RedeclarationOnly || !isa(LookupCtx))
           return LookupResult::CreateLookupResult(Context, 0);
       
         // Perform lookup into our base classes.
      @@ -455,7 +438,7 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
       
         // Look for this member in our base classes
         if (!LookupInBases(cast(LookupCtx), 
      -                     MemberLookupCriteria(Name, Criteria), Paths))
      +                     MemberLookupCriteria(Name, NameKind, IDNS), Paths))
           return LookupResult::CreateLookupResult(Context, 0);
       
         // C++ [class.member.lookup]p2:
      @@ -552,18 +535,21 @@ Sema::LookupQualifiedName(DeclContext *LookupCtx, DeclarationName Name,
       /// @param Name     The name of the entity that name lookup will
       /// search for.
       ///
      -/// @param Criteria The criteria that will determine which entities
      -/// are visible to name lookup.
      -///
       /// @returns The result of qualified or unqualified name lookup.
       Sema::LookupResult
      -Sema::LookupParsedName(Scope *S, const CXXScopeSpec &SS, 
      -                       DeclarationName Name, LookupCriteria Criteria) {
      -  if (SS.isSet())
      -    return LookupQualifiedName(static_cast(SS.getScopeRep()),
      -                               Name, Criteria);
      +Sema::LookupParsedName(Scope *S, const CXXScopeSpec *SS, 
      +                       DeclarationName Name, LookupNameKind NameKind,
      +                       bool RedeclarationOnly) {
      +  if (SS) {
      +    if (SS->isInvalid())
      +      return LookupResult::CreateLookupResult(Context, 0);
      +
      +    if (SS->isSet())
      +      return LookupQualifiedName(static_cast(SS->getScopeRep()),
      +                                 Name, NameKind, RedeclarationOnly);
      +  }
       
      -  return LookupName(S, Name, Criteria);
      +  return LookupName(S, Name, NameKind, RedeclarationOnly);
       }
       
       /// @brief Produce a diagnostic describing the ambiguity that resulted
      diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
      index 0f9f0cf9c6aa..17ad387ac3eb 100644
      --- a/clang/lib/Sema/SemaOverload.cpp
      +++ b/clang/lib/Sema/SemaOverload.cpp
      @@ -2279,9 +2279,8 @@ void Sema::AddOperatorCandidates(OverloadedOperatorKind Op, Scope *S,
         //        of type T2 or “reference to (possibly cv-qualified) T2”,
         //        when T2 is an enumeration type, are candidate functions.
         {
      -    IdentifierResolver::iterator
      -      I = IdResolver.begin(OpName, CurContext, true/*LookInParentCtx*/),
      -      IEnd = IdResolver.end();
      +    IdentifierResolver::iterator I = IdResolver.begin(OpName),
      +                              IEnd = IdResolver.end();
           for (; I != IEnd; ++I) {
             // We don't need to check the identifier namespace, because
             // operator names can only be ordinary identifiers.
      diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
      index 7ecac0027707..f1b8617daed6 100644
      --- a/clang/lib/Sema/SemaTemplate.cpp
      +++ b/clang/lib/Sema/SemaTemplate.cpp
      @@ -32,9 +32,7 @@ Sema::DeclTy *Sema::isTemplateName(IdentifierInfo &II, Scope *S,
             return 0;
           DC = static_cast(SS->getScopeRep());
         }
      -  Decl *IIDecl = DC ? 
      -                 LookupDeclInContext(&II, Decl::IDNS_Ordinary, DC, false) :
      -                 LookupDeclInScope(&II, Decl::IDNS_Ordinary, S, false);
      +  Decl *IIDecl = LookupParsedName(S, SS, &II, LookupOrdinaryName);
       
         if (IIDecl) {
           // FIXME: We need to represent templates via some kind of
      @@ -96,7 +94,7 @@ Sema::DeclTy *Sema::ActOnTypeParameter(Scope *S, bool Typename,
         bool Invalid = false;
       
         if (ParamName) {
      -    Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S);
      +    Decl *PrevDecl = LookupName(S, ParamName, LookupTagName);
           if (PrevDecl && PrevDecl->isTemplateParameter())
             Invalid = Invalid || DiagnoseTemplateParameterShadow(ParamNameLoc,
       							   PrevDecl);
      @@ -132,7 +130,7 @@ Sema::DeclTy *Sema::ActOnNonTypeTemplateParameter(Scope *S, Declarator &D,
       
         IdentifierInfo *ParamName = D.getIdentifier();
         if (ParamName) {
      -    Decl *PrevDecl = LookupDeclInScope(ParamName, Decl::IDNS_Tag, S);
      +    Decl *PrevDecl = LookupName(S, ParamName, LookupTagName);
           if (PrevDecl && PrevDecl->isTemplateParameter())
             Invalid = Invalid || DiagnoseTemplateParameterShadow(D.getIdentifierLoc(),
       							   PrevDecl);
      -- 
      GitLab
      
      
      From 9c9a3b6665e470c854f7c8efdb40a095852aa2d8 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 01:13:16 +0000
      Subject: [PATCH 463/682] Propagate debug location info for the token factor.
      
      llvm-svn: 63355
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 10 +++++-----
       1 file changed, 5 insertions(+), 5 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 13256e0e79f1..2947794e919c 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -770,7 +770,6 @@ SDValue DAGCombiner::visit(SDNode *N) {
       }
       
       SDValue DAGCombiner::combine(SDNode *N) {
      -
         SDValue RV = visit(N);
       
         // If nothing happened, try a target-specific DAG combine.
      @@ -796,6 +795,7 @@ SDValue DAGCombiner::combine(SDNode *N) {
             N->getNumValues() == 1) {
           SDValue N0 = N->getOperand(0);
           SDValue N1 = N->getOperand(1);
      +
           // Constant operands are canonicalized to RHS.
           if (isa(N0) || !isa(N1)) {
             SDValue Ops[] = { N1, N0 };
      @@ -821,7 +821,7 @@ static SDValue getInputChainForNode(SDNode *N) {
             if (N->getOperand(i).getValueType() == MVT::Other)
               return N->getOperand(i);
         }
      -  return SDValue(0, 0);
      +  return SDValue();
       }
       
       SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
      @@ -890,9 +890,10 @@ SDValue DAGCombiner::visitTokenFactor(SDNode *N) {
             Result = DAG.getEntryNode();
           } else {
             // New and improved token factor.
      -      Result = DAG.getNode(ISD::TokenFactor, MVT::Other, &Ops[0], Ops.size());
      +      Result = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(),
      +                           MVT::Other, &Ops[0], Ops.size());
           }
      -    
      +
           // Don't add users to work list.
           return CombineTo(N, Result, false);
         }
      @@ -911,7 +912,6 @@ SDValue DAGCombiner::visitMERGE_VALUES(SDNode *N) {
         return SDValue(N, 0);   // Return N so it doesn't get rechecked!
       }
       
      -
       static
       SDValue combineShlAddConstant(SDValue N0, SDValue N1, SelectionDAG &DAG) {
         MVT VT = N0.getValueType();
      -- 
      GitLab
      
      
      From 4ba91058d2434c208a11ff13746b8fdb35ac1392 Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 01:21:46 +0000
      Subject: [PATCH 464/682] Add DW_AT_declaration for class methods.
      
      llvm-svn: 63356
      ---
       llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp   |  7 +++--
       .../DebugInfo/2009-01-29-MethodDeclaration.ll | 31 +++++++++++++++++++
       2 files changed, 36 insertions(+), 2 deletions(-)
       create mode 100644 llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      
      diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      index 8d668122e551..d88c0e6fcae6 100644
      --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      @@ -1965,9 +1965,12 @@ private:
               AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ???
               SPDie->AddChild(Arg);
             }
      -    
      +
      +    if (!SP.isDefinition())
      +      AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1);
      +
           if (!SP.isLocalToUnit())
      -      AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);                     
      +      AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1);
           return SPDie;
         }
       
      diff --git a/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll b/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      new file mode 100644
      index 000000000000..323135f5210a
      --- /dev/null
      +++ b/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      @@ -0,0 +1,31 @@
      +; RUN: llvm-as < %s | llc | grep 0x3C | count 1
      +; Check DW_AT_declaration attribute for class method foo.
      +	%llvm.dbg.anchor.type = type { i32, i32 }
      +	%llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* }
      +	%llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i8* }
      +	%llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i8*, i8* }
      +	%llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, i8*, i8* }
      +	%llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }*, i8*, i8* }
      +	%llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, i8*, i8* }
      +	%struct.A = type <{ i8 }>
      +@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata"		; <%llvm.dbg.anchor.type*> [#uses=1]
      +@.str = internal constant [6 x i8] c"cl.cc\00", section "llvm.metadata"		; <[6 x i8]*> [#uses=1]
      +@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata"		; <[26 x i8]*> [#uses=1]
      +@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build)\00", section "llvm.metadata"		; <[52 x i8]*> [#uses=1]
      +@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 4, i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i8* null }, section "llvm.metadata"		; <%llvm.dbg.compile_unit.type*> [#uses=1]
      +@a = global %struct.A zeroinitializer		; <%struct.A*> [#uses=1]
      +@.str3 = internal constant [2 x i8] c"A\00", section "llvm.metadata"		; <[2 x i8]*> [#uses=1]
      +@.str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata"		; <[4 x i8]*> [#uses=1]
      +@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5, i8* null, i8* null }, section "llvm.metadata"		; <%llvm.dbg.basictype.type*> [#uses=1]
      +@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i8* null, i8* null }, section "llvm.metadata"		; <%llvm.dbg.derivedtype.type*> [#uses=1]
      +@llvm.dbg.array = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*) ], section "llvm.metadata"		; <[2 x { }*]*> [#uses=1]
      +@llvm.dbg.composite5 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array to { }*), i8* null, i8* null }, section "llvm.metadata"		; <%llvm.dbg.composite.type*> [#uses=1]
      +@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata"		; <%llvm.dbg.anchor.type*> [#uses=1]
      +@.str6 = internal constant [4 x i8] c"foo\00", section "llvm.metadata"		; <[4 x i8]*> [#uses=1]
      +@.str7 = internal constant [12 x i8] c"_ZN1A3fooEv\00", section "llvm.metadata"		; <[12 x i8]*> [#uses=1]
      +@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([12 x i8]* @.str7, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite5 to { }*), i1 false, i1 false, i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata"		; <%llvm.dbg.subprogram.type*> [#uses=1]
      +@llvm.dbg.array8 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) ], section "llvm.metadata"		; <[1 x { }*]*> [#uses=1]
      +@llvm.dbg.composite9 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, i64 8, i64 8, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array8 to { }*), i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata"		; <%llvm.dbg.composite.type*> [#uses=1]
      +@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata"		; <%llvm.dbg.anchor.type*> [#uses=1]
      +@.str10 = internal constant [2 x i8] c"a\00", section "llvm.metadata"		; <[2 x i8]*> [#uses=1]
      +@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { i32 458804, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str10, i32 0, i32 0), i8* getelementptr ([2 x i8]* @.str10, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 7, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite9 to { }*), i1 false, i1 true, { }* bitcast (%struct.A* @a to { }*), i8* getelementptr ([6 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata"		; <%llvm.dbg.global_variable.type*> [#uses=0]
      -- 
      GitLab
      
      
      From 776a4c5baa3b0677d0a6738826ccefb67896dafa Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 01:25:47 +0000
      Subject: [PATCH 465/682] Remove dead code.
      
      llvm-svn: 63357
      ---
       llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 10 ----------
       1 file changed, 10 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      index d88c0e6fcae6..f19c0c3bb468 100644
      --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      @@ -1650,16 +1650,6 @@ private:
           AddDIEntry(Entity, DW_AT_type, DW_FORM_ref4, BasicTypeDie);
         }
       
      -  /// AddPointerType - Add a new pointer type attribute to the specified entity.
      -  ///
      -  void AddPointerType(DIE *Entity, CompileUnit *Unit, const std::string &Name) {
      -    DIE Buffer(DW_TAG_pointer_type);
      -    AddUInt(&Buffer, DW_AT_byte_size, 0, TD->getPointerSize());
      -    if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
      -    DIE *PointerTypeDie =  Unit->AddDie(Buffer);
      -    AddDIEntry(Entity, DW_AT_type, DW_FORM_ref4, PointerTypeDie);
      -  }
      -
         /// AddType - Add a new type attribute to the specified entity.
         void AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
           if (Ty.isNull())
      -- 
      GitLab
      
      
      From 33a21670f47d709e0e6eccabd5d3845eabe7532a Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 01:27:49 +0000
      Subject: [PATCH 466/682] Remove dead code, again.
      
      llvm-svn: 63358
      ---
       llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 14 --------------
       1 file changed, 14 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      index f19c0c3bb468..b2a52cabe0e7 100644
      --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp
      @@ -1636,20 +1636,6 @@ private:
           AddBlock(Die, Attribute, 0, Block);
         }
       
      -  /// AddBasicType - Add a new basic type attribute to the specified entity.
      -  ///
      -  void AddBasicType(DIE *Entity, CompileUnit *Unit,
      -                    const std::string &Name,
      -                    unsigned Encoding, unsigned Size) {
      -
      -    DIE Buffer(DW_TAG_base_type);
      -    AddUInt(&Buffer, DW_AT_byte_size, 0, Size);
      -    AddUInt(&Buffer, DW_AT_encoding, DW_FORM_data1, Encoding);
      -    if (!Name.empty()) AddString(&Buffer, DW_AT_name, DW_FORM_string, Name);
      -    DIE *BasicTypeDie = Unit->AddDie(Buffer);
      -    AddDIEntry(Entity, DW_AT_type, DW_FORM_ref4, BasicTypeDie);
      -  }
      -
         /// AddType - Add a new type attribute to the specified entity.
         void AddType(CompileUnit *DW_Unit, DIE *Entity, DIType Ty) {
           if (Ty.isNull())
      -- 
      GitLab
      
      
      From ed255b3d8e85784fc725dcda6540655b09b7116c Mon Sep 17 00:00:00 2001
      From: Dale Johannesen 
      Date: Fri, 30 Jan 2009 01:34:22 +0000
      Subject: [PATCH 467/682] Propagate debug info when building SelectionDAG.
      
      llvm-svn: 63359
      ---
       llvm/include/llvm/CodeGen/SelectionDAG.h      |   6 +
       .../SelectionDAG/SelectionDAGBuild.cpp        | 918 ++++++++++--------
       2 files changed, 525 insertions(+), 399 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
      index a06158a39b2d..6b09a745c338 100644
      --- a/llvm/include/llvm/CodeGen/SelectionDAG.h
      +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
      @@ -79,6 +79,9 @@ class SelectionDAG {
         MachineModuleInfo *MMI;
         DwarfWriter *DW;
       
      +  /// CurDebugLoc - current file + line number.  Changes as we build the DAG.
      +  DebugLoc CurDebugLoc;
      +
         /// EntryNode - The starting token.
         SDNode EntryNode;
       
      @@ -137,6 +140,7 @@ public:
         FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; }
         MachineModuleInfo *getMachineModuleInfo() const { return MMI; }
         DwarfWriter *getDwarfWriter() const { return DW; }
      +  DebugLoc getCurDebugLoc() const { return CurDebugLoc; }
       
         /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'.
         ///
      @@ -195,6 +199,8 @@ public:
           return Root = N;
         }
       
      +  void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; }
      +
         /// Combine - This iterates over the nodes in the SelectionDAG, folding
         /// certain types of nodes together, or eliminating superfluous nodes.  The
         /// Level argument controls whether Combine is allowed to produce nodes and
      diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
      index a0154cb0a0d4..026a6f44084a 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp
      @@ -404,12 +404,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts,
               Hi = getCopyFromParts(DAG, Parts+RoundParts/2, RoundParts/2,
                                     PartVT, HalfVT);
             } else {
      -        Lo = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[0]);
      -        Hi = DAG.getNode(ISD::BIT_CONVERT, HalfVT, Parts[1]);
      +        Lo = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(),
      +                                           HalfVT, Parts[0]);
      +        Hi = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(),
      +                                           HalfVT, Parts[1]);
             }
             if (TLI.isBigEndian())
               std::swap(Lo, Hi);
      -      Val = DAG.getNode(ISD::BUILD_PAIR, RoundVT, Lo, Hi);
      +      Val = DAG.getNode(ISD::BUILD_PAIR, DAG.getCurDebugLoc(), RoundVT, Lo, Hi);
       
             if (RoundParts < NumParts) {
               // Assemble the trailing non-power-of-2 part.
      @@ -422,12 +424,12 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts,
               if (TLI.isBigEndian())
                 std::swap(Lo, Hi);
               MVT TotalVT = MVT::getIntegerVT(NumParts * PartBits);
      -        Hi = DAG.getNode(ISD::ANY_EXTEND, TotalVT, Hi);
      -        Hi = DAG.getNode(ISD::SHL, TotalVT, Hi,
      +        Hi = DAG.getNode(ISD::ANY_EXTEND, DAG.getCurDebugLoc(), TotalVT, Hi);
      +        Hi = DAG.getNode(ISD::SHL, DAG.getCurDebugLoc(), TotalVT, Hi,
                                DAG.getConstant(Lo.getValueType().getSizeInBits(),
                                                TLI.getShiftAmountTy()));
      -        Lo = DAG.getNode(ISD::ZERO_EXTEND, TotalVT, Lo);
      -        Val = DAG.getNode(ISD::OR, TotalVT, Lo, Hi);
      +        Lo = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), TotalVT, Lo);
      +        Val = DAG.getNode(ISD::OR, DAG.getCurDebugLoc(), TotalVT, Lo, Hi);
             }
           } else {
             // Handle a multi-element vector.
      @@ -465,6 +467,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts,
             // operands.
             Val = DAG.getNode(IntermediateVT.isVector() ?
                               ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR,
      +                        DAG.getCurDebugLoc(),
                               ValueVT, &Ops[0], NumIntermediates);
           }
         }
      @@ -477,14 +480,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts,
       
         if (PartVT.isVector()) {
           assert(ValueVT.isVector() && "Unknown vector conversion!");
      -    return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
      +    return DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), ValueVT, Val);
         }
       
         if (ValueVT.isVector()) {
           assert(ValueVT.getVectorElementType() == PartVT &&
                  ValueVT.getVectorNumElements() == 1 &&
                  "Only trivial scalar-to-vector conversions should get here!");
      -    return DAG.getNode(ISD::BUILD_VECTOR, ValueVT, Val);
      +    return DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), ValueVT, Val);
         }
       
         if (PartVT.isInteger() &&
      @@ -494,24 +497,24 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts,
             // indicate whether the truncated bits will always be
             // zero or sign-extension.
             if (AssertOp != ISD::DELETED_NODE)
      -        Val = DAG.getNode(AssertOp, PartVT, Val,
      +        Val = DAG.getNode(AssertOp, DAG.getCurDebugLoc(), PartVT, Val,
                                 DAG.getValueType(ValueVT));
      -      return DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
      +      return DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ValueVT, Val);
           } else {
      -      return DAG.getNode(ISD::ANY_EXTEND, ValueVT, Val);
      +      return DAG.getNode(ISD::ANY_EXTEND, DAG.getCurDebugLoc(), ValueVT, Val);
           }
         }
       
         if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
           if (ValueVT.bitsLT(Val.getValueType()))
             // FP_ROUND's are always exact here.
      -      return DAG.getNode(ISD::FP_ROUND, ValueVT, Val,
      +      return DAG.getNode(ISD::FP_ROUND, DAG.getCurDebugLoc(), ValueVT, Val,
                                DAG.getIntPtrConstant(1));
      -    return DAG.getNode(ISD::FP_EXTEND, ValueVT, Val);
      +    return DAG.getNode(ISD::FP_EXTEND, DAG.getCurDebugLoc(), ValueVT, Val);
         }
       
         if (PartVT.getSizeInBits() == ValueVT.getSizeInBits())
      -    return DAG.getNode(ISD::BIT_CONVERT, ValueVT, Val);
      +    return DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), ValueVT, Val);
       
         assert(0 && "Unknown mismatch!");
         return SDValue();
      @@ -543,22 +546,22 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
             // If the parts cover more bits than the value has, promote the value.
             if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) {
               assert(NumParts == 1 && "Do not know what to promote to!");
      -        Val = DAG.getNode(ISD::FP_EXTEND, PartVT, Val);
      +        Val = DAG.getNode(ISD::FP_EXTEND, DAG.getCurDebugLoc(), PartVT, Val);
             } else if (PartVT.isInteger() && ValueVT.isInteger()) {
               ValueVT = MVT::getIntegerVT(NumParts * PartBits);
      -        Val = DAG.getNode(ExtendKind, ValueVT, Val);
      +        Val = DAG.getNode(ExtendKind, DAG.getCurDebugLoc(), ValueVT, Val);
             } else {
               assert(0 && "Unknown mismatch!");
             }
           } else if (PartBits == ValueVT.getSizeInBits()) {
             // Different types of the same size.
             assert(NumParts == 1 && PartVT != ValueVT);
      -      Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
      +      Val = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), PartVT, Val);
           } else if (NumParts * PartBits < ValueVT.getSizeInBits()) {
             // If the parts cover less bits than value has, truncate the value.
             if (PartVT.isInteger() && ValueVT.isInteger()) {
               ValueVT = MVT::getIntegerVT(NumParts * PartBits);
      -        Val = DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
      +        Val = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ValueVT, Val);
             } else {
               assert(0 && "Unknown mismatch!");
             }
      @@ -583,7 +586,7 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
             unsigned RoundParts = 1 << Log2_32(NumParts);
             unsigned RoundBits = RoundParts * PartBits;
             unsigned OddParts = NumParts - RoundParts;
      -      SDValue OddVal = DAG.getNode(ISD::SRL, ValueVT, Val,
      +      SDValue OddVal = DAG.getNode(ISD::SRL, DAG.getCurDebugLoc(), ValueVT, Val,
                                          DAG.getConstant(RoundBits,
                                                          TLI.getShiftAmountTy()));
             getCopyToParts(DAG, OddVal, Parts + RoundParts, OddParts, PartVT);
      @@ -592,12 +595,12 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
               std::reverse(Parts + RoundParts, Parts + NumParts);
             NumParts = RoundParts;
             ValueVT = MVT::getIntegerVT(NumParts * PartBits);
      -      Val = DAG.getNode(ISD::TRUNCATE, ValueVT, Val);
      +      Val = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ValueVT, Val);
           }
       
           // The number of parts is a power of 2.  Repeatedly bisect the value using
           // EXTRACT_ELEMENT.
      -    Parts[0] = DAG.getNode(ISD::BIT_CONVERT,
      +    Parts[0] = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), 
                                  MVT::getIntegerVT(ValueVT.getSizeInBits()),
                                  Val);
           for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) {
      @@ -607,14 +610,18 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
               SDValue &Part0 = Parts[i];
               SDValue &Part1 = Parts[i+StepSize/2];
       
      -        Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
      +        Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DAG.getCurDebugLoc(), 
      +                            ThisVT, Part0,
                                   DAG.getConstant(1, PtrVT));
      -        Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, ThisVT, Part0,
      +        Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DAG.getCurDebugLoc(), 
      +                            ThisVT, Part0,
                                   DAG.getConstant(0, PtrVT));
       
               if (ThisBits == PartBits && ThisVT != PartVT) {
      -          Part0 = DAG.getNode(ISD::BIT_CONVERT, PartVT, Part0);
      -          Part1 = DAG.getNode(ISD::BIT_CONVERT, PartVT, Part1);
      +          Part0 = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), 
      +                                                PartVT, Part0);
      +          Part1 = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), 
      +                                                PartVT, Part1);
               }
             }
           }
      @@ -629,12 +636,13 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
         if (NumParts == 1) {
           if (PartVT != ValueVT) {
             if (PartVT.isVector()) {
      -        Val = DAG.getNode(ISD::BIT_CONVERT, PartVT, Val);
      +        Val = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), PartVT, Val);
             } else {
               assert(ValueVT.getVectorElementType() == PartVT &&
                      ValueVT.getVectorNumElements() == 1 &&
                      "Only trivial vector-to-scalar conversions should get here!");
      -        Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, PartVT, Val,
      +        Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), 
      +                          PartVT, Val,
                                 DAG.getConstant(0, PtrVT));
             }
           }
      @@ -659,12 +667,12 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val,
         SmallVector Ops(NumIntermediates);
         for (unsigned i = 0; i != NumIntermediates; ++i)
           if (IntermediateVT.isVector())
      -      Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR,
      +      Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DAG.getCurDebugLoc(), 
                                  IntermediateVT, Val,
                                  DAG.getConstant(i * (NumElements / NumIntermediates),
                                                  PtrVT));
           else
      -      Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
      +      Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), 
                                  IntermediateVT, Val,
                                  DAG.getConstant(i, PtrVT));
       
      @@ -722,7 +730,7 @@ SDValue SelectionDAGLowering::getRoot() {
         }
       
         // Otherwise, we have to make a token factor node.
      -  SDValue Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
      +  SDValue Root = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), MVT::Other,
                                      &PendingLoads[0], PendingLoads.size());
         PendingLoads.clear();
         DAG.setRoot(Root);
      @@ -752,7 +760,7 @@ SDValue SelectionDAGLowering::getControlRoot() {
             PendingExports.push_back(Root);
         }
       
      -  Root = DAG.getNode(ISD::TokenFactor, MVT::Other,
      +  Root = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), MVT::Other,
                            &PendingExports[0],
                            PendingExports.size());
         PendingExports.clear();
      @@ -812,7 +820,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
       
           if (isa(C) && !isa(V->getType()) &&
               !V->getType()->isAggregateType())
      -      return N = DAG.getNode(ISD::UNDEF, VT);
      +      return N = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), VT);
       
           if (ConstantExpr *CE = dyn_cast(C)) {
             visit(CE->getOpcode(), *CE);
      @@ -845,7 +853,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
             for (unsigned i = 0; i != NumElts; ++i) {
               MVT EltVT = ValueVTs[i];
               if (isa(C))
      -          Constants[i] = DAG.getNode(ISD::UNDEF, EltVT);
      +          Constants[i] = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), EltVT);
               else if (EltVT.isFloatingPoint())
                 Constants[i] = DAG.getConstantFP(0, EltVT);
               else
      @@ -870,7 +878,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
       
             SDValue Op;
             if (isa(C))
      -        Op = DAG.getNode(ISD::UNDEF, EltVT);
      +        Op = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), EltVT);
             else if (EltVT.isFloatingPoint())
               Op = DAG.getConstantFP(0, EltVT);
             else
      @@ -879,7 +887,8 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
           }
       
           // Create a BUILD_VECTOR node.
      -    return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size());
      +    return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), 
      +                                    VT, &Ops[0], Ops.size());
         }
       
         // If this is a static alloca, generate it as the frameindex instead of
      @@ -902,7 +911,8 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
       
       void SelectionDAGLowering::visitRet(ReturnInst &I) {
         if (I.getNumOperands() == 0) {
      -    DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other, getControlRoot()));
      +    DAG.setRoot(DAG.getNode(ISD::RET, DAG.getCurDebugLoc(), 
      +                            MVT::Other, getControlRoot()));
           return;
         }
       
      @@ -951,7 +961,7 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) {
             }
           }
         }
      -  DAG.setRoot(DAG.getNode(ISD::RET, MVT::Other,
      +  DAG.setRoot(DAG.getNode(ISD::RET, DAG.getCurDebugLoc(), MVT::Other,
                                 &NewValues[0], NewValues.size()));
       }
       
      @@ -1191,7 +1201,8 @@ void SelectionDAGLowering::visitBr(BranchInst &I) {
       
           // If this is not a fall-through branch, emit the branch.
           if (Succ0MBB != NextBlock)
      -      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
      +      DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), 
      +                              MVT::Other, getControlRoot(),
                                     DAG.getBasicBlock(Succ0MBB)));
           return;
         }
      @@ -1270,7 +1281,8 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
             Cond = CondLHS;
           else if (CB.CmpRHS == ConstantInt::getFalse() && CB.CC == ISD::SETEQ) {
             SDValue True = DAG.getConstant(1, CondLHS.getValueType());
      -      Cond = DAG.getNode(ISD::XOR, CondLHS.getValueType(), CondLHS, True);
      +      Cond = DAG.getNode(ISD::XOR, DAG.getCurDebugLoc(), 
      +                         CondLHS.getValueType(), CondLHS, True);
           } else
             Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC);
         } else {
      @@ -1285,7 +1297,8 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
           if (cast(CB.CmpLHS)->isMinValue(true)) {
             Cond = DAG.getSetCC(MVT::i1, CmpOp, DAG.getConstant(High, VT), ISD::SETLE);
           } else {
      -      SDValue SUB = DAG.getNode(ISD::SUB, VT, CmpOp, DAG.getConstant(Low, VT));
      +      SDValue SUB = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), 
      +                                VT, CmpOp, DAG.getConstant(Low, VT));
             Cond = DAG.getSetCC(MVT::i1, SUB,
                                 DAG.getConstant(High-Low, VT), ISD::SETULE);
           }
      @@ -1307,10 +1320,12 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
         if (CB.TrueBB == NextBlock) {
           std::swap(CB.TrueBB, CB.FalseBB);
           SDValue True = DAG.getConstant(1, Cond.getValueType());
      -    Cond = DAG.getNode(ISD::XOR, Cond.getValueType(), Cond, True);
      +    Cond = DAG.getNode(ISD::XOR, DAG.getCurDebugLoc(), 
      +                       Cond.getValueType(), Cond, True);
         }
      -  SDValue BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(), Cond,
      -                                 DAG.getBasicBlock(CB.TrueBB));
      +  SDValue BrCond = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(),
      +                               MVT::Other, getControlRoot(), Cond,
      +                               DAG.getBasicBlock(CB.TrueBB));
       
         // If the branch was constant folded, fix up the CFG.
         if (BrCond.getOpcode() == ISD::BR) {
      @@ -1324,7 +1339,7 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) {
           if (CB.FalseBB == NextBlock)
             DAG.setRoot(BrCond);
           else
      -      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
      +      DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, BrCond,
                                     DAG.getBasicBlock(CB.FalseBB)));
         }
       }
      @@ -1336,7 +1351,8 @@ void SelectionDAGLowering::visitJumpTable(JumpTable &JT) {
         MVT PTy = TLI.getPointerTy();
         SDValue Index = DAG.getCopyFromReg(getControlRoot(), JT.Reg, PTy);
         SDValue Table = DAG.getJumpTable(JT.JTI, PTy);
      -  DAG.setRoot(DAG.getNode(ISD::BR_JT, MVT::Other, Index.getValue(1),
      +  DAG.setRoot(DAG.getNode(ISD::BR_JT, DAG.getCurDebugLoc(), 
      +                          MVT::Other, Index.getValue(1),
                                 Table, Index));
       }
       
      @@ -1349,7 +1365,7 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
         // difference between smallest and largest cases.
         SDValue SwitchOp = getValue(JTH.SValue);
         MVT VT = SwitchOp.getValueType();
      -  SDValue SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
      +  SDValue SUB = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), VT, SwitchOp,
                                   DAG.getConstant(JTH.First, VT));
       
         // The SDNode we just created, which holds the value being switched on minus
      @@ -1358,9 +1374,11 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
         // This value may be smaller or larger than the target's pointer type, and
         // therefore require extension or truncating.
         if (VT.bitsGT(TLI.getPointerTy()))
      -    SwitchOp = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), SUB);
      +    SwitchOp = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), 
      +                           TLI.getPointerTy(), SUB);
         else
      -    SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), SUB);
      +    SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), 
      +                           TLI.getPointerTy(), SUB);
       
         unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy());
         SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), JumpTableReg, SwitchOp);
      @@ -1380,13 +1398,14 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT,
         if (++BBI != CurMBB->getParent()->end())
           NextBlock = BBI;
       
      -  SDValue BrCond = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, CMP,
      +  SDValue BrCond = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(),
      +                               MVT::Other, CopyTo, CMP,
                                      DAG.getBasicBlock(JT.Default));
       
         if (JT.MBB == NextBlock)
           DAG.setRoot(BrCond);
         else
      -    DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrCond,
      +    DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, BrCond,
                                   DAG.getBasicBlock(JT.MBB)));
       }
       
      @@ -1396,7 +1415,7 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
         // Subtract the minimum value
         SDValue SwitchOp = getValue(B.SValue);
         MVT VT = SwitchOp.getValueType();
      -  SDValue SUB = DAG.getNode(ISD::SUB, VT, SwitchOp,
      +  SDValue SUB = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), VT, SwitchOp,
                                   DAG.getConstant(B.First, VT));
       
         // Check range
      @@ -1406,9 +1425,11 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
       
         SDValue ShiftOp;
         if (VT.bitsGT(TLI.getShiftAmountTy()))
      -    ShiftOp = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), SUB);
      +    ShiftOp = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), 
      +                          TLI.getShiftAmountTy(), SUB);
         else
      -    ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), SUB);
      +    ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), 
      +                          TLI.getShiftAmountTy(), SUB);
       
         B.Reg = FuncInfo.MakeReg(TLI.getShiftAmountTy());
         SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), B.Reg, ShiftOp);
      @@ -1425,13 +1446,14 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) {
         CurMBB->addSuccessor(B.Default);
         CurMBB->addSuccessor(MBB);
       
      -  SDValue BrRange = DAG.getNode(ISD::BRCOND, MVT::Other, CopyTo, RangeCmp,
      +  SDValue BrRange = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(),
      +                                MVT::Other, CopyTo, RangeCmp,
                                       DAG.getBasicBlock(B.Default));
       
         if (MBB == NextBlock)
           DAG.setRoot(BrRange);
         else
      -    DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, CopyTo,
      +    DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, CopyTo,
                                   DAG.getBasicBlock(MBB)));
       }
       
      @@ -1442,12 +1464,14 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
         // Make desired shift
         SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), Reg,
                                              TLI.getShiftAmountTy());
      -  SDValue SwitchVal = DAG.getNode(ISD::SHL, TLI.getPointerTy(),
      +  SDValue SwitchVal = DAG.getNode(ISD::SHL, DAG.getCurDebugLoc(), 
      +                                  TLI.getPointerTy(),
                                         DAG.getConstant(1, TLI.getPointerTy()),
                                         ShiftOp);
       
         // Emit bit tests and jumps
      -  SDValue AndOp = DAG.getNode(ISD::AND, TLI.getPointerTy(), SwitchVal,
      +  SDValue AndOp = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), 
      +                              TLI.getPointerTy(), SwitchVal,
                                     DAG.getConstant(B.Mask, TLI.getPointerTy()));
         SDValue AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp.getValueType()),
                                       AndOp, DAG.getConstant(0, TLI.getPointerTy()),
      @@ -1456,7 +1480,8 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
         CurMBB->addSuccessor(B.TargetBB);
         CurMBB->addSuccessor(NextMBB);
       
      -  SDValue BrAnd = DAG.getNode(ISD::BRCOND, MVT::Other, getControlRoot(),
      +  SDValue BrAnd = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(),
      +                              MVT::Other, getControlRoot(),
                                     AndCmp, DAG.getBasicBlock(B.TargetBB));
       
         // Set NextBlock to be the MBB immediately after the current one, if any.
      @@ -1469,7 +1494,7 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB,
         if (NextMBB == NextBlock)
           DAG.setRoot(BrAnd);
         else
      -    DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, BrAnd,
      +    DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, BrAnd,
                                   DAG.getBasicBlock(NextMBB)));
       }
       
      @@ -1497,7 +1522,8 @@ void SelectionDAGLowering::visitInvoke(InvokeInst &I) {
         CurMBB->addSuccessor(LandingPad);
       
         // Drop into normal successor.
      -  DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
      +  DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), 
      +                          MVT::Other, getControlRoot(),
                                 DAG.getBasicBlock(Return)));
       }
       
      @@ -2000,7 +2026,8 @@ void SelectionDAGLowering::visitSwitch(SwitchInst &SI) {
           // If this is not a fall-through branch, emit the branch.
           CurMBB->addSuccessor(Default);
           if (Default != NextBlock)
      -      DAG.setRoot(DAG.getNode(ISD::BR, MVT::Other, getControlRoot(),
      +      DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(),
      +                              MVT::Other, getControlRoot(),
                                     DAG.getBasicBlock(Default)));
           return;
         }
      @@ -2062,7 +2089,8 @@ void SelectionDAGLowering::visitSub(User &I) {
               Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size());
               if (CV == CNZ) {
                 SDValue Op2 = getValue(I.getOperand(1));
      -          setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
      +          setValue(&I, DAG.getNode(ISD::FNEG, DAG.getCurDebugLoc(), 
      +                                   Op2.getValueType(), Op2));
                 return;
               }
             }
      @@ -2072,7 +2100,8 @@ void SelectionDAGLowering::visitSub(User &I) {
           if (ConstantFP *CFP = dyn_cast(I.getOperand(0)))
             if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) {
               SDValue Op2 = getValue(I.getOperand(1));
      -        setValue(&I, DAG.getNode(ISD::FNEG, Op2.getValueType(), Op2));
      +        setValue(&I, DAG.getNode(ISD::FNEG, DAG.getCurDebugLoc(), 
      +                                 Op2.getValueType(), Op2));
               return;
             }
         }
      @@ -2084,7 +2113,8 @@ void SelectionDAGLowering::visitBinary(User &I, unsigned OpCode) {
         SDValue Op1 = getValue(I.getOperand(0));
         SDValue Op2 = getValue(I.getOperand(1));
       
      -  setValue(&I, DAG.getNode(OpCode, Op1.getValueType(), Op1, Op2));
      +  setValue(&I, DAG.getNode(OpCode, DAG.getCurDebugLoc(), 
      +                           Op1.getValueType(), Op1, Op2));
       }
       
       void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
      @@ -2092,12 +2122,15 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) {
         SDValue Op2 = getValue(I.getOperand(1));
         if (!isa(I.getType())) {
           if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType()))
      -      Op2 = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), Op2);
      +      Op2 = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), 
      +                        TLI.getShiftAmountTy(), Op2);
           else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType()))
      -      Op2 = DAG.getNode(ISD::ANY_EXTEND, TLI.getShiftAmountTy(), Op2);
      +      Op2 = DAG.getNode(ISD::ANY_EXTEND, DAG.getCurDebugLoc(), 
      +                        TLI.getShiftAmountTy(), Op2);
         }
       
      -  setValue(&I, DAG.getNode(Opcode, Op1.getValueType(), Op1, Op2));
      +  setValue(&I, DAG.getNode(Opcode, DAG.getCurDebugLoc(), 
      +                           Op1.getValueType(), Op1, Op2));
       }
       
       void SelectionDAGLowering::visitICmp(User &I) {
      @@ -2161,11 +2194,12 @@ void SelectionDAGLowering::visitSelect(User &I) {
           SDValue FalseVal = getValue(I.getOperand(2));
       
           for (unsigned i = 0; i != NumValues; ++i)
      -      Values[i] = DAG.getNode(ISD::SELECT, TrueVal.getValueType(), Cond,
      +      Values[i] = DAG.getNode(ISD::SELECT, DAG.getCurDebugLoc(), 
      +                              TrueVal.getValueType(), Cond,
                                     SDValue(TrueVal.getNode(), TrueVal.getResNo() + i),
                                     SDValue(FalseVal.getNode(), FalseVal.getResNo() + i));
       
      -    setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
      +    setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), 
                                    DAG.getVTList(&ValueVTs[0], NumValues),
                                    &Values[0], NumValues));
         }
      @@ -2176,7 +2210,7 @@ void SelectionDAGLowering::visitTrunc(User &I) {
         // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest).
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitZExt(User &I) {
      @@ -2184,7 +2218,7 @@ void SelectionDAGLowering::visitZExt(User &I) {
         // ZExt also can't be a cast to bool for same reason. So, nothing much to do
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitSExt(User &I) {
      @@ -2192,49 +2226,50 @@ void SelectionDAGLowering::visitSExt(User &I) {
         // SExt also can't be a cast to bool for same reason. So, nothing much to do
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitFPTrunc(User &I) {
         // FPTrunc is never a no-op cast, no need to check
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::FP_ROUND, DestVT, N, DAG.getIntPtrConstant(0)));
      +  setValue(&I, DAG.getNode(ISD::FP_ROUND, DAG.getCurDebugLoc(), 
      +                           DestVT, N, DAG.getIntPtrConstant(0)));
       }
       
       void SelectionDAGLowering::visitFPExt(User &I){
         // FPTrunc is never a no-op cast, no need to check
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::FP_EXTEND, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::FP_EXTEND, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitFPToUI(User &I) {
         // FPToUI is never a no-op cast, no need to check
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitFPToSI(User &I) {
         // FPToSI is never a no-op cast, no need to check
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitUIToFP(User &I) {
         // UIToFP is never a no-op cast, no need to check
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitSIToFP(User &I){
         // SIToFP is never a no-op cast, no need to check
         SDValue N = getValue(I.getOperand(0));
         MVT DestVT = TLI.getValueType(I.getType());
      -  setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DestVT, N));
      +  setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DAG.getCurDebugLoc(), DestVT, N));
       }
       
       void SelectionDAGLowering::visitPtrToInt(User &I) {
      @@ -2245,10 +2280,10 @@ void SelectionDAGLowering::visitPtrToInt(User &I) {
         MVT DestVT = TLI.getValueType(I.getType());
         SDValue Result;
         if (DestVT.bitsLT(SrcVT))
      -    Result = DAG.getNode(ISD::TRUNCATE, DestVT, N);
      +    Result = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), DestVT, N);
         else
           // Note: ZERO_EXTEND can handle cases where the sizes are equal too
      -    Result = DAG.getNode(ISD::ZERO_EXTEND, DestVT, N);
      +    Result = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), DestVT, N);
         setValue(&I, Result);
       }
       
      @@ -2259,10 +2294,11 @@ void SelectionDAGLowering::visitIntToPtr(User &I) {
         MVT SrcVT = N.getValueType();
         MVT DestVT = TLI.getValueType(I.getType());
         if (DestVT.bitsLT(SrcVT))
      -    setValue(&I, DAG.getNode(ISD::TRUNCATE, DestVT, N));
      +    setValue(&I, DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), DestVT, N));
         else
           // Note: ZERO_EXTEND can handle cases where the sizes are equal too
      -    setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DestVT, N));
      +    setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), 
      +                             DestVT, N));
       }
       
       void SelectionDAGLowering::visitBitCast(User &I) {
      @@ -2272,7 +2308,8 @@ void SelectionDAGLowering::visitBitCast(User &I) {
         // BitCast assures us that source and destination are the same size so this
         // is either a BIT_CONVERT or a no-op.
         if (DestVT != N.getValueType())
      -    setValue(&I, DAG.getNode(ISD::BIT_CONVERT, DestVT, N)); // convert types
      +    setValue(&I, DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), 
      +                             DestVT, N)); // convert types
         else
           setValue(&I, N); // noop cast.
       }
      @@ -2280,19 +2317,21 @@ void SelectionDAGLowering::visitBitCast(User &I) {
       void SelectionDAGLowering::visitInsertElement(User &I) {
         SDValue InVec = getValue(I.getOperand(0));
         SDValue InVal = getValue(I.getOperand(1));
      -  SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
      +  SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), 
      +                                TLI.getPointerTy(),
                                       getValue(I.getOperand(2)));
       
      -  setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT,
      +  setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, DAG.getCurDebugLoc(), 
                                  TLI.getValueType(I.getType()),
                                  InVec, InVal, InIdx));
       }
       
       void SelectionDAGLowering::visitExtractElement(User &I) {
         SDValue InVec = getValue(I.getOperand(0));
      -  SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(),
      +  SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), 
      +                                TLI.getPointerTy(),
                                       getValue(I.getOperand(1)));
      -  setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT,
      +  setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(),
                                  TLI.getValueType(I.getType()), InVec, InIdx));
       }
       
      @@ -2322,7 +2361,8 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
         int SrcNumElts = SrcVT.getVectorNumElements();
       
         if (SrcNumElts == MaskNumElts) {
      -    setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
      +    setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, DAG.getCurDebugLoc(), 
      +                             VT, Src1, Src2, Mask));
           return;
         }
       
      @@ -2335,13 +2375,14 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
           // lengths match.
           if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) {
             // The shuffle is concatenating two vectors together.
      -      setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, VT, Src1, Src2));
      +      setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, DAG.getCurDebugLoc(), 
      +                               VT, Src1, Src2));
             return;
           }
       
           // Pad both vectors with undefs to make them the same length as the mask.
           unsigned NumConcat = MaskNumElts / SrcNumElts;
      -    SDValue UndefVal = DAG.getNode(ISD::UNDEF, SrcVT);
      +    SDValue UndefVal = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), SrcVT);
       
           SDValue* MOps1 = new SDValue[NumConcat];
           SDValue* MOps2 = new SDValue[NumConcat];
      @@ -2351,8 +2392,10 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
             MOps1[i] = UndefVal;
             MOps2[i] = UndefVal;
           }
      -    Src1 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps1, NumConcat);
      -    Src2 = DAG.getNode(ISD::CONCAT_VECTORS, VT, MOps2, NumConcat);
      +    Src1 = DAG.getNode(ISD::CONCAT_VECTORS, DAG.getCurDebugLoc(), 
      +                       VT, MOps1, NumConcat);
      +    Src2 = DAG.getNode(ISD::CONCAT_VECTORS, DAG.getCurDebugLoc(), 
      +                       VT, MOps2, NumConcat);
       
           delete [] MOps1;
           delete [] MOps2;
      @@ -2371,10 +2414,12 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
                                                     MaskEltVT));
             }
           }
      -    Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
      +    Mask = DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), 
      +                       Mask.getValueType(),
                              &MappedOps[0], MappedOps.size());
       
      -    setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
      +    setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, DAG.getCurDebugLoc(), 
      +                             VT, Src1, Src2, Mask));
           return;
         }
       
      @@ -2439,7 +2484,8 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
           }
       
           if (RangeUse[0] == 0 && RangeUse[0] == 0) {
      -      setValue(&I, DAG.getNode(ISD::UNDEF, VT));  // Vectors are not used.
      +      setValue(&I, DAG.getNode(ISD::UNDEF, 
      +                          DAG.getCurDebugLoc(), VT));  // Vectors are not used.
             return;
           }
           else if (RangeUse[0] < 2 && RangeUse[1] < 2) {
      @@ -2447,10 +2493,10 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
             for (int Input=0; Input < 2; ++Input) {
               SDValue& Src = Input == 0 ? Src1 : Src2;
               if (RangeUse[Input] == 0) {
      -          Src = DAG.getNode(ISD::UNDEF, VT);
      +          Src = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), VT);
               } else {
      -          Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, VT, Src,
      -                            DAG.getIntPtrConstant(StartIdx[Input]));
      +          Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DAG.getCurDebugLoc(), VT,
      +                            Src, DAG.getIntPtrConstant(StartIdx[Input]));
               }
             }
             // Calculate new mask.
      @@ -2469,9 +2515,11 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
                 }
               }
             }
      -      Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getValueType(),
      +      Mask = DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), 
      +                         Mask.getValueType(),
                                &MappedOps[0], MappedOps.size());
      -      setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Src1, Src2, Mask));
      +      setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, DAG.getCurDebugLoc(), 
      +                               VT, Src1, Src2, Mask));
             return;
           }
         }
      @@ -2485,19 +2533,21 @@ void SelectionDAGLowering::visitShuffleVector(User &I) {
         for (int i = 0; i != MaskNumElts; ++i) {
           SDValue Arg = Mask.getOperand(i);
           if (Arg.getOpcode() == ISD::UNDEF) {
      -      Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT));
      +      Ops.push_back(DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), EltVT));
           } else {
             assert(isa(Arg) && "Invalid VECTOR_SHUFFLE mask!");
             int Idx = cast(Arg)->getZExtValue();
             if (Idx < SrcNumElts)
      -        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src1,
      -                                  DAG.getConstant(Idx, PtrVT)));
      +        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(),
      +                                  EltVT, Src1, DAG.getConstant(Idx, PtrVT)));
             else
      -        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Src2,
      +        Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(),
      +                                  EltVT, Src2, 
                                         DAG.getConstant(Idx - SrcNumElts, PtrVT)));
           }
         }
      -  setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()));
      +  setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), 
      +                           VT, &Ops[0], Ops.size()));
       }
       
       void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
      @@ -2525,18 +2575,21 @@ void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) {
         unsigned i = 0;
         // Copy the beginning value(s) from the original aggregate.
         for (; i != LinearIndex; ++i)
      -    Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
      +    Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), 
      +                                        AggValueVTs[i]) :
                       SDValue(Agg.getNode(), Agg.getResNo() + i);
         // Copy values from the inserted value(s).
         for (; i != LinearIndex + NumValValues; ++i)
      -    Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
      +    Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), 
      +                                        AggValueVTs[i]) :
                       SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex);
         // Copy remaining value(s) from the original aggregate.
         for (; i != NumAggValues; ++i)
      -    Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, AggValueVTs[i]) :
      +    Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), 
      +                                        AggValueVTs[i]) :
                       SDValue(Agg.getNode(), Agg.getResNo() + i);
       
      -  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
      +  setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), 
                                  DAG.getVTList(&AggValueVTs[0], NumAggValues),
                                  &Values[0], NumAggValues));
       }
      @@ -2561,11 +2614,11 @@ void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) {
         for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i)
           Values[i - LinearIndex] =
             OutOfUndef ?
      -        DAG.getNode(ISD::UNDEF,
      +        DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), 
                           Agg.getNode()->getValueType(Agg.getResNo() + i)) :
               SDValue(Agg.getNode(), Agg.getResNo() + i);
       
      -  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
      +  setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), 
                                  DAG.getVTList(&ValValueVTs[0], NumValValues),
                                  &Values[0], NumValValues));
       }
      @@ -2583,7 +2636,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
             if (Field) {
               // N = N + Offset
               uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field);
      -        N = DAG.getNode(ISD::ADD, N.getValueType(), N,
      +        N = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), N.getValueType(), N,
                               DAG.getIntPtrConstant(Offset));
             }
             Ty = StTy->getElementType(Field);
      @@ -2595,7 +2648,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
               if (CI->getZExtValue() == 0) continue;
               uint64_t Offs =
                   TD->getTypePaddedSize(Ty)*cast(CI)->getSExtValue();
      -        N = DAG.getNode(ISD::ADD, N.getValueType(), N,
      +        N = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), N.getValueType(), N,
                               DAG.getIntPtrConstant(Offs));
               continue;
             }
      @@ -2607,24 +2660,29 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) {
             // If the index is smaller or larger than intptr_t, truncate or extend
             // it.
             if (IdxN.getValueType().bitsLT(N.getValueType()))
      -        IdxN = DAG.getNode(ISD::SIGN_EXTEND, N.getValueType(), IdxN);
      +        IdxN = DAG.getNode(ISD::SIGN_EXTEND, DAG.getCurDebugLoc(), 
      +                           N.getValueType(), IdxN);
             else if (IdxN.getValueType().bitsGT(N.getValueType()))
      -        IdxN = DAG.getNode(ISD::TRUNCATE, N.getValueType(), IdxN);
      +        IdxN = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), 
      +                           N.getValueType(), IdxN);
       
             // If this is a multiply by a power of two, turn it into a shl
             // immediately.  This is a very common case.
             if (ElementSize != 1) {
               if (isPowerOf2_64(ElementSize)) {
                 unsigned Amt = Log2_64(ElementSize);
      -          IdxN = DAG.getNode(ISD::SHL, N.getValueType(), IdxN,
      +          IdxN = DAG.getNode(ISD::SHL, DAG.getCurDebugLoc(), 
      +                             N.getValueType(), IdxN,
                                    DAG.getConstant(Amt, TLI.getShiftAmountTy()));
               } else {
                 SDValue Scale = DAG.getIntPtrConstant(ElementSize);
      -          IdxN = DAG.getNode(ISD::MUL, N.getValueType(), IdxN, Scale);
      +          IdxN = DAG.getNode(ISD::MUL, DAG.getCurDebugLoc(), 
      +                             N.getValueType(), IdxN, Scale);
               }
             }
       
      -      N = DAG.getNode(ISD::ADD, N.getValueType(), N, IdxN);
      +      N = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), 
      +                      N.getValueType(), N, IdxN);
           }
         }
         setValue(&I, N);
      @@ -2645,11 +2703,13 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
         SDValue AllocSize = getValue(I.getArraySize());
         MVT IntPtr = TLI.getPointerTy();
         if (IntPtr.bitsLT(AllocSize.getValueType()))
      -    AllocSize = DAG.getNode(ISD::TRUNCATE, IntPtr, AllocSize);
      +    AllocSize = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), 
      +                            IntPtr, AllocSize);
         else if (IntPtr.bitsGT(AllocSize.getValueType()))
      -    AllocSize = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, AllocSize);
      +    AllocSize = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), 
      +                            IntPtr, AllocSize);
       
      -  AllocSize = DAG.getNode(ISD::MUL, IntPtr, AllocSize,
      +  AllocSize = DAG.getNode(ISD::MUL, DAG.getCurDebugLoc(), IntPtr, AllocSize,
                                 DAG.getIntPtrConstant(TySize));
       
         // Handle alignment.  If the requested alignment is less than or equal to
      @@ -2662,16 +2722,19 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) {
       
         // Round the size of the allocation up to the stack alignment size
         // by add SA-1 to the size.
      -  AllocSize = DAG.getNode(ISD::ADD, AllocSize.getValueType(), AllocSize,
      +  AllocSize = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), 
      +                          AllocSize.getValueType(), AllocSize,
                                 DAG.getIntPtrConstant(StackAlign-1));
         // Mask out the low bits for alignment purposes.
      -  AllocSize = DAG.getNode(ISD::AND, AllocSize.getValueType(), AllocSize,
      +  AllocSize = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), 
      +                          AllocSize.getValueType(), AllocSize,
                                 DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1)));
       
         SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) };
         const MVT *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(),
                                                           MVT::Other);
      -  SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, VTs, 2, Ops, 3);
      +  SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, DAG.getCurDebugLoc(), 
      +                            VTs, 2, Ops, 3);
         setValue(&I, DSA);
         DAG.setRoot(DSA.getValue(1));
       
      @@ -2713,8 +2776,9 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
         SmallVector Chains(NumValues);
         MVT PtrVT = Ptr.getValueType();
         for (unsigned i = 0; i != NumValues; ++i) {
      -    SDValue L = DAG.getLoad(ValueVTs[i], Root,
      -                              DAG.getNode(ISD::ADD, PtrVT, Ptr,
      +    SDValue L = DAG.getLoad(ValueVTs[i], DAG.getCurDebugLoc(), Root,
      +                              DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), 
      +                                          PtrVT, Ptr,
                                                 DAG.getConstant(Offsets[i], PtrVT)),
                                     SV, Offsets[i],
                                     isVolatile, Alignment);
      @@ -2723,7 +2787,8 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
         }
       
         if (!ConstantMemory) {
      -    SDValue Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
      +    SDValue Chain = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), 
      +                                  MVT::Other,
                                         &Chains[0], NumValues);
           if (isVolatile)
             DAG.setRoot(Chain);
      @@ -2731,7 +2796,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) {
             PendingLoads.push_back(Chain);
         }
       
      -  setValue(&I, DAG.getNode(ISD::MERGE_VALUES,
      +  setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), 
                                  DAG.getVTList(&ValueVTs[0], NumValues),
                                  &Values[0], NumValues));
       }
      @@ -2760,13 +2825,16 @@ void SelectionDAGLowering::visitStore(StoreInst &I) {
         bool isVolatile = I.isVolatile();
         unsigned Alignment = I.getAlignment();
         for (unsigned i = 0; i != NumValues; ++i)
      -    Chains[i] = DAG.getStore(Root, SDValue(Src.getNode(), Src.getResNo() + i),
      -                             DAG.getNode(ISD::ADD, PtrVT, Ptr,
      +    Chains[i] = DAG.getStore(Root, DAG.getCurDebugLoc(),
      +                             SDValue(Src.getNode(), Src.getResNo() + i),
      +                             DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), 
      +                                         PtrVT, Ptr,
                                                DAG.getConstant(Offsets[i], PtrVT)),
                                    PtrV, Offsets[i],
                                    isVolatile, Alignment);
       
      -  DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumValues));
      +  DAG.setRoot(DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), 
      +                          MVT::Other, &Chains[0], NumValues));
       }
       
       /// visitTargetIntrinsic - Lower a call of a target intrinsic to an INTRINSIC
      @@ -2826,20 +2894,24 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
         SDValue Result;
         if (IsTgtIntrinsic) {
           // This is target intrinsic that touches memory
      -    Result = DAG.getMemIntrinsicNode(Info.opc, VTList, VTs.size(),
      +    Result = DAG.getMemIntrinsicNode(Info.opc, DAG.getCurDebugLoc(),
      +                                     VTList, VTs.size(),
                                            &Ops[0], Ops.size(),
                                            Info.memVT, Info.ptrVal, Info.offset,
                                            Info.align, Info.vol,
                                            Info.readMem, Info.writeMem);
         }
         else if (!HasChain)
      -    Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, VTList, VTs.size(),
      +    Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DAG.getCurDebugLoc(), 
      +                         VTList, VTs.size(),
                                &Ops[0], Ops.size());
         else if (I.getType() != Type::VoidTy)
      -    Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, VTList, VTs.size(),
      +    Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DAG.getCurDebugLoc(), 
      +                         VTList, VTs.size(),
                                &Ops[0], Ops.size());
         else
      -    Result = DAG.getNode(ISD::INTRINSIC_VOID, VTList, VTs.size(),
      +    Result = DAG.getNode(ISD::INTRINSIC_VOID, DAG.getCurDebugLoc(), 
      +                         VTList, VTs.size(),
                                &Ops[0], Ops.size());
       
         if (HasChain) {
      @@ -2852,7 +2924,7 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I,
         if (I.getType() != Type::VoidTy) {
           if (const VectorType *PTy = dyn_cast(I.getType())) {
             MVT VT = TLI.getValueType(PTy);
      -      Result = DAG.getNode(ISD::BIT_CONVERT, VT, Result);
      +      Result = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), VT, Result);
           }
           setValue(&I, Result);
         }
      @@ -2933,11 +3005,11 @@ void AddCatchInfo(CallInst &I, MachineModuleInfo *MMI,
       /// where Op is the hexidecimal representation of floating point value.
       static SDValue
       GetSignificand(SelectionDAG &DAG, SDValue Op) {
      -  SDValue t1 = DAG.getNode(ISD::AND, MVT::i32, Op,
      +  SDValue t1 = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), MVT::i32, Op,
                                  DAG.getConstant(0x007fffff, MVT::i32));
      -  SDValue t2 = DAG.getNode(ISD::OR, MVT::i32, t1,
      +  SDValue t2 = DAG.getNode(ISD::OR, DAG.getCurDebugLoc(), MVT::i32, t1,
                                  DAG.getConstant(0x3f800000, MVT::i32));
      -  return DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t2);
      +  return DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), MVT::f32, t2);
       }
       
       /// GetExponent - Get the exponent:
      @@ -2947,11 +3019,11 @@ GetSignificand(SelectionDAG &DAG, SDValue Op) {
       /// where Op is the hexidecimal representation of floating point value.
       static SDValue
       GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI) {
      -  SDValue t0 = DAG.getNode(ISD::AND, MVT::i32, Op,
      +  SDValue t0 = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), MVT::i32, Op,
                                  DAG.getConstant(0x7f800000, MVT::i32));
      -  SDValue t1 = DAG.getNode(ISD::SRL, MVT::i32, t0,
      +  SDValue t1 = DAG.getNode(ISD::SRL, DAG.getCurDebugLoc(), MVT::i32, t0,
                                  DAG.getConstant(23, TLI.getShiftAmountTy()));
      -  SDValue t2 = DAG.getNode(ISD::SUB, MVT::i32, t1,
      +  SDValue t2 = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), MVT::i32, t1,
                                  DAG.getConstant(127, MVT::i32));
         return DAG.getNode(ISD::SINT_TO_FP, MVT::f32, t2);
       }
      @@ -2969,7 +3041,8 @@ const char *
       SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) {
         SDValue Root = getRoot();
         SDValue L =
      -    DAG.getAtomic(Op, getValue(I.getOperand(2)).getValueType().getSimpleVT(),
      +    DAG.getAtomic(Op, DAG.getCurDebugLoc(),
      +                  getValue(I.getOperand(2)).getValueType().getSimpleVT(),
                         Root,
                         getValue(I.getOperand(1)),
                         getValue(I.getOperand(2)),
      @@ -2988,7 +3061,8 @@ SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
         MVT ValueVTs[] = { Op1.getValueType(), MVT::i1 };
         SDValue Ops[] = { Op1, Op2 };
       
      -  SDValue Result = DAG.getNode(Op, DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
      +  SDValue Result = DAG.getNode(Op, DAG.getCurDebugLoc(), 
      +                               DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2);
       
         setValue(&I, Result);
         return 0;
      @@ -2999,6 +3073,7 @@ SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) {
       void
       SelectionDAGLowering::visitExp(CallInst &I) {
         SDValue result;
      +  DebugLoc dl = DAG.getCurDebugLoc();
       
         if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
             LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
      @@ -3009,16 +3084,16 @@ SelectionDAGLowering::visitExp(CallInst &I) {
           //
           //   #define LOG2OFe 1.4426950f
           //   IntegerPartOfX = ((int32_t)(X * LOG2OFe));
      -    SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, Op,
      +    SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op,
                                    getF32Constant(DAG, 0x3fb8aa3b));
      -    SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, MVT::i32, t0);
      +    SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, t0);
       
           //   FractionalPartOfX = (X * LOG2OFe) - (float)IntegerPartOfX;
      -    SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, MVT::f32, IntegerPartOfX);
      -    SDValue X = DAG.getNode(ISD::FSUB, MVT::f32, t0, t1);
      +    SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
      +    SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
       
           //   IntegerPartOfX <<= 23;
      -    IntegerPartOfX = DAG.getNode(ISD::SHL, MVT::i32, IntegerPartOfX,
      +    IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
                                        DAG.getConstant(23, TLI.getShiftAmountTy()));
       
           if (LimitFloatPrecision <= 6) {
      @@ -3029,20 +3104,20 @@ SelectionDAGLowering::visitExp(CallInst &I) {
             //       (0.735607626f + 0.252464424f * x) * x;
             //
             // error 0.0144103317, which is 6 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3e814304));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3f3c50c8));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f7f5e7e));
      -      SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t5);
      +      SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, dl,MVT::i32, t5);
       
             // Add the exponent into the result in integer domain.
      -      SDValue t6 = DAG.getNode(ISD::ADD, MVT::i32,
      +      SDValue t6 = DAG.getNode(ISD::ADD, dl, MVT::i32,
                                      TwoToFracPartOfX, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t6);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t6);
           } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
             // For floating-point precision of 12:
             //
      @@ -3052,23 +3127,23 @@ SelectionDAGLowering::visitExp(CallInst &I) {
             //         (0.224338339f + 0.792043434e-1f * x) * x) * x;
             //
             // 0.000107046256 error, which is 13 to 14 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3da235e3));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3e65b8f3));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f324b07));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3f7ff8fd));
      -      SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t7);
      +      SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, dl,MVT::i32, t7);
       
             // Add the exponent into the result in integer domain.
      -      SDValue t8 = DAG.getNode(ISD::ADD, MVT::i32,
      +      SDValue t8 = DAG.getNode(ISD::ADD, dl, MVT::i32,
                                      TwoToFracPartOfX, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t8);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t8);
           } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
             // For floating-point precision of 18:
             //
      @@ -3081,36 +3156,37 @@ SelectionDAGLowering::visitExp(CallInst &I) {
             //               (0.136028312e-2f + 0.157059148e-3f *x)*x)*x)*x)*x)*x;
             //
             // error 2.47208000*10^(-7), which is better than 18 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3924b03e));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3ab24b87));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3c1d8c17));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3d634a1d));
      -      SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
      -      SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
      +      SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
      +      SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
                                      getF32Constant(DAG, 0x3e75fe14));
      -      SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
      -      SDValue t11 = DAG.getNode(ISD::FADD, MVT::f32, t10,
      +      SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
      +      SDValue t11 = DAG.getNode(ISD::FADD, dl, MVT::f32, t10,
                                       getF32Constant(DAG, 0x3f317234));
      -      SDValue t12 = DAG.getNode(ISD::FMUL, MVT::f32, t11, X);
      -      SDValue t13 = DAG.getNode(ISD::FADD, MVT::f32, t12,
      +      SDValue t12 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t11, X);
      +      SDValue t13 = DAG.getNode(ISD::FADD, dl, MVT::f32, t12,
                                       getF32Constant(DAG, 0x3f800000));
      -      SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t13);
      +      SDValue TwoToFracPartOfX = DAG.getNode(ISD::BIT_CONVERT, dl, 
      +                                             MVT::i32, t13);
       
             // Add the exponent into the result in integer domain.
      -      SDValue t14 = DAG.getNode(ISD::ADD, MVT::i32,
      +      SDValue t14 = DAG.getNode(ISD::ADD, dl, MVT::i32,
                                       TwoToFracPartOfX, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, t14);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t14);
           }
         } else {
           // No special expansion.
      -    result = DAG.getNode(ISD::FEXP,
      +    result = DAG.getNode(ISD::FEXP, dl,
                                getValue(I.getOperand(1)).getValueType(),
                                getValue(I.getOperand(1)));
         }
      @@ -3123,15 +3199,16 @@ SelectionDAGLowering::visitExp(CallInst &I) {
       void
       SelectionDAGLowering::visitLog(CallInst &I) {
         SDValue result;
      +  DebugLoc dl = DAG.getCurDebugLoc();
       
         if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
             LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
           SDValue Op = getValue(I.getOperand(1));
      -    SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
      +    SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
       
           // Scale the exponent by log(2) [0.69314718f].
           SDValue Exp = GetExponent(DAG, Op1, TLI);
      -    SDValue LogOfExponent = DAG.getNode(ISD::FMUL, MVT::f32, Exp,
      +    SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
                                               getF32Constant(DAG, 0x3f317218));
       
           // Get the significand and build it into a floating-point number with
      @@ -3146,15 +3223,16 @@ SelectionDAGLowering::visitLog(CallInst &I) {
             //       (1.4034025f - 0.23903021f * x) * x;
             //
             // error 0.0034276066, which is better than 8 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbe74c456));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3fb3a2b1));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                                 getF32Constant(DAG, 0x3f949a29));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, LogOfMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, LogOfMantissa);
           } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
             // For floating-point precision of 12:
             //
      @@ -3165,21 +3243,22 @@ SelectionDAGLowering::visitLog(CallInst &I) {
             //           (0.44717955f - 0.56570851e-1f * x) * x) * x) * x;
             //
             // error 0.000061011436, which is 14 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbd67b6d6));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3ee4f4b8));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3fbc278b));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x40348e95));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
                                                 getF32Constant(DAG, 0x3fdef31a));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, LogOfMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, LogOfMantissa);
           } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
             // For floating-point precision of 18:
             //
      @@ -3192,31 +3271,32 @@ SelectionDAGLowering::visitLog(CallInst &I) {
             //               (0.19073739f - 0.17809712e-1f * x) * x) * x) * x) * x)*x;
             //
             // error 0.0000023660568, which is better than 18 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbc91e5ac));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3e4350aa));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3f60d3e3));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x4011cdf0));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FSUB, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x406cfd1c));
      -      SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
      -      SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
      +      SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
      +      SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
                                      getF32Constant(DAG, 0x408797cb));
      -      SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
      -      SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t10,
      +      SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
      +      SDValue LogOfMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t10,
                                                 getF32Constant(DAG, 0x4006dcab));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, LogOfMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, LogOfMantissa);
           }
         } else {
           // No special expansion.
      -    result = DAG.getNode(ISD::FLOG,
      +    result = DAG.getNode(ISD::FLOG, dl,
                                getValue(I.getOperand(1)).getValueType(),
                                getValue(I.getOperand(1)));
         }
      @@ -3229,11 +3309,12 @@ SelectionDAGLowering::visitLog(CallInst &I) {
       void
       SelectionDAGLowering::visitLog2(CallInst &I) {
         SDValue result;
      +  DebugLoc dl = DAG.getCurDebugLoc();
       
         if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
             LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
           SDValue Op = getValue(I.getOperand(1));
      -    SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
      +    SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
       
           // Get the exponent.
           SDValue LogOfExponent = GetExponent(DAG, Op1, TLI);
      @@ -3250,15 +3331,16 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
             //   Log2ofMantissa = -1.6749035f + (2.0246817f - .34484768f * x) * x;
             //
             // error 0.0049451742, which is more than 7 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbeb08fe0));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x40019463));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                                  getF32Constant(DAG, 0x3fd6633d));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log2ofMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, Log2ofMantissa);
           } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
             // For floating-point precision of 12:
             //
      @@ -3269,21 +3351,22 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
             //           (.645142248f - 0.816157886e-1f * x) * x) * x) * x;
             //
             // error 0.0000876136000, which is better than 13 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbda7262e));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3f25280b));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x4007b923));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x40823e2f));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
                                                  getF32Constant(DAG, 0x4020d29c));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log2ofMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, Log2ofMantissa);
           } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
             // For floating-point precision of 18:
             //
      @@ -3297,31 +3380,32 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
             //                 0.25691327e-1f * x) * x) * x) * x) * x) * x;
             //
             // error 0.0000018516, which is better than 18 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbcd2769e));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3e8ce0b9));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue t3 = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue t3 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3fa22ae7));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x40525723));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FSUB, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x40aaf200));
      -      SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
      -      SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
      +      SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
      +      SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
                                      getF32Constant(DAG, 0x40c39dad));
      -      SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
      -      SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t10,
      +      SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
      +      SDValue Log2ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t10,
                                                  getF32Constant(DAG, 0x4042902c));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log2ofMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, Log2ofMantissa);
           }
         } else {
           // No special expansion.
      -    result = DAG.getNode(ISD::FLOG2,
      +    result = DAG.getNode(ISD::FLOG2, dl,
                                getValue(I.getOperand(1)).getValueType(),
                                getValue(I.getOperand(1)));
         }
      @@ -3334,15 +3418,16 @@ SelectionDAGLowering::visitLog2(CallInst &I) {
       void
       SelectionDAGLowering::visitLog10(CallInst &I) {
         SDValue result;
      +  DebugLoc dl = DAG.getCurDebugLoc();
       
         if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
             LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
           SDValue Op = getValue(I.getOperand(1));
      -    SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op);
      +    SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op);
       
           // Scale the exponent by log10(2) [0.30102999f].
           SDValue Exp = GetExponent(DAG, Op1, TLI);
      -    SDValue LogOfExponent = DAG.getNode(ISD::FMUL, MVT::f32, Exp,
      +    SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp,
                                               getF32Constant(DAG, 0x3e9a209a));
       
           // Get the significand and build it into a floating-point number with
      @@ -3357,15 +3442,16 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
             //       (0.60948995f - 0.10380950f * x) * x;
             //
             // error 0.0014886165, which is 6 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0xbdd49a13));
      -      SDValue t1 = DAG.getNode(ISD::FADD, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FADD, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3f1c0789));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t2,
                                                   getF32Constant(DAG, 0x3f011300));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log10ofMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, Log10ofMantissa);
           } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
             // For floating-point precision of 12:
             //
      @@ -3375,18 +3461,19 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
             //         (-0.31664806f + 0.47637168e-1f * x) * x) * x;
             //
             // error 0.00019228036, which is better than 12 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3d431f31));
      -      SDValue t1 = DAG.getNode(ISD::FSUB, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3ea21fb2));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3f6ae232));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t4,
                                                   getF32Constant(DAG, 0x3f25f7c3));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log10ofMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, Log10ofMantissa);
           } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
             // For floating-point precision of 18:
             //
      @@ -3398,28 +3485,29 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
             //             (-0.12539807f + 0.13508273e-1f * x) * x) * x) * x) * x;
             //
             // error 0.0000037995730, which is better than 18 bits
      -      SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3c5d51ce));
      -      SDValue t1 = DAG.getNode(ISD::FSUB, MVT::f32, t0,
      +      SDValue t1 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0,
                                      getF32Constant(DAG, 0x3e00685a));
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, t1, X);
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t1, X);
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3efb6798));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FSUB, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FSUB, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f88d192));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3fc4316c));
      -      SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
      -      SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, MVT::f32, t8,
      +      SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
      +      SDValue Log10ofMantissa = DAG.getNode(ISD::FSUB, dl, MVT::f32, t8,
                                                   getF32Constant(DAG, 0x3f57ce70));
       
      -      result = DAG.getNode(ISD::FADD, MVT::f32, LogOfExponent, Log10ofMantissa);
      +      result = DAG.getNode(ISD::FADD, dl, 
      +                           MVT::f32, LogOfExponent, Log10ofMantissa);
           }
         } else {
           // No special expansion.
      -    result = DAG.getNode(ISD::FLOG10,
      +    result = DAG.getNode(ISD::FLOG10, dl,
                                getValue(I.getOperand(1)).getValueType(),
                                getValue(I.getOperand(1)));
         }
      @@ -3432,19 +3520,20 @@ SelectionDAGLowering::visitLog10(CallInst &I) {
       void
       SelectionDAGLowering::visitExp2(CallInst &I) {
         SDValue result;
      +  DebugLoc dl = DAG.getCurDebugLoc();
       
         if (getValue(I.getOperand(1)).getValueType() == MVT::f32 &&
             LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) {
           SDValue Op = getValue(I.getOperand(1));
       
      -    SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Op);
      +    SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Op);
       
           //   FractionalPartOfX = x - (float)IntegerPartOfX;
      -    SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, MVT::f32, IntegerPartOfX);
      -    SDValue X = DAG.getNode(ISD::FSUB, MVT::f32, Op, t1);
      +    SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
      +    SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, Op, t1);
       
           //   IntegerPartOfX <<= 23;
      -    IntegerPartOfX = DAG.getNode(ISD::SHL, MVT::i32, IntegerPartOfX,
      +    IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
                                        DAG.getConstant(23, TLI.getShiftAmountTy()));
       
           if (LimitFloatPrecision <= 6) {
      @@ -3455,18 +3544,19 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
             //       (0.735607626f + 0.252464424f * x) * x;
             //
             // error 0.0144103317, which is 6 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3e814304));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3f3c50c8));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f7f5e7e));
      -      SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t5);
      +      SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t5);
             SDValue TwoToFractionalPartOfX =
      -        DAG.getNode(ISD::ADD, MVT::i32, t6, IntegerPartOfX);
      +        DAG.getNode(ISD::ADD, dl, MVT::i32, t6, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, 
      +                           MVT::f32, TwoToFractionalPartOfX);
           } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
             // For floating-point precision of 12:
             //
      @@ -3476,21 +3566,22 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
             //         (0.224338339f + 0.792043434e-1f * x) * x) * x;
             //
             // error 0.000107046256, which is 13 to 14 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3da235e3));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3e65b8f3));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f324b07));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3f7ff8fd));
      -      SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t7);
      +      SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t7);
             SDValue TwoToFractionalPartOfX =
      -        DAG.getNode(ISD::ADD, MVT::i32, t8, IntegerPartOfX);
      +        DAG.getNode(ISD::ADD, dl, MVT::i32, t8, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, 
      +                           MVT::f32, TwoToFractionalPartOfX);
           } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
             // For floating-point precision of 18:
             //
      @@ -3502,34 +3593,35 @@ SelectionDAGLowering::visitExp2(CallInst &I) {
             //             (0.961591928e-2f +
             //               (0.136028312e-2f + 0.157059148e-3f *x)*x)*x)*x)*x)*x;
             // error 2.47208000*10^(-7), which is better than 18 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3924b03e));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3ab24b87));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3c1d8c17));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3d634a1d));
      -      SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
      -      SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
      +      SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
      +      SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
                                      getF32Constant(DAG, 0x3e75fe14));
      -      SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
      -      SDValue t11 = DAG.getNode(ISD::FADD, MVT::f32, t10,
      +      SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
      +      SDValue t11 = DAG.getNode(ISD::FADD, dl, MVT::f32, t10,
                                       getF32Constant(DAG, 0x3f317234));
      -      SDValue t12 = DAG.getNode(ISD::FMUL, MVT::f32, t11, X);
      -      SDValue t13 = DAG.getNode(ISD::FADD, MVT::f32, t12,
      +      SDValue t12 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t11, X);
      +      SDValue t13 = DAG.getNode(ISD::FADD, dl, MVT::f32, t12,
                                       getF32Constant(DAG, 0x3f800000));
      -      SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t13);
      +      SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t13);
             SDValue TwoToFractionalPartOfX =
      -        DAG.getNode(ISD::ADD, MVT::i32, t14, IntegerPartOfX);
      +        DAG.getNode(ISD::ADD, dl, MVT::i32, t14, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, 
      +                           MVT::f32, TwoToFractionalPartOfX);
           }
         } else {
           // No special expansion.
      -    result = DAG.getNode(ISD::FEXP2,
      +    result = DAG.getNode(ISD::FEXP2, dl,
                                getValue(I.getOperand(1)).getValueType(),
                                getValue(I.getOperand(1)));
         }
      @@ -3543,6 +3635,7 @@ void
       SelectionDAGLowering::visitPow(CallInst &I) {
         SDValue result;
         Value *Val = I.getOperand(1);
      +  DebugLoc dl = DAG.getCurDebugLoc();
         bool IsExp10 = false;
       
         if (getValue(Val).getValueType() == MVT::f32 &&
      @@ -3564,16 +3657,16 @@ SelectionDAGLowering::visitPow(CallInst &I) {
           //
           //   #define LOG2OF10 3.3219281f
           //   IntegerPartOfX = (int32_t)(x * LOG2OF10);
      -    SDValue t0 = DAG.getNode(ISD::FMUL, MVT::f32, Op,
      +    SDValue t0 = DAG.getNode(ISD::FMUL, dl, MVT::f32, Op,
                                    getF32Constant(DAG, 0x40549a78));
      -    SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, MVT::i32, t0);
      +    SDValue IntegerPartOfX = DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, t0);
       
           //   FractionalPartOfX = x - (float)IntegerPartOfX;
      -    SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, MVT::f32, IntegerPartOfX);
      -    SDValue X = DAG.getNode(ISD::FSUB, MVT::f32, t0, t1);
      +    SDValue t1 = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, IntegerPartOfX);
      +    SDValue X = DAG.getNode(ISD::FSUB, dl, MVT::f32, t0, t1);
       
           //   IntegerPartOfX <<= 23;
      -    IntegerPartOfX = DAG.getNode(ISD::SHL, MVT::i32, IntegerPartOfX,
      +    IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX,
                                        DAG.getConstant(23, TLI.getShiftAmountTy()));
       
           if (LimitFloatPrecision <= 6) {
      @@ -3584,18 +3677,19 @@ SelectionDAGLowering::visitPow(CallInst &I) {
             //       (0.735607626f + 0.252464424f * x) * x;
             //
             // error 0.0144103317, which is 6 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3e814304));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3f3c50c8));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f7f5e7e));
      -      SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t5);
      +      SDValue t6 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t5);
             SDValue TwoToFractionalPartOfX =
      -        DAG.getNode(ISD::ADD, MVT::i32, t6, IntegerPartOfX);
      +        DAG.getNode(ISD::ADD, dl, MVT::i32, t6, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl,
      +                           MVT::f32, TwoToFractionalPartOfX);
           } else if (LimitFloatPrecision > 6 && LimitFloatPrecision <= 12) {
             // For floating-point precision of 12:
             //
      @@ -3605,21 +3699,22 @@ SelectionDAGLowering::visitPow(CallInst &I) {
             //         (0.224338339f + 0.792043434e-1f * x) * x) * x;
             //
             // error 0.000107046256, which is 13 to 14 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3da235e3));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3e65b8f3));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3f324b07));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3f7ff8fd));
      -      SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t7);
      +      SDValue t8 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t7);
             SDValue TwoToFractionalPartOfX =
      -        DAG.getNode(ISD::ADD, MVT::i32, t8, IntegerPartOfX);
      +        DAG.getNode(ISD::ADD, dl, MVT::i32, t8, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, 
      +                           MVT::f32, TwoToFractionalPartOfX);
           } else { // LimitFloatPrecision > 12 && LimitFloatPrecision <= 18
             // For floating-point precision of 18:
             //
      @@ -3631,34 +3726,35 @@ SelectionDAGLowering::visitPow(CallInst &I) {
             //             (0.961591928e-2f +
             //               (0.136028312e-2f + 0.157059148e-3f *x)*x)*x)*x)*x)*x;
             // error 2.47208000*10^(-7), which is better than 18 bits
      -      SDValue t2 = DAG.getNode(ISD::FMUL, MVT::f32, X,
      +      SDValue t2 = DAG.getNode(ISD::FMUL, dl, MVT::f32, X,
                                      getF32Constant(DAG, 0x3924b03e));
      -      SDValue t3 = DAG.getNode(ISD::FADD, MVT::f32, t2,
      +      SDValue t3 = DAG.getNode(ISD::FADD, dl, MVT::f32, t2,
                                      getF32Constant(DAG, 0x3ab24b87));
      -      SDValue t4 = DAG.getNode(ISD::FMUL, MVT::f32, t3, X);
      -      SDValue t5 = DAG.getNode(ISD::FADD, MVT::f32, t4,
      +      SDValue t4 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t3, X);
      +      SDValue t5 = DAG.getNode(ISD::FADD, dl, MVT::f32, t4,
                                      getF32Constant(DAG, 0x3c1d8c17));
      -      SDValue t6 = DAG.getNode(ISD::FMUL, MVT::f32, t5, X);
      -      SDValue t7 = DAG.getNode(ISD::FADD, MVT::f32, t6,
      +      SDValue t6 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t5, X);
      +      SDValue t7 = DAG.getNode(ISD::FADD, dl, MVT::f32, t6,
                                      getF32Constant(DAG, 0x3d634a1d));
      -      SDValue t8 = DAG.getNode(ISD::FMUL, MVT::f32, t7, X);
      -      SDValue t9 = DAG.getNode(ISD::FADD, MVT::f32, t8,
      +      SDValue t8 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t7, X);
      +      SDValue t9 = DAG.getNode(ISD::FADD, dl, MVT::f32, t8,
                                      getF32Constant(DAG, 0x3e75fe14));
      -      SDValue t10 = DAG.getNode(ISD::FMUL, MVT::f32, t9, X);
      -      SDValue t11 = DAG.getNode(ISD::FADD, MVT::f32, t10,
      +      SDValue t10 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t9, X);
      +      SDValue t11 = DAG.getNode(ISD::FADD, dl, MVT::f32, t10,
                                       getF32Constant(DAG, 0x3f317234));
      -      SDValue t12 = DAG.getNode(ISD::FMUL, MVT::f32, t11, X);
      -      SDValue t13 = DAG.getNode(ISD::FADD, MVT::f32, t12,
      +      SDValue t12 = DAG.getNode(ISD::FMUL, dl, MVT::f32, t11, X);
      +      SDValue t13 = DAG.getNode(ISD::FADD, dl, MVT::f32, t12,
                                       getF32Constant(DAG, 0x3f800000));
      -      SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, t13);
      +      SDValue t14 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, t13);
             SDValue TwoToFractionalPartOfX =
      -        DAG.getNode(ISD::ADD, MVT::i32, t14, IntegerPartOfX);
      +        DAG.getNode(ISD::ADD, dl, MVT::i32, t14, IntegerPartOfX);
       
      -      result = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, TwoToFractionalPartOfX);
      +      result = DAG.getNode(ISD::BIT_CONVERT, dl, 
      +                           MVT::f32, TwoToFractionalPartOfX);
           }
         } else {
           // No special expansion.
      -    result = DAG.getNode(ISD::FPOW,
      +    result = DAG.getNode(ISD::FPOW, dl,
                                getValue(I.getOperand(1)).getValueType(),
                                getValue(I.getOperand(1)),
                                getValue(I.getOperand(2)));
      @@ -3672,6 +3768,7 @@ SelectionDAGLowering::visitPow(CallInst &I) {
       /// otherwise lower it and return null.
       const char *
       SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
      +  DebugLoc dl = DAG.getCurDebugLoc();
         switch (Intrinsic) {
         default:
           // By default, turn this into a target intrinsic node.
      @@ -3681,11 +3778,11 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
         case Intrinsic::vaend:    visitVAEnd(I); return 0;
         case Intrinsic::vacopy:   visitVACopy(I); return 0;
         case Intrinsic::returnaddress:
      -    setValue(&I, DAG.getNode(ISD::RETURNADDR, TLI.getPointerTy(),
      +    setValue(&I, DAG.getNode(ISD::RETURNADDR, dl, TLI.getPointerTy(),
                                    getValue(I.getOperand(1))));
           return 0;
         case Intrinsic::frameaddress:
      -    setValue(&I, DAG.getNode(ISD::FRAMEADDR, TLI.getPointerTy(),
      +    setValue(&I, DAG.getNode(ISD::FRAMEADDR, dl, TLI.getPointerTy(),
                                    getValue(I.getOperand(1))));
           return 0;
         case Intrinsic::setjmp:
      @@ -3737,11 +3834,19 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
         case Intrinsic::dbg_stoppoint: {
           DwarfWriter *DW = DAG.getDwarfWriter();
           DbgStopPointInst &SPI = cast(I);
      -    if (DW && DW->ValidDebugInfo(SPI.getContext()))
      +    if (DW && DW->ValidDebugInfo(SPI.getContext())) {
             DAG.setRoot(DAG.getDbgStopPoint(getRoot(),
                                             SPI.getLine(),
                                             SPI.getColumn(),
                                             SPI.getContext()));
      +      DICompileUnit CU(cast(SPI.getContext()));
      +      unsigned SrcFile = DW->RecordSource(CU.getDirectory(), CU.getFilename());
      +      unsigned idx = DAG.getMachineFunction().
      +                         getOrCreateDebugLocID(SrcFile,
      +                                               SPI.getLine(), 
      +                                               SPI.getColumn());
      +      DAG.setCurDebugLoc(DebugLoc::get(idx));
      +    }
           return 0;
         }
         case Intrinsic::dbg_region_start: {
      @@ -3781,10 +3886,13 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
             // Record the source line but does not create a label for the normal
             // function start. It will be emitted at asm emission time. However,
             // create a label if this is a beginning of inlined function.
      +      unsigned Line = Subprogram.getLineNumber();
             unsigned LabelID =
      -        DW->RecordSourceLine(Subprogram.getLineNumber(), 0, SrcFile);
      +        DW->RecordSourceLine(Line, 0, SrcFile);
             if (DW->getRecordSourceLineCount() != 1)
               DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID));
      +      DAG.setCurDebugLoc(DebugLoc::get(DAG.getMachineFunction().
      +                         getOrCreateDebugLocID(SrcFile, Line, 0)));
           }
       
           return 0;
      @@ -3794,7 +3902,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           DbgDeclareInst &DI = cast(I);
           Value *Variable = DI.getVariable();
           if (DW && DW->ValidDebugInfo(Variable))
      -      DAG.setRoot(DAG.getNode(ISD::DECLARE, MVT::Other, getRoot(),
      +      DAG.setRoot(DAG.getNode(ISD::DECLARE, dl, MVT::Other, getRoot(),
                                     getValue(DI.getAddress()), getValue(Variable)));
           return 0;
         }
      @@ -3809,7 +3917,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           SDVTList VTs = DAG.getVTList(TLI.getPointerTy(), MVT::Other);
           SDValue Ops[1];
           Ops[0] = DAG.getRoot();
      -    SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, VTs, Ops, 1);
      +    SDValue Op = DAG.getNode(ISD::EXCEPTIONADDR, dl, VTs, Ops, 1);
           setValue(&I, Op);
           DAG.setRoot(Op.getValue(1));
           return 0;
      @@ -3838,7 +3946,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
             SDValue Ops[2];
             Ops[0] = getValue(I.getOperand(1));
             Ops[1] = getRoot();
      -      SDValue Op = DAG.getNode(ISD::EHSELECTION, VTs, Ops, 2);
      +      SDValue Op = DAG.getNode(ISD::EHSELECTION, dl, VTs, Ops, 2);
             setValue(&I, Op);
             DAG.setRoot(Op.getValue(1));
           } else {
      @@ -3872,7 +3980,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
         case Intrinsic::eh_return_i64:
           if (MachineModuleInfo *MMI = DAG.getMachineModuleInfo()) {
             MMI->setCallsEHReturn(true);
      -      DAG.setRoot(DAG.getNode(ISD::EH_RETURN,
      +      DAG.setRoot(DAG.getNode(ISD::EH_RETURN, dl,
                                     MVT::Other,
                                     getControlRoot(),
                                     getValue(I.getOperand(1)),
      @@ -3893,20 +4001,20 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           MVT VT = getValue(I.getOperand(1)).getValueType();
           SDValue CfaArg;
           if (VT.bitsGT(TLI.getPointerTy()))
      -      CfaArg = DAG.getNode(ISD::TRUNCATE,
      +      CfaArg = DAG.getNode(ISD::TRUNCATE, dl,
                                  TLI.getPointerTy(), getValue(I.getOperand(1)));
           else
      -      CfaArg = DAG.getNode(ISD::SIGN_EXTEND,
      +      CfaArg = DAG.getNode(ISD::SIGN_EXTEND, dl,
                                  TLI.getPointerTy(), getValue(I.getOperand(1)));
       
      -    SDValue Offset = DAG.getNode(ISD::ADD,
      +    SDValue Offset = DAG.getNode(ISD::ADD, dl,
                                        TLI.getPointerTy(),
      -                                 DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET,
      +                                 DAG.getNode(ISD::FRAME_TO_ARGS_OFFSET, dl,
                                                    TLI.getPointerTy()),
                                        CfaArg);
      -    setValue(&I, DAG.getNode(ISD::ADD,
      +    setValue(&I, DAG.getNode(ISD::ADD, dl,
                                    TLI.getPointerTy(),
      -                             DAG.getNode(ISD::FRAMEADDR,
      +                             DAG.getNode(ISD::FRAMEADDR, dl,
                                                TLI.getPointerTy(),
                                                DAG.getConstant(0,
                                                                TLI.getPointerTy())),
      @@ -3947,23 +4055,23 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
         }
       
         case Intrinsic::sqrt:
      -    setValue(&I, DAG.getNode(ISD::FSQRT,
      +    setValue(&I, DAG.getNode(ISD::FSQRT, dl,
                                    getValue(I.getOperand(1)).getValueType(),
                                    getValue(I.getOperand(1))));
           return 0;
         case Intrinsic::powi:
      -    setValue(&I, DAG.getNode(ISD::FPOWI,
      +    setValue(&I, DAG.getNode(ISD::FPOWI, dl,
                                    getValue(I.getOperand(1)).getValueType(),
                                    getValue(I.getOperand(1)),
                                    getValue(I.getOperand(2))));
           return 0;
         case Intrinsic::sin:
      -    setValue(&I, DAG.getNode(ISD::FSIN,
      +    setValue(&I, DAG.getNode(ISD::FSIN, dl,
                                    getValue(I.getOperand(1)).getValueType(),
                                    getValue(I.getOperand(1))));
           return 0;
         case Intrinsic::cos:
      -    setValue(&I, DAG.getNode(ISD::FCOS,
      +    setValue(&I, DAG.getNode(ISD::FCOS, dl,
                                    getValue(I.getOperand(1)).getValueType(),
                                    getValue(I.getOperand(1))));
           return 0;
      @@ -3987,12 +4095,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           return 0;
         case Intrinsic::pcmarker: {
           SDValue Tmp = getValue(I.getOperand(1));
      -    DAG.setRoot(DAG.getNode(ISD::PCMARKER, MVT::Other, getRoot(), Tmp));
      +    DAG.setRoot(DAG.getNode(ISD::PCMARKER, dl, MVT::Other, getRoot(), Tmp));
           return 0;
         }
         case Intrinsic::readcyclecounter: {
           SDValue Op = getRoot();
      -    SDValue Tmp = DAG.getNode(ISD::READCYCLECOUNTER,
      +    SDValue Tmp = DAG.getNode(ISD::READCYCLECOUNTER, dl,
                                       DAG.getNodeValueTypes(MVT::i64, MVT::Other), 2,
                                       &Op, 1);
           setValue(&I, Tmp);
      @@ -4010,34 +4118,34 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           abort();
         }
         case Intrinsic::bswap:
      -    setValue(&I, DAG.getNode(ISD::BSWAP,
      +    setValue(&I, DAG.getNode(ISD::BSWAP, dl,
                                    getValue(I.getOperand(1)).getValueType(),
                                    getValue(I.getOperand(1))));
           return 0;
         case Intrinsic::cttz: {
           SDValue Arg = getValue(I.getOperand(1));
           MVT Ty = Arg.getValueType();
      -    SDValue result = DAG.getNode(ISD::CTTZ, Ty, Arg);
      +    SDValue result = DAG.getNode(ISD::CTTZ, dl, Ty, Arg);
           setValue(&I, result);
           return 0;
         }
         case Intrinsic::ctlz: {
           SDValue Arg = getValue(I.getOperand(1));
           MVT Ty = Arg.getValueType();
      -    SDValue result = DAG.getNode(ISD::CTLZ, Ty, Arg);
      +    SDValue result = DAG.getNode(ISD::CTLZ, dl, Ty, Arg);
           setValue(&I, result);
           return 0;
         }
         case Intrinsic::ctpop: {
           SDValue Arg = getValue(I.getOperand(1));
           MVT Ty = Arg.getValueType();
      -    SDValue result = DAG.getNode(ISD::CTPOP, Ty, Arg);
      +    SDValue result = DAG.getNode(ISD::CTPOP, dl, Ty, Arg);
           setValue(&I, result);
           return 0;
         }
         case Intrinsic::stacksave: {
           SDValue Op = getRoot();
      -    SDValue Tmp = DAG.getNode(ISD::STACKSAVE,
      +    SDValue Tmp = DAG.getNode(ISD::STACKSAVE, dl,
                     DAG.getNodeValueTypes(TLI.getPointerTy(), MVT::Other), 2, &Op, 1);
           setValue(&I, Tmp);
           DAG.setRoot(Tmp.getValue(1));
      @@ -4045,7 +4153,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
         }
         case Intrinsic::stackrestore: {
           SDValue Tmp = getValue(I.getOperand(1));
      -    DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, MVT::Other, getRoot(), Tmp));
      +    DAG.setRoot(DAG.getNode(ISD::STACKRESTORE, dl, MVT::Other, getRoot(), Tmp));
           return 0;
         }
         case Intrinsic::stackprotector: {
      @@ -4063,7 +4171,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           SDValue FIN = DAG.getFrameIndex(FI, PtrTy);
       
           // Store the stack protector onto the stack.
      -    SDValue Result = DAG.getStore(getRoot(), Src, FIN,
      +    SDValue Result = DAG.getStore(getRoot(), DAG.getCurDebugLoc(), Src, FIN,
                                         PseudoSourceValue::getFixedStack(FI),
                                         0, true);
           setValue(&I, Result);
      @@ -4085,7 +4193,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           Ops[4] = DAG.getSrcValue(I.getOperand(1));
           Ops[5] = DAG.getSrcValue(F);
       
      -    SDValue Tmp = DAG.getNode(ISD::TRAMPOLINE,
      +    SDValue Tmp = DAG.getNode(ISD::TRAMPOLINE, dl,
                                       DAG.getNodeValueTypes(TLI.getPointerTy(),
                                                             MVT::Other), 2,
                                       Ops, 6);
      @@ -4111,12 +4219,12 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           return 0;
       
         case Intrinsic::flt_rounds: {
      -    setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, MVT::i32));
      +    setValue(&I, DAG.getNode(ISD::FLT_ROUNDS_, dl, MVT::i32));
           return 0;
         }
       
         case Intrinsic::trap: {
      -    DAG.setRoot(DAG.getNode(ISD::TRAP, MVT::Other, getRoot()));
      +    DAG.setRoot(DAG.getNode(ISD::TRAP, dl,MVT::Other, getRoot()));
           return 0;
         }
       
      @@ -4139,7 +4247,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           Ops[1] = getValue(I.getOperand(1));
           Ops[2] = getValue(I.getOperand(2));
           Ops[3] = getValue(I.getOperand(3));
      -    DAG.setRoot(DAG.getNode(ISD::PREFETCH, MVT::Other, &Ops[0], 4));
      +    DAG.setRoot(DAG.getNode(ISD::PREFETCH, dl, MVT::Other, &Ops[0], 4));
           return 0;
         }
       
      @@ -4149,13 +4257,13 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) {
           for (int x = 1; x < 6; ++x)
             Ops[x] = getValue(I.getOperand(x));
       
      -    DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, MVT::Other, &Ops[0], 6));
      +    DAG.setRoot(DAG.getNode(ISD::MEMBARRIER, dl, MVT::Other, &Ops[0], 6));
           return 0;
         }
         case Intrinsic::atomic_cmp_swap: {
           SDValue Root = getRoot();
           SDValue L =
      -      DAG.getAtomic(ISD::ATOMIC_CMP_SWAP,
      +      DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, DAG.getCurDebugLoc(),
                           getValue(I.getOperand(2)).getValueType().getSimpleVT(),
                           Root,
                           getValue(I.getOperand(1)),
      @@ -4278,8 +4386,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
                   I.getType() == I.getOperand(2)->getType()) {
                 SDValue LHS = getValue(I.getOperand(1));
                 SDValue RHS = getValue(I.getOperand(2));
      -          setValue(&I, DAG.getNode(ISD::FCOPYSIGN, LHS.getValueType(),
      -                                   LHS, RHS));
      +          setValue(&I, DAG.getNode(ISD::FCOPYSIGN, DAG.getCurDebugLoc(), 
      +                                   LHS.getValueType(), LHS, RHS));
                 return;
               }
             } else if (NameStr[0] == 'f' &&
      @@ -4290,7 +4398,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
                   I.getOperand(1)->getType()->isFloatingPoint() &&
                   I.getType() == I.getOperand(1)->getType()) {
                 SDValue Tmp = getValue(I.getOperand(1));
      -          setValue(&I, DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp));
      +          setValue(&I, DAG.getNode(ISD::FABS, DAG.getCurDebugLoc(), 
      +                                   Tmp.getValueType(), Tmp));
                 return;
               }
             } else if (NameStr[0] == 's' &&
      @@ -4301,7 +4410,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
                   I.getOperand(1)->getType()->isFloatingPoint() &&
                   I.getType() == I.getOperand(1)->getType()) {
                 SDValue Tmp = getValue(I.getOperand(1));
      -          setValue(&I, DAG.getNode(ISD::FSIN, Tmp.getValueType(), Tmp));
      +          setValue(&I, DAG.getNode(ISD::FSIN, DAG.getCurDebugLoc(), 
      +                                   Tmp.getValueType(), Tmp));
                 return;
               }
             } else if (NameStr[0] == 'c' &&
      @@ -4312,7 +4422,8 @@ void SelectionDAGLowering::visitCall(CallInst &I) {
                   I.getOperand(1)->getType()->isFloatingPoint() &&
                   I.getType() == I.getOperand(1)->getType()) {
                 SDValue Tmp = getValue(I.getOperand(1));
      -          setValue(&I, DAG.getNode(ISD::FCOS, Tmp.getValueType(), Tmp));
      +          setValue(&I, DAG.getNode(ISD::FCOS, DAG.getCurDebugLoc(), 
      +                                   Tmp.getValueType(), Tmp));
                 return;
               }
             }
      @@ -4395,6 +4506,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
       
                 if (FromVT != MVT::Other) {
                   P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext,
      +                            DAG.getCurDebugLoc(),
                                   RegisterVT, P, DAG.getValueType(FromVT));
       
                 }
      @@ -4410,7 +4522,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG,
           Parts.clear();
         }
       
      -  return DAG.getNode(ISD::MERGE_VALUES,
      +  return DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(),
                            DAG.getVTList(&ValueVTs[0], ValueVTs.size()),
                            &Values[0], ValueVTs.size());
       }
      @@ -4460,7 +4572,8 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG,
           //        = op c3, ..., f2
           Chain = Chains[NumRegs-1];
         else
      -    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Chains[0], NumRegs);
      +    Chain = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(),
      +                        MVT::Other, &Chains[0], NumRegs);
       }
       
       /// AddInlineAsmOperands - Add this value to the specified inlineasm node
      @@ -4672,8 +4785,8 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
             // vector types).
             MVT RegVT = *PhysReg.second->vt_begin();
             if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) {
      -        OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, RegVT,
      -                                         OpInfo.CallOperand);
      +        OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(),
      +                                         RegVT, OpInfo.CallOperand);
               OpInfo.ConstraintVT = RegVT;
             } else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) {
               // If the input is a FP value and we want it in FP registers, do a
      @@ -4681,8 +4794,8 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo,
               // into i64, which can be passed with two i32 values on a 32-bit
               // machine.
               RegVT = MVT::getIntegerVT(OpInfo.ConstraintVT.getSizeInBits());
      -        OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, RegVT,
      -                                         OpInfo.CallOperand);
      +        OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(),
      +                                         RegVT, OpInfo.CallOperand);
               OpInfo.ConstraintVT = RegVT;
             }
           }
      @@ -4947,7 +5060,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
               MachineFunction &MF = DAG.getMachineFunction();
               int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align);
               SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy());
      -        Chain = DAG.getStore(Chain, OpInfo.CallOperand, StackSlot, NULL, 0);
      +        Chain = DAG.getStore(Chain, DAG.getCurDebugLoc(),
      +                             OpInfo.CallOperand, StackSlot, NULL, 0);
               OpInfo.CallOperand = StackSlot;
             }
       
      @@ -5156,7 +5270,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
         AsmNodeOperands[0] = Chain;
         if (Flag.getNode()) AsmNodeOperands.push_back(Flag);
       
      -  Chain = DAG.getNode(ISD::INLINEASM,
      +  Chain = DAG.getNode(ISD::INLINEASM, DAG.getCurDebugLoc(),
                             DAG.getNodeValueTypes(MVT::Other, MVT::Flag), 2,
                             &AsmNodeOperands[0], AsmNodeOperands.size());
         Flag = Chain.getValue(1);
      @@ -5176,14 +5290,15 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
             // not have the same VT as was expected.  Convert it to the right type
             // with bit_convert.
             if (ResultType != Val.getValueType() && Val.getValueType().isVector()) {
      -        Val = DAG.getNode(ISD::BIT_CONVERT, ResultType, Val);
      +        Val = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(),
      +                          ResultType, Val);
       
             } else if (ResultType != Val.getValueType() &&
                        ResultType.isInteger() && Val.getValueType().isInteger()) {
               // If a result value was tied to an input value, the computed result may
               // have a wider width than the expected result.  Extract the relevant
               // portion.
      -        Val = DAG.getNode(ISD::TRUNCATE, ResultType, Val);
      +        Val = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ResultType, Val);
             }
       
             assert(ResultType == Val.getValueType() && "Asm result value mismatch!");
      @@ -5206,11 +5321,12 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) {
         // Emit the non-flagged stores from the physregs.
         SmallVector OutChains;
         for (unsigned i = 0, e = StoresToEmit.size(); i != e; ++i)
      -    OutChains.push_back(DAG.getStore(Chain, StoresToEmit[i].first,
      +    OutChains.push_back(DAG.getStore(Chain, DAG.getCurDebugLoc(),
      +                                    StoresToEmit[i].first,
                                           getValue(StoresToEmit[i].second),
                                           StoresToEmit[i].second, 0));
         if (!OutChains.empty())
      -    Chain = DAG.getNode(ISD::TokenFactor, MVT::Other,
      +    Chain = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), MVT::Other,
                               &OutChains[0], OutChains.size());
         DAG.setRoot(Chain);
       }
      @@ -5222,13 +5338,13 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) {
         MVT IntPtr = TLI.getPointerTy();
       
         if (IntPtr.bitsLT(Src.getValueType()))
      -    Src = DAG.getNode(ISD::TRUNCATE, IntPtr, Src);
      +    Src = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), IntPtr, Src);
         else if (IntPtr.bitsGT(Src.getValueType()))
      -    Src = DAG.getNode(ISD::ZERO_EXTEND, IntPtr, Src);
      +    Src = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), IntPtr, Src);
       
         // Scale the source by the type size.
         uint64_t ElementSize = TD->getTypePaddedSize(I.getType()->getElementType());
      -  Src = DAG.getNode(ISD::MUL, Src.getValueType(),
      +  Src = DAG.getNode(ISD::MUL, DAG.getCurDebugLoc(), Src.getValueType(),
                           Src, DAG.getIntPtrConstant(ElementSize));
       
         TargetLowering::ArgListTy Args;
      @@ -5261,7 +5377,8 @@ void SelectionDAGLowering::visitFree(FreeInst &I) {
       }
       
       void SelectionDAGLowering::visitVAStart(CallInst &I) {
      -  DAG.setRoot(DAG.getNode(ISD::VASTART, MVT::Other, getRoot(),
      +  DAG.setRoot(DAG.getNode(ISD::VASTART, DAG.getCurDebugLoc(),
      +                          MVT::Other, getRoot(),
                                 getValue(I.getOperand(1)),
                                 DAG.getSrcValue(I.getOperand(1))));
       }
      @@ -5275,13 +5392,15 @@ void SelectionDAGLowering::visitVAArg(VAArgInst &I) {
       }
       
       void SelectionDAGLowering::visitVAEnd(CallInst &I) {
      -  DAG.setRoot(DAG.getNode(ISD::VAEND, MVT::Other, getRoot(),
      +  DAG.setRoot(DAG.getNode(ISD::VAEND, DAG.getCurDebugLoc(),
      +                          MVT::Other, getRoot(),
                                 getValue(I.getOperand(1)),
                                 DAG.getSrcValue(I.getOperand(1))));
       }
       
       void SelectionDAGLowering::visitVACopy(CallInst &I) {
      -  DAG.setRoot(DAG.getNode(ISD::VACOPY, MVT::Other, getRoot(),
      +  DAG.setRoot(DAG.getNode(ISD::VACOPY, DAG.getCurDebugLoc(),
      +                          MVT::Other, getRoot(),
                                 getValue(I.getOperand(1)),
                                 getValue(I.getOperand(2)),
                                 DAG.getSrcValue(I.getOperand(1)),
      @@ -5358,7 +5477,7 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG,
         RetVals.push_back(MVT::Other);
       
         // Create the node.
      -  SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS,
      +  SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS, DAG.getCurDebugLoc(),
                                      DAG.getVTList(&RetVals[0], RetVals.size()),
                                      &Ops[0], Ops.size()).getNode();
       
      @@ -5517,7 +5636,8 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
         LoweredRetTys.push_back(MVT::Other);  // Always has a chain.
       
         // Create the CALL node.
      -  SDValue Res = DAG.getCall(CallingConv, isVarArg, isTailCall, isInreg,
      +  SDValue Res = DAG.getCall(CallingConv, DAG.getCurDebugLoc(), 
      +                            isVarArg, isTailCall, isInreg,
                                   DAG.getVTList(&LoweredRetTys[0],
                                                 LoweredRetTys.size()),
                                   &Ops[0], Ops.size()
      @@ -5548,7 +5668,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy,
                                AssertOp);
             ReturnValues.push_back(ReturnValue);
           }
      -    Res = DAG.getNode(ISD::MERGE_VALUES,
      +    Res = DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(),
                             DAG.getVTList(&RetTys[0], RetTys.size()),
                             &ReturnValues[0], ReturnValues.size());
         }
      -- 
      GitLab
      
      
      From a103ee4f0da82743d0e13b51ae5c338586e4f288 Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 01:37:30 +0000
      Subject: [PATCH 468/682] Linux and other target's  encoding for
       DW_AT_declaration may not match.
      
      llvm-svn: 63360
      ---
       llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll | 1 +
       1 file changed, 1 insertion(+)
      
      diff --git a/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll b/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      index 323135f5210a..e7287e265121 100644
      --- a/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      +++ b/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      @@ -1,5 +1,6 @@
       ; RUN: llvm-as < %s | llc | grep 0x3C | count 1
       ; Check DW_AT_declaration attribute for class method foo.
      +; target triple = "i386-apple-darwin*"
       	%llvm.dbg.anchor.type = type { i32, i32 }
       	%llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* }
       	%llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i8* }
      -- 
      GitLab
      
      
      From acbb381cc41437533533a62c34fce03d74bd541f Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 01:40:58 +0000
      Subject: [PATCH 469/682] Enable target tripple.
      
      llvm-svn: 63361
      ---
       llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll b/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      index e7287e265121..6d1e1e91b15a 100644
      --- a/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      +++ b/llvm/test/DebugInfo/2009-01-29-MethodDeclaration.ll
      @@ -1,6 +1,6 @@
       ; RUN: llvm-as < %s | llc | grep 0x3C | count 1
       ; Check DW_AT_declaration attribute for class method foo.
      -; target triple = "i386-apple-darwin*"
      +target triple = "i386-apple-darwin*"
       	%llvm.dbg.anchor.type = type { i32, i32 }
       	%llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* }
       	%llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i8* }
      -- 
      GitLab
      
      
      From caffe92d865fb9d6fd1c1332ba38943dddaf9bd4 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Fri, 30 Jan 2009 01:58:19 +0000
      Subject: [PATCH 470/682] Fix a bug in getMaxValue/getMinValue to pass the
       right signedness the the constructed APSInt, patch suggested by Ben Laurie!
      
      llvm-svn: 63362
      ---
       llvm/include/llvm/ADT/APSInt.h | 12 ++++++------
       1 file changed, 6 insertions(+), 6 deletions(-)
      
      diff --git a/llvm/include/llvm/ADT/APSInt.h b/llvm/include/llvm/ADT/APSInt.h
      index 386a8ad18df2..6fef4c7a0d0c 100644
      --- a/llvm/include/llvm/ADT/APSInt.h
      +++ b/llvm/include/llvm/ADT/APSInt.h
      @@ -236,16 +236,16 @@ public:
       
         /// getMaxValue - Return the APSInt representing the maximum integer value
         ///  with the given bit width and signedness.
      -  static APSInt getMaxValue(uint32_t numBits, bool Signed) {
      -    return APSInt(Signed ? APInt::getSignedMaxValue(numBits)
      -                         : APInt::getMaxValue(numBits), Signed);
      +  static APSInt getMaxValue(uint32_t numBits, bool Unsigned) {
      +    return APSInt(Unsigned ? APInt::getMaxValue(numBits)
      +                           : APInt::getSignedMaxValue(numBits), Unsigned);
         }
       
         /// getMinValue - Return the APSInt representing the minimum integer value
         ///  with the given bit width and signedness.
      -  static APSInt getMinValue(uint32_t numBits, bool Signed) {
      -    return APSInt(Signed ? APInt::getSignedMinValue(numBits)
      -                         : APInt::getMinValue(numBits), Signed);
      +  static APSInt getMinValue(uint32_t numBits, bool Unsigned) {
      +    return APSInt(Unsigned ? APInt::getMinValue(numBits)
      +                           : APInt::getSignedMinValue(numBits), Unsigned);
         }
       
         /// Profile - Used to insert APSInt objects, or objects that contain APSInt
      -- 
      GitLab
      
      
      From 34beb046ea3bd9e7f2c03c151dcaf3328e365010 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Fri, 30 Jan 2009 01:58:33 +0000
      Subject: [PATCH 471/682] update for change in API.
      
      llvm-svn: 63363
      ---
       clang/lib/Analysis/BasicConstraintManager.cpp | 8 ++++----
       1 file changed, 4 insertions(+), 4 deletions(-)
      
      diff --git a/clang/lib/Analysis/BasicConstraintManager.cpp b/clang/lib/Analysis/BasicConstraintManager.cpp
      index f14ada7aed63..0c98bf645027 100644
      --- a/clang/lib/Analysis/BasicConstraintManager.cpp
      +++ b/clang/lib/Analysis/BasicConstraintManager.cpp
      @@ -345,7 +345,7 @@ BasicConstraintManager::AssumeSymLT(const GRState* St, SymbolRef sym,
                                           const llvm::APSInt& V, bool& isFeasible) {
         
         // Is 'V' the smallest possible value?
      -  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
      +  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
           // sym cannot be any value less than 'V'.  This path is infeasible.
           isFeasible = false;
           return St;
      @@ -360,7 +360,7 @@ BasicConstraintManager::AssumeSymGT(const GRState* St, SymbolRef sym,
                                           const llvm::APSInt& V, bool& isFeasible) {
       
         // Is 'V' the largest possible value?
      -  if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
      +  if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
           // sym cannot be any value greater than 'V'.  This path is infeasible.
           isFeasible = false;
           return St;
      @@ -382,7 +382,7 @@ BasicConstraintManager::AssumeSymGE(const GRState* St, SymbolRef sym,
         
         // Sym is not a constant, but it is worth looking to see if V is the
         // maximum integer value.
      -  if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isSigned())) {
      +  if (V == llvm::APSInt::getMaxValue(V.getBitWidth(), V.isUnsigned())) {
           // If we know that sym != V, then this condition is infeasible since
           // there is no other value greater than V.    
           isFeasible = !isNotEqual(St, sym, V);
      @@ -411,7 +411,7 @@ BasicConstraintManager::AssumeSymLE(const GRState* St, SymbolRef sym,
         
         // Sym is not a constant, but it is worth looking to see if V is the
         // minimum integer value.
      -  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isSigned())) {
      +  if (V == llvm::APSInt::getMinValue(V.getBitWidth(), V.isUnsigned())) {
           // If we know that sym != V, then this condition is infeasible since
           // there is no other value less than V.    
           isFeasible = !isNotEqual(St, sym, V);
      -- 
      GitLab
      
      
      From c7d6951c92a3153e6e5cec17b70d94d76ff6609f Mon Sep 17 00:00:00 2001
      From: Mikhail Glushenkov 
      Date: Fri, 30 Jan 2009 02:12:57 +0000
      Subject: [PATCH 472/682] Add some comments.
      
      llvm-svn: 63364
      ---
       llvm/tools/llvmc/driver/CompilationGraph.cpp | 6 +++++-
       1 file changed, 5 insertions(+), 1 deletion(-)
      
      diff --git a/llvm/tools/llvmc/driver/CompilationGraph.cpp b/llvm/tools/llvmc/driver/CompilationGraph.cpp
      index 2c59ee6314c0..238ef6f42a78 100644
      --- a/llvm/tools/llvmc/driver/CompilationGraph.cpp
      +++ b/llvm/tools/llvmc/driver/CompilationGraph.cpp
      @@ -390,6 +390,8 @@ int CompilationGraph::CheckMultipleDefaultEdges() const {
         int ret = 0;
         InputLanguagesSet Dummy;
       
      +  // For all nodes, just iterate over the outgoing edges and check if there is
      +  // more than one edge with maximum weight.
         for (const_nodes_iterator B = this->NodesMap.begin(),
                E = this->NodesMap.end(); B != E; ++B) {
           const Node& N = B->second;
      @@ -423,6 +425,9 @@ int CompilationGraph::CheckCycles() {
         std::queue Q;
         Q.push(&getNode("root"));
       
      +  // Try to delete all nodes that have no ingoing edges, starting from the
      +  // root. If there are any nodes left after this operation, then we have a
      +  // cycle. This relies on '--check-graph' not performing the topological sort.
         while (!Q.empty()) {
           Node* A = Q.front();
           Q.pop();
      @@ -447,7 +452,6 @@ int CompilationGraph::CheckCycles() {
         return 0;
       }
       
      -
       int CompilationGraph::Check () {
         // We try to catch as many errors as we can in one go.
         int ret = 0;
      -- 
      GitLab
      
      
      From cdd96133bdc4bb292bbdfffa954e454a603a3226 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:23:43 +0000
      Subject: [PATCH 473/682] - Propagate debug loc info in combineSelectAndUse().
       - Modify ReassociateOps so that the resulting SDValue is what the comment
       claims   it is.
      
      llvm-svn: 63365
      ---
       llvm/include/llvm/CodeGen/SelectionDAG.h      | 23 +++++++++--
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 39 +++++++++++--------
       2 files changed, 42 insertions(+), 20 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h
      index 6b09a745c338..895285c74843 100644
      --- a/llvm/include/llvm/CodeGen/SelectionDAG.h
      +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h
      @@ -487,7 +487,12 @@ public:
         ///
         SDValue getSetCC(MVT VT, SDValue LHS, SDValue RHS,
                          ISD::CondCode Cond) {
      -    return getNode(ISD::SETCC, VT, LHS, RHS, getCondCode(Cond));
      +    return getNode(ISD::SETCC, DebugLoc::getUnknownLoc(), VT,
      +                   LHS, RHS, getCondCode(Cond));
      +  }
      +  SDValue getSetCC(DebugLoc DL, MVT VT, SDValue LHS, SDValue RHS,
      +                   ISD::CondCode Cond) {
      +    return getNode(ISD::SETCC, DL, VT, LHS, RHS, getCondCode(Cond));
         }
       
         /// getVSetCC - Helper function to make it easier to build VSetCC's nodes
      @@ -495,7 +500,12 @@ public:
         ///
         SDValue getVSetCC(MVT VT, SDValue LHS, SDValue RHS,
                           ISD::CondCode Cond) {
      -    return getNode(ISD::VSETCC, VT, LHS, RHS, getCondCode(Cond));
      +    return getNode(ISD::VSETCC, DebugLoc::getUnknownLoc(), VT,
      +                   LHS, RHS, getCondCode(Cond));
      +  }
      +  SDValue getVSetCC(DebugLoc DL, MVT VT, SDValue LHS, SDValue RHS,
      +                    ISD::CondCode Cond) {
      +    return getNode(ISD::VSETCC, DL, VT, LHS, RHS, getCondCode(Cond));
         }
       
         /// getSelectCC - Helper function to make it easier to build SelectCC's if you
      @@ -503,8 +513,13 @@ public:
         ///
         SDValue getSelectCC(SDValue LHS, SDValue RHS,
                             SDValue True, SDValue False, ISD::CondCode Cond) {
      -    return getNode(ISD::SELECT_CC, True.getValueType(), LHS, RHS, True, False,
      -                   getCondCode(Cond));
      +    return getNode(ISD::SELECT_CC, DebugLoc::getUnknownLoc(), True.getValueType(),
      +                   LHS, RHS, True, False, getCondCode(Cond));
      +  }
      +  SDValue getSelectCC(DebugLoc DL, SDValue LHS, SDValue RHS,
      +                      SDValue True, SDValue False, ISD::CondCode Cond) {
      +    return getNode(ISD::SELECT_CC, DL, True.getValueType(),
      +                   LHS, RHS, True, False, getCondCode(Cond));
         }
         
         /// getVAArg - VAArg produces a result and token chain, and takes a pointer
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 2947794e919c..2c1db2f710ec 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -485,10 +485,10 @@ SDValue DAGCombiner::ReassociateOps(unsigned Opc, DebugLoc DL,
         if (N0.getOpcode() == Opc && isa(N0.getOperand(1))) {
           if (isa(N1)) {
             // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2))
      -      SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
      +      SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT,
                                          N0.getOperand(1), N1);
             AddToWorkList(OpNode.getNode());
      -      return DAG.getNode(Opc, DL, VT, OpNode, N0.getOperand(0));
      +      return DAG.getNode(Opc, DL, VT, N0.getOperand(0), OpNode);
           } else if (N0.hasOneUse()) {
             // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use
             SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
      @@ -504,10 +504,10 @@ SDValue DAGCombiner::ReassociateOps(unsigned Opc, DebugLoc DL,
             SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT,
                                          N1.getOperand(1), N0);
             AddToWorkList(OpNode.getNode());
      -      return DAG.getNode(Opc, DL, VT, OpNode, N1.getOperand(0));
      +      return DAG.getNode(Opc, DL, VT, N1.getOperand(0), OpNode);
           } else if (N1.hasOneUse()) {
             // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use
      -      SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT,
      +      SDValue OpNode = DAG.getNode(Opc, N0.getDebugLoc(), VT,
                                          N1.getOperand(0), N0);
             AddToWorkList(OpNode.getNode());
             return DAG.getNode(Opc, DL, VT, OpNode, N1.getOperand(1));
      @@ -913,18 +913,24 @@ SDValue DAGCombiner::visitMERGE_VALUES(SDNode *N) {
       }
       
       static
      -SDValue combineShlAddConstant(SDValue N0, SDValue N1, SelectionDAG &DAG) {
      +SDValue combineShlAddConstant(DebugLoc DL, SDValue N0, SDValue N1,
      +                              SelectionDAG &DAG) {
         MVT VT = N0.getValueType();
         SDValue N00 = N0.getOperand(0);
         SDValue N01 = N0.getOperand(1);
         ConstantSDNode *N01C = dyn_cast(N01);
      +
         if (N01C && N00.getOpcode() == ISD::ADD && N00.getNode()->hasOneUse() &&
             isa(N00.getOperand(1))) {
      -    N0 = DAG.getNode(ISD::ADD, VT,
      -                     DAG.getNode(ISD::SHL, VT, N00.getOperand(0), N01),
      -                     DAG.getNode(ISD::SHL, VT, N00.getOperand(1), N01));
      -    return DAG.getNode(ISD::ADD, VT, N0, N1);
      +    // fold (add (shl (add x, c1), c2), ) -> (add (add (shl x, c2), c1<getDebugLoc(), OtherOp, Result,
                                    Slct.getOperand(0), Slct.getOperand(1), CC);
           SDValue CCOp = Slct.getOperand(0);
           if (InvCC)
      -      CCOp = DAG.getSetCC(CCOp.getValueType(), CCOp.getOperand(0),
      -                          CCOp.getOperand(1), CC);
      -    return DAG.getNode(ISD::SELECT, VT, CCOp, OtherOp, Result);
      +      CCOp = DAG.getSetCC(Slct.getDebugLoc(), CCOp.getValueType(),
      +                          CCOp.getOperand(0), CCOp.getOperand(1), CC);
      +    return DAG.getNode(ISD::SELECT, N->getDebugLoc(), VT,
      +                       CCOp, OtherOp, Result);
         }
         return SDValue();
       }
      @@ -1100,11 +1107,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
       
         // fold (add (shl (add x, c1), c2), ) -> (add (add (shl x, c2), c1<hasOneUse()) {
      -    SDValue Result = combineShlAddConstant(N0, N1, DAG);
      +    SDValue Result = combineShlAddConstant(N->getDebugLoc(), N0, N1, DAG);
           if (Result.getNode()) return Result;
         }
         if (N1.getOpcode() == ISD::SHL && N1.getNode()->hasOneUse()) {
      -    SDValue Result = combineShlAddConstant(N1, N0, DAG);
      +    SDValue Result = combineShlAddConstant(N->getDebugLoc(), N1, N0, DAG);
           if (Result.getNode()) return Result;
         }
       
      -- 
      GitLab
      
      
      From c442348dd79966790e0a630e381a7b16d7d1578e Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:31:17 +0000
      Subject: [PATCH 474/682] Propagate debug loc info in DAG combine's "ADD".
      
      llvm-svn: 63366
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 38 +++++++++----------
       1 file changed, 18 insertions(+), 20 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 2c1db2f710ec..c84591d52ecc 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1016,7 +1016,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
           return DAG.FoldConstantArithmetic(ISD::ADD, VT, N0C, N1C);
         // canonicalize constant to RHS
         if (N0C && !N1C)
      -    return DAG.getNode(ISD::ADD, VT, N1, N0);
      +    return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0);
         // fold (add x, 0) -> x
         if (N1C && N1C->isNullValue())
           return N0;
      @@ -1030,7 +1030,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
         // fold ((c1-A)+c2) -> (c1+c2)-A
         if (N1C && N0.getOpcode() == ISD::SUB)
           if (ConstantSDNode *N0C = dyn_cast(N0.getOperand(0)))
      -      return DAG.getNode(ISD::SUB, VT,
      +      return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
                                DAG.getConstant(N1C->getAPIntValue()+
                                                N0C->getAPIntValue(), VT),
                                N0.getOperand(1));
      @@ -1041,11 +1041,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
         // fold ((0-A) + B) -> B-A
         if (N0.getOpcode() == ISD::SUB && isa(N0.getOperand(0)) &&
             cast(N0.getOperand(0))->isNullValue())
      -    return DAG.getNode(ISD::SUB, VT, N1, N0.getOperand(1));
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1, N0.getOperand(1));
         // fold (A + (0-B)) -> A-B
         if (N1.getOpcode() == ISD::SUB && isa(N1.getOperand(0)) &&
             cast(N1.getOperand(0))->isNullValue())
      -    return DAG.getNode(ISD::SUB, VT, N0, N1.getOperand(1));
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, N1.getOperand(1));
         // fold (A+(B-A)) -> B
         if (N1.getOpcode() == ISD::SUB && N0 == N1.getOperand(1))
           return N1.getOperand(0);
      @@ -1054,23 +1054,20 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
           return N0.getOperand(0);
         // fold (A+(B-(A+C))) to (B-C)
         if (N1.getOpcode() == ISD::SUB && N1.getOperand(1).getOpcode() == ISD::ADD &&
      -      N0 == N1.getOperand(1).getOperand(0)) {
      -    return DAG.getNode(ISD::SUB, VT, N1.getOperand(0),
      +      N0 == N1.getOperand(1).getOperand(0))
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1.getOperand(0),
                              N1.getOperand(1).getOperand(1));
      -  }
         // fold (A+(B-(C+A))) to (B-C)
         if (N1.getOpcode() == ISD::SUB && N1.getOperand(1).getOpcode() == ISD::ADD &&
      -      N0 == N1.getOperand(1).getOperand(1)) {
      -    return DAG.getNode(ISD::SUB, VT, N1.getOperand(0),
      +      N0 == N1.getOperand(1).getOperand(1))
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N1.getOperand(0),
                              N1.getOperand(1).getOperand(0));
      -  }
         // fold (A+((B-A)+or-C)) to (B+or-C)
         if ((N1.getOpcode() == ISD::SUB || N1.getOpcode() == ISD::ADD) &&
             N1.getOperand(0).getOpcode() == ISD::SUB &&
      -      N0 == N1.getOperand(0).getOperand(1)) {
      -    return DAG.getNode(N1.getOpcode(), VT, N1.getOperand(0).getOperand(0),
      -                       N1.getOperand(1));
      -  }
      +      N0 == N1.getOperand(0).getOperand(1))
      +    return DAG.getNode(N1.getOpcode(), N->getDebugLoc(), VT,
      +                       N1.getOperand(0).getOperand(0), N1.getOperand(1));
       
         // fold (A-B)+(C-D) to (A+C)-(B+D) when A or C is constant
         if (N0.getOpcode() == ISD::SUB && N1.getOpcode() == ISD::SUB) {
      @@ -1078,11 +1075,11 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
           SDValue N01 = N0.getOperand(1);
           SDValue N10 = N1.getOperand(0);
           SDValue N11 = N1.getOperand(1);
      -    if (isa(N00) || isa(N10)) {
      -      return DAG.getNode(ISD::SUB, VT,
      -                 DAG.getNode(ISD::ADD, VT, N00, N10),
      -                 DAG.getNode(ISD::ADD, VT, N01, N11));
      -    }
      +
      +    if (isa(N00) || isa(N10))
      +      return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
      +                         DAG.getNode(ISD::ADD, N0.getDebugLoc(), VT, N00, N10),
      +                         DAG.getNode(ISD::ADD, N1.getDebugLoc(), VT, N01, N11));
         }
       
         if (!VT.isVector() && SimplifyDemandedBits(SDValue(N, 0)))
      @@ -1094,6 +1091,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
           APInt RHSZero, RHSOne;
           APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
           DAG.ComputeMaskedBits(N0, Mask, LHSZero, LHSOne);
      +
           if (LHSZero.getBoolValue()) {
             DAG.ComputeMaskedBits(N1, Mask, RHSZero, RHSOne);
             
      @@ -1101,7 +1099,7 @@ SDValue DAGCombiner::visitADD(SDNode *N) {
             // If all possibly-set bits on the RHS are clear on the LHS, return an OR.
             if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
                 (LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
      -        return DAG.getNode(ISD::OR, VT, N0, N1);
      +        return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1);
           }
         }
       
      -- 
      GitLab
      
      
      From 612775792017c5d04bb3f3687f49c8ca03b360aa Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:38:00 +0000
      Subject: [PATCH 475/682] Propagate debug loc info in ADDC and ADDE.
      
      llvm-svn: 63367
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 24 ++++++++++---------
       1 file changed, 13 insertions(+), 11 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index c84591d52ecc..fc3ddbe319da 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1135,22 +1135,25 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
         
         // If the flag result is dead, turn this into an ADD.
         if (N->hasNUsesOfValue(0, 1))
      -    return CombineTo(N, DAG.getNode(ISD::ADD, VT, N1, N0),
      -                     DAG.getNode(ISD::CARRY_FALSE, MVT::Flag));
      +    return CombineTo(N, DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1, N0),
      +                     DAG.getNode(ISD::CARRY_FALSE,
      +                                 N->getDebugLoc(), MVT::Flag));
         
         // canonicalize constant to RHS.
         if (N0C && !N1C)
      -    return DAG.getNode(ISD::ADDC, N->getVTList(), N1, N0);
      +    return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
         
         // fold (addc x, 0) -> x + no carry out
         if (N1C && N1C->isNullValue())
      -    return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE, MVT::Flag));
      +    return CombineTo(N, N0, DAG.getNode(ISD::CARRY_FALSE,
      +                                        N->getDebugLoc(), MVT::Flag));
         
         // fold (addc a, b) -> (or a, b), CARRY_FALSE iff a and b share no bits.
         APInt LHSZero, LHSOne;
         APInt RHSZero, RHSOne;
         APInt Mask = APInt::getAllOnesValue(VT.getSizeInBits());
         DAG.ComputeMaskedBits(N0, Mask, LHSZero, LHSOne);
      +
         if (LHSZero.getBoolValue()) {
           DAG.ComputeMaskedBits(N1, Mask, RHSZero, RHSOne);
           
      @@ -1158,8 +1161,9 @@ SDValue DAGCombiner::visitADDC(SDNode *N) {
           // If all possibly-set bits on the RHS are clear on the LHS, return an OR.
           if ((RHSZero & (~LHSZero & Mask)) == (~LHSZero & Mask) ||
               (LHSZero & (~RHSZero & Mask)) == (~RHSZero & Mask))
      -      return CombineTo(N, DAG.getNode(ISD::OR, VT, N0, N1),
      -                       DAG.getNode(ISD::CARRY_FALSE, MVT::Flag));
      +      return CombineTo(N, DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N1),
      +                       DAG.getNode(ISD::CARRY_FALSE,
      +                                   N->getDebugLoc(), MVT::Flag));
         }
         
         return SDValue();
      @@ -1171,21 +1175,19 @@ SDValue DAGCombiner::visitADDE(SDNode *N) {
         SDValue CarryIn = N->getOperand(2);
         ConstantSDNode *N0C = dyn_cast(N0);
         ConstantSDNode *N1C = dyn_cast(N1);
      -  //MVT VT = N0.getValueType();
         
         // canonicalize constant to RHS
         if (N0C && !N1C)
      -    return DAG.getNode(ISD::ADDE, N->getVTList(), N1, N0, CarryIn);
      +    return DAG.getNode(ISD::ADDE, N->getDebugLoc(), N->getVTList(),
      +                       N1, N0, CarryIn);
         
         // fold (adde x, y, false) -> (addc x, y)
         if (CarryIn.getOpcode() == ISD::CARRY_FALSE)
      -    return DAG.getNode(ISD::ADDC, N->getVTList(), N1, N0);
      +    return DAG.getNode(ISD::ADDC, N->getDebugLoc(), N->getVTList(), N1, N0);
         
         return SDValue();
       }
       
      -
      -
       SDValue DAGCombiner::visitSUB(SDNode *N) {
         SDValue N0 = N->getOperand(0);
         SDValue N1 = N->getOperand(1);
      -- 
      GitLab
      
      
      From 48ff08ef3edac0482d43eae0cbdda5e3359b3e58 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:42:10 +0000
      Subject: [PATCH 476/682] Propagate debug loc info in SUB.
      
      llvm-svn: 63368
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 ++++++++-------
       1 file changed, 8 insertions(+), 7 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index fc3ddbe319da..2039595e749c 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1209,7 +1209,7 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
           return DAG.FoldConstantArithmetic(ISD::SUB, VT, N0C, N1C);
         // fold (sub x, c) -> (add x, -c)
         if (N1C)
      -    return DAG.getNode(ISD::ADD, VT, N0,
      +    return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0,
                              DAG.getConstant(-N1C->getAPIntValue(), VT));
         // fold (A+B)-A -> B
         if (N0.getOpcode() == ISD::ADD && N0.getOperand(0) == N1)
      @@ -1222,25 +1222,26 @@ SDValue DAGCombiner::visitSUB(SDNode *N) {
             (N0.getOperand(1).getOpcode() == ISD::SUB ||
              N0.getOperand(1).getOpcode() == ISD::ADD) &&
             N0.getOperand(1).getOperand(0) == N1)
      -    return DAG.getNode(N0.getOperand(1).getOpcode(), VT, N0.getOperand(0), 
      -                                     N0.getOperand(1).getOperand(1));
      +    return DAG.getNode(N0.getOperand(1).getOpcode(), N->getDebugLoc(), VT,
      +                       N0.getOperand(0), N0.getOperand(1).getOperand(1));
         // fold ((A+(C+B))-B) -> A+C
         if (N0.getOpcode() == ISD::ADD &&
             N0.getOperand(1).getOpcode() == ISD::ADD &&
             N0.getOperand(1).getOperand(1) == N1)
      -    return DAG.getNode(ISD::ADD, VT, N0.getOperand(0), 
      -                                     N0.getOperand(1).getOperand(0));
      +    return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT,
      +                       N0.getOperand(0), N0.getOperand(1).getOperand(0));
         // fold ((A-(B-C))-C) -> A-B
         if (N0.getOpcode() == ISD::SUB &&
             N0.getOperand(1).getOpcode() == ISD::SUB &&
             N0.getOperand(1).getOperand(1) == N1)
      -    return DAG.getNode(ISD::SUB, VT, N0.getOperand(0), 
      -                                     N0.getOperand(1).getOperand(0));
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
      +                       N0.getOperand(0), N0.getOperand(1).getOperand(0));
         // fold (sub x, (select cc, 0, c)) -> (select cc, x, (sub, x, c))
         if (N1.getOpcode() == ISD::SELECT && N1.getNode()->hasOneUse()) {
           SDValue Result = combineSelectAndUse(N, N1, N0, DAG, TLI, LegalOperations);
           if (Result.getNode()) return Result;
         }
      +
         // If either operand of a sub is undef, the result is undef
         if (N0.getOpcode() == ISD::UNDEF)
           return N0;
      -- 
      GitLab
      
      
      From 091f92f568d01309bc958941493990ce434def45 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:45:56 +0000
      Subject: [PATCH 477/682] Propagate debug loc info for MUL.
      
      llvm-svn: 63369
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 37 +++++++++++--------
       1 file changed, 21 insertions(+), 16 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 2039595e749c..0a09d6443b1d 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1287,34 +1287,36 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
           return DAG.FoldConstantArithmetic(ISD::MUL, VT, N0C, N1C);
         // canonicalize constant to RHS
         if (N0C && !N1C)
      -    return DAG.getNode(ISD::MUL, VT, N1, N0);
      +    return DAG.getNode(ISD::MUL, N->getDebugLoc(), VT, N1, N0);
         // fold (mul x, 0) -> 0
         if (N1C && N1C->isNullValue())
           return N1;
         // fold (mul x, -1) -> 0-x
         if (N1C && N1C->isAllOnesValue())
      -    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
      +                       DAG.getConstant(0, VT), N0);
         // fold (mul x, (1 << c)) -> x << c
         if (N1C && N1C->getAPIntValue().isPowerOf2())
      -    return DAG.getNode(ISD::SHL, VT, N0,
      +    return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
                              DAG.getConstant(N1C->getAPIntValue().logBase2(),
                                              TLI.getShiftAmountTy()));
         // fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c
      -  if (N1C && isPowerOf2_64(-N1C->getSExtValue())) {
      +  if (N1C && isPowerOf2_64(-N1C->getSExtValue()))
           // FIXME: If the input is something that is easily negated (e.g. a 
           // single-use add), we should put the negate there.
      -    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT),
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
      +                       DAG.getConstant(0, VT),
                              DAG.getNode(ISD::SHL, VT, N0,
                                   DAG.getConstant(Log2_64(-N1C->getSExtValue()),
                                                   TLI.getShiftAmountTy())));
      -  }
      -
         // (mul (shl X, c1), c2) -> (mul X, c2 << c1)
         if (N1C && N0.getOpcode() == ISD::SHL && 
             isa(N0.getOperand(1))) {
      -    SDValue C3 = DAG.getNode(ISD::SHL, VT, N1, N0.getOperand(1));
      +    SDValue C3 = DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
      +                             N1, N0.getOperand(1));
           AddToWorkList(C3.getNode());
      -    return DAG.getNode(ISD::MUL, VT, N0.getOperand(0), C3);
      +    return DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
      +                       N0.getOperand(0), C3);
         }
         
         // Change (mul (shl X, C), Y) -> (shl (mul X, Y), C) when the shift has one
      @@ -1331,17 +1333,20 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
             Sh = N1; Y = N0;
           }
           if (Sh.getNode()) {
      -      SDValue Mul = DAG.getNode(ISD::MUL, VT, Sh.getOperand(0), Y);
      -      return DAG.getNode(ISD::SHL, VT, Mul, Sh.getOperand(1));
      +      SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
      +                                Sh.getOperand(0), Y);
      +      return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
      +                         Mul, Sh.getOperand(1));
           }
         }
         // fold (mul (add x, c1), c2) -> (add (mul x, c2), c1*c2)
         if (N1C && N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse() && 
      -      isa(N0.getOperand(1))) {
      -    return DAG.getNode(ISD::ADD, VT, 
      -                       DAG.getNode(ISD::MUL, VT, N0.getOperand(0), N1),
      -                       DAG.getNode(ISD::MUL, VT, N0.getOperand(1), N1));
      -  }
      +      isa(N0.getOperand(1)))
      +    return DAG.getNode(ISD::ADD, N->getDebugLoc(), VT,
      +                       DAG.getNode(ISD::MUL, N0.getDebugLoc(), VT,
      +                                   N0.getOperand(0), N1),
      +                       DAG.getNode(ISD::MUL, N1.getDebugLoc(), VT,
      +                                   N0.getOperand(1), N1));
         
         // reassociate mul
         SDValue RMUL = ReassociateOps(ISD::MUL, N->getDebugLoc(), N0, N1);
      -- 
      GitLab
      
      
      From 1ee0d41ef82b1030f592a22224c7188c720578db Mon Sep 17 00:00:00 2001
      From: Dan Gohman 
      Date: Fri, 30 Jan 2009 02:49:14 +0000
      Subject: [PATCH 478/682] Fix a post-RA scheduling dependency bug.
      
      If a MachineInstr doesn't have a memoperand but has an opcode that
      is known to load or store, assume its memory reference may alias
      *anything*, including stack slots which the compiler completely
      controls.
      
      To partially compensate for this, teach the ScheduleDAG building
      code to do basic getUnderlyingValue analysis. This greatly
      reduces the number of instructions that require restrictive
      dependencies. This code will need to be revisited when we start
      doing real alias analysis, but it should suffice for now.
      
      llvm-svn: 63370
      ---
       llvm/include/llvm/Analysis/AliasAnalysis.h |   5 +
       llvm/lib/Analysis/BasicAliasAnalysis.cpp   |   2 +-
       llvm/lib/CodeGen/ScheduleDAGInstrs.cpp     | 101 ++++++++++++++++++---
       3 files changed, 96 insertions(+), 12 deletions(-)
      
      diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h
      index c705bccca4d3..2beb8fb0bf16 100644
      --- a/llvm/include/llvm/Analysis/AliasAnalysis.h
      +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h
      @@ -345,6 +345,11 @@ public:
         }
       };
       
      +/// isIdentifiedObject - Return true if this pointer refers to a distinct and
      +/// identifiable object.
      +///
      +bool isIdentifiedObject(const Value *V);
      +
       } // End llvm namespace
       
       // Because of the way .a files work, we must force the BasicAA implementation to
      diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
      index 82514400b826..1002868e84cb 100644
      --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp
      +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp
      @@ -80,7 +80,7 @@ static bool isNoAliasCall(const Value *V) {
       ///    ByVal and NoAlias Arguments
       ///    NoAlias returns
       ///
      -static bool isIdentifiedObject(const Value *V) {
      +bool llvm::isIdentifiedObject(const Value *V) {
         if (isa(V) || isa(V) || isNoAliasCall(V))
           return true;
         if (const Argument *A = dyn_cast(V))
      diff --git a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
      index 0ffdd05c2ee1..9541de642423 100644
      --- a/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
      +++ b/llvm/lib/CodeGen/ScheduleDAGInstrs.cpp
      @@ -13,6 +13,7 @@
       //===----------------------------------------------------------------------===//
       
       #define DEBUG_TYPE "sched-instrs"
      +#include "llvm/Analysis/AliasAnalysis.h"
       #include "llvm/CodeGen/MachineDominators.h"
       #include "llvm/CodeGen/MachineFunctionPass.h"
       #include "llvm/CodeGen/MachineLoopInfo.h"
      @@ -95,6 +96,82 @@ ScheduleDAGInstrs::ScheduleDAGInstrs(MachineFunction &mf,
                                            const MachineDominatorTree &mdt)
         : ScheduleDAG(mf), MLI(mli), MDT(mdt) {}
       
      +/// getOpcode - If this is an Instruction or a ConstantExpr, return the
      +/// opcode value. Otherwise return UserOp1.
      +static unsigned getOpcode(const Value *V) {
      +  if (const Instruction *I = dyn_cast(V))
      +    return I->getOpcode();
      +  if (const ConstantExpr *CE = dyn_cast(V))
      +    return CE->getOpcode();
      +  // Use UserOp1 to mean there's no opcode.
      +  return Instruction::UserOp1;
      +}
      +
      +/// getUnderlyingObjectFromInt - This is the function that does the work of
      +/// looking through basic ptrtoint+arithmetic+inttoptr sequences.
      +static const Value *getUnderlyingObjectFromInt(const Value *V) {
      +  do {
      +    if (const User *U = dyn_cast(V)) {
      +      // If we find a ptrtoint, we can transfer control back to the
      +      // regular getUnderlyingObjectFromInt.
      +      if (getOpcode(U) == Instruction::PtrToInt)
      +        return U->getOperand(0);
      +      // If we find an add of a constant or a multiplied value, it's
      +      // likely that the other operand will lead us to the base
      +      // object. We don't have to worry about the case where the
      +      // object address is somehow being computed bt the multiply,
      +      // because our callers only care when the result is an
      +      // identifibale object.
      +      if (getOpcode(U) != Instruction::Add ||
      +          (!isa(U->getOperand(1)) &&
      +           getOpcode(U->getOperand(1)) != Instruction::Mul))
      +        return V;
      +      V = U->getOperand(0);
      +    } else {
      +      return V;
      +    }
      +    assert(isa(V->getType()) && "Unexpected operand type!");
      +  } while (1);
      +}
      +
      +/// getUnderlyingObject - This is a wrapper around Value::getUnderlyingObject
      +/// and adds support for basic ptrtoint+arithmetic+inttoptr sequences.
      +static const Value *getUnderlyingObject(const Value *V) {
      +  // First just call Value::getUnderlyingObject to let it do what it does.
      +  do {
      +    V = V->getUnderlyingObject();
      +    // If it found an inttoptr, use special code to continue climing.
      +    if (getOpcode(V) != Instruction::IntToPtr)
      +      break;
      +    const Value *O = getUnderlyingObjectFromInt(cast(V)->getOperand(0));
      +    // If that succeeded in finding a pointer, continue the search.
      +    if (!isa(O->getType()))
      +      break;
      +    V = O;
      +  } while (1);
      +  return V;
      +}
      +
      +/// getUnderlyingObjectForInstr - If this machine instr has memory reference
      +/// information and it can be tracked to a normal reference to a known
      +/// object, return the Value for that object. Otherwise return null.
      +static const Value *getUnderlyingObjectForInstr(const MachineInstr *MI) {
      +  if (!MI->hasOneMemOperand() ||
      +      !MI->memoperands_begin()->getValue() ||
      +      MI->memoperands_begin()->isVolatile())
      +    return 0;
      +
      +  const Value *V = MI->memoperands_begin()->getValue();
      +  if (!V)
      +    return 0;
      +
      +  V = getUnderlyingObject(V);
      +  if (!isa(V) && !isIdentifiedObject(V))
      +    return 0;
      +
      +  return V;
      +}
      +
       void ScheduleDAGInstrs::BuildSchedGraph() {
         SUnits.reserve(BB->size());
       
      @@ -313,12 +390,8 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
               // Unknown memory accesses. Assume the worst.
               ChainMMO = 0;
           } else if (TID.mayStore()) {
      -      if (MI->hasOneMemOperand() &&
      -          MI->memoperands_begin()->getValue() &&
      -          !MI->memoperands_begin()->isVolatile() &&
      -          isa(MI->memoperands_begin()->getValue())) {
      +      if (const Value *V = getUnderlyingObjectForInstr(MI)) {
               // A store to a specific PseudoSourceValue. Add precise dependencies.
      -        const Value *V = MI->memoperands_begin()->getValue();
               // Handle the def in MemDefs, if there is one.
               std::map::iterator I = MemDefs.find(V);
               if (I != MemDefs.end()) {
      @@ -337,6 +410,10 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
                                              /*isNormalMemory=*/true));
                 J->second.clear();
               }
      +        // Add dependencies from all the PendingLoads, since without
      +        // memoperands we must assume they alias anything.
      +        for (unsigned k = 0, m = PendingLoads.size(); k != m; ++k)
      +          PendingLoads[k]->addPred(SDep(SU, SDep::Order, SU->Latency));
               // Add a general dependence too, if needed.
               if (Chain)
                 Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
      @@ -346,12 +423,8 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
           } else if (TID.mayLoad()) {
             if (TII->isInvariantLoad(MI)) {
               // Invariant load, no chain dependencies needed!
      -      } else if (MI->hasOneMemOperand() &&
      -                 MI->memoperands_begin()->getValue() &&
      -                 !MI->memoperands_begin()->isVolatile() &&
      -                 isa(MI->memoperands_begin()->getValue())) {
      +      } else if (const Value *V = getUnderlyingObjectForInstr(MI)) {
               // A load from a specific PseudoSourceValue. Add precise dependencies.
      -        const Value *V = MI->memoperands_begin()->getValue();
               std::map::iterator I = MemDefs.find(V);
               if (I != MemDefs.end())
                 I->second->addPred(SDep(SU, SDep::Order, SU->Latency, /*Reg=*/0,
      @@ -367,9 +440,15 @@ void ScheduleDAGInstrs::BuildSchedGraph() {
               // cases where memoperand information is unavailable.
               goto new_chain;
             } else {
      -        // A normal load. Just depend on the general chain.
      +        // A normal load. Depend on the general chain, as well as on
      +        // all stores. In the absense of MachineMemOperand information,
      +        // we can't even assume that the load doesn't alias well-behaved
      +        // memory locations.
               if (Chain)
                 Chain->addPred(SDep(SU, SDep::Order, SU->Latency));
      +        for (std::map::iterator I = MemDefs.begin(),
      +             E = MemDefs.end(); I != E; ++I)
      +          I->second->addPred(SDep(SU, SDep::Order, SU->Latency));
               PendingLoads.push_back(SU);
             }
           }
      -- 
      GitLab
      
      
      From b48dcf67e5d5973dfe59b875c9467c64f2b8fcca Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:49:26 +0000
      Subject: [PATCH 479/682] Forgot to propagate debug loc info here.
      
      llvm-svn: 63371
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 ++++--
       1 file changed, 4 insertions(+), 2 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 0a09d6443b1d..1340ec5435a9 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1306,11 +1306,11 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
           // single-use add), we should put the negate there.
           return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
                              DAG.getConstant(0, VT),
      -                       DAG.getNode(ISD::SHL, VT, N0,
      +                       DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0,
                                   DAG.getConstant(Log2_64(-N1C->getSExtValue()),
                                                   TLI.getShiftAmountTy())));
         // (mul (shl X, c1), c2) -> (mul X, c2 << c1)
      -  if (N1C && N0.getOpcode() == ISD::SHL && 
      +  if (N1C && N0.getOpcode() == ISD::SHL &&
             isa(N0.getOperand(1))) {
           SDValue C3 = DAG.getNode(ISD::SHL, N->getDebugLoc(), VT,
                                    N1, N0.getOperand(1));
      @@ -1332,6 +1332,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
                      N1.getNode()->hasOneUse()) {
             Sh = N1; Y = N0;
           }
      +
           if (Sh.getNode()) {
             SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
                                       Sh.getOperand(0), Y);
      @@ -1339,6 +1340,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) {
                                Mul, Sh.getOperand(1));
           }
         }
      +
         // fold (mul (add x, c1), c2) -> (add (mul x, c2), c1*c2)
         if (N1C && N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse() && 
             isa(N0.getOperand(1)))
      -- 
      GitLab
      
      
      From 5b663e7b53fc1e1ef7a18f0fb9fbbe16b3597c6c Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:52:17 +0000
      Subject: [PATCH 480/682] Propagate debug loc info for SDIV.
      
      llvm-svn: 63372
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 33 ++++++++++++-------
       1 file changed, 21 insertions(+), 12 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 1340ec5435a9..2b59fe57917f 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1379,12 +1379,14 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
           return N0;
         // fold (sdiv X, -1) -> 0-X
         if (N1C && N1C->isAllOnesValue())
      -    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), N0);
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
      +                       DAG.getConstant(0, VT), N0);
         // If we know the sign bits of both operands are zero, strength reduce to a
         // udiv instead.  Handles (X&15) /s 4 -> X&15 >> 2
         if (!VT.isVector()) {
           if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
      -      return DAG.getNode(ISD::UDIV, N1.getValueType(), N0, N1);
      +      return DAG.getNode(ISD::UDIV, N->getDebugLoc(), N1.getValueType(),
      +                         N0, N1);
         }
         // fold (sdiv X, pow2) -> simple ops after legalize
         if (N1C && !N1C->isNullValue() && !TLI.isIntDivCheap() &&
      @@ -1394,30 +1396,37 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) {
           // fold.
           if (TLI.isPow2DivCheap())
             return SDValue();
      +
           int64_t pow2 = N1C->getSExtValue();
           int64_t abs2 = pow2 > 0 ? pow2 : -pow2;
           unsigned lg2 = Log2_64(abs2);
      +
           // Splat the sign bit into the register
      -    SDValue SGN = DAG.getNode(ISD::SRA, VT, N0,
      -                                DAG.getConstant(VT.getSizeInBits()-1,
      -                                                TLI.getShiftAmountTy()));
      +    SDValue SGN = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0,
      +                              DAG.getConstant(VT.getSizeInBits()-1,
      +                                              TLI.getShiftAmountTy()));
           AddToWorkList(SGN.getNode());
      +
           // Add (N0 < 0) ? abs2 - 1 : 0;
      -    SDValue SRL = DAG.getNode(ISD::SRL, VT, SGN,
      -                                DAG.getConstant(VT.getSizeInBits()-lg2,
      -                                                TLI.getShiftAmountTy()));
      -    SDValue ADD = DAG.getNode(ISD::ADD, VT, N0, SRL);
      +    SDValue SRL = DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, SGN,
      +                              DAG.getConstant(VT.getSizeInBits() - lg2,
      +                                              TLI.getShiftAmountTy()));
      +    SDValue ADD = DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0, SRL);
           AddToWorkList(SRL.getNode());
           AddToWorkList(ADD.getNode());    // Divide by pow2
      -    SDValue SRA = DAG.getNode(ISD::SRA, VT, ADD,
      -                                DAG.getConstant(lg2, TLI.getShiftAmountTy()));
      +    SDValue SRA = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, ADD,
      +                              DAG.getConstant(lg2, TLI.getShiftAmountTy()));
      +
           // If we're dividing by a positive value, we're done.  Otherwise, we must
           // negate the result.
           if (pow2 > 0)
             return SRA;
      +
           AddToWorkList(SRA.getNode());
      -    return DAG.getNode(ISD::SUB, VT, DAG.getConstant(0, VT), SRA);
      +    return DAG.getNode(ISD::SUB, N->getDebugLoc(), VT,
      +                       DAG.getConstant(0, VT), SRA);
         }
      +
         // if integer divide is expensive and we satisfy the requirements, emit an
         // alternate sequence.
         if (N1C && (N1C->getSExtValue() < -1 || N1C->getSExtValue() > 1) && 
      -- 
      GitLab
      
      
      From aff3e03765af9762d3f146bb464bd41e6caca42c Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:55:25 +0000
      Subject: [PATCH 481/682] Propagate debug loc info for UDIV.
      
      llvm-svn: 63373
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 13 +++++++------
       1 file changed, 7 insertions(+), 6 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 2b59fe57917f..64e7f3aa3ab8 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1463,7 +1463,7 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {
           return DAG.FoldConstantArithmetic(ISD::UDIV, VT, N0C, N1C);
         // fold (udiv x, (1 << c)) -> x >>u c
         if (N1C && N1C->getAPIntValue().isPowerOf2())
      -    return DAG.getNode(ISD::SRL, VT, N0, 
      +    return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, 
                              DAG.getConstant(N1C->getAPIntValue().logBase2(),
                                              TLI.getShiftAmountTy()));
         // fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2
      @@ -1471,12 +1471,13 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) {
           if (ConstantSDNode *SHC = dyn_cast(N1.getOperand(0))) {
             if (SHC->getAPIntValue().isPowerOf2()) {
               MVT ADDVT = N1.getOperand(1).getValueType();
      -        SDValue Add = DAG.getNode(ISD::ADD, ADDVT, N1.getOperand(1),
      -                                    DAG.getConstant(SHC->getAPIntValue()
      -                                                                    .logBase2(),
      -                                                    ADDVT));
      +        SDValue Add = DAG.getNode(ISD::ADD, N->getDebugLoc(), ADDVT,
      +                                  N1.getOperand(1),
      +                                  DAG.getConstant(SHC->getAPIntValue()
      +                                                                  .logBase2(),
      +                                                  ADDVT));
               AddToWorkList(Add.getNode());
      -        return DAG.getNode(ISD::SRL, VT, N0, Add);
      +        return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, Add);
             }
           }
         }
      -- 
      GitLab
      
      
      From d033af09fd73ef935d16baa942e3898c2664d876 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 02:57:00 +0000
      Subject: [PATCH 482/682] Propagate debug loc info for SREM and UREM.
      
      llvm-svn: 63374
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 22 ++++++++++---------
       1 file changed, 12 insertions(+), 10 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 64e7f3aa3ab8..9794644bc92e 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1511,18 +1511,19 @@ SDValue DAGCombiner::visitSREM(SDNode *N) {
         // urem instead.  Handles (X & 0x0FFFFFFF) %s 16 -> X&15
         if (!VT.isVector()) {
           if (DAG.SignBitIsZero(N1) && DAG.SignBitIsZero(N0))
      -      return DAG.getNode(ISD::UREM, VT, N0, N1);
      +      return DAG.getNode(ISD::UREM, N->getDebugLoc(), VT, N0, N1);
         }
         
         // If X/C can be simplified by the division-by-constant logic, lower
         // X%C to the equivalent of X-X/C*C.
         if (N1C && !N1C->isNullValue()) {
      -    SDValue Div = DAG.getNode(ISD::SDIV, VT, N0, N1);
      +    SDValue Div = DAG.getNode(ISD::SDIV, N->getDebugLoc(), VT, N0, N1);
           AddToWorkList(Div.getNode());
           SDValue OptimizedDiv = combine(Div.getNode());
           if (OptimizedDiv.getNode() && OptimizedDiv.getNode() != Div.getNode()) {
      -      SDValue Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1);
      -      SDValue Sub = DAG.getNode(ISD::SUB, VT, N0, Mul);
      +      SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
      +                                OptimizedDiv, N1);
      +      SDValue Sub = DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, Mul);
             AddToWorkList(Mul.getNode());
             return Sub;
           }
      @@ -1550,18 +1551,18 @@ SDValue DAGCombiner::visitUREM(SDNode *N) {
           return DAG.FoldConstantArithmetic(ISD::UREM, VT, N0C, N1C);
         // fold (urem x, pow2) -> (and x, pow2-1)
         if (N1C && !N1C->isNullValue() && N1C->getAPIntValue().isPowerOf2())
      -    return DAG.getNode(ISD::AND, VT, N0,
      +    return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0,
                              DAG.getConstant(N1C->getAPIntValue()-1,VT));
         // fold (urem x, (shl pow2, y)) -> (and x, (add (shl pow2, y), -1))
         if (N1.getOpcode() == ISD::SHL) {
           if (ConstantSDNode *SHC = dyn_cast(N1.getOperand(0))) {
             if (SHC->getAPIntValue().isPowerOf2()) {
               SDValue Add =
      -          DAG.getNode(ISD::ADD, VT, N1,
      +          DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N1,
                        DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()),
                                        VT));
               AddToWorkList(Add.getNode());
      -        return DAG.getNode(ISD::AND, VT, N0, Add);
      +        return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0, Add);
             }
           }
         }
      @@ -1569,12 +1570,13 @@ SDValue DAGCombiner::visitUREM(SDNode *N) {
         // If X/C can be simplified by the division-by-constant logic, lower
         // X%C to the equivalent of X-X/C*C.
         if (N1C && !N1C->isNullValue()) {
      -    SDValue Div = DAG.getNode(ISD::UDIV, VT, N0, N1);
      +    SDValue Div = DAG.getNode(ISD::UDIV, N->getDebugLoc(), VT, N0, N1);
           AddToWorkList(Div.getNode());
           SDValue OptimizedDiv = combine(Div.getNode());
           if (OptimizedDiv.getNode() && OptimizedDiv.getNode() != Div.getNode()) {
      -      SDValue Mul = DAG.getNode(ISD::MUL, VT, OptimizedDiv, N1);
      -      SDValue Sub = DAG.getNode(ISD::SUB, VT, N0, Mul);
      +      SDValue Mul = DAG.getNode(ISD::MUL, N->getDebugLoc(), VT,
      +                                OptimizedDiv, N1);
      +      SDValue Sub = DAG.getNode(ISD::SUB, N->getDebugLoc(), VT, N0, Mul);
             AddToWorkList(Mul.getNode());
             return Sub;
           }
      -- 
      GitLab
      
      
      From faed065e5c65a18c43f0cc00e50b907eedf8981b Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 03:00:18 +0000
      Subject: [PATCH 483/682] Propagate debug loc info for MULHS.
      
      llvm-svn: 63375
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 4 ++--
       1 file changed, 2 insertions(+), 2 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 9794644bc92e..6511233dd192 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1603,8 +1603,8 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) {
           return N1;
         // fold (mulhs x, 1) -> (sra x, size(x)-1)
         if (N1C && N1C->getAPIntValue() == 1)
      -    return DAG.getNode(ISD::SRA, N0.getValueType(), N0, 
      -                       DAG.getConstant(N0.getValueType().getSizeInBits()-1,
      +    return DAG.getNode(ISD::SRA, N->getDebugLoc(), N0.getValueType(), N0,
      +                       DAG.getConstant(N0.getValueType().getSizeInBits() - 1,
                                              TLI.getShiftAmountTy()));
         // fold (mulhs x, undef) -> 0
         if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF)
      -- 
      GitLab
      
      
      From 9b3407e5bb5f6fbe5a6fbf4559989426abfd58a8 Mon Sep 17 00:00:00 2001
      From: Bill Wendling 
      Date: Fri, 30 Jan 2009 03:08:40 +0000
      Subject: [PATCH 484/682] Propagate debug loc info in
       SimplifyNodeWithTwoResults.
      
      llvm-svn: 63376
      ---
       llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 15 ++++++++-------
       1 file changed, 8 insertions(+), 7 deletions(-)
      
      diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      index 6511233dd192..36927b358d7f 100644
      --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
      @@ -1643,8 +1643,8 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
         if (!HiExists &&
             (!LegalOperations ||
              TLI.isOperationLegal(LoOp, N->getValueType(0)))) {
      -    SDValue Res = DAG.getNode(LoOp, N->getValueType(0), N->op_begin(),
      -                              N->getNumOperands());
      +    SDValue Res = DAG.getNode(LoOp, N->getDebugLoc(), N->getValueType(0),
      +                              N->op_begin(), N->getNumOperands());
           return CombineTo(N, Res, Res);
         }
       
      @@ -1653,8 +1653,8 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
         if (!LoExists &&
             (!LegalOperations ||
              TLI.isOperationLegal(HiOp, N->getValueType(1)))) {
      -    SDValue Res = DAG.getNode(HiOp, N->getValueType(1), N->op_begin(),
      -                              N->getNumOperands());
      +    SDValue Res = DAG.getNode(HiOp, N->getDebugLoc(), N->getValueType(1),
      +                              N->op_begin(), N->getNumOperands());
           return CombineTo(N, Res, Res);
         }
       
      @@ -1664,8 +1664,8 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
       
         // If the two computed results can be simplified separately, separate them.
         if (LoExists) {
      -    SDValue Lo = DAG.getNode(LoOp, N->getValueType(0),
      -                               N->op_begin(), N->getNumOperands());
      +    SDValue Lo = DAG.getNode(LoOp, N->getDebugLoc(), N->getValueType(0),
      +                             N->op_begin(), N->getNumOperands());
           AddToWorkList(Lo.getNode());
           SDValue LoOpt = combine(Lo.getNode());
           if (LoOpt.getNode() && LoOpt.getNode() != Lo.getNode() &&
      @@ -1675,7 +1675,7 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
         }
       
         if (HiExists) {
      -    SDValue Hi = DAG.getNode(HiOp, N->getValueType(1),
      +    SDValue Hi = DAG.getNode(HiOp, N->getDebugLoc(), N->getValueType(1),
                                    N->op_begin(), N->getNumOperands());
           AddToWorkList(Hi.getNode());
           SDValue HiOpt = combine(Hi.getNode());
      @@ -1684,6 +1684,7 @@ SDValue DAGCombiner::SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp,
                TLI.isOperationLegal(HiOpt.getOpcode(), HiOpt.getValueType())))
             return CombineTo(N, HiOpt, HiOpt);
         }
      +
         return SDValue();
       }
       
      -- 
      GitLab
      
      
      From 964a29f6717b1c29d0f74a56a1e23d77bdc8b1d0 Mon Sep 17 00:00:00 2001
      From: Sanjiv Gupta 
      Date: Fri, 30 Jan 2009 04:25:10 +0000
      Subject: [PATCH 485/682] Enable emitting of constant values in non-default
       address space as well. The APIs emitting constants now take an additional
       parameter signifying the address space in which to emit. The APIs like
       getData8BitsDirective() etc are made virtual enabling targets to be able to
       define appropirate directivers for various sizes and address spaces.
      
      llvm-svn: 63377
      ---
       llvm/include/llvm/CodeGen/AsmPrinter.h       |  13 ++-
       llvm/include/llvm/Target/TargetAsmInfo.h     |  27 +++--
       llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp   | 115 ++++++++++---------
       llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp    |  41 +------
       llvm/lib/Target/PIC16/PIC16AsmPrinter.h      |   1 -
       llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp |  32 +++++-
       llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h   |   6 +
       7 files changed, 119 insertions(+), 116 deletions(-)
      
      diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
      index cdc795162579..d63b06d954e2 100644
      --- a/llvm/include/llvm/CodeGen/AsmPrinter.h
      +++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
      @@ -309,7 +309,7 @@ namespace llvm {
         protected:
           /// EmitZeros - Emit a block of zeros.
           ///
      -    void EmitZeros(uint64_t NumZeros) const;
      +    void EmitZeros(uint64_t NumZeros, unsigned AddrSpace = 0) const;
       
           /// EmitString - Emit a zero-byte-terminated string constant.
           ///
      @@ -320,7 +320,7 @@ namespace llvm {
           void EmitConstantValueOnly(const Constant *CV);
       
           /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
      -    void EmitGlobalConstant(const Constant* CV);
      +    void EmitGlobalConstant(const Constant* CV, unsigned AddrSpace = 0);
       
           virtual void EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV);
           
      @@ -351,7 +351,7 @@ namespace llvm {
           
           /// printDataDirective - This method prints the asm directive for the
           /// specified type.
      -    void printDataDirective(const Type *type);
      +    void printDataDirective(const Type *type, unsigned AddrSpace = 0);
       
           /// printSuffixedName - This prints a name with preceding 
           /// getPrivateGlobalPrefix and the specified suffix, handling quoted names
      @@ -371,11 +371,12 @@ namespace llvm {
           const GlobalValue *findGlobalValue(const Constant* CV);
           void EmitLLVMUsedList(Constant *List);
           void EmitXXStructorList(Constant *List);
      -    void EmitGlobalConstantStruct(const ConstantStruct* CVS);
      +    void EmitGlobalConstantStruct(const ConstantStruct* CVS,
      +                                  unsigned AddrSpace);
           void EmitGlobalConstantArray(const ConstantArray* CVA);
           void EmitGlobalConstantVector(const ConstantVector* CP);
      -    void EmitGlobalConstantFP(const ConstantFP* CFP);
      -    void EmitGlobalConstantLargeInt(const ConstantInt* CI);
      +    void EmitGlobalConstantFP(const ConstantFP* CFP, unsigned AddrSpace);
      +    void EmitGlobalConstantLargeInt(const ConstantInt* CI, unsigned AddrSpace);
           GCMetadataPrinter *GetOrCreateGCPrinter(GCStrategy *C);
         };
       }
      diff --git a/llvm/include/llvm/Target/TargetAsmInfo.h b/llvm/include/llvm/Target/TargetAsmInfo.h
      index bdfacf765715..1cd55d0fcd1d 100644
      --- a/llvm/include/llvm/Target/TargetAsmInfo.h
      +++ b/llvm/include/llvm/Target/TargetAsmInfo.h
      @@ -598,6 +598,21 @@ namespace llvm {
       
           static unsigned getULEB128Size(unsigned Value);
       
      +    // Data directive accessors
      +    //
      +    virtual const char *getData8bitsDirective(unsigned AddrSpace = 0) const {
      +      return Data8bitsDirective;
      +    }
      +    virtual const char *getData16bitsDirective(unsigned AddrSpace = 0) const {
      +      return Data16bitsDirective;
      +    }
      +    virtual const char *getData32bitsDirective(unsigned AddrSpace = 0) const {
      +      return Data32bitsDirective;
      +    }
      +    virtual const char *getData64bitsDirective(unsigned AddrSpace = 0) const {
      +      return Data64bitsDirective;
      +    }
      +
           // Accessors.
           //
           const Section *getTextSection() const {
      @@ -711,18 +726,6 @@ namespace llvm {
           const char *getAscizDirective() const {
             return AscizDirective;
           }
      -    const char *getData8bitsDirective() const {
      -      return Data8bitsDirective;
      -    }
      -    const char *getData16bitsDirective() const {
      -      return Data16bitsDirective;
      -    }
      -    const char *getData32bitsDirective() const {
      -      return Data32bitsDirective;
      -    }
      -    const char *getData64bitsDirective() const {
      -      return Data64bitsDirective;
      -    }
           const char *getJumpTableDirective() const {
             return JumpTableDirective;
           }
      diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
      index 9334f1ef3f2e..c6b0313c39f4 100644
      --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
      +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
      @@ -770,7 +770,7 @@ void AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV,
           
       /// EmitZeros - Emit a block of zeros.
       ///
      -void AsmPrinter::EmitZeros(uint64_t NumZeros) const {
      +void AsmPrinter::EmitZeros(uint64_t NumZeros, unsigned AddrSpace) const {
         if (NumZeros) {
           if (TAI->getZeroDirective()) {
             O << TAI->getZeroDirective() << NumZeros;
      @@ -779,7 +779,7 @@ void AsmPrinter::EmitZeros(uint64_t NumZeros) const {
             O << '\n';
           } else {
             for (; NumZeros; --NumZeros)
      -        O << TAI->getData8bitsDirective() << "0\n";
      +        O << TAI->getData8bitsDirective(AddrSpace) << "0\n";
           }
         }
       }
      @@ -956,7 +956,8 @@ void AsmPrinter::EmitGlobalConstantVector(const ConstantVector *CP) {
           EmitGlobalConstant(CP->getOperand(I));
       }
       
      -void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS) {
      +void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS,
      +                                          unsigned AddrSpace) {
         // Print the fields in successive locations. Pad to align if needed!
         const TargetData *TD = TM.getTargetData();
         unsigned Size = TD->getTypePaddedSize(CVS->getType());
      @@ -972,46 +973,47 @@ void AsmPrinter::EmitGlobalConstantStruct(const ConstantStruct *CVS) {
           sizeSoFar += fieldSize + padSize;
       
           // Now print the actual field value.
      -    EmitGlobalConstant(field);
      +    EmitGlobalConstant(field, AddrSpace);
       
           // Insert padding - this may include padding to increase the size of the
           // current field up to the ABI size (if the struct is not packed) as well
           // as padding to ensure that the next field starts at the right offset.
      -    EmitZeros(padSize);
      +    EmitZeros(padSize, AddrSpace);
         }
         assert(sizeSoFar == cvsLayout->getSizeInBytes() &&
                "Layout of constant struct may be incorrect!");
       }
       
      -void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
      +void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP, 
      +                                      unsigned AddrSpace) {
         // FP Constants are printed as integer constants to avoid losing
         // precision...
         const TargetData *TD = TM.getTargetData();
         if (CFP->getType() == Type::DoubleTy) {
           double Val = CFP->getValueAPF().convertToDouble();  // for comment only
           uint64_t i = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
      -    if (TAI->getData64bitsDirective())
      -      O << TAI->getData64bitsDirective() << i << '\t'
      +    if (TAI->getData64bitsDirective(AddrSpace))
      +      O << TAI->getData64bitsDirective(AddrSpace) << i << '\t'
               << TAI->getCommentString() << " double value: " << Val << '\n';
           else if (TD->isBigEndian()) {
      -      O << TAI->getData32bitsDirective() << unsigned(i >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32)
               << '\t' << TAI->getCommentString()
               << " double most significant word " << Val << '\n';
      -      O << TAI->getData32bitsDirective() << unsigned(i)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i)
               << '\t' << TAI->getCommentString()
               << " double least significant word " << Val << '\n';
           } else {
      -      O << TAI->getData32bitsDirective() << unsigned(i)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i)
               << '\t' << TAI->getCommentString()
               << " double least significant word " << Val << '\n';
      -      O << TAI->getData32bitsDirective() << unsigned(i >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(i >> 32)
               << '\t' << TAI->getCommentString()
               << " double most significant word " << Val << '\n';
           }
           return;
         } else if (CFP->getType() == Type::FloatTy) {
           float Val = CFP->getValueAPF().convertToFloat();  // for comment only
      -    O << TAI->getData32bitsDirective()
      +    O << TAI->getData32bitsDirective(AddrSpace)
             << CFP->getValueAPF().bitcastToAPInt().getZExtValue()
             << '\t' << TAI->getCommentString() << " float " << Val << '\n';
           return;
      @@ -1026,42 +1028,42 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
           DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
                             &ignored);
           if (TD->isBigEndian()) {
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
               << '\t' << TAI->getCommentString()
               << " long double most significant halfword of ~"
               << DoubleVal.convertToDouble() << '\n';
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32)
               << '\t' << TAI->getCommentString()
               << " long double next halfword\n";
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16)
               << '\t' << TAI->getCommentString()
               << " long double next halfword\n";
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0])
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
               << '\t' << TAI->getCommentString()
               << " long double next halfword\n";
      -      O << TAI->getData16bitsDirective() << uint16_t(p[1])
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
               << '\t' << TAI->getCommentString()
               << " long double least significant halfword\n";
            } else {
      -      O << TAI->getData16bitsDirective() << uint16_t(p[1])
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[1])
               << '\t' << TAI->getCommentString()
               << " long double least significant halfword of ~"
               << DoubleVal.convertToDouble() << '\n';
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0])
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0])
               << '\t' << TAI->getCommentString()
               << " long double next halfword\n";
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 16)
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 16)
               << '\t' << TAI->getCommentString()
               << " long double next halfword\n";
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 32)
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 32)
               << '\t' << TAI->getCommentString()
               << " long double next halfword\n";
      -      O << TAI->getData16bitsDirective() << uint16_t(p[0] >> 48)
      +      O << TAI->getData16bitsDirective(AddrSpace) << uint16_t(p[0] >> 48)
               << '\t' << TAI->getCommentString()
               << " long double most significant halfword\n";
           }
           EmitZeros(TD->getTypePaddedSize(Type::X86_FP80Ty) -
      -              TD->getTypeStoreSize(Type::X86_FP80Ty));
      +              TD->getTypeStoreSize(Type::X86_FP80Ty), AddrSpace);
           return;
         } else if (CFP->getType() == Type::PPC_FP128Ty) {
           // all long double variants are printed as hex
      @@ -1069,29 +1071,29 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
           APInt api = CFP->getValueAPF().bitcastToAPInt();
           const uint64_t *p = api.getRawData();
           if (TD->isBigEndian()) {
      -      O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32)
               << '\t' << TAI->getCommentString()
               << " long double most significant word\n";
      -      O << TAI->getData32bitsDirective() << uint32_t(p[0])
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0])
               << '\t' << TAI->getCommentString()
               << " long double next word\n";
      -      O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32)
               << '\t' << TAI->getCommentString()
               << " long double next word\n";
      -      O << TAI->getData32bitsDirective() << uint32_t(p[1])
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1])
               << '\t' << TAI->getCommentString()
               << " long double least significant word\n";
            } else {
      -      O << TAI->getData32bitsDirective() << uint32_t(p[1])
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1])
               << '\t' << TAI->getCommentString()
               << " long double least significant word\n";
      -      O << TAI->getData32bitsDirective() << uint32_t(p[1] >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[1] >> 32)
               << '\t' << TAI->getCommentString()
               << " long double next word\n";
      -      O << TAI->getData32bitsDirective() << uint32_t(p[0])
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0])
               << '\t' << TAI->getCommentString()
               << " long double next word\n";
      -      O << TAI->getData32bitsDirective() << uint32_t(p[0] >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << uint32_t(p[0] >> 32)
               << '\t' << TAI->getCommentString()
               << " long double most significant word\n";
           }
      @@ -1099,7 +1101,8 @@ void AsmPrinter::EmitGlobalConstantFP(const ConstantFP *CFP) {
         } else assert(0 && "Floating point constant type not handled");
       }
       
      -void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
      +void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI,
      +                                            unsigned AddrSpace) {
         const TargetData *TD = TM.getTargetData();
         unsigned BitWidth = CI->getBitWidth();
         assert(isPowerOf2_32(BitWidth) &&
      @@ -1116,20 +1119,20 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
           else
             Val = RawData[i];
       
      -    if (TAI->getData64bitsDirective())
      -      O << TAI->getData64bitsDirective() << Val << '\n';
      +    if (TAI->getData64bitsDirective(AddrSpace))
      +      O << TAI->getData64bitsDirective(AddrSpace) << Val << '\n';
           else if (TD->isBigEndian()) {
      -      O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32)
               << '\t' << TAI->getCommentString()
               << " Double-word most significant word " << Val << '\n';
      -      O << TAI->getData32bitsDirective() << unsigned(Val)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val)
               << '\t' << TAI->getCommentString()
               << " Double-word least significant word " << Val << '\n';
           } else {
      -      O << TAI->getData32bitsDirective() << unsigned(Val)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val)
               << '\t' << TAI->getCommentString()
               << " Double-word least significant word " << Val << '\n';
      -      O << TAI->getData32bitsDirective() << unsigned(Val >> 32)
      +      O << TAI->getData32bitsDirective(AddrSpace) << unsigned(Val >> 32)
               << '\t' << TAI->getCommentString()
               << " Double-word most significant word " << Val << '\n';
           }
      @@ -1137,27 +1140,27 @@ void AsmPrinter::EmitGlobalConstantLargeInt(const ConstantInt *CI) {
       }
       
       /// EmitGlobalConstant - Print a general LLVM constant to the .s file.
      -void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
      +void AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
         const TargetData *TD = TM.getTargetData();
         const Type *type = CV->getType();
         unsigned Size = TD->getTypePaddedSize(type);
       
         if (CV->isNullValue() || isa(CV)) {
      -    EmitZeros(Size);
      +    EmitZeros(Size, AddrSpace);
           return;
         } else if (const ConstantArray *CVA = dyn_cast(CV)) {
           EmitGlobalConstantArray(CVA);
           return;
         } else if (const ConstantStruct *CVS = dyn_cast(CV)) {
      -    EmitGlobalConstantStruct(CVS);
      +    EmitGlobalConstantStruct(CVS, AddrSpace);
           return;
         } else if (const ConstantFP *CFP = dyn_cast(CV)) {
      -    EmitGlobalConstantFP(CFP);
      +    EmitGlobalConstantFP(CFP, AddrSpace);
           return;
         } else if (const ConstantInt *CI = dyn_cast(CV)) {
           // Small integers are handled below; large integers are handled here.
           if (Size > 4) {
      -      EmitGlobalConstantLargeInt(CI);
      +      EmitGlobalConstantLargeInt(CI, AddrSpace);
             return;
           }
         } else if (const ConstantVector *CP = dyn_cast(CV)) {
      @@ -1165,7 +1168,7 @@ void AsmPrinter::EmitGlobalConstant(const Constant *CV) {
           return;
         }
       
      -  printDataDirective(type);
      +  printDataDirective(type, AddrSpace);
         EmitConstantValueOnly(CV);
         if (const ConstantInt *CI = dyn_cast(CV)) {
           SmallString<40> S;
      @@ -1491,21 +1494,21 @@ void AsmPrinter::printPICJumpTableSetLabel(unsigned uid, unsigned uid2,
       
       /// printDataDirective - This method prints the asm directive for the
       /// specified type.
      -void AsmPrinter::printDataDirective(const Type *type) {
      +void AsmPrinter::printDataDirective(const Type *type, unsigned AddrSpace) {
         const TargetData *TD = TM.getTargetData();
         switch (type->getTypeID()) {
         case Type::IntegerTyID: {
           unsigned BitWidth = cast(type)->getBitWidth();
           if (BitWidth <= 8)
      -      O << TAI->getData8bitsDirective();
      +      O << TAI->getData8bitsDirective(AddrSpace);
           else if (BitWidth <= 16)
      -      O << TAI->getData16bitsDirective();
      +      O << TAI->getData16bitsDirective(AddrSpace);
           else if (BitWidth <= 32)
      -      O << TAI->getData32bitsDirective();
      +      O << TAI->getData32bitsDirective(AddrSpace);
           else if (BitWidth <= 64) {
      -      assert(TAI->getData64bitsDirective() &&
      +      assert(TAI->getData64bitsDirective(AddrSpace) &&
                    "Target cannot handle 64-bit constant exprs!");
      -      O << TAI->getData64bitsDirective();
      +      O << TAI->getData64bitsDirective(AddrSpace);
           } else {
             assert(0 && "Target cannot handle given data directive width!");
           }
      @@ -1513,15 +1516,15 @@ void AsmPrinter::printDataDirective(const Type *type) {
         }
         case Type::PointerTyID:
           if (TD->getPointerSize() == 8) {
      -      assert(TAI->getData64bitsDirective() &&
      +      assert(TAI->getData64bitsDirective(AddrSpace) &&
                    "Target cannot handle 64-bit pointer exprs!");
      -      O << TAI->getData64bitsDirective();
      +      O << TAI->getData64bitsDirective(AddrSpace);
           } else if (TD->getPointerSize() == 2) {
      -      O << TAI->getData16bitsDirective();
      +      O << TAI->getData16bitsDirective(AddrSpace);
           } else if (TD->getPointerSize() == 1) {
      -      O << TAI->getData8bitsDirective();
      +      O << TAI->getData8bitsDirective(AddrSpace);
           } else {
      -      O << TAI->getData32bitsDirective();
      +      O << TAI->getData32bitsDirective(AddrSpace);
           }
           break;
         case Type::FloatTyID: case Type::DoubleTyID:
      diff --git a/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp b/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp
      index dc91128d5a38..63ad6e4f4488 100644
      --- a/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp
      +++ b/llvm/lib/Target/PIC16/PIC16AsmPrinter.cpp
      @@ -242,48 +242,11 @@ void PIC16AsmPrinter::EmitInitData (Module &M) {
               continue;
       
             O << name;
      -      EmitGlobalConstant(C);
      +      EmitGlobalConstant(C, AddrSpace);
           }
         }
       }
       
      -void PIC16AsmPrinter::EmitConstantValueOnly(const Constant* CV) {
      -  if (const ConstantInt *CI = dyn_cast(CV)) {
      -    unsigned BitWidth = CI->getBitWidth();
      -    int Val = CI->getZExtValue();
      -    if (BitWidth == 8) {
      -      // Expecting db directive here. In case of romdata we need to pad the
      -      // word with zeros.
      -      if (IsRomData)
      -        O << 0 <<", ";
      -      O << Val; 
      -    }
      -    else if (BitWidth == 16) {
      -      unsigned Element1, Element2;
      -      Element1 = 0x00ff & Val;
      -      Element2 = 0x00ff & (Val >> 8);
      -      if (IsRomData)
      -        O << 0 <<", "<> 8);
      -      Element3 = 0x00ff & (Val >> 16);
      -      Element4 = 0x00ff & (Val >> 24);
      -      if (IsRomData)
      -        O << 0 <<", "<< Element1 <<", "<< 0 <<", "<< Element2 <<", "<< 0 
      -          <<", "<< Element3 <<", "<< 0 <<", "<< Element4;
      -      else 
      -        O << Element1 <<", "<< Element2 <<", "<< Element3 <<", "<< Element4;    
      -    }
      -    return;
      -  }
      -  AsmPrinter::EmitConstantValueOnly(CV);
      -}
      -
       void PIC16AsmPrinter::EmitRomData (Module &M)
       {
         SwitchToSection(TAI->getReadOnlySection());
      @@ -308,7 +271,7 @@ void PIC16AsmPrinter::EmitRomData (Module &M)
               continue;
       
             O << name;
      -      EmitGlobalConstant(C);
      +      EmitGlobalConstant(C, AddrSpace);
             O << "\n";
           }
         }
      diff --git a/llvm/lib/Target/PIC16/PIC16AsmPrinter.h b/llvm/lib/Target/PIC16/PIC16AsmPrinter.h
      index 876e4be7439a..ce79afd6079e 100644
      --- a/llvm/lib/Target/PIC16/PIC16AsmPrinter.h
      +++ b/llvm/lib/Target/PIC16/PIC16AsmPrinter.h
      @@ -43,7 +43,6 @@ namespace llvm {
           void EmitInitData (Module &M);
           void EmitUnInitData (Module &M);
           void EmitRomData (Module &M);
      -    virtual void EmitConstantValueOnly(const Constant *CV);
           void emitFunctionData(MachineFunction &MF);
           void emitFunctionTempData(MachineFunction &MF, unsigned &FrameSize);
       
      diff --git a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
      index 8e2392e6f71a..b86576be896e 100644
      --- a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
      +++ b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp
      @@ -22,8 +22,11 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
         : TargetAsmInfo(TM) {
         CommentString = ";";
         Data8bitsDirective = " db ";
      -  Data16bitsDirective = " db ";
      -  Data32bitsDirective = " db ";
      +  Data16bitsDirective = " dw ";
      +  Data32bitsDirective = " dl ";
      +  RomData8bitsDirective = " dw ";
      +  RomData16bitsDirective = " rom_di ";
      +  RomData8bitsDirective = " rom_dl ";
         ZeroDirective = NULL;
         AsciiDirective = " dt ";
         AscizDirective = NULL;
      @@ -33,3 +36,28 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM)
         DataSection = getNamedSection("idata.# IDATA", SectionFlags::Writeable);
         SwitchToSectionDirective = "";
       }
      +
      +const char *PIC16TargetAsmInfo::getData8bitsDirective(unsigned AddrSpace)
      +                                                       const {
      +      if (AddrSpace == PIC16ISD::ROM_SPACE)
      +        return RomData8bitsDirective;
      +      else 
      +        return Data8bitsDirective; 
      +  }
      +
      +const char *PIC16TargetAsmInfo::getData16bitsDirective(unsigned AddrSpace)
      +                                                       const {
      +      if (AddrSpace == PIC16ISD::ROM_SPACE)
      +        return RomData16bitsDirective;
      +      else
      +        return Data16bitsDirective;
      +  }
      +
      +const char *PIC16TargetAsmInfo::getData32bitsDirective(unsigned AddrSpace)
      +                                                       const {
      +      if (AddrSpace == PIC16ISD::ROM_SPACE)
      +        return RomData32bitsDirective;
      +      else
      +        return Data32bitsDirective;
      +  }
      +
      diff --git a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h
      index 88de79f357eb..b75699ba8c4b 100644
      --- a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h
      +++ b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h
      @@ -23,7 +23,13 @@ namespace llvm {
       
         struct PIC16TargetAsmInfo : public TargetAsmInfo {
           PIC16TargetAsmInfo(const PIC16TargetMachine &TM);
      +    const char *RomData8bitsDirective;
      +    const char *RomData16bitsDirective;
      +    const char *RomData32bitsDirective;
           public :
      +    virtual const char *getData8bitsDirective(unsigned AddrSpace = 0) const;
      +    virtual const char *getData16bitsDirective(unsigned AddrSpace = 0) const;
      +    virtual const char *getData32bitsDirective(unsigned AddrSpace = 0) const;
         };
       
       } // namespace llvm
      -- 
      GitLab
      
      
      From 6d6d01f25465ac399acc32117b8f9f3bebfcf2e1 Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Fri, 30 Jan 2009 04:43:19 +0000
      Subject: [PATCH 486/682] ccc: Forward -fobjc-nonfragile-abi to clang.
      
      llvm-svn: 63378
      ---
       clang/tools/ccc/ccclib/Arguments.py | 1 +
       clang/tools/ccc/ccclib/Tools.py     | 1 +
       2 files changed, 2 insertions(+)
      
      diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py
      index 1ff76eccd9f3..0f258cfda47f 100644
      --- a/clang/tools/ccc/ccclib/Arguments.py
      +++ b/clang/tools/ccc/ccclib/Arguments.py
      @@ -803,6 +803,7 @@ class OptionParser:
               self.f_noWorkingDirectoryOption = self.addOption(FlagOption('-fno-working-directory', self.fGroup))
               self.f_objcGcOnlyOption = self.addOption(FlagOption('-fobjc-gc-only', self.fGroup))
               self.f_objcGcOption = self.addOption(FlagOption('-fobjc-gc', self.fGroup))
      +        self.f_objcNonfragileAbiOption = self.addOption(FlagOption('-fobjc-nonfragile-abi', self.fGroup))
               self.f_objcOption = self.addOption(FlagOption('-fobjc', self.fGroup))
               self.f_omitFramePointerOption = self.addOption(FlagOption('-fomit-frame-pointer', self.fGroup))
               self.f_openmpOption = self.addOption(FlagOption('-fopenmp', self.fGroup))
      diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py
      index ed138141b26a..6156684ca555 100644
      --- a/clang/tools/ccc/ccclib/Tools.py
      +++ b/clang/tools/ccc/ccclib/Tools.py
      @@ -315,6 +315,7 @@ class Clang_CompileTool(Tool):
       
               arglist.addAllArgs(cmd_args, arglist.parser.f_objcGcOption)
               arglist.addAllArgs(cmd_args, arglist.parser.f_objcGcOnlyOption)
      +        arglist.addAllArgs(cmd_args, arglist.parser.f_objcNonfragileAbiOption)
               arglist.addAllArgs(cmd_args, arglist.parser.f_nextRuntimeOption)
               arglist.addAllArgs(cmd_args, arglist.parser.f_gnuRuntimeOption)
               arglist.addLastArg(cmd_args, arglist.parser.f_exceptionsOption)
      -- 
      GitLab
      
      
      From 02714ed353e7c83022c1800c4a616a6671b39e43 Mon Sep 17 00:00:00 2001
      From: Anders Carlsson 
      Date: Fri, 30 Jan 2009 06:13:25 +0000
      Subject: [PATCH 487/682] Implement constant generation of
       ImplicitValueInitExprs.
      
      llvm-svn: 63379
      ---
       clang/lib/CodeGen/CGExprConstant.cpp | 7 ++++++-
       1 file changed, 6 insertions(+), 1 deletion(-)
      
      diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
      index 3aedf9bc7f78..604090e2b35b 100644
      --- a/clang/lib/CodeGen/CGExprConstant.cpp
      +++ b/clang/lib/CodeGen/CGExprConstant.cpp
      @@ -297,7 +297,12 @@ public:
       
           return llvm::ConstantVector::get(VType, Elts);    
         }
      -                                          
      +  
      +  llvm::Constant *VisitImplicitValueInitExpr(ImplicitValueInitExpr* E) {
      +    const llvm::Type* RetTy = CGM.getTypes().ConvertType(E->getType());
      +    return llvm::Constant::getNullValue(RetTy);
      +  }
      +    
         llvm::Constant *VisitInitListExpr(InitListExpr *ILE) {
           if (ILE->getType()->isScalarType()) {
             // We have a scalar in braces. Just use the first element.
      -- 
      GitLab
      
      
      From cbb20a6ee1af9577879abce63e3e8ca806dd6328 Mon Sep 17 00:00:00 2001
      From: Mon P Wang 
      Date: Fri, 30 Jan 2009 07:07:40 +0000
      Subject: [PATCH 488/682] When PerformBuildVectorCombine, avoid creating a
       X86ISD::VZEXT_LOAD of an illegal type.
      
      llvm-svn: 63380
      ---
       llvm/lib/Target/X86/X86ISelLowering.cpp | 6 +++++-
       1 file changed, 5 insertions(+), 1 deletion(-)
      
      diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
      index bf7c704b9ba0..e17ae99b5c94 100644
      --- a/llvm/lib/Target/X86/X86ISelLowering.cpp
      +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
      @@ -7601,7 +7601,11 @@ static SDValue PerformBuildVectorCombine(SDNode *N, SelectionDAG &DAG,
         // Load must not be an extload.
         if (LD->getExtensionType() != ISD::NON_EXTLOAD)
           return SDValue();
      -  
      +
      +  // Load type should legal type so we don't have to legalize it.
      +  if (!TLI.isTypeLegal(VT))
      +    return SDValue();
      +
         SDVTList Tys = DAG.getVTList(VT, MVT::Other);
         SDValue Ops[] = { LD->getChain(), LD->getBasePtr() };
         SDValue ResNode = DAG.getNode(X86ISD::VZEXT_LOAD, Tys, Ops, 2);
      -- 
      GitLab
      
      
      From 082174cb784e116d13a0601598c124974f22a25a Mon Sep 17 00:00:00 2001
      From: Sanjiv Gupta 
      Date: Fri, 30 Jan 2009 07:55:25 +0000
      Subject: [PATCH 489/682] Use sublw for comparison with literals instead of
       subwf.
      
      llvm-svn: 63382
      ---
       llvm/lib/Target/PIC16/PIC16ISelLowering.cpp | 20 +++++++++++---------
       1 file changed, 11 insertions(+), 9 deletions(-)
      
      diff --git a/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp b/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp
      index ae031bc64693..83d7a3e56498 100644
      --- a/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp
      +++ b/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp
      @@ -1288,23 +1288,25 @@ SDValue PIC16TargetLowering::getPIC16Cmp(SDValue LHS, SDValue RHS,
         }
       
         PIC16CC = DAG.getConstant(CondCode, MVT::i8);
      -  SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
       
         // These are signed comparisons. 
         SDValue Mask = DAG.getConstant(128, MVT::i8);
         if (isSignedComparison(CondCode)) {
      -    LHS = DAG.getNode (ISD::XOR, MVT::i8, LHS, Mask); 
      +    LHS = DAG.getNode (ISD::XOR, MVT::i8, LHS, Mask);
           RHS = DAG.getNode (ISD::XOR, MVT::i8, RHS, Mask); 
         }
      +
      +  SDVTList VTs = DAG.getVTList (MVT::i8, MVT::Flag);
         // We can use a subtract operation to set the condition codes. But
         // we need to put one operand in memory if required.
      -  // Nothing to do if the first operand is already a direct load and it has
      -  // only one use.
      -  if (! (isDirectLoad(LHS) && LHS.hasOneUse()))
      -    // Put first operand on stack.
      -    LHS = ConvertToMemOperand (LHS, DAG);
      -
      -  SDVTList Tys = DAG.getVTList(MVT::i8, MVT::Flag);
      +  // Nothing to do if the first operand is already a valid type (direct load 
      +  // for subwf and literal for sublw) and it is used by this operation only. 
      +  if ((LHS.getOpcode() == ISD::Constant || isDirectLoad(LHS)) 
      +      && LHS.hasOneUse())
      +    return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
      +
      +  // else convert the first operand to mem.
      +  LHS = ConvertToMemOperand (LHS, DAG);
         return DAG.getNode(PIC16ISD::SUBCC, VTs, LHS, RHS);
       }
       
      -- 
      GitLab
      
      
      From f5222fa0ad3200b9771fa088108d7f970219cc3c Mon Sep 17 00:00:00 2001
      From: Daniel Dunbar 
      Date: Fri, 30 Jan 2009 08:09:32 +0000
      Subject: [PATCH 490/682] x86_64 ABI: Implement classification for arrays.  -
       This brings us down to an 8% failure rate on the first 500 return    types
       tests (from 12%).
      
      llvm-svn: 63383
      ---
       clang/lib/CodeGen/CGCall.cpp | 156 +++++++++++++++++++++++------------
       1 file changed, 101 insertions(+), 55 deletions(-)
      
      diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
      index 65d70385f089..b8f0ae868f06 100644
      --- a/clang/lib/CodeGen/CGCall.cpp
      +++ b/clang/lib/CodeGen/CGCall.cpp
      @@ -406,6 +406,16 @@ class X86_64ABIInfo : public ABIInfo {
           Memory
         };
       
      +  /// merge - Implement the X86_64 ABI merging algorithm.
      +  ///
      +  /// \param Offset - The offset of the current field.
      +  /// \param FieldLo - The low classification of the current field.
      +  /// \param FieldHi - The high classification of the current field.
      +  /// \param Lo [in] [out] - The accumulated low classification.
      +  /// \param Lo [in] [out] - The accumulated high classification.  
      +  void merge(uint64_t Offset, Class FieldLo, Class FieldHi,
      +             Class &Lo, Class &Hi) const;
      +
         /// classify - Determine the x86_64 register classes in which the
         /// given type T should be passed.
         ///
      @@ -435,6 +445,58 @@ public:
       };
       }
       
      +void X86_64ABIInfo::merge(uint64_t Offset, Class FieldLo, Class FieldHi,
      +                          Class &Lo, Class &Hi) const {
      +  // Determine which half of the structure we are classifying.
      +  //
      +  // AMD64-ABI 3.2.3p2: Rule 3. f the size of the aggregate
      +  // exceeds a single eightbyte, each is classified
      +  // separately. Each eightbyte gets initialized to class
      +  // NO_CLASS.
      +  Class &Target = Offset < 64 ? Lo : Hi;
      +
      +  // Merge the lo field classifcation.
      +  //
      +  // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is
      +  // classified recursively so that always two fields are
      +  // considered. The resulting class is calculated according to
      +  // the classes of the fields in the eightbyte:
      +  //
      +  // (a) If both classes are equal, this is the resulting class.
      +  //
      +  // (b) If one of the classes is NO_CLASS, the resulting class is
      +  // the other class.
      +  //
      +  // (c) If one of the classes is MEMORY, the result is the MEMORY
      +  // class.
      +  //
      +  // (d) If one of the classes is INTEGER, the result is the
      +  // INTEGER.
      +  //
      +  // (e) If one of the classes is X87, X87UP, COMPLEX_X87 class,
      +  // MEMORY is used as class.
      +  //
      +  // (f) Otherwise class SSE is used.
      +  if (Target == FieldLo || FieldLo == NoClass) ;
      +  else if (FieldLo == Memory)
      +    Lo = Memory;
      +  else if (Target == NoClass)
      +    Target = FieldLo;
      +  else if (Target == Integer || FieldLo == Integer) 
      +    Target = Integer;
      +  else if (FieldLo == X87 || FieldLo == X87Up || FieldLo == ComplexX87)
      +    Lo = Memory;
      +  else
      +    Target = SSE;
      +
      +  // It isn't clear from the ABI spec what the role of the high
      +  // classification is here, but since this should only happen
      +  // when we have a struct with a two eightbyte member, we can
      +  // just push the field high class into the overall high class.
      +  if (FieldHi != NoClass)
      +    Hi = FieldHi;
      +}
      +
       void X86_64ABIInfo::classify(QualType Ty,
                                    ASTContext &Context,
                                    uint64_t OffsetBase,
      @@ -494,6 +556,39 @@ void X86_64ABIInfo::classify(QualType Ty,
           uint64_t EB_Imag = (OffsetBase + Context.getTypeSize(ET)) >> 3;
           if (Hi == NoClass && EB_Real != EB_Imag)
             Hi = Lo;
      +  } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) {
      +    // Arrays are treated like structures.
      +
      +    uint64_t Size = Context.getTypeSize(Ty);
      +    
      +    // AMD64-ABI 3.2.3p2: Rule 1. If the size of an object is larger
      +    // than two eightbytes, ..., it has class MEMORY.
      +    if (Size > 128)
      +      return;
      +    
      +    // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
      +    // fields, it has class MEMORY.
      +    //
      +    // Only need to check alignment of array base.
      +    if (OffsetBase % Context.getTypeAlign(AT->getElementType())) {
      +      Lo = Memory;
      +      return;
      +    }
      +
      +    // Otherwise implement simplified merge. We could be smarter about
      +    // this, but it isn't worth it and would be harder to verify.
      +    Lo = NoClass;
      +    uint64_t EltSize = Context.getTypeSize(AT->getElementType());
      +    uint64_t ArraySize = AT->getSize().getZExtValue();
      +    for (uint64_t i=0, Offset=OffsetBase; igetElementType(), Context, Offset, FieldLo, FieldHi);
      +    
      +      merge(Offset, FieldLo, FieldHi, Lo, Hi);
      +      // Memory is never over-ridden, exit early if we see it.
      +      if (Lo == Memory)
      +        return;
      +    }
         } else if (const RecordType *RT = Ty->getAsRecordType()) {
           uint64_t Size = Context.getTypeSize(Ty);
           
      @@ -515,72 +610,23 @@ void X86_64ABIInfo::classify(QualType Ty,
           unsigned idx = 0;
           for (RecordDecl::field_iterator i = RD->field_begin(), 
                  e = RD->field_end(); i != e; ++i, ++idx) {
      -      unsigned Offset = OffsetBase + Layout.getFieldOffset(idx);
      +      uint64_t Offset = OffsetBase + Layout.getFieldOffset(idx);
       
      -      //  AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
      -      //  fields, it has class MEMORY.
      +      // AMD64-ABI 3.2.3p2: Rule 1. If ..., or it contains unaligned
      +      // fields, it has class MEMORY.
             if (Offset % Context.getTypeAlign(i->getType())) {
               Lo = Memory;
               return;
             }
       
      -      // Determine which half of the structure we are classifying.
      -      //
      -      // AMD64-ABI 3.2.3p2: Rule 3. f the size of the aggregate
      -      // exceeds a single eightbyte, each is classified
      -      // separately. Each eightbyte gets initialized to class
      -      // NO_CLASS.
      -      Class &Target = Offset < 64 ? Lo : Hi;
      -
             // Classify this field.
             Class FieldLo, FieldHi;
             classify(i->getType(), Context, Offset, FieldLo, FieldHi);
             
      -      // Merge the lo field classifcation.
      -      //
      -      // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is
      -      // classified recursively so that always two fields are
      -      // considered. The resulting class is calculated according to
      -      // the classes of the fields in the eightbyte:
      -      //
      -      // (a) If both classes are equal, this is the resulting class.
      -      //
      -      // (b) If one of the classes is NO_CLASS, the resulting class is
      -      // the other class.
      -      //
      -      // (c) If one of the classes is MEMORY, the result is the MEMORY
      -      // class.
      -      //
      -      // (d) If one of the classes is INTEGER, the result is the
      -      // INTEGER.
      -      //
      -      // (e) If one of the classes is X87, X87UP, COMPLEX_X87 class,
      -      // MEMORY is used as class.
      -      //
      -      // (f) Otherwise class SSE is used.
      -      if (Target == FieldLo || FieldLo == NoClass) ;
      -      else if (FieldLo == Memory) {
      -        // Memory is never over-ridden, just bail.
      -        Lo = Memory;
      -        return;
      -      } 
      -      else if (Target == NoClass)
      -        Target = FieldLo;
      -      else if (Target == Integer || FieldLo == Integer) 
      -        Target = Integer;
      -      else if (FieldLo == X87 || FieldLo == X87Up || FieldLo == ComplexX87) {
      -        // As before, just bail once we generate a memory class.
      -        Lo = Memory;
      +      merge(Offset, FieldLo, FieldHi, Lo, Hi);
      +      // Memory is never over-ridden, exit early if we see it.
      +      if (Lo == Memory)
               return;
      -      } else
      -        Target = SSE;
      -
      -      // It isn't clear from the ABI spec what the role of the high
      -      // classification is here, but since this should only happen
      -      // when we have a struct with a two eightbyte member, we can
      -      // just push the field high class into the overall high class.
      -      if (FieldHi != NoClass)
      -        Hi = FieldHi;
           }
       
           // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done:
      -- 
      GitLab
      
      
      From ecbe4a0860319ba3373962b13c9a775f6eb94c84 Mon Sep 17 00:00:00 2001
      From: Mike Stump 
      Date: Fri, 30 Jan 2009 08:19:46 +0000
      Subject: [PATCH 491/682] Add opposite_of and inverse_opt to support -fno-
       style options.  This is necessary for eventual gcc commmand line
       compatibility.
      
      llvm-svn: 63384
      ---
       llvm/include/llvm/Support/CommandLine.h | 33 +++++++++++++++++++++++++
       llvm/lib/Support/CommandLine.cpp        | 22 ++++++++++++++++-
       2 files changed, 54 insertions(+), 1 deletion(-)
      
      diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h
      index e7f5a02b77d7..9b218dab031c 100644
      --- a/llvm/include/llvm/Support/CommandLine.h
      +++ b/llvm/include/llvm/Support/CommandLine.h
      @@ -302,6 +302,12 @@ struct LocationClass {
       template
       LocationClass location(Ty &L) { return LocationClass(L); }
       
      +// opposite_of - Allow the user to specify which other option this
      +// option is the opposite of.
      +//
      +template
      +LocationClass opposite_of(Ty &O) { return location(O.getValue()); }
      +
       
       //===----------------------------------------------------------------------===//
       // Enum valued command line option
      @@ -576,6 +582,30 @@ public:
       
       EXTERN_TEMPLATE_INSTANTIATION(class basic_parser);
       
      +//--------------------------------------------------
      +// parser
      +class boolInverse { };
      +template<>
      +class parser : public basic_parser {
      +public:
      +  typedef bool parser_data_type;
      +  // parse - Return true on error.
      +  bool parse(Option &O, const char *ArgName, const std::string &Arg,
      +             bool &Val);
      +
      +  enum ValueExpected getValueExpectedFlagDefault() const {
      +    return ValueOptional;
      +  }
      +
      +  // getValueName - Do not print = at all.
      +  virtual const char *getValueName() const { return 0; }
      +
      +  // An out-of-line virtual method to provide a 'home' for this class.
      +  virtual void anchor();
      +};
      +
      +EXTERN_TEMPLATE_INSTANTIATION(class basic_parser);
      +
       //--------------------------------------------------
       // parser
       //
      @@ -917,6 +947,9 @@ EXTERN_TEMPLATE_INSTANTIATION(class opt);
       EXTERN_TEMPLATE_INSTANTIATION(class opt);
       EXTERN_TEMPLATE_INSTANTIATION(class opt);
       
      +class boolInverse;
      +typedef opt > inverse_opt;
      +
       //===----------------------------------------------------------------------===//
       // list_storage class
       
      diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp
      index 2414734869db..e06f324c8715 100644
      --- a/llvm/lib/Support/CommandLine.cpp
      +++ b/llvm/lib/Support/CommandLine.cpp
      @@ -40,6 +40,7 @@ using namespace cl;
       //
       TEMPLATE_INSTANTIATION(class basic_parser);
       TEMPLATE_INSTANTIATION(class basic_parser);
      +TEMPLATE_INSTANTIATION(class basic_parser);
       TEMPLATE_INSTANTIATION(class basic_parser);
       TEMPLATE_INSTANTIATION(class basic_parser);
       TEMPLATE_INSTANTIATION(class basic_parser);
      @@ -55,6 +56,7 @@ void Option::anchor() {}
       void basic_parser_impl::anchor() {}
       void parser::anchor() {}
       void parser::anchor() {}
      +void parser::anchor() {}
       void parser::anchor() {}
       void parser::anchor() {}
       void parser::anchor() {}
      @@ -882,7 +884,8 @@ bool parser::parse(Option &O, const char *ArgName,
         if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
             Arg == "1") {
           Value = BOU_TRUE;
      -  } else if (Arg == "false" || Arg == "FALSE" || Arg == "False" || Arg == "0") {
      +  } else if (Arg == "false" || Arg == "FALSE"
      +             || Arg == "False" || Arg == "0") {
           Value = BOU_FALSE;
         } else {
           return O.error(": '" + Arg +
      @@ -891,6 +894,23 @@ bool parser::parse(Option &O, const char *ArgName,
         return false;
       }
       
      +// parser implementation
      +//
      +bool parser::parse(Option &O, const char *ArgName,
      +                                const std::string &Arg, bool &Value) {
      +  if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
      +      Arg == "1") {
      +    Value = false;
      +  } else if (Arg == "false" || Arg == "FALSE"
      +             || Arg == "False" || Arg == "0") {
      +    Value = true;
      +  } else {
      +    return O.error(": '" + Arg +
      +                   "' is invalid value for boolean argument! Try 0 or 1");
      +  }
      +  return false;
      +}
      +
       // parser implementation
       //
       bool parser::parse(Option &O, const char *ArgName,
      -- 
      GitLab
      
      
      From c99d003b25bbdf13b0513a8d91eec5be0e9b5860 Mon Sep 17 00:00:00 2001
      From: Mike Stump 
      Date: Fri, 30 Jan 2009 08:22:07 +0000
      Subject: [PATCH 492/682] Add -fno-blocks support.  This fixes
       block-no-block-def.c.
      
      llvm-svn: 63385
      ---
       clang/Driver/clang.cpp              | 7 +++++--
       clang/tools/ccc/ccclib/Arguments.py | 5 +++++
       clang/tools/ccc/ccclib/Tools.py     | 5 +++--
       3 files changed, 13 insertions(+), 4 deletions(-)
      
      diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp
      index 4e79733043f0..b16a83657186 100644
      --- a/clang/Driver/clang.cpp
      +++ b/clang/Driver/clang.cpp
      @@ -486,7 +486,10 @@ LaxVectorConversions("flax-vector-conversions",
                                           " with a different number of elements or "
                                           "different element types"));
       static llvm::cl::opt
      -EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature"));
      +EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature"), llvm::cl::ValueDisallowed);
      +
      +static llvm::cl::inverse_opt
      +DisableBlocks("fno-blocks", llvm::cl::opposite_of(EnableBlocks), llvm::cl::ValueDisallowed);
       
       static llvm::cl::opt
       ObjCNonFragileABI("fobjc-nonfragile-abi", llvm::cl::desc("enable objective-c's nonfragile abi"));
      @@ -614,7 +617,7 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK,
         Options.WritableStrings = WritableStrings;
         Options.LaxVectorConversions = LaxVectorConversions;
         Options.Exceptions = Exceptions;
      -  if (EnableBlocks.getPosition())
      +  if (EnableBlocks.getPosition() || DisableBlocks.getPosition())
           Options.Blocks = EnableBlocks;
       
         // Override the default runtime if the user requested it.
      diff --git a/clang/tools/ccc/ccclib/Arguments.py b/clang/tools/ccc/ccclib/Arguments.py
      index 0f258cfda47f..dcf1e70188f5 100644
      --- a/clang/tools/ccc/ccclib/Arguments.py
      +++ b/clang/tools/ccc/ccclib/Arguments.py
      @@ -768,6 +768,11 @@ class OptionParser:
               # want to avoid passing them to gcc/cc1 (which will generally
               # not eat them), or should we let the user sort it out.
       
      +        self.fblocksGroup = OptionGroup('-fblocks')
      +        self.f_blocks = self.addOption(FlagOption('-fblocks', self.fblocksGroup))
      +        self.f_noblocks = self.addOption(FlagOption('-fno-blocks', self.fblocksGroup))
      +        # self.fblocksOption = self.addOption(JoinedOption('-fblocks', self.fblocksGroup))
      +        
               self.fGroup = OptionGroup('-f')
               self.fastOption = self.addOption(FlagOption('-fast', self.fGroup))
               self.fastfOption = self.addOption(FlagOption('-fastf', self.fGroup))
      diff --git a/clang/tools/ccc/ccclib/Tools.py b/clang/tools/ccc/ccclib/Tools.py
      index 6156684ca555..a86ab9ba9fcd 100644
      --- a/clang/tools/ccc/ccclib/Tools.py
      +++ b/clang/tools/ccc/ccclib/Tools.py
      @@ -305,8 +305,7 @@ class Clang_CompileTool(Tool):
                       cmd_args.append('-token-cache')
                       cmd_args.append(pthPath)
       
      -        # FIXME: Dehardcode this.
      -        cmd_args.append('-fblocks')
      +        arglist.addAllArgs(cmd_args, arglist.parser.fblocksGroup)
       
               arglist.addAllArgs(cmd_args, arglist.parser.OOption)
               arglist.addAllArgs2(cmd_args, arglist.parser.ClangWGroup, arglist.parser.pedanticGroup)
      @@ -466,6 +465,7 @@ class Darwin_X86_CC1Tool(Tool):
               # ccc treats -fsyntax-only specially.
               arglist.addAllArgs2(cmd_args, arglist.parser.fGroup, 
                                   arglist.parser.syntaxOnlyOption)
      +        arglist.addAllArgs(cmd_args, arglist.parser.fblocksGroup)
       
               arglist.addAllArgs(cmd_args, arglist.parser.undefOption)
               if arglist.getLastArg(arglist.parser.QnOption):
      @@ -538,6 +538,7 @@ class Darwin_X86_CC1Tool(Tool):
               # ccc treats -fsyntax-only specially.
               arglist.addAllArgs2(cmd_args, arglist.parser.fGroup, 
                                   arglist.parser.syntaxOnlyOption)
      +        arglist.addAllArgs(cmd_args, arglist.parser.fblocksGroup)
       
               if (arglist.getLastArg(arglist.parser.gGroup) and
                   not arglist.getLastArg(arglist.parser.g0Option) and
      -- 
      GitLab
      
      
      From 1e36fbb5ed5559665b7bd1ee13d4eba883db6e60 Mon Sep 17 00:00:00 2001
      From: Zhou Sheng 
      Date: Fri, 30 Jan 2009 08:59:51 +0000
      Subject: [PATCH 493/682] This is case is to uncover the bug in
       IntrinsicLowering.cpp, the LowerPartSet(). It didn't handle the situation
       correctly when the low, high argument values are in reverse order (low >
       high) with 'Val' type is i32 (a corner case).
      
      llvm-svn: 63386
      ---
       llvm/test/ExecutionEngine/2009-01-29-PartSet.ll | 17 +++++++++++++++++
       1 file changed, 17 insertions(+)
       create mode 100644 llvm/test/ExecutionEngine/2009-01-29-PartSet.ll
      
      diff --git a/llvm/test/ExecutionEngine/2009-01-29-PartSet.ll b/llvm/test/ExecutionEngine/2009-01-29-PartSet.ll
      new file mode 100644
      index 000000000000..ae766876fc7e
      --- /dev/null
      +++ b/llvm/test/ExecutionEngine/2009-01-29-PartSet.ll
      @@ -0,0 +1,17 @@
      +; RUN: llvm-as %s -o - | lli -force-interpreter | grep FF8F
      +
      +; ModuleID = 'partset.c.bc'
      +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
      +target triple = "x86_64-unknown-linux-gnu"
      +@.str = internal constant [4 x i8] c"%X\0A\00"      ; <[4 x i8]*> [#uses=1]
      +
      +define i32 @main() nounwind  {
      +entry:
      +    %part_set = tail call i32 @llvm.part.set.i32.i8( i32 65535, i8 1, i32 7, i32 4 )        ;  [#uses=1]
      +    %tmp4 = tail call i32 (i8*, ...)* @printf( i8* noalias  getelementptr ([4 x i8]* @.str, i32 0, i64 0), i32 %part_set ) nounwind         ;  [#uses=0]
      +    ret i32 0
      +}
      +
      +declare i32 @llvm.part.set.i32.i8(i32, i8, i32, i32) nounwind readnone
      +
      +declare i32 @printf(i8*, ...) nounwind
      -- 
      GitLab
      
      
      From c10d810303e2ba18d6723f47a31d2da40ae4af25 Mon Sep 17 00:00:00 2001
      From: Sanjiv Gupta 
      Date: Fri, 30 Jan 2009 09:01:44 +0000
      Subject: [PATCH 494/682] Fixed the comment. No functionality change.
      
      llvm-svn: 63387
      ---
       llvm/lib/Target/PIC16/PIC16InstrInfo.td | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/llvm/lib/Target/PIC16/PIC16InstrInfo.td b/llvm/lib/Target/PIC16/PIC16InstrInfo.td
      index 077b50838e8b..31ceba37996c 100644
      --- a/llvm/lib/Target/PIC16/PIC16InstrInfo.td
      +++ b/llvm/lib/Target/PIC16/PIC16InstrInfo.td
      @@ -7,7 +7,7 @@
       //
       //===----------------------------------------------------------------------===//
       //
      -// This file describes the ARM instructions in TableGen format.
      +// This file describes the PIC16 instructions in TableGen format.
       //
       //===----------------------------------------------------------------------===//
       
      -- 
      GitLab
      
      
      From 25b6f8153e341de4948d42b125e438fa79c508e8 Mon Sep 17 00:00:00 2001
      From: Zhou Sheng 
      Date: Fri, 30 Jan 2009 09:02:50 +0000
      Subject: [PATCH 495/682] This is to fix the bug in IntrinsicLowering.cpp, the
       LowerPartSet(). It didn't handle the situation correctly when the low, high
       argument values are in reverse order (low > high) with 'Val' type i32 (a
       corner case).
      
      llvm-svn: 63388
      ---
       llvm/lib/CodeGen/IntrinsicLowering.cpp | 3 ++-
       1 file changed, 2 insertions(+), 1 deletion(-)
      
      diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp
      index 960d660cb946..0ef9706668b8 100644
      --- a/llvm/lib/CodeGen/IntrinsicLowering.cpp
      +++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp
      @@ -533,7 +533,8 @@ static Instruction *LowerPartSet(CallInst *CI) {
             Lo = new ZExtInst(Lo_pn, ValTy, "", entry);
           } else if (ValBits < 32) {
             Lo = new TruncInst(Lo_pn, ValTy, "", entry);
      -    }
      +    } else
      +      Lo = Lo_pn;
           // Determine if the replacement bits are larger than the number of bits we
           // are replacing and deal with it.
           ICmpInst* is_large = 
      -- 
      GitLab
      
      
      From 4b23938fb95c8681c3a2200ebbb405201a1ac73d Mon Sep 17 00:00:00 2001
      From: Zhou Sheng 
      Date: Fri, 30 Jan 2009 09:44:49 +0000
      Subject: [PATCH 496/682] As Duncan suggested, add braces for the one-line
       "else branch". Thanks, Duncan.
      
      llvm-svn: 63389
      ---
       llvm/lib/CodeGen/IntrinsicLowering.cpp | 3 ++-
       1 file changed, 2 insertions(+), 1 deletion(-)
      
      diff --git a/llvm/lib/CodeGen/IntrinsicLowering.cpp b/llvm/lib/CodeGen/IntrinsicLowering.cpp
      index 0ef9706668b8..e893a06699c3 100644
      --- a/llvm/lib/CodeGen/IntrinsicLowering.cpp
      +++ b/llvm/lib/CodeGen/IntrinsicLowering.cpp
      @@ -533,8 +533,9 @@ static Instruction *LowerPartSet(CallInst *CI) {
             Lo = new ZExtInst(Lo_pn, ValTy, "", entry);
           } else if (ValBits < 32) {
             Lo = new TruncInst(Lo_pn, ValTy, "", entry);
      -    } else
      +    } else {
             Lo = Lo_pn;
      +    }
           // Determine if the replacement bits are larger than the number of bits we
           // are replacing and deal with it.
           ICmpInst* is_large = 
      -- 
      GitLab
      
      
      From 92f95eb7396c045acc808bd4bca38c7cd6acaad1 Mon Sep 17 00:00:00 2001
      From: Nuno Lopes 
      Date: Fri, 30 Jan 2009 12:58:18 +0000
      Subject: [PATCH 497/682] enable test as it already works
      
      llvm-svn: 63390
      ---
       clang/test/CodeGen/designated-initializers.c | 5 ++---
       1 file changed, 2 insertions(+), 3 deletions(-)
      
      diff --git a/clang/test/CodeGen/designated-initializers.c b/clang/test/CodeGen/designated-initializers.c
      index 0605b24b1c50..060181849499 100644
      --- a/clang/test/CodeGen/designated-initializers.c
      +++ b/clang/test/CodeGen/designated-initializers.c
      @@ -1,5 +1,5 @@
      -// RUN: clang %s -emit-llvm -o -
      -// XFAIL
      +// RUN: clang %s -emit-llvm -o - | grep "<{ i8\* null, i32 1024 }>"
      +
       struct foo {
           void *a;
           int b;
      @@ -14,4 +14,3 @@ int main(int argc, char **argv)
               .b = 1024,
           };
       }
      -
      -- 
      GitLab
      
      
      From c3a558fd45c4f114f609e3305bda9f50f7d56e9d Mon Sep 17 00:00:00 2001
      From: Nuno Lopes 
      Date: Fri, 30 Jan 2009 13:01:29 +0000
      Subject: [PATCH 498/682] enable test as it works
      
      llvm-svn: 63391
      ---
       clang/test/Analysis/uninit-vals-ps-region.c | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/clang/test/Analysis/uninit-vals-ps-region.c b/clang/test/Analysis/uninit-vals-ps-region.c
      index 830e32ad8fa3..73c23590e3ac 100644
      --- a/clang/test/Analysis/uninit-vals-ps-region.c
      +++ b/clang/test/Analysis/uninit-vals-ps-region.c
      @@ -1,4 +1,4 @@
      -// DISABLE: clang -analyze -checker-simple -analyzer-store-region -verify %s
      +// RUN: clang -analyze -checker-simple -analyzer-store-region -verify %s
       
       struct s {
         int data;
      -- 
      GitLab
      
      
      From 8247c9a38f4f2b2942c0f1eb151437382764f0c4 Mon Sep 17 00:00:00 2001
      From: Nuno Lopes 
      Date: Fri, 30 Jan 2009 14:03:37 +0000
      Subject: [PATCH 499/682] fix RUN line
      
      llvm-svn: 63392
      ---
       clang/test/Analysis/rdar-6541136.c | 2 +-
       1 file changed, 1 insertion(+), 1 deletion(-)
      
      diff --git a/clang/test/Analysis/rdar-6541136.c b/clang/test/Analysis/rdar-6541136.c
      index 919a21dc21c1..524f154adc01 100644
      --- a/clang/test/Analysis/rdar-6541136.c
      +++ b/clang/test/Analysis/rdar-6541136.c
      @@ -1,4 +1,4 @@
      -// clang -verify -analyze -checker-cfref -analyzer-store-basic %s
      +// RUN: clang -verify -analyze -checker-cfref -analyzer-store-basic %s
       
       struct tea_cheese { unsigned magic; };
       typedef struct tea_cheese kernel_tea_cheese_t;
      -- 
      GitLab
      
      
      From 3b6a4bd891c6aea7da24322d640f237fb7a48918 Mon Sep 17 00:00:00 2001
      From: Steve Naroff 
      Date: Fri, 30 Jan 2009 14:23:32 +0000
      Subject: [PATCH 500/682] Simplify/cleanup r63219 (based on Chris review).
      
      llvm-svn: 63393
      ---
       clang/lib/Parse/ParseDecl.cpp | 14 +-------------
       1 file changed, 1 insertion(+), 13 deletions(-)
      
      diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
      index 7b6d8f818522..cc1e9970e9d1 100644
      --- a/clang/lib/Parse/ParseDecl.cpp
      +++ b/clang/lib/Parse/ParseDecl.cpp
      @@ -1993,25 +1993,13 @@ void Parser::ParseFunctionDeclarator(SourceLocation LParenLoc, Declarator &D,
         // Alternatively, this parameter list may be an identifier list form for a
         // K&R-style function:  void foo(a,b,c)
         if (!getLang().CPlusPlus && Tok.is(tok::identifier)) {
      -
      -    TypeTy *TypeRep = Actions.getTypeName(*Tok.getIdentifierInfo(), CurScope);
      -    if (TypeRep) {
      -      // This is a typename. Replace the current token in-place with an
      -      // annotation type token.
      -      Tok.setKind(tok::annot_typename);
      -      Tok.setAnnotationValue(TypeRep);
      -      Tok.setAnnotationEndLoc(Tok.getLocation());
      -      // In case the tokens were cached, have Preprocessor replace
      -      // them with the annotation token.
      -      PP.AnnotateCachedTokens(Tok);
      -    } else {
      +    if (!TryAnnotateTypeOrScopeToken()) {
             // K&R identifier lists can't have typedefs as identifiers, per
             // C99 6.7.5.3p11.
             if (RequiresArg) {
               Diag(Tok, diag::err_argument_required_after_attribute);
               delete AttrList;
             }
      -      
             // Identifier list.  Note that '(' identifier-list ')' is only allowed for
             // normal declarators, not for abstract-declarators.
             return ParseFunctionDeclaratorIdentifierList(LParenLoc, D);
      -- 
      GitLab
      
      
      From 221483dd4e6c4241d1ed0f1545bd97285c83a215 Mon Sep 17 00:00:00 2001
      From: Anders Carlsson 
      Date: Fri, 30 Jan 2009 16:41:04 +0000
      Subject: [PATCH 501/682] Make sure to cast the VLA size of array to the type
       of size_t. Fixes PR3442.
      
      llvm-svn: 63394
      ---
       clang/lib/CodeGen/CGExprScalar.cpp |  5 ++++-
       clang/test/CodeGen/sizeof-vla.c    | 13 +++++++++++++
       2 files changed, 17 insertions(+), 1 deletion(-)
       create mode 100644 clang/test/CodeGen/sizeof-vla.c
      
      diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
      index 1d389b6049c2..44eefea71dbd 100644
      --- a/clang/lib/CodeGen/CGExprScalar.cpp
      +++ b/clang/lib/CodeGen/CGExprScalar.cpp
      @@ -684,7 +684,10 @@ ScalarExprEmitter::VisitSizeOfAlignOfExpr(const SizeOfAlignOfExpr *E) {
               // sizeof(type) - make sure to emit the VLA size.
               CGF.EmitVLASize(TypeToSize);
             }
      -      return CGF.GetVLASize(VAT);
      +      
      +      llvm::Value *VLASize = CGF.GetVLASize(VAT);
      +      return Builder.CreateIntCast(VLASize, ConvertType(E->getType()), 
      +                                   false, "conv");
           }
         }
       
      diff --git a/clang/test/CodeGen/sizeof-vla.c b/clang/test/CodeGen/sizeof-vla.c
      new file mode 100644
      index 000000000000..d49bf120975b
      --- /dev/null
      +++ b/clang/test/CodeGen/sizeof-vla.c
      @@ -0,0 +1,13 @@
      +// RUN: clang -triple x86_64-unknown-unknown -emit-llvm -o %t %s
      +
      +// PR3442
      +
      +static void *g(unsigned long len);
      +
      +void
      +f(int n)
      +{
      + unsigned begin_set[n];
      + 
      + g(sizeof(begin_set));
      +}
      -- 
      GitLab
      
      
      From ddb2485eb695802972c52ddf07dbf7ff2276dcd1 Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Fri, 30 Jan 2009 17:31:00 +0000
      Subject: [PATCH 502/682] Switch Type::isAggregateType to use the C++
       definition of "aggregate type" rather than the C definition. We do this
       because both C99 and Clang always use "aggregate type" as "aggregate or union
       type", and the C++ definition includes union types.
      
      llvm-svn: 63395
      ---
       clang/include/clang/AST/Type.h      |  2 +-
       clang/lib/AST/Type.cpp              | 18 +++++++++++++-----
       clang/lib/Analysis/GRExprEngine.cpp |  3 +--
       clang/lib/Sema/SemaDecl.cpp         |  1 +
       clang/lib/Sema/SemaInit.cpp         |  4 ++--
       5 files changed, 18 insertions(+), 10 deletions(-)
      
      diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
      index baa2016f553b..7697f4a01da6 100644
      --- a/clang/include/clang/AST/Type.h
      +++ b/clang/include/clang/AST/Type.h
      @@ -328,7 +328,7 @@ public:
         bool isVoidType() const;         // C99 6.2.5p19
         bool isDerivedType() const;      // C99 6.2.5p20
         bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
      -  bool isAggregateType() const;    // C99 6.2.5p21 (arrays, structures)
      +  bool isAggregateType() const;
         
         // Type Predicates: Check to see if this type is structurally the specified
         // type, ignoring typedefs and qualifiers.
      diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
      index 65fd3b40408c..5d3478b2eaba 100644
      --- a/clang/lib/AST/Type.cpp
      +++ b/clang/lib/AST/Type.cpp
      @@ -661,12 +661,20 @@ bool Type::isScalarType() const {
                isa(CanonicalType);
       }
       
      +/// \brief Determines whether the type is a C++ aggregate type or C
      +/// aggregate or union type.
      +///
      +/// An aggregate type is an array or a class type (struct, union, or
      +/// class) that has no user-declared constructors, no private or
      +/// protected non-static data members, no base classes, and no virtual
      +/// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type
      +/// subsumes the notion of C aggregates (C99 6.2.5p21) because it also
      +/// includes union types.
       bool Type::isAggregateType() const {
      -  if (const TagType *TT = dyn_cast(CanonicalType)) {
      -    if (TT->getDecl()->isStruct())
      -      return true;
      -    return false;
      -  }
      +  if (const CXXRecordType *CXXClassType = dyn_cast(CanonicalType))
      +    return CXXClassType->getDecl()->isAggregate();
      +  if (isa(CanonicalType))
      +    return true;
         if (const ASQualType *ASQT = dyn_cast(CanonicalType))
           return ASQT->getBaseType()->isAggregateType();
         return isa(CanonicalType);
      diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp
      index 6a7f86b14bf0..d9bdd8be0b69 100644
      --- a/clang/lib/Analysis/GRExprEngine.cpp
      +++ b/clang/lib/Analysis/GRExprEngine.cpp
      @@ -493,8 +493,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
             // can be used in a lvalue context.  We need to enhance our support
             // of such temporaries in both the environment and the store, so right
             // now we just do a regular visit.
      -      assert ((Ex->getType()->isAggregateType() || 
      -              Ex->getType()->isUnionType()) &&
      +      assert ((Ex->getType()->isAggregateType()) &&
                     "Other kinds of expressions with non-aggregate/union types do"
                     " not have lvalues.");
             
      diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
      index ad6a7197718d..3395313f84cd 100644
      --- a/clang/lib/Sema/SemaDecl.cpp
      +++ b/clang/lib/Sema/SemaDecl.cpp
      @@ -1083,6 +1083,7 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
           // we have an initializer list and a destination type that is not
           // an aggregate.
           // FIXME: In C++0x, this is yet another form of initialization.
      +    // FIXME: Move this checking into CheckInitList!
           if (const RecordType *ClassRec = DeclType->getAsRecordType()) {
             const CXXRecordDecl *ClassDecl = cast(ClassRec->getDecl());
             if (!ClassDecl->isAggregate())
      diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
      index 77679ee36f98..ed44acff7ee9 100644
      --- a/clang/lib/Sema/SemaInit.cpp
      +++ b/clang/lib/Sema/SemaInit.cpp
      @@ -287,8 +287,8 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
           CheckScalarType(IList, DeclType, Index, StructuredList, StructuredIndex);
         } else if (DeclType->isVectorType()) {
           CheckVectorType(IList, DeclType, Index, StructuredList, StructuredIndex);
      -  } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
      -    if (DeclType->isStructureType() || DeclType->isUnionType()) {
      +  } else if (DeclType->isAggregateType()) {
      +    if (DeclType->isRecordType()) {
             RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
             CheckStructUnionTypes(IList, DeclType, RD->field_begin(), 
                                   SubobjectIsDesignatorContext, Index,
      -- 
      GitLab
      
      
      From 1958677ccfa1dadc23490df2334cfb3db2ca53f2 Mon Sep 17 00:00:00 2001
      From: Chris Lattner 
      Date: Fri, 30 Jan 2009 17:41:53 +0000
      Subject: [PATCH 503/682] " Attached is a patch for TextDiagnosticPrinter that
       adds an optional parameter that allows users to omit the printing of the
       source location on a diagnostic. So basically it would omit the "abc.c:5:1: "
       at the beginning of the line."
      
      Patch by Alexei Svitkine!
      
      llvm-svn: 63396
      ---
       clang/include/clang/Driver/TextDiagnosticPrinter.h |  6 ++++--
       clang/lib/Driver/TextDiagnosticPrinter.cpp         | 10 ++++++----
       2 files changed, 10 insertions(+), 6 deletions(-)
      
      diff --git a/clang/include/clang/Driver/TextDiagnosticPrinter.h b/clang/include/clang/Driver/TextDiagnosticPrinter.h
      index b49094dcb1e9..972fe6d8bc26 100644
      --- a/clang/include/clang/Driver/TextDiagnosticPrinter.h
      +++ b/clang/include/clang/Driver/TextDiagnosticPrinter.h
      @@ -31,10 +31,12 @@ class TextDiagnosticPrinter : public DiagnosticClient {
         llvm::raw_ostream &OS;
         bool ShowColumn;
         bool CaretDiagnostics;
      +  bool ShowLocation;
       public:
         TextDiagnosticPrinter(llvm::raw_ostream &os, bool showColumn = true,
      -                        bool caretDiagnistics = true)
      -    : OS(os), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics) {}
      +                        bool caretDiagnistics = true, bool showLocation = true)
      +    : OS(os), ShowColumn(showColumn), CaretDiagnostics(caretDiagnistics),
      +      ShowLocation(showLocation) {}
       
         void PrintIncludeStack(SourceLocation Loc, const SourceManager &SM);
       
      diff --git a/clang/lib/Driver/TextDiagnosticPrinter.cpp b/clang/lib/Driver/TextDiagnosticPrinter.cpp
      index 36e2d28d2e33..27353b83443e 100644
      --- a/clang/lib/Driver/TextDiagnosticPrinter.cpp
      +++ b/clang/lib/Driver/TextDiagnosticPrinter.cpp
      @@ -113,10 +113,12 @@ void TextDiagnosticPrinter::HandleDiagnostic(Diagnostic::Level Level,
         
           // Compute the column number.
           ColNo = PLoc.getColumn();
      -    OS << PLoc.getFilename() << ':' << LineNo << ':';
      -    if (ColNo && ShowColumn) 
      -      OS << ColNo << ':';
      -    OS << ' ';
      +    if (ShowLocation) {
      +      OS << PLoc.getFilename() << ':' << LineNo << ':';
      +      if (ColNo && ShowColumn) 
      +        OS << ColNo << ':';
      +      OS << ' ';
      +    }
         }
         
         switch (Level) {
      -- 
      GitLab
      
      
      From d5576dee1c82c7ea15b62d84d09b0bae3eee364d Mon Sep 17 00:00:00 2001
      From: Douglas Gregor 
      Date: Fri, 30 Jan 2009 17:42:28 +0000
      Subject: [PATCH 504/682] Closed out a few radars that were addressed by
       designated initializers
      
      llvm-svn: 63398
      ---
       clang/test/Sema/init.c | 16 ++++++++++++++++
       1 file changed, 16 insertions(+)
      
      diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c
      index 9f0867869a98..41ca6244ff29 100644
      --- a/clang/test/Sema/init.c
      +++ b/clang/test/Sema/init.c
      @@ -80,3 +80,19 @@ struct s1 s2 = {
       
       // PR3382
       char t[] = ("Hello");
      +
      +// 
      +typedef struct { } empty;
      +
      +typedef struct {
      +  empty e;
      +  int i2;
      +} st;
      +
      +st st1 = { .i2 = 1 };
      +
      +// 
      +struct {
      +  int a;
      +  int z[2];
      +} y = { .z = {} };
      -- 
      GitLab
      
      
      From c094970cd215bf469b0f12b38c95208f3c2ee3f8 Mon Sep 17 00:00:00 2001
      From: Devang Patel 
      Date: Fri, 30 Jan 2009 18:20:31 +0000
      Subject: [PATCH 505/682]  Each input file is encoded as a separate compile
       unit in LLVM debugging information output. However, many target specific tool
       chains prefer to encode only one compile unit in an object file. In this
       situation, the LLVM code generator will include  debugging information
       entities in the compile unit that is marked as main compile unit. The code
       generator accepts maximum one main compile unit per module. If a module does
       not contain any main compile unit then the code generator will emit multiple
       compile units in the output object file.
      
      [Part 1]
      
      Update DebugInfo APIs to accept optional boolean value while creating DICompileUnit  to mark the unit as "main" unit. By defaults all units are considered  non-main.  Update SourceLevelDebugging.html to document "main" compile unit.
      
      Update DebugInfo APIs to not accept and encode separate source file/directory entries while creating various llvm.dbg.* entities. There was a recent, yet to be documented, change to include this additional information so no documentation changes are required here.
      
      Update DwarfDebug to handle "main" compile unit. If "main" compile unit is seen then all DIEs are inserted into "main" compile unit. All other compile units are used to find source location for llvm.dbg.* values. If there is not any "main" compile unit then create unique compile unit DIEs for each llvm.dbg.compile_unit.
      
      [Part 2]
      
      Create separate llvm.dbg.compile_unit for each input file. Mark compile unit create for main_input_filename as "main" compile unit. Use appropriate compile unit, based on source location information collected from the tree node, while creating llvm.dbg.* values using DebugInfo APIs.
      
      ---
      
      This is Part 1.
      
      llvm-svn: 63400
      ---
       llvm/docs/SourceLevelDebugging.html           |  9 +++
       llvm/include/llvm/Analysis/DebugInfo.h        | 75 +++++------------
       llvm/lib/Analysis/DebugInfo.cpp               | 52 ++++--------
       llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp   | 80 +++++++++++--------
       .../DebugInfo/2009-01-29-HeaderLocation.ll    | 46 +++++++++++
       5 files changed, 134 insertions(+), 128 deletions(-)
       create mode 100644 llvm/test/DebugInfo/2009-01-29-HeaderLocation.ll
      
      diff --git a/llvm/docs/SourceLevelDebugging.html b/llvm/docs/SourceLevelDebugging.html
      index 4a55a1c1a2ad..263f40c6ebc0 100644
      --- a/llvm/docs/SourceLevelDebugging.html
      +++ b/llvm/docs/SourceLevelDebugging.html
      @@ -378,6 +378,7 @@ deleted.

      sbyte*, ;; Source file name sbyte*, ;; Source file directory (includes trailing slash) sbyte* ;; Producer (ex. "4.0.1 LLVM (LLVM research group)") + bool ;; True if this is a main compile unit. }
      @@ -392,6 +393,14 @@ specific source file. Global variables and top level functions would be defined using this context. Compile unit descriptors also provide context for source line correspondence.

      +

      Each input file is encoded as a separate compile unit in LLVM debugging +information output. However, many target specific tool chains prefer to encode +only one compile unit in an object file. In this situation, the LLVM code +generator will include debugging information entities in the compile unit +that is marked as main compile unit. The code generator accepts maximum one main +compile unit per module. If a module does not contain any main compile unit +then the code generator will emit multiple compile units in the output object +file.

      diff --git a/llvm/include/llvm/Analysis/DebugInfo.h b/llvm/include/llvm/Analysis/DebugInfo.h index 310c1acf08fa..5113d5f77370 100644 --- a/llvm/include/llvm/Analysis/DebugInfo.h +++ b/llvm/include/llvm/Analysis/DebugInfo.h @@ -109,8 +109,18 @@ namespace llvm { std::string getFilename() const { return getStringField(3); } std::string getDirectory() const { return getStringField(4); } std::string getProducer() const { return getStringField(5); } - bool isOptimized() const { return getUnsignedField(6); } - std::string getFlags() const { return getStringField(7); } + + /// isMain - Each input file is encoded as a separate compile unit in LLVM + /// debugging information output. However, many target specific tool chains + /// prefer to encode only one compile unit in an object file. In this + /// situation, the LLVM code generator will include debugging information + /// entities in the compile unit that is marked as main compile unit. The + /// code generator accepts maximum one main compile unit per module. If a + /// module does not contain any main compile unit then the code generator + /// will emit multiple compile units in the output object file. + bool isMain() const { return getUnsignedField(6); } + bool isOptimized() const { return getUnsignedField(7); } + std::string getFlags() const { return getStringField(8); } /// Verify - Verify that a compile unit is well formed. bool Verify() const; @@ -183,16 +193,6 @@ namespace llvm { bool isProtected() const { return (getFlags() & FlagProtected) != 0; } bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; } - virtual std::string getFilename() const { - assert (0 && "Invalid DIDescriptor"); - return ""; - } - - virtual std::string getDirectory() const { - assert (0 && "Invalid DIDescriptor"); - return ""; - } - /// dump - print type. void dump() const; }; @@ -201,10 +201,7 @@ namespace llvm { class DIBasicType : public DIType { public: explicit DIBasicType(GlobalVariable *GV); - unsigned getEncoding() const { return getUnsignedField(9); } - std::string getFilename() const { return getStringField(10); } - std::string getDirectory() const { return getStringField(11); } /// dump - print basic type. void dump() const; @@ -218,10 +215,7 @@ namespace llvm { : DIType(GV, true, true) {} public: explicit DIDerivedType(GlobalVariable *GV); - DIType getTypeDerivedFrom() const { return getFieldAs(9); } - std::string getFilename() const { return getStringField(10); } - std::string getDirectory() const { return getStringField(11); } /// dump - print derived type. void dump() const; @@ -233,10 +227,7 @@ namespace llvm { class DICompositeType : public DIDerivedType { public: explicit DICompositeType(GlobalVariable *GV); - DIArray getTypeArray() const { return getFieldAs(10); } - std::string getFilename() const { return getStringField(11); } - std::string getDirectory() const { return getStringField(12); } /// Verify - Verify that a composite type descriptor is well formed. bool Verify() const; @@ -279,16 +270,6 @@ namespace llvm { unsigned isLocalToUnit() const { return getUnsignedField(9); } unsigned isDefinition() const { return getUnsignedField(10); } - virtual std::string getFilename() const { - assert (0 && "Invalid DIDescriptor"); - return ""; - } - - virtual std::string getDirectory() const { - assert (0 && "Invalid DIDescriptor"); - return ""; - } - /// dump - print global. void dump() const; }; @@ -297,8 +278,6 @@ namespace llvm { class DISubprogram : public DIGlobal { public: explicit DISubprogram(GlobalVariable *GV = 0); - std::string getFilename() const { return getStringField(11); } - std::string getDirectory() const { return getStringField(12); } DICompositeType getType() const { return getFieldAs(8); } /// Verify - Verify that a subprogram descriptor is well formed. @@ -312,10 +291,7 @@ namespace llvm { class DIGlobalVariable : public DIGlobal { public: explicit DIGlobalVariable(GlobalVariable *GV = 0); - GlobalVariable *getGlobal() const { return getGlobalVariableField(11); } - std::string getFilename() const { return getStringField(12); } - std::string getDirectory() const { return getStringField(13); } /// Verify - Verify that a global variable descriptor is well formed. bool Verify() const; @@ -335,8 +311,6 @@ namespace llvm { DICompileUnit getCompileUnit() const{ return getFieldAs(3); } unsigned getLineNumber() const { return getUnsignedField(4); } DIType getType() const { return getFieldAs(5); } - std::string getFilename() const { return getStringField(6); } - std::string getDirectory() const { return getStringField(7); } /// isVariable - Return true if the specified tag is legal for DIVariable. static bool isVariable(unsigned Tag); @@ -402,6 +376,7 @@ namespace llvm { const std::string &Filename, const std::string &Directory, const std::string &Producer, + bool isMain = false, bool isOptimized = false, const char *Flags = ""); @@ -413,9 +388,7 @@ namespace llvm { DICompileUnit CompileUnit, unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, - unsigned Encoding, - const std::string *FileName = 0, - const std::string *Directory = 0); + unsigned Encoding); /// CreateDerivedType - Create a derived type like const qualified type, /// pointer, typedef, etc. @@ -425,9 +398,7 @@ namespace llvm { unsigned LineNumber, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, - DIType DerivedFrom, - const std::string *FileName = 0, - const std::string *Directory = 0); + DIType DerivedFrom); /// CreateCompositeType - Create a composite type like array, struct, etc. DICompositeType CreateCompositeType(unsigned Tag, DIDescriptor Context, @@ -438,9 +409,7 @@ namespace llvm { uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, - DIArray Elements, - const std::string *FileName = 0, - const std::string *Directory = 0); + DIArray Elements); /// CreateSubprogram - Create a new descriptor for the specified subprogram. /// See comments in DISubprogram for descriptions of these fields. @@ -449,9 +418,7 @@ namespace llvm { const std::string &LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type, bool isLocalToUnit, - bool isDefinition, - const std::string *FileName = 0, - const std::string *Directory = 0); + bool isDefinition); /// CreateGlobalVariable - Create a new descriptor for the specified global. DIGlobalVariable @@ -460,17 +427,13 @@ namespace llvm { const std::string &LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type, bool isLocalToUnit, - bool isDefinition, llvm::GlobalVariable *GV, - const std::string *FileName = 0, - const std::string *Directory = 0); + bool isDefinition, llvm::GlobalVariable *GV); /// CreateVariable - Create a new descriptor for the specified variable. DIVariable CreateVariable(unsigned Tag, DIDescriptor Context, const std::string &Name, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type, - const std::string *FileName = 0, - const std::string *Directory = 0); + DIType Type); /// CreateBlock - This creates a descriptor for a lexical block with the /// specified parent context. diff --git a/llvm/lib/Analysis/DebugInfo.cpp b/llvm/lib/Analysis/DebugInfo.cpp index e5bbbd5aab09..0ec80894f11c 100644 --- a/llvm/lib/Analysis/DebugInfo.cpp +++ b/llvm/lib/Analysis/DebugInfo.cpp @@ -442,6 +442,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID, const std::string &Filename, const std::string &Directory, const std::string &Producer, + bool isMain, bool isOptimized, const char *Flags) { Constant *Elts[] = { @@ -451,6 +452,7 @@ DICompileUnit DIFactory::CreateCompileUnit(unsigned LangID, GetStringConstant(Filename), GetStringConstant(Directory), GetStringConstant(Producer), + ConstantInt::get(Type::Int1Ty, isMain), ConstantInt::get(Type::Int1Ty, isOptimized), GetStringConstant(Flags) }; @@ -492,9 +494,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context, uint64_t SizeInBits, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, - unsigned Encoding, - const std::string *FileName, - const std::string *Directory) { + unsigned Encoding) { Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_base_type), getCastToEmpty(Context), @@ -505,9 +505,7 @@ DIBasicType DIFactory::CreateBasicType(DIDescriptor Context, ConstantInt::get(Type::Int64Ty, AlignInBits), ConstantInt::get(Type::Int64Ty, OffsetInBits), ConstantInt::get(Type::Int32Ty, Flags), - ConstantInt::get(Type::Int32Ty, Encoding), - GetStringConstant(FileName ? FileName->c_str() : ""), - GetStringConstant(Directory ? Directory->c_str() : "") + ConstantInt::get(Type::Int32Ty, Encoding) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -531,9 +529,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag, uint64_t AlignInBits, uint64_t OffsetInBits, unsigned Flags, - DIType DerivedFrom, - const std::string *FileName, - const std::string *Directory) { + DIType DerivedFrom) { Constant *Elts[] = { GetTagConstant(Tag), getCastToEmpty(Context), @@ -544,9 +540,7 @@ DIDerivedType DIFactory::CreateDerivedType(unsigned Tag, ConstantInt::get(Type::Int64Ty, AlignInBits), ConstantInt::get(Type::Int64Ty, OffsetInBits), ConstantInt::get(Type::Int32Ty, Flags), - getCastToEmpty(DerivedFrom), - GetStringConstant(FileName ? FileName->c_str() : ""), - GetStringConstant(Directory ? Directory->c_str() : "") + getCastToEmpty(DerivedFrom) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -570,9 +564,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag, uint64_t OffsetInBits, unsigned Flags, DIType DerivedFrom, - DIArray Elements, - const std::string *FileName, - const std::string *Directory) { + DIArray Elements) { Constant *Elts[] = { GetTagConstant(Tag), @@ -585,9 +577,7 @@ DICompositeType DIFactory::CreateCompositeType(unsigned Tag, ConstantInt::get(Type::Int64Ty, OffsetInBits), ConstantInt::get(Type::Int32Ty, Flags), getCastToEmpty(DerivedFrom), - getCastToEmpty(Elements), - GetStringConstant(FileName ? FileName->c_str() : ""), - GetStringConstant(Directory ? Directory->c_str() : "") + getCastToEmpty(Elements) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -611,9 +601,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, DICompileUnit CompileUnit, unsigned LineNo, DIType Type, bool isLocalToUnit, - bool isDefinition, - const std::string *FileName, - const std::string *Directory) { + bool isDefinition) { Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_subprogram), @@ -626,9 +614,7 @@ DISubprogram DIFactory::CreateSubprogram(DIDescriptor Context, ConstantInt::get(Type::Int32Ty, LineNo), getCastToEmpty(Type), ConstantInt::get(Type::Int1Ty, isLocalToUnit), - ConstantInt::get(Type::Int1Ty, isDefinition), - GetStringConstant(FileName ? FileName->c_str() : ""), - GetStringConstant(Directory ? Directory->c_str() : "") + ConstantInt::get(Type::Int1Ty, isDefinition) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -648,9 +634,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name, const std::string &LinkageName, DICompileUnit CompileUnit, unsigned LineNo, DIType Type,bool isLocalToUnit, - bool isDefinition, llvm::GlobalVariable *Val, - const std::string *FileName, - const std::string *Directory) { + bool isDefinition, llvm::GlobalVariable *Val) { Constant *Elts[] = { GetTagConstant(dwarf::DW_TAG_variable), getCastToEmpty(GetOrCreateGlobalVariableAnchor()), @@ -663,9 +647,7 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name, getCastToEmpty(Type), ConstantInt::get(Type::Int1Ty, isLocalToUnit), ConstantInt::get(Type::Int1Ty, isDefinition), - ConstantExpr::getBitCast(Val, EmptyStructPtr), - GetStringConstant(FileName ? FileName->c_str() : ""), - GetStringConstant(Directory ? Directory->c_str() : "") + ConstantExpr::getBitCast(Val, EmptyStructPtr) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); @@ -683,20 +665,14 @@ DIFactory::CreateGlobalVariable(DIDescriptor Context, const std::string &Name, DIVariable DIFactory::CreateVariable(unsigned Tag, DIDescriptor Context, const std::string &Name, DICompileUnit CompileUnit, unsigned LineNo, - DIType Type, - const std::string *FileName, - const std::string *Directory) { - - + DIType Type) { Constant *Elts[] = { GetTagConstant(Tag), getCastToEmpty(Context), GetStringConstant(Name), getCastToEmpty(CompileUnit), ConstantInt::get(Type::Int32Ty, LineNo), - getCastToEmpty(Type), - GetStringConstant(FileName ? FileName->c_str() : ""), - GetStringConstant(Directory ? Directory->c_str() : "") + getCastToEmpty(Type) }; Constant *Init = ConstantStruct::get(Elts, sizeof(Elts)/sizeof(Elts[0])); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index b2a52cabe0e7..95990cfe6718 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1274,6 +1274,9 @@ private: /// of each entry in this vector corresponds to the sources in MMI. DenseMap DW_CUs; + /// MainCU - Some platform prefers one compile unit per .o file. In such + /// cases, all dies are inserted in MainCU. + CompileUnit *MainCU; /// AbbreviationsSet - Used to uniquely define abbreviations. /// FoldingSet AbbreviationsSet; @@ -1559,16 +1562,8 @@ private: void AddSourceLine(DIE *Die, const DIVariable *V) { unsigned FileID = 0; unsigned Line = V->getLineNumber(); - if (V->getVersion() <= LLVMDebugVersion6) { - // Version6 or earlier. Use compile unit info to get file id. - CompileUnit *Unit = FindCompileUnit(V->getCompileUnit()); - FileID = Unit->getID(); - } else { - // Version7 or newer, use filename and directory info from DIVariable - // directly. - unsigned DID = Directories.idFor(V->getDirectory()); - FileID = SrcFiles.idFor(SrcFileInfo(DID, V->getFilename())); - } + CompileUnit *Unit = FindCompileUnit(V->getCompileUnit()); + FileID = Unit->getID(); AddUInt(Die, DW_AT_decl_file, 0, FileID); AddUInt(Die, DW_AT_decl_line, 0, Line); } @@ -1578,16 +1573,8 @@ private: void AddSourceLine(DIE *Die, const DIGlobal *G) { unsigned FileID = 0; unsigned Line = G->getLineNumber(); - if (G->getVersion() <= LLVMDebugVersion6) { - // Version6 or earlier. Use compile unit info to get file id. - CompileUnit *Unit = FindCompileUnit(G->getCompileUnit()); - FileID = Unit->getID(); - } else { - // Version7 or newer, use filename and directory info from DIGlobal - // directly. - unsigned DID = Directories.idFor(G->getDirectory()); - FileID = SrcFiles.idFor(SrcFileInfo(DID, G->getFilename())); - } + CompileUnit *Unit = FindCompileUnit(G->getCompileUnit()); + FileID = Unit->getID(); AddUInt(Die, DW_AT_decl_file, 0, FileID); AddUInt(Die, DW_AT_decl_line, 0, Line); } @@ -1595,16 +1582,11 @@ private: void AddSourceLine(DIE *Die, const DIType *Ty) { unsigned FileID = 0; unsigned Line = Ty->getLineNumber(); - if (Ty->getVersion() <= LLVMDebugVersion6) { - // Version6 or earlier. Use compile unit info to get file id. - CompileUnit *Unit = FindCompileUnit(Ty->getCompileUnit()); - FileID = Unit->getID(); - } else { - // Version7 or newer, use filename and directory info from DIType - // directly. - unsigned DID = Directories.idFor(Ty->getDirectory()); - FileID = SrcFiles.idFor(SrcFileInfo(DID, Ty->getFilename())); - } + DICompileUnit CU = Ty->getCompileUnit(); + if (CU.isNull()) + return; + CompileUnit *Unit = FindCompileUnit(CU); + FileID = Unit->getID(); AddUInt(Die, DW_AT_decl_file, 0, FileID); AddUInt(Die, DW_AT_decl_line, 0, Line); } @@ -2091,7 +2073,9 @@ private: DISubprogram SPD(Desc.getGV()); // Get the compile unit context. - CompileUnit *Unit = FindCompileUnit(SPD.getCompileUnit()); + CompileUnit *Unit = MainCU; + if (!Unit) + Unit = FindCompileUnit(SPD.getCompileUnit()); // Get the subprogram die. DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); @@ -2122,7 +2106,9 @@ private: if (SPD.getName() == MF->getFunction()->getName()) { // Get the compile unit context. - CompileUnit *Unit = FindCompileUnit(SPD.getCompileUnit()); + CompileUnit *Unit = MainCU; + if (!Unit) + Unit = FindCompileUnit(SPD.getCompileUnit()); // Get the subprogram die. DIE *SPDie = Unit->getDieMapSlotFor(SPD.getGV()); @@ -2294,6 +2280,15 @@ private: /// void SizeAndOffsets() { // Process base compile unit. + if (MainCU) { + // Compute size of compile unit header + unsigned Offset = sizeof(int32_t) + // Length of Compilation Unit Info + sizeof(int16_t) + // DWARF version number + sizeof(int32_t) + // Offset Into Abbrev. Section + sizeof(int8_t); // Pointer Size (in bytes) + SizeAndOffsetDie(MainCU->getDie(), Offset, true); + return; + } for (DenseMap::iterator CI = DW_CUs.begin(), CE = DW_CUs.end(); CI != CE; ++CI) { CompileUnit *Unit = CI->second; @@ -2315,6 +2310,8 @@ private: for (DenseMap::iterator CI = DW_CUs.begin(), CE = DW_CUs.end(); CI != CE; ++CI) { CompileUnit *Unit = CI->second; + if (MainCU) + Unit = MainCU; DIE *Die = Unit->getDie(); // Emit the compile units header. EmitLabel("info_begin", Unit->getID()); @@ -2340,6 +2337,8 @@ private: EmitLabel("info_end", Unit->getID()); Asm->EOL(); + if (MainCU) + return; } } @@ -2639,6 +2638,8 @@ private: for (DenseMap::iterator CI = DW_CUs.begin(), CE = DW_CUs.end(); CI != CE; ++CI) { CompileUnit *Unit = CI->second; + if (MainCU) + Unit = MainCU; EmitDifference("pubnames_end", Unit->getID(), "pubnames_begin", Unit->getID(), true); @@ -2672,6 +2673,8 @@ private: EmitLabel("pubnames_end", Unit->getID()); Asm->EOL(); + if (MainCU) + return; } } @@ -2789,6 +2792,10 @@ private: AddString(Die, DW_AT_APPLE_flags, DW_FORM_string, Flags); CompileUnit *Unit = new CompileUnit(ID, Die); + if (DIUnit.isMain()) { + assert (!MainCU && "Multiple main compile units are found!"); + MainCU = Unit; + } DW_CUs[DIUnit.getGV()] = Unit; } } @@ -2802,7 +2809,9 @@ private: for (std::vector::iterator GVI = Result.begin(), GVE = Result.end(); GVI != GVE; ++GVI) { DIGlobalVariable DI_GV(*GVI); - CompileUnit *DW_Unit = FindCompileUnit(DI_GV.getCompileUnit()); + CompileUnit *DW_Unit = MainCU; + if (!DW_Unit) + DW_Unit = FindCompileUnit(DI_GV.getCompileUnit()); // Check for pre-existence. DIE *&Slot = DW_Unit->getDieMapSlotFor(DI_GV.getGV()); @@ -2839,7 +2848,9 @@ private: RE = Result.end(); RI != RE; ++RI) { DISubprogram SP(*RI); - CompileUnit *Unit = FindCompileUnit(SP.getCompileUnit()); + CompileUnit *Unit = MainCU; + if (!Unit) + Unit = FindCompileUnit(SP.getCompileUnit()); // Check for pre-existence. DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV()); @@ -2862,6 +2873,7 @@ public: // DwarfDebug(raw_ostream &OS, AsmPrinter *A, const TargetAsmInfo *T) : Dwarf(OS, A, T, "dbg") + , MainCU(NULL) , AbbreviationsSet(InitAbbreviationsSetSize) , Abbreviations() , ValuesSet(InitValuesSetSize) diff --git a/llvm/test/DebugInfo/2009-01-29-HeaderLocation.ll b/llvm/test/DebugInfo/2009-01-29-HeaderLocation.ll new file mode 100644 index 000000000000..c59a1c730cdd --- /dev/null +++ b/llvm/test/DebugInfo/2009-01-29-HeaderLocation.ll @@ -0,0 +1,46 @@ +; RUN: llvm-as < %s | llc | grep "m.h" | count 1 +target triple = "i386-apple-darwin9.6" + %llvm.dbg.anchor.type = type { i32, i32 } + %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } + %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* } + %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* } + %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } +@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str = internal constant [4 x i8] c"m.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1] +@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] +@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] +@.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] +@llvm.dbg.array = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] +@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@.str4 = internal constant [4 x i8] c"m.h\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@llvm.dbg.compile_unit5 = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] +@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str6 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str6, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] + +define i32 @main() nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) + call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*)) + store i32 0, i32* %0, align 4 + %1 = load i32* %0, align 4 ; [#uses=1] + store i32 %1, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + call void @llvm.dbg.stoppoint(i32 2, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit5 to { }*)) + call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) + ret i32 %retval1 +} + +declare void @llvm.dbg.func.start({ }*) nounwind + +declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind + +declare void @llvm.dbg.region.end({ }*) nounwind -- GitLab From 97f1720621b4d456a67a467f1df2c59a254a40f5 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Fri, 30 Jan 2009 18:21:13 +0000 Subject: [PATCH 506/682] use precise getters llvm-svn: 63402 --- llvm/lib/Transforms/Utils/Local.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index b8077aefb132..c22485342e09 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -38,8 +38,8 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB) { // Branch - See if we are conditional jumping on constant if (BranchInst *BI = dyn_cast(T)) { if (BI->isUnconditional()) return false; // Can't optimize uncond branch - BasicBlock *Dest1 = cast(BI->getOperand(0)); - BasicBlock *Dest2 = cast(BI->getOperand(1)); + BasicBlock *Dest1 = BI->getSuccessor(0); + BasicBlock *Dest2 = BI->getSuccessor(1); if (ConstantInt *Cond = dyn_cast(BI->getCondition())) { // Are we branching on constant? -- GitLab From 1933b00c12a1165e677ef1eb562a36550b198379 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Fri, 30 Jan 2009 18:27:21 +0000 Subject: [PATCH 507/682] use precise getters llvm-svn: 63403 --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 0cb476e30519..e37c439f5ce0 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -811,11 +811,14 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, } break; case Instruction::Br: - Code = bitc::FUNC_CODE_INST_BR; - Vals.push_back(VE.getValueID(I.getOperand(0))); - if (cast(I).isConditional()) { - Vals.push_back(VE.getValueID(I.getOperand(1))); - Vals.push_back(VE.getValueID(I.getOperand(2))); + { + Code = bitc::FUNC_CODE_INST_BR; + BranchInst &II(cast(I)); + Vals.push_back(VE.getValueID(II.getSuccessor(0))); + if (II.isConditional()) { + Vals.push_back(VE.getValueID(II.getSuccessor(1))); + Vals.push_back(VE.getValueID(II.getCondition())); + } } break; case Instruction::Switch: -- GitLab From 890c6b552086ec13c9156a341c4c03712576d3d7 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 30 Jan 2009 18:40:10 +0000 Subject: [PATCH 508/682] x86_64 ABI: Split small vectors which cross an eightbyte boundary. Down to 33/500 return type failures. llvm-svn: 63404 --- clang/lib/CodeGen/CGCall.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b8f0ae868f06..8027612cd4b3 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -530,6 +530,11 @@ void X86_64ABIInfo::classify(QualType Ty, // double> as INTEGER; this seems wrong, but we will match for // now (icc rejects <1 x double>, so...). Lo = (VT->getElementType() == Context.DoubleTy) ? Integer : SSE; + + // If this type crosses an eightbyte boundary, it should be + // split. + if (OffsetBase && OffsetBase != 8) + Hi = Lo; } else if (Size == 128) { Lo = SSE; Hi = SSEUp; @@ -537,8 +542,8 @@ void X86_64ABIInfo::classify(QualType Ty, } else if (const ComplexType *CT = Ty->getAsComplexType()) { QualType ET = CT->getElementType(); + uint64_t Size = Context.getTypeSize(Ty); if (ET->isIntegerType()) { - uint64_t Size = Context.getTypeSize(Ty); if (Size <= 64) Lo = Integer; else if (Size <= 128) @@ -553,7 +558,7 @@ void X86_64ABIInfo::classify(QualType Ty, // If this complex type crosses an eightbyte boundary then it // should be split. uint64_t EB_Real = (OffsetBase) >> 3; - uint64_t EB_Imag = (OffsetBase + Context.getTypeSize(ET)) >> 3; + uint64_t EB_Imag = (OffsetBase + Size) >> 3; if (Hi == NoClass && EB_Real != EB_Imag) Hi = Lo; } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { -- GitLab From d8cc884a367dea2ef2981e87d6feb54783c5cefc Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Jan 2009 18:44:17 +0000 Subject: [PATCH 509/682] avoid emitting a bogus line marker for the top level #include location. We now -E a file containing "foo" into: # 1 "t.c" # 1 "t.c" 1 # 1 "" 1 # 1 "t.c" 2 foo instead of: # 1 "t.c" # 1 "t.c" 1 # 0 "t.c" # 1 "" 1 # 1 "t.c" 2 foo llvm-svn: 63405 --- clang/Driver/PrintPreprocessedOutput.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/clang/Driver/PrintPreprocessedOutput.cpp b/clang/Driver/PrintPreprocessedOutput.cpp index 5c4a140fa9ae..2c764ade008d 100644 --- a/clang/Driver/PrintPreprocessedOutput.cpp +++ b/clang/Driver/PrintPreprocessedOutput.cpp @@ -150,7 +150,9 @@ void PrintPPOutputPPCallbacks::FileChanged(SourceLocation Loc, // #include directive was at. SourceManager &SourceMgr = PP.getSourceManager(); if (Reason == PPCallbacks::EnterFile) { - MoveToLine(SourceMgr.getPresumedLoc(Loc).getIncludeLoc()); + SourceLocation IncludeLoc = SourceMgr.getPresumedLoc(Loc).getIncludeLoc(); + if (IncludeLoc.isValid()) + MoveToLine(IncludeLoc); } else if (Reason == PPCallbacks::SystemHeaderPragma) { MoveToLine(Loc); -- GitLab From 7da8d0b32100abb2d9bd30bfe82dc27b92e724f4 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 30 Jan 2009 18:47:53 +0000 Subject: [PATCH 510/682] Remove testing -use-x86_64-abi option; current implementation is robust enough for general use. llvm-svn: 63406 --- clang/lib/CodeGen/CGCall.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 8027612cd4b3..21eccdc2a363 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -27,11 +27,6 @@ using namespace clang; using namespace CodeGen; -static llvm::cl::opt -UseX86_64ABI("use-x86_64-abi", - llvm::cl::desc("Enable use of experimental x86_64 ABI."), - llvm::cl::init(false)); - /***/ // FIXME: Use iterator and sidestep silly type array creation. @@ -760,8 +755,7 @@ const ABIInfo &CodeGenTypes::getABIInfo() const { case 32: return *(TheABIInfo = new X86_32ABIInfo()); case 64: - if (UseX86_64ABI) - return *(TheABIInfo = new X86_64ABIInfo()); + return *(TheABIInfo = new X86_64ABIInfo()); } } -- GitLab From be70ced6a6965467828857fc889f1c6e7506f3b9 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Jan 2009 18:49:16 +0000 Subject: [PATCH 511/682] add testcase for PR3437 and r63405 llvm-svn: 63407 --- clang/test/Preprocessor/print_line_track.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/test/Preprocessor/print_line_track.c b/clang/test/Preprocessor/print_line_track.c index 567da3c1a213..505e5f9fae11 100644 --- a/clang/test/Preprocessor/print_line_track.c +++ b/clang/test/Preprocessor/print_line_track.c @@ -1,8 +1,10 @@ /* RUN: clang -E %s | grep 'a 3' && - * RUN: clang -E %s | grep 'b 14' && + * RUN: clang -E %s | grep 'b 16' && * RUN: clang -E -P %s | grep 'a 3' && - * RUN: clang -E -P %s | grep 'b 14' + * RUN: clang -E -P %s | grep 'b 16' && + * RUN: clang -E %s | not grep '# 0 ' * PR1848 + * PR3437 */ #define t(x) x -- GitLab From 097feda5e03e72b3a5d99473993f8066ac2a85a3 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 30 Jan 2009 18:58:59 +0000 Subject: [PATCH 512/682] Code gen. for @protocol expression in the new nonfragile abi. llvm-svn: 63408 --- clang/lib/CodeGen/CGObjCMac.cpp | 38 +++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 526a95a96366..cf7010ae2dc0 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -638,10 +638,8 @@ public: virtual void GenerateCategory(const ObjCCategoryImplDecl *CMD); virtual void GenerateClass(const ObjCImplementationDecl *ClassDecl); - virtual llvm::Value *GenerateProtocolRef(CGBuilderTy &Builder, - const ObjCProtocolDecl *PD) - { return 0; } + const ObjCProtocolDecl *PD); virtual llvm::Function *GetPropertyGetFunction(){ return 0; } virtual llvm::Function *GetPropertySetFunction() @@ -3461,6 +3459,38 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); } +/// GenerateProtocolRef - This routine is called to generate code for +/// a protocol reference expression; as in: +/// @code +/// @protocol(Proto1); +/// @endcode +/// It generates a weak reference to l_OBJC_PROTOCOL_REFERENCE_$_Proto1 +/// which will hold address of the protocol meta-data. +/// +llvm::Value *CGObjCNonFragileABIMac::GenerateProtocolRef(CGBuilderTy &Builder, + const ObjCProtocolDecl *PD) { + + llvm::Constant *Init = llvm::ConstantExpr::getBitCast(GetProtocolRef(PD), + ObjCTypes.ExternalProtocolPtrTy); + + std::string ProtocolName("\01l_OBJC_PROTOCOL_REFERENCE_$_"); + ProtocolName += PD->getNameAsCString(); + + llvm::GlobalVariable *PTGV = CGM.getModule().getGlobalVariable(ProtocolName); + if (PTGV) + return Builder.CreateLoad(PTGV, false, "tmp"); + PTGV = new llvm::GlobalVariable( + Init->getType(), false, + llvm::GlobalValue::WeakLinkage, + Init, + ProtocolName, + &CGM.getModule()); + PTGV->setSection("__DATA, __objc_protorefs, coalesced, no_dead_strip"); + PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); + UsedGlobals.push_back(PTGV); + return Builder.CreateLoad(PTGV, false, "tmp"); +} + /// GenerateCategory - Build metadata for a category implementation. /// struct _category_t { /// const char * const name; @@ -3936,7 +3966,7 @@ CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { Desc[0] = llvm::ConstantExpr::getBitCast(GetMethodVarName(MD->getSelector()), ObjCTypes.SelectorPtrTy); Desc[1] = GetMethodVarType(MD); - // FIXME. This is really always NULL? + // Protocol methods have no implementation. So, this entry is always NULL. Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); } -- GitLab From 83ab0a83f5f35d93f46ec4ae7460c0d3438c5430 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Jan 2009 19:01:41 +0000 Subject: [PATCH 513/682] wire up -fno-show-source-location option, patch by Alexei Svitkine! llvm-svn: 63409 --- clang/Driver/clang.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index b16a83657186..5e545b98e44b 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -187,6 +187,11 @@ static llvm::cl::opt NoShowColumn("fno-show-column", llvm::cl::desc("Do not include column number on diagnostics")); +static llvm::cl::opt +NoShowLocation("fno-show-source-location", + llvm::cl::desc("Do not include source location information with" + " diagnostics")); + static llvm::cl::opt NoCaretDiagnostics("fno-caret-diagnostics", llvm::cl::desc("Do not include source line and caret with" @@ -1530,7 +1535,8 @@ int main(int argc, char **argv) { // Print diagnostics to stderr by default. TextDiagClient = new TextDiagnosticPrinter(llvm::errs(), !NoShowColumn, - !NoCaretDiagnostics); + !NoCaretDiagnostics, + !NoShowLocation); } else { // When checking diagnostics, just buffer them up. TextDiagClient = new TextDiagnosticBuffer(); -- GitLab From ce3f6818e12f7bf0df52e227f76cefd949a2069b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 30 Jan 2009 19:06:38 +0000 Subject: [PATCH 514/682] Fix inverted logic in ParentMap::hasParent() llvm-svn: 63410 --- clang/include/clang/AST/ParentMap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/AST/ParentMap.h b/clang/include/clang/AST/ParentMap.h index 5fb96f54b4c9..fae9557b217e 100644 --- a/clang/include/clang/AST/ParentMap.h +++ b/clang/include/clang/AST/ParentMap.h @@ -26,7 +26,7 @@ public: Stmt* getParent(Stmt*) const; bool hasParent(Stmt* S) const { - return !getParent(S); + return getParent(S) != 0; } }; -- GitLab From 781db7a1ad4cd218f27d02040afb0a78cc204a5d Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 19:25:47 +0000 Subject: [PATCH 515/682] Propagate debug loc info in SimplifyBinOpWithSameOpcodeHands. llvm-svn: 63411 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 36927b358d7f..9a1f03b6b7c9 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1731,11 +1731,11 @@ SDValue DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) { if ((N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND|| N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::TRUNCATE) && N0.getOperand(0).getValueType() == N1.getOperand(0).getValueType()) { - SDValue ORNode = DAG.getNode(N->getOpcode(), - N0.getOperand(0).getValueType(), - N0.getOperand(0), N1.getOperand(0)); + SDValue ORNode = DAG.getNode(N->getOpcode(), N0.getDebugLoc(), + N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); AddToWorkList(ORNode.getNode()); - return DAG.getNode(N0.getOpcode(), VT, ORNode); + return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, ORNode); } // For each of OP in SHL/SRL/SRA/AND... @@ -1745,11 +1745,12 @@ SDValue DAGCombiner::SimplifyBinOpWithSameOpcodeHands(SDNode *N) { if ((N0.getOpcode() == ISD::SHL || N0.getOpcode() == ISD::SRL || N0.getOpcode() == ISD::SRA || N0.getOpcode() == ISD::AND) && N0.getOperand(1) == N1.getOperand(1)) { - SDValue ORNode = DAG.getNode(N->getOpcode(), - N0.getOperand(0).getValueType(), - N0.getOperand(0), N1.getOperand(0)); + SDValue ORNode = DAG.getNode(N->getOpcode(), N0.getDebugLoc(), + N0.getOperand(0).getValueType(), + N0.getOperand(0), N1.getOperand(0)); AddToWorkList(ORNode.getNode()); - return DAG.getNode(N0.getOpcode(), VT, ORNode, N0.getOperand(1)); + return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, + ORNode, N0.getOperand(1)); } return SDValue(); -- GitLab From 0b0a64830a8f8517545190db1305c6a82d75a367 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 30 Jan 2009 19:27:39 +0000 Subject: [PATCH 516/682] Move method out-of-line. llvm-svn: 63412 --- .../Analysis/PathSensitive/GRExprEngine.h | 31 +------------------ clang/lib/Analysis/GRExprEngine.cpp | 30 ++++++++++++++++++ 2 files changed, 31 insertions(+), 30 deletions(-) diff --git a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h index 05bb333cdc54..d84d17c01715 100644 --- a/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h +++ b/clang/include/clang/Analysis/PathSensitive/GRExprEngine.h @@ -638,36 +638,7 @@ protected: void EvalBinOp(GRStateSet& OStates, const GRState* St, Expr* Ex, BinaryOperator::Opcode Op, NonLoc L, NonLoc R); - SVal EvalBinOp(BinaryOperator::Opcode Op, SVal L, SVal R) { - - if (L.isUndef() || R.isUndef()) - return UndefinedVal(); - - if (L.isUnknown() || R.isUnknown()) - return UnknownVal(); - - if (isa(L)) { - if (isa(R)) - return getTF().EvalBinOp(*this, Op, cast(L), cast(R)); - else - return getTF().EvalBinOp(*this, Op, cast(L), cast(R)); - } - - if (isa(R)) { - // Support pointer arithmetic where the increment/decrement operand - // is on the left and the pointer on the right. - - assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); - - // Commute the operands. - return getTF().EvalBinOp(*this, Op, cast(R), - cast(L)); - } - else - return getTF().DetermEvalBinOpNN(*this, Op, cast(L), - cast(R)); - } - + SVal EvalBinOp(BinaryOperator::Opcode Op, SVal L, SVal R); void EvalCall(NodeSet& Dst, CallExpr* CE, SVal L, NodeTy* Pred) { assert (Builder && "GRStmtNodeBuilder must be defined."); diff --git a/clang/lib/Analysis/GRExprEngine.cpp b/clang/lib/Analysis/GRExprEngine.cpp index d9bdd8be0b69..5268e1324f55 100644 --- a/clang/lib/Analysis/GRExprEngine.cpp +++ b/clang/lib/Analysis/GRExprEngine.cpp @@ -2691,6 +2691,36 @@ void GRExprEngine::EvalBinOp(GRStateSet& OStates, const GRState* St, if (R.isValid()) getTF().EvalBinOpNN(OStates, *this, St, Ex, Op, L, R); } +SVal GRExprEngine::EvalBinOp(BinaryOperator::Opcode Op, SVal L, SVal R) { + + if (L.isUndef() || R.isUndef()) + return UndefinedVal(); + + if (L.isUnknown() || R.isUnknown()) + return UnknownVal(); + + if (isa(L)) { + if (isa(R)) + return getTF().EvalBinOp(*this, Op, cast(L), cast(R)); + else + return getTF().EvalBinOp(*this, Op, cast(L), cast(R)); + } + + if (isa(R)) { + // Support pointer arithmetic where the increment/decrement operand + // is on the left and the pointer on the right. + + assert (Op == BinaryOperator::Add || Op == BinaryOperator::Sub); + + // Commute the operands. + return getTF().EvalBinOp(*this, Op, cast(R), + cast(L)); + } + else + return getTF().DetermEvalBinOpNN(*this, Op, cast(L), + cast(R)); +} + //===----------------------------------------------------------------------===// // Visualization. //===----------------------------------------------------------------------===// -- GitLab From 4d22eaeb44dbca67d974bb8dc893bf46888ce4a5 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 30 Jan 2009 19:38:39 +0000 Subject: [PATCH 517/682] x86_64 ABI: Pass <1 x double> in memory. This is arguably wrong, but matches gcc 4.2 (not llvm-gcc). llvm-svn: 63413 --- clang/lib/CodeGen/CGCall.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 21eccdc2a363..cf4f60e36659 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -521,10 +521,13 @@ void X86_64ABIInfo::classify(QualType Ty, } else if (const VectorType *VT = Ty->getAsVectorType()) { uint64_t Size = Context.getTypeSize(VT); if (Size == 64) { - // FIXME: For some reason, gcc appears to be treating <1 x - // double> as INTEGER; this seems wrong, but we will match for - // now (icc rejects <1 x double>, so...). - Lo = (VT->getElementType() == Context.DoubleTy) ? Integer : SSE; + // gcc passes <1 x double> in memory. + if (VT->getElementType() == Context.DoubleTy) { + Lo = Memory; + return; + } + + Lo = Integer; // If this type crosses an eightbyte boundary, it should be // split. -- GitLab From 1d63998135266fa62ba1fe96e239000616c680a4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Jan 2009 20:03:59 +0000 Subject: [PATCH 518/682] memset takes an int, not a char. llvm-svn: 63414 --- clang/include/clang/AST/Builtins.def | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/include/clang/AST/Builtins.def b/clang/include/clang/AST/Builtins.def index 07c751db3ee4..7d8f27a23687 100644 --- a/clang/include/clang/AST/Builtins.def +++ b/clang/include/clang/AST/Builtins.def @@ -123,7 +123,7 @@ BUILTIN(__builtin_stdarg_start, "vA.", "n") BUILTIN(__builtin_bzero, "vv*z", "n") BUILTIN(__builtin_memcpy, "v*v*vC*z", "n") BUILTIN(__builtin_memmove, "v*v*vC*z", "n") -BUILTIN(__builtin_memset, "v*v*cz", "n") +BUILTIN(__builtin_memset, "v*v*iz", "n") BUILTIN(__builtin_return_address, "v*Ui", "n") BUILTIN(__builtin_frame_address, "v*Ui", "n") BUILTIN(__builtin_flt_rounds, "i", "nc") -- GitLab From 22b43cdc053b62fe31c9ecc9c98bf4d834cd09fe Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 30 Jan 2009 20:04:14 +0000 Subject: [PATCH 519/682] DiagnosticKinds.def is gone. llvm-svn: 63415 --- clang/clang.xcodeproj/project.pbxproj | 4 ---- 1 file changed, 4 deletions(-) diff --git a/clang/clang.xcodeproj/project.pbxproj b/clang/clang.xcodeproj/project.pbxproj index f4be191e7894..ffb91da7511b 100644 --- a/clang/clang.xcodeproj/project.pbxproj +++ b/clang/clang.xcodeproj/project.pbxproj @@ -186,7 +186,6 @@ DED676FA0B6C797B00AAD4A3 /* Builtins.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED676F90B6C797B00AAD4A3 /* Builtins.h */; }; DED677C90B6C854100AAD4A3 /* Builtins.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED677C80B6C854100AAD4A3 /* Builtins.cpp */; }; DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7310A524295003AD0FB /* Diagnostic.h */; }; - DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7320A524295003AD0FB /* DiagnosticKinds.def */; }; DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7330A524295003AD0FB /* FileManager.h */; }; DED7D7450A524295003AD0FB /* SourceLocation.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7350A524295003AD0FB /* SourceLocation.h */; }; DED7D7460A524295003AD0FB /* SourceManager.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = DED7D7360A524295003AD0FB /* SourceManager.h */; }; @@ -228,7 +227,6 @@ dstSubfolderSpec = 0; files = ( DED7D7410A524295003AD0FB /* Diagnostic.h in CopyFiles */, - DED7D7420A524295003AD0FB /* DiagnosticKinds.def in CopyFiles */, DED7D7430A524295003AD0FB /* FileManager.h in CopyFiles */, DED7D7450A524295003AD0FB /* SourceLocation.h in CopyFiles */, DED7D7460A524295003AD0FB /* SourceManager.h in CopyFiles */, @@ -561,7 +559,6 @@ DED676F90B6C797B00AAD4A3 /* Builtins.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Builtins.h; path = clang/AST/Builtins.h; sourceTree = ""; tabWidth = 2; }; DED677C80B6C854100AAD4A3 /* Builtins.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Builtins.cpp; path = lib/AST/Builtins.cpp; sourceTree = ""; tabWidth = 2; }; DED7D7310A524295003AD0FB /* Diagnostic.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = Diagnostic.h; sourceTree = ""; tabWidth = 2; }; - DED7D7320A524295003AD0FB /* DiagnosticKinds.def */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = text; path = DiagnosticKinds.def; sourceTree = ""; tabWidth = 2; }; DED7D7330A524295003AD0FB /* FileManager.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = FileManager.h; sourceTree = ""; tabWidth = 2; }; DED7D7350A524295003AD0FB /* SourceLocation.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SourceLocation.h; sourceTree = ""; tabWidth = 2; }; DED7D7360A524295003AD0FB /* SourceManager.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 2; lastKnownFileType = sourcecode.c.h; path = SourceManager.h; sourceTree = ""; tabWidth = 2; }; @@ -1078,7 +1075,6 @@ DEA099FE0F302C65000C2258 /* DiagnosticAnalysisKinds.def */, DEA09A000F302C65000C2258 /* DiagnosticASTKinds.def */, DEA09A010F302C65000C2258 /* DiagnosticCommonKinds.def */, - DED7D7320A524295003AD0FB /* DiagnosticKinds.def */, DEA09A040F302C65000C2258 /* DiagnosticLexKinds.def */, DEA09A060F302C65000C2258 /* DiagnosticParseKinds.def */, DEA09A080F302C65000C2258 /* DiagnosticSemaKinds.def */, -- GitLab From 8617191302ab19f84ce8cca32b08e72ef7977ca6 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 20:43:18 +0000 Subject: [PATCH 520/682] Propagate debug loc info for AND. Also clean up some comments. llvm-svn: 63416 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9a1f03b6b7c9..e507b893bc25 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1802,8 +1802,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { APInt Mask = ~N1C->getAPIntValue(); Mask.trunc(N0Op0.getValueSizeInBits()); if (DAG.MaskedValueIsZero(N0Op0, Mask)) { - SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, N0.getValueType(), - N0Op0); + SDValue Zext = DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), + N0.getValueType(), N0Op0); // Replace uses of the AND with uses of the Zero extend node. CombineTo(N, Zext); @@ -1822,23 +1822,26 @@ SDValue DAGCombiner::visitAND(SDNode *N) { if (LR == RR && isa(LR) && Op0 == Op1 && LL.getValueType().isInteger()) { - // fold (X == 0) & (Y == 0) -> (X|Y == 0) + // fold (and (seteq X, 0), (seteq Y, 0)) -> (seteq (or X, Y), 0) if (cast(LR)->isNullValue() && Op1 == ISD::SETEQ) { - SDValue ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + SDValue ORNode = DAG.getNode(ISD::OR, N0.getDebugLoc(), + LR.getValueType(), LL, RL); AddToWorkList(ORNode.getNode()); - return DAG.getSetCC(VT, ORNode, LR, Op1); + return DAG.getSetCC(N->getDebugLoc(), VT, ORNode, LR, Op1); } - // fold (X == -1) & (Y == -1) -> (X&Y == -1) + // fold (and (seteq X, -1), (seteq Y, -1)) -> (seteq (and X, Y), -1) if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETEQ) { - SDValue ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); + SDValue ANDNode = DAG.getNode(ISD::AND, N0.getDebugLoc(), + LR.getValueType(), LL, RL); AddToWorkList(ANDNode.getNode()); - return DAG.getSetCC(VT, ANDNode, LR, Op1); + return DAG.getSetCC(N->getDebugLoc(), VT, ANDNode, LR, Op1); } - // fold (X > -1) & (Y > -1) -> (X|Y > -1) + // fold (and (setgt X, -1), (setgt Y, -1)) -> (setgt (or X, Y), -1) if (cast(LR)->isAllOnesValue() && Op1 == ISD::SETGT) { - SDValue ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + SDValue ORNode = DAG.getNode(ISD::OR, N0.getDebugLoc(), + LR.getValueType(), LL, RL); AddToWorkList(ORNode.getNode()); - return DAG.getSetCC(VT, ORNode, LR, Op1); + return DAG.getSetCC(N->getDebugLoc(), VT, ORNode, LR, Op1); } } // canonicalize equivalent to ll == rl @@ -1851,11 +1854,12 @@ SDValue DAGCombiner::visitAND(SDNode *N) { ISD::CondCode Result = ISD::getSetCCAndOperation(Op0, Op1, isInteger); if (Result != ISD::SETCC_INVALID && (!LegalOperations || TLI.isCondCodeLegal(Result, LL.getValueType()))) - return DAG.getSetCC(N0.getValueType(), LL, LR, Result); + return DAG.getSetCC(N->getDebugLoc(), N0.getValueType(), + LL, LR, Result); } } - // Simplify: and (op x...), (op y...) -> (op (and x, y)) + // Simplify: (and (op x...), (op y...)) -> (op (and x, y)) if (N0.getOpcode() == N1.getOpcode()) { SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N); if (Tmp.getNode()) return Tmp; @@ -1877,8 +1881,9 @@ SDValue DAGCombiner::visitAND(SDNode *N) { BitWidth - EVT.getSizeInBits())) && ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { - SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), - LN0->getBasePtr(), LN0->getSrcValue(), + SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N0.getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), + LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); AddToWorkList(N); @@ -1898,7 +1903,8 @@ SDValue DAGCombiner::visitAND(SDNode *N) { BitWidth - EVT.getSizeInBits())) && ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { - SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N0.getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); @@ -1922,11 +1928,13 @@ SDValue DAGCombiner::visitAND(SDNode *N) { EVT = MVT::getIntegerVT(ActiveBits); MVT LoadedVT = LN0->getMemoryVT(); + // Do not generate loads of non-round integer types since these can // be expensive (and would be wrong if the type is not byte sized). if (EVT != MVT::Other && LoadedVT.bitsGT(EVT) && EVT.isRound() && (!LegalOperations || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT))) { MVT PtrType = N0.getOperand(1).getValueType(); + // For big endian targets, we need to add an offset to the pointer to // load the correct bytes. For little endian systems, we merely need to // read fewer bytes from the same pointer. @@ -1935,16 +1943,18 @@ SDValue DAGCombiner::visitAND(SDNode *N) { unsigned PtrOff = LVTStoreBytes - EVTStoreBytes; unsigned Alignment = LN0->getAlignment(); SDValue NewPtr = LN0->getBasePtr(); + if (TLI.isBigEndian()) { - NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr, - DAG.getConstant(PtrOff, PtrType)); + NewPtr = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), PtrType, + NewPtr, DAG.getConstant(PtrOff, PtrType)); Alignment = MinAlign(Alignment, PtrOff); } + AddToWorkList(NewPtr.getNode()); SDValue Load = - DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), NewPtr, - LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, - LN0->isVolatile(), Alignment); + DAG.getExtLoad(ISD::ZEXTLOAD, LN0->getDebugLoc(), VT, LN0->getChain(), + NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), + EVT, LN0->isVolatile(), Alignment); AddToWorkList(N); CombineTo(N0.getNode(), Load, Load.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! -- GitLab From ff8acd684fbbc5c37fb0dd856275a4c344b81f29 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 20:50:00 +0000 Subject: [PATCH 521/682] Perform obvious constant arithmetic folding. llvm-svn: 63417 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index e507b893bc25..d639ec018e16 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -485,9 +485,10 @@ SDValue DAGCombiner::ReassociateOps(unsigned Opc, DebugLoc DL, if (N0.getOpcode() == Opc && isa(N0.getOperand(1))) { if (isa(N1)) { // reassoc. (op (op x, c1), c2) -> (op x, (op c1, c2)) - SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT, - N0.getOperand(1), N1); - AddToWorkList(OpNode.getNode()); + SDValue OpNode = + DAG.FoldConstantArithmetic(Opc, VT, + cast(N0.getOperand(1)), + cast(N1)); return DAG.getNode(Opc, DL, VT, N0.getOperand(0), OpNode); } else if (N0.hasOneUse()) { // reassoc. (op (op x, c1), y) -> (op (op x, y), c1) iff x+c1 has one use @@ -501,9 +502,10 @@ SDValue DAGCombiner::ReassociateOps(unsigned Opc, DebugLoc DL, if (N1.getOpcode() == Opc && isa(N1.getOperand(1))) { if (isa(N0)) { // reassoc. (op c2, (op x, c1)) -> (op x, (op c1, c2)) - SDValue OpNode = DAG.getNode(Opc, N1.getDebugLoc(), VT, - N1.getOperand(1), N0); - AddToWorkList(OpNode.getNode()); + SDValue OpNode = + DAG.FoldConstantArithmetic(Opc, VT, + cast(N1.getOperand(1)), + cast(N0)); return DAG.getNode(Opc, DL, VT, N1.getOperand(0), OpNode); } else if (N1.hasOneUse()) { // reassoc. (op y, (op x, c1)) -> (op (op x, y), c1) iff x+c1 has one use -- GitLab From 279abd31a9046b79f3f3bb37f5900c4bb9a3803e Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 30 Jan 2009 20:55:31 +0000 Subject: [PATCH 522/682] Generate list of implemented classes and categories in their own sections (related to objc2 nonfragile abi). llvm-svn: 63418 --- clang/lib/CodeGen/CGObjCMac.cpp | 57 ++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index cf7010ae2dc0..67ef1ae0e830 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3144,6 +3144,59 @@ llvm::Function *CGObjCNonFragileABIMac::ModuleInitFunction() { void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { // nonfragile abi has no module definition. + + // Build list of all implemented classe addresses in array + // L_OBJC_LABEL_CLASS_$. + // FIXME. Also generate in L_OBJC_LABEL_NONLAZY_CLASS_$ + // list of 'nonlazy' implementations (defined as those with a +load{} + // method!!). + unsigned NumClasses = DefinedClasses.size(); + if (NumClasses) { + std::vector Symbols(NumClasses); + for (unsigned i=0; igetType(), false, + llvm::GlobalValue::InternalLinkage, + Init, + "\01L_OBJC_LABEL_CLASS_$", + &CGM.getModule()); + GV->setSection("__DATA, __objc_classlist, regular, no_dead_strip"); + UsedGlobals.push_back(GV); + } + + // Build list of all implemented category addresses in array + // L_OBJC_LABEL_CATEGORY_$. + // FIXME. Also generate in L_OBJC_LABEL_NONLAZY_CATEGORY_$ + // list of 'nonlazy' category implementations (defined as those with a +load{} + // method!!). + unsigned NumCategory = DefinedCategories.size(); + if (NumCategory) { + std::vector Symbols(NumCategory); + for (unsigned i=0; igetType(), false, + llvm::GlobalValue::InternalLinkage, + Init, + "\01L_OBJC_LABEL_CATEGORY_$", + &CGM.getModule()); + GV->setSection("__DATA, __objc_catlist, regular, no_dead_strip"); + UsedGlobals.push_back(GV); + } + std::vector Used; for (std::vector::iterator i = UsedGlobals.begin(), e = UsedGlobals.end(); i != e; ++i) { @@ -3456,7 +3509,9 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { ID); TClassName = ObjCClassName + ClassName; - BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); + llvm::GlobalVariable *ClassMD = + BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); + DefinedClasses.push_back(ClassMD); } /// GenerateProtocolRef - This routine is called to generate code for -- GitLab From f29b6e1318841c3a802407108bd3e16828453f58 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 20:59:34 +0000 Subject: [PATCH 523/682] Propagate debug loc info for OR. Also clean up some comments. llvm-svn: 63419 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d639ec018e16..4973433b7206 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1989,7 +1989,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) { return DAG.FoldConstantArithmetic(ISD::OR, VT, N0C, N1C); // canonicalize constant to RHS if (N0C && !N1C) - return DAG.getNode(ISD::OR, VT, N1, N0); + return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N1, N0); // fold (or x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -2007,10 +2007,10 @@ SDValue DAGCombiner::visitOR(SDNode *N) { if (N1C && N0.getOpcode() == ISD::AND && N0.getNode()->hasOneUse() && isa(N0.getOperand(1))) { ConstantSDNode *C1 = cast(N0.getOperand(1)); - return DAG.getNode(ISD::AND, VT, DAG.getNode(ISD::OR, VT, N0.getOperand(0), - N1), - DAG.getConstant(N1C->getAPIntValue() | - C1->getAPIntValue(), VT)); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, + DAG.getNode(ISD::OR, N0.getDebugLoc(), VT, + N0.getOperand(0), N1), + DAG.FoldConstantArithmetic(ISD::OR, VT, N1C, C1)); } // fold (or (setcc x), (setcc y)) -> (setcc (or x, y)) if (isSetCCEquivalent(N0, LL, LR, CC0) && isSetCCEquivalent(N1, RL, RR, CC1)){ @@ -2019,21 +2019,23 @@ SDValue DAGCombiner::visitOR(SDNode *N) { if (LR == RR && isa(LR) && Op0 == Op1 && LL.getValueType().isInteger()) { - // fold (X != 0) | (Y != 0) -> (X|Y != 0) - // fold (X < 0) | (Y < 0) -> (X|Y < 0) + // fold (or (setne X, 0), (setne Y, 0)) -> (setne (or X, Y), 0) + // fold (or (setlt X, 0), (setlt Y, 0)) -> (setne (or X, Y), 0) if (cast(LR)->isNullValue() && (Op1 == ISD::SETNE || Op1 == ISD::SETLT)) { - SDValue ORNode = DAG.getNode(ISD::OR, LR.getValueType(), LL, RL); + SDValue ORNode = DAG.getNode(ISD::OR, LR.getDebugLoc(), + LR.getValueType(), LL, RL); AddToWorkList(ORNode.getNode()); - return DAG.getSetCC(VT, ORNode, LR, Op1); + return DAG.getSetCC(N->getDebugLoc(), VT, ORNode, LR, Op1); } - // fold (X != -1) | (Y != -1) -> (X&Y != -1) - // fold (X > -1) | (Y > -1) -> (X&Y > -1) + // fold (or (setne X, -1), (setne Y, -1)) -> (setne (and X, Y), -1) + // fold (or (setgt X, -1), (setgt Y -1)) -> (setgt (and X, Y), -1) if (cast(LR)->isAllOnesValue() && (Op1 == ISD::SETNE || Op1 == ISD::SETGT)) { - SDValue ANDNode = DAG.getNode(ISD::AND, LR.getValueType(), LL, RL); + SDValue ANDNode = DAG.getNode(ISD::AND, LR.getDebugLoc(), + LR.getValueType(), LL, RL); AddToWorkList(ANDNode.getNode()); - return DAG.getSetCC(VT, ANDNode, LR, Op1); + return DAG.getSetCC(N->getDebugLoc(), VT, ANDNode, LR, Op1); } } // canonicalize equivalent to ll == rl @@ -2046,17 +2048,18 @@ SDValue DAGCombiner::visitOR(SDNode *N) { ISD::CondCode Result = ISD::getSetCCOrOperation(Op0, Op1, isInteger); if (Result != ISD::SETCC_INVALID && (!LegalOperations || TLI.isCondCodeLegal(Result, LL.getValueType()))) - return DAG.getSetCC(N0.getValueType(), LL, LR, Result); + return DAG.getSetCC(N->getDebugLoc(), N0.getValueType(), + LL, LR, Result); } } - // Simplify: or (op x...), (op y...) -> (op (or x, y)) + // Simplify: (or (op x...), (op y...)) -> (op (or x, y)) if (N0.getOpcode() == N1.getOpcode()) { SDValue Tmp = SimplifyBinOpWithSameOpcodeHands(N); if (Tmp.getNode()) return Tmp; } - // (X & C1) | (Y & C2) -> (X|Y) & C3 if possible. + // (or (and X, C1), (and Y, C2)) -> (and (or X, Y), C3) if possible. if (N0.getOpcode() == ISD::AND && N1.getOpcode() == ISD::AND && N0.getOperand(1).getOpcode() == ISD::Constant && @@ -2072,12 +2075,13 @@ SDValue DAGCombiner::visitOR(SDNode *N) { if (DAG.MaskedValueIsZero(N0.getOperand(0), RHSMask&~LHSMask) && DAG.MaskedValueIsZero(N1.getOperand(0), LHSMask&~RHSMask)) { - SDValue X =DAG.getNode(ISD::OR, VT, N0.getOperand(0), N1.getOperand(0)); - return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(LHSMask|RHSMask, VT)); + SDValue X = DAG.getNode(ISD::OR, N0.getDebugLoc(), VT, + N0.getOperand(0), N1.getOperand(0)); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, X, + DAG.getConstant(LHSMask | RHSMask, VT)); } } - // See if this is some rotate idiom. if (SDNode *Rot = MatchRotate(N0, N1)) return SDValue(Rot, 0); @@ -2085,7 +2089,6 @@ SDValue DAGCombiner::visitOR(SDNode *N) { return SDValue(); } - /// MatchRotateHalf - Match "(X shl/srl V1) & V2" where V2 may not be present. static bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) { if (Op.getOpcode() == ISD::AND) { @@ -2101,10 +2104,10 @@ static bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) { Shift = Op; return true; } + return false; } - // MatchRotate - Handle an 'or' of two operands. If this is one of the many // idioms for rotate, and if the target supports rotation instructions, generate // a rot[lr]. -- GitLab From 35972a9460975bca008d3fe4a0736f725f67dc47 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 21:14:50 +0000 Subject: [PATCH 524/682] Propagate debug loc info for XOR and MatchRotate. llvm-svn: 63420 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 70 ++++++++++--------- 1 file changed, 38 insertions(+), 32 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 4973433b7206..a41d2a1a5a6c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -214,7 +214,7 @@ namespace { SDValue ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *, MVT); SDValue BuildSDIV(SDNode *N); SDValue BuildUDIV(SDNode *N); - SDNode *MatchRotate(SDValue LHS, SDValue RHS); + SDNode *MatchRotate(SDValue LHS, SDValue RHS, DebugLoc DL); SDValue ReduceLoadWidth(SDNode *N); SDValue GetDemandedBits(SDValue V, const APInt &Mask); @@ -2083,7 +2083,7 @@ SDValue DAGCombiner::visitOR(SDNode *N) { } // See if this is some rotate idiom. - if (SDNode *Rot = MatchRotate(N0, N1)) + if (SDNode *Rot = MatchRotate(N0, N1, N->getDebugLoc())) return SDValue(Rot, 0); return SDValue(); @@ -2111,7 +2111,7 @@ static bool MatchRotateHalf(SDValue Op, SDValue &Shift, SDValue &Mask) { // MatchRotate - Handle an 'or' of two operands. If this is one of the many // idioms for rotate, and if the target supports rotation instructions, generate // a rot[lr]. -SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { +SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, DebugLoc DL) { // Must be a legal type. Expanded 'n promoted things won't work with rotates. MVT VT = LHS.getValueType(); if (!TLI.isTypeLegal(VT)) return 0; @@ -2161,9 +2161,9 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { SDValue Rot; if (HasROTL) - Rot = DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt); + Rot = DAG.getNode(ISD::ROTL, DL, VT, LHSShiftArg, LHSShiftAmt); else - Rot = DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt); + Rot = DAG.getNode(ISD::ROTR, DL, VT, LHSShiftArg, RHSShiftAmt); // If there is an AND of either shifted operand, apply it to the result. if (LHSMask.getNode() || RHSMask.getNode()) { @@ -2178,7 +2178,7 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { Mask &= cast(RHSMask)->getAPIntValue() | LHSBits; } - Rot = DAG.getNode(ISD::AND, VT, Rot, DAG.getConstant(Mask, VT)); + Rot = DAG.getNode(ISD::AND, DL, VT, Rot, DAG.getConstant(Mask, VT)); } return Rot.getNode(); @@ -2197,9 +2197,11 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { dyn_cast(RHSShiftAmt.getOperand(0))) { if (SUBC->getAPIntValue() == OpSizeInBits) { if (HasROTL) - return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).getNode(); + return DAG.getNode(ISD::ROTL, DL, VT, + LHSShiftArg, LHSShiftAmt).getNode(); else - return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).getNode(); + return DAG.getNode(ISD::ROTR, DL, VT, + LHSShiftArg, RHSShiftAmt).getNode(); } } } @@ -2212,9 +2214,11 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { dyn_cast(LHSShiftAmt.getOperand(0))) { if (SUBC->getAPIntValue() == OpSizeInBits) { if (HasROTR) - return DAG.getNode(ISD::ROTR, VT, LHSShiftArg, RHSShiftAmt).getNode(); + return DAG.getNode(ISD::ROTR, DL, VT, + LHSShiftArg, RHSShiftAmt).getNode(); else - return DAG.getNode(ISD::ROTL, VT, LHSShiftArg, LHSShiftAmt).getNode(); + return DAG.getNode(ISD::ROTL, DL, VT, + LHSShiftArg, LHSShiftAmt).getNode(); } } } @@ -2239,7 +2243,8 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { if (ConstantSDNode *SUBC = dyn_cast(RExtOp0.getOperand(0))) { if (SUBC->getAPIntValue() == OpSizeInBits) { - return DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, VT, LHSShiftArg, + return DAG.getNode(HasROTL ? ISD::ROTL : ISD::ROTR, DL, VT, + LHSShiftArg, HasROTL ? LHSShiftAmt : RHSShiftAmt).getNode(); } } @@ -2252,7 +2257,8 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { if (ConstantSDNode *SUBC = dyn_cast(LExtOp0.getOperand(0))) { if (SUBC->getAPIntValue() == OpSizeInBits) { - return DAG.getNode(HasROTR ? ISD::ROTR : ISD::ROTL, VT, LHSShiftArg, + return DAG.getNode(HasROTR ? ISD::ROTR : ISD::ROTL, DL, VT, + LHSShiftArg, HasROTR ? RHSShiftAmt : LHSShiftAmt).getNode(); } } @@ -2262,7 +2268,6 @@ SDNode *DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS) { return 0; } - SDValue DAGCombiner::visitXOR(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -2290,7 +2295,7 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { return DAG.FoldConstantArithmetic(ISD::XOR, VT, N0C, N1C); // canonicalize constant to RHS if (N0C && !N1C) - return DAG.getNode(ISD::XOR, VT, N1, N0); + return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N1, N0); // fold (xor x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -2311,9 +2316,9 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { assert(0 && "Unhandled SetCC Equivalent!"); abort(); case ISD::SETCC: - return DAG.getSetCC(VT, LHS, RHS, NotCC); + return DAG.getSetCC(N->getDebugLoc(), VT, LHS, RHS, NotCC); case ISD::SELECT_CC: - return DAG.getSelectCC(LHS, RHS, N0.getOperand(2), + return DAG.getSelectCC(N->getDebugLoc(), LHS, RHS, N0.getOperand(2), N0.getOperand(3), NotCC); } } @@ -2324,47 +2329,47 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { N0.getNode()->hasOneUse() && isSetCCEquivalent(N0.getOperand(0), LHS, RHS, CC)){ SDValue V = N0.getOperand(0); - V = DAG.getNode(ISD::XOR, V.getValueType(), V, + V = DAG.getNode(ISD::XOR, N0.getDebugLoc(), V.getValueType(), V, DAG.getConstant(1, V.getValueType())); AddToWorkList(V.getNode()); - return DAG.getNode(ISD::ZERO_EXTEND, VT, V); + return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, V); } - // fold !(x or y) -> (!x and !y) iff x or y are setcc + // fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are setcc if (N1C && N1C->getAPIntValue() == 1 && VT == MVT::i1 && (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1); if (isOneUseSetCC(RHS) || isOneUseSetCC(LHS)) { unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND; - LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS - RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS + LHS = DAG.getNode(ISD::XOR, LHS.getDebugLoc(), VT, LHS, N1); // LHS = ~LHS + RHS = DAG.getNode(ISD::XOR, RHS.getDebugLoc(), VT, RHS, N1); // RHS = ~RHS AddToWorkList(LHS.getNode()); AddToWorkList(RHS.getNode()); - return DAG.getNode(NewOpcode, VT, LHS, RHS); + return DAG.getNode(NewOpcode, N->getDebugLoc(), VT, LHS, RHS); } } - // fold !(x or y) -> (!x and !y) iff x or y are constants + // fold (not (or x, y)) -> (and (not x), (not y)) iff x or y are constants if (N1C && N1C->isAllOnesValue() && (N0.getOpcode() == ISD::OR || N0.getOpcode() == ISD::AND)) { SDValue LHS = N0.getOperand(0), RHS = N0.getOperand(1); if (isa(RHS) || isa(LHS)) { unsigned NewOpcode = N0.getOpcode() == ISD::AND ? ISD::OR : ISD::AND; - LHS = DAG.getNode(ISD::XOR, VT, LHS, N1); // RHS = ~LHS - RHS = DAG.getNode(ISD::XOR, VT, RHS, N1); // RHS = ~RHS + LHS = DAG.getNode(ISD::XOR, LHS.getDebugLoc(), VT, LHS, N1); // LHS = ~LHS + RHS = DAG.getNode(ISD::XOR, RHS.getDebugLoc(), VT, RHS, N1); // RHS = ~RHS AddToWorkList(LHS.getNode()); AddToWorkList(RHS.getNode()); - return DAG.getNode(NewOpcode, VT, LHS, RHS); + return DAG.getNode(NewOpcode, N->getDebugLoc(), VT, LHS, RHS); } } - // fold (xor (xor x, c1), c2) -> (xor x, c1^c2) + // fold (xor (xor x, c1), c2) -> (xor x, (xor c1, c2)) if (N1C && N0.getOpcode() == ISD::XOR) { ConstantSDNode *N00C = dyn_cast(N0.getOperand(0)); ConstantSDNode *N01C = dyn_cast(N0.getOperand(1)); if (N00C) - return DAG.getNode(ISD::XOR, VT, N0.getOperand(1), - DAG.getConstant(N1C->getAPIntValue()^ + return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N0.getOperand(1), + DAG.getConstant(N1C->getAPIntValue() ^ N00C->getAPIntValue(), VT)); if (N01C) - return DAG.getNode(ISD::XOR, VT, N0.getOperand(0), - DAG.getConstant(N1C->getAPIntValue()^ + return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, N0.getOperand(0), + DAG.getConstant(N1C->getAPIntValue() ^ N01C->getAPIntValue(), VT)); } // fold (xor x, x) -> 0 @@ -2375,7 +2380,8 @@ SDValue DAGCombiner::visitXOR(SDNode *N) { // Produce a vector of zeros. SDValue El = DAG.getConstant(0, VT.getVectorElementType()); std::vector Ops(VT.getVectorNumElements(), El); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); + return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, + &Ops[0], Ops.size()); } } -- GitLab From 378e7fd330d9b0328fd2d20f6edab9006eb43dd3 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Fri, 30 Jan 2009 21:35:30 +0000 Subject: [PATCH 525/682] Fix horrible non-termination bug in LiveVariables. The issue was that the liveness state of block-level expressions could oscillate because of two issues: - The initial value before a merge was not always set to "Top" - The set of live block-level expressions is a union, not an intersection This fixes . llvm-svn: 63421 --- .../Analysis/FlowSensitive/DataflowSolver.h | 24 ++----------- .../Analysis/Support/BlkExprDeclBitVector.h | 8 +++-- clang/lib/Analysis/LiveVariables.cpp | 4 +-- clang/test/Analysis/rdar-6540084.m | 36 +++++++++++++++++++ 4 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 clang/test/Analysis/rdar-6540084.m diff --git a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h b/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h index 0ed4c8667f16..38612593368b 100644 --- a/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h +++ b/clang/include/clang/Analysis/FlowSensitive/DataflowSolver.h @@ -200,28 +200,9 @@ private: } } - void ResetValues(CFG& cfg, ValTy& V, const CFGBlock* B, - dataflow::forward_analysis_tag){ - - if (B == &cfg.getEntry()) - TF.SetTopValue(V); - else - V.resetValues(D.getAnalysisData()); - } - - void ResetValues(CFG& cfg, ValTy& V, const CFGBlock* B, - dataflow::backward_analysis_tag){ - - if (B == &cfg.getExit()) - TF.SetTopValue(V); - else - V.resetValues(D.getAnalysisData()); - } - void ProcessMerge(CFG& cfg, const CFGBlock* B) { - - ValTy& V = TF.getVal(); - ResetValues(cfg, V, B, AnalysisDirTag()); + ValTy& V = TF.getVal(); + TF.SetTopValue(V); // Merge dataflow values from all predecessors of this block. MergeOperatorTy Merge; @@ -287,7 +268,6 @@ private: /// UpdateEdgeValue - Update the value associated with a given edge. void UpdateEdgeValue(BlockEdge E, ValTy& V, const CFGBlock* TargetBlock) { - EdgeDataMapTy& M = D.getEdgeDataMap(); typename EdgeDataMapTy::iterator I = M.find(E); diff --git a/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h b/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h index 5bd42332ba32..a592be815419 100644 --- a/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h +++ b/clang/include/clang/Analysis/Support/BlkExprDeclBitVector.h @@ -216,8 +216,7 @@ struct StmtDeclBitVector_Types { } public: - - + void resetBlkExprValues(AnalysisDataTy& AD) { BlkExprBV.resize(AD.getNumBlkExprs()); BlkExprBV.reset(); @@ -233,6 +232,11 @@ struct StmtDeclBitVector_Types { resetBlkExprValues(AD); } + void setValues(AnalysisDataTy& AD) { + setDeclValues(AD); + setBlkExprValues(AD); + } + bool operator==(const ValTy& RHS) const { return ParentRef(*this) == ParentRef(RHS) && BlkExprBV == RHS.BlkExprBV; diff --git a/clang/lib/Analysis/LiveVariables.cpp b/clang/lib/Analysis/LiveVariables.cpp index 4c86d44e4db6..23f6f461aa13 100644 --- a/clang/lib/Analysis/LiveVariables.cpp +++ b/clang/lib/Analysis/LiveVariables.cpp @@ -130,7 +130,7 @@ public: void VisitTerminator(CFGBlock* B); void SetTopValue(LiveVariables::ValTy& V) { - V = AD.AlwaysLive; + V = AD.AlwaysLive; } }; @@ -300,7 +300,7 @@ struct Merge { void operator()(ValTy& Dst, const ValTy& Src) { Dst.OrDeclBits(Src); - Dst.AndBlkExprBits(Src); + Dst.OrBlkExprBits(Src); } }; diff --git a/clang/test/Analysis/rdar-6540084.m b/clang/test/Analysis/rdar-6540084.m new file mode 100644 index 000000000000..e1347d92eb53 --- /dev/null +++ b/clang/test/Analysis/rdar-6540084.m @@ -0,0 +1,36 @@ +// RUN: clang -analyze -warn-dead-stores -verify %s +// +// This test exercises the live variables analysis (LiveVariables.cpp). +// The case originally identified a non-termination bug. +// +typedef signed char BOOL; +typedef unsigned int NSUInteger; +typedef struct _NSZone NSZone; +@protocol NSObject - (BOOL)isEqual:(id)object; @end +@interface NSObject {} @end +extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone); +@class NSArray; +@class NSMutableArray, NSIndexSet, NSView, NSPredicate, NSString, NSViewAnimation, NSTimer; +@interface FooBazController : NSObject {} +@end +typedef struct {} TazVersion; +@class TazNode; +@interface TazGuttenberg : NSObject {} typedef NSUInteger BugsBunnyType; @end +@interface FooBaz : NSObject {} +@property (nonatomic) BugsBunnyType matchType; +@property (nonatomic, retain) NSArray *papyrus; @end +@implementation FooBazController +- (NSArray *)excitingStuff:(FooBaz *)options { + BugsBunnyType matchType = options.matchType; + NSPredicate *isSearchablePredicate = [NSPredicate predicateWithFormat:@"isSearchable == YES"]; // expected-warning{{return type defaults to 'id'}} + for (TazGuttenberg *Guttenberg in options.papyrus) { + NSArray *GuttenbergNodes = [Guttenberg nodes]; // expected-warning{{return type defaults to 'id'}} + NSArray *searchableNodes = [GuttenbergNodes filteredArrayUsingPredicate:isSearchablePredicate]; // expected-warning{{return type defaults to 'id'}} + for (TazNode *node in searchableNodes) { + switch (matchType) { + default: break; + } + } + } +} +@end -- GitLab From d51e3ff5402bd5e973de0ef7c5c4af2506567c6e Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 21:37:17 +0000 Subject: [PATCH 526/682] Propagate debug loc info for Shifts. llvm-svn: 63424 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 128 ++++++++++-------- 1 file changed, 68 insertions(+), 60 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index a41d2a1a5a6c..d7a44d8a05c5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2430,13 +2430,12 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { // We require the RHS of the binop to be a constant as well. ConstantSDNode *BinOpCst = dyn_cast(LHS->getOperand(1)); if (!BinOpCst) return SDValue(); - - - // FIXME: disable this for unless the input to the binop is a shift by a - // constant. If it is not a shift, it pessimizes some common cases like: + + // FIXME: disable this unless the input to the binop is a shift by a constant. + // If it is not a shift, it pessimizes some common cases like: // - //void foo(int *X, int i) { X[i & 1235] = 1; } - //int bar(int *X, int i) { return X[i & 255]; } + // void foo(int *X, int i) { X[i & 1235] = 1; } + // int bar(int *X, int i) { return X[i & 255]; } SDNode *BinOpLHSVal = LHS->getOperand(0).getNode(); if ((BinOpLHSVal->getOpcode() != ISD::SHL && BinOpLHSVal->getOpcode() != ISD::SRA && @@ -2446,11 +2445,10 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { MVT VT = N->getValueType(0); - // If this is a signed shift right, and the high bit is modified - // by the logical operation, do not perform the transformation. - // The highBitSet boolean indicates the value of the high bit of - // the constant which would cause it to be modified for this - // operation. + // If this is a signed shift right, and the high bit is modified by the + // logical operation, do not perform the transformation. The highBitSet + // boolean indicates the value of the high bit of the constant which would + // cause it to be modified for this operation. if (N->getOpcode() == ISD::SRA) { bool BinOpRHSSignSet = BinOpCst->getAPIntValue().isNegative(); if (BinOpRHSSignSet != HighBitSet) @@ -2458,18 +2456,18 @@ SDValue DAGCombiner::visitShiftByConstant(SDNode *N, unsigned Amt) { } // Fold the constants, shifting the binop RHS by the shift amount. - SDValue NewRHS = DAG.getNode(N->getOpcode(), N->getValueType(0), - LHS->getOperand(1), N->getOperand(1)); + SDValue NewRHS = DAG.getNode(N->getOpcode(), LHS->getOperand(1).getDebugLoc(), + N->getValueType(0), + LHS->getOperand(1), N->getOperand(1)); // Create the new shift. - SDValue NewShift = DAG.getNode(N->getOpcode(), VT, LHS->getOperand(0), - N->getOperand(1)); + SDValue NewShift = DAG.getNode(N->getOpcode(), LHS->getOperand(0).getDebugLoc(), + VT, LHS->getOperand(0), N->getOperand(1)); // Create the new binop. - return DAG.getNode(LHS->getOpcode(), VT, NewShift, NewRHS); + return DAG.getNode(LHS->getOpcode(), N->getDebugLoc(), VT, NewShift, NewRHS); } - SDValue DAGCombiner::visitSHL(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -2486,7 +2484,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { return N0; // fold (shl x, c >= size(x)) -> undef if (N1C && N1C->getZExtValue() >= OpSizeInBits) - return DAG.getNode(ISD::UNDEF, VT); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT); // fold (shl x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -2505,7 +2503,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { SDValue N100 = N1.getOperand(0).getOperand(0); uint64_t TruncC = TruncVT.getIntegerVTBitMask() & N101C->getZExtValue(); - return DAG.getNode(ISD::SHL, VT, N0, + return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, DAG.getNode(ISD::AND, TruncVT, DAG.getNode(ISD::TRUNCATE, TruncVT, N100), DAG.getConstant(TruncC, TruncVT))); @@ -2514,34 +2512,35 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { if (N1C && SimplifyDemandedBits(SDValue(N, 0))) return SDValue(N, 0); - // fold (shl (shl x, c1), c2) -> 0 or (shl x, c1+c2) + + // fold (shl (shl x, c1), c2) -> 0 or (shl x, (add c1, c2)) if (N1C && N0.getOpcode() == ISD::SHL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); if (c1 + c2 > OpSizeInBits) return DAG.getConstant(0, VT); - return DAG.getNode(ISD::SHL, VT, N0.getOperand(0), + return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); } - // fold (shl (srl x, c1), c2) -> (shl (and x, -1 << c1), c2-c1) or - // (srl (and x, -1 << c1), c1-c2) + // fold (shl (srl x, c1), c2) -> (shl (and x, (shl -1, c1)), (sub c2, c1)) or + // (srl (and x, (shl -1, c1)), (sub c1, c2)) if (N1C && N0.getOpcode() == ISD::SRL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); - SDValue Mask = DAG.getNode(ISD::AND, VT, N0.getOperand(0), - DAG.getConstant(~0ULL << c1, VT)); + SDValue Mask = DAG.getNode(ISD::AND, N0.getDebugLoc(), VT, N0.getOperand(0), + DAG.getConstant(~0ULL << c1, VT)); if (c2 > c1) - return DAG.getNode(ISD::SHL, VT, Mask, + return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, Mask, DAG.getConstant(c2-c1, N1.getValueType())); else - return DAG.getNode(ISD::SRL, VT, Mask, + return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, Mask, DAG.getConstant(c1-c2, N1.getValueType())); } - // fold (shl (sra x, c1), c1) -> (and x, -1 << c1) + // fold (shl (sra x, c1), c1) -> (and x, (shl -1, c1)) if (N1C && N0.getOpcode() == ISD::SRA && N1 == N0.getOperand(1)) - return DAG.getNode(ISD::AND, VT, N0.getOperand(0), + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(~0ULL << N1C->getZExtValue(), VT)); return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue(); @@ -2554,7 +2553,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { ConstantSDNode *N1C = dyn_cast(N1); MVT VT = N0.getValueType(); - // fold (sra c1, c2) -> c1>>c2 + // fold (sra c1, c2) -> (sra c1, c2) if (N0C && N1C) return DAG.FoldConstantArithmetic(ISD::SRA, VT, N0C, N1C); // fold (sra 0, x) -> 0 @@ -2563,9 +2562,9 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { // fold (sra -1, x) -> -1 if (N0C && N0C->isAllOnesValue()) return N0; - // fold (sra x, c >= size(x)) -> undef + // fold (sra x, (setge c, size(x))) -> undef if (N1C && N1C->getZExtValue() >= VT.getSizeInBits()) - return DAG.getNode(ISD::UNDEF, VT); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT); // fold (sra x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -2575,22 +2574,22 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { unsigned LowBits = VT.getSizeInBits() - (unsigned)N1C->getZExtValue(); MVT EVT = MVT::getIntegerVT(LowBits); if ((!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, EVT))) - return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), - DAG.getValueType(EVT)); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, + N0.getOperand(0), DAG.getValueType(EVT)); } - // fold (sra (sra x, c1), c2) -> (sra x, c1+c2) + // fold (sra (sra x, c1), c2) -> (sra x, (add c1, c2)) if (N1C && N0.getOpcode() == ISD::SRA) { if (ConstantSDNode *C1 = dyn_cast(N0.getOperand(1))) { unsigned Sum = N1C->getZExtValue() + C1->getZExtValue(); if (Sum >= VT.getSizeInBits()) Sum = VT.getSizeInBits()-1; - return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), + return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(Sum, N1C->getValueType(0))); } } - // fold sra (shl X, m), result_size - n - // -> (sign_extend (trunc (shl X, result_size - n - m))) for + // fold (sra (shl X, m), (sub result_size, n)) + // -> (sign_extend (trunc (shl X, (sub (sub result_size, n), m)))) for // result_size - n != m. // If truncate is free for the target sext(shl) is likely to result in better // code. @@ -2615,9 +2614,12 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { TLI.isTruncateFree(VT, TruncVT)) { SDValue Amt = DAG.getConstant(ShiftAmt, TLI.getShiftAmountTy()); - SDValue Shift = DAG.getNode(ISD::SRL, VT, N0.getOperand(0), Amt); - SDValue Trunc = DAG.getNode(ISD::TRUNCATE, TruncVT, Shift); - return DAG.getNode(ISD::SIGN_EXTEND, N->getValueType(0), Trunc); + SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, + N0.getOperand(0), Amt); + SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), TruncVT, + Shift); + return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), + N->getValueType(0), Trunc); } } } @@ -2633,8 +2635,9 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { SDValue N100 = N1.getOperand(0).getOperand(0); uint64_t TruncC = TruncVT.getIntegerVTBitMask() & N101C->getZExtValue(); - return DAG.getNode(ISD::SRA, VT, N0, - DAG.getNode(ISD::AND, TruncVT, + return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0, + DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), + TruncVT, DAG.getNode(ISD::TRUNCATE, TruncVT, N100), DAG.getConstant(TruncC, TruncVT))); } @@ -2647,7 +2650,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { // If the sign bit is known to be zero, switch this to a SRL. if (DAG.SignBitIsZero(N0)) - return DAG.getNode(ISD::SRL, VT, N0, N1); + return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, N1); return N1C ? visitShiftByConstant(N, N1C->getZExtValue()) : SDValue(); } @@ -2668,7 +2671,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { return N0; // fold (srl x, c >= size(x)) -> undef if (N1C && N1C->getZExtValue() >= OpSizeInBits) - return DAG.getNode(ISD::UNDEF, VT); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT); // fold (srl x, 0) -> x if (N1C && N1C->isNullValue()) return N0; @@ -2677,14 +2680,14 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { APInt::getAllOnesValue(OpSizeInBits))) return DAG.getConstant(0, VT); - // fold (srl (srl x, c1), c2) -> 0 or (srl x, c1+c2) + // fold (srl (srl x, c1), c2) -> 0 or (srl x, (add c1, c2)) if (N1C && N0.getOpcode() == ISD::SRL && N0.getOperand(1).getOpcode() == ISD::Constant) { uint64_t c1 = cast(N0.getOperand(1))->getZExtValue(); uint64_t c2 = N1C->getZExtValue(); if (c1 + c2 > OpSizeInBits) return DAG.getConstant(0, VT); - return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), + return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getConstant(c1 + c2, N1.getValueType())); } @@ -2693,18 +2696,19 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { // Shifting in all undef bits? MVT SmallVT = N0.getOperand(0).getValueType(); if (N1C->getZExtValue() >= SmallVT.getSizeInBits()) - return DAG.getNode(ISD::UNDEF, VT); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), VT); - SDValue SmallShift = DAG.getNode(ISD::SRL, SmallVT, N0.getOperand(0), N1); + SDValue SmallShift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), SmallVT, + N0.getOperand(0), N1); AddToWorkList(SmallShift.getNode()); - return DAG.getNode(ISD::ANY_EXTEND, VT, SmallShift); + return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, SmallShift); } // fold (srl (sra X, Y), 31) -> (srl X, 31). This srl only looks at the sign // bit, which is unmodified by sra. - if (N1C && N1C->getZExtValue()+1 == VT.getSizeInBits()) { + if (N1C && N1C->getZExtValue() + 1 == VT.getSizeInBits()) { if (N0.getOpcode() == ISD::SRA) - return DAG.getNode(ISD::SRL, VT, N0.getOperand(0), N1); + return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0.getOperand(0), N1); } // fold (srl (ctlz x), "5") -> x iff x has one bit set (the low bit). @@ -2724,19 +2728,22 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (UnknownBits == 0) return DAG.getConstant(1, VT); // Otherwise, check to see if there is exactly one bit input to the ctlz. - if ((UnknownBits & (UnknownBits-1)) == 0) { + if ((UnknownBits & (UnknownBits - 1)) == 0) { // Okay, we know that only that the single bit specified by UnknownBits - // could be set on input to the CTLZ node. If this bit is set, the SRL - // will return 0, if it is clear, it returns 1. Change the CTLZ/SRL pair - // to an SRL,XOR pair, which is likely to simplify more. + // could be set on input to the CTLZ node. If this bit is set, the SRL + // will return 0, if it is clear, it returns 1. Change the CTLZ/SRL pair + // to an SRL/XOR pair, which is likely to simplify more. unsigned ShAmt = UnknownBits.countTrailingZeros(); SDValue Op = N0.getOperand(0); + if (ShAmt) { - Op = DAG.getNode(ISD::SRL, VT, Op, + Op = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, Op, DAG.getConstant(ShAmt, TLI.getShiftAmountTy())); AddToWorkList(Op.getNode()); } - return DAG.getNode(ISD::XOR, VT, Op, DAG.getConstant(1, VT)); + + return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, + Op, DAG.getConstant(1, VT)); } } @@ -2751,8 +2758,9 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { SDValue N100 = N1.getOperand(0).getOperand(0); uint64_t TruncC = TruncVT.getIntegerVTBitMask() & N101C->getZExtValue(); - return DAG.getNode(ISD::SRL, VT, N0, - DAG.getNode(ISD::AND, TruncVT, + return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, + DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), + TruncVT, DAG.getNode(ISD::TRUNCATE, TruncVT, N100), DAG.getConstant(TruncC, TruncVT))); } -- GitLab From c35dca92f58d3ec452b62eb071c22ae0a834b387 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 30 Jan 2009 21:50:20 +0000 Subject: [PATCH 527/682] x86_64 ABI: Fix thinko in prev commit, 64-bit vectors should have SSE class, not integer. llvm-svn: 63426 --- clang/lib/CodeGen/CGCall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index cf4f60e36659..ba27200f2c1c 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -527,7 +527,7 @@ void X86_64ABIInfo::classify(QualType Ty, return; } - Lo = Integer; + Lo = SSE; // If this type crosses an eightbyte boundary, it should be // split. -- GitLab From b6b6f46fe4a3fcc7df7546499122e24e7b5020f5 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:02:18 +0000 Subject: [PATCH 528/682] - Propagate debug loc info for SELECT. - Added xform for (select X, 1, Y) and (select X, Y, 0), which was commented on, but missing. llvm-svn: 63428 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 57 +++++++++++-------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d7a44d8a05c5..736e08cd925f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2780,7 +2780,7 @@ SDValue DAGCombiner::visitCTLZ(SDNode *N) { // fold (ctlz c1) -> c2 if (isa(N0)) - return DAG.getNode(ISD::CTLZ, VT, N0); + return DAG.getNode(ISD::CTLZ, N->getDebugLoc(), VT, N0); return SDValue(); } @@ -2790,7 +2790,7 @@ SDValue DAGCombiner::visitCTTZ(SDNode *N) { // fold (cttz c1) -> c2 if (isa(N0)) - return DAG.getNode(ISD::CTTZ, VT, N0); + return DAG.getNode(ISD::CTTZ, N->getDebugLoc(), VT, N0); return SDValue(); } @@ -2800,7 +2800,7 @@ SDValue DAGCombiner::visitCTPOP(SDNode *N) { // fold (ctpop c1) -> c2 if (isa(N0)) - return DAG.getNode(ISD::CTPOP, VT, N0); + return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), VT, N0); return SDValue(); } @@ -2814,53 +2814,58 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { MVT VT = N->getValueType(0); MVT VT0 = N0.getValueType(); - // fold select C, X, X -> X + // fold (select C, X, X) -> X if (N1 == N2) return N1; - // fold select true, X, Y -> X + // fold (select true, X, Y) -> X if (N0C && !N0C->isNullValue()) return N1; - // fold select false, X, Y -> Y + // fold (select false, X, Y) -> Y if (N0C && N0C->isNullValue()) return N2; - // fold select C, 1, X -> C | X + // fold (select C, 1, X) -> (or C, X) if (VT == MVT::i1 && N1C && N1C->getAPIntValue() == 1) - return DAG.getNode(ISD::OR, VT, N0, N2); - // fold select C, 0, 1 -> C ^ 1 + return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N2); + // fold (select C, 0, 1) -> (xor C, 1) if (VT.isInteger() && (VT0 == MVT::i1 || (VT0.isInteger() && TLI.getBooleanContents() == TargetLowering::ZeroOrOneBooleanContent)) && N1C && N2C && N1C->isNullValue() && N2C->getAPIntValue() == 1) { - SDValue XORNode = DAG.getNode(ISD::XOR, VT0, N0, DAG.getConstant(1, VT0)); + SDValue XORNode; if (VT == VT0) - return XORNode; + return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT0, + N0, DAG.getConstant(1, VT0)); + XORNode = DAG.getNode(ISD::XOR, N0.getDebugLoc(), VT0, + N0, DAG.getConstant(1, VT0)); AddToWorkList(XORNode.getNode()); if (VT.bitsGT(VT0)) - return DAG.getNode(ISD::ZERO_EXTEND, VT, XORNode); - return DAG.getNode(ISD::TRUNCATE, VT, XORNode); + return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, XORNode); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, XORNode); } - // fold select C, 0, X -> ~C & X + // fold (select C, 0, X) -> (and (not C), X) if (VT == VT0 && VT == MVT::i1 && N1C && N1C->isNullValue()) { SDValue NOTNode = DAG.getNOT(N0, VT); AddToWorkList(NOTNode.getNode()); return DAG.getNode(ISD::AND, VT, NOTNode, N2); } - // fold select C, X, 1 -> ~C | X + // fold (select C, X, 1) -> (or (not C), X) if (VT == VT0 && VT == MVT::i1 && N2C && N2C->getAPIntValue() == 1) { - SDValue NOTNode = DAG.getNOT(N0, VT); + SDValue NOTNode = DAG.getNOT(N0.getDebugLoc(), N0, VT); AddToWorkList(NOTNode.getNode()); return DAG.getNode(ISD::OR, VT, NOTNode, N1); } - // fold select C, X, 0 -> C & X + // fold (select C, X, 0) -> (and C, X) if (VT == MVT::i1 && N2C && N2C->isNullValue()) - return DAG.getNode(ISD::AND, VT, N0, N1); - // fold X ? X : Y --> X ? 1 : Y --> X | Y - if (VT == MVT::i1 && N0 == N1) - return DAG.getNode(ISD::OR, VT, N0, N2); - // fold X ? Y : X --> X ? Y : 0 --> X & Y - if (VT == MVT::i1 && N0 == N2) - return DAG.getNode(ISD::AND, VT, N0, N1); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0, N1); + // fold (select X, X, Y) -> (or X, Y) + // fold (select X, 1, Y) -> (or X, Y) + if (VT == MVT::i1 && (N0 == N1 || (N1C && N1C->getAPIntValue() == 1))) + return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, N0, N2); + // fold (select X, Y, X) -> (and X, Y) + // fold (select X, Y, 0) -> (and X, Y) + if (VT == MVT::i1 && (N0 == N2 || (N2C && N2C->getAPIntValue() == 0))) + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N0, N1); // If we can fold this based on the true/false value, do so. if (SimplifySelectOps(N, N1, N2)) @@ -2873,11 +2878,13 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { // having to say they don't support SELECT_CC on every type the DAG knows // about, since there is no way to mark an opcode illegal at all value types if (TLI.isOperationLegalOrCustom(ISD::SELECT_CC, MVT::Other)) - return DAG.getNode(ISD::SELECT_CC, VT, N0.getOperand(0), N0.getOperand(1), + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), VT, + N0.getOperand(0), N0.getOperand(1), N1, N2, N0.getOperand(2)); else return SimplifySelect(N0, N1, N2); } + return SDValue(); } -- GitLab From fa57e8e7abde3c0473096b6b7b85215e7817d109 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 30 Jan 2009 22:07:48 +0000 Subject: [PATCH 529/682] add imag_info section and data (for objc2 nonfragile abi). llvm-svn: 63430 --- clang/lib/CodeGen/CGObjCMac.cpp | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 67ef1ae0e830..14b39cb13b74 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3197,6 +3197,23 @@ void CGObjCNonFragileABIMac::FinishNonFragileABIModule() { UsedGlobals.push_back(GV); } + // static int L_OBJC_IMAGE_INFO[2] = { 0, flags }; + // FIXME. flags can be 0 | 1 | 2 | 6. For now just use 0 + std::vector Values(2); + Values[0] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); + Values[1] = llvm::ConstantInt::get(ObjCTypes.IntTy, 0); + llvm::Constant* Init = llvm::ConstantArray::get( + llvm::ArrayType::get(ObjCTypes.IntTy, 2), + Values); + llvm::GlobalVariable *IMGV = + new llvm::GlobalVariable(Init->getType(), false, + llvm::GlobalValue::InternalLinkage, + Init, + "\01L_OBJC_IMAGE_INFO", + &CGM.getModule()); + IMGV->setSection("__DATA, __objc_imageinfo, regular, no_dead_strip"); + UsedGlobals.push_back(IMGV); + std::vector Used; for (std::vector::iterator i = UsedGlobals.begin(), e = UsedGlobals.end(); i != e; ++i) { @@ -3361,8 +3378,6 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( &CGM.getModule()); GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); - // FIXME! why? - GV->setAlignment(32); return GV; } @@ -3836,8 +3851,6 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocolRef( &CGM.getModule()); Entry->setSection("__DATA,__datacoal_nt,coalesced"); UsedGlobals.push_back(Entry); - // FIXME: Is this necessary? Why only for protocol? - Entry->setAlignment(4); } return Entry; @@ -3941,8 +3954,6 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName, &CGM.getModule()); Entry->setSection("__DATA,__datacoal_nt,coalesced"); - // FIXME: Is this necessary? Why only for protocol? - Entry->setAlignment(4); } Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); -- GitLab From d14247a9e5800268d3b0757fa32f0b8bdfb6f859 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 30 Jan 2009 22:09:00 +0000 Subject: [PATCH 530/682] Implement and test aggregate initialization in C++. Major changes: - Support initialization of reference members; complain if any reference members are left uninitialized. - Use C++ copy-initialization for initializing each element (falls back to constraint checking in C) - Make sure we diagnose when one tries to provide an initializer list for a non-aggregate. - Don't complain about empty initializers in C++ (they are permitted) - Unrelated but necessary: don't bother trying to convert the decl-specifier-seq to a type when we're dealing with a C++ constructor, destructor, or conversion operator; it results in spurious warnings. llvm-svn: 63431 --- .../clang/Basic/DiagnosticSemaKinds.def | 4 + clang/lib/Parse/ParseInit.cpp | 6 +- clang/lib/Sema/SemaDecl.cpp | 18 +- clang/lib/Sema/SemaInit.cpp | 186 +++++++++++++++--- clang/lib/Sema/SemaType.cpp | 30 ++- clang/test/SemaCXX/dcl_init_aggr.cpp | 107 ++++++++++ clang/www/cxx_status.html | 9 +- 7 files changed, 304 insertions(+), 56 deletions(-) create mode 100644 clang/test/SemaCXX/dcl_init_aggr.cpp diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index 8cafa318f0e4..6e31de631719 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -270,6 +270,10 @@ DIAG(err_const_var_requires_init, ERROR, "declaration of const variable '%0' requires an initializer") DIAG(err_init_non_aggr_init_list, ERROR, "initialization of non-aggregate type %0 with an initializer list") +DIAG(err_init_reference_member_uninitialized, ERROR, + "reference member of type %0 uninitialized") +DIAG(note_uninit_reference_member, NOTE, + "uninitialized reference member is here") // Objective-C++ DIAG(err_objc_decls_may_only_appear_in_global_scope, ERROR, diff --git a/clang/lib/Parse/ParseInit.cpp b/clang/lib/Parse/ParseInit.cpp index c654a750ddd6..ec8470cb45d8 100644 --- a/clang/lib/Parse/ParseInit.cpp +++ b/clang/lib/Parse/ParseInit.cpp @@ -256,10 +256,10 @@ Parser::OwningExprResult Parser::ParseBraceInitializer() { /// was specified for it, if any. InitListDesignations InitExprDesignations(Actions); - // We support empty initializers, but tell the user that they aren't using - // C99-clean code. if (Tok.is(tok::r_brace)) { - Diag(LBraceLoc, diag::ext_gnu_empty_initializer); + // Empty initializers are a C++ feature and a GNU extension to C. + if (!getLang().CPlusPlus) + Diag(LBraceLoc, diag::ext_gnu_empty_initializer); // Match the '}'. return Actions.ActOnInitList(LBraceLoc, Action::MultiExprArg(Actions), InitExprDesignations, ConsumeBrace()); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 3395313f84cd..5dd45fb072d9 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1074,23 +1074,7 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType, << Init->getSourceRange(); return CheckSingleInitializer(Init, DeclType, DirectInit); - } else if (getLangOptions().CPlusPlus) { - // C++ [dcl.init]p14: - // [...] If the class is an aggregate (8.5.1), and the initializer - // is a brace-enclosed list, see 8.5.1. - // - // Note: 8.5.1 is handled below; here, we diagnose the case where - // we have an initializer list and a destination type that is not - // an aggregate. - // FIXME: In C++0x, this is yet another form of initialization. - // FIXME: Move this checking into CheckInitList! - if (const RecordType *ClassRec = DeclType->getAsRecordType()) { - const CXXRecordDecl *ClassDecl = cast(ClassRec->getDecl()); - if (!ClassDecl->isAggregate()) - return Diag(InitLoc, diag::err_init_non_aggr_init_list) - << DeclType << Init->getSourceRange(); - } - } + } bool hadError = CheckInitList(InitList, DeclType); Init = InitList; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index ed44acff7ee9..5d40e43039ac 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -69,11 +69,14 @@ class InitListChecker { unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex); - // FIXME: Does DeclType need to be a reference type? - void CheckScalarType(InitListExpr *IList, QualType &DeclType, + void CheckScalarType(InitListExpr *IList, QualType DeclType, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex); + void CheckReferenceType(InitListExpr *IList, QualType DeclType, + unsigned &Index, + InitListExpr *StructuredList, + unsigned &StructuredIndex); void CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex); @@ -106,6 +109,8 @@ class InitListChecker { Expr *expr); int numArrayElements(QualType DeclType); int numStructUnionElements(QualType DeclType); + + void FillInValueInitializations(InitListExpr *ILE); public: InitListChecker(Sema *S, InitListExpr *IL, QualType &T); bool HadError() { return hadError; } @@ -116,12 +121,12 @@ public: }; } - /// Recursively replaces NULL values within the given initializer list /// with expressions that perform value-initialization of the /// appropriate type. -static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) { - assert((ILE->getType() != Context.VoidTy) && "Should not have void type"); +void InitListChecker::FillInValueInitializations(InitListExpr *ILE) { + assert((ILE->getType() != SemaRef->Context.VoidTy) && + "Should not have void type"); if (const RecordType *RType = ILE->getType()->getAsRecordType()) { unsigned Init = 0, NumInits = ILE->getNumInits(); for (RecordDecl::field_iterator Field = RType->getDecl()->field_begin(), @@ -130,17 +135,31 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) { if (Field->isUnnamedBitfield()) continue; - if (Init >= NumInits) - break; - - // FIXME: Check for fields with reference type in C++? - if (!ILE->getInit(Init)) + if (Init >= NumInits) { + if (Field->getType()->isReferenceType()) { + // C++ [dcl.init.aggr]p9: + // If an incomplete or empty initializer-list leaves a + // member of reference type uninitialized, the program is + // ill-formed. + SemaRef->Diag(ILE->getSyntacticForm()->getLocStart(), + diag::err_init_reference_member_uninitialized) + << Field->getType() + << ILE->getSyntacticForm()->getSourceRange(); + SemaRef->Diag(Field->getLocation(), + diag::note_uninit_reference_member); + hadError = true; + } + } else if (!ILE->getInit(Init)) ILE->setInit(Init, - new (Context) ImplicitValueInitExpr(Field->getType())); + new (SemaRef->Context) ImplicitValueInitExpr(Field->getType())); else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init))) - fillInValueInitializations(Context, InnerILE); + FillInValueInitializations(InnerILE); ++Init; + + // Only look at the first initialization of a union. + if (RType->getDecl()->isUnion()) + break; } return; @@ -148,7 +167,7 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) { QualType ElementType; - if (const ArrayType *AType = Context.getAsArrayType(ILE->getType())) + if (const ArrayType *AType = SemaRef->Context.getAsArrayType(ILE->getType())) ElementType = AType->getElementType(); else if (const VectorType *VType = ILE->getType()->getAsVectorType()) ElementType = VType->getElementType(); @@ -158,9 +177,10 @@ static void fillInValueInitializations(ASTContext &Context, InitListExpr *ILE) { for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; ++Init) { if (!ILE->getInit(Init)) - ILE->setInit(Init, new (Context) ImplicitValueInitExpr(ElementType)); + ILE->setInit(Init, + new (SemaRef->Context) ImplicitValueInitExpr(ElementType)); else if (InitListExpr *InnerILE =dyn_cast(ILE->getInit(Init))) - fillInValueInitializations(Context, InnerILE); + FillInValueInitializations(InnerILE); } } @@ -175,9 +195,8 @@ InitListChecker::InitListChecker(Sema *S, InitListExpr *IL, QualType &T) { = getStructuredSubobjectInit(IL, newIndex, T, 0, 0, SourceRange()); CheckExplicitInitList(IL, T, newIndex, FullyStructuredList, newStructuredIndex); - if (!hadError) { - fillInValueInitializations(SemaRef->Context, FullyStructuredList); - } + if (!hadError) + FillInValueInitializations(FullyStructuredList); } int InitListChecker::numArrayElements(QualType DeclType) { @@ -219,7 +238,6 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList, else assert(0 && "CheckImplicitInitList(): Illegal type"); - // FIXME: Perhaps we should move this warning elsewhere? if (maxElements == 0) { SemaRef->Diag(ParentIList->getInit(Index)->getLocStart(), diag::err_implicit_empty_initializer); @@ -308,6 +326,20 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList, SemaRef->Diag(IList->getLocStart(), diag::err_illegal_initializer_type) << DeclType; hadError = true; + } else if (DeclType->isRecordType()) { + // C++ [dcl.init]p14: + // [...] If the class is an aggregate (8.5.1), and the initializer + // is a brace-enclosed list, see 8.5.1. + // + // Note: 8.5.1 is handled below; here, we diagnose the case where + // we have an initializer list and a destination type that is not + // an aggregate. + // FIXME: In C++0x, this is yet another form of initialization. + SemaRef->Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list) + << DeclType << IList->getSourceRange(); + hadError = true; + } else if (DeclType->isReferenceType()) { + CheckReferenceType(IList, DeclType, Index, StructuredList, StructuredIndex); } else { // In C, all types are either scalars or aggregates, but // additional handling is needed here for C++ (and possibly others?). @@ -339,21 +371,70 @@ void InitListChecker::CheckSubElementType(InitListExpr *IList, ++Index; } else if (ElemType->isScalarType()) { CheckScalarType(IList, ElemType, Index, StructuredList, StructuredIndex); - } else if (expr->getType()->getAsRecordType() && - SemaRef->Context.typesAreCompatible( - expr->getType().getUnqualifiedType(), - ElemType.getUnqualifiedType())) { - UpdateStructuredListElement(StructuredList, StructuredIndex, expr); - ++Index; - // FIXME: Add checking + } else if (ElemType->isReferenceType()) { + CheckReferenceType(IList, ElemType, Index, StructuredList, StructuredIndex); } else { - CheckImplicitInitList(IList, ElemType, Index, StructuredList, - StructuredIndex); - ++StructuredIndex; - } + if (SemaRef->getLangOptions().CPlusPlus) { + // C++ [dcl.init.aggr]p12: + // All implicit type conversions (clause 4) are considered when + // initializing the aggregate member with an ini- tializer from + // an initializer-list. If the initializer can initialize a + // member, the member is initialized. [...] + ImplicitConversionSequence ICS + = SemaRef->TryCopyInitialization(expr, ElemType); + if (ICS.ConversionKind != ImplicitConversionSequence::BadConversion) { + if (SemaRef->PerformImplicitConversion(expr, ElemType, ICS, + "initializing")) + hadError = true; + UpdateStructuredListElement(StructuredList, StructuredIndex, expr); + ++Index; + return; + } + + // Fall through for subaggregate initialization + } else { + // C99 6.7.8p13: + // + // The initializer for a structure or union object that has + // automatic storage duration shall be either an initializer + // list as described below, or a single expression that has + // compatible structure or union type. In the latter case, the + // initial value of the object, including unnamed members, is + // that of the expression. + QualType ExprType = SemaRef->Context.getCanonicalType(expr->getType()); + QualType ElemTypeCanon = SemaRef->Context.getCanonicalType(ElemType); + if (SemaRef->Context.typesAreCompatible(ExprType.getUnqualifiedType(), + ElemTypeCanon.getUnqualifiedType())) { + UpdateStructuredListElement(StructuredList, StructuredIndex, expr); + ++Index; + return; + } + + // Fall through for subaggregate initialization + } + + // C++ [dcl.init.aggr]p12: + // + // [...] Otherwise, if the member is itself a non-empty + // subaggregate, brace elision is assumed and the initializer is + // considered for the initialization of the first member of + // the subaggregate. + if (ElemType->isAggregateType() || ElemType->isVectorType()) { + CheckImplicitInitList(IList, ElemType, Index, StructuredList, + StructuredIndex); + ++StructuredIndex; + } else { + // We cannot initialize this element, so let + // PerformCopyInitialization produce the appropriate diagnostic. + SemaRef->PerformCopyInitialization(expr, ElemType, "initializing"); + hadError = true; + ++Index; + ++StructuredIndex; + } + } } -void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType, +void InitListChecker::CheckScalarType(InitListExpr *IList, QualType DeclType, unsigned &Index, InitListExpr *StructuredList, unsigned &StructuredIndex) { @@ -399,6 +480,49 @@ void InitListChecker::CheckScalarType(InitListExpr *IList, QualType &DeclType, } } +void InitListChecker::CheckReferenceType(InitListExpr *IList, QualType DeclType, + unsigned &Index, + InitListExpr *StructuredList, + unsigned &StructuredIndex) { + if (Index < IList->getNumInits()) { + Expr *expr = IList->getInit(Index); + if (isa(expr)) { + SemaRef->Diag(IList->getLocStart(), diag::err_init_non_aggr_init_list) + << DeclType << IList->getSourceRange(); + hadError = true; + ++Index; + ++StructuredIndex; + return; + } + + Expr *savExpr = expr; // Might be promoted by CheckSingleInitializer. + if (SemaRef->CheckReferenceInit(expr, DeclType)) + hadError = true; + else if (savExpr != expr) { + // The type was promoted, update initializer list. + IList->setInit(Index, expr); + } + if (hadError) + ++StructuredIndex; + else + UpdateStructuredListElement(StructuredList, StructuredIndex, expr); + ++Index; + } else { + // FIXME: It would be wonderful if we could point at the actual + // member. In general, it would be useful to pass location + // information down the stack, so that we know the location (or + // decl) of the "current object" being initialized. + SemaRef->Diag(IList->getLocStart(), + diag::err_init_reference_member_uninitialized) + << DeclType + << IList->getSourceRange(); + hadError = true; + ++Index; + ++StructuredIndex; + return; + } +} + void InitListChecker::CheckVectorType(InitListExpr *IList, QualType DeclType, unsigned &Index, InitListExpr *StructuredList, diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 43f8baae507d..9d78d0adbf95 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -18,8 +18,11 @@ #include "clang/Parse/DeclSpec.h" using namespace clang; -/// ConvertDeclSpecToType - Convert the specified declspec to the appropriate -/// type object. This returns null on error. +/// \brief Convert the specified declspec to the appropriate type +/// object. +/// \param DS the declaration specifiers +/// \returns The type described by the declaration specifiers, or NULL +/// if there was an error. QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { // FIXME: Should move the logic from DeclSpec::Finish to here for validity // checking. @@ -81,6 +84,7 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) { // "At least one type specifier shall be given in the declaration // specifiers in each declaration, and in the specifier-qualifier list in // each struct declaration and type name." + // FIXME: this should be a hard error in C++ if (!DS.hasTypeSpecifier()) Diag(DS.getSourceRange().getBegin(), diag::ext_missing_type_specifier); } @@ -254,8 +258,26 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { if (!getLangOptions().C99 && !getLangOptions().CPlusPlus0x && D.getDeclSpec().getTypeSpecWidth() == DeclSpec::TSW_longlong) Diag(D.getDeclSpec().getTypeSpecWidthLoc(), diag::ext_longlong); - - QualType T = ConvertDeclSpecToType(D.getDeclSpec()); + + // Determine the type of the declarator. Not all forms of declarator + // have a type. + QualType T; + switch (D.getKind()) { + case Declarator::DK_Abstract: + case Declarator::DK_Normal: + case Declarator::DK_Operator: + T = ConvertDeclSpecToType(D.getDeclSpec()); + break; + + case Declarator::DK_Constructor: + case Declarator::DK_Destructor: + case Declarator::DK_Conversion: + // Constructors and destructors don't have return types. Use + // "void" instead. Conversion operators will check their return + // types separately. + T = Context.VoidTy; + break; + } // Walk the DeclTypeInfo, building the recursive type as we go. DeclTypeInfos // are ordered from the identifier out, which is opposite of what we want :). diff --git a/clang/test/SemaCXX/dcl_init_aggr.cpp b/clang/test/SemaCXX/dcl_init_aggr.cpp new file mode 100644 index 000000000000..d8a41805365f --- /dev/null +++ b/clang/test/SemaCXX/dcl_init_aggr.cpp @@ -0,0 +1,107 @@ +// RUN: clang -fsyntax-only -pedantic -verify %s +// C++ [dcl.init.aggr]p2 +struct A { + int x; + struct B { + int i; + int j; + } b; +} a1 = { 1, { 2, 3 } }; + +struct NonAggregate { + NonAggregate(); + + int a, b; +}; +NonAggregate non_aggregate_test = { 1, 2 }; // expected-error{{initialization of non-aggregate type 'struct NonAggregate' with an initializer list}} + +NonAggregate non_aggregate_test2[2] = { { 1, 2 }, { 3, 4 } }; // expected-error{{initialization of non-aggregate type 'struct NonAggregate' with an initializer list}} + + +// C++ [dcl.init.aggr]p3 +A a_init = A(); + +// C++ [dcl.init.aggr]p4 +int x[] = { 1, 3, 5 }; +int x_sizecheck[(sizeof(x) / sizeof(int)) == 3? 1 : -1]; +int x2[] = { }; // expected-warning{{zero size arrays are an extension}} + +// C++ [dcl.init.aggr]p5 +struct StaticMemberTest { + int i; + static int s; + int *j; +} smt = { 1, &smt.i }; + +// C++ [dcl.init.aggr]p6 +char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-warning{{excess elements in array initializer}} + +// C++ [dcl.init.aggr]p7 +struct TooFew { int a; char* b; int c; }; +TooFew too_few = { 1, "asdf" }; // okay + +// C++ [dcl.init.aggr]p8 +struct Empty { }; +struct EmptyTest { + Empty s; + int i; +} empty_test = { { }, 3 }; + +EmptyTest empty_test2 = { 3 }; // expected-error{{initializer for aggregate with no elements requires explicit braces}} + +struct NonEmpty { + int a; + Empty empty; +}; +struct NonEmptyTest { + NonEmpty a, b; +} non_empty_test = { { }, { } }; + +// C++ [dcl.init.aggr]p9 +struct HasReference { + int i; + int &j; // expected-note{{uninitialized reference member is here}} +}; +int global_int; +HasReference r1 = { 1, global_int }; +HasReference r2 = { 1 } ; // expected-error{{initialization leaves reference member of type 'int &' uninitialized}} + +// C++ [dcl.init.aggr]p10 +// Note: the behavior here is identical to C +int xs[2][2] = { 3, 1, 4, 2 }; +float y[4][3] = { { 1 }, { 2 }, { 3 }, { 4 } }; + +// C++ [dcl.init.aggr]p11 +// Note: the behavior here is identical to C +float y2[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 } }; +float same_as_y2[4][3] = { 1, 3, 5, 2, 4, 6, 3, 5, 7 }; + +// C++ [dcl.init.aggr]p12 +struct A2 { + int i; + operator int *(); +}; +struct B2 { + A2 a1, a2; + int *z; +}; +struct C2 { + operator A2(); +}; +struct D2 { + operator int(); +}; +A2 a2; +C2 c2; +D2 d2; +B2 b2 = { 4, a2, a2 }; +B2 b2_2 = { 4, d2, 0 }; +// FIXME: B2 b2_3 = { c2, a2, a2 }; + +// C++ [dcl.init.aggr]p15: +union u { int a; char* b; }; +u u1 = { 1 }; +u u2 = u1; +u u3 = 1; // expected-error{{cannot initialize 'u3' with an rvalue of type 'int'}} +u u4 = { 0, "asdf" }; // expected-warning{{excess elements in array initializer}} +u u5 = { "asdf" }; // expected-error{{incompatible type initializing 'char const [5]', expected 'int'}} diff --git a/clang/www/cxx_status.html b/clang/www/cxx_status.html index 6135b3f49bf4..d508b50db9fc 100644 --- a/clang/www/cxx_status.html +++ b/clang/www/cxx_status.html @@ -999,7 +999,14 @@ welcome!

        8.4 [dcl.fct.def]   8.5 [dcl.init] -    8.5.1 [dcl.init.aggr] + +     8.5.1[dcl.init.aggr] + + + + + No CodeGen for initializing non-aggregates or dynamic initialization. +     8.5.2 [dcl.init.string]     8.5.3 [dcl.init.ref] -- GitLab From cab9a2eef5574e7dc83464b1991c73034909dab5 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:11:22 +0000 Subject: [PATCH 531/682] DebugLoc form of getNOT(). llvm-svn: 63433 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 1 + llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 895285c74843..0972f6b3b785 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -379,6 +379,7 @@ public: /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). SDValue getNOT(SDValue Val, MVT VT); + SDValue getNOT(DebugLoc DL, SDValue Val, MVT VT); /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have /// a flag result (to ensure it's not CSE'd). diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 16f17e56f465..d573476a35d5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -846,6 +846,23 @@ SDValue SelectionDAG::getNOT(SDValue Val, MVT VT) { return getNode(ISD::XOR, VT, Val, NegOne); } +/// getNOT - Create a bitwise NOT operation as (XOR Val, -1). +/// +SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) { + SDValue NegOne; + if (VT.isVector()) { + MVT EltVT = VT.getVectorElementType(); + SDValue NegOneElt = getConstant(EltVT.getIntegerVTBitMask(), EltVT); + std::vector NegOnes(VT.getVectorNumElements(), NegOneElt); + NegOne = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), VT, + &NegOnes[0], NegOnes.size()); + } else { + NegOne = getConstant(VT.getIntegerVTBitMask(), VT); + } + + return getNode(ISD::XOR, DL, VT, Val, NegOne); +} + SDValue SelectionDAG::getConstant(uint64_t Val, MVT VT, bool isT) { MVT EltVT = VT.isVector() ? VT.getVectorElementType() : VT; assert((EltVT.getSizeInBits() >= 64 || -- GitLab From c40931856201822e36e0d8a4cc9ade526315b803 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:23:15 +0000 Subject: [PATCH 532/682] Propagate debug loc info for some of the *_EXTEND functions. llvm-svn: 63434 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 1 + llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 88 ++++++++++++------- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 8 ++ 3 files changed, 64 insertions(+), 33 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 0972f6b3b785..a0dff6a942f1 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -376,6 +376,7 @@ public: /// getZeroExtendInReg - Return the expression required to zero extend the Op /// value assuming it was the smaller SrcTy value. SDValue getZeroExtendInReg(SDValue Op, MVT SrcTy); + SDValue getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT SrcTy); /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). SDValue getNOT(SDValue Val, MVT VT); diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 736e08cd925f..0dcc9645643a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2914,7 +2914,7 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) { // Fold to a simpler select_cc if (SCC.getNode() && SCC.getOpcode() == ISD::SETCC) - return DAG.getNode(ISD::SELECT_CC, N2.getValueType(), + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), N2.getValueType(), SCC.getOperand(0), SCC.getOperand(1), N2, N3, SCC.getOperand(2)); @@ -3006,12 +3006,13 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // fold (sext c1) -> c1 if (isa(N0)) - return DAG.getNode(ISD::SIGN_EXTEND, VT, N0); + return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, N0); // fold (sext (sext x)) -> (sext x) // fold (sext (aext x)) -> (sext x) if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) - return DAG.getNode(ISD::SIGN_EXTEND, VT, N0.getOperand(0)); + return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, + N0.getOperand(0)); if (N0.getOpcode() == ISD::TRUNCATE) { // fold (sext (truncate (load x))) -> (sext (smaller load x)) @@ -3020,7 +3021,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { if (NarrowLoad.getNode()) { if (NarrowLoad.getNode() != N0.getNode()) CombineTo(N0.getNode(), NarrowLoad); - return DAG.getNode(ISD::SIGN_EXTEND, VT, NarrowLoad); + return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, NarrowLoad); } // See if the value being truncated is already sign extended. If so, just @@ -3040,22 +3041,22 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // Op is i32, Mid is i8, and Dest is i64. If Op has more than 24 sign // bits, just sext from i32. if (NumSignBits > OpBits-MidBits) - return DAG.getNode(ISD::SIGN_EXTEND, VT, Op); + return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, Op); } else { // Op is i64, Mid is i8, and Dest is i32. If Op has more than 56 sign // bits, just truncate to i32. if (NumSignBits > OpBits-MidBits) - return DAG.getNode(ISD::TRUNCATE, VT, Op); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Op); } // fold (sext (truncate x)) -> (sextinreg x). if (!LegalOperations || TLI.isOperationLegal(ISD::SIGN_EXTEND_INREG, N0.getValueType())) { if (Op.getValueType().bitsLT(VT)) - Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op); + Op = DAG.getNode(ISD::ANY_EXTEND, N0.getDebugLoc(), VT, Op); else if (Op.getValueType().bitsGT(VT)) - Op = DAG.getNode(ISD::TRUNCATE, VT, Op); - return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, Op, + Op = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), VT, Op); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, Op, DAG.getValueType(N0.getValueType())); } } @@ -3070,29 +3071,37 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { DoXform = ExtendUsesToFormExtLoad(N, N0, ISD::SIGN_EXTEND, SetCCs, TLI); if (DoXform) { LoadSDNode *LN0 = cast(N0); - SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), + VT, LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); - SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad); + SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), + N0.getValueType(), ExtLoad); CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1)); + // Extend SetCC uses if necessary. for (unsigned i = 0, e = SetCCs.size(); i != e; ++i) { SDNode *SetCC = SetCCs[i]; SmallVector Ops; + for (unsigned j = 0; j != 2; ++j) { SDValue SOp = SetCC->getOperand(j); if (SOp == Trunc) Ops.push_back(ExtLoad); else - Ops.push_back(DAG.getNode(ISD::SIGN_EXTEND, VT, SOp)); - } + Ops.push_back(DAG.getNode(ISD::SIGN_EXTEND, DebugLoc::getUnknownLoc(), + VT, SOp)); + } + Ops.push_back(SetCC->getOperand(2)); - CombineTo(SetCC, DAG.getNode(ISD::SETCC, SetCC->getValueType(0), + CombineTo(SetCC, DAG.getNode(ISD::SETCC, DebugLoc::getUnknownLoc(), + SetCC->getValueType(0), &Ops[0], Ops.size())); } + return SDValue(N, 0); // Return N so it doesn't get rechecked! } } @@ -3105,19 +3114,21 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { MVT EVT = LN0->getMemoryVT(); if ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT)) { - SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), - DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), + DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), + N0.getValueType(), ExtLoad), ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! } } - // sext(setcc x,y,cc) -> select_cc x, y, -1, 0, cc + // sext(setcc x, y, cc) -> (select_cc x, y, -1, 0, cc) if (N0.getOpcode() == ISD::SETCC) { SDValue SCC = SimplifySelectCC(N0.getOperand(0), N0.getOperand(1), @@ -3129,7 +3140,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // fold (sext x) -> (zext x) if the sign bit is known zero. if ((!LegalOperations || TLI.isOperationLegal(ISD::ZERO_EXTEND, VT)) && DAG.SignBitIsZero(N0)) - return DAG.getNode(ISD::ZERO_EXTEND, VT, N0); + return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, N0); return SDValue(); } @@ -3140,11 +3151,12 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { // fold (zext c1) -> c1 if (isa(N0)) - return DAG.getNode(ISD::ZERO_EXTEND, VT, N0); + return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, N0); // fold (zext (zext x)) -> (zext x) // fold (zext (aext x)) -> (zext x) if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) - return DAG.getNode(ISD::ZERO_EXTEND, VT, N0.getOperand(0)); + return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, + N0.getOperand(0)); // fold (zext (truncate (load x))) -> (zext (smaller load x)) // fold (zext (truncate (srl (load x), c))) -> (zext (small load (x+c/n))) @@ -3153,7 +3165,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { if (NarrowLoad.getNode()) { if (NarrowLoad.getNode() != N0.getNode()) CombineTo(N0.getNode(), NarrowLoad); - return DAG.getNode(ISD::ZERO_EXTEND, VT, NarrowLoad); + return DAG.getNode(ISD::ZERO_EXTEND, N->getDebugLoc(), VT, NarrowLoad); } } @@ -3162,11 +3174,11 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { (!LegalOperations || TLI.isOperationLegal(ISD::AND, VT))) { SDValue Op = N0.getOperand(0); if (Op.getValueType().bitsLT(VT)) { - Op = DAG.getNode(ISD::ANY_EXTEND, VT, Op); + Op = DAG.getNode(ISD::ANY_EXTEND, DebugLoc::getUnknownLoc(), VT, Op); } else if (Op.getValueType().bitsGT(VT)) { - Op = DAG.getNode(ISD::TRUNCATE, VT, Op); + Op = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, Op); } - return DAG.getZeroExtendInReg(Op, N0.getValueType()); + return DAG.getZeroExtendInReg(Op, N->getDebugLoc(), N0.getValueType()); } // fold (zext (and (trunc x), cst)) -> (and x, cst). @@ -3175,13 +3187,14 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { N0.getOperand(1).getOpcode() == ISD::Constant) { SDValue X = N0.getOperand(0).getOperand(0); if (X.getValueType().bitsLT(VT)) { - X = DAG.getNode(ISD::ANY_EXTEND, VT, X); + X = DAG.getNode(ISD::ANY_EXTEND, DebugLoc::getUnknownLoc(), VT, X); } else if (X.getValueType().bitsGT(VT)) { - X = DAG.getNode(ISD::TRUNCATE, VT, X); + X = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, X); } APInt Mask = cast(N0.getOperand(1))->getAPIntValue(); Mask.zext(VT.getSizeInBits()); - return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(Mask, VT)); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, + X, DAG.getConstant(Mask, VT)); } // fold (zext (load x)) -> (zext (truncate (zextload x))) @@ -3194,29 +3207,36 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { DoXform = ExtendUsesToFormExtLoad(N, N0, ISD::ZERO_EXTEND, SetCCs, TLI); if (DoXform) { LoadSDNode *LN0 = cast(N0); - SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); - SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad); + SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), + N0.getValueType(), ExtLoad); CombineTo(N0.getNode(), Trunc, ExtLoad.getValue(1)); + // Extend SetCC uses if necessary. for (unsigned i = 0, e = SetCCs.size(); i != e; ++i) { SDNode *SetCC = SetCCs[i]; SmallVector Ops; + for (unsigned j = 0; j != 2; ++j) { SDValue SOp = SetCC->getOperand(j); if (SOp == Trunc) Ops.push_back(ExtLoad); else Ops.push_back(DAG.getNode(ISD::ZERO_EXTEND, VT, SOp)); - } + } + Ops.push_back(SetCC->getOperand(2)); - CombineTo(SetCC, DAG.getNode(ISD::SETCC, SetCC->getValueType(0), + CombineTo(SetCC, DAG.getNode(ISD::SETCC, DebugLoc::getUnknownLoc(), + SetCC->getValueType(0), &Ops[0], Ops.size())); } + return SDValue(N, 0); // Return N so it doesn't get rechecked! } } @@ -3229,13 +3249,15 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { MVT EVT = LN0->getMemoryVT(); if ((!LegalOperations && !LN0->isVolatile()) || TLI.isLoadExtLegal(ISD::ZEXTLOAD, EVT)) { - SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::ZEXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), - DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), + DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), N0.getValueType(), + ExtLoad), ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d573476a35d5..d3a59b4bf9be 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -831,6 +831,14 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, MVT VT) { getConstant(Imm, Op.getValueType())); } +SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT VT) { + if (Op.getValueType() == VT) return Op; + APInt Imm = APInt::getLowBitsSet(Op.getValueSizeInBits(), + VT.getSizeInBits()); + return getNode(ISD::AND, DL, Op.getValueType(), Op, + getConstant(Imm, Op.getValueType())); +} + /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). /// SDValue SelectionDAG::getNOT(SDValue Val, MVT VT) { -- GitLab From d42a0fb41bee91ff78eb330b8e201d28744a0856 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 30 Jan 2009 22:26:29 +0000 Subject: [PATCH 533/682] Upgrade the "excess elements in array initializer" warning to an error, since both C99 and C++ consider it an error. For reference, GCC makes this a warning while G++ makes it an error. llvm-svn: 63435 --- .../clang/Basic/DiagnosticSemaKinds.def | 2 +- clang/lib/Sema/SemaInit.cpp | 5 +++-- clang/test/CodeGen/globalinit.c | 1 - clang/test/CodeGen/init.c | 1 - clang/test/CodeGen/trunc-array-initializer.c | 3 --- clang/test/CodeGen/vector.c | 1 - clang/test/Sema/array-init.c | 18 +++++++++--------- clang/test/Sema/vector-init.c | 4 ++-- clang/test/SemaCXX/dcl_init_aggr.cpp | 4 ++-- 9 files changed, 17 insertions(+), 22 deletions(-) delete mode 100644 clang/test/CodeGen/trunc-array-initializer.c diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index 6e31de631719..8b3bd1510a52 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -540,7 +540,7 @@ DIAG(err_variable_object_no_init, ERROR, "variable-sized object may not be initialized") DIAG(err_array_init_list_required, ERROR, "initialization with '{...}' expected for array") -DIAG(warn_excess_initializers, WARNING, +DIAG(err_excess_initializers, ERROR, "excess elements in array initializer") DIAG(err_excess_initializers_in_char_array_initializer, ERROR, "excess elements in char array initializer") diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 5d40e43039ac..3440d04f07bc 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -283,9 +283,10 @@ void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T, << IList->getInit(Index)->getSourceRange(); hadError = true; } else if (!T->isIncompleteType()) { - // Don't warn for incomplete types, since we'll get an error elsewhere + // Don't complain for incomplete types, since we'll get an error + // elsewhere SemaRef->Diag(IList->getInit(Index)->getLocStart(), - diag::warn_excess_initializers) + diag::err_excess_initializers) << IList->getInit(Index)->getSourceRange(); } } diff --git a/clang/test/CodeGen/globalinit.c b/clang/test/CodeGen/globalinit.c index 0f3e21a6cafd..1bcb3e48f507 100644 --- a/clang/test/CodeGen/globalinit.c +++ b/clang/test/CodeGen/globalinit.c @@ -34,7 +34,6 @@ void booltest2() { // Scalars in braces. static int a = { 1 }; -static int b = { 1, 2 }; // References to enums. enum { diff --git a/clang/test/CodeGen/init.c b/clang/test/CodeGen/init.c index 9d18f0a767d5..fa39ba6f5a0a 100644 --- a/clang/test/CodeGen/init.c +++ b/clang/test/CodeGen/init.c @@ -2,7 +2,6 @@ void f1() { // Scalars in braces. int a = { 1 }; - int b = { 1, 2 }; } void f2() { diff --git a/clang/test/CodeGen/trunc-array-initializer.c b/clang/test/CodeGen/trunc-array-initializer.c deleted file mode 100644 index f397657f8f9f..000000000000 --- a/clang/test/CodeGen/trunc-array-initializer.c +++ /dev/null @@ -1,3 +0,0 @@ -// RUN: clang -emit-llvm %s -o %t - -int ary[2] = { 1, 2, 3 }; diff --git a/clang/test/CodeGen/vector.c b/clang/test/CodeGen/vector.c index 366c9aafddcb..528afdfe5e8f 100644 --- a/clang/test/CodeGen/vector.c +++ b/clang/test/CodeGen/vector.c @@ -8,4 +8,3 @@ void f() __v4hi x = {1,2,3}; __v4hi y = {1,2,3,4}; -__v4hi z = {1,2,3,4,5}; diff --git a/clang/test/Sema/array-init.c b/clang/test/Sema/array-init.c index 3d2cf6912744..b10d60da3fcb 100644 --- a/clang/test/Sema/array-init.c +++ b/clang/test/Sema/array-init.c @@ -20,7 +20,7 @@ void func() { int x3[x] = { 1, 2 }; // expected-error{{variable-sized object may not be initialized}} - int x4 = { 1, 2 }; // expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}} + int x4 = { 1, 2 }; // expected-warning{{braces around scalar initializer}} expected-error{{excess elements in array initializer}} int y[4][3] = { { 1, 3, 5 }, @@ -37,7 +37,7 @@ void func() { { 2, 4, 6 }, { 3, 5, 7 }, { 4, 6, 8 }, - { 5 }, // expected-warning{{excess elements in array initializer}} + { 5 }, // expected-error{{excess elements in array initializer}} }; struct threeElements { @@ -53,17 +53,17 @@ void func() { void test() { int y1[3] = { - { 1, 2, 3 } // expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}} + { 1, 2, 3 } // expected-warning{{braces around scalar initializer}} expected-error{{excess elements in array initializer}} }; int y3[4][3] = { { 1, 3, 5 }, { 2, 4, 6 }, { 3, 5, 7 }, { 4, 6, 8 }, - { }, // expected-warning{{use of GNU empty initializer extension}} expected-warning{{excess elements in array initializer}} + { }, // expected-warning{{use of GNU empty initializer extension}} expected-error{{excess elements in array initializer}} }; int y4[4][3] = { - { 1, 3, 5, 2 }, // expected-warning{{excess elements in array initializer}} + { 1, 3, 5, 2 }, // expected-error{{excess elements in array initializer}} { 4, 6 }, { 3, 5, 7 }, { 4, 6, 8 }, @@ -178,7 +178,7 @@ float r2[] = {{8}}; //expected-warning{{braces around scalar initializer}} char r3[][5] = {1,2,3,4,5,6}; int r3_sizecheck[(sizeof(r3) / sizeof(char[5])) == 2? 1 : -1]; char r3_2[sizeof r3 == 10 ? 1 : -1]; -float r4[1][2] = {1,{2},3,4}; //expected-warning{{braces around scalar initializer}} expected-warning{{excess elements in array initializer}} +float r4[1][2] = {1,{2},3,4}; //expected-warning{{braces around scalar initializer}} expected-error{{excess elements in array initializer}} char r5[][5] = {"aa", "bbb", "ccccc"}; char r6[sizeof r5 == 15 ? 1 : -1]; const char r7[] = "zxcv"; @@ -203,12 +203,12 @@ int bar (void) { struct s3 {void (*a)(void);} t5 = {autoStructTest}; // FIXME: GCC extension; flexible array init. Once this is implemented, the warning should be removed. // Note that clang objc implementation depends on this extension. -struct {int a; int b[];} t6 = {1, {1, 2, 3}}; //expected-warning{{excess elements in array initializer}} +struct {int a; int b[];} t6 = {1, {1, 2, 3}}; //expected-error{{excess elements in array initializer}} union {char a; int b;} t7[] = {1, 2, 3}; int t8[sizeof t7 == (3*sizeof(int)) ? 1 : -1]; struct bittest{int : 31, a, :21, :12, b;}; -struct bittest bittestvar = {1, 2, 3, 4}; //expected-warning{{excess elements in array initializer}} +struct bittest bittestvar = {1, 2, 3, 4}; //expected-error{{excess elements in array initializer}} // Not completely sure what should happen here... int u1 = {}; //expected-warning{{use of GNU empty initializer extension}} expected-error{{scalar initializer cannot be empty}} @@ -243,7 +243,7 @@ struct soft_segment_descriptor gdt_segs[] = { }; static void sppp_ipv6cp_up(); -const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-warning{{excess elements in array initializer}} +const struct {} ipcp = { sppp_ipv6cp_up }; //expected-warning{{empty struct extension}} expected-error{{excess elements in array initializer}} struct _Matrix { union { float m[4][4]; }; }; //expected-warning{{anonymous unions are a GNU extension in C}} typedef struct _Matrix Matrix; diff --git a/clang/test/Sema/vector-init.c b/clang/test/Sema/vector-init.c index 6913082228ca..e2a00b1ffb45 100644 --- a/clang/test/Sema/vector-init.c +++ b/clang/test/Sema/vector-init.c @@ -9,7 +9,7 @@ float4 array[] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0}; int array_sizecheck[(sizeof(array) / sizeof(float4)) == 3? 1 : -1]; float4 array2[2] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, - 9.0 }; // expected-warning {{excess elements in array initializer}} + 9.0 }; // expected-error {{excess elements in array initializer}} float4 array3[2] = { {1.0, 2.0, 3.0}, 5.0, 6.0, 7.0, 8.0, - 9.0 }; // expected-warning {{excess elements in array initializer}} + 9.0 }; // expected-error {{excess elements in array initializer}} diff --git a/clang/test/SemaCXX/dcl_init_aggr.cpp b/clang/test/SemaCXX/dcl_init_aggr.cpp index d8a41805365f..410322710622 100644 --- a/clang/test/SemaCXX/dcl_init_aggr.cpp +++ b/clang/test/SemaCXX/dcl_init_aggr.cpp @@ -34,7 +34,7 @@ struct StaticMemberTest { } smt = { 1, &smt.i }; // C++ [dcl.init.aggr]p6 -char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-warning{{excess elements in array initializer}} +char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in array initializer}} // C++ [dcl.init.aggr]p7 struct TooFew { int a; char* b; int c; }; @@ -103,5 +103,5 @@ union u { int a; char* b; }; u u1 = { 1 }; u u2 = u1; u u3 = 1; // expected-error{{cannot initialize 'u3' with an rvalue of type 'int'}} -u u4 = { 0, "asdf" }; // expected-warning{{excess elements in array initializer}} +u u4 = { 0, "asdf" }; // expected-error{{excess elements in array initializer}} u u5 = { "asdf" }; // expected-error{{incompatible type initializing 'char const [5]', expected 'int'}} -- GitLab From 9b3dc8d848d14b0dd1502bfa21686475e0e0f79c Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:27:33 +0000 Subject: [PATCH 534/682] Propagate debug loc info for ANY_EXTEND. llvm-svn: 63436 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 0dcc9645643a..3935f6da09be 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3288,7 +3288,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { if (N0.getOpcode() == ISD::ANY_EXTEND || N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND) - return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0)); + return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, N0.getOperand(0)); // fold (aext (truncate (load x))) -> (aext (smaller load x)) // fold (aext (truncate (srl (load x), c))) -> (aext (small load (x+c/n))) @@ -3297,7 +3297,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { if (NarrowLoad.getNode()) { if (NarrowLoad.getNode() != N0.getNode()) CombineTo(N0.getNode(), NarrowLoad); - return DAG.getNode(ISD::ANY_EXTEND, VT, NarrowLoad); + return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, NarrowLoad); } } @@ -3307,8 +3307,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { if (TruncOp.getValueType() == VT) return TruncOp; // x iff x size == zext size. if (TruncOp.getValueType().bitsGT(VT)) - return DAG.getNode(ISD::TRUNCATE, VT, TruncOp); - return DAG.getNode(ISD::ANY_EXTEND, VT, TruncOp); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, TruncOp); + return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, TruncOp); } // fold (aext (and (trunc x), cst)) -> (and x, cst). @@ -3317,13 +3317,14 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { N0.getOperand(1).getOpcode() == ISD::Constant) { SDValue X = N0.getOperand(0).getOperand(0); if (X.getValueType().bitsLT(VT)) { - X = DAG.getNode(ISD::ANY_EXTEND, VT, X); + X = DAG.getNode(ISD::ANY_EXTEND, DebugLoc::getUnknownLoc(), VT, X); } else if (X.getValueType().bitsGT(VT)) { - X = DAG.getNode(ISD::TRUNCATE, VT, X); + X = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, X); } APInt Mask = cast(N0.getOperand(1))->getAPIntValue(); Mask.zext(VT.getSizeInBits()); - return DAG.getNode(ISD::AND, VT, X, DAG.getConstant(Mask, VT)); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, + X, DAG.getConstant(Mask, VT)); } // fold (aext (load x)) -> (aext (truncate (extload x))) @@ -3331,7 +3332,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) { LoadSDNode *LN0 = cast(N0); - SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), @@ -3342,7 +3344,8 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { SDValue(ExtLoad.getNode(), 1)); // If any node needs the original loaded value, recompute it. if (!LN0->use_empty()) - CombineTo(LN0, DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), + CombineTo(LN0, DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), + N0.getValueType(), ExtLoad), ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! } @@ -3355,14 +3358,15 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { N0.hasOneUse()) { LoadSDNode *LN0 = cast(N0); MVT EVT = LN0->getMemoryVT(); - SDValue ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), VT, - LN0->getChain(), LN0->getBasePtr(), + SDValue ExtLoad = DAG.getExtLoad(LN0->getExtensionType(), N->getDebugLoc(), + VT, LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); CombineTo(N0.getNode(), - DAG.getNode(ISD::TRUNCATE, N0.getValueType(), ExtLoad), + DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), + N0.getValueType(), ExtLoad), ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! } -- GitLab From 7bfa43b022f2d4ba35d70c17b7d8581ed9dcb240 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:33:24 +0000 Subject: [PATCH 535/682] Propagate debug loc info for more *_EXTEND methods. llvm-svn: 63437 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 39 ++++++++++++------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 3935f6da09be..9d535d135816 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3405,14 +3405,14 @@ SDValue DAGCombiner::GetDemandedBits(SDValue V, const APInt &Mask) { if (ConstantSDNode *RHSC = dyn_cast(V.getOperand(1))) { // See if we can recursively simplify the LHS. unsigned Amt = RHSC->getZExtValue(); + // Watch out for shift count overflow though. if (Amt >= Mask.getBitWidth()) break; APInt NewMask = Mask << Amt; SDValue SimplifyLHS = GetDemandedBits(V.getOperand(0), NewMask); - if (SimplifyLHS.getNode()) { - return DAG.getNode(ISD::SRL, V.getValueType(), + if (SimplifyLHS.getNode()) + return DAG.getNode(ISD::SRL, V.getDebugLoc(), V.getValueType(), SimplifyLHS, V.getOperand(1)); - } } } return SDValue(); @@ -3465,6 +3465,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { !cast(N0)->isVolatile()) { LoadSDNode *LN0 = cast(N0); MVT PtrType = N0.getOperand(1).getValueType(); + // For big endian targets, we need to adjust the offset to the pointer to // load the correct bytes. if (TLI.isBigEndian()) { @@ -3472,22 +3473,27 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { unsigned EVTStoreBits = EVT.getStoreSizeInBits(); ShAmt = LVTStoreBits - EVTStoreBits - ShAmt; } + uint64_t PtrOff = ShAmt / 8; unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); - SDValue NewPtr = DAG.getNode(ISD::ADD, PtrType, LN0->getBasePtr(), + SDValue NewPtr = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), + PtrType, LN0->getBasePtr(), DAG.getConstant(PtrOff, PtrType)); AddToWorkList(NewPtr.getNode()); + SDValue Load = (ExtType == ISD::NON_EXTLOAD) - ? DAG.getLoad(VT, LN0->getChain(), NewPtr, + ? DAG.getLoad(VT, N0.getDebugLoc(), LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff, LN0->isVolatile(), NewAlign) - : DAG.getExtLoad(ExtType, VT, LN0->getChain(), NewPtr, + : DAG.getExtLoad(ExtType, N0.getDebugLoc(), VT, LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset() + PtrOff, EVT, LN0->isVolatile(), NewAlign); + // Replace the old load's chain with the new load's chain. WorkListRemover DeadNodes(*this); DAG.ReplaceAllUsesOfValueWith(N0.getValue(1), Load.getValue(1), &DeadNodes); + // Return the new loaded value. return Load; } @@ -3495,7 +3501,6 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { return SDValue(); } - SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { SDValue N0 = N->getOperand(0); SDValue N1 = N->getOperand(1); @@ -3506,7 +3511,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { // fold (sext_in_reg c1) -> c1 if (isa(N0) || N0.getOpcode() == ISD::UNDEF) - return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0, N1); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, N0, N1); // If the input is already sign extended, just drop the extension. if (DAG.ComputeNumSignBits(N0) >= VT.getSizeInBits()-EVTBits+1) @@ -3515,7 +3520,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { // fold (sext_in_reg (sext_in_reg x, VT2), VT1) -> (sext_in_reg x, minVT) pt2 if (N0.getOpcode() == ISD::SIGN_EXTEND_INREG && EVT.bitsLT(cast(N0.getOperand(1))->getVT())) { - return DAG.getNode(ISD::SIGN_EXTEND_INREG, VT, N0.getOperand(0), N1); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), VT, + N0.getOperand(0), N1); } // fold (sext_in_reg (sext x)) -> (sext x) @@ -3524,7 +3530,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { if (N0.getOpcode() == ISD::SIGN_EXTEND || N0.getOpcode() == ISD::ANY_EXTEND) { SDValue N00 = N0.getOperand(0); if (N00.getValueType().getSizeInBits() < EVTBits) - return DAG.getNode(ISD::SIGN_EXTEND, VT, N00, N1); + return DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, N00, N1); } // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is known zero. @@ -3542,8 +3548,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { if (NarrowLoad.getNode()) return NarrowLoad; - // fold (sext_in_reg (srl X, 24), i8) -> sra X, 24 - // fold (sext_in_reg (srl X, 23), i8) -> sra X, 23 iff possible. + // fold (sext_in_reg (srl X, 24), i8) -> (sra X, 24) + // fold (sext_in_reg (srl X, 23), i8) -> (sra X, 23) iff possible. // We already fold "(sext_in_reg (srl X, 25), i8) -> srl X, 25" above. if (N0.getOpcode() == ISD::SRL) { if (ConstantSDNode *ShAmt = dyn_cast(N0.getOperand(1))) @@ -3552,7 +3558,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { // extended enough. unsigned InSignBits = DAG.ComputeNumSignBits(N0.getOperand(0)); if (VT.getSizeInBits()-(ShAmt->getZExtValue()+EVTBits) < InSignBits) - return DAG.getNode(ISD::SRA, VT, N0.getOperand(0), N0.getOperand(1)); + return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, + N0.getOperand(0), N0.getOperand(1)); } } @@ -3563,7 +3570,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) { LoadSDNode *LN0 = cast(N0); - SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); @@ -3578,7 +3586,8 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::SEXTLOAD, EVT))) { LoadSDNode *LN0 = cast(N0); - SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::SEXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), EVT, LN0->isVolatile(), LN0->getAlignment()); -- GitLab From 6a046c64d9e215a3e479473b31d11422ff434a7d Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Fri, 30 Jan 2009 22:40:15 +0000 Subject: [PATCH 536/682] x86_64 ABI: Fix more thinkos, straddling computation for complex was computing in bytes not bits. We are now down to 22/1000 failures on the return types tests, and 18 of those are gcc bugs I believe. llvm-svn: 63438 --- clang/lib/CodeGen/CGCall.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index ba27200f2c1c..666d427a254f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -416,9 +416,9 @@ class X86_64ABIInfo : public ABIInfo { /// /// \param Lo - The classification for the low word of the type. /// \param Hi - The classification for the high word of the type. - /// \param OffsetBase - The byte position of the type in the root - /// structure. Some parameters are classified different depending on - /// whether they straddle an eightbyte boundary. + /// \param OffsetBase - The bit offset of the field in the + /// containing object. Some parameters are classified different + /// depending on whether they straddle an eightbyte boundary. /// /// If a word is unused its result will be NoClass; if a type should /// be passed in Memory then at least the classification of \arg Lo @@ -531,7 +531,7 @@ void X86_64ABIInfo::classify(QualType Ty, // If this type crosses an eightbyte boundary, it should be // split. - if (OffsetBase && OffsetBase != 8) + if (OffsetBase && OffsetBase != 64) Hi = Lo; } else if (Size == 128) { Lo = SSE; @@ -555,8 +555,8 @@ void X86_64ABIInfo::classify(QualType Ty, // If this complex type crosses an eightbyte boundary then it // should be split. - uint64_t EB_Real = (OffsetBase) >> 3; - uint64_t EB_Imag = (OffsetBase + Size) >> 3; + uint64_t EB_Real = (OffsetBase) / 64; + uint64_t EB_Imag = (OffsetBase + Context.getTypeSize(ET)) / 64; if (Hi == NoClass && EB_Real != EB_Imag) Hi = Lo; } else if (const ConstantArrayType *AT = Context.getAsConstantArrayType(Ty)) { -- GitLab From 4e0a61514b7b0802b0b539e9ba841c4c6c70f83c Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:44:24 +0000 Subject: [PATCH 537/682] Propagate debug loc info for BIT_CONVERT. llvm-svn: 63439 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 75 ++++++++++++------- 1 file changed, 46 insertions(+), 29 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9d535d135816..c5a0ce1b5521 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3607,19 +3607,20 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) { return N0; // fold (truncate c1) -> c1 if (isa(N0)) - return DAG.getNode(ISD::TRUNCATE, VT, N0); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, N0); // fold (truncate (truncate x)) -> (truncate x) if (N0.getOpcode() == ISD::TRUNCATE) - return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, N0.getOperand(0)); // fold (truncate (ext x)) -> (ext x) or (truncate x) or x if (N0.getOpcode() == ISD::ZERO_EXTEND || N0.getOpcode() == ISD::SIGN_EXTEND|| N0.getOpcode() == ISD::ANY_EXTEND) { if (N0.getOperand(0).getValueType().bitsLT(VT)) // if the source is smaller than the dest, we still need an extend - return DAG.getNode(N0.getOpcode(), VT, N0.getOperand(0)); + return DAG.getNode(N0.getOpcode(), N->getDebugLoc(), VT, + N0.getOperand(0)); else if (N0.getOperand(0).getValueType().bitsGT(VT)) // if the source is larger than the dest, than we just need the truncate - return DAG.getNode(ISD::TRUNCATE, VT, N0.getOperand(0)); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, N0.getOperand(0)); else // if the source and dest are the same type, we can drop both the extend // and the truncate @@ -3633,7 +3634,7 @@ SDValue DAGCombiner::visitTRUNCATE(SDNode *N) { GetDemandedBits(N0, APInt::getLowBitsSet(N0.getValueSizeInBits(), VT.getSizeInBits())); if (Shorter.getNode()) - return DAG.getNode(ISD::TRUNCATE, VT, Shorter); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Shorter); // fold (truncate (load x)) -> (smaller load x) // fold (truncate (srl (load x), c)) -> (smaller load (x+c/evtbits)) @@ -3658,6 +3659,7 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, MVT VT) { MVT LD1VT = LD1->getValueType(0); SDNode *LD2 = getBuildPairElt(N, 1); const MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo(); + if (ISD::isNON_EXTLoad(LD2) && LD2->hasOneUse() && // If both are volatile this would reduce the number of volatile loads. @@ -3669,12 +3671,14 @@ SDValue DAGCombiner::CombineConsecutiveLoads(SDNode *N, MVT VT) { unsigned Align = LD->getAlignment(); unsigned NewAlign = TLI.getTargetData()-> getABITypeAlignment(VT.getTypeForMVT()); + if (NewAlign <= Align && (!LegalOperations || TLI.isOperationLegal(ISD::LOAD, VT))) - return DAG.getLoad(VT, LD->getChain(), LD->getBasePtr(), + return DAG.getLoad(VT, N->getDebugLoc(), LD->getChain(), LD->getBasePtr(), LD->getSrcValue(), LD->getSrcValueOffset(), false, Align); } + return SDValue(); } @@ -3701,19 +3705,20 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) { MVT DestEltVT = N->getValueType(0).getVectorElementType(); assert(!DestEltVT.isVector() && "Element type of vector ValueType must not be vector!"); - if (isSimple) { + if (isSimple) return ConstantFoldBIT_CONVERTofBUILD_VECTOR(N0.getNode(), DestEltVT); - } } // If the input is a constant, let getNode fold it. if (isa(N0) || isa(N0)) { - SDValue Res = DAG.getNode(ISD::BIT_CONVERT, VT, N0); + SDValue Res = DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), VT, N0); if (Res.getNode() != N) return Res; } - if (N0.getOpcode() == ISD::BIT_CONVERT) // conv(conv(x,t1),t2) -> conv(x,t2) - return DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0)); + // (conv (conv x, t1), t2) -> (conv x, t2) + if (N0.getOpcode() == ISD::BIT_CONVERT) + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), VT, + N0.getOperand(0)); // fold (conv (load x)) -> (load (conv*)x) // If the resultant load doesn't need a higher alignment than the original! @@ -3725,69 +3730,81 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) { unsigned Align = TLI.getTargetData()-> getABITypeAlignment(VT.getTypeForMVT()); unsigned OrigAlign = LN0->getAlignment(); + if (Align <= OrigAlign) { - SDValue Load = DAG.getLoad(VT, LN0->getChain(), LN0->getBasePtr(), + SDValue Load = DAG.getLoad(VT, N->getDebugLoc(), LN0->getChain(), + LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), LN0->isVolatile(), OrigAlign); AddToWorkList(N); CombineTo(N0.getNode(), - DAG.getNode(ISD::BIT_CONVERT, N0.getValueType(), Load), + DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(), + N0.getValueType(), Load), Load.getValue(1)); return Load; } } - // Fold bitconvert(fneg(x)) -> xor(bitconvert(x), signbit) - // Fold bitconvert(fabs(x)) -> and(bitconvert(x), ~signbit) + // fold (bitconvert (fneg x)) -> (xor (bitconvert x), signbit) + // fold (bitconvert (fabs x)) -> (and (bitconvert x), (not signbit)) // This often reduces constant pool loads. if ((N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FABS) && N0.getNode()->hasOneUse() && VT.isInteger() && !VT.isVector()) { - SDValue NewConv = DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0)); + SDValue NewConv = DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(), VT, + N0.getOperand(0)); AddToWorkList(NewConv.getNode()); APInt SignBit = APInt::getSignBit(VT.getSizeInBits()); if (N0.getOpcode() == ISD::FNEG) - return DAG.getNode(ISD::XOR, VT, NewConv, DAG.getConstant(SignBit, VT)); + return DAG.getNode(ISD::XOR, N->getDebugLoc(), VT, + NewConv, DAG.getConstant(SignBit, VT)); assert(N0.getOpcode() == ISD::FABS); - return DAG.getNode(ISD::AND, VT, NewConv, DAG.getConstant(~SignBit, VT)); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, + NewConv, DAG.getConstant(~SignBit, VT)); } - // Fold bitconvert(fcopysign(cst, x)) -> bitconvert(x)&sign | cst&~sign' - // Note that we don't handle copysign(x,cst) because this can always be folded - // to an fneg or fabs. + // fold (bitconvert (fcopysign cst, x)) -> + // (or (and (bitconvert x), sign), (and cst, (not sign))) + // Note that we don't handle (copysign x, cst) because this can always be + // folded to an fneg or fabs. if (N0.getOpcode() == ISD::FCOPYSIGN && N0.getNode()->hasOneUse() && isa(N0.getOperand(0)) && VT.isInteger() && !VT.isVector()) { unsigned OrigXWidth = N0.getOperand(1).getValueType().getSizeInBits(); MVT IntXVT = MVT::getIntegerVT(OrigXWidth); if (TLI.isTypeLegal(IntXVT) || !LegalTypes) { - SDValue X = DAG.getNode(ISD::BIT_CONVERT, IntXVT, N0.getOperand(1)); + SDValue X = DAG.getNode(ISD::BIT_CONVERT, DebugLoc::getUnknownLoc(), + IntXVT, N0.getOperand(1)); AddToWorkList(X.getNode()); // If X has a different width than the result/lhs, sext it or truncate it. unsigned VTWidth = VT.getSizeInBits(); if (OrigXWidth < VTWidth) { - X = DAG.getNode(ISD::SIGN_EXTEND, VT, X); + X = DAG.getNode(ISD::SIGN_EXTEND, DebugLoc::getUnknownLoc(), VT, X); AddToWorkList(X.getNode()); } else if (OrigXWidth > VTWidth) { // To get the sign bit in the right place, we have to shift it right // before truncating. - X = DAG.getNode(ISD::SRL, X.getValueType(), X, + X = DAG.getNode(ISD::SRL, DebugLoc::getUnknownLoc(), + X.getValueType(), X, DAG.getConstant(OrigXWidth-VTWidth, X.getValueType())); AddToWorkList(X.getNode()); - X = DAG.getNode(ISD::TRUNCATE, VT, X); + X = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, X); AddToWorkList(X.getNode()); } APInt SignBit = APInt::getSignBit(VT.getSizeInBits()); - X = DAG.getNode(ISD::AND, VT, X, DAG.getConstant(SignBit, VT)); + X = DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), VT, + X, DAG.getConstant(SignBit, VT)); AddToWorkList(X.getNode()); - SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, VT, N0.getOperand(0)); - Cst = DAG.getNode(ISD::AND, VT, Cst, DAG.getConstant(~SignBit, VT)); + SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, DebugLoc::getUnknownLoc(), + VT, N0.getOperand(0)); + Cst = DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), VT, + Cst, DAG.getConstant(~SignBit, VT)); AddToWorkList(Cst.getNode()); - return DAG.getNode(ISD::OR, VT, X, Cst); + return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, X, Cst); } } -- GitLab From cb9be5d17485b3b87b8dedafbb171fb2907d3750 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:53:48 +0000 Subject: [PATCH 538/682] Propagate debug loc info for some FP arithmetic methods. llvm-svn: 63440 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 52 +++++++++++-------- 1 file changed, 30 insertions(+), 22 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index c5a0ce1b5521..d1d3220a2571 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -3846,7 +3846,8 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { } MVT VT = MVT::getVectorVT(DstEltVT, BV->getValueType(0).getVectorNumElements()); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); + return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT, + &Ops[0], Ops.size()); } // Otherwise, we're growing or shrinking the elements. To avoid having to @@ -3896,13 +3897,15 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { } if (EltIsUndef) - Ops.push_back(DAG.getNode(ISD::UNDEF, DstEltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), + DstEltVT)); else Ops.push_back(DAG.getConstant(NewBits, DstEltVT)); } MVT VT = MVT::getVectorVT(DstEltVT, Ops.size()); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); + return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT, + &Ops[0], Ops.size()); } // Finally, this must be the case where we are shrinking elements: each input @@ -3911,19 +3914,24 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { unsigned NumOutputsPerInput = SrcBitSize/DstBitSize; MVT VT = MVT::getVectorVT(DstEltVT, NumOutputsPerInput*BV->getNumOperands()); SmallVector Ops; + for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { if (BV->getOperand(i).getOpcode() == ISD::UNDEF) { for (unsigned j = 0; j != NumOutputsPerInput; ++j) - Ops.push_back(DAG.getNode(ISD::UNDEF, DstEltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), + DstEltVT)); continue; } + APInt OpVal = cast(BV->getOperand(i))->getAPIntValue(); + for (unsigned j = 0; j != NumOutputsPerInput; ++j) { APInt ThisVal = APInt(OpVal).trunc(DstBitSize); Ops.push_back(DAG.getConstant(ThisVal, DstEltVT)); if (isS2V && i == 0 && j == 0 && APInt(ThisVal).zext(SrcBitSize) == OpVal) // Simply turn this into a SCALAR_TO_VECTOR of the new type. - return DAG.getNode(ISD::SCALAR_TO_VECTOR, VT, Ops[0]); + return DAG.getNode(ISD::SCALAR_TO_VECTOR, BV->getDebugLoc(), VT, + Ops[0]); OpVal = OpVal.lshr(DstBitSize); } @@ -3931,10 +3939,10 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { if (TLI.isBigEndian()) std::reverse(Ops.end()-NumOutputsPerInput, Ops.end()); } - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); -} - + return DAG.getNode(ISD::BUILD_VECTOR, BV->getDebugLoc(), VT, + &Ops[0], Ops.size()); +} SDValue DAGCombiner::visitFADD(SDNode *N) { SDValue N0 = N->getOperand(0); @@ -3949,28 +3957,28 @@ SDValue DAGCombiner::visitFADD(SDNode *N) { if (FoldedVOp.getNode()) return FoldedVOp; } - // fold (fadd c1, c2) -> c1+c2 + // fold (fadd c1, c2) -> (fadd c1, c2) if (N0CFP && N1CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FADD, VT, N0, N1); + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N1); // canonicalize constant to RHS if (N0CFP && !N1CFP) - return DAG.getNode(ISD::FADD, VT, N1, N0); - // fold (A + 0) -> A + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N1, N0); + // fold (fadd A, 0) -> A if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) return N0; - // fold (A + (-B)) -> A-B + // fold (fadd A, (fneg B)) -> (fsub A, B) if (isNegatibleForFree(N1, LegalOperations) == 2) - return DAG.getNode(ISD::FSUB, VT, N0, + return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N0, GetNegatedExpression(N1, DAG, LegalOperations)); - // fold ((-A) + B) -> B-A + // fold (fadd (fneg A), B) -> (fsub B, A) if (isNegatibleForFree(N0, LegalOperations) == 2) - return DAG.getNode(ISD::FSUB, VT, N1, + return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N1, GetNegatedExpression(N0, DAG, LegalOperations)); // If allowed, fold (fadd (fadd x, c1), c2) -> (fadd x, (fadd c1, c2)) if (UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FADD && N0.getNode()->hasOneUse() && isa(N0.getOperand(1))) - return DAG.getNode(ISD::FADD, VT, N0.getOperand(0), + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getNode(ISD::FADD, VT, N0.getOperand(1), N1)); return SDValue(); @@ -3992,19 +4000,19 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { // fold (fsub c1, c2) -> c1-c2 if (N0CFP && N1CFP && VT != MVT::ppcf128) return DAG.getNode(ISD::FSUB, VT, N0, N1); - // fold (A-0) -> A + // fold (fsub A, 0) -> A if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) return N0; - // fold (0-B) -> -B + // fold (fsub 0, B) -> -B if (UnsafeFPMath && N0CFP && N0CFP->getValueAPF().isZero()) { if (isNegatibleForFree(N1, LegalOperations)) return GetNegatedExpression(N1, DAG, LegalOperations); if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) - return DAG.getNode(ISD::FNEG, VT, N1); + return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT, N1); } - // fold (A-(-B)) -> A+B + // fold (fsub A, (fneg B)) -> (fadd A, B) if (isNegatibleForFree(N1, LegalOperations)) - return DAG.getNode(ISD::FADD, VT, N0, + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, GetNegatedExpression(N1, DAG, LegalOperations)); return SDValue(); -- GitLab From 3dc5d2454e8e31df587c7dc27ddbce853d4f34df Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 22:57:07 +0000 Subject: [PATCH 539/682] Propagate debug loc info for some FP arithmetic methods. llvm-svn: 63441 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index d1d3220a2571..8eae47058501 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4033,28 +4033,28 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { // fold (fmul c1, c2) -> c1*c2 if (N0CFP && N1CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FMUL, VT, N0, N1); + return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N0, N1); // canonicalize constant to RHS if (N0CFP && !N1CFP) - return DAG.getNode(ISD::FMUL, VT, N1, N0); - // fold (A * 0) -> 0 + return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N1, N0); + // fold (fmul A, 0) -> 0 if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) return N1; // fold (fmul X, 2.0) -> (fadd X, X) if (N1CFP && N1CFP->isExactlyValue(+2.0)) - return DAG.getNode(ISD::FADD, VT, N0, N0); - // fold (fmul X, -1.0) -> (fneg X) + return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0, N0); + // fold (fmul X, (fneg 1.0)) -> (fneg X) if (N1CFP && N1CFP->isExactlyValue(-1.0)) if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) - return DAG.getNode(ISD::FNEG, VT, N0); + return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT, N0); - // -X * -Y -> X*Y + // fold (fmul (fneg X), (fneg Y)) -> (fmul X, Y) if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) { if (char RHSNeg = isNegatibleForFree(N1, LegalOperations)) { // Both can be negated for free, check to see if at least one is cheaper // negated. if (LHSNeg == 2 || RHSNeg == 2) - return DAG.getNode(ISD::FMUL, VT, + return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, GetNegatedExpression(N0, DAG, LegalOperations), GetNegatedExpression(N1, DAG, LegalOperations)); } @@ -4063,7 +4063,7 @@ SDValue DAGCombiner::visitFMUL(SDNode *N) { // If allowed, fold (fmul (fmul x, c1), c2) -> (fmul x, (fmul c1, c2)) if (UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FMUL && N0.getNode()->hasOneUse() && isa(N0.getOperand(1))) - return DAG.getNode(ISD::FMUL, VT, N0.getOperand(0), + return DAG.getNode(ISD::FMUL, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getNode(ISD::FMUL, VT, N0.getOperand(1), N1)); return SDValue(); @@ -4084,16 +4084,16 @@ SDValue DAGCombiner::visitFDIV(SDNode *N) { // fold (fdiv c1, c2) -> c1/c2 if (N0CFP && N1CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FDIV, VT, N0, N1); + return DAG.getNode(ISD::FDIV, N->getDebugLoc(), VT, N0, N1); - // -X / -Y -> X*Y + // (fdiv (fneg X), (fneg Y)) -> (fdiv X, Y) if (char LHSNeg = isNegatibleForFree(N0, LegalOperations)) { if (char RHSNeg = isNegatibleForFree(N1, LegalOperations)) { // Both can be negated for free, check to see if at least one is cheaper // negated. if (LHSNeg == 2 || RHSNeg == 2) - return DAG.getNode(ISD::FDIV, VT, + return DAG.getNode(ISD::FDIV, N->getDebugLoc(), VT, GetNegatedExpression(N0, DAG, LegalOperations), GetNegatedExpression(N1, DAG, LegalOperations)); } @@ -4111,7 +4111,7 @@ SDValue DAGCombiner::visitFREM(SDNode *N) { // fold (frem c1, c2) -> fmod(c1,c2) if (N0CFP && N1CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FREM, VT, N0, N1); + return DAG.getNode(ISD::FREM, N->getDebugLoc(), VT, N0, N1); return SDValue(); } -- GitLab From 8fb81f1b3d32e8e8a2b012438c65624e87b306af Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 23:03:19 +0000 Subject: [PATCH 540/682] Get rid of the non-DebugLoc-ified getNOT() method. llvm-svn: 63442 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 1 - llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 8 ++++---- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 8 +++++--- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 15 --------------- llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp | 10 +++++----- llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +- 6 files changed, 15 insertions(+), 29 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index a0dff6a942f1..c466cf952a96 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -379,7 +379,6 @@ public: SDValue getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT SrcTy); /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). - SDValue getNOT(SDValue Val, MVT VT); SDValue getNOT(DebugLoc DL, SDValue Val, MVT VT); /// getCALLSEQ_START - Return a new CALLSEQ_START node, which always must have diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 8eae47058501..604432b1cc80 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2845,15 +2845,15 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { } // fold (select C, 0, X) -> (and (not C), X) if (VT == VT0 && VT == MVT::i1 && N1C && N1C->isNullValue()) { - SDValue NOTNode = DAG.getNOT(N0, VT); + SDValue NOTNode = DAG.getNOT(N0.getDebugLoc(), N0, VT); AddToWorkList(NOTNode.getNode()); - return DAG.getNode(ISD::AND, VT, NOTNode, N2); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, NOTNode, N2); } // fold (select C, X, 1) -> (or (not C), X) if (VT == VT0 && VT == MVT::i1 && N2C && N2C->getAPIntValue() == 1) { SDValue NOTNode = DAG.getNOT(N0.getDebugLoc(), N0, VT); AddToWorkList(NOTNode.getNode()); - return DAG.getNode(ISD::OR, VT, NOTNode, N1); + return DAG.getNode(ISD::OR, N->getDebugLoc(), VT, NOTNode, N1); } // fold (select C, X, 0) -> (and C, X) if (VT == MVT::i1 && N2C && N2C->isNullValue()) @@ -5739,7 +5739,7 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, if (N1C && N1C->isNullValue() && CC == ISD::SETGT) { SDValue NegN0 = DAG.getNode(ISD::SUB, XType, DAG.getConstant(0, XType), N0); - SDValue NotN0 = DAG.getNOT(N0, XType); + SDValue NotN0 = DAG.getNOT(N0.getDebugLoc(), N0, XType); return DAG.getNode(ISD::SRL, XType, DAG.getNode(ISD::AND, XType, NegN0, NotN0), DAG.getConstant(XType.getSizeInBits()-1, diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index eba252f18496..5ae6364d6700 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -6321,7 +6321,7 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3)); } - Op = DAG.getNOT(Op, VT); + Op = DAG.getNOT(DebugLoc::getUnknownLoc(), Op, VT); return DAG.getNode(ISD::CTPOP, VT, Op); } case ISD::CTTZ: { @@ -6330,8 +6330,10 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { // { return 32 - nlz(~x & (x-1)); } // see also http://www.hackersdelight.org/HDcode/ntz.cc MVT VT = Op.getValueType(); - SDValue Tmp3 = DAG.getNode(ISD::AND, VT, DAG.getNOT(Op, VT), - DAG.getNode(ISD::SUB, VT, Op, DAG.getConstant(1, VT))); + SDValue Tmp3 = DAG.getNode(ISD::AND, VT, + DAG.getNOT(DebugLoc::getUnknownLoc(), Op, VT), + DAG.getNode(ISD::SUB, VT, Op, + DAG.getConstant(1, VT))); // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d3a59b4bf9be..bb1c7289e5e4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -839,21 +839,6 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, DebugLoc DL, MVT VT) { getConstant(Imm, Op.getValueType())); } -/// getNOT - Create a bitwise NOT operation as (XOR Val, -1). -/// -SDValue SelectionDAG::getNOT(SDValue Val, MVT VT) { - SDValue NegOne; - if (VT.isVector()) { - MVT EltVT = VT.getVectorElementType(); - SDValue NegOneElt = getConstant(EltVT.getIntegerVTBitMask(), EltVT); - std::vector NegOnes(VT.getVectorNumElements(), NegOneElt); - NegOne = getNode(ISD::BUILD_VECTOR, VT, &NegOnes[0], NegOnes.size()); - } else - NegOne = getConstant(VT.getIntegerVTBitMask(), VT); - - return getNode(ISD::XOR, VT, Val, NegOne); -} - /// getNOT - Create a bitwise NOT operation as (XOR Val, -1). /// SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) { diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 1f9d9cf9a72e..ebc5067c7047 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1841,7 +1841,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, default: assert(0 && "Unknown integer setcc!"); case ISD::SETEQ: // X == Y -> ~(X^Y) Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); - N0 = DAG.getNOT(Temp, MVT::i1); + N0 = DAG.getNOT(DebugLoc::getUnknownLoc(), Temp, MVT::i1); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; @@ -1850,28 +1850,28 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, break; case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> ~X & Y case ISD::SETULT: // X X == 0 & Y == 1 --> ~X & Y - Temp = DAG.getNOT(N0, MVT::i1); + Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N0, MVT::i1); N0 = DAG.getNode(ISD::AND, MVT::i1, N1, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETLT: // X X == 1 & Y == 0 --> ~Y & X case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> ~Y & X - Temp = DAG.getNOT(N1, MVT::i1); + Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N1, MVT::i1); N0 = DAG.getNode(ISD::AND, MVT::i1, N0, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> ~X | Y case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> ~X | Y - Temp = DAG.getNOT(N0, MVT::i1); + Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N0, MVT::i1); N0 = DAG.getNode(ISD::OR, MVT::i1, N1, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> ~Y | X case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> ~Y | X - Temp = DAG.getNOT(N1, MVT::i1); + Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N1, MVT::i1); N0 = DAG.getNode(ISD::OR, MVT::i1, N0, Temp); break; } diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index e17ae99b5c94..2aa2e4af44a2 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5280,7 +5280,7 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) { // If the logical-not of the result is required, perform that now. if (Invert) - Result = DAG.getNOT(Result, VT); + Result = DAG.getNOT(Op.getDebugLoc(), Result, VT); return Result; } -- GitLab From 6fbf5495f86ffbdd33252cb85f6f3e4b382068fb Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 23:10:18 +0000 Subject: [PATCH 541/682] Standardize comments about folding xforms. llvm-svn: 63443 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 604432b1cc80..568033df7aff 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -337,23 +337,23 @@ static char isNegatibleForFree(SDValue Op, bool LegalOperations, // FIXME: determine better conditions for this xform. if (!UnsafeFPMath) return 0; - // -(A+B) -> -A - B + // fold (fsub (fadd A, B)) -> (fsub (fneg A), B) if (char V = isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return V; - // -(A+B) -> -B - A + // fold (fneg (fadd A, B)) -> (fsub (fneg B), A) return isNegatibleForFree(Op.getOperand(1), LegalOperations, Depth+1); case ISD::FSUB: // We can't turn -(A-B) into B-A when we honor signed zeros. if (!UnsafeFPMath) return 0; - // -(A-B) -> B-A + // fold (fneg (fsub A, B)) -> (fsub B, A) return 1; case ISD::FMUL: case ISD::FDIV: if (HonorSignDependentRoundingFPMath()) return 0; - // -(X*Y) -> (-X * Y) or (X*-Y) + // fold (fneg (fmul X, Y)) -> (fmul (fneg X), Y) or (fmul X, (fneg Y)) if (char V = isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return V; @@ -388,13 +388,13 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG, // FIXME: determine better conditions for this xform. assert(UnsafeFPMath); - // -(A+B) -> -A - B + // fold (fneg (fadd A, B)) -> (fsub (fneg A), B) if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(), GetNegatedExpression(Op.getOperand(0), DAG, LegalOperations, Depth+1), Op.getOperand(1)); - // -(A+B) -> -B - A + // fold (fneg (fadd A, B)) -> (fsub (fneg B), A) return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(), GetNegatedExpression(Op.getOperand(1), DAG, LegalOperations, Depth+1), @@ -403,12 +403,12 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG, // We can't turn -(A-B) into B-A when we honor signed zeros. assert(UnsafeFPMath); - // -(0-B) -> B + // fold (fneg (fsub 0, B)) -> B if (ConstantFPSDNode *N0CFP = dyn_cast(Op.getOperand(0))) if (N0CFP->getValueAPF().isZero()) return Op.getOperand(1); - // -(A-B) -> B-A + // fold (fneg (fsub A, B)) -> (fsub B, A) return DAG.getNode(ISD::FSUB, Op.getDebugLoc(), Op.getValueType(), Op.getOperand(1), Op.getOperand(0)); @@ -416,14 +416,14 @@ static SDValue GetNegatedExpression(SDValue Op, SelectionDAG &DAG, case ISD::FDIV: assert(!HonorSignDependentRoundingFPMath()); - // -(X*Y) -> -X * Y + // fold (fneg (fmul X, Y)) -> (fmul (fneg X), Y) if (isNegatibleForFree(Op.getOperand(0), LegalOperations, Depth+1)) return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(), GetNegatedExpression(Op.getOperand(0), DAG, LegalOperations, Depth+1), Op.getOperand(1)); - // -(X*Y) -> X * -Y + // fold (fneg (fmul X, Y)) -> (fmul X, (fneg Y)) return DAG.getNode(Op.getOpcode(), Op.getDebugLoc(), Op.getValueType(), Op.getOperand(0), GetNegatedExpression(Op.getOperand(1), DAG, -- GitLab From 555a375bb6d8a664e449bc675fe443343e895c26 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Fri, 30 Jan 2009 23:10:59 +0000 Subject: [PATCH 542/682] Make LowerCallTo and LowerArguments take a DebugLoc argument. Adjust all callers and overloaded versions. llvm-svn: 63444 --- llvm/include/llvm/Target/TargetLowering.h | 5 +-- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 6 ++-- .../CodeGen/SelectionDAG/LegalizeTypes.cpp | 4 ++- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 9 +++-- .../SelectionDAG/SelectionDAGBuild.cpp | 20 ++++++----- llvm/lib/Target/ARM/ARMISelLowering.cpp | 4 ++- llvm/lib/Target/Alpha/AlphaISelLowering.cpp | 18 ++++++---- llvm/lib/Target/Alpha/AlphaISelLowering.h | 3 +- llvm/lib/Target/CellSPU/SPUISelLowering.cpp | 3 +- llvm/lib/Target/IA64/IA64ISelLowering.cpp | 36 ++++++++++--------- llvm/lib/Target/IA64/IA64ISelLowering.h | 6 ++-- llvm/lib/Target/PIC16/PIC16ISelLowering.cpp | 7 ++-- llvm/lib/Target/PIC16/PIC16ISelLowering.h | 2 +- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 3 +- llvm/lib/Target/Sparc/SparcISelLowering.cpp | 3 +- llvm/lib/Target/Sparc/SparcISelLowering.h | 3 +- llvm/lib/Target/X86/X86ISelLowering.cpp | 4 ++- 17 files changed, 83 insertions(+), 53 deletions(-) diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index 4ec7d3f62793..0e49b77f33bb 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -29,6 +29,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Codegen/DebugLoc.h" #include #include #include @@ -1059,7 +1060,7 @@ public: /// lower the arguments for the specified function, into the specified DAG. virtual void LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl& ArgValues); + SmallVectorImpl& ArgValues, DebugLoc dl); /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. This returns a pair of operands. The first element is the @@ -1084,7 +1085,7 @@ public: LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned CallingConv, bool isTailCall, SDValue Callee, ArgListTy &Args, - SelectionDAG &DAG); + SelectionDAG &DAG, DebugLoc dl); /// EmitTargetCodeForMemcpy - Emit target-specific code that performs a /// memcpy. This can be used by targets to provide code sequences for cases diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 5ae6364d6700..71fce0decfa1 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -991,6 +991,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { assert(isTypeLegal(Op.getValueType()) && "Caller should expand or promote operands that are not legal!"); SDNode *Node = Op.getNode(); + DebugLoc dl = Node->getDebugLoc(); // If this operation defines any values that cannot be represented in a // register on this target, make sure to expand or promote them. @@ -4323,7 +4324,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { TLI.LowerCallTo(Tmp1, Type::VoidTy, false, false, false, false, CallingConv::C, false, DAG.getExternalSymbol("abort", TLI.getPointerTy()), - Args, DAG); + Args, DAG, dl); Result = CallResult.second; break; } @@ -5791,7 +5792,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, const Type *RetTy = Node->getValueType(0).getTypeForMVT(); std::pair CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, - CallingConv::C, false, Callee, Args, DAG); + CallingConv::C, false, Callee, Args, DAG, + Node->getDebugLoc()); // Legalize the call sequence, starting with the chain. This will advance // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 36180c33d46e..7010814f634c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -987,9 +987,11 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT, TLI.getPointerTy()); const Type *RetTy = RetVT.getTypeForMVT(); + // FIXME pass in debug loc std::pair CallInfo = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, CallingConv::C, false, Callee, Args, DAG); + false, CallingConv::C, false, Callee, Args, DAG, + DebugLoc::getUnknownLoc()); return CallInfo.first; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index bb1c7289e5e4..bda9d934a41c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3285,11 +3285,12 @@ SDValue SelectionDAG::getMemcpy(SDValue Chain, SDValue Dst, Entry.Node = Dst; Args.push_back(Entry); Entry.Node = Src; Args.push_back(Entry); Entry.Node = Size; Args.push_back(Entry); + // FIXME: pass in DebugLoc std::pair CallResult = TLI.LowerCallTo(Chain, Type::VoidTy, false, false, false, false, CallingConv::C, false, getExternalSymbol("memcpy", TLI.getPointerTy()), - Args, *this); + Args, *this, DebugLoc::getUnknownLoc()); return CallResult.second; } @@ -3330,11 +3331,12 @@ SDValue SelectionDAG::getMemmove(SDValue Chain, SDValue Dst, Entry.Node = Dst; Args.push_back(Entry); Entry.Node = Src; Args.push_back(Entry); Entry.Node = Size; Args.push_back(Entry); + // FIXME: pass in DebugLoc std::pair CallResult = TLI.LowerCallTo(Chain, Type::VoidTy, false, false, false, false, CallingConv::C, false, getExternalSymbol("memmove", TLI.getPointerTy()), - Args, *this); + Args, *this, DebugLoc::getUnknownLoc()); return CallResult.second; } @@ -3381,11 +3383,12 @@ SDValue SelectionDAG::getMemset(SDValue Chain, SDValue Dst, Args.push_back(Entry); Entry.Node = Size; Entry.Ty = IntPtrTy; Entry.isSExt = false; Args.push_back(Entry); + // FIXME: pass in DebugLoc std::pair CallResult = TLI.LowerCallTo(Chain, Type::VoidTy, false, false, false, false, CallingConv::C, false, getExternalSymbol("memset", TLI.getPointerTy()), - Args, *this); + Args, *this, DebugLoc::getUnknownLoc()); return CallResult.second; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 026a6f44084a..3f3ce0d5b409 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -4344,7 +4344,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee, CS.paramHasAttr(0, Attribute::InReg), CS.getCallingConv(), IsTailCall && PerformTailCallOpt, - Callee, Args, DAG); + Callee, Args, DAG, DAG.getCurDebugLoc()); if (CS.getType() != Type::VoidTy) setValue(CS.getInstruction(), Result.first); DAG.setRoot(Result.second); @@ -5357,7 +5357,7 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) { TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, false, CallingConv::C, PerformTailCallOpt, DAG.getExternalSymbol("malloc", IntPtr), - Args, DAG); + Args, DAG, DAG.getCurDebugLoc()); setValue(&I, Result.first); // Pointers always fit in registers DAG.setRoot(Result.second); } @@ -5372,7 +5372,8 @@ void SelectionDAGLowering::visitFree(FreeInst &I) { std::pair Result = TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, false, CallingConv::C, PerformTailCallOpt, - DAG.getExternalSymbol("free", IntPtr), Args, DAG); + DAG.getExternalSymbol("free", IntPtr), Args, DAG, + DAG.getCurDebugLoc()); DAG.setRoot(Result.second); } @@ -5412,7 +5413,8 @@ void SelectionDAGLowering::visitVACopy(CallInst &I) { /// targets are migrated to using FORMAL_ARGUMENTS, this hook should be /// integrated into SDISel. void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl &ArgValues) { + SmallVectorImpl &ArgValues, + DebugLoc dl) { // Add CC# and isVararg as operands to the FORMAL_ARGUMENTS node. SmallVector Ops; Ops.push_back(DAG.getRoot()); @@ -5477,7 +5479,7 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, RetVals.push_back(MVT::Other); // Create the node. - SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS, DAG.getCurDebugLoc(), + SDNode *Result = DAG.getNode(ISD::FORMAL_ARGUMENTS, dl, DAG.getVTList(&RetVals[0], RetVals.size()), &Ops[0], Ops.size()).getNode(); @@ -5545,7 +5547,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, bool isInreg, unsigned CallingConv, bool isTailCall, SDValue Callee, - ArgListTy &Args, SelectionDAG &DAG) { + ArgListTy &Args, SelectionDAG &DAG, DebugLoc dl) { assert((!isTailCall || PerformTailCallOpt) && "isTailCall set when tail-call optimizations are disabled!"); @@ -5636,7 +5638,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, LoweredRetTys.push_back(MVT::Other); // Always has a chain. // Create the CALL node. - SDValue Res = DAG.getCall(CallingConv, DAG.getCurDebugLoc(), + SDValue Res = DAG.getCall(CallingConv, dl, isVarArg, isTailCall, isInreg, DAG.getVTList(&LoweredRetTys[0], LoweredRetTys.size()), @@ -5668,7 +5670,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, AssertOp); ReturnValues.push_back(ReturnValue); } - Res = DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), + Res = DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(&RetTys[0], RetTys.size()), &ReturnValues[0], ReturnValues.size()); } @@ -5712,7 +5714,7 @@ LowerArguments(BasicBlock *LLVMBB) { Function &F = *LLVMBB->getParent(); SDValue OldRoot = SDL->DAG.getRoot(); SmallVector Args; - TLI.LowerArguments(F, SDL->DAG, Args); + TLI.LowerArguments(F, SDL->DAG, Args, SDL->DAG.getCurDebugLoc()); unsigned a = 0; for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); diff --git a/llvm/lib/Target/ARM/ARMISelLowering.cpp b/llvm/lib/Target/ARM/ARMISelLowering.cpp index 79ae745d4db6..9067c2d47847 100644 --- a/llvm/lib/Target/ARM/ARMISelLowering.cpp +++ b/llvm/lib/Target/ARM/ARMISelLowering.cpp @@ -740,10 +740,12 @@ ARMTargetLowering::LowerToTLSGeneralDynamicModel(GlobalAddressSDNode *GA, Entry.Node = Argument; Entry.Ty = (const Type *) Type::Int32Ty; Args.push_back(Entry); + // FIXME: is there useful debug info available here? std::pair CallResult = LowerCallTo(Chain, (const Type *) Type::Int32Ty, false, false, false, false, CallingConv::C, false, - DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG); + DAG.getExternalSymbol("__tls_get_addr", PtrVT), Args, DAG, + DebugLoc::getUnknownLoc()); return CallResult.first; } diff --git a/llvm/lib/Target/Alpha/AlphaISelLowering.cpp b/llvm/lib/Target/Alpha/AlphaISelLowering.cpp index 1c090ff3e2d3..753906ed94fa 100644 --- a/llvm/lib/Target/Alpha/AlphaISelLowering.cpp +++ b/llvm/lib/Target/Alpha/AlphaISelLowering.cpp @@ -356,7 +356,8 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned CallingConv, bool isTailCall, SDValue Callee, - ArgListTy &Args, SelectionDAG &DAG) { + ArgListTy &Args, SelectionDAG &DAG, + DebugLoc dl) { int NumBytes = 0; if (Args.size() > 6) NumBytes = (Args.size() - 6) * 8; @@ -374,11 +375,13 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, // Promote the integer to 64 bits. If the input type is signed use a // sign extend, otherwise use a zero extend. if (Args[i].isSExt) - Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].Node); + Args[i].Node = DAG.getNode(ISD::SIGN_EXTEND, dl, + MVT::i64, Args[i].Node); else if (Args[i].isZExt) - Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].Node); + Args[i].Node = DAG.getNode(ISD::ZERO_EXTEND, dl, + MVT::i64, Args[i].Node); else - Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, MVT::i64, Args[i].Node); + Args[i].Node = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::i64, Args[i].Node); break; case MVT::i64: case MVT::f64: @@ -402,7 +405,8 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, Ops.push_back(Chain); Ops.push_back(Callee); Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end()); - SDValue TheCall = DAG.getNode(AlphaISD::CALL, RetVals, &Ops[0], Ops.size()); + SDValue TheCall = DAG.getNode(AlphaISD::CALL, dl, + RetVals, &Ops[0], Ops.size()); Chain = TheCall.getValue(RetTyVT != MVT::isVoid); Chain = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(NumBytes, true), DAG.getIntPtrConstant(0, true), SDValue()); @@ -416,10 +420,10 @@ AlphaTargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, AssertKind = ISD::AssertZext; if (AssertKind != ISD::DELETED_NODE) - RetVal = DAG.getNode(AssertKind, MVT::i64, RetVal, + RetVal = DAG.getNode(AssertKind, dl, MVT::i64, RetVal, DAG.getValueType(RetTyVT)); - RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); + RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal); } return std::make_pair(RetVal, Chain); diff --git a/llvm/lib/Target/Alpha/AlphaISelLowering.h b/llvm/lib/Target/Alpha/AlphaISelLowering.h index cebd3ac998ae..f165a7fa71f4 100644 --- a/llvm/lib/Target/Alpha/AlphaISelLowering.h +++ b/llvm/lib/Target/Alpha/AlphaISelLowering.h @@ -87,7 +87,8 @@ namespace llvm { virtual std::pair LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned CC, bool isTailCall, - SDValue Callee, ArgListTy &Args, SelectionDAG &DAG); + SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, + DebugLoc dl); ConstraintType getConstraintType(const std::string &Constraint) const; diff --git a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp index 86b233c1ecd1..0718330d422d 100644 --- a/llvm/lib/Target/CellSPU/SPUISelLowering.cpp +++ b/llvm/lib/Target/CellSPU/SPUISelLowering.cpp @@ -113,7 +113,8 @@ namespace { const Type *RetTy = Op.getNode()->getValueType(0).getTypeForMVT(); std::pair CallInfo = TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, - CallingConv::C, false, Callee, Args, DAG); + CallingConv::C, false, Callee, Args, DAG, + Op.getNode()->getDebugLoc()); return CallInfo.first; } diff --git a/llvm/lib/Target/IA64/IA64ISelLowering.cpp b/llvm/lib/Target/IA64/IA64ISelLowering.cpp index c40f89d7f0de..ff7ad9018779 100644 --- a/llvm/lib/Target/IA64/IA64ISelLowering.cpp +++ b/llvm/lib/Target/IA64/IA64ISelLowering.cpp @@ -145,7 +145,8 @@ MVT IA64TargetLowering::getSetCCResultType(MVT VT) const { } void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl &ArgValues) { + SmallVectorImpl &ArgValues, + DebugLoc dl) { // // add beautiful description of IA64 stack frame format // here (from intel 24535803.pdf most likely) @@ -199,7 +200,7 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), argVreg[count], MVT::f64); if (I->getType() == Type::FloatTy) - argt = DAG.getNode(ISD::FP_ROUND, MVT::f32, argt, + argt = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, argt, DAG.getIntPtrConstant(0)); break; case MVT::i1: // NOTE: as far as C abi stuff goes, @@ -218,7 +219,7 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, argt = newroot = DAG.getCopyFromReg(DAG.getRoot(), argVreg[count], MVT::i64); if ( getValueType(I->getType()) != MVT::i64) - argt = DAG.getNode(ISD::TRUNCATE, getValueType(I->getType()), + argt = DAG.getNode(ISD::TRUNCATE, dl, getValueType(I->getType()), newroot); break; } @@ -230,7 +231,7 @@ void IA64TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, // Create the SelectionDAG nodes corresponding to a load //from this parameter SDValue FIN = DAG.getFrameIndex(FI, MVT::i64); - argt = newroot = DAG.getLoad(getValueType(I->getType()), + argt = newroot = DAG.getLoad(getValueType(I->getType()), dl, DAG.getEntryNode(), FIN, NULL, 0); } ++count; @@ -307,7 +308,8 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned CallingConv, bool isTailCall, SDValue Callee, - ArgListTy &Args, SelectionDAG &DAG) { + ArgListTy &Args, SelectionDAG &DAG, + DebugLoc dl) { MachineFunction &MF = DAG.getMachineFunction(); @@ -360,7 +362,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, ExtendKind = ISD::SIGN_EXTEND; else if (Args[i].isZExt) ExtendKind = ISD::ZERO_EXTEND; - Val = DAG.getNode(ExtendKind, MVT::i64, Val); + Val = DAG.getNode(ExtendKind, dl, MVT::i64, Val); // XXX: fall through } case MVT::i64: @@ -373,7 +375,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, break; case MVT::f32: //promote to 64-bits - Val = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Val); + Val = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Val); // XXX: fall through case MVT::f64: if(RegValuesToPass.size() >= 8) { @@ -392,19 +394,21 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, StackPtr = DAG.getRegister(IA64::r12, MVT::i64); } SDValue PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); - PtrOff = DAG.getNode(ISD::ADD, MVT::i64, StackPtr, PtrOff); - Stores.push_back(DAG.getStore(Chain, ValToStore, PtrOff, NULL, 0)); + PtrOff = DAG.getNode(ISD::ADD, dl, MVT::i64, StackPtr, PtrOff); + Stores.push_back(DAG.getStore(Chain, dl, ValToStore, PtrOff, NULL, 0)); ArgOffset += ObjSize; } if(ValToConvert.getNode()) { - Converts.push_back(DAG.getNode(IA64ISD::GETFD, MVT::i64, ValToConvert)); + Converts.push_back(DAG.getNode(IA64ISD::GETFD, dl, + MVT::i64, ValToConvert)); } } // Emit all stores, make sure they occur before any copies into physregs. if (!Stores.empty()) - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0],Stores.size()); + Chain = DAG.getNode(ISD::TokenFactor, dl, + MVT::Other, &Stores[0],Stores.size()); static const unsigned IntArgRegs[] = { IA64::out0, IA64::out1, IA64::out2, IA64::out3, @@ -477,7 +481,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, assert(0 && "this should never happen!\n"); // to make way for a hack: - Chain = DAG.getNode(IA64ISD::BRCALL, NodeTys, + Chain = DAG.getNode(IA64ISD::BRCALL, dl, NodeTys, &CallOperands[0], CallOperands.size()); InFlag = Chain.getValue(1); @@ -508,7 +512,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, InFlag = zeroReg.getValue(2); Chain = zeroReg.getValue(1); - RetVal = DAG.getSetCC(MVT::i1, boolInR8, zeroReg, ISD::SETNE); + RetVal = DAG.getSetCC(dl, MVT::i1, boolInR8, zeroReg, ISD::SETNE); break; } case MVT::i8: @@ -520,9 +524,9 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, // keep track of whether it is sign or zero extended (todo: bools?) /* XXX RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext, - MVT::i64, RetVal, DAG.getValueType(RetTyVT)); + dl, MVT::i64, RetVal, DAG.getValueType(RetTyVT)); */ - RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); + RetVal = DAG.getNode(ISD::TRUNCATE, dl, RetTyVT, RetVal); break; case MVT::i64: RetVal = DAG.getCopyFromReg(Chain, IA64::r8, MVT::i64, InFlag); @@ -532,7 +536,7 @@ IA64TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, case MVT::f32: RetVal = DAG.getCopyFromReg(Chain, IA64::F8, MVT::f64, InFlag); Chain = RetVal.getValue(1); - RetVal = DAG.getNode(ISD::FP_ROUND, MVT::f32, RetVal, + RetVal = DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, RetVal, DAG.getIntPtrConstant(0)); break; case MVT::f64: diff --git a/llvm/lib/Target/IA64/IA64ISelLowering.h b/llvm/lib/Target/IA64/IA64ISelLowering.h index 9b0854fb8931..edf7eb895ad2 100644 --- a/llvm/lib/Target/IA64/IA64ISelLowering.h +++ b/llvm/lib/Target/IA64/IA64ISelLowering.h @@ -54,7 +54,8 @@ namespace llvm { /// LowerArguments - This hook must be implemented to indicate how we should /// lower the arguments for the specified function, into the specified DAG. virtual void LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl &ArgValues); + SmallVectorImpl &ArgValues, + DebugLoc dl); /// LowerCallTo - This hook lowers an abstract call to a function into an /// actual call. @@ -62,7 +63,8 @@ namespace llvm { LowerCallTo(SDValue Chain, const Type *RetTy, bool RetSExt, bool RetZExt, bool isVarArg, bool isInreg, unsigned CC, bool isTailCall, - SDValue Callee, ArgListTy &Args, SelectionDAG &DAG); + SDValue Callee, ArgListTy &Args, SelectionDAG &DAG, + DebugLoc dl); /// LowerOperation - for custom lowering specific ops /// (currently, only "ret void") diff --git a/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp b/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp index 83d7a3e56498..4e7e1e44fcb8 100644 --- a/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp +++ b/llvm/lib/Target/PIC16/PIC16ISelLowering.cpp @@ -172,7 +172,7 @@ SDValue PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, - SelectionDAG &DAG) { + SelectionDAG &DAG, DebugLoc dl) { TargetLowering::ArgListTy Args; Args.reserve(NumOps); @@ -190,7 +190,7 @@ PIC16TargetLowering::MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, const Type *RetTy = RetVT.getTypeForMVT(); std::pair CallInfo = LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, CallingConv::C, false, Callee, Args, DAG); + false, CallingConv::C, false, Callee, Args, DAG, dl); return CallInfo.first; } @@ -758,7 +758,8 @@ SDValue PIC16TargetLowering::LowerShift(SDValue Op, SelectionDAG &DAG) { SmallVector Ops(2); Ops[0] = Value; Ops[1] = Amt; - SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, true, DAG); + SDValue Call = MakePIC16Libcall(CallCode, N->getValueType(0), &Ops[0], 2, + true, DAG, N->getDebugLoc()); return Call; } diff --git a/llvm/lib/Target/PIC16/PIC16ISelLowering.h b/llvm/lib/Target/PIC16/PIC16ISelLowering.h index 78571f46fbbb..011d91e4383b 100644 --- a/llvm/lib/Target/PIC16/PIC16ISelLowering.h +++ b/llvm/lib/Target/PIC16/PIC16ISelLowering.h @@ -168,7 +168,7 @@ namespace llvm { // Make PIC16 Libcall SDValue MakePIC16Libcall(PIC16ISD::PIC16Libcall Call, MVT RetVT, const SDValue *Ops, unsigned NumOps, bool isSigned, - SelectionDAG &DAG); + SelectionDAG &DAG, DebugLoc dl); // Check if operation has a direct load operand. inline bool isDirectLoad(const SDValue Op); diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 67c253654677..1a192a101700 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -1229,6 +1229,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) { SDValue Trmp = Op.getOperand(1); // trampoline SDValue FPtr = Op.getOperand(2); // nested function SDValue Nest = Op.getOperand(3); // 'nest' parameter value + DebugLoc dl = Op.getNode()->getDebugLoc(); MVT PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); bool isPPC64 = (PtrVT == MVT::i64); @@ -1254,7 +1255,7 @@ SDValue PPCTargetLowering::LowerTRAMPOLINE(SDValue Op, SelectionDAG &DAG) { LowerCallTo(Chain, Op.getValueType().getTypeForMVT(), false, false, false, false, CallingConv::C, false, DAG.getExternalSymbol("__trampoline_setup", PtrVT), - Args, DAG); + Args, DAG, dl); SDValue Ops[] = { CallResult.first, CallResult.second }; diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.cpp b/llvm/lib/Target/Sparc/SparcISelLowering.cpp index b1031b46be6b..af5d6e526e27 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.cpp +++ b/llvm/lib/Target/Sparc/SparcISelLowering.cpp @@ -77,7 +77,8 @@ static SDValue LowerRET(SDValue Op, SelectionDAG &DAG) { /// in FP registers for fastcc functions. void SparcTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl &ArgValues) { + SmallVectorImpl &ArgValues, + DebugLoc dl) { MachineFunction &MF = DAG.getMachineFunction(); MachineRegisterInfo &RegInfo = MF.getRegInfo(); diff --git a/llvm/lib/Target/Sparc/SparcISelLowering.h b/llvm/lib/Target/Sparc/SparcISelLowering.h index a0e3c653441f..acd1b50dc894 100644 --- a/llvm/lib/Target/Sparc/SparcISelLowering.h +++ b/llvm/lib/Target/Sparc/SparcISelLowering.h @@ -58,7 +58,8 @@ namespace llvm { unsigned Depth = 0) const; virtual void LowerArguments(Function &F, SelectionDAG &DAG, - SmallVectorImpl &ArgValues); + SmallVectorImpl &ArgValues, + DebugLoc dl); virtual MachineBasicBlock *EmitInstrWithCustomInserter(MachineInstr *MI, MachineBasicBlock *MBB); diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 2aa2e4af44a2..2c79da5bf541 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5532,10 +5532,12 @@ X86TargetLowering::EmitTargetCodeForMemset(SelectionDAG &DAG, Args.push_back(Entry); Entry.Node = Size; Args.push_back(Entry); + // FIXME provide DebugLoc info std::pair CallResult = LowerCallTo(Chain, Type::VoidTy, false, false, false, false, CallingConv::C, false, - DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG); + DAG.getExternalSymbol(bzeroEntry, IntPtr), Args, DAG, + DebugLoc::getUnknownLoc()); return CallResult.second; } -- GitLab From e46e284efdf5fa2028113db618b8a7057525a41e Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 30 Jan 2009 23:15:42 +0000 Subject: [PATCH 543/682] Setting correct alignent for objc2 meta-data. llvm-svn: 63445 --- clang/lib/CodeGen/CGObjCMac.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 14b39cb13b74..07a9df272cc6 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -363,6 +363,11 @@ protected: /// defined. The return value has type ProtocolPtrTy. llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); + /// GetPointerAlign - get alignment of a pointer. + uint32_t GetPointerAlign(void) { + return CGM.getContext().getTypeAlign(CGM.getContext().VoidPtrTy) >> 3; + } + public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { } @@ -3335,6 +3340,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, &CGM.getModule()); + CLASS_RO_GV->setAlignment(GetPointerAlign()); CLASS_RO_GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(CLASS_RO_GV); return CLASS_RO_GV; @@ -3377,6 +3383,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( ClassName, &CGM.getModule()); GV->setSection("__DATA, __objc_const"); + GV->setAlignment(GetPointerAlign()); UsedGlobals.push_back(GV); return GV; } @@ -3644,6 +3651,7 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) Init, ExtCatName, &CGM.getModule()); + GCATV->setAlignment(GetPointerAlign()); GCATV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GCATV); DefinedCategories.push_back(GCATV); @@ -3700,6 +3708,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( Init, Name, &CGM.getModule()); + GV->setAlignment(GetPointerAlign()); GV->setSection(Section); UsedGlobals.push_back(GV); return llvm::ConstantExpr::getBitCast(GV, @@ -3953,6 +3962,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( Init, std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName, &CGM.getModule()); + Entry->setAlignment(GetPointerAlign()); Entry->setSection("__DATA,__datacoal_nt,coalesced"); } Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); @@ -3967,6 +3977,7 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( std::string("\01l_OBJC_LABEL_PROTOCOL_$_") +ProtocolName, &CGM.getModule()); + PTGV->setAlignment(GetPointerAlign()); PTGV->setSection("__DATA, __objc_protolist"); PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); UsedGlobals.push_back(PTGV); @@ -4015,6 +4026,7 @@ CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name, Name, &CGM.getModule()); GV->setSection("__DATA, __objc_const"); + GV->setAlignment(GetPointerAlign()); UsedGlobals.push_back(GV); return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); } -- GitLab From 0bd29743e3599f7d8db583018adfc24c98d817ed Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 23:15:49 +0000 Subject: [PATCH 544/682] More DebugLoc propagation in floating-point methods. llvm-svn: 63446 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 67 +++++++++++-------- 1 file changed, 40 insertions(+), 27 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 568033df7aff..bd8be9239559 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4132,10 +4132,12 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { // copysign(x, c1) -> fneg(fabs(x)) iff isneg(c1) if (!V.isNegative()) { if (!LegalOperations || TLI.isOperationLegal(ISD::FABS, VT)) - return DAG.getNode(ISD::FABS, VT, N0); + return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0); } else { if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) - return DAG.getNode(ISD::FNEG, VT, DAG.getNode(ISD::FABS, VT, N0)); + return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT, + DAG.getNode(ISD::FABS, DebugLoc::getUnknownLoc(), + VT, N0)); } } @@ -4144,20 +4146,23 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { // copysign(copysign(x,z), y) -> copysign(x, y) if (N0.getOpcode() == ISD::FABS || N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN) - return DAG.getNode(ISD::FCOPYSIGN, VT, N0.getOperand(0), N1); + return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, + N0.getOperand(0), N1); // copysign(x, abs(y)) -> abs(x) if (N1.getOpcode() == ISD::FABS) - return DAG.getNode(ISD::FABS, VT, N0); + return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0); // copysign(x, copysign(y,z)) -> copysign(x, z) if (N1.getOpcode() == ISD::FCOPYSIGN) - return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(1)); + return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, + N0, N1.getOperand(1)); // copysign(x, fp_extend(y)) -> copysign(x, y) // copysign(x, fp_round(y)) -> copysign(x, y) if (N1.getOpcode() == ISD::FP_EXTEND || N1.getOpcode() == ISD::FP_ROUND) - return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1.getOperand(0)); + return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, + N0, N1.getOperand(0)); return SDValue(); } @@ -4172,7 +4177,7 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) { // fold (sint_to_fp c1) -> c1fp if (N0C && OpVT != MVT::ppcf128) - return DAG.getNode(ISD::SINT_TO_FP, VT, N0); + return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0); // If the input is a legal type, and SINT_TO_FP is not legal on this target, // but UINT_TO_FP is legal on this target, try to convert. @@ -4180,10 +4185,9 @@ SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, OpVT)) { // If the sign bit is known to be zero, we can change this to UINT_TO_FP. if (DAG.SignBitIsZero(N0)) - return DAG.getNode(ISD::UINT_TO_FP, VT, N0); + return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0); } - - + return SDValue(); } @@ -4195,7 +4199,7 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) { // fold (uint_to_fp c1) -> c1fp if (N0C && OpVT != MVT::ppcf128) - return DAG.getNode(ISD::UINT_TO_FP, VT, N0); + return DAG.getNode(ISD::UINT_TO_FP, N->getDebugLoc(), VT, N0); // If the input is a legal type, and UINT_TO_FP is not legal on this target, // but SINT_TO_FP is legal on this target, try to convert. @@ -4203,7 +4207,7 @@ SDValue DAGCombiner::visitUINT_TO_FP(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, OpVT)) { // If the sign bit is known to be zero, we can change this to SINT_TO_FP. if (DAG.SignBitIsZero(N0)) - return DAG.getNode(ISD::SINT_TO_FP, VT, N0); + return DAG.getNode(ISD::SINT_TO_FP, N->getDebugLoc(), VT, N0); } return SDValue(); @@ -4216,7 +4220,8 @@ SDValue DAGCombiner::visitFP_TO_SINT(SDNode *N) { // fold (fp_to_sint c1fp) -> c1 if (N0CFP) - return DAG.getNode(ISD::FP_TO_SINT, VT, N0); + return DAG.getNode(ISD::FP_TO_SINT, N->getDebugLoc(), VT, N0); + return SDValue(); } @@ -4227,7 +4232,8 @@ SDValue DAGCombiner::visitFP_TO_UINT(SDNode *N) { // fold (fp_to_uint c1fp) -> c1 if (N0CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FP_TO_UINT, VT, N0); + return DAG.getNode(ISD::FP_TO_UINT, N->getDebugLoc(), VT, N0); + return SDValue(); } @@ -4239,7 +4245,7 @@ SDValue DAGCombiner::visitFP_ROUND(SDNode *N) { // fold (fp_round c1fp) -> c1fp if (N0CFP && N0.getValueType() != MVT::ppcf128) - return DAG.getNode(ISD::FP_ROUND, VT, N0, N1); + return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT, N0, N1); // fold (fp_round (fp_extend x)) -> x if (N0.getOpcode() == ISD::FP_EXTEND && VT == N0.getOperand(0).getValueType()) @@ -4250,15 +4256,17 @@ SDValue DAGCombiner::visitFP_ROUND(SDNode *N) { // This is a value preserving truncation if both round's are. bool IsTrunc = N->getConstantOperandVal(1) == 1 && N0.getNode()->getConstantOperandVal(1) == 1; - return DAG.getNode(ISD::FP_ROUND, VT, N0.getOperand(0), + return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT, N0.getOperand(0), DAG.getIntPtrConstant(IsTrunc)); } // fold (fp_round (copysign X, Y)) -> (copysign (fp_round X), Y) if (N0.getOpcode() == ISD::FCOPYSIGN && N0.getNode()->hasOneUse()) { - SDValue Tmp = DAG.getNode(ISD::FP_ROUND, VT, N0.getOperand(0), N1); + SDValue Tmp = DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(), VT, + N0.getOperand(0), N1); AddToWorkList(Tmp.getNode()); - return DAG.getNode(ISD::FCOPYSIGN, VT, Tmp, N0.getOperand(1)); + return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, + Tmp, N0.getOperand(1)); } return SDValue(); @@ -4273,8 +4281,9 @@ SDValue DAGCombiner::visitFP_ROUND_INREG(SDNode *N) { // fold (fp_round_inreg c1fp) -> c1fp if (N0CFP && (TLI.isTypeLegal(EVT) || !LegalTypes)) { SDValue Round = DAG.getConstantFP(*N0CFP->getConstantFPValue(), EVT); - return DAG.getNode(ISD::FP_EXTEND, VT, Round); + return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, Round); } + return SDValue(); } @@ -4290,7 +4299,7 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) { // fold (fp_extend c1fp) -> c1fp if (N0CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FP_EXTEND, VT, N0); + return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, N0); // Turn fp_extend(fp_round(X, 1)) -> x since the fp_round doesn't affect the // value of X. @@ -4299,8 +4308,9 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) { SDValue In = N0.getOperand(0); if (In.getValueType() == VT) return In; if (VT.bitsLT(In.getValueType())) - return DAG.getNode(ISD::FP_ROUND, VT, In, N0.getOperand(1)); - return DAG.getNode(ISD::FP_EXTEND, VT, In); + return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), VT, + In, N0.getOperand(1)); + return DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), VT, In); } // fold (fpext (load x)) -> (fpext (fptrunc (extload x))) @@ -4308,14 +4318,16 @@ SDValue DAGCombiner::visitFP_EXTEND(SDNode *N) { ((!LegalOperations && !cast(N0)->isVolatile()) || TLI.isLoadExtLegal(ISD::EXTLOAD, N0.getValueType()))) { LoadSDNode *LN0 = cast(N0); - SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, VT, LN0->getChain(), + SDValue ExtLoad = DAG.getExtLoad(ISD::EXTLOAD, N->getDebugLoc(), VT, + LN0->getChain(), LN0->getBasePtr(), LN0->getSrcValue(), LN0->getSrcValueOffset(), N0.getValueType(), LN0->isVolatile(), LN0->getAlignment()); CombineTo(N, ExtLoad); - CombineTo(N0.getNode(), DAG.getNode(ISD::FP_ROUND, N0.getValueType(), - ExtLoad, DAG.getIntPtrConstant(1)), + CombineTo(N0.getNode(), + DAG.getNode(ISD::FP_ROUND, N0.getDebugLoc(), + N0.getValueType(), ExtLoad, DAG.getIntPtrConstant(1)), ExtLoad.getValue(1)); return SDValue(N, 0); // Return N so it doesn't get rechecked! } @@ -4337,10 +4349,11 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) { SDValue Int = N0.getOperand(0); MVT IntVT = Int.getValueType(); if (IntVT.isInteger() && !IntVT.isVector()) { - Int = DAG.getNode(ISD::XOR, IntVT, Int, + Int = DAG.getNode(ISD::XOR, DebugLoc::getUnknownLoc(), IntVT, Int, DAG.getConstant(IntVT.getIntegerVTSignBit(), IntVT)); AddToWorkList(Int.getNode()); - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Int); + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), + N->getValueType(0), Int); } } -- GitLab From db5a9b675c000134dc835d9ca1b77d6ee333b8f2 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 30 Jan 2009 23:17:46 +0000 Subject: [PATCH 545/682] Turn on -flax-vector-conversions by default, issue a warning whenever one is done. Add a -fnolax-vector-conversions option. Fixes PR2862. llvm-svn: 63447 --- clang/Driver/clang.cpp | 11 ++++---- .../clang/Basic/DiagnosticSemaKinds.def | 2 ++ clang/include/clang/Basic/LangOptions.h | 3 ++- clang/lib/Sema/Sema.h | 4 +++ clang/lib/Sema/SemaExpr.cpp | 17 ++++++++---- clang/test/Sema/typedef-retain.c | 2 +- clang/test/Sema/vector-assign.c | 26 +++++++++---------- 7 files changed, 40 insertions(+), 25 deletions(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 5e545b98e44b..52f34783c1f2 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -486,10 +486,10 @@ WritableStrings("fwritable-strings", llvm::cl::desc("Store string literals as writable data")); static llvm::cl::opt -LaxVectorConversions("flax-vector-conversions", - llvm::cl::desc("Allow implicit conversions between vectors" - " with a different number of elements or " - "different element types")); +NoLaxVectorConversions("fnolax-vector-conversions", + llvm::cl::desc("Disallow implicit conversions between " + "vectors with a different number of " + "elements or different element types")); static llvm::cl::opt EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature"), llvm::cl::ValueDisallowed); @@ -620,7 +620,8 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, Options.PascalStrings = PascalStrings; Options.Microsoft = MSExtensions; Options.WritableStrings = WritableStrings; - Options.LaxVectorConversions = LaxVectorConversions; + if (NoLaxVectorConversions.getPosition()) + Options.LaxVectorConversions = 0; Options.Exceptions = Exceptions; if (EnableBlocks.getPosition() || DisableBlocks.getPosition()) Options.Blocks = EnableBlocks; diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index 8b3bd1510a52..89577dfd3922 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -878,6 +878,8 @@ DIAG(ext_typecheck_convert_incompatible_pointer, EXTWARN, "incompatible pointer types %2 %1, expected %0") DIAG(ext_typecheck_convert_discards_qualifiers, EXTWARN, "%2 %1 discards qualifiers, expected %0") +DIAG(warn_incompatible_vectors, WARNING, + "incompatible vector types %2 %1, expected %0") DIAG(err_int_to_block_pointer, ERROR, "invalid conversion %2 integer %1, expected block pointer %0") DIAG(err_typecheck_comparison_of_distinct_blocks, ERROR, diff --git a/clang/include/clang/Basic/LangOptions.h b/clang/include/clang/Basic/LangOptions.h index daae904823a7..b615412f20b6 100644 --- a/clang/include/clang/Basic/LangOptions.h +++ b/clang/include/clang/Basic/LangOptions.h @@ -66,7 +66,8 @@ public: GC = ObjC1 = ObjC2 = ObjCNonFragileABI = 0; C99 = Microsoft = CPlusPlus = CPlusPlus0x = NoExtensions = 0; CXXOperatorNames = PascalStrings = Boolean = WritableStrings = 0; - LaxVectorConversions = Exceptions = NeXTRuntime = 0; + Exceptions = NeXTRuntime = 0; + LaxVectorConversions = 1; // FIXME: The default should be 1. ThreadsafeStatics = 0; diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 6e3a55268644..45f08bc8df59 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1584,6 +1584,10 @@ public: /// c/v/r qualifiers, which we accept as an extension. CompatiblePointerDiscardsQualifiers, + /// IncompatibleVectors - The assignment is between two vector types that + /// have the same size, which we accept as an extension. + IncompatibleVectors, + /// IntToBlockPointer - The assignment converts an int to a block /// pointer. We disallow this. IntToBlockPointer, diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 129967a14b62..ddd5349c1564 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -2448,7 +2448,7 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) { if (getLangOptions().LaxVectorConversions && lhsType->isVectorType() && rhsType->isVectorType()) { if (Context.getTypeSize(lhsType) == Context.getTypeSize(rhsType)) - return Compatible; + return IncompatibleVectors; } return Incompatible; } @@ -2599,13 +2599,17 @@ inline QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, // Handle the case of a vector & extvector type of the same size and element // type. It would be nice if we only had one vector type someday. - if (getLangOptions().LaxVectorConversions) - if (const VectorType *LV = lhsType->getAsVectorType()) + if (getLangOptions().LaxVectorConversions) { + // FIXME: Should we warn here? + if (const VectorType *LV = lhsType->getAsVectorType()) { if (const VectorType *RV = rhsType->getAsVectorType()) if (LV->getElementType() == RV->getElementType() && - LV->getNumElements() == RV->getNumElements()) + LV->getNumElements() == RV->getNumElements()) { return lhsType->isExtVectorType() ? lhsType : rhsType; - + } + } + } + // If the lhs is an extended vector and the rhs is a scalar of the same type // or a literal, promote the rhs to the vector type. if (const ExtVectorType *V = lhsType->getAsExtVectorType()) { @@ -4359,6 +4363,9 @@ bool Sema::DiagnoseAssignmentResult(AssignConvertType ConvTy, // it can give a more specific diagnostic. DiagKind = diag::warn_incompatible_qualified_id; break; + case IncompatibleVectors: + DiagKind = diag::warn_incompatible_vectors; + break; case Incompatible: DiagKind = diag::err_typecheck_convert_incompatible; isInvalid = true; diff --git a/clang/test/Sema/typedef-retain.c b/clang/test/Sema/typedef-retain.c index 861e0771cc42..641b7ec03288 100644 --- a/clang/test/Sema/typedef-retain.c +++ b/clang/test/Sema/typedef-retain.c @@ -1,4 +1,4 @@ -// RUN: clang -fsyntax-only -verify %s +// RUN: clang -fsyntax-only -verify %s -fnolax-vector-conversions typedef float float4 __attribute__((vector_size(16))); typedef int int4 __attribute__((vector_size(16))); diff --git a/clang/test/Sema/vector-assign.c b/clang/test/Sema/vector-assign.c index be447120c51c..548c08e7e32a 100644 --- a/clang/test/Sema/vector-assign.c +++ b/clang/test/Sema/vector-assign.c @@ -1,4 +1,4 @@ -// RUN: clang %s -verify -fsyntax-only -flax-vector-conversions +// RUN: clang %s -verify -fsyntax-only typedef unsigned int v2u __attribute__ ((vector_size (8))); typedef signed int v2s __attribute__ ((vector_size (8))); typedef signed int v1s __attribute__ ((vector_size (4))); @@ -12,30 +12,30 @@ void f() { v2f v4; v4ss v5; - v1 = v2; + v1 = v2; // expected-warning {{incompatible vector types assigning 'v2u', expected 'v2s'}} v1 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2s'}} - v1 = v4; - v1 = v5; + v1 = v4; // expected-warning {{incompatible vector types assigning 'v2f', expected 'v2s'}} + v1 = v5; // expected-warning {{incompatible vector types assigning 'v4ss', expected 'v2s'}} - v2 = v1; + v2 = v1; // expected-warning {{incompatible vector types assigning 'v2s', expected 'v2u'}} v2 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2u'}} - v2 = v4; - v2 = v5; + v2 = v4; // expected-warning {{incompatible vector types assigning 'v2f', expected 'v2u'}} + v2 = v5; // expected-warning {{incompatible vector types assigning 'v4ss', expected 'v2u'}} v3 = v1; // expected-error {{incompatible type assigning 'v2s', expected 'v1s'}} v3 = v2; // expected-error {{incompatible type assigning 'v2u', expected 'v1s'}} v3 = v4; // expected-error {{incompatible type assigning 'v2f', expected 'v1s'}} v3 = v5; // expected-error {{incompatible type assigning 'v4ss', expected 'v1s'}} - v4 = v1; - v4 = v2; + v4 = v1; // expected-warning {{incompatible vector types assigning 'v2s', expected 'v2f'}} + v4 = v2; // expected-warning {{incompatible vector types assigning 'v2u', expected 'v2f'}} v4 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v2f'}} - v4 = v5; + v4 = v5; // expected-warning {{incompatible vector types assigning 'v4ss', expected 'v2f'}} - v5 = v1; - v5 = v2; + v5 = v1; // expected-warning {{incompatible vector types assigning 'v2s', expected 'v4ss'}} + v5 = v2; // expected-warning {{incompatible vector types assigning 'v2u', expected 'v4ss'}} v5 = v3; // expected-error {{incompatible type assigning 'v1s', expected 'v4ss'}} - v5 = v4; + v5 = v4; // expected-warning {{incompatible vector types assigning 'v2f', expected 'v4ss'}} } // PR2263 -- GitLab From 9d7c69d832c5571c7fd0d1c60691b77aad76b328 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Fri, 30 Jan 2009 23:20:42 +0000 Subject: [PATCH 546/682] Fix build on case-sensitive filesystems (i.e. everybody else) llvm-svn: 63448 --- llvm/include/llvm/Target/TargetLowering.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index 0e49b77f33bb..5005df3c7997 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -29,7 +29,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" -#include "llvm/Codegen/DebugLoc.h" +#include "llvm/CodeGen/DebugLoc.h" #include #include #include -- GitLab From f6e6057e92d58efde867c21b4ada7255dc687ce8 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Fri, 30 Jan 2009 23:26:40 +0000 Subject: [PATCH 547/682] Fix typo noticed by Chris. llvm-svn: 63449 --- clang/Driver/clang.cpp | 2 +- clang/test/Sema/typedef-retain.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index 52f34783c1f2..fe5e7f834441 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -486,7 +486,7 @@ WritableStrings("fwritable-strings", llvm::cl::desc("Store string literals as writable data")); static llvm::cl::opt -NoLaxVectorConversions("fnolax-vector-conversions", +NoLaxVectorConversions("fno-lax-vector-conversions", llvm::cl::desc("Disallow implicit conversions between " "vectors with a different number of " "elements or different element types")); diff --git a/clang/test/Sema/typedef-retain.c b/clang/test/Sema/typedef-retain.c index 641b7ec03288..b621743373c4 100644 --- a/clang/test/Sema/typedef-retain.c +++ b/clang/test/Sema/typedef-retain.c @@ -1,4 +1,4 @@ -// RUN: clang -fsyntax-only -verify %s -fnolax-vector-conversions +// RUN: clang -fsyntax-only -verify %s -fno-lax-vector-conversions typedef float float4 __attribute__((vector_size(16))); typedef int int4 __attribute__((vector_size(16))); -- GitLab From 576e98cc1e5133980630f1cbbc95522b7017d484 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Fri, 30 Jan 2009 23:27:23 +0000 Subject: [PATCH 548/682] Improve our handling of the second step in a user-defined conversion sequence. Previously, we weren't permitting the second step to call copy constructors, which left user-defined conversion sequences surprisingly broken. Now, we perform overload resolution among all of the constructors, but only accept the result if it makes the conversion a standard conversion. Note that this behavior is different from both GCC and EDG (which don't agree with each other, either); I've submitted a core issue on the matter. llvm-svn: 63450 --- clang/lib/Sema/Sema.h | 3 +- clang/lib/Sema/SemaDeclCXX.cpp | 15 +++++- clang/lib/Sema/SemaOverload.cpp | 48 +++++++++++++------ clang/test/SemaCXX/dcl_init_aggr.cpp | 2 +- .../test/SemaCXX/user-defined-conversions.cpp | 32 +++++++++++++ 5 files changed, 83 insertions(+), 17 deletions(-) diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 45f08bc8df59..6108f9447fdb 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -433,7 +433,8 @@ public: bool IsQualificationConversion(QualType FromType, QualType ToType); bool IsUserDefinedConversion(Expr *From, QualType ToType, UserDefinedConversionSequence& User, - bool AllowExplicit = false); + bool AllowConversionFunctions, + bool AllowExplicit); ImplicitConversionSequence::CompareKind CompareImplicitConversionSequences(const ImplicitConversionSequence& ICS1, diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 24f753164d90..f3bb9a5dfbc8 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1867,7 +1867,6 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, // the temporary or to a sub-object within the // temporary. // - // // The constructor that would be used to make the copy // shall be callable whether or not the copy is actually // done. @@ -1915,6 +1914,20 @@ Sema::CheckReferenceInit(Expr *&Init, QualType &DeclType, return true; } + // If at least one of the types is a class type, the types are not + // related, and we aren't allowed any user conversions, the + // reference binding fails. This case is important for breaking + // recursion, since TryImplicitConversion below will attempt to + // create a temporary through the use of a copy constructor. + if (SuppressUserConversions && RefRelationship == Ref_Incompatible && + (T1->isRecordType() || T2->isRecordType())) { + if (!ICS) + Diag(Init->getSourceRange().getBegin(), + diag::err_typecheck_convert_incompatible) + << DeclType << Init->getType() << "initializing" << Init->getSourceRange(); + return true; + } + // Actually try to convert the initializer to T1. if (ICS) { /// C++ [over.ics.ref]p2: diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 17ad387ac3eb..1fa703c775ab 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -366,13 +366,13 @@ Sema::IsOverload(FunctionDecl *New, Decl* OldD, ImplicitConversionSequence Sema::TryImplicitConversion(Expr* From, QualType ToType, bool SuppressUserConversions, - bool AllowExplict) + bool AllowExplicit) { ImplicitConversionSequence ICS; if (IsStandardConversion(From, ToType, ICS.Standard)) ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; - else if (!SuppressUserConversions && - IsUserDefinedConversion(From, ToType, ICS.UserDefined, AllowExplict)) { + else if (IsUserDefinedConversion(From, ToType, ICS.UserDefined, + !SuppressUserConversions, AllowExplicit)) { ICS.ConversionKind = ImplicitConversionSequence::UserDefinedConversion; // C++ [over.ics.user]p4: // A conversion of an expression of class type to the same class @@ -396,6 +396,17 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType, ICS.Standard.Second = ICK_Derived_To_Base; } } + + // C++ [over.best.ics]p4: + // However, when considering the argument of a user-defined + // conversion function that is a candidate by 13.3.1.3 when + // invoked for the copying of the temporary in the second step + // of a class copy-initialization, or by 13.3.1.4, 13.3.1.5, or + // 13.3.1.6 in all cases, only standard conversion sequences and + // ellipsis conversion sequences are allowed. + if (SuppressUserConversions && + ICS.ConversionKind == ImplicitConversionSequence::UserDefinedConversion) + ICS.ConversionKind = ImplicitConversionSequence::BadConversion; } else ICS.ConversionKind = ImplicitConversionSequence::BadConversion; @@ -1188,17 +1199,23 @@ Sema::IsQualificationConversion(QualType FromType, QualType ToType) FromType.getUnqualifiedType() == ToType.getUnqualifiedType(); } -/// IsUserDefinedConversion - Determines whether there is a -/// user-defined conversion sequence (C++ [over.ics.user]) that -/// converts expression From to the type ToType. If such a conversion -/// exists, User will contain the user-defined conversion sequence -/// that performs such a conversion and this routine will return -/// true. Otherwise, this routine returns false and User is -/// unspecified. AllowExplicit is true if the conversion should -/// consider C++0x "explicit" conversion functions as well as -/// non-explicit conversion functions (C++0x [class.conv.fct]p2). +/// Determines whether there is a user-defined conversion sequence +/// (C++ [over.ics.user]) that converts expression From to the type +/// ToType. If such a conversion exists, User will contain the +/// user-defined conversion sequence that performs such a conversion +/// and this routine will return true. Otherwise, this routine returns +/// false and User is unspecified. +/// +/// \param AllowConversionFunctions true if the conversion should +/// consider conversion functions at all. If false, only constructors +/// will be considered. +/// +/// \param AllowExplicit true if the conversion should consider C++0x +/// "explicit" conversion functions as well as non-explicit conversion +/// functions (C++0x [class.conv.fct]p2). bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, UserDefinedConversionSequence& User, + bool AllowConversionFunctions, bool AllowExplicit) { OverloadCandidateSet CandidateSet; @@ -1226,8 +1243,11 @@ bool Sema::IsUserDefinedConversion(Expr *From, QualType ToType, } } - if (const CXXRecordType *FromRecordType - = dyn_cast_or_null(From->getType()->getAsRecordType())) { + if (!AllowConversionFunctions) { + // Don't allow any conversion functions to enter the overload set. + } else if (const CXXRecordType *FromRecordType + = dyn_cast_or_null( + From->getType()->getAsRecordType())) { // Add all of the conversion functions as candidates. // FIXME: Look for conversions in base classes! CXXRecordDecl *FromRecordDecl = FromRecordType->getDecl(); diff --git a/clang/test/SemaCXX/dcl_init_aggr.cpp b/clang/test/SemaCXX/dcl_init_aggr.cpp index 410322710622..c2c9d67a4d52 100644 --- a/clang/test/SemaCXX/dcl_init_aggr.cpp +++ b/clang/test/SemaCXX/dcl_init_aggr.cpp @@ -96,7 +96,7 @@ C2 c2; D2 d2; B2 b2 = { 4, a2, a2 }; B2 b2_2 = { 4, d2, 0 }; -// FIXME: B2 b2_3 = { c2, a2, a2 }; +B2 b2_3 = { c2, a2, a2 }; // C++ [dcl.init.aggr]p15: union u { int a; char* b; }; diff --git a/clang/test/SemaCXX/user-defined-conversions.cpp b/clang/test/SemaCXX/user-defined-conversions.cpp index 8292c7a009f5..e4b12fc3f713 100644 --- a/clang/test/SemaCXX/user-defined-conversions.cpp +++ b/clang/test/SemaCXX/user-defined-conversions.cpp @@ -35,3 +35,35 @@ void h(volatile A&); void h_test(C c) { h(c); } + +// Test conversion followed by copy-construction +struct FunkyDerived; + +struct Base { + Base(const FunkyDerived&); +}; + +struct Derived : Base { }; + +struct FunkyDerived : Base { }; + +struct ConvertibleToBase { + operator Base(); +}; + +struct ConvertibleToDerived { + operator Derived(); +}; + +struct ConvertibleToFunkyDerived { + operator FunkyDerived(); +}; + +void test_conversion(ConvertibleToBase ctb, ConvertibleToDerived ctd, + ConvertibleToFunkyDerived ctfd) { + Base b1 = ctb; + Base b2(ctb); + Base b3 = ctd; + Base b4(ctd); + Base b5 = ctfd; // expected-error{{cannot initialize 'b5' with an lvalue of type 'struct ConvertibleToFunkyDerived'}} +} -- GitLab From 306bfc221301a1a9d472998cfb5b3af01c46783e Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 23:27:35 +0000 Subject: [PATCH 549/682] More DebugLoc propagation in LOAD etc. methods. llvm-svn: 63451 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 68 ++++++++++++------- 1 file changed, 42 insertions(+), 26 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index bd8be9239559..2b7b26fff5c4 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4367,14 +4367,14 @@ SDValue DAGCombiner::visitFABS(SDNode *N) { // fold (fabs c1) -> fabs(c1) if (N0CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FABS, VT, N0); + return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0); // fold (fabs (fabs x)) -> (fabs x) if (N0.getOpcode() == ISD::FABS) return N->getOperand(0); // fold (fabs (fneg x)) -> (fabs x) // fold (fabs (fcopysign x, y)) -> (fabs x) if (N0.getOpcode() == ISD::FNEG || N0.getOpcode() == ISD::FCOPYSIGN) - return DAG.getNode(ISD::FABS, VT, N0.getOperand(0)); + return DAG.getNode(ISD::FABS, N->getDebugLoc(), VT, N0.getOperand(0)); // Transform fabs(bitconvert(x)) -> bitconvert(x&~sign) to avoid loading // constant pool values. @@ -4384,10 +4384,11 @@ SDValue DAGCombiner::visitFABS(SDNode *N) { SDValue Int = N0.getOperand(0); MVT IntVT = Int.getValueType(); if (IntVT.isInteger() && !IntVT.isVector()) { - Int = DAG.getNode(ISD::AND, IntVT, Int, + Int = DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), IntVT, Int, DAG.getConstant(~IntVT.getIntegerVTSignBit(), IntVT)); AddToWorkList(Int.getNode()); - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Int); + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), + N->getValueType(0), Int); } } @@ -4405,14 +4406,16 @@ SDValue DAGCombiner::visitBRCOND(SDNode *N) { return Chain; // unconditional branch if (N1C && N1C->getAPIntValue() == 1) - return DAG.getNode(ISD::BR, MVT::Other, Chain, N2); + return DAG.getNode(ISD::BR, N->getDebugLoc(), MVT::Other, Chain, N2); // fold a brcond with a setcc condition into a BR_CC node if BR_CC is legal // on the target. if (N1.getOpcode() == ISD::SETCC && TLI.isOperationLegalOrCustom(ISD::BR_CC, MVT::Other)) { - return DAG.getNode(ISD::BR_CC, MVT::Other, Chain, N1.getOperand(2), + return DAG.getNode(ISD::BR_CC, N->getDebugLoc(), MVT::Other, + Chain, N1.getOperand(2), N1.getOperand(0), N1.getOperand(1), N2); } + return SDValue(); } @@ -4431,21 +4434,22 @@ SDValue DAGCombiner::visitBR_CC(SDNode *N) { // fold br_cc true, dest -> br dest (unconditional branch) if (SCCC && !SCCC->isNullValue()) - return DAG.getNode(ISD::BR, MVT::Other, N->getOperand(0), - N->getOperand(4)); + return DAG.getNode(ISD::BR, N->getDebugLoc(), MVT::Other, + N->getOperand(0), N->getOperand(4)); // fold br_cc false, dest -> unconditional fall through if (SCCC && SCCC->isNullValue()) return N->getOperand(0); // fold to a simpler setcc if (Simp.getNode() && Simp.getOpcode() == ISD::SETCC) - return DAG.getNode(ISD::BR_CC, MVT::Other, N->getOperand(0), - Simp.getOperand(2), Simp.getOperand(0), - Simp.getOperand(1), N->getOperand(4)); + return DAG.getNode(ISD::BR_CC, N->getDebugLoc(), MVT::Other, + N->getOperand(0), Simp.getOperand(2), + Simp.getOperand(0), Simp.getOperand(1), + N->getOperand(4)); + return SDValue(); } - /// CombineToPreIndexedLoadStore - Try turning a load / store into a /// pre-indexed load / store when the base pointer is an add or subtract /// and it has other uses besides the load / store. After the @@ -4476,8 +4480,9 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) { return false; Ptr = ST->getBasePtr(); isLoad = false; - } else + } else { return false; + } // If the pointer is not an add/sub, or if it doesn't have multiple uses, bail // out. There is no reason to make this a preinc/predec. @@ -4532,14 +4537,17 @@ bool DAGCombiner::CombineToPreIndexedLoadStore(SDNode *N) { cast(Use)->getBasePtr() == Ptr))) RealUse = true; } + if (!RealUse) return false; SDValue Result; if (isLoad) - Result = DAG.getIndexedLoad(SDValue(N,0), BasePtr, Offset, AM); + Result = DAG.getIndexedLoad(SDValue(N,0), N->getDebugLoc(), + BasePtr, Offset, AM); else - Result = DAG.getIndexedStore(SDValue(N,0), BasePtr, Offset, AM); + Result = DAG.getIndexedStore(SDValue(N,0), N->getDebugLoc(), + BasePtr, Offset, AM); ++PreIndexedNodes; ++NodesCombined; DOUT << "\nReplacing.4 "; DEBUG(N->dump(&DAG)); @@ -4597,8 +4605,9 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) { return false; Ptr = ST->getBasePtr(); isLoad = false; - } else + } else { return false; + } if (Ptr.getNode()->hasOneUse()) return false; @@ -4657,14 +4666,17 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) { } } } + if (TryNext) continue; // Check for #2 if (!Op->isPredecessorOf(N) && !N->isPredecessorOf(Op)) { SDValue Result = isLoad - ? DAG.getIndexedLoad(SDValue(N,0), BasePtr, Offset, AM) - : DAG.getIndexedStore(SDValue(N,0), BasePtr, Offset, AM); + ? DAG.getIndexedLoad(SDValue(N,0), N->getDebugLoc(), + BasePtr, Offset, AM) + : DAG.getIndexedStore(SDValue(N,0), N->getDebugLoc(), + BasePtr, Offset, AM); ++PostIndexedNodes; ++NodesCombined; DOUT << "\nReplacing.5 "; DEBUG(N->dump(&DAG)); @@ -4694,6 +4706,7 @@ bool DAGCombiner::CombineToPostIndexedLoadStore(SDNode *N) { } } } + return false; } @@ -4749,13 +4762,13 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { if (!Fast && LD->isUnindexed()) { if (unsigned Align = InferAlignment(Ptr, DAG)) { if (Align > LD->getAlignment()) - return DAG.getExtLoad(LD->getExtensionType(), LD->getValueType(0), + return DAG.getExtLoad(LD->getExtensionType(), N->getDebugLoc(), + LD->getValueType(0), Chain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), LD->getMemoryVT(), LD->isVolatile(), Align); } } - // If load is not volatile and there are no uses of the loaded value (and // the updated indexed value in case of indexed loads), change uses of the @@ -4775,10 +4788,12 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { DOUT << "\n"; WorkListRemover DeadNodes(*this); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), Chain, &DeadNodes); + if (N->use_empty()) { removeFromWorkList(N); DAG.DeleteNode(N); } + return SDValue(N, 0); // Return N so it doesn't get rechecked! } } else { @@ -4792,7 +4807,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { WorkListRemover DeadNodes(*this); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Undef, &DeadNodes); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), - DAG.getNode(ISD::UNDEF, N->getValueType(1)), + DAG.getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), + N->getValueType(1)), &DeadNodes); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 2), Chain, &DeadNodes); removeFromWorkList(N); @@ -4826,11 +4842,12 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { // Replace the chain to void dependency. if (LD->getExtensionType() == ISD::NON_EXTLOAD) { - ReplLoad = DAG.getLoad(N->getValueType(0), BetterChain, Ptr, + ReplLoad = DAG.getLoad(N->getValueType(0), LD->getDebugLoc(), + BetterChain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), LD->isVolatile(), LD->getAlignment()); } else { - ReplLoad = DAG.getExtLoad(LD->getExtensionType(), + ReplLoad = DAG.getExtLoad(LD->getExtensionType(), LD->getDebugLoc(), LD->getValueType(0), BetterChain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), @@ -4840,8 +4857,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { } // Create token factor to keep old chain connected. - SDValue Token = DAG.getNode(ISD::TokenFactor, MVT::Other, - Chain, ReplLoad.getValue(1)); + SDValue Token = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), + MVT::Other, Chain, ReplLoad.getValue(1)); // Replace uses with load result and token factor. Don't add users // to work list. @@ -4856,7 +4873,6 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { return SDValue(); } - SDValue DAGCombiner::visitSTORE(SDNode *N) { StoreSDNode *ST = cast(N); SDValue Chain = ST->getChain(); -- GitLab From 27d9dd4b5701ee29380121bbbef0075fd0ac9e0c Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 23:36:47 +0000 Subject: [PATCH 550/682] More DebugLoc propagation. llvm-svn: 63452 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 105 +++++++++++------- 1 file changed, 62 insertions(+), 43 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 2b7b26fff5c4..bf707601c435 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -4883,7 +4883,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { if (!Fast && ST->isUnindexed()) { if (unsigned Align = InferAlignment(Ptr, DAG)) { if (Align > ST->getAlignment()) - return DAG.getTruncStore(Chain, Value, Ptr, ST->getSrcValue(), + return DAG.getTruncStore(Chain, N->getDebugLoc(), Value, + Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), ST->isVolatile(), Align); } @@ -4900,7 +4901,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { if (Align <= OrigAlign && ((!LegalOperations && !ST->isVolatile()) || TLI.isOperationLegalOrCustom(ISD::STORE, SVT))) - return DAG.getStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(), + return DAG.getStore(Chain, N->getDebugLoc(), Value.getOperand(0), + Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), OrigAlign); } @@ -4924,7 +4926,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i32)) { Tmp = DAG.getConstant((uint32_t)CFP->getValueAPF(). bitcastToAPInt().getZExtValue(), MVT::i32); - return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), + return DAG.getStore(Chain, N->getDebugLoc(), Tmp, + Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); } @@ -4934,8 +4937,9 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { !ST->isVolatile()) || TLI.isOperationLegalOrCustom(ISD::STORE, MVT::i64)) { Tmp = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). - getZExtValue(), MVT::i64); - return DAG.getStore(Chain, Tmp, Ptr, ST->getSrcValue(), + getZExtValue(), MVT::i64); + return DAG.getStore(Chain, N->getDebugLoc(), Tmp, + Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); } else if (!ST->isVolatile() && @@ -4952,17 +4956,21 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { unsigned Alignment = ST->getAlignment(); bool isVolatile = ST->isVolatile(); - SDValue St0 = DAG.getStore(Chain, Lo, Ptr, ST->getSrcValue(), - ST->getSrcValueOffset(), - isVolatile, ST->getAlignment()); - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + SDValue St0 = DAG.getStore(Chain, ST->getDebugLoc(), Lo, + Ptr, ST->getSrcValue(), + ST->getSrcValueOffset(), + isVolatile, ST->getAlignment()); + Ptr = DAG.getNode(ISD::ADD, N->getDebugLoc(), Ptr.getValueType(), Ptr, DAG.getConstant(4, Ptr.getValueType())); SVOffset += 4; Alignment = MinAlign(Alignment, 4U); - SDValue St1 = DAG.getStore(Chain, Hi, Ptr, ST->getSrcValue(), - SVOffset, isVolatile, Alignment); - return DAG.getNode(ISD::TokenFactor, MVT::Other, St0, St1); + SDValue St1 = DAG.getStore(Chain, ST->getDebugLoc(), Hi, + Ptr, ST->getSrcValue(), + SVOffset, isVolatile, Alignment); + return DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other, + St0, St1); } + break; } } @@ -4977,20 +4985,20 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { // Replace the chain to avoid dependency. SDValue ReplStore; if (ST->isTruncatingStore()) { - ReplStore = DAG.getTruncStore(BetterChain, Value, Ptr, + ReplStore = DAG.getTruncStore(BetterChain, N->getDebugLoc(), Value, Ptr, ST->getSrcValue(),ST->getSrcValueOffset(), ST->getMemoryVT(), ST->isVolatile(), ST->getAlignment()); } else { - ReplStore = DAG.getStore(BetterChain, Value, Ptr, + ReplStore = DAG.getStore(BetterChain, N->getDebugLoc(), Value, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); } // Create token to keep both nodes around. - SDValue Token = - DAG.getNode(ISD::TokenFactor, MVT::Other, Chain, ReplStore); - + SDValue Token = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), + MVT::Other, Chain, ReplStore); + // Don't add users to work list. return CombineTo(N, Token, false); } @@ -5008,11 +5016,12 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { // "truncstore (or (shl x, 8), y), i8" -> "truncstore y, i8" SDValue Shorter = GetDemandedBits(Value, - APInt::getLowBitsSet(Value.getValueSizeInBits(), - ST->getMemoryVT().getSizeInBits())); + APInt::getLowBitsSet(Value.getValueSizeInBits(), + ST->getMemoryVT().getSizeInBits())); AddToWorkList(Value.getNode()); if (Shorter.getNode()) - return DAG.getTruncStore(Chain, Shorter, Ptr, ST->getSrcValue(), + return DAG.getTruncStore(Chain, N->getDebugLoc(), Shorter, + Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), ST->isVolatile(), ST->getAlignment()); @@ -5044,7 +5053,8 @@ SDValue DAGCombiner::visitSTORE(SDNode *N) { && Value.getNode()->hasOneUse() && ST->isUnindexed() && TLI.isTruncStoreLegal(Value.getOperand(0).getValueType(), ST->getMemoryVT())) { - return DAG.getTruncStore(Chain, Value.getOperand(0), Ptr, ST->getSrcValue(), + return DAG.getTruncStore(Chain, N->getDebugLoc(), Value.getOperand(0), + Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), ST->isVolatile(), ST->getAlignment()); } @@ -5065,8 +5075,8 @@ SDValue DAGCombiner::visitINSERT_VECTOR_ELT(SDNode *N) { InVec.getNode()->op_end()); if (Elt < Ops.size()) Ops[Elt] = InVal; - return DAG.getNode(ISD::BUILD_VECTOR, InVec.getValueType(), - &Ops[0], Ops.size()); + return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), + InVec.getValueType(), &Ops[0], Ops.size()); } return SDValue(); @@ -5095,6 +5105,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { MVT VT = InVec.getValueType(); MVT EVT = VT.getVectorElementType(); MVT LVT = EVT; + if (InVec.getOpcode() == ISD::BIT_CONVERT) { MVT BCVT = InVec.getOperand(0).getValueType(); if (!BCVT.isVector() || EVT.bitsGT(BCVT.getVectorElementType())) @@ -5107,11 +5118,11 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { } LoadSDNode *LN0 = NULL; - if (ISD::isNormalLoad(InVec.getNode())) + if (ISD::isNormalLoad(InVec.getNode())) { LN0 = cast(InVec); - else if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR && - InVec.getOperand(0).getValueType() == EVT && - ISD::isNormalLoad(InVec.getOperand(0).getNode())) { + } else if (InVec.getOpcode() == ISD::SCALAR_TO_VECTOR && + InVec.getOperand(0).getValueType() == EVT && + ISD::isNormalLoad(InVec.getOperand(0).getNode())) { LN0 = cast(InVec.getOperand(0)); } else if (InVec.getOpcode() == ISD::VECTOR_SHUFFLE) { // (vextract (vector_shuffle (load $addr), v2, <1, u, u, u>), 1) @@ -5133,6 +5144,7 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { Elt = (Idx < NumElems) ? Idx : Idx - NumElems; } } + if (!LN0 || !LN0->hasOneUse() || LN0->isVolatile()) return SDValue(); @@ -5140,10 +5152,12 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { if (NewLoad) { // Check the resultant load doesn't need a higher alignment than the // original load. - unsigned NewAlign = TLI.getTargetData()-> - getABITypeAlignment(LVT.getTypeForMVT()); + unsigned NewAlign = + TLI.getTargetData()->getABITypeAlignment(LVT.getTypeForMVT()); + if (NewAlign > Align || !TLI.isOperationLegalOrCustom(ISD::LOAD, LVT)) return SDValue(); + Align = NewAlign; } @@ -5153,16 +5167,17 @@ SDValue DAGCombiner::visitEXTRACT_VECTOR_ELT(SDNode *N) { MVT PtrType = NewPtr.getValueType(); if (TLI.isBigEndian()) PtrOff = VT.getSizeInBits() / 8 - PtrOff; - NewPtr = DAG.getNode(ISD::ADD, PtrType, NewPtr, + NewPtr = DAG.getNode(ISD::ADD, N->getDebugLoc(), PtrType, NewPtr, DAG.getConstant(PtrOff, PtrType)); } - return DAG.getLoad(LVT, LN0->getChain(), NewPtr, + + return DAG.getLoad(LVT, N->getDebugLoc(), LN0->getChain(), NewPtr, LN0->getSrcValue(), LN0->getSrcValueOffset(), LN0->isVolatile(), Align); } + return SDValue(); } - SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { unsigned NumInScalars = N->getNumOperands(); @@ -5214,7 +5229,9 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { SmallVector BuildVecIndices; for (unsigned i = 0; i != NumInScalars; ++i) { if (N->getOperand(i).getOpcode() == ISD::UNDEF) { - BuildVecIndices.push_back(DAG.getNode(ISD::UNDEF, TLI.getPointerTy())); + BuildVecIndices.push_back(DAG.getNode(ISD::UNDEF, + DebugLoc::getUnknownLoc(), + TLI.getPointerTy())); continue; } @@ -5245,15 +5262,15 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { } else { // Use an undef build_vector as input for the second operand. std::vector UnOps(NumInScalars, - DAG.getNode(ISD::UNDEF, - EltType)); - Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, VT, + DAG.getNode(ISD::UNDEF, EltType)); + Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, &UnOps[0], UnOps.size()); AddToWorkList(Ops[1].getNode()); } - Ops[2] = DAG.getNode(ISD::BUILD_VECTOR, BuildVecVT, + + Ops[2] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), BuildVecVT, &BuildVecIndices[0], BuildVecIndices.size()); - return DAG.getNode(ISD::VECTOR_SHUFFLE, VT, Ops, 3); + return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), VT, Ops, 3); } return SDValue(); @@ -5266,9 +5283,8 @@ SDValue DAGCombiner::visitCONCAT_VECTORS(SDNode *N) { // node. // If we only have one input vector, we don't need to do any concatenation. - if (N->getNumOperands() == 1) { + if (N->getNumOperands() == 1) return N->getOperand(0); - } return SDValue(); } @@ -5381,6 +5397,7 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { // Check the SHUFFLE mask, mapping any inputs from the 2nd operand into the // first operand. SmallVector MappedOps; + for (unsigned i = 0; i != NumElts; ++i) { if (ShufMask.getOperand(i).getOpcode() == ISD::UNDEF || cast(ShufMask.getOperand(i))->getZExtValue() < @@ -5394,11 +5411,13 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { ShufMask.getOperand(i).getValueType())); } } - ShufMask = DAG.getNode(ISD::BUILD_VECTOR, ShufMask.getValueType(), + + ShufMask = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), + ShufMask.getValueType(), &MappedOps[0], MappedOps.size()); AddToWorkList(ShufMask.getNode()); - return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getValueType(0), - N0, + return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), + N->getValueType(0), N0, DAG.getNode(ISD::UNDEF, N->getValueType(0)), ShufMask); } -- GitLab From 75e0351adbd54a87346761444d09f2a7d1276968 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Fri, 30 Jan 2009 23:51:52 +0000 Subject: [PATCH 551/682] Missed another mis-alignment of an objc2 meta-data. llvm-svn: 63453 --- clang/lib/CodeGen/CGObjCMac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 07a9df272cc6..b5e380496450 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3836,7 +3836,7 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( Init, Prefix + OID->getNameAsString(), &CGM.getModule()); - + GV->setAlignment(GetPointerAlign()); GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); -- GitLab From 31b50991cbcc99bc07e44b4580fd96d562804478 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 30 Jan 2009 23:59:18 +0000 Subject: [PATCH 552/682] More DebugLoc propagation. llvm-svn: 63454 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 207 ++++++++++-------- 1 file changed, 120 insertions(+), 87 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index bf707601c435..9b65d85ca36a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -202,10 +202,10 @@ namespace { bool SimplifySelectOps(SDNode *SELECT, SDValue LHS, SDValue RHS); SDValue SimplifyBinOpWithSameOpcodeHands(SDNode *N); - SDValue SimplifySelect(SDValue N0, SDValue N1, SDValue N2); - SDValue SimplifySelectCC(SDValue N0, SDValue N1, SDValue N2, - SDValue N3, ISD::CondCode CC, - bool NotExtCompare = false); + SDValue SimplifySelect(DebugLoc DL, SDValue N0, SDValue N1, SDValue N2); + SDValue SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue N2, + SDValue N3, ISD::CondCode CC, + bool NotExtCompare = false); SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, bool foldBooleans = true); SDValue SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp, @@ -229,13 +229,13 @@ namespace { bool isAlias(SDValue Ptr1, int64_t Size1, const Value *SrcValue1, int SrcValueOffset1, SDValue Ptr2, int64_t Size2, - const Value *SrcValue2, int SrcValueOffset2); + const Value *SrcValue2, int SrcValueOffset2) const; /// FindAliasInfo - Extracts the relevant alias information from the memory /// node. Returns true if the operand was a load. bool FindAliasInfo(SDNode *N, SDValue &Ptr, int64_t &Size, - const Value *&SrcValue, int &SrcValueOffset); + const Value *&SrcValue, int &SrcValueOffset) const; /// FindBetterChain - Walk up chain skipping non-aliasing memory nodes, /// looking for a better chain (aliasing node.) @@ -2882,7 +2882,7 @@ SDValue DAGCombiner::visitSELECT(SDNode *N) { N0.getOperand(0), N0.getOperand(1), N1, N2, N0.getOperand(2)); else - return SimplifySelect(N0, N1, N2); + return SimplifySelect(N->getDebugLoc(), N0, N1, N2); } return SDValue(); @@ -2923,7 +2923,7 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) { return SDValue(N, 0); // Don't revisit N. // fold select_cc into other things, such as min/max/abs - return SimplifySelectCC(N0, N1, N2, N3, CC); + return SimplifySelectCC(N->getDebugLoc(), N0, N1, N2, N3, CC); } SDValue DAGCombiner::visitSETCC(SDNode *N) { @@ -3131,7 +3131,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { // sext(setcc x, y, cc) -> (select_cc x, y, -1, 0, cc) if (N0.getOpcode() == ISD::SETCC) { SDValue SCC = - SimplifySelectCC(N0.getOperand(0), N0.getOperand(1), + SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1), DAG.getConstant(~0ULL, VT), DAG.getConstant(0, VT), cast(N0.getOperand(2))->get(), true); if (SCC.getNode()) return SCC; @@ -3266,7 +3266,7 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { // zext(setcc x,y,cc) -> select_cc x, y, 1, 0, cc if (N0.getOpcode() == ISD::SETCC) { SDValue SCC = - SimplifySelectCC(N0.getOperand(0), N0.getOperand(1), + SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1), DAG.getConstant(1, VT), DAG.getConstant(0, VT), cast(N0.getOperand(2))->get(), true); if (SCC.getNode()) return SCC; @@ -3374,7 +3374,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { // aext(setcc x,y,cc) -> select_cc x, y, 1, 0, cc if (N0.getOpcode() == ISD::SETCC) { SDValue SCC = - SimplifySelectCC(N0.getOperand(0), N0.getOperand(1), + SimplifySelectCC(N->getDebugLoc(), N0.getOperand(0), N0.getOperand(1), DAG.getConstant(1, VT), DAG.getConstant(0, VT), cast(N0.getOperand(2))->get(), true); if (SCC.getNode()) @@ -5460,21 +5460,25 @@ SDValue DAGCombiner::XformToShuffleWithZero(SDNode *N) { MVT VT = MVT::getVectorVT(EVT, NumElts); MVT MaskVT = MVT::getVectorVT(TLI.getPointerTy(), NumElts); std::vector Ops; - LHS = DAG.getNode(ISD::BIT_CONVERT, VT, LHS); + LHS = DAG.getNode(ISD::BIT_CONVERT, DebugLoc::getUnknownLoc(), VT, LHS); Ops.push_back(LHS); AddToWorkList(LHS.getNode()); std::vector ZeroOps(NumElts, DAG.getConstant(0, EVT)); - Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, VT, - &ZeroOps[0], ZeroOps.size())); - Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, MaskVT, - &IdxOps[0], IdxOps.size())); - SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, VT, - &Ops[0], Ops.size()); + Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), + VT, &ZeroOps[0], ZeroOps.size())); + Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), + MaskVT, &IdxOps[0], IdxOps.size())); + SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), + VT, &Ops[0], Ops.size()); + if (VT != N->getValueType(0)) - Result = DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Result); + Result = DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), + N->getValueType(0), Result); + return Result; } } + return SDValue(); } @@ -5510,6 +5514,7 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { RHSOp.getOpcode() != ISD::Constant && RHSOp.getOpcode() != ISD::ConstantFP)) break; + // Can't fold divide by zero. if (N->getOpcode() == ISD::SDIV || N->getOpcode() == ISD::UDIV || N->getOpcode() == ISD::FDIV) { @@ -5519,7 +5524,9 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { cast(RHSOp.getNode())->getValueAPF().isZero())) break; } - Ops.push_back(DAG.getNode(N->getOpcode(), EltType, LHSOp, RHSOp)); + + Ops.push_back(DAG.getNode(N->getOpcode(), DebugLoc::getUnknownLoc(), + EltType, LHSOp, RHSOp)); AddToWorkList(Ops.back().getNode()); assert((Ops.back().getOpcode() == ISD::UNDEF || Ops.back().getOpcode() == ISD::Constant || @@ -5529,18 +5536,21 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { if (Ops.size() == LHS.getNumOperands()) { MVT VT = LHS.getValueType(); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); + return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, + &Ops[0], Ops.size()); } } return SDValue(); } -SDValue DAGCombiner::SimplifySelect(SDValue N0, SDValue N1, SDValue N2){ +SDValue DAGCombiner::SimplifySelect(DebugLoc DL, SDValue N0, + SDValue N1, SDValue N2){ assert(N0.getOpcode() ==ISD::SETCC && "First argument must be a SetCC node!"); - SDValue SCC = SimplifySelectCC(N0.getOperand(0), N0.getOperand(1), N1, N2, + SDValue SCC = SimplifySelectCC(DL, N0.getOperand(0), N0.getOperand(1), N1, N2, cast(N0.getOperand(2))->get()); + // If we got a simplified select_cc node back from SimplifySelectCC, then // break it down into a new SETCC node, and a new SELECT node, and then return // the SELECT node, since we were called with a SELECT node. @@ -5548,13 +5558,15 @@ SDValue DAGCombiner::SimplifySelect(SDValue N0, SDValue N1, SDValue N2){ // Check to see if we got a select_cc back (to turn into setcc/select). // Otherwise, just return whatever node we got back, like fabs. if (SCC.getOpcode() == ISD::SELECT_CC) { - SDValue SETCC = DAG.getNode(ISD::SETCC, N0.getValueType(), - SCC.getOperand(0), SCC.getOperand(1), - SCC.getOperand(4)); + SDValue SETCC = DAG.getNode(ISD::SETCC, N0.getDebugLoc(), + N0.getValueType(), + SCC.getOperand(0), SCC.getOperand(1), + SCC.getOperand(4)); AddToWorkList(SETCC.getNode()); - return DAG.getNode(ISD::SELECT, SCC.getValueType(), SCC.getOperand(2), - SCC.getOperand(3), SETCC); + return DAG.getNode(ISD::SELECT, SCC.getDebugLoc(), SCC.getValueType(), + SCC.getOperand(2), SCC.getOperand(3), SETCC); } + return SCC; } return SDValue(); @@ -5566,7 +5578,6 @@ SDValue DAGCombiner::SimplifySelect(SDValue N0, SDValue N1, SDValue N2){ /// returns true. As such, they should return the appropriate thing (e.g. the /// node) back to the top-level of the DAG combiner loop to avoid it being /// looked at. -/// bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, SDValue RHS) { @@ -5597,7 +5608,8 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, // this will induce a cycle into the DAG. if (!LLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode())) { - Addr = DAG.getNode(ISD::SELECT, LLD->getBasePtr().getValueType(), + Addr = DAG.getNode(ISD::SELECT, TheSelect->getDebugLoc(), + LLD->getBasePtr().getValueType(), TheSelect->getOperand(0), LLD->getBasePtr(), RLD->getBasePtr()); } @@ -5608,24 +5620,28 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, !RLD->isPredecessorOf(TheSelect->getOperand(0).getNode()) && !LLD->isPredecessorOf(TheSelect->getOperand(1).getNode()) && !RLD->isPredecessorOf(TheSelect->getOperand(1).getNode())) { - Addr = DAG.getNode(ISD::SELECT_CC, LLD->getBasePtr().getValueType(), - TheSelect->getOperand(0), - TheSelect->getOperand(1), - LLD->getBasePtr(), RLD->getBasePtr(), - TheSelect->getOperand(4)); + Addr = DAG.getNode(ISD::SELECT_CC, TheSelect->getDebugLoc(), + LLD->getBasePtr().getValueType(), + TheSelect->getOperand(0), + TheSelect->getOperand(1), + LLD->getBasePtr(), RLD->getBasePtr(), + TheSelect->getOperand(4)); } } if (Addr.getNode()) { SDValue Load; - if (LLD->getExtensionType() == ISD::NON_EXTLOAD) - Load = DAG.getLoad(TheSelect->getValueType(0), LLD->getChain(), + if (LLD->getExtensionType() == ISD::NON_EXTLOAD) { + Load = DAG.getLoad(TheSelect->getValueType(0), + TheSelect->getDebugLoc(), + LLD->getChain(), Addr,LLD->getSrcValue(), LLD->getSrcValueOffset(), LLD->isVolatile(), LLD->getAlignment()); - else { + } else { Load = DAG.getExtLoad(LLD->getExtensionType(), + TheSelect->getDebugLoc(), TheSelect->getValueType(0), LLD->getChain(), Addr, LLD->getSrcValue(), LLD->getSrcValueOffset(), @@ -5633,6 +5649,7 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, LLD->isVolatile(), LLD->getAlignment()); } + // Users of the select now use the result of the load. CombineTo(TheSelect, Load); @@ -5649,10 +5666,9 @@ bool DAGCombiner::SimplifySelectOps(SDNode *TheSelect, SDValue LHS, return false; } -SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, +SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue N2, SDValue N3, ISD::CondCode CC, bool NotExtCompare) { - MVT VT = N2.getValueType(); ConstantSDNode *N1C = dyn_cast(N1.getNode()); ConstantSDNode *N2C = dyn_cast(N2.getNode()); @@ -5679,18 +5695,18 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, if ((CC == ISD::SETGE || CC == ISD::SETGT) && N0 == N2 && N3.getOpcode() == ISD::FNEG && N2 == N3.getOperand(0)) - return DAG.getNode(ISD::FABS, VT, N0); + return DAG.getNode(ISD::FABS, DL, VT, N0); // select (setl[te] X, +/-0.0), fneg(X), X -> fabs if ((CC == ISD::SETLT || CC == ISD::SETLE) && N0 == N3 && N2.getOpcode() == ISD::FNEG && N2.getOperand(0) == N3) - return DAG.getNode(ISD::FABS, VT, N3); + return DAG.getNode(ISD::FABS, DL, VT, N3); } } // Check to see if we can perform the "gzip trick", transforming - // select_cc setlt X, 0, A, 0 -> and (sra X, size(X)-1), A + // (select_cc setlt X, 0, A, 0) -> (and (sra X, (sub size(X), 1), A) if (N1C && N3C && N3C->isNullValue() && CC == ISD::SETLT && N0.getValueType().isInteger() && N2.getValueType().isInteger() && @@ -5705,23 +5721,32 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, unsigned ShCtV = N2C->getAPIntValue().logBase2(); ShCtV = XType.getSizeInBits()-ShCtV-1; SDValue ShCt = DAG.getConstant(ShCtV, TLI.getShiftAmountTy()); - SDValue Shift = DAG.getNode(ISD::SRL, XType, N0, ShCt); + SDValue Shift = DAG.getNode(ISD::SRL, DebugLoc::getUnknownLoc(), + XType, N0, ShCt); AddToWorkList(Shift.getNode()); + if (XType.bitsGT(AType)) { - Shift = DAG.getNode(ISD::TRUNCATE, AType, Shift); + Shift = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), + AType, Shift); AddToWorkList(Shift.getNode()); } - return DAG.getNode(ISD::AND, AType, Shift, N2); + + return DAG.getNode(ISD::AND, DL, AType, Shift, N2); } - SDValue Shift = DAG.getNode(ISD::SRA, XType, N0, - DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); + + SDValue Shift = DAG.getNode(ISD::SRA, DebugLoc::getUnknownLoc(), + XType, N0, + DAG.getConstant(XType.getSizeInBits()-1, + TLI.getShiftAmountTy())); AddToWorkList(Shift.getNode()); + if (XType.bitsGT(AType)) { - Shift = DAG.getNode(ISD::TRUNCATE, AType, Shift); + Shift = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), + AType, Shift); AddToWorkList(Shift.getNode()); } - return DAG.getNode(ISD::AND, AType, Shift, N2); + + return DAG.getNode(ISD::AND, DL, AType, Shift, N2); } } @@ -5740,23 +5765,29 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, SDValue Temp, SCC; // cast from setcc result type to select result type if (LegalTypes) { - SCC = DAG.getSetCC(TLI.getSetCCResultType(N0.getValueType()), + SCC = DAG.getSetCC(DebugLoc::getUnknownLoc(), + TLI.getSetCCResultType(N0.getValueType()), N0, N1, CC); if (N2.getValueType().bitsLT(SCC.getValueType())) - Temp = DAG.getZeroExtendInReg(SCC, N2.getValueType()); + Temp = DAG.getZeroExtendInReg(SCC, DebugLoc::getUnknownLoc(), + N2.getValueType()); else - Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getValueType(), SCC); + Temp = DAG.getNode(ISD::ZERO_EXTEND, DebugLoc::getUnknownLoc(), + N2.getValueType(), SCC); } else { - SCC = DAG.getSetCC(MVT::i1, N0, N1, CC); - Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getValueType(), SCC); + SCC = DAG.getSetCC(DebugLoc::getUnknownLoc(), MVT::i1, N0, N1, CC); + Temp = DAG.getNode(ISD::ZERO_EXTEND, DebugLoc::getUnknownLoc(), + N2.getValueType(), SCC); } + AddToWorkList(SCC.getNode()); AddToWorkList(Temp.getNode()); if (N2C->getAPIntValue() == 1) return Temp; + // shl setcc result by log2 n2c - return DAG.getNode(ISD::SHL, N2.getValueType(), Temp, + return DAG.getNode(ISD::SHL, DL, N2.getValueType(), Temp, DAG.getConstant(N2C->getAPIntValue().logBase2(), TLI.getShiftAmountTy())); } @@ -5768,37 +5799,38 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, MVT XType = N0.getValueType(); if (!LegalOperations || TLI.isOperationLegal(ISD::SETCC, TLI.getSetCCResultType(XType))) { - SDValue Res = DAG.getSetCC(TLI.getSetCCResultType(XType), N0, N1, CC); + SDValue Res = DAG.getSetCC(DL, TLI.getSetCCResultType(XType), N0, N1, CC); if (Res.getValueType() != VT) - Res = DAG.getNode(ISD::ZERO_EXTEND, VT, Res); + Res = DAG.getNode(ISD::ZERO_EXTEND, DL, VT, Res); return Res; } - // seteq X, 0 -> srl (ctlz X, log2(size(X))) + // fold (seteq X, 0) -> (srl (ctlz X, log2(size(X)))) if (N1C && N1C->isNullValue() && CC == ISD::SETEQ && (!LegalOperations || TLI.isOperationLegal(ISD::CTLZ, XType))) { - SDValue Ctlz = DAG.getNode(ISD::CTLZ, XType, N0); - return DAG.getNode(ISD::SRL, XType, Ctlz, + SDValue Ctlz = DAG.getNode(ISD::CTLZ, DebugLoc::getUnknownLoc(), + XType, N0); + return DAG.getNode(ISD::SRL, DL, XType, Ctlz, DAG.getConstant(Log2_32(XType.getSizeInBits()), TLI.getShiftAmountTy())); } - // setgt X, 0 -> srl (and (-X, ~X), size(X)-1) + // fold (setgt X, 0) -> (srl (and (-X, ~X), size(X)-1)) if (N1C && N1C->isNullValue() && CC == ISD::SETGT) { - SDValue NegN0 = DAG.getNode(ISD::SUB, XType, DAG.getConstant(0, XType), - N0); + SDValue NegN0 = DAG.getNode(ISD::SUB, N0.getDebugLoc(), + XType, DAG.getConstant(0, XType), N0); SDValue NotN0 = DAG.getNOT(N0.getDebugLoc(), N0, XType); - return DAG.getNode(ISD::SRL, XType, + return DAG.getNode(ISD::SRL, DL, XType, DAG.getNode(ISD::AND, XType, NegN0, NotN0), DAG.getConstant(XType.getSizeInBits()-1, TLI.getShiftAmountTy())); } - // setgt X, -1 -> xor (srl (X, size(X)-1), 1) + // fold (setgt X, -1) -> (xor (srl (X, size(X)-1), 1)) if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT) { - SDValue Sign = DAG.getNode(ISD::SRL, XType, N0, - DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); - return DAG.getNode(ISD::XOR, XType, Sign, DAG.getConstant(1, XType)); + SDValue Sign = DAG.getNode(ISD::SRL, DebugLoc::getUnknownLoc(), XType, N0, + DAG.getConstant(XType.getSizeInBits()-1, + TLI.getShiftAmountTy())); + return DAG.getNode(ISD::XOR, DL, XType, Sign, DAG.getConstant(1, XType)); } } @@ -5808,13 +5840,14 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, N0 == N3 && N2.getOpcode() == ISD::SUB && N0 == N2.getOperand(1) && N2.getOperand(0) == N1 && N0.getValueType().isInteger()) { MVT XType = N0.getValueType(); - SDValue Shift = DAG.getNode(ISD::SRA, XType, N0, - DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); - SDValue Add = DAG.getNode(ISD::ADD, XType, N0, Shift); + SDValue Shift = DAG.getNode(ISD::SRA, DebugLoc::getUnknownLoc(), XType, N0, + DAG.getConstant(XType.getSizeInBits()-1, + TLI.getShiftAmountTy())); + SDValue Add = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), XType, + N0, Shift); AddToWorkList(Shift.getNode()); AddToWorkList(Add.getNode()); - return DAG.getNode(ISD::XOR, XType, Add, Shift); + return DAG.getNode(ISD::XOR, DL, XType, Add, Shift); } // Check to see if this is an integer abs. select_cc setgt X, -1, X, -X -> // Y = sra (X, size(X)-1); xor (add (X, Y), Y) @@ -5823,13 +5856,15 @@ SDValue DAGCombiner::SimplifySelectCC(SDValue N0, SDValue N1, if (ConstantSDNode *SubC = dyn_cast(N3.getOperand(0))) { MVT XType = N0.getValueType(); if (SubC->isNullValue() && XType.isInteger()) { - SDValue Shift = DAG.getNode(ISD::SRA, XType, N0, - DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); - SDValue Add = DAG.getNode(ISD::ADD, XType, N0, Shift); + SDValue Shift = DAG.getNode(ISD::SRA, DebugLoc::getUnknownLoc(), XType, + N0, + DAG.getConstant(XType.getSizeInBits()-1, + TLI.getShiftAmountTy())); + SDValue Add = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), + XType, N0, Shift); AddToWorkList(Shift.getNode()); AddToWorkList(Add.getNode()); - return DAG.getNode(ISD::XOR, XType, Add, Shift); + return DAG.getNode(ISD::XOR, DL, XType, Add, Shift); } } } @@ -5899,8 +5934,7 @@ static bool FindBaseOffset(SDValue Ptr, SDValue &Base, int64_t &Offset) { bool DAGCombiner::isAlias(SDValue Ptr1, int64_t Size1, const Value *SrcValue1, int SrcValueOffset1, SDValue Ptr2, int64_t Size2, - const Value *SrcValue2, int SrcValueOffset2) -{ + const Value *SrcValue2, int SrcValueOffset2) const { // If they are the same then they must be aliases. if (Ptr1 == Ptr2) return true; @@ -5911,10 +5945,9 @@ bool DAGCombiner::isAlias(SDValue Ptr1, int64_t Size1, bool KnownBase2 = FindBaseOffset(Ptr2, Base2, Offset2); // If they have a same base address then... - if (Base1 == Base2) { + if (Base1 == Base2) // Check to see if the addresses overlap. - return!((Offset1 + Size1) <= Offset2 || (Offset2 + Size2) <= Offset1); - } + return !((Offset1 + Size1) <= Offset2 || (Offset2 + Size2) <= Offset1); // If we know both bases then they can't alias. if (KnownBase1 && KnownBase2) return false; @@ -5938,7 +5971,7 @@ bool DAGCombiner::isAlias(SDValue Ptr1, int64_t Size1, /// node. Returns true if the operand was a load. bool DAGCombiner::FindAliasInfo(SDNode *N, SDValue &Ptr, int64_t &Size, - const Value *&SrcValue, int &SrcValueOffset) { + const Value *&SrcValue, int &SrcValueOffset) const { if (LoadSDNode *LD = dyn_cast(N)) { Ptr = LD->getBasePtr(); Size = LD->getMemoryVT().getSizeInBits() >> 3; -- GitLab From 34aa3ca8c45ded46181f222367d696982d3b7f9a Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 31 Jan 2009 00:06:58 +0000 Subject: [PATCH 553/682] x86_64 ABI: Retool classification to compute lo & hi classifications in terms of where the type resides in the containing object. This is a more clear embodiement of the spec & fixes a merging issue with unions. Down to 3/1000 failures. llvm-svn: 63455 --- clang/lib/CodeGen/CGCall.cpp | 165 ++++++++++++++++++----------------- 1 file changed, 86 insertions(+), 79 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 666d427a254f..0807caff9bea 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -388,7 +388,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, } namespace { -/// X86_32ABIInfo - The X86_64 ABI information. +/// X86_64ABIInfo - The X86_64 ABI information. class X86_64ABIInfo : public ABIInfo { enum Class { Integer = 0, @@ -403,20 +403,25 @@ class X86_64ABIInfo : public ABIInfo { /// merge - Implement the X86_64 ABI merging algorithm. /// - /// \param Offset - The offset of the current field. - /// \param FieldLo - The low classification of the current field. - /// \param FieldHi - The high classification of the current field. - /// \param Lo [in] [out] - The accumulated low classification. - /// \param Lo [in] [out] - The accumulated high classification. - void merge(uint64_t Offset, Class FieldLo, Class FieldHi, - Class &Lo, Class &Hi) const; + /// Merge an accumulating classification \arg Accum with a field + /// classification \arg Field. + /// + /// \param Accum - The accumulating classification. This should + /// always be either NoClass or the result of a previous merge + /// call. In addition, this should never be Memory (the caller + /// should just return Memory for the aggregate). + Class merge(Class Accum, Class Field) const; /// classify - Determine the x86_64 register classes in which the /// given type T should be passed. /// - /// \param Lo - The classification for the low word of the type. - /// \param Hi - The classification for the high word of the type. - /// \param OffsetBase - The bit offset of the field in the + /// \param Lo - The classification for the parts of the type + /// residing in the low word of the containing object. + /// + /// \param Hi - The classification for the parts of the type + /// residing in the high word of the containing object. + /// + /// \param OffsetBase - The bit offset of this type in the /// containing object. Some parameters are classified different /// depending on whether they straddle an eightbyte boundary. /// @@ -430,7 +435,7 @@ class X86_64ABIInfo : public ABIInfo { /// be NoClass. void classify(QualType T, ASTContext &Context, uint64_t OffsetBase, Class &Lo, Class &Hi) const; - + public: virtual ABIArgInfo classifyReturnType(QualType RetTy, ASTContext &Context) const; @@ -440,18 +445,8 @@ public: }; } -void X86_64ABIInfo::merge(uint64_t Offset, Class FieldLo, Class FieldHi, - Class &Lo, Class &Hi) const { - // Determine which half of the structure we are classifying. - // - // AMD64-ABI 3.2.3p2: Rule 3. f the size of the aggregate - // exceeds a single eightbyte, each is classified - // separately. Each eightbyte gets initialized to class - // NO_CLASS. - Class &Target = Offset < 64 ? Lo : Hi; - - // Merge the lo field classifcation. - // +X86_64ABIInfo::Class X86_64ABIInfo::merge(Class Accum, + Class Field) const { // AMD64-ABI 3.2.3p2: Rule 4. Each field of an object is // classified recursively so that always two fields are // considered. The resulting class is calculated according to @@ -472,62 +467,59 @@ void X86_64ABIInfo::merge(uint64_t Offset, Class FieldLo, Class FieldHi, // MEMORY is used as class. // // (f) Otherwise class SSE is used. - if (Target == FieldLo || FieldLo == NoClass) ; - else if (FieldLo == Memory) - Lo = Memory; - else if (Target == NoClass) - Target = FieldLo; - else if (Target == Integer || FieldLo == Integer) - Target = Integer; - else if (FieldLo == X87 || FieldLo == X87Up || FieldLo == ComplexX87) - Lo = Memory; + assert((Accum == NoClass || Accum == Integer || + Accum == SSE || Accum == SSEUp) && + "Invalid accumulated classification during merge."); + if (Accum == Field || Field == NoClass) + return Accum; + else if (Field == Memory) + return Memory; + else if (Accum == NoClass) + return Field; + else if (Accum == Integer || Field == Integer) + return Integer; + else if (Field == X87 || Field == X87Up || Field == ComplexX87) + return Memory; else - Target = SSE; - - // It isn't clear from the ABI spec what the role of the high - // classification is here, but since this should only happen - // when we have a struct with a two eightbyte member, we can - // just push the field high class into the overall high class. - if (FieldHi != NoClass) - Hi = FieldHi; + return SSE; } void X86_64ABIInfo::classify(QualType Ty, ASTContext &Context, uint64_t OffsetBase, Class &Lo, Class &Hi) const { - Lo = Memory; - Hi = NoClass; + Lo = Hi = NoClass; + + Class &Current = OffsetBase < 64 ? Lo : Hi; + Current = Memory; + if (const BuiltinType *BT = Ty->getAsBuiltinType()) { BuiltinType::Kind k = BT->getKind(); if (k == BuiltinType::Void) { - Lo = NoClass; + Current = NoClass; } else if (k >= BuiltinType::Bool && k <= BuiltinType::LongLong) { - Lo = Integer; + Current = Integer; } else if (k == BuiltinType::Float || k == BuiltinType::Double) { - Lo = SSE; + Current = SSE; } else if (k == BuiltinType::LongDouble) { Lo = X87; Hi = X87Up; } - // FIXME: _Decimal32 and _Decimal64 are SSE. // FIXME: _float128 and _Decimal128 are (SSE, SSEUp). // FIXME: __int128 is (Integer, Integer). } else if (Ty->isPointerLikeType() || Ty->isBlockPointerType() || Ty->isObjCQualifiedInterfaceType()) { - Lo = Integer; + Current = Integer; } else if (const VectorType *VT = Ty->getAsVectorType()) { uint64_t Size = Context.getTypeSize(VT); if (Size == 64) { // gcc passes <1 x double> in memory. - if (VT->getElementType() == Context.DoubleTy) { - Lo = Memory; + if (VT->getElementType() == Context.DoubleTy) return; - } - Lo = SSE; + Current = SSE; // If this type crosses an eightbyte boundary, it should be // split. @@ -543,15 +535,15 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t Size = Context.getTypeSize(Ty); if (ET->isIntegerType()) { if (Size <= 64) - Lo = Integer; + Current = Integer; else if (Size <= 128) Lo = Hi = Integer; } else if (ET == Context.FloatTy) - Lo = SSE; + Current = SSE; else if (ET == Context.DoubleTy) Lo = Hi = SSE; else if (ET == Context.LongDoubleTy) - Lo = ComplexX87; + Current = ComplexX87; // If this complex type crosses an eightbyte boundary then it // should be split. @@ -573,25 +565,27 @@ void X86_64ABIInfo::classify(QualType Ty, // fields, it has class MEMORY. // // Only need to check alignment of array base. - if (OffsetBase % Context.getTypeAlign(AT->getElementType())) { - Lo = Memory; + if (OffsetBase % Context.getTypeAlign(AT->getElementType())) return; - } // Otherwise implement simplified merge. We could be smarter about // this, but it isn't worth it and would be harder to verify. - Lo = NoClass; + Current = NoClass; uint64_t EltSize = Context.getTypeSize(AT->getElementType()); uint64_t ArraySize = AT->getSize().getZExtValue(); for (uint64_t i=0, Offset=OffsetBase; igetElementType(), Context, Offset, FieldLo, FieldHi); - - merge(Offset, FieldLo, FieldHi, Lo, Hi); - // Memory is never over-ridden, exit early if we see it. - if (Lo == Memory) - return; + Lo = merge(Lo, FieldLo); + Hi = merge(Hi, FieldHi); + if (Lo == Memory || Hi == Memory) + break; } + + // Do post merger cleanup (see below). Only case we worry about is Memory. + if (Hi == Memory) + Lo = Memory; + assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp array classification."); } else if (const RecordType *RT = Ty->getAsRecordType()) { uint64_t Size = Context.getTypeSize(Ty); @@ -609,7 +603,7 @@ void X86_64ABIInfo::classify(QualType Ty, const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); // Reset Lo class, this will be recomputed. - Lo = NoClass; + Current = NoClass; unsigned idx = 0; for (RecordDecl::field_iterator i = RD->field_begin(), e = RD->field_end(); i != e; ++i, ++idx) { @@ -623,13 +617,17 @@ void X86_64ABIInfo::classify(QualType Ty, } // Classify this field. + // + // AMD64-ABI 3.2.3p2: Rule 3. If the size of the aggregate + // exceeds a single eightbyte, each is classified + // separately. Each eightbyte gets initialized to class + // NO_CLASS. Class FieldLo, FieldHi; classify(i->getType(), Context, Offset, FieldLo, FieldHi); - - merge(Offset, FieldLo, FieldHi, Lo, Hi); - // Memory is never over-ridden, exit early if we see it. - if (Lo == Memory) - return; + Lo = merge(Lo, FieldLo); + Hi = merge(Hi, FieldHi); + if (Lo == Memory || Hi == Memory) + break; } // AMD64-ABI 3.2.3p2: Rule 5. Then a post merger cleanup is done: @@ -640,14 +638,18 @@ void X86_64ABIInfo::classify(QualType Ty, // (b) If SSEUP is not preceeded by SSE, it is converted to SSE. // The first of these conditions is guaranteed by how we implement - // the merge (just bail). I don't believe the second is actually - // possible at all. - assert(Lo != Memory && "Unexpected memory classification."); + // the merge (just bail). + // + // The second condition occurs in the case of unions; for example + // union { _Complex double; unsigned; }. + if (Hi == Memory) + Lo = Memory; if (Hi == SSEUp && Lo != SSE) - Hi = SSE; + Hi = SSE; } } + ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy, ASTContext &Context) const { // AMD64-ABI 3.2.3p4: Rule 1. Classify the return type with the @@ -655,6 +657,11 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy, X86_64ABIInfo::Class Lo, Hi; classify(RetTy, Context, 0, Lo, Hi); + // Check some invariants. + assert((Hi != Memory || Lo == Memory) && "Invalid memory classification."); + assert((Lo != NoClass || Hi == NoClass) && "Invalid null classification."); + assert((Hi != SSEUp || Lo == SSE) && "Invalid SSEUp classification."); + const llvm::Type *ResType = 0; switch (Lo) { case NoClass: @@ -664,8 +671,8 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy, case X87Up: assert(0 && "Invalid classification for lo word."); - // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via - // hidden argument, i.e. structret. + // AMD64-ABI 3.2.3p4: Rule 2. Types of class memory are returned via + // hidden argument, i.e. structret. case Memory: return ABIArgInfo::getStructRet(); @@ -684,9 +691,9 @@ ABIArgInfo X86_64ABIInfo::classifyReturnType(QualType RetTy, case X87: ResType = llvm::Type::X86_FP80Ty; break; - // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real - // part of the value is returned in %st0 and the imaginary part in - // %st1. + // AMD64-ABI 3.2.3p4: Rule 8. If the class is COMPLEX_X87, the real + // part of the value is returned in %st0 and the imaginary part in + // %st1. case ComplexX87: assert(Hi == NoClass && "Unexpected ComplexX87 classification."); ResType = llvm::VectorType::get(llvm::Type::X86_FP80Ty, 2); -- GitLab From c9108895111db788c994a005a7c8c9dee80105ed Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 00:11:23 +0000 Subject: [PATCH 554/682] Propagate debug info through MakeLibCall and a couple of things that use it. llvm-svn: 63456 --- .../SelectionDAG/LegalizeFloatTypes.cpp | 85 ++++++++++--------- .../SelectionDAG/LegalizeIntegerTypes.cpp | 38 ++++++--- .../CodeGen/SelectionDAG/LegalizeTypes.cpp | 15 ++-- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 7 +- 4 files changed, 81 insertions(+), 64 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 837955117298..d95853846b89 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -132,7 +132,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { RTLIB::ADD_F64, RTLIB::ADD_F80, RTLIB::ADD_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { @@ -143,7 +143,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { RTLIB::CEIL_F64, RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { @@ -193,7 +193,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { RTLIB::COS_F64, RTLIB::COS_F80, RTLIB::COS_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { @@ -205,7 +205,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FDIV(SDNode *N) { RTLIB::DIV_F64, RTLIB::DIV_F80, RTLIB::DIV_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { @@ -216,7 +216,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP(SDNode *N) { RTLIB::EXP_F64, RTLIB::EXP_F80, RTLIB::EXP_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { @@ -227,7 +227,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FEXP2(SDNode *N) { RTLIB::EXP2_F64, RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { @@ -238,7 +238,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FFLOOR(SDNode *N) { RTLIB::FLOOR_F64, RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { @@ -249,7 +249,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG(SDNode *N) { RTLIB::LOG_F64, RTLIB::LOG_F80, RTLIB::LOG_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { @@ -260,7 +260,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG2(SDNode *N) { RTLIB::LOG2_F64, RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { @@ -271,7 +271,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FLOG10(SDNode *N) { RTLIB::LOG10_F64, RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { @@ -283,7 +283,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FMUL(SDNode *N) { RTLIB::MUL_F64, RTLIB::MUL_F80, RTLIB::MUL_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { @@ -294,7 +294,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FNEARBYINT(SDNode *N) { RTLIB::NEARBYINT_F64, RTLIB::NEARBYINT_F80, RTLIB::NEARBYINT_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { @@ -307,7 +307,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FNEG(SDNode *N) { RTLIB::SUB_F64, RTLIB::SUB_F80, RTLIB::SUB_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { @@ -315,7 +315,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FP_EXTEND(SDNode *N) { SDValue Op = N->getOperand(0); RTLIB::Libcall LC = RTLIB::getFPEXT(Op.getValueType(), N->getValueType(0)); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_EXTEND!"); - return MakeLibCall(LC, NVT, &Op, 1, false); + return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { @@ -323,7 +323,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FP_ROUND(SDNode *N) { SDValue Op = N->getOperand(0); RTLIB::Libcall LC = RTLIB::getFPROUND(Op.getValueType(), N->getValueType(0)); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND!"); - return MakeLibCall(LC, NVT, &Op, 1, false); + return MakeLibCall(LC, NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { @@ -335,7 +335,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOW(SDNode *N) { RTLIB::POW_F64, RTLIB::POW_F80, RTLIB::POW_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { @@ -348,7 +348,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FPOWI(SDNode *N) { RTLIB::POWI_F64, RTLIB::POWI_F80, RTLIB::POWI_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { @@ -359,7 +359,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FRINT(SDNode *N) { RTLIB::RINT_F64, RTLIB::RINT_F80, RTLIB::RINT_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { @@ -370,7 +370,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSIN(SDNode *N) { RTLIB::SIN_F64, RTLIB::SIN_F80, RTLIB::SIN_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { @@ -381,7 +381,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSQRT(SDNode *N) { RTLIB::SQRT_F64, RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { @@ -393,7 +393,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FSUB(SDNode *N) { RTLIB::SUB_F64, RTLIB::SUB_F80, RTLIB::SUB_PPCF128), - NVT, Ops, 2, false); + NVT, Ops, 2, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { @@ -404,7 +404,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FTRUNC(SDNode *N) { RTLIB::TRUNC_F64, RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128), - NVT, &Op, 1, false); + NVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { @@ -455,6 +455,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { MVT SVT = N->getOperand(0).getValueType(); MVT RVT = N->getValueType(0); MVT NVT = MVT(); + DebugLoc dl = N->getDebugLoc(); // If the input is not legal, eg: i1 -> fp, then it needs to be promoted to // a larger type, eg: i8 -> fp. Even if it is legal, no libcall may exactly @@ -472,7 +473,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { // Sign/zero extend the argument if the libcall takes a larger type. SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, NVT, N->getOperand(0)); - return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false); + return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false, dl); } @@ -522,7 +523,7 @@ bool DAGTypeLegalizer::SoftenFloatOperand(SDNode *N, unsigned OpNo) { /// SoftenSetCCOperands - Soften the operands of a comparison. This code is /// shared among BR_CC, SELECT_CC, and SETCC handlers. void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode) { + ISD::CondCode &CCCode, DebugLoc dl) { SDValue LHSInt = GetSoftenedFloat(NewLHS); SDValue RHSInt = GetSoftenedFloat(NewRHS); MVT VT = NewLHS.getValueType(); @@ -590,13 +591,13 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, MVT RetVT = MVT::i32; // FIXME: is this the correct return type? SDValue Ops[2] = { LHSInt, RHSInt }; - NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/); + NewLHS = MakeLibCall(LC1, RetVT, Ops, 2, false/*sign irrelevant*/, dl); NewRHS = DAG.getConstant(0, RetVT); CCCode = TLI.getCmpLibcallCC(LC1); if (LC2 != RTLIB::UNKNOWN_LIBCALL) { SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), NewLHS, NewRHS, DAG.getCondCode(CCCode)); - NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/); + NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl); NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), NewLHS, NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS); @@ -617,13 +618,13 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_ROUND(SDNode *N) { assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_ROUND libcall"); SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(LC, RVT, &Op, 1, false); + return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatOp_BR_CC(SDNode *N) { SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); ISD::CondCode CCCode = cast(N->getOperand(1))->get(); - SoftenSetCCOperands(NewLHS, NewRHS, CCCode); + SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If SoftenSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. @@ -643,7 +644,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_SINT(SDNode *N) { RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(LC, RVT, &Op, 1, false); + return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { @@ -651,13 +652,13 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_FP_TO_UINT(SDNode *N) { RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return MakeLibCall(LC, RVT, &Op, 1, false); + return MakeLibCall(LC, RVT, &Op, 1, false, N->getDebugLoc()); } SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(4))->get(); - SoftenSetCCOperands(NewLHS, NewRHS, CCCode); + SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If SoftenSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. @@ -675,7 +676,7 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_SELECT_CC(SDNode *N) { SDValue DAGTypeLegalizer::SoftenFloatOp_SETCC(SDNode *N) { SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(2))->get(); - SoftenSetCCOperands(NewLHS, NewRHS, CCCode); + SoftenSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If SoftenSetCCOperands returned a scalar, use it. if (NewRHS.getNode() == 0) { @@ -844,7 +845,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, RTLIB::DIV_F64, RTLIB::DIV_F80, RTLIB::DIV_PPCF128), - N->getValueType(0), Ops, 2, false); + N->getValueType(0), Ops, 2, false, + N->getDebugLoc()); assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); @@ -924,7 +926,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, RTLIB::MUL_F64, RTLIB::MUL_F80, RTLIB::MUL_PPCF128), - N->getValueType(0), Ops, 2, false); + N->getValueType(0), Ops, 2, false, + N->getDebugLoc()); assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); @@ -1020,7 +1023,8 @@ void DAGTypeLegalizer::ExpandFloatRes_FSUB(SDNode *N, SDValue &Lo, RTLIB::SUB_F64, RTLIB::SUB_F80, RTLIB::SUB_PPCF128), - N->getValueType(0), Ops, 2, false); + N->getValueType(0), Ops, 2, false, + N->getDebugLoc()); assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Call.getOperand(0); Hi = Call.getOperand(1); @@ -1077,6 +1081,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, SDValue Src = N->getOperand(0); MVT SrcVT = Src.getValueType(); bool isSigned = N->getOpcode() == ISD::SINT_TO_FP; + DebugLoc dl = N->getDebugLoc(); // First do an SINT_TO_FP, whether the original was signed or unsigned. // When promoting partial word types to i32 we must honor the signedness, @@ -1099,7 +1104,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, } assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); - Hi = MakeLibCall(LC, VT, &Src, 1, true); + Hi = MakeLibCall(LC, VT, &Src, 1, true, dl); assert(Hi.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); Lo = Hi.getOperand(0); Hi = Hi.getOperand(1); @@ -1259,7 +1264,8 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { MVT RVT = N->getValueType(0); - + DebugLoc dl = N->getDebugLoc(); + // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on // PPC (the libcall is not available). FIXME: Do this in a less hacky way. if (RVT == MVT::i32) { @@ -1273,11 +1279,12 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_SINT!"); - return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false); + return MakeLibCall(LC, RVT, &N->getOperand(0), 1, false, dl); } SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { MVT RVT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on // PPC (the libcall is not available). FIXME: Do this in a less hacky way. @@ -1303,7 +1310,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { RTLIB::Libcall LC = RTLIB::getFPTOUINT(N->getOperand(0).getValueType(), RVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported FP_TO_UINT!"); - return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false); + return MakeLibCall(LC, N->getValueType(0), &N->getOperand(0), 1, false, dl); } SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f9813b0bdda0..f5405d847389 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -1378,20 +1378,22 @@ void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_FP_TO_SINT(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); MVT VT = N->getValueType(0); SDValue Op = N->getOperand(0); RTLIB::Libcall LC = RTLIB::getFPTOSINT(Op.getValueType(), VT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-sint conversion!"); - SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*sign irrelevant*/), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, &Op, 1, true/*irrelevant*/, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_FP_TO_UINT(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); MVT VT = N->getValueType(0); SDValue Op = N->getOperand(0); RTLIB::Libcall LC = RTLIB::getFPTOUINT(Op.getValueType(), VT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unexpected fp-to-uint conversion!"); - SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*sign irrelevant*/), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, &Op, 1, false/*irrelevant*/, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, @@ -1516,6 +1518,7 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); + DebugLoc dl = N->getDebugLoc(); bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, NVT); bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, NVT); @@ -1598,12 +1601,13 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported MUL!"); SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*sign irrelevant*/), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, true/*irrelevant*/, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (VT == MVT::i32) @@ -1615,12 +1619,13 @@ void DAGTypeLegalizer::ExpandIntRes_SDIV(SDNode *N, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SDIV!"); SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); // If we can emit an efficient shift operation, do so now. Check to see if // the RHS is a constant. @@ -1698,7 +1703,7 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported shift!"); SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, isSigned, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, @@ -1757,6 +1762,7 @@ ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) { void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (VT == MVT::i32) @@ -1768,7 +1774,7 @@ void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported SREM!"); SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(LC, VT, Ops, 2, true), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, true, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, @@ -1784,6 +1790,7 @@ void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (VT == MVT::i32) @@ -1795,12 +1802,13 @@ void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UDIV!"); SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (VT == MVT::i32) @@ -1812,7 +1820,7 @@ void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported UREM!"); SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - SplitInteger(MakeLibCall(LC, VT, Ops, 2, false), Lo, Hi); + SplitInteger(MakeLibCall(LC, VT, Ops, 2, false, dl), Lo, Hi); } void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N, @@ -1899,7 +1907,8 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { /// is shared among BR_CC, SELECT_CC, and SETCC handlers. void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode) { + ISD::CondCode &CCCode, + DebugLoc dl) { SDValue LHSLo, LHSHi, RHSLo, RHSHi; GetExpandedInteger(NewLHS, LHSLo, LHSHi); GetExpandedInteger(NewRHS, RHSLo, RHSHi); @@ -1998,7 +2007,7 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) { SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); ISD::CondCode CCCode = cast(N->getOperand(1))->get(); - IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode); + IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If ExpandSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. @@ -2016,7 +2025,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_BR_CC(SDNode *N) { SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) { SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(4))->get(); - IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode); + IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If ExpandSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. @@ -2034,7 +2043,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SELECT_CC(SDNode *N) { SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) { SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(2))->get(); - IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode); + IntegerExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If ExpandSetCCOperands returned a scalar, use it. if (NewRHS.getNode() == 0) { @@ -2054,7 +2063,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) { RTLIB::Libcall LC = RTLIB::getSINTTOFP(Op.getValueType(), DstVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Don't know how to expand this SINT_TO_FP!"); - return MakeLibCall(LC, DstVT, &Op, 1, true); + return MakeLibCall(LC, DstVT, &Op, 1, true, N->getDebugLoc()); } SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { @@ -2147,6 +2156,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { SDValue Op = N->getOperand(0); MVT SrcVT = Op.getValueType(); MVT DstVT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){ // Do a signed conversion then adjust the result. @@ -2205,5 +2215,5 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { RTLIB::Libcall LC = RTLIB::getUINTTOFP(SrcVT, DstVT); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Don't know how to expand this UINT_TO_FP!"); - return MakeLibCall(LC, DstVT, &Op, 1, true); + return MakeLibCall(LC, DstVT, &Op, 1, true, dl); } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 7010814f634c..c88fd5d1dd83 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -951,27 +951,28 @@ SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { SDValue DAGTypeLegalizer::LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned) { unsigned NumOps = N->getNumOperands(); + DebugLoc dl = N->getDebugLoc(); if (NumOps == 0) { - return MakeLibCall(LC, N->getValueType(0), 0, 0, isSigned); + return MakeLibCall(LC, N->getValueType(0), 0, 0, isSigned, dl); } else if (NumOps == 1) { SDValue Op = N->getOperand(0); - return MakeLibCall(LC, N->getValueType(0), &Op, 1, isSigned); + return MakeLibCall(LC, N->getValueType(0), &Op, 1, isSigned, dl); } else if (NumOps == 2) { SDValue Ops[2] = { N->getOperand(0), N->getOperand(1) }; - return MakeLibCall(LC, N->getValueType(0), Ops, 2, isSigned); + return MakeLibCall(LC, N->getValueType(0), Ops, 2, isSigned, dl); } SmallVector Ops(NumOps); for (unsigned i = 0; i < NumOps; ++i) Ops[i] = N->getOperand(i); - return MakeLibCall(LC, N->getValueType(0), &Ops[0], NumOps, isSigned); + return MakeLibCall(LC, N->getValueType(0), &Ops[0], NumOps, isSigned, dl); } /// MakeLibCall - Generate a libcall taking the given operands as arguments and /// returning a result of type RetVT. SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT, const SDValue *Ops, unsigned NumOps, - bool isSigned) { + bool isSigned, DebugLoc dl) { TargetLowering::ArgListTy Args; Args.reserve(NumOps); @@ -987,11 +988,9 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT, TLI.getPointerTy()); const Type *RetTy = RetVT.getTypeForMVT(); - // FIXME pass in debug loc std::pair CallInfo = TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, - false, CallingConv::C, false, Callee, Args, DAG, - DebugLoc::getUnknownLoc()); + false, CallingConv::C, false, Callee, Args, DAG, dl); return CallInfo.first; } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 17b79233e49b..e7854d97b1cd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -196,7 +196,8 @@ private: SDValue JoinIntegers(SDValue Lo, SDValue Hi); SDValue LibCallify(RTLIB::Libcall LC, SDNode *N, bool isSigned); SDValue MakeLibCall(RTLIB::Libcall LC, MVT RetVT, - const SDValue *Ops, unsigned NumOps, bool isSigned); + const SDValue *Ops, unsigned NumOps, bool isSigned, + DebugLoc dl); SDValue PromoteTargetBoolean(SDValue Bool, MVT VT); void ReplaceValueWith(SDValue From, SDValue To); void ReplaceValueWithHelper(SDValue From, SDValue To); @@ -361,7 +362,7 @@ private: SDValue ExpandIntOp_UINT_TO_FP(SDNode *N); void IntegerExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode); + ISD::CondCode &CCCode, DebugLoc dl); //===--------------------------------------------------------------------===// // Float to Integer Conversion Support: LegalizeFloatTypes.cpp @@ -426,7 +427,7 @@ private: SDValue SoftenFloatOp_STORE(SDNode *N, unsigned OpNo); void SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode); + ISD::CondCode &CCCode, DebugLoc dl); //===--------------------------------------------------------------------===// // Float Expansion Support: LegalizeFloatTypes.cpp -- GitLab From 42aa385e20ee8526e0b229b7568f2d6ff0317231 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 00:20:43 +0000 Subject: [PATCH 555/682] Propagate debug info. This file complete (modulo bugs) llvm-svn: 63457 --- .../SelectionDAG/LegalizeIntegerTypes.cpp | 456 ++++++++++-------- 1 file changed, 255 insertions(+), 201 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f5405d847389..fac80a61496d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -123,18 +123,21 @@ void DAGTypeLegalizer::PromoteIntegerResult(SDNode *N, unsigned ResNo) { SDValue DAGTypeLegalizer::PromoteIntRes_AssertSext(SDNode *N) { // Sign-extend the new bits, and continue the assertion. SDValue Op = SExtPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::AssertSext, Op.getValueType(), Op, N->getOperand(1)); + return DAG.getNode(ISD::AssertSext, N->getDebugLoc(), + Op.getValueType(), Op, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { // Zero the new bits, and continue the assertion. SDValue Op = ZExtPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::AssertZext, Op.getValueType(), Op, N->getOperand(1)); + return DAG.getNode(ISD::AssertZext, N->getDebugLoc(), + Op.getValueType(), Op, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { SDValue Op2 = GetPromotedInteger(N->getOperand(2)); - SDValue Res = DAG.getAtomic(N->getOpcode(), N->getMemoryVT(), + SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), + N->getMemoryVT(), N->getChain(), N->getBasePtr(), Op2, N->getSrcValue(), N->getAlignment()); // Legalized the chain result - switch anything that used the old chain to @@ -161,6 +164,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { MVT NInVT = TLI.getTypeToTransformTo(InVT); MVT OutVT = N->getValueType(0); MVT NOutVT = TLI.getTypeToTransformTo(OutVT); + DebugLoc dl = N->getDebugLoc(); switch (getTypeAction(InVT)) { default: @@ -171,17 +175,18 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { case PromoteInteger: if (NOutVT.bitsEq(NInVT)) // The input promotes to the same size. Convert the promoted value. - return DAG.getNode(ISD::BIT_CONVERT, NOutVT, GetPromotedInteger(InOp)); + return DAG.getNode(ISD::BIT_CONVERT, dl, + NOutVT, GetPromotedInteger(InOp)); break; case SoftenFloat: // Promote the integer operand by hand. - return DAG.getNode(ISD::ANY_EXTEND, NOutVT, GetSoftenedFloat(InOp)); + return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, GetSoftenedFloat(InOp)); case ExpandInteger: case ExpandFloat: break; case ScalarizeVector: // Convert the element to an integer and promote it by hand. - return DAG.getNode(ISD::ANY_EXTEND, NOutVT, + return DAG.getNode(ISD::ANY_EXTEND, dl, NOutVT, BitConvertToInteger(GetScalarizedVector(InOp))); case SplitVector: { // For example, i32 = BIT_CONVERT v2i16 on alpha. Convert the split @@ -194,15 +199,15 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { if (TLI.isBigEndian()) std::swap(Lo, Hi); - InOp = DAG.getNode(ISD::ANY_EXTEND, + InOp = DAG.getNode(ISD::ANY_EXTEND, dl, MVT::getIntegerVT(NOutVT.getSizeInBits()), JoinIntegers(Lo, Hi)); - return DAG.getNode(ISD::BIT_CONVERT, NOutVT, InOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, InOp); } case WidenVector: if (OutVT.bitsEq(NInVT)) // The input is widened to the same size. Convert to the widened value. - return DAG.getNode(ISD::BIT_CONVERT, OutVT, GetWidenedVector(InOp)); + return DAG.getNode(ISD::BIT_CONVERT, dl, OutVT, GetWidenedVector(InOp)); } // Otherwise, lower the bit-convert to a store/load from the stack. @@ -211,26 +216,27 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, NULL, 0); // Result is an extending load from the stack slot. - return DAG.getExtLoad(ISD::EXTLOAD, NOutVT, Store, FIPtr, NULL, 0, OutVT); + return DAG.getExtLoad(ISD::EXTLOAD, dl, NOutVT, Store, FIPtr, NULL, 0, OutVT); } SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); MVT OVT = N->getValueType(0); MVT NVT = Op.getValueType(); + DebugLoc dl = N->getDebugLoc(); unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); - return DAG.getNode(ISD::SRL, NVT, DAG.getNode(ISD::BSWAP, NVT, Op), + return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op), DAG.getConstant(DiffBits, TLI.getShiftAmountTy())); } SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) { // The pair element type may be legal, or may not promote to the same type as // the result, for example i14 = BUILD_PAIR (i7, i7). Handle all cases. - return DAG.getNode(ISD::ANY_EXTEND, + return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), TLI.getTypeToTransformTo(N->getValueType(0)), JoinIntegers(N->getOperand(0), N->getOperand(1))); } @@ -265,7 +271,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) { MVT NVT = Op.getValueType(); Op = DAG.getNode(ISD::CTLZ, NVT, Op); // Subtract off the extra leading bits in the bigger type. - return DAG.getNode(ISD::SUB, NVT, Op, + return DAG.getNode(ISD::SUB, N->getDebugLoc(), NVT, Op, DAG.getConstant(NVT.getSizeInBits() - OVT.getSizeInBits(), NVT)); } @@ -273,20 +279,21 @@ SDValue DAGTypeLegalizer::PromoteIntRes_CTLZ(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntRes_CTPOP(SDNode *N) { // Zero extend to the promoted type and do the count there. SDValue Op = ZExtPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::CTPOP, Op.getValueType(), Op); + return DAG.getNode(ISD::CTPOP, N->getDebugLoc(), Op.getValueType(), Op); } SDValue DAGTypeLegalizer::PromoteIntRes_CTTZ(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); MVT OVT = N->getValueType(0); MVT NVT = Op.getValueType(); + DebugLoc dl = N->getDebugLoc(); // The count is the same in the promoted type except if the original // value was zero. This can be handled by setting the bit just off // the top of the original type. APInt TopBit(NVT.getSizeInBits(), 0); TopBit.set(OVT.getSizeInBits()); - Op = DAG.getNode(ISD::OR, NVT, Op, DAG.getConstant(TopBit, NVT)); - return DAG.getNode(ISD::CTTZ, NVT, Op); + Op = DAG.getNode(ISD::OR, dl, NVT, Op, DAG.getConstant(TopBit, NVT)); + return DAG.getNode(ISD::CTTZ, dl, NVT, Op); } SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { @@ -295,6 +302,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { if (getTypeAction(OldVec.getValueType()) == WidenVector) OldVec = GetWidenedVector(N->getOperand(0)); unsigned OldElts = OldVec.getValueType().getVectorNumElements(); + DebugLoc dl = N->getDebugLoc(); if (OldElts == 1) { assert(!isTypeLegal(OldVec.getValueType()) && @@ -302,7 +310,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { // It is tempting to follow GetScalarizedVector by a call to // GetPromotedInteger, but this would be wrong because the // scalarized value may not yet have been processed. - return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT), + return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), GetScalarizedVector(OldVec)); } @@ -312,34 +320,35 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { MVT NewVT = MVT::getIntegerVT(2 * OldVT.getSizeInBits()); assert(OldVT.isSimple() && NewVT.isSimple()); - SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, + SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::getVectorVT(NewVT, OldElts / 2), OldVec); // Extract the element at OldIdx / 2 from the new vector. SDValue OldIdx = N->getOperand(1); - SDValue NewIdx = DAG.getNode(ISD::SRL, OldIdx.getValueType(), OldIdx, + SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx, DAG.getConstant(1, TLI.getShiftAmountTy())); - SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, NewIdx); + SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx); // Select the appropriate half of the element: Lo if OldIdx was even, // Hi if it was odd. SDValue Lo = Elt; - SDValue Hi = DAG.getNode(ISD::SRL, NewVT, Elt, + SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt, DAG.getConstant(OldVT.getSizeInBits(), TLI.getShiftAmountTy())); if (TLI.isBigEndian()) std::swap(Lo, Hi); // Extend to the promoted type. - SDValue Odd = DAG.getNode(ISD::TRUNCATE, MVT::i1, OldIdx); - SDValue Res = DAG.getNode(ISD::SELECT, NewVT, Odd, Hi, Lo); - return DAG.getNode(ISD::ANY_EXTEND, TLI.getTypeToTransformTo(OldVT), Res); + SDValue Odd = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, OldIdx); + SDValue Res = DAG.getNode(ISD::SELECT, dl, NewVT, Odd, Hi, Lo); + return DAG.getNode(ISD::ANY_EXTEND, dl, TLI.getTypeToTransformTo(OldVT), Res); } SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); unsigned NewOpc = N->getOpcode(); + DebugLoc dl = N->getDebugLoc(); // If we're promoting a UINT to a larger size, check to see if the new node // will be legal. If it isn't, check to see if FP_TO_SINT is legal, since @@ -351,18 +360,19 @@ SDValue DAGTypeLegalizer::PromoteIntRes_FP_TO_XINT(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT)) NewOpc = ISD::FP_TO_SINT; - SDValue Res = DAG.getNode(NewOpc, NVT, N->getOperand(0)); + SDValue Res = DAG.getNode(NewOpc, dl, NVT, N->getOperand(0)); // Assert that the converted value fits in the original type. If it doesn't // (eg: because the value being converted is too big), then the result of the // original operation was undefined anyway, so the assert is still correct. return DAG.getNode(N->getOpcode() == ISD::FP_TO_UINT ? - ISD::AssertZext : ISD::AssertSext, + ISD::AssertZext : ISD::AssertSext, dl, NVT, Res, DAG.getValueType(N->getValueType(0))); } SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + DebugLoc dl = N->getDebugLoc(); if (getTypeAction(N->getOperand(0).getValueType()) == PromoteInteger) { SDValue Res = GetPromotedInteger(N->getOperand(0)); @@ -373,7 +383,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { if (NVT == Res.getValueType()) { // The high bits are not guaranteed to be anything. Insert an extend. if (N->getOpcode() == ISD::SIGN_EXTEND) - return DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, + return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res, DAG.getValueType(N->getOperand(0).getValueType())); if (N->getOpcode() == ISD::ZERO_EXTEND) return DAG.getZeroExtendInReg(Res, N->getOperand(0).getValueType()); @@ -383,7 +393,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_INT_EXTEND(SDNode *N) { } // Otherwise, just extend the original operand all the way to the larger type. - return DAG.getNode(N->getOpcode(), NVT, N->getOperand(0)); + return DAG.getNode(N->getOpcode(), dl, NVT, N->getOperand(0)); } SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) { @@ -391,7 +401,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_LOAD(LoadSDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); ISD::LoadExtType ExtType = ISD::isNON_EXTLoad(N) ? ISD::EXTLOAD : N->getExtensionType(); - SDValue Res = DAG.getExtLoad(ExtType, NVT, N->getChain(), N->getBasePtr(), + DebugLoc dl = N->getDebugLoc(); + SDValue Res = DAG.getExtLoad(ExtType, dl, NVT, N->getChain(), N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), N->getMemoryVT(), N->isVolatile(), N->getAlignment()); @@ -408,7 +419,8 @@ SDValue DAGTypeLegalizer::PromoteIntRes_Overflow(SDNode *N) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(1)); MVT ValueVTs[] = { N->getValueType(0), NVT }; SDValue Ops[] = { N->getOperand(0), N->getOperand(1) }; - SDValue Res = DAG.getNode(N->getOpcode(), DAG.getVTList(ValueVTs, 2), Ops, 2); + SDValue Res = DAG.getNode(N->getOpcode(), N->getDebugLoc(), + DAG.getVTList(ValueVTs, 2), Ops, 2); // Modified the sum result - switch anything that used the old sum to use // the new one. @@ -427,17 +439,18 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SADDSUBO(SDNode *N, unsigned ResNo) { SDValue RHS = SExtPromotedInteger(N->getOperand(1)); MVT OVT = N->getOperand(0).getValueType(); MVT NVT = LHS.getValueType(); + DebugLoc dl = N->getDebugLoc(); // Do the arithmetic in the larger type. unsigned Opcode = N->getOpcode() == ISD::SADDO ? ISD::ADD : ISD::SUB; - SDValue Res = DAG.getNode(Opcode, NVT, LHS, RHS); + SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS); // Calculate the overflow flag: sign extend the arithmetic result from // the original type. - SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Res, + SDValue Ofl = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Res, DAG.getValueType(OVT)); // Overflowed if and only if this is not equal to Res. - Ofl = DAG.getSetCC(N->getValueType(1), Ofl, Res, ISD::SETNE); + Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE); // Use the calculated overflow everywhere. ReplaceValueWith(SDValue(N, 1), Ofl); @@ -449,45 +462,50 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SDIV(SDNode *N) { // Sign extend the input. SDValue LHS = SExtPromotedInteger(N->getOperand(0)); SDValue RHS = SExtPromotedInteger(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), + LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_SELECT(SDNode *N) { SDValue LHS = GetPromotedInteger(N->getOperand(1)); SDValue RHS = GetPromotedInteger(N->getOperand(2)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); + return DAG.getNode(ISD::SELECT, N->getDebugLoc(), + LHS.getValueType(), N->getOperand(0),LHS,RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_SELECT_CC(SDNode *N) { SDValue LHS = GetPromotedInteger(N->getOperand(2)); SDValue RHS = GetPromotedInteger(N->getOperand(3)); - return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), + LHS.getValueType(), N->getOperand(0), N->getOperand(1), LHS, RHS, N->getOperand(4)); } SDValue DAGTypeLegalizer::PromoteIntRes_SETCC(SDNode *N) { MVT SVT = TLI.getSetCCResultType(N->getOperand(0).getValueType()); assert(isTypeLegal(SVT) && "Illegal SetCC type!"); + DebugLoc dl = N->getDebugLoc(); // Get the SETCC result using the canonical SETCC type. - SDValue SetCC = DAG.getNode(ISD::SETCC, SVT, N->getOperand(0), + SDValue SetCC = DAG.getNode(ISD::SETCC, dl, SVT, N->getOperand(0), N->getOperand(1), N->getOperand(2)); // Convert to the expected type. MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); assert(NVT.bitsLE(SVT) && "Integer type overpromoted?"); - return DAG.getNode(ISD::TRUNCATE, NVT, SetCC); + return DAG.getNode(ISD::TRUNCATE, dl, NVT, SetCC); } SDValue DAGTypeLegalizer::PromoteIntRes_SHL(SDNode *N) { - return DAG.getNode(ISD::SHL, TLI.getTypeToTransformTo(N->getValueType(0)), + return DAG.getNode(ISD::SHL, N->getDebugLoc(), + TLI.getTypeToTransformTo(N->getValueType(0)), GetPromotedInteger(N->getOperand(0)), N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_SIGN_EXTEND_INREG(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), Op, - N->getOperand(1)); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, N->getDebugLoc(), + Op.getValueType(), Op, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) { @@ -496,13 +514,15 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SimpleIntBinOp(SDNode *N) { // that too is okay if they are integer operations. SDValue LHS = GetPromotedInteger(N->getOperand(0)); SDValue RHS = GetPromotedInteger(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), + LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_SRA(SDNode *N) { // The input value must be properly sign extended. SDValue Res = SExtPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::SRA, Res.getValueType(), Res, N->getOperand(1)); + return DAG.getNode(ISD::SRA, N->getDebugLoc(), + Res.getValueType(), Res, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { @@ -510,7 +530,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_SRL(SDNode *N) { MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); SDValue Res = ZExtPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::SRL, NVT, Res, N->getOperand(1)); + return DAG.getNode(ISD::SRL, N->getDebugLoc(), NVT, Res, N->getOperand(1)); } SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { @@ -529,7 +549,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_TRUNCATE(SDNode *N) { } // Truncate to NVT instead of VT - return DAG.getNode(ISD::TRUNCATE, NVT, Res); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), NVT, Res); } SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) { @@ -542,16 +562,17 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UADDSUBO(SDNode *N, unsigned ResNo) { SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); MVT OVT = N->getOperand(0).getValueType(); MVT NVT = LHS.getValueType(); + DebugLoc dl = N->getDebugLoc(); // Do the arithmetic in the larger type. unsigned Opcode = N->getOpcode() == ISD::UADDO ? ISD::ADD : ISD::SUB; - SDValue Res = DAG.getNode(Opcode, NVT, LHS, RHS); + SDValue Res = DAG.getNode(Opcode, dl, NVT, LHS, RHS); // Calculate the overflow flag: zero extend the arithmetic result from // the original type. SDValue Ofl = DAG.getZeroExtendInReg(Res, OVT); // Overflowed if and only if this is not equal to Res. - Ofl = DAG.getSetCC(N->getValueType(1), Ofl, Res, ISD::SETNE); + Ofl = DAG.getSetCC(dl, N->getValueType(1), Ofl, Res, ISD::SETNE); // Use the calculated overflow everywhere. ReplaceValueWith(SDValue(N, 1), Ofl); @@ -563,17 +584,20 @@ SDValue DAGTypeLegalizer::PromoteIntRes_UDIV(SDNode *N) { // Zero extend the input. SDValue LHS = ZExtPromotedInteger(N->getOperand(0)); SDValue RHS = ZExtPromotedInteger(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), + LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::PromoteIntRes_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, TLI.getTypeToTransformTo(N->getValueType(0))); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + TLI.getTypeToTransformTo(N->getValueType(0))); } SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { SDValue Chain = N->getOperand(0); // Get the chain. SDValue Ptr = N->getOperand(1); // Get the pointer. MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); MVT RegVT = TLI.getRegisterType(VT); unsigned NumRegs = TLI.getNumRegisters(VT); @@ -591,14 +615,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { // Assemble the parts in the promoted type. MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, NVT, Parts[0]); + SDValue Res = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[0]); for (unsigned i = 1; i < NumRegs; ++i) { - SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, NVT, Parts[i]); + SDValue Part = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Parts[i]); // Shift it to the right position and "or" it in. - Part = DAG.getNode(ISD::SHL, NVT, Part, + Part = DAG.getNode(ISD::SHL, dl, NVT, Part, DAG.getConstant(i * RegVT.getSizeInBits(), TLI.getShiftAmountTy())); - Res = DAG.getNode(ISD::OR, NVT, Res, Part); + Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part); } // Modified the chain result - switch anything that used the old chain to @@ -707,7 +731,7 @@ void DAGTypeLegalizer::PromoteSetCCOperands(SDValue &NewLHS,SDValue &NewRHS, SDValue DAGTypeLegalizer::PromoteIntOp_ANY_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); + return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op); } SDValue DAGTypeLegalizer::PromoteIntOp_BR_CC(SDNode *N, unsigned OpNo) { @@ -741,11 +765,12 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) { SDValue Lo = ZExtPromotedInteger(N->getOperand(0)); SDValue Hi = GetPromotedInteger(N->getOperand(1)); assert(Lo.getValueType() == N->getValueType(0) && "Operand over promoted?"); + DebugLoc dl = N->getDebugLoc(); - Hi = DAG.getNode(ISD::SHL, N->getValueType(0), Hi, + Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi, DAG.getConstant(OVT.getSizeInBits(), TLI.getShiftAmountTy())); - return DAG.getNode(ISD::OR, N->getValueType(0), Lo, Hi); + return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi); } SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { @@ -755,6 +780,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { MVT VecVT = N->getValueType(0); unsigned NumElts = VecVT.getVectorNumElements(); assert(!(NumElts & 1) && "Legal vector of one illegal element?"); + DebugLoc dl = N->getDebugLoc(); // Build a vector of half the length out of elements of twice the bitwidth. // For example <4 x i16> -> <2 x i32>. @@ -774,12 +800,12 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_VECTOR(SDNode *N) { NewElts.push_back(JoinIntegers(Lo, Hi)); } - SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, + SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::getVectorVT(NewVT, NewElts.size()), &NewElts[0], NewElts.size()); // Convert the new vector to the old vector type. - return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec); + return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); } SDValue DAGTypeLegalizer::PromoteIntOp_CONVERT_RNDSAT(SDNode *N) { @@ -864,8 +890,9 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) { SDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); - Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); - return DAG.getNode(ISD::SIGN_EXTEND_INREG, Op.getValueType(), + DebugLoc dl = N->getDebugLoc(); + Op = DAG.getNode(ISD::ANY_EXTEND, dl, N->getValueType(0), Op); + return DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Op.getValueType(), Op, DAG.getValueType(N->getOperand(0).getValueType())); } @@ -880,18 +907,19 @@ SDValue DAGTypeLegalizer::PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo){ int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); + DebugLoc dl = N->getDebugLoc(); SDValue Val = GetPromotedInteger(N->getValue()); // Get promoted value. // Truncate the value and store the result. - return DAG.getTruncStore(Ch, Val, Ptr, N->getSrcValue(), + return DAG.getTruncStore(Ch, dl, Val, Ptr, N->getSrcValue(), SVOffset, N->getMemoryVT(), isVolatile, Alignment); } SDValue DAGTypeLegalizer::PromoteIntOp_TRUNCATE(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); - return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), Op); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), Op); } SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) { @@ -901,7 +929,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_UINT_TO_FP(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntOp_ZERO_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); - Op = DAG.getNode(ISD::ANY_EXTEND, N->getValueType(0), Op); + Op = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), N->getValueType(0), Op); return DAG.getZeroExtendInReg(Op, N->getOperand(0).getValueType()); } @@ -991,6 +1019,7 @@ void DAGTypeLegalizer::ExpandIntegerResult(SDNode *N, unsigned ResNo) { /// and the shift amount is a constant 'Amt'. Expand the operation. void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); // Expand the incoming operand to be shifted, so that we have its parts SDValue InL, InH; GetExpandedInteger(N->getOperand(0), InL, InH); @@ -1005,7 +1034,8 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, Lo = Hi = DAG.getConstant(0, NVT); } else if (Amt > NVTBits) { Lo = DAG.getConstant(0, NVT); - Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); + Hi = DAG.getNode(ISD::SHL, dl, + NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); } else if (Amt == NVTBits) { Lo = DAG.getConstant(0, NVT); Hi = InL; @@ -1015,15 +1045,15 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, // Emit this X << 1 as X+X. SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); SDValue LoOps[2] = { InL, InL }; - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); SDValue HiOps[3] = { InH, InH, Lo.getValue(1) }; - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); } else { - Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Amt, ShTy)); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SHL, NVT, InH, + Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Amt, ShTy)); + Hi = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SHL, dl, NVT, InH, DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SRL, NVT, InL, + DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(NVTBits-Amt, ShTy))); } return; @@ -1034,42 +1064,43 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, Lo = DAG.getConstant(0, NVT); Hi = DAG.getConstant(0, NVT); } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); + Lo = DAG.getNode(ISD::SRL, dl, + NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); Hi = DAG.getConstant(0, NVT); } else if (Amt == NVTBits) { Lo = InH; Hi = DAG.getConstant(0, NVT); } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, + Lo = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, + DAG.getNode(ISD::SHL, dl, NVT, InH, DAG.getConstant(NVTBits-Amt, ShTy))); - Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Amt, ShTy)); + Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Amt, ShTy)); } return; } assert(N->getOpcode() == ISD::SRA && "Unknown shift!"); if (Amt > VTBits) { - Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, + Hi = Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRA, NVT, InH, + Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Amt-NVTBits, ShTy)); - Hi = DAG.getNode(ISD::SRA, NVT, InH, + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); } else if (Amt == NVTBits) { Lo = InH; - Hi = DAG.getNode(ISD::SRA, NVT, InH, + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); } else { Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, + DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(Amt, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, + DAG.getNode(ISD::SHL, dl, NVT, InH, DAG.getConstant(NVTBits-Amt, ShTy))); - Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Amt, ShTy)); + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Amt, ShTy)); } } @@ -1086,6 +1117,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { unsigned NVTBits = NVT.getSizeInBits(); assert(isPowerOf2_32(NVTBits) && "Expanded integer type size not a power of two!"); + DebugLoc dl = N->getDebugLoc(); APInt HighBitMask = APInt::getHighBitsSet(ShBits, ShBits - Log2_32(NVTBits)); APInt KnownZero, KnownOne; @@ -1103,23 +1135,23 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { // can do this as a couple of simple shifts. if (KnownOne.intersects(HighBitMask)) { // Mask out the high bit, which we know is set. - Amt = DAG.getNode(ISD::AND, ShTy, Amt, + Amt = DAG.getNode(ISD::AND, dl, ShTy, Amt, DAG.getConstant(~HighBitMask, ShTy)); switch (N->getOpcode()) { default: assert(0 && "Unknown shift"); case ISD::SHL: Lo = DAG.getConstant(0, NVT); // Low part is zero. - Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part. + Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part. return true; case ISD::SRL: Hi = DAG.getConstant(0, NVT); // Hi part is zero. - Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part. + Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part. return true; case ISD::SRA: - Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part. + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part. DAG.getConstant(NVTBits-1, ShTy)); - Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part. + Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part. return true; } } @@ -1154,6 +1186,7 @@ ExpandShiftWithKnownAmountBit(SDNode *N, SDValue &Lo, SDValue &Hi) { void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); // Expand the subcomponents. SDValue LHSL, LHSH, RHSL, RHSH; GetExpandedInteger(N->getOperand(0), LHSL, LHSH); @@ -1176,38 +1209,38 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUB(SDNode *N, if (hasCarry) { SDVTList VTList = DAG.getVTList(NVT, MVT::Flag); if (N->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); } } else { if (N->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADD, NVT, LoOps, 2); - Hi = DAG.getNode(ISD::ADD, NVT, HiOps, 2); - SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, LoOps[0], + Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2); + Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2); + SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0], ISD::SETULT); - SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1, + SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1, DAG.getConstant(1, NVT), DAG.getConstant(0, NVT)); - SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, LoOps[1], + SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1], ISD::SETULT); - SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2, + SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2, DAG.getConstant(1, NVT), Carry1); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2); } else { - Lo = DAG.getNode(ISD::SUB, NVT, LoOps, 2); - Hi = DAG.getNode(ISD::SUB, NVT, HiOps, 2); + Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2); + Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2); SDValue Cmp = DAG.getSetCC(TLI.getSetCCResultType(LoOps[0].getValueType()), LoOps[0], LoOps[1], ISD::SETULT); - SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp, + SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, DAG.getConstant(1, NVT), DAG.getConstant(0, NVT)); - Hi = DAG.getNode(ISD::SUB, NVT, Hi, Borrow); + Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow); } } } @@ -1216,6 +1249,7 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N, SDValue &Lo, SDValue &Hi) { // Expand the subcomponents. SDValue LHSL, LHSH, RHSL, RHSH; + DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); @@ -1223,13 +1257,13 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBC(SDNode *N, SDValue HiOps[3] = { LHSH, RHSH }; if (N->getOpcode() == ISD::ADDC) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); } // Legalized the flag result - switch anything that used the old flag to @@ -1241,15 +1275,16 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, SDValue &Lo, SDValue &Hi) { // Expand the subcomponents. SDValue LHSL, LHSH, RHSL, RHSH; + DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), LHSL, LHSH); GetExpandedInteger(N->getOperand(1), RHSL, RHSH); SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); SDValue LoOps[3] = { LHSL, RHSL, N->getOperand(2) }; SDValue HiOps[3] = { LHSH, RHSH }; - Lo = DAG.getNode(N->getOpcode(), VTList, LoOps, 3); + Lo = DAG.getNode(N->getOpcode(), dl, VTList, LoOps, 3); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(N->getOpcode(), VTList, HiOps, 3); + Hi = DAG.getNode(N->getOpcode(), dl, VTList, HiOps, 3); // Legalized the flag result - switch anything that used the old flag to // use the new one. @@ -1259,11 +1294,12 @@ void DAGTypeLegalizer::ExpandIntRes_ADDSUBE(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + DebugLoc dl = N->getDebugLoc(); SDValue Op = N->getOperand(0); if (Op.getValueType().bitsLE(NVT)) { // The low part is any extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Op); - Hi = DAG.getNode(ISD::UNDEF, NVT); // The high part is undefined. + Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Op); + Hi = DAG.getNode(ISD::UNDEF, dl, NVT); // The high part is undefined. } else { // For example, extension of an i48 to an i64. The operand type necessarily // promotes to the result type, so will end up being expanded too. @@ -1279,6 +1315,7 @@ void DAGTypeLegalizer::ExpandIntRes_ANY_EXTEND(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), Lo, Hi); MVT NVT = Lo.getValueType(); MVT EVT = cast(N->getOperand(1))->getVT(); @@ -1286,18 +1323,19 @@ void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N, unsigned EVTBits = EVT.getSizeInBits(); if (NVTBits < EVTBits) { - Hi = DAG.getNode(ISD::AssertSext, NVT, Hi, + Hi = DAG.getNode(ISD::AssertSext, dl, NVT, Hi, DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits))); } else { - Lo = DAG.getNode(ISD::AssertSext, NVT, Lo, DAG.getValueType(EVT)); + Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT)); // The high part replicates the sign bit of Lo, make it explicit. - Hi = DAG.getNode(ISD::SRA, NVT, Lo, + Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, DAG.getConstant(NVTBits-1, TLI.getShiftAmountTy())); } } void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), Lo, Hi); MVT NVT = Lo.getValueType(); MVT EVT = cast(N->getOperand(1))->getVT(); @@ -1305,10 +1343,10 @@ void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N, unsigned EVTBits = EVT.getSizeInBits(); if (NVTBits < EVTBits) { - Hi = DAG.getNode(ISD::AssertZext, NVT, Hi, + Hi = DAG.getNode(ISD::AssertZext, dl, NVT, Hi, DAG.getValueType(MVT::getIntegerVT(EVTBits - NVTBits))); } else { - Lo = DAG.getNode(ISD::AssertZext, NVT, Lo, DAG.getValueType(EVT)); + Lo = DAG.getNode(ISD::AssertZext, dl, NVT, Lo, DAG.getValueType(EVT)); // The high part must be zero, make it explicit. Hi = DAG.getConstant(0, NVT); } @@ -1316,9 +1354,10 @@ void DAGTypeLegalizer::ExpandIntRes_AssertZext(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_BSWAP(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), Hi, Lo); // Note swapped operands. - Lo = DAG.getNode(ISD::BSWAP, Lo.getValueType(), Lo); - Hi = DAG.getNode(ISD::BSWAP, Hi.getValueType(), Hi); + Lo = DAG.getNode(ISD::BSWAP, dl, Lo.getValueType(), Lo); + Hi = DAG.getNode(ISD::BSWAP, dl, Hi.getValueType(), Hi); } void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N, @@ -1332,46 +1371,49 @@ void DAGTypeLegalizer::ExpandIntRes_Constant(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_CTLZ(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); // ctlz (HiLo) -> Hi != 0 ? ctlz(Hi) : (ctlz(Lo)+32) GetExpandedInteger(N->getOperand(0), Lo, Hi); MVT NVT = Lo.getValueType(); - SDValue HiNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), Hi, + SDValue HiNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Hi, DAG.getConstant(0, NVT), ISD::SETNE); - SDValue LoLZ = DAG.getNode(ISD::CTLZ, NVT, Lo); - SDValue HiLZ = DAG.getNode(ISD::CTLZ, NVT, Hi); + SDValue LoLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Lo); + SDValue HiLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi); - Lo = DAG.getNode(ISD::SELECT, NVT, HiNotZero, HiLZ, - DAG.getNode(ISD::ADD, NVT, LoLZ, + Lo = DAG.getNode(ISD::SELECT, dl, NVT, HiNotZero, HiLZ, + DAG.getNode(ISD::ADD, dl, NVT, LoLZ, DAG.getConstant(NVT.getSizeInBits(), NVT))); Hi = DAG.getConstant(0, NVT); } void DAGTypeLegalizer::ExpandIntRes_CTPOP(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); // ctpop(HiLo) -> ctpop(Hi)+ctpop(Lo) GetExpandedInteger(N->getOperand(0), Lo, Hi); MVT NVT = Lo.getValueType(); - Lo = DAG.getNode(ISD::ADD, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo), - DAG.getNode(ISD::CTPOP, NVT, Hi)); + Lo = DAG.getNode(ISD::ADD, dl, NVT, DAG.getNode(ISD::CTPOP, NVT, Lo), + DAG.getNode(ISD::CTPOP, dl, NVT, Hi)); Hi = DAG.getConstant(0, NVT); } void DAGTypeLegalizer::ExpandIntRes_CTTZ(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); // cttz (HiLo) -> Lo != 0 ? cttz(Lo) : (cttz(Hi)+32) GetExpandedInteger(N->getOperand(0), Lo, Hi); MVT NVT = Lo.getValueType(); - SDValue LoNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), Lo, + SDValue LoNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, DAG.getConstant(0, NVT), ISD::SETNE); - SDValue LoLZ = DAG.getNode(ISD::CTTZ, NVT, Lo); - SDValue HiLZ = DAG.getNode(ISD::CTTZ, NVT, Hi); + SDValue LoLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo); + SDValue HiLZ = DAG.getNode(ISD::CTTZ, dl, NVT, Hi); - Lo = DAG.getNode(ISD::SELECT, NVT, LoNotZero, LoLZ, - DAG.getNode(ISD::ADD, NVT, HiLZ, + Lo = DAG.getNode(ISD::SELECT, dl, NVT, LoNotZero, LoLZ, + DAG.getNode(ISD::ADD, dl, NVT, HiLZ, DAG.getConstant(NVT.getSizeInBits(), NVT))); Hi = DAG.getConstant(0, NVT); } @@ -1413,14 +1455,15 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); + DebugLoc dl = N->getDebugLoc(); assert(NVT.isByteSized() && "Expanded type not byte sized!"); if (N->getMemoryVT().bitsLE(NVT)) { MVT EVT = N->getMemoryVT(); - Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, EVT, - isVolatile, Alignment); + Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + EVT, isVolatile, Alignment); // Remember the chain. Ch = Lo.getValue(1); @@ -1429,7 +1472,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, // The high part is obtained by SRA'ing all but one of the bits of the // lo part. unsigned LoSize = Lo.getValueType().getSizeInBits(); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, + Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); } else if (ExtType == ISD::ZEXTLOAD) { // The high part is just a zero. @@ -1437,11 +1480,11 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, } else { assert(ExtType == ISD::EXTLOAD && "Unknown extload!"); // The high part is undefined. - Hi = DAG.getNode(ISD::UNDEF, NVT); + Hi = DAG.getNode(ISD::UNDEF, dl, NVT); } } else if (TLI.isLittleEndian()) { // Little-endian - low bits are at low addresses. - Lo = DAG.getLoad(NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + Lo = DAG.getLoad(NVT, dl, Ch, Ptr, N->getSrcValue(), SVOffset, isVolatile, Alignment); unsigned ExcessBits = @@ -1450,15 +1493,15 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, // Increment the pointer to the other half. unsigned IncrementSize = NVT.getSizeInBits()/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), + Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, NEVT, isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); } else { // Big-endian - high bits are at low addresses. Favor aligned loads at @@ -1469,32 +1512,33 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, unsigned ExcessBits = (EBytes - IncrementSize)*8; // Load both the high bits and maybe some of the low bits. - Hi = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, + Hi = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset, MVT::getIntegerVT(EVT.getSizeInBits() - ExcessBits), isVolatile, Alignment); // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); // Load the rest of the low bits. - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, NVT, Ch, Ptr, N->getSrcValue(), + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, NVT, Ch, Ptr, N->getSrcValue(), SVOffset+IncrementSize, MVT::getIntegerVT(ExcessBits), isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); if (ExcessBits < NVT.getSizeInBits()) { // Transfer low bits from the bottom of Hi to the top of Lo. - Lo = DAG.getNode(ISD::OR, NVT, Lo, - DAG.getNode(ISD::SHL, NVT, Hi, + Lo = DAG.getNode(ISD::OR, dl, NVT, Lo, + DAG.getNode(ISD::SHL, dl, NVT, Hi, DAG.getConstant(ExcessBits, TLI.getShiftAmountTy()))); // Move high bits to the right position in Hi. - Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, NVT, Hi, + Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, + NVT, Hi, DAG.getConstant(NVT.getSizeInBits() - ExcessBits, TLI.getShiftAmountTy())); } @@ -1507,11 +1551,12 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, void DAGTypeLegalizer::ExpandIntRes_Logical(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); SDValue LL, LH, RL, RH; GetExpandedInteger(N->getOperand(0), LL, LH); GetExpandedInteger(N->getOperand(1), RL, RH); - Lo = DAG.getNode(N->getOpcode(), LL.getValueType(), LL, RL); - Hi = DAG.getNode(N->getOpcode(), LL.getValueType(), LH, RH); + Lo = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LL, RL); + Hi = DAG.getNode(N->getOpcode(), dl, LL.getValueType(), LH, RH); } void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, @@ -1539,14 +1584,14 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, // The inputs are both zero-extended. if (HasUMUL_LOHI) { // We can emit a umul_lohi. - Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); Hi = SDValue(Lo.getNode(), 1); return; } if (HasMULHU) { // We can emit a mulhu+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); return; } } @@ -1554,36 +1599,36 @@ void DAGTypeLegalizer::ExpandIntRes_MUL(SDNode *N, // The input values are both sign-extended. if (HasSMUL_LOHI) { // We can emit a smul_lohi. - Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); Hi = SDValue(Lo.getNode(), 1); return; } if (HasMULHS) { // We can emit a mulhs+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); + Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL); return; } } if (HasUMUL_LOHI) { // Lo,Hi = umul LHS, RHS. - SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, + SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); Lo = UMulLOHI; Hi = UMulLOHI.getValue(1); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); return; } if (HasMULHU) { - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); return; } } @@ -1660,7 +1705,7 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, SDValue Ops[] = { LHSL, LHSH, N->getOperand(1) }; MVT VT = LHSL.getValueType(); - Lo = DAG.getNode(PartsOpc, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); + Lo = DAG.getNode(PartsOpc, dl, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); Hi = Lo.getValue(1); return; } @@ -1709,13 +1754,14 @@ void DAGTypeLegalizer::ExpandIntRes_Shift(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + DebugLoc dl = N->getDebugLoc(); SDValue Op = N->getOperand(0); if (Op.getValueType().bitsLE(NVT)) { // The low part is sign extension of the input (degenerates to a copy). - Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, N->getOperand(0)); + Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, N->getOperand(0)); // The high part is obtained by SRA'ing all but one of the bits of low part. unsigned LoSize = NVT.getSizeInBits(); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, + Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); } else { // For example, extension of an i48 to an i64. The operand type necessarily @@ -1729,24 +1775,25 @@ void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, SplitInteger(Res, Lo, Hi); unsigned ExcessBits = Op.getValueType().getSizeInBits() - NVT.getSizeInBits(); - Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, + Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi, DAG.getValueType(MVT::getIntegerVT(ExcessBits))); } } void DAGTypeLegalizer:: ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); GetExpandedInteger(N->getOperand(0), Lo, Hi); MVT EVT = cast(N->getOperand(1))->getVT(); if (EVT.bitsLE(Lo.getValueType())) { // sext_inreg the low part if needed. - Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, Lo.getValueType(), Lo, + Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Lo.getValueType(), Lo, N->getOperand(1)); // The high part gets the sign extension from the lo-part. This handles // things like sextinreg V:i64 from i8. - Hi = DAG.getNode(ISD::SRA, Hi.getValueType(), Lo, + Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo, DAG.getConstant(Hi.getValueType().getSizeInBits()-1, TLI.getShiftAmountTy())); } else { @@ -1754,7 +1801,7 @@ ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) { // sext_inreg the high part. unsigned ExcessBits = EVT.getSizeInBits() - Lo.getValueType().getSizeInBits(); - Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, Hi.getValueType(), Hi, + Hi = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Hi.getValueType(), Hi, DAG.getValueType(MVT::getIntegerVT(ExcessBits))); } } @@ -1780,11 +1827,13 @@ void DAGTypeLegalizer::ExpandIntRes_SREM(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - Lo = DAG.getNode(ISD::TRUNCATE, NVT, N->getOperand(0)); - Hi = DAG.getNode(ISD::SRL, N->getOperand(0).getValueType(), N->getOperand(0), + DebugLoc dl = N->getDebugLoc(); + Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0)); + Hi = DAG.getNode(ISD::SRL, dl, + N->getOperand(0).getValueType(), N->getOperand(0), DAG.getConstant(NVT.getSizeInBits(), TLI.getShiftAmountTy())); - Hi = DAG.getNode(ISD::TRUNCATE, NVT, Hi); + Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi); } void DAGTypeLegalizer::ExpandIntRes_UDIV(SDNode *N, @@ -1826,10 +1875,11 @@ void DAGTypeLegalizer::ExpandIntRes_UREM(SDNode *N, void DAGTypeLegalizer::ExpandIntRes_ZERO_EXTEND(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); + DebugLoc dl = N->getDebugLoc(); SDValue Op = N->getOperand(0); if (Op.getValueType().bitsLE(NVT)) { // The low part is zero extension of the input (degenerates to a copy). - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, N->getOperand(0)); + Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0)); Hi = DAG.getConstant(0, NVT); // The high part is just a zero. } else { // For example, extension of an i48 to an i64. The operand type necessarily @@ -1920,16 +1970,17 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) { if (RHSCST->isAllOnesValue()) { // Equality comparison to -1. - NewLHS = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); + NewLHS = DAG.getNode(ISD::AND, dl, + LHSLo.getValueType(), LHSLo, LHSHi); NewRHS = RHSLo; return; } } } - NewLHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); - NewRHS = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); - NewLHS = DAG.getNode(ISD::OR, NewLHS.getValueType(), NewLHS, NewRHS); + NewLHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo); + NewRHS = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi); + NewLHS = DAG.getNode(ISD::OR, dl, NewLHS.getValueType(), NewLHS, NewRHS); NewRHS = DAG.getConstant(0, NewLHS.getValueType()); return; } @@ -1969,12 +2020,13 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, LowCC, false, DagCombineInfo); if (!Tmp1.getNode()) - Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()), + Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, LowCC); Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, CCCode, false, DagCombineInfo); if (!Tmp2.getNode()) - Tmp2 = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp2 = DAG.getNode(ISD::SETCC, dl, + TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, DAG.getCondCode(CCCode)); ConstantSDNode *Tmp1C = dyn_cast(Tmp1.getNode()); @@ -1997,9 +2049,9 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETEQ, false, DagCombineInfo); if (!NewLHS.getNode()) - NewLHS = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETEQ); - NewLHS = DAG.getNode(ISD::SELECT, Tmp1.getValueType(), + NewLHS = DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(), NewLHS, Tmp1, Tmp2); NewRHS = SDValue(); } @@ -2080,19 +2132,20 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { int SVOffset = N->getSrcValueOffset(); unsigned Alignment = N->getAlignment(); bool isVolatile = N->isVolatile(); + DebugLoc dl = N->getDebugLoc(); SDValue Lo, Hi; assert(NVT.isByteSized() && "Expanded type not byte sized!"); if (N->getMemoryVT().bitsLE(NVT)) { GetExpandedInteger(N->getValue(), Lo, Hi); - return DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, + return DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, N->getMemoryVT(), isVolatile, Alignment); } else if (TLI.isLittleEndian()) { // Little-endian - low bits are at low addresses. GetExpandedInteger(N->getValue(), Lo, Hi); - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, + Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, isVolatile, Alignment); unsigned ExcessBits = @@ -2101,12 +2154,12 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { // Increment the pointer to the other half. unsigned IncrementSize = NVT.getSizeInBits()/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), + Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, NEVT, isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } else { // Big-endian - high bits are at low addresses. Favor aligned stores at // the cost of some bit-fiddling. @@ -2120,28 +2173,28 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { if (ExcessBits < NVT.getSizeInBits()) { // Transfer high bits from the top of Lo to the bottom of Hi. - Hi = DAG.getNode(ISD::SHL, NVT, Hi, + Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi, DAG.getConstant(NVT.getSizeInBits() - ExcessBits, TLI.getShiftAmountTy())); - Hi = DAG.getNode(ISD::OR, NVT, Hi, + Hi = DAG.getNode(ISD::OR, dl, NVT, Hi, DAG.getNode(ISD::SRL, NVT, Lo, DAG.getConstant(ExcessBits, TLI.getShiftAmountTy()))); } // Store both the high bits and maybe some of the low bits. - Hi = DAG.getTruncStore(Ch, Hi, Ptr, N->getSrcValue(), + Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset, HiVT, isVolatile, Alignment); // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); // Store the lowest ExcessBits bits in the second half. - Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), + Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset+IncrementSize, MVT::getIntegerVT(ExcessBits), isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } } @@ -2149,7 +2202,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_TRUNCATE(SDNode *N) { SDValue InL, InH; GetExpandedInteger(N->getOperand(0), InL, InH); // Just truncate the low part of the source. - return DAG.getNode(ISD::TRUNCATE, N->getValueType(0), InL); + return DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), N->getValueType(0), InL); } SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { @@ -2160,7 +2213,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { if (TLI.getOperationAction(ISD::SINT_TO_FP, SrcVT) == TargetLowering::Custom){ // Do a signed conversion then adjust the result. - SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, DstVT, Op); + SDValue SignedConv = DAG.getNode(ISD::SINT_TO_FP, dl, DstVT, Op); SignedConv = TLI.LowerOperation(SignedConv, DAG); // The result of the signed conversion needs adjusting if the 'sign bit' of @@ -2184,7 +2237,8 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { // Check whether the sign bit is set. SDValue Lo, Hi; GetExpandedInteger(Op, Lo, Hi); - SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi.getValueType()), + SDValue SignSet = DAG.getSetCC(dl, + TLI.getSetCCResultType(Hi.getValueType()), Hi, DAG.getConstant(0, Hi.getValueType()), ISD::SETLT); @@ -2196,19 +2250,19 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { SDValue Zero = DAG.getIntPtrConstant(0); SDValue Four = DAG.getIntPtrConstant(4); if (TLI.isBigEndian()) std::swap(Zero, Four); - SDValue Offset = DAG.getNode(ISD::SELECT, Zero.getValueType(), SignSet, + SDValue Offset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet, Zero, Four); unsigned Alignment = 1 << cast(FudgePtr)->getAlignment(); - FudgePtr = DAG.getNode(ISD::ADD, TLI.getPointerTy(), FudgePtr, Offset); + FudgePtr = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), FudgePtr, Offset); Alignment = std::min(Alignment, 4u); // Load the value out, extending it from f32 to the destination float type. // FIXME: Avoid the extend by constructing the right constant pool? - SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, DstVT, DAG.getEntryNode(), + SDValue Fudge = DAG.getExtLoad(ISD::EXTLOAD, dl, DstVT, DAG.getEntryNode(), FudgePtr, NULL, 0, MVT::f32, false, Alignment); - return DAG.getNode(ISD::FADD, DstVT, SignedConv, Fudge); + return DAG.getNode(ISD::FADD, dl, DstVT, SignedConv, Fudge); } // Otherwise, use a libcall. -- GitLab From dc0f1244293912f273f2943b7a6620da8c846394 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 00:43:08 +0000 Subject: [PATCH 556/682] Propagate debug info in LegalizeFloatTypes. Complete (modulo bugs). llvm-svn: 63458 --- .../SelectionDAG/LegalizeFloatTypes.cpp | 134 ++++++++++-------- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 2 +- 2 files changed, 74 insertions(+), 62 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index d95853846b89..648e9e6302c3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -101,7 +101,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_BIT_CONVERT(SDNode *N) { SDValue DAGTypeLegalizer::SoftenFloatRes_BUILD_PAIR(SDNode *N) { // Convert the inputs to integers, and build a new pair out of them. - return DAG.getNode(ISD::BUILD_PAIR, + return DAG.getNode(ISD::BUILD_PAIR, N->getDebugLoc(), TLI.getTypeToTransformTo(N->getValueType(0)), BitConvertToInteger(N->getOperand(0)), BitConvertToInteger(N->getOperand(1))); @@ -120,7 +120,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FABS(SDNode *N) { SDValue Mask = DAG.getConstant(APInt::getAllOnesValue(Size).clear(Size-1), NVT); SDValue Op = GetSoftenedFloat(N->getOperand(0)); - return DAG.getNode(ISD::AND, NVT, Op, Mask); + return DAG.getNode(ISD::AND, N->getDebugLoc(), NVT, Op, Mask); } SDValue DAGTypeLegalizer::SoftenFloatRes_FADD(SDNode *N) { @@ -149,6 +149,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCEIL(SDNode *N) { SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { SDValue LHS = GetSoftenedFloat(N->getOperand(0)); SDValue RHS = BitConvertToInteger(N->getOperand(1)); + DebugLoc dl = N->getDebugLoc(); MVT LVT = LHS.getValueType(); MVT RVT = RHS.getValueType(); @@ -157,32 +158,32 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_FCOPYSIGN(SDNode *N) { unsigned RSize = RVT.getSizeInBits(); // First get the sign bit of second operand. - SDValue SignBit = DAG.getNode(ISD::SHL, RVT, DAG.getConstant(1, RVT), + SDValue SignBit = DAG.getNode(ISD::SHL, dl, RVT, DAG.getConstant(1, RVT), DAG.getConstant(RSize - 1, TLI.getShiftAmountTy())); - SignBit = DAG.getNode(ISD::AND, RVT, RHS, SignBit); + SignBit = DAG.getNode(ISD::AND, dl, RVT, RHS, SignBit); // Shift right or sign-extend it if the two operands have different types. int SizeDiff = RVT.getSizeInBits() - LVT.getSizeInBits(); if (SizeDiff > 0) { - SignBit = DAG.getNode(ISD::SRL, RVT, SignBit, + SignBit = DAG.getNode(ISD::SRL, dl, RVT, SignBit, DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); - SignBit = DAG.getNode(ISD::TRUNCATE, LVT, SignBit); + SignBit = DAG.getNode(ISD::TRUNCATE, dl, LVT, SignBit); } else if (SizeDiff < 0) { - SignBit = DAG.getNode(ISD::ANY_EXTEND, LVT, SignBit); - SignBit = DAG.getNode(ISD::SHL, LVT, SignBit, + SignBit = DAG.getNode(ISD::ANY_EXTEND, dl, LVT, SignBit); + SignBit = DAG.getNode(ISD::SHL, dl, LVT, SignBit, DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); } // Clear the sign bit of the first operand. - SDValue Mask = DAG.getNode(ISD::SHL, LVT, DAG.getConstant(1, LVT), + SDValue Mask = DAG.getNode(ISD::SHL, dl, LVT, DAG.getConstant(1, LVT), DAG.getConstant(LSize - 1, TLI.getShiftAmountTy())); - Mask = DAG.getNode(ISD::SUB, LVT, Mask, DAG.getConstant(1, LVT)); - LHS = DAG.getNode(ISD::AND, LVT, LHS, Mask); + Mask = DAG.getNode(ISD::SUB, dl, LVT, Mask, DAG.getConstant(1, LVT)); + LHS = DAG.getNode(ISD::AND, dl, LVT, LHS, Mask); // Or the value with the sign bit. - return DAG.getNode(ISD::OR, LVT, LHS, SignBit); + return DAG.getNode(ISD::OR, dl, LVT, LHS, SignBit); } SDValue DAGTypeLegalizer::SoftenFloatRes_FCOS(SDNode *N) { @@ -411,10 +412,11 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { LoadSDNode *L = cast(N); MVT VT = N->getValueType(0); MVT NVT = TLI.getTypeToTransformTo(VT); + DebugLoc dl = N->getDebugLoc(); SDValue NewL; if (L->getExtensionType() == ISD::NON_EXTLOAD) { - NewL = DAG.getLoad(L->getAddressingMode(), L->getExtensionType(), + NewL = DAG.getLoad(L->getAddressingMode(), dl, L->getExtensionType(), NVT, L->getChain(), L->getBasePtr(), L->getOffset(), L->getSrcValue(), L->getSrcValueOffset(), NVT, L->isVolatile(), L->getAlignment()); @@ -425,7 +427,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { } // Do a non-extending load followed by FP_EXTEND. - NewL = DAG.getLoad(L->getAddressingMode(), ISD::NON_EXTLOAD, + NewL = DAG.getLoad(L->getAddressingMode(), dl, ISD::NON_EXTLOAD, L->getMemoryVT(), L->getChain(), L->getBasePtr(), L->getOffset(), L->getSrcValue(), L->getSrcValueOffset(), @@ -434,19 +436,21 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_LOAD(SDNode *N) { // Legalized the chain result - switch anything that used the old chain to // use the new one. ReplaceValueWith(SDValue(N, 1), NewL.getValue(1)); - return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, VT, NewL)); + return BitConvertToInteger(DAG.getNode(ISD::FP_EXTEND, dl, VT, NewL)); } SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT(SDNode *N) { SDValue LHS = GetSoftenedFloat(N->getOperand(1)); SDValue RHS = GetSoftenedFloat(N->getOperand(2)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0),LHS,RHS); + return DAG.getNode(ISD::SELECT, N->getDebugLoc(), + LHS.getValueType(), N->getOperand(0),LHS,RHS); } SDValue DAGTypeLegalizer::SoftenFloatRes_SELECT_CC(SDNode *N) { SDValue LHS = GetSoftenedFloat(N->getOperand(2)); SDValue RHS = GetSoftenedFloat(N->getOperand(3)); - return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), N->getOperand(0), + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), + LHS.getValueType(), N->getOperand(0), N->getOperand(1), LHS, RHS, N->getOperand(4)); } @@ -471,7 +475,7 @@ SDValue DAGTypeLegalizer::SoftenFloatRes_XINT_TO_FP(SDNode *N) { assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unsupported XINT_TO_FP!"); // Sign/zero extend the argument if the libcall takes a larger type. - SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + SDValue Op = DAG.getNode(Signed ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, NVT, N->getOperand(0)); return MakeLibCall(LC, TLI.getTypeToTransformTo(RVT), &Op, 1, false, dl); } @@ -595,18 +599,18 @@ void DAGTypeLegalizer::SoftenSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, NewRHS = DAG.getConstant(0, RetVT); CCCode = TLI.getCmpLibcallCC(LC1); if (LC2 != RTLIB::UNKNOWN_LIBCALL) { - SDValue Tmp = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), + SDValue Tmp = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS, NewRHS, DAG.getCondCode(CCCode)); NewLHS = MakeLibCall(LC2, RetVT, Ops, 2, false/*sign irrelevant*/, dl); - NewLHS = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(RetVT), NewLHS, + NewLHS = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(RetVT), NewLHS, NewRHS, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); - NewLHS = DAG.getNode(ISD::OR, Tmp.getValueType(), Tmp, NewLHS); + NewLHS = DAG.getNode(ISD::OR, dl, Tmp.getValueType(), Tmp, NewLHS); NewRHS = SDValue(); } } SDValue DAGTypeLegalizer::SoftenFloatOp_BIT_CONVERT(SDNode *N) { - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), GetSoftenedFloat(N->getOperand(0))); } @@ -695,15 +699,16 @@ SDValue DAGTypeLegalizer::SoftenFloatOp_STORE(SDNode *N, unsigned OpNo) { assert(OpNo == 1 && "Can only soften the stored value!"); StoreSDNode *ST = cast(N); SDValue Val = ST->getValue(); + DebugLoc dl = N->getDebugLoc(); if (ST->isTruncatingStore()) // Do an FP_ROUND followed by a non-truncating store. - Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, ST->getMemoryVT(), + Val = BitConvertToInteger(DAG.getNode(ISD::FP_ROUND, dl, ST->getMemoryVT(), Val, DAG.getIntPtrConstant(0))); else Val = GetSoftenedFloat(Val); - return DAG.getStore(ST->getChain(), Val, ST->getBasePtr(), + return DAG.getStore(ST->getChain(), dl, Val, ST->getBasePtr(), ST->getSrcValue(), ST->getSrcValueOffset(), ST->isVolatile(), ST->getAlignment()); } @@ -795,12 +800,13 @@ void DAGTypeLegalizer::ExpandFloatRes_FABS(SDNode *N, SDValue &Lo, SDValue &Hi) { assert(N->getValueType(0) == MVT::ppcf128 && "Logic only correct for ppcf128!"); + DebugLoc dl = N->getDebugLoc(); SDValue Tmp; GetExpandedFloat(N->getOperand(0), Lo, Tmp); - Hi = DAG.getNode(ISD::FABS, Tmp.getValueType(), Tmp); + Hi = DAG.getNode(ISD::FABS, dl, Tmp.getValueType(), Tmp); // Lo = Hi==fabs(Hi) ? Lo : -Lo; - Lo = DAG.getNode(ISD::SELECT_CC, Lo.getValueType(), Tmp, Hi, Lo, - DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo), + Lo = DAG.getNode(ISD::SELECT_CC, dl, Lo.getValueType(), Tmp, Hi, Lo, + DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo), DAG.getCondCode(ISD::SETEQ)); } @@ -948,15 +954,16 @@ void DAGTypeLegalizer::ExpandFloatRes_FNEARBYINT(SDNode *N, void DAGTypeLegalizer::ExpandFloatRes_FNEG(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); GetExpandedFloat(N->getOperand(0), Lo, Hi); - Lo = DAG.getNode(ISD::FNEG, Lo.getValueType(), Lo); - Hi = DAG.getNode(ISD::FNEG, Hi.getValueType(), Hi); + Lo = DAG.getNode(ISD::FNEG, dl, Lo.getValueType(), Lo); + Hi = DAG.getNode(ISD::FNEG, dl, Hi.getValueType(), Hi); } void DAGTypeLegalizer::ExpandFloatRes_FP_EXTEND(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - Hi = DAG.getNode(ISD::FP_EXTEND, NVT, N->getOperand(0)); + Hi = DAG.getNode(ISD::FP_EXTEND, N->getDebugLoc(), NVT, N->getOperand(0)); Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); } @@ -1052,12 +1059,13 @@ void DAGTypeLegalizer::ExpandFloatRes_LOAD(SDNode *N, SDValue &Lo, LoadSDNode *LD = cast(N); SDValue Chain = LD->getChain(); SDValue Ptr = LD->getBasePtr(); + DebugLoc dl = N->getDebugLoc(); MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); assert(NVT.isByteSized() && "Expanded type not byte sized!"); assert(LD->getMemoryVT().bitsLE(NVT) && "Float type not round?"); - Hi = DAG.getExtLoad(LD->getExtensionType(), NVT, Chain, Ptr, + Hi = DAG.getExtLoad(LD->getExtensionType(), dl, NVT, Chain, Ptr, LD->getSrcValue(), LD->getSrcValueOffset(), LD->getMemoryVT(), LD->isVolatile(), LD->getAlignment()); @@ -1088,14 +1096,14 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, // though. if (SrcVT.bitsLE(MVT::i32)) { // The integer can be represented exactly in an f64. - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, MVT::i32, Src); Lo = DAG.getConstantFP(APFloat(APInt(NVT.getSizeInBits(), 0)), NVT); - Hi = DAG.getNode(ISD::SINT_TO_FP, NVT, Src); + Hi = DAG.getNode(ISD::SINT_TO_FP, dl, NVT, Src); } else { RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; if (SrcVT.bitsLE(MVT::i64)) { - Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, + Src = DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, dl, MVT::i64, Src); LC = RTLIB::SINTTOFP_I64_PPCF128; } else if (SrcVT.bitsLE(MVT::i128)) { @@ -1114,7 +1122,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, return; // Unsigned - fix up the SINT_TO_FP value just calculated. - Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); + Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); SrcVT = Src.getValueType(); // x>=0 ? (ppcf128)(iN)x : (ppcf128)(iN)x + 2^N; N=32,64,128. @@ -1137,13 +1145,13 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, break; } - Lo = DAG.getNode(ISD::FADD, VT, Hi, + Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), MVT::ppcf128)); - Lo = DAG.getNode(ISD::SELECT_CC, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, - DAG.getCondCode(ISD::SETLT)); - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(1)); - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Lo, DAG.getIntPtrConstant(0)); + Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), + Lo, Hi, DAG.getCondCode(ISD::SETLT)); + Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(1)); + Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(0)); } @@ -1207,7 +1215,8 @@ bool DAGTypeLegalizer::ExpandFloatOperand(SDNode *N, unsigned OpNo) { /// is shared among BR_CC, SELECT_CC, and SETCC handlers. void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode) { + ISD::CondCode &CCCode, + DebugLoc dl) { SDValue LHSLo, LHSHi, RHSLo, RHSHi; GetExpandedFloat(NewLHS, LHSLo, LHSHi); GetExpandedFloat(NewRHS, RHSLo, RHSHi); @@ -1221,24 +1230,24 @@ void DAGTypeLegalizer::FloatExpandSetCCOperands(SDValue &NewLHS, // FCMPU crN, lo1, lo2 // The following can be improved, but not that much. SDValue Tmp1, Tmp2, Tmp3; - Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETOEQ); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()), + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, CCCode); - Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETUNE); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, CCCode); - Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - NewLHS = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); + Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); + NewLHS = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3); NewRHS = SDValue(); // LHS is the result, not a compare. } SDValue DAGTypeLegalizer::ExpandFloatOp_BR_CC(SDNode *N) { SDValue NewLHS = N->getOperand(2), NewRHS = N->getOperand(3); ISD::CondCode CCCode = cast(N->getOperand(1))->get(); - FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); + FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If ExpandSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. @@ -1259,7 +1268,8 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { SDValue Lo, Hi; GetExpandedFloat(N->getOperand(0), Lo, Hi); // Round it the rest of the way (e.g. to f32) if needed. - return DAG.getNode(ISD::FP_ROUND, N->getValueType(0), Hi, N->getOperand(1)); + return DAG.getNode(ISD::FP_ROUND, N->getDebugLoc(), + N->getValueType(0), Hi, N->getOperand(1)); } SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { @@ -1271,10 +1281,11 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { if (RVT == MVT::i32) { assert(N->getOperand(0).getValueType() == MVT::ppcf128 && "Logic only correct for ppcf128!"); - SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128, + SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, N->getOperand(0), DAG.getValueType(MVT::f64)); - Res = DAG.getNode(ISD::FP_ROUND, MVT::f64, Res, DAG.getIntPtrConstant(1)); - return DAG.getNode(ISD::FP_TO_SINT, MVT::i32, Res); + Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, + DAG.getIntPtrConstant(1)); + return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); } RTLIB::Libcall LC = RTLIB::getFPTOSINT(N->getOperand(0).getValueType(), RVT); @@ -1296,15 +1307,16 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { SDValue Tmp = DAG.getConstantFP(APF, MVT::ppcf128); // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X // FIXME: generated code sucks. - return DAG.getNode(ISD::SELECT_CC, MVT::i32, N->getOperand(0), Tmp, - DAG.getNode(ISD::ADD, MVT::i32, - DAG.getNode(ISD::FP_TO_SINT, MVT::i32, - DAG.getNode(ISD::FSUB, + return DAG.getNode(ISD::SELECT_CC, dl, MVT::i32, N->getOperand(0), Tmp, + DAG.getNode(ISD::ADD, dl, MVT::i32, + DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, + DAG.getNode(ISD::FSUB, dl, MVT::ppcf128, N->getOperand(0), Tmp)), DAG.getConstant(0x80000000, MVT::i32)), - DAG.getNode(ISD::FP_TO_SINT, MVT::i32, N->getOperand(0)), + DAG.getNode(ISD::FP_TO_SINT, dl, + MVT::i32, N->getOperand(0)), DAG.getCondCode(ISD::SETGE)); } @@ -1316,7 +1328,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_UINT(SDNode *N) { SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(4))->get(); - FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); + FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If ExpandSetCCOperands returned a scalar, we need to compare the result // against zero to select between true and false values. @@ -1334,7 +1346,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_SELECT_CC(SDNode *N) { SDValue DAGTypeLegalizer::ExpandFloatOp_SETCC(SDNode *N) { SDValue NewLHS = N->getOperand(0), NewRHS = N->getOperand(1); ISD::CondCode CCCode = cast(N->getOperand(2))->get(); - FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode); + FloatExpandSetCCOperands(NewLHS, NewRHS, CCCode, N->getDebugLoc()); // If ExpandSetCCOperands returned a scalar, use it. if (NewRHS.getNode() == 0) { @@ -1366,7 +1378,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_STORE(SDNode *N, unsigned OpNo) { SDValue Lo, Hi; GetExpandedOp(ST->getValue(), Lo, Hi); - return DAG.getTruncStore(Chain, Hi, Ptr, + return DAG.getTruncStore(Chain, N->getDebugLoc(), Hi, Ptr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getMemoryVT(), ST->isVolatile(), ST->getAlignment()); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index e7854d97b1cd..cdbf231911a7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -481,7 +481,7 @@ private: SDValue ExpandFloatOp_STORE(SDNode *N, unsigned OpNo); void FloatExpandSetCCOperands(SDValue &NewLHS, SDValue &NewRHS, - ISD::CondCode &CCCode); + ISD::CondCode &CCCode, DebugLoc dl); //===--------------------------------------------------------------------===// // Scalarization Support: LegalizeVectorTypes.cpp -- GitLab From f88092ee064cd1fcab01758cbc2be9dbbf6b9153 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Sat, 31 Jan 2009 00:58:14 +0000 Subject: [PATCH 557/682] use precise accessors llvm-svn: 63459 --- llvm/lib/VMCore/AsmWriter.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp index 6a17516be26d..0322d669d325 100644 --- a/llvm/lib/VMCore/AsmWriter.cpp +++ b/llvm/lib/VMCore/AsmWriter.cpp @@ -1505,13 +1505,14 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; // Special case conditional branches to swizzle the condition out to the front - if (isa(I) && I.getNumOperands() > 1) { + if (isa(I) && cast(I).isConditional()) { + BranchInst &BI(cast(I)); Out << ' '; - writeOperand(I.getOperand(2), true); + writeOperand(BI.getCondition(), true); Out << ", "; - writeOperand(Operand, true); + writeOperand(BI.getSuccessor(0), true); Out << ", "; - writeOperand(I.getOperand(1), true); + writeOperand(BI.getSuccessor(1), true); } else if (isa(I)) { // Special case switch statement to get formatting nice and correct... -- GitLab From 822082517fd718fc2688e62abe9ee26aa665f006 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 31 Jan 2009 00:59:10 +0000 Subject: [PATCH 558/682] Recognize class's visibility attribute and set its linkage to private extern (in objc2 nonfragile abi). llvm-svn: 63460 --- clang/lib/CodeGen/CGObjCMac.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index b5e380496450..7f5857090014 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -573,7 +573,8 @@ private: llvm::GlobalVariable * BuildClassMetaData(std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV, - llvm::Constant *ClassRoGV); + llvm::Constant *ClassRoGV, + bool HiddenVisibility); llvm::Constant *GetMethodConstant(const ObjCMethodDecl *MD); @@ -3361,7 +3362,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( std::string &ClassName, llvm::Constant *IsAGV, llvm::Constant *SuperClassGV, - llvm::Constant *ClassRoGV) { + llvm::Constant *ClassRoGV, + bool HiddenVisibility) { std::vector Values(5); Values[0] = IsAGV; Values[1] = SuperClassGV @@ -3384,6 +3386,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( &CGM.getModule()); GV->setSection("__DATA, __objc_const"); GV->setAlignment(GetPointerAlign()); + if (HiddenVisibility) + GV->setVisibility(llvm::GlobalValue::HiddenVisibility); UsedGlobals.push_back(GV); return GV; } @@ -3421,7 +3425,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { llvm::GlobalVariable *SuperClassGV, *IsAGV; - if (IsClassHidden(ID->getClassInterface())) + bool classIsHidden = IsClassHidden(ID->getClassInterface()); + if (classIsHidden) flags |= OBJC2_CLS_HIDDEN; if (!ID->getClassInterface()->getSuperClass()) { // class is root @@ -3467,11 +3472,12 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { InstanceSize,ID); std::string TClassName = ObjCMetaClassName + ClassName; llvm::GlobalVariable *MetaTClass = - BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV); + BuildClassMetaData(TClassName, IsAGV, SuperClassGV, CLASS_RO_GV, + classIsHidden); // Metadata for the class flags = CLS; - if (IsClassHidden(ID->getClassInterface())) + if (classIsHidden) flags |= OBJC2_CLS_HIDDEN; if (!ID->getClassInterface()->getSuperClass()) { flags |= CLS_ROOT; @@ -3532,7 +3538,8 @@ void CGObjCNonFragileABIMac::GenerateClass(const ObjCImplementationDecl *ID) { TClassName = ObjCClassName + ClassName; llvm::GlobalVariable *ClassMD = - BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV); + BuildClassMetaData(TClassName, MetaTClass, SuperClassGV, CLASS_RO_GV, + classIsHidden); DefinedClasses.push_back(ClassMD); } @@ -3745,6 +3752,11 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( Ivar->getAccessControl() == ObjCIvarDecl::Protected); if (!globalVisibility) IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); + else + if (const ObjCInterfaceDecl *OID = ID->getClassInterface()) + if (IsClassHidden(OID)) + IvarOffsetGV->setVisibility(llvm::GlobalValue::HiddenVisibility); + IvarOffsetGV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(IvarOffsetGV); -- GitLab From 040872326943cd75a9be5b9246698949f3a0ae3b Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 31 Jan 2009 01:07:39 +0000 Subject: [PATCH 559/682] class meta-data belong to __objc_data section (in objc2 nonfragile abi). llvm-svn: 63461 --- clang/lib/CodeGen/CGObjCMac.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 7f5857090014..6c35041b9714 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -3384,7 +3384,7 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( Init, ClassName, &CGM.getModule()); - GV->setSection("__DATA, __objc_const"); + GV->setSection("__DATA, __objc_data"); GV->setAlignment(GetPointerAlign()); if (HiddenVisibility) GV->setVisibility(llvm::GlobalValue::HiddenVisibility); -- GitLab From d277d790e0f6f23043397ba919619b5c3e157ff3 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 31 Jan 2009 01:16:18 +0000 Subject: [PATCH 560/682] Add sema support for the cleanup attribute. llvm-svn: 63462 --- clang/include/clang/AST/Attr.h | 19 +++++++- .../clang/Basic/DiagnosticSemaKinds.def | 8 +++- clang/include/clang/Parse/AttributeList.h | 1 + clang/lib/Parse/AttributeList.cpp | 1 + clang/lib/Sema/SemaDeclAttr.cpp | 46 +++++++++++++++++++ 5 files changed, 73 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/AST/Attr.h b/clang/include/clang/AST/Attr.h index 726d35007226..38e2b9ecb181 100644 --- a/clang/include/clang/AST/Attr.h +++ b/clang/include/clang/AST/Attr.h @@ -52,7 +52,8 @@ public: Weak, Blocks, Const, - Pure + Pure, + Cleanup }; private: @@ -446,6 +447,22 @@ public: static bool classof(const BlocksAttr *A) { return true; } }; +class FunctionDecl; + +class CleanupAttr : public Attr { + FunctionDecl *FD; + +public: + CleanupAttr(FunctionDecl *fd) : Attr(Cleanup), FD(fd) {} + + const FunctionDecl *getFunctionDecl() const { return FD; } + + // Implement isa/cast/dyncast/etc. + + static bool classof(const Attr *A) { return A->getKind() == Cleanup; } + static bool classof(const CleanupAttr *A) { return true; } +}; + } // end namespace clang #endif diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.def b/clang/include/clang/Basic/DiagnosticSemaKinds.def index 89577dfd3922..7f1ca49b66f1 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.def +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.def @@ -377,7 +377,13 @@ DIAG(err_attribute_sentinel_less_than_zero, ERROR, "'sentinel' parameter 1 less than zero") DIAG(err_attribute_sentinel_not_zero_or_one, ERROR, "'sentinel' parameter 2 not 0 or 1") - +DIAG(err_attribute_cleanup_arg_not_found, ERROR, + "'cleanup' argument %0 not found") +DIAG(err_attribute_cleanup_arg_not_function, ERROR, + "'cleanup' argument %0 is not a function") +DIAG(err_attribute_cleanup_arg_must_take_one_arg, ERROR, + "'cleanup' function %0 must take 1 parameter") + // Clang-Specific Attributes DIAG(err_attribute_iboutlet_non_ivar, ERROR, "'iboutlet' attribute can only be applied to instance variables") diff --git a/clang/include/clang/Parse/AttributeList.h b/clang/include/clang/Parse/AttributeList.h index 9c8c70945e11..bca12a3e60a1 100644 --- a/clang/include/clang/Parse/AttributeList.h +++ b/clang/include/clang/Parse/AttributeList.h @@ -77,6 +77,7 @@ public: AT_sentinel, AT_const, AT_nsobject, + AT_cleanup, UnknownAttribute }; diff --git a/clang/lib/Parse/AttributeList.cpp b/clang/lib/Parse/AttributeList.cpp index 6c1583a0feb9..477d6e363d18 100644 --- a/clang/lib/Parse/AttributeList.cpp +++ b/clang/lib/Parse/AttributeList.cpp @@ -73,6 +73,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { if (!memcmp(Str, "nonnull", 7)) return AT_nonnull; if (!memcmp(Str, "objc_gc", 7)) return AT_objc_gc; if (!memcmp(Str, "stdcall", 7)) return AT_stdcall; + if (!memcmp(Str, "cleanup", 7)) return AT_cleanup; break; case 8: if (!memcmp(Str, "annotate", 8)) return AT_annotate; diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index bf4549d05bca..33985ee1a33f 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -846,6 +846,51 @@ static void HandlePureAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(new PureAttr()); } +static void HandleCleanupAttr(Decl *d, const AttributeList &Attr, Sema &S) { + if (!Attr.getParameterName()) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; + return; + } + + if (Attr.getNumArgs() != 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1; + return; + } + + VarDecl *VD = dyn_cast(d); + + if (!VD || !VD->hasLocalStorage()) { + S.Diag(Attr.getLoc(), diag::warn_attribute_ignored) << "cleanup"; + return; + } + + // Look up the function + Decl *CleanupDecl = S.LookupName(S.TUScope, Attr.getParameterName(), + Sema::LookupOrdinaryName); + if (!CleanupDecl) { + S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_found) << + Attr.getParameterName(); + return; + } + + FunctionDecl *FD = dyn_cast(CleanupDecl); + if (!FD) { + S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_not_function) << + Attr.getParameterName(); + return; + } + + // FIXME: This needs to work with C++ overloading. + // FIXME: This should verify that the function type is compatible + if (FD->getNumParams() != 1) { + S.Diag(Attr.getLoc(), diag::err_attribute_cleanup_arg_must_take_one_arg)<< + Attr.getParameterName(); + return; + } + + d->addAttr(new CleanupAttr(FD)); +} + /// Handle __attribute__((format(type,idx,firstarg))) attributes /// based on http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html static void HandleFormatAttr(Decl *d, const AttributeList &Attr, Sema &S) { @@ -1248,6 +1293,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { case AttributeList::AT_sentinel: HandleSentinelAttr (D, Attr, S); break; case AttributeList::AT_const: HandleConstAttr (D, Attr, S); break; case AttributeList::AT_pure: HandlePureAttr (D, Attr, S); break; + case AttributeList::AT_cleanup: HandleCleanupAttr (D, Attr, S); break; default: #if 0 // TODO: when we have the full set of attributes, warn about unknown ones. -- GitLab From dc588689bb66c1fd0c6257b31af1597266662d00 Mon Sep 17 00:00:00 2001 From: Gabor Greif Date: Sat, 31 Jan 2009 01:31:59 +0000 Subject: [PATCH 561/682] back out my previous change, it exposes a latent bug. investigating llvm-svn: 63463 --- llvm/lib/VMCore/AsmWriter.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/llvm/lib/VMCore/AsmWriter.cpp b/llvm/lib/VMCore/AsmWriter.cpp index 0322d669d325..6a17516be26d 100644 --- a/llvm/lib/VMCore/AsmWriter.cpp +++ b/llvm/lib/VMCore/AsmWriter.cpp @@ -1505,14 +1505,13 @@ void AssemblyWriter::printInstruction(const Instruction &I) { const Value *Operand = I.getNumOperands() ? I.getOperand(0) : 0; // Special case conditional branches to swizzle the condition out to the front - if (isa(I) && cast(I).isConditional()) { - BranchInst &BI(cast(I)); + if (isa(I) && I.getNumOperands() > 1) { Out << ' '; - writeOperand(BI.getCondition(), true); + writeOperand(I.getOperand(2), true); Out << ", "; - writeOperand(BI.getSuccessor(0), true); + writeOperand(Operand, true); Out << ", "; - writeOperand(BI.getSuccessor(1), true); + writeOperand(I.getOperand(1), true); } else if (isa(I)) { // Special case switch statement to get formatting nice and correct... -- GitLab From a377abfe26dc0957ae184f9545d92e01623c08fd Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Sat, 31 Jan 2009 01:32:23 +0000 Subject: [PATCH 562/682] Update checker build. llvm-svn: 63464 --- clang/www/latest_checker.html.incl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/www/latest_checker.html.incl b/clang/www/latest_checker.html.incl index 52820d065920..96ba4eeb7ab6 100644 --- a/clang/www/latest_checker.html.incl +++ b/clang/www/latest_checker.html.incl @@ -1 +1 @@ -checker-0.146.tar.bz2 (built January 28, 2009) +checker-0.147.tar.bz2 (built January 30, 2009) -- GitLab From 3cd20632ff20fe85d00e2f0d591b5c517e85abf3 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 31 Jan 2009 02:19:00 +0000 Subject: [PATCH 563/682] Kill off CGCallInfo, always use CGFunctionInfo for encapsulating function/call info. llvm-svn: 63466 --- clang/lib/CodeGen/CGCall.cpp | 51 +++++++++++------------------ clang/lib/CodeGen/CGCall.h | 14 ++------ clang/lib/CodeGen/CGObjCMac.cpp | 4 +-- clang/lib/CodeGen/CodeGenModule.cpp | 3 +- clang/lib/CodeGen/CodeGenModule.h | 3 +- clang/lib/CodeGen/CodeGenTypes.h | 4 --- 6 files changed, 26 insertions(+), 53 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 0807caff9bea..e282980d13a2 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -73,27 +73,21 @@ CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD, ArgTypes.push_back((*i)->getType()); } -ArgTypeIterator CGFunctionInfo::argtypes_begin() const { - return ArgTypes.begin(); -} - -ArgTypeIterator CGFunctionInfo::argtypes_end() const { - return ArgTypes.end(); -} - -/***/ - -CGCallInfo::CGCallInfo(QualType _ResultType, const CallArgList &_Args) { - ArgTypes.push_back(_ResultType); - for (CallArgList::const_iterator i = _Args.begin(), e = _Args.end(); i!=e; ++i) +CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args, + bool _IsVariadic) + : IsVariadic(_IsVariadic) +{ + ArgTypes.push_back(ResTy); + for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); + i != e; ++i) ArgTypes.push_back(i->second); } -ArgTypeIterator CGCallInfo::argtypes_begin() const { +ArgTypeIterator CGFunctionInfo::argtypes_begin() const { return ArgTypes.begin(); } -ArgTypeIterator CGCallInfo::argtypes_end() const { +ArgTypeIterator CGFunctionInfo::argtypes_end() const { return ArgTypes.end(); } @@ -878,14 +872,10 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, /***/ -const llvm::FunctionType * -CodeGenTypes::GetFunctionType(const CGCallInfo &CI, bool IsVariadic) { - return GetFunctionType(CI.argtypes_begin(), CI.argtypes_end(), IsVariadic); -} - const llvm::FunctionType * CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { - return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), FI.isVariadic()); + return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), + FI.isVariadic()); } const llvm::FunctionType * @@ -962,8 +952,7 @@ bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) { } void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, - ArgTypeIterator begin, - ArgTypeIterator end, + const CGFunctionInfo &Info, AttributeListType &PAL) { unsigned FuncAttrs = 0; unsigned RetAttrs = 0; @@ -979,6 +968,7 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, FuncAttrs |= llvm::Attribute::ReadNone; } + ArgTypeIterator begin = Info.argtypes_begin(), end = Info.argtypes_end(); QualType RetTy = *begin; unsigned Index = 1; ABIArgInfo RetAI = getABIReturnInfo(RetTy, getTypes()); @@ -995,8 +985,8 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, case ABIArgInfo::StructRet: PAL.push_back(llvm::AttributeWithIndex::get(Index, - llvm::Attribute::StructRet| - llvm::Attribute::NoAlias)); + llvm::Attribute::StructRet | + llvm::Attribute::NoAlias)); ++Index; break; @@ -1294,16 +1284,15 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, } llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); - CGCallInfo CallInfo(RetTy, CallArgs); + bool isVariadic = cast(Callee->getType())->isVarArg(); + CGFunctionInfo CallInfo(RetTy, CallArgs, isVariadic); // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. CodeGen::AttributeListType AttributeList; - CGM.ConstructAttributeList(0, - CallInfo.argtypes_begin(), CallInfo.argtypes_end(), - AttributeList); + CGM.ConstructAttributeList(0, CallInfo, AttributeList); CI->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(), - AttributeList.size())); - + AttributeList.size())); + if (const llvm::Function *F = dyn_cast(Callee)) CI->setCallingConv(F->getCallingConv()); if (CI->getType() != llvm::Type::VoidTy) diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 744344a7acc5..fd6eb481598e 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -64,24 +64,14 @@ namespace CodeGen { CGFunctionInfo(const FunctionDecl *FD); CGFunctionInfo(const ObjCMethodDecl *MD, const ASTContext &Context); + CGFunctionInfo(QualType ResTy, const CallArgList &Args, + bool _IsVariadic); bool isVariadic() const { return IsVariadic; } ArgTypeIterator argtypes_begin() const; ArgTypeIterator argtypes_end() const; }; - - /// CGCallInfo - Class to encapsulate the arguments and clang types - /// used in a call. - class CGCallInfo { - llvm::SmallVector ArgTypes; - - public: - CGCallInfo(QualType _ResultType, const CallArgList &Args); - - ArgTypeIterator argtypes_begin() const; - ArgTypeIterator argtypes_end() const; - }; } // end namespace CodeGen } // end namespace clang diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 6c35041b9714..4e6611bc554b 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -799,8 +799,8 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); const llvm::FunctionType *FTy = - CGM.getTypes().GetFunctionType(CGCallInfo(ResultType, ActualArgs), - false); + CGM.getTypes().GetFunctionType(CGFunctionInfo(ResultType, ActualArgs, + false)); llvm::Constant *Fn; if (CGM.ReturnTypeUsesSret(ResultType)) { diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 6e1321f4d6c6..bdb99d6439b7 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -265,8 +265,7 @@ void CodeGenModule::SetFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F) { AttributeListType AttributeList; - ConstructAttributeList(D, Info.argtypes_begin(), Info.argtypes_end(), - AttributeList); + ConstructAttributeList(D, Info, AttributeList); F->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(), AttributeList.size())); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 0bd0e2c724fd..724ca28b886f 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -247,8 +247,7 @@ public: bool ReturnTypeUsesSret(QualType RetTy); void ConstructAttributeList(const Decl *TargetDecl, - const ArgTypeIterator begin, - const ArgTypeIterator end, + const CGFunctionInfo &Info, AttributeListType &PAL); private: diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 2fe7c89fadac..46ca79a3caa1 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -145,10 +145,6 @@ public: /// GetFunctionType - Get the LLVM function type from Info. const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info); - /// GetFunctionType - Get the LLVM function type from Info. - /// \param IsVariadic Should the resulting type be variadic? - const llvm::FunctionType *GetFunctionType(const CGCallInfo &Info, - bool IsVariadic); /// GetFunctionType - Get the LLVM function type for the given types /// and variadicness. -- GitLab From a37249c66371f13f9e3a94231c1f688e81683c1f Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 31 Jan 2009 02:20:43 +0000 Subject: [PATCH 564/682] Err, unbreak my previous "no functionality change commit", will fix properly later. llvm-svn: 63467 --- clang/lib/CodeGen/CGCall.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index e282980d13a2..b6c5d8d273ed 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1284,7 +1284,7 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, } llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); - bool isVariadic = cast(Callee->getType())->isVarArg(); + bool isVariadic = false; // cast(Callee->getType())->isVarArg(); CGFunctionInfo CallInfo(RetTy, CallArgs, isVariadic); // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. -- GitLab From db7c5f6a7b25bed22a4f0b65103b7bc92b8c7ae8 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 02:22:37 +0000 Subject: [PATCH 565/682] Move CurDebugLoc into SelectionDAGLowering. llvm-svn: 63468 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 6 - .../SelectionDAG/SelectionDAGBuild.cpp | 445 +++++++++--------- .../CodeGen/SelectionDAG/SelectionDAGBuild.h | 10 +- 3 files changed, 233 insertions(+), 228 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index c466cf952a96..f8be1679e7e4 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -79,9 +79,6 @@ class SelectionDAG { MachineModuleInfo *MMI; DwarfWriter *DW; - /// CurDebugLoc - current file + line number. Changes as we build the DAG. - DebugLoc CurDebugLoc; - /// EntryNode - The starting token. SDNode EntryNode; @@ -140,7 +137,6 @@ public: FunctionLoweringInfo &getFunctionLoweringInfo() const { return FLI; } MachineModuleInfo *getMachineModuleInfo() const { return MMI; } DwarfWriter *getDwarfWriter() const { return DW; } - DebugLoc getCurDebugLoc() const { return CurDebugLoc; } /// viewGraph - Pop up a GraphViz/gv window with the DAG rendered using 'dot'. /// @@ -199,8 +195,6 @@ public: return Root = N; } - void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; } - /// Combine - This iterates over the nodes in the SelectionDAG, folding /// certain types of nodes together, or eliminating superfluous nodes. The /// Level argument controls whether Combine is allowed to produce nodes and diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 3f3ce0d5b409..024cb4b92f4e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -216,14 +216,14 @@ namespace llvm { /// this value and returns the result as a ValueVTs value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. /// If the Flag pointer is NULL, no flag is used. - SDValue getCopyFromRegs(SelectionDAG &DAG, + SDValue getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, SDValue &Chain, SDValue *Flag) const; /// getCopyToRegs - Emit a series of CopyToReg nodes that copies the /// specified value into the registers specified by this object. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. /// If the Flag pointer is NULL, no flag is used. - void getCopyToRegs(SDValue Val, SelectionDAG &DAG, + void getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, SDValue &Chain, SDValue *Flag) const; /// AddInlineAsmOperands - Add this value to the specified inlineasm node @@ -374,7 +374,8 @@ unsigned FunctionLoweringInfo::CreateRegForValue(const Value *V) { /// larger then ValueVT then AssertOp can be used to specify whether the extra /// bits are known to be zero (ISD::AssertZext) or sign extended from ValueVT /// (ISD::AssertSext). -static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, +static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, + const SDValue *Parts, unsigned NumParts, MVT PartVT, MVT ValueVT, ISD::NodeType AssertOp = ISD::DELETED_NODE) { assert(NumParts > 0 && "No parts to assemble!"); @@ -400,36 +401,35 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, MVT::getFloatingPointVT(RoundBits/2); if (RoundParts > 2) { - Lo = getCopyFromParts(DAG, Parts, RoundParts/2, PartVT, HalfVT); - Hi = getCopyFromParts(DAG, Parts+RoundParts/2, RoundParts/2, + Lo = getCopyFromParts(DAG, dl, Parts, RoundParts/2, PartVT, HalfVT); + Hi = getCopyFromParts(DAG, dl, Parts+RoundParts/2, RoundParts/2, PartVT, HalfVT); } else { - Lo = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), - HalfVT, Parts[0]); - Hi = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), - HalfVT, Parts[1]); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[0]); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HalfVT, Parts[1]); } if (TLI.isBigEndian()) std::swap(Lo, Hi); - Val = DAG.getNode(ISD::BUILD_PAIR, DAG.getCurDebugLoc(), RoundVT, Lo, Hi); + Val = DAG.getNode(ISD::BUILD_PAIR, dl, RoundVT, Lo, Hi); if (RoundParts < NumParts) { // Assemble the trailing non-power-of-2 part. unsigned OddParts = NumParts - RoundParts; MVT OddVT = MVT::getIntegerVT(OddParts * PartBits); - Hi = getCopyFromParts(DAG, Parts+RoundParts, OddParts, PartVT, OddVT); + Hi = getCopyFromParts(DAG, dl, + Parts+RoundParts, OddParts, PartVT, OddVT); // Combine the round and odd parts. Lo = Val; if (TLI.isBigEndian()) std::swap(Lo, Hi); MVT TotalVT = MVT::getIntegerVT(NumParts * PartBits); - Hi = DAG.getNode(ISD::ANY_EXTEND, DAG.getCurDebugLoc(), TotalVT, Hi); - Hi = DAG.getNode(ISD::SHL, DAG.getCurDebugLoc(), TotalVT, Hi, + Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi); + Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi, DAG.getConstant(Lo.getValueType().getSizeInBits(), TLI.getShiftAmountTy())); - Lo = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), TotalVT, Lo); - Val = DAG.getNode(ISD::OR, DAG.getCurDebugLoc(), TotalVT, Lo, Hi); + Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo); + Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi); } } else { // Handle a multi-element vector. @@ -450,7 +450,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, // If the register was not expanded, truncate or copy the value, // as appropriate. for (unsigned i = 0; i != NumParts; ++i) - Ops[i] = getCopyFromParts(DAG, &Parts[i], 1, + Ops[i] = getCopyFromParts(DAG, dl, &Parts[i], 1, PartVT, IntermediateVT); } else if (NumParts > 0) { // If the intermediate type was expanded, build the intermediate operands @@ -459,15 +459,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, "Must expand into a divisible number of parts!"); unsigned Factor = NumParts / NumIntermediates; for (unsigned i = 0; i != NumIntermediates; ++i) - Ops[i] = getCopyFromParts(DAG, &Parts[i * Factor], Factor, + Ops[i] = getCopyFromParts(DAG, dl, &Parts[i * Factor], Factor, PartVT, IntermediateVT); } // Build a vector with BUILD_VECTOR or CONCAT_VECTORS from the intermediate // operands. Val = DAG.getNode(IntermediateVT.isVector() ? - ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, - DAG.getCurDebugLoc(), + ISD::CONCAT_VECTORS : ISD::BUILD_VECTOR, dl, ValueVT, &Ops[0], NumIntermediates); } } @@ -480,14 +479,14 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, if (PartVT.isVector()) { assert(ValueVT.isVector() && "Unknown vector conversion!"); - return DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), ValueVT, Val); + return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); } if (ValueVT.isVector()) { assert(ValueVT.getVectorElementType() == PartVT && ValueVT.getVectorNumElements() == 1 && "Only trivial scalar-to-vector conversions should get here!"); - return DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), ValueVT, Val); + return DAG.getNode(ISD::BUILD_VECTOR, dl, ValueVT, Val); } if (PartVT.isInteger() && @@ -497,24 +496,24 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, // indicate whether the truncated bits will always be // zero or sign-extension. if (AssertOp != ISD::DELETED_NODE) - Val = DAG.getNode(AssertOp, DAG.getCurDebugLoc(), PartVT, Val, + Val = DAG.getNode(AssertOp, dl, PartVT, Val, DAG.getValueType(ValueVT)); - return DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ValueVT, Val); + return DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); } else { - return DAG.getNode(ISD::ANY_EXTEND, DAG.getCurDebugLoc(), ValueVT, Val); + return DAG.getNode(ISD::ANY_EXTEND, dl, ValueVT, Val); } } if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) { if (ValueVT.bitsLT(Val.getValueType())) // FP_ROUND's are always exact here. - return DAG.getNode(ISD::FP_ROUND, DAG.getCurDebugLoc(), ValueVT, Val, + return DAG.getNode(ISD::FP_ROUND, dl, ValueVT, Val, DAG.getIntPtrConstant(1)); - return DAG.getNode(ISD::FP_EXTEND, DAG.getCurDebugLoc(), ValueVT, Val); + return DAG.getNode(ISD::FP_EXTEND, dl, ValueVT, Val); } if (PartVT.getSizeInBits() == ValueVT.getSizeInBits()) - return DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), ValueVT, Val); + return DAG.getNode(ISD::BIT_CONVERT, dl, ValueVT, Val); assert(0 && "Unknown mismatch!"); return SDValue(); @@ -523,7 +522,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, const SDValue *Parts, /// getCopyToParts - Create a series of nodes that contain the specified value /// split into legal parts. If the parts contain more bits than Val, then, for /// integers, ExtendKind can be used to specify how to generate the extra bits. -static void getCopyToParts(SelectionDAG &DAG, SDValue Val, +static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, SDValue Val, SDValue *Parts, unsigned NumParts, MVT PartVT, ISD::NodeType ExtendKind = ISD::ANY_EXTEND) { const TargetLowering &TLI = DAG.getTargetLoweringInfo(); @@ -546,22 +545,22 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, // If the parts cover more bits than the value has, promote the value. if (PartVT.isFloatingPoint() && ValueVT.isFloatingPoint()) { assert(NumParts == 1 && "Do not know what to promote to!"); - Val = DAG.getNode(ISD::FP_EXTEND, DAG.getCurDebugLoc(), PartVT, Val); + Val = DAG.getNode(ISD::FP_EXTEND, dl, PartVT, Val); } else if (PartVT.isInteger() && ValueVT.isInteger()) { ValueVT = MVT::getIntegerVT(NumParts * PartBits); - Val = DAG.getNode(ExtendKind, DAG.getCurDebugLoc(), ValueVT, Val); + Val = DAG.getNode(ExtendKind, dl, ValueVT, Val); } else { assert(0 && "Unknown mismatch!"); } } else if (PartBits == ValueVT.getSizeInBits()) { // Different types of the same size. assert(NumParts == 1 && PartVT != ValueVT); - Val = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), PartVT, Val); + Val = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Val); } else if (NumParts * PartBits < ValueVT.getSizeInBits()) { // If the parts cover less bits than value has, truncate the value. if (PartVT.isInteger() && ValueVT.isInteger()) { ValueVT = MVT::getIntegerVT(NumParts * PartBits); - Val = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ValueVT, Val); + Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); } else { assert(0 && "Unknown mismatch!"); } @@ -586,21 +585,21 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, unsigned RoundParts = 1 << Log2_32(NumParts); unsigned RoundBits = RoundParts * PartBits; unsigned OddParts = NumParts - RoundParts; - SDValue OddVal = DAG.getNode(ISD::SRL, DAG.getCurDebugLoc(), ValueVT, Val, + SDValue OddVal = DAG.getNode(ISD::SRL, dl, ValueVT, Val, DAG.getConstant(RoundBits, TLI.getShiftAmountTy())); - getCopyToParts(DAG, OddVal, Parts + RoundParts, OddParts, PartVT); + getCopyToParts(DAG, dl, OddVal, Parts + RoundParts, OddParts, PartVT); if (TLI.isBigEndian()) // The odd parts were reversed by getCopyToParts - unreverse them. std::reverse(Parts + RoundParts, Parts + NumParts); NumParts = RoundParts; ValueVT = MVT::getIntegerVT(NumParts * PartBits); - Val = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ValueVT, Val); + Val = DAG.getNode(ISD::TRUNCATE, dl, ValueVT, Val); } // The number of parts is a power of 2. Repeatedly bisect the value using // EXTRACT_ELEMENT. - Parts[0] = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + Parts[0] = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::getIntegerVT(ValueVT.getSizeInBits()), Val); for (unsigned StepSize = NumParts; StepSize > 1; StepSize /= 2) { @@ -610,17 +609,17 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, SDValue &Part0 = Parts[i]; SDValue &Part1 = Parts[i+StepSize/2]; - Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, DAG.getCurDebugLoc(), + Part1 = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, ThisVT, Part0, DAG.getConstant(1, PtrVT)); - Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, DAG.getCurDebugLoc(), + Part0 = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, ThisVT, Part0, DAG.getConstant(0, PtrVT)); if (ThisBits == PartBits && ThisVT != PartVT) { - Part0 = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + Part0 = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Part0); - Part1 = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + Part1 = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Part1); } } @@ -636,12 +635,12 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, if (NumParts == 1) { if (PartVT != ValueVT) { if (PartVT.isVector()) { - Val = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), PartVT, Val); + Val = DAG.getNode(ISD::BIT_CONVERT, dl, PartVT, Val); } else { assert(ValueVT.getVectorElementType() == PartVT && ValueVT.getVectorNumElements() == 1 && "Only trivial vector-to-scalar conversions should get here!"); - Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), + Val = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, PartVT, Val, DAG.getConstant(0, PtrVT)); } @@ -667,12 +666,12 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, SmallVector Ops(NumIntermediates); for (unsigned i = 0; i != NumIntermediates; ++i) if (IntermediateVT.isVector()) - Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DAG.getCurDebugLoc(), + Ops[i] = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, IntermediateVT, Val, DAG.getConstant(i * (NumElements / NumIntermediates), PtrVT)); else - Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), + Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, IntermediateVT, Val, DAG.getConstant(i, PtrVT)); @@ -681,7 +680,7 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, // If the register was not expanded, promote or copy the value, // as appropriate. for (unsigned i = 0; i != NumParts; ++i) - getCopyToParts(DAG, Ops[i], &Parts[i], 1, PartVT); + getCopyToParts(DAG, dl, Ops[i], &Parts[i], 1, PartVT); } else if (NumParts > 0) { // If the intermediate type was expanded, split each the value into // legal parts. @@ -689,7 +688,7 @@ static void getCopyToParts(SelectionDAG &DAG, SDValue Val, "Must expand into a divisible number of parts!"); unsigned Factor = NumParts / NumIntermediates; for (unsigned i = 0; i != NumIntermediates; ++i) - getCopyToParts(DAG, Ops[i], &Parts[i * Factor], Factor, PartVT); + getCopyToParts(DAG, dl, Ops[i], &Parts[i * Factor], Factor, PartVT); } } @@ -730,7 +729,7 @@ SDValue SelectionDAGLowering::getRoot() { } // Otherwise, we have to make a token factor node. - SDValue Root = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), MVT::Other, + SDValue Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &PendingLoads[0], PendingLoads.size()); PendingLoads.clear(); DAG.setRoot(Root); @@ -760,7 +759,7 @@ SDValue SelectionDAGLowering::getControlRoot() { PendingExports.push_back(Root); } - Root = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), MVT::Other, + Root = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &PendingExports[0], PendingExports.size()); PendingExports.clear(); @@ -820,7 +819,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) { if (isa(C) && !isa(V->getType()) && !V->getType()->isAggregateType()) - return N = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), VT); + return N = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), VT); if (ConstantExpr *CE = dyn_cast(C)) { visit(CE->getOpcode(), *CE); @@ -853,7 +852,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) { for (unsigned i = 0; i != NumElts; ++i) { MVT EltVT = ValueVTs[i]; if (isa(C)) - Constants[i] = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), EltVT); + Constants[i] = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), EltVT); else if (EltVT.isFloatingPoint()) Constants[i] = DAG.getConstantFP(0, EltVT); else @@ -878,7 +877,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) { SDValue Op; if (isa(C)) - Op = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), EltVT); + Op = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), EltVT); else if (EltVT.isFloatingPoint()) Op = DAG.getConstantFP(0, EltVT); else @@ -887,7 +886,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) { } // Create a BUILD_VECTOR node. - return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), + return NodeMap[V] = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), VT, &Ops[0], Ops.size()); } @@ -905,13 +904,13 @@ SDValue SelectionDAGLowering::getValue(const Value *V) { RegsForValue RFV(TLI, InReg, V->getType()); SDValue Chain = DAG.getEntryNode(); - return RFV.getCopyFromRegs(DAG, Chain, NULL); + return RFV.getCopyFromRegs(DAG, getCurDebugLoc(), Chain, NULL); } void SelectionDAGLowering::visitRet(ReturnInst &I) { if (I.getNumOperands() == 0) { - DAG.setRoot(DAG.getNode(ISD::RET, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::RET, getCurDebugLoc(), MVT::Other, getControlRoot())); return; } @@ -948,7 +947,8 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) { else if (F->paramHasAttr(0, Attribute::ZExt)) ExtendKind = ISD::ZERO_EXTEND; - getCopyToParts(DAG, SDValue(RetOp.getNode(), RetOp.getResNo() + j), + getCopyToParts(DAG, getCurDebugLoc(), + SDValue(RetOp.getNode(), RetOp.getResNo() + j), &Parts[0], NumParts, PartVT, ExtendKind); // 'inreg' on function refers to return value @@ -961,7 +961,7 @@ void SelectionDAGLowering::visitRet(ReturnInst &I) { } } } - DAG.setRoot(DAG.getNode(ISD::RET, DAG.getCurDebugLoc(), MVT::Other, + DAG.setRoot(DAG.getNode(ISD::RET, getCurDebugLoc(), MVT::Other, &NewValues[0], NewValues.size())); } @@ -1201,7 +1201,7 @@ void SelectionDAGLowering::visitBr(BranchInst &I) { // If this is not a fall-through branch, emit the branch. if (Succ0MBB != NextBlock) - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, getControlRoot(), DAG.getBasicBlock(Succ0MBB))); return; @@ -1281,7 +1281,7 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) { Cond = CondLHS; else if (CB.CmpRHS == ConstantInt::getFalse() && CB.CC == ISD::SETEQ) { SDValue True = DAG.getConstant(1, CondLHS.getValueType()); - Cond = DAG.getNode(ISD::XOR, DAG.getCurDebugLoc(), + Cond = DAG.getNode(ISD::XOR, getCurDebugLoc(), CondLHS.getValueType(), CondLHS, True); } else Cond = DAG.getSetCC(MVT::i1, CondLHS, getValue(CB.CmpRHS), CB.CC); @@ -1297,7 +1297,7 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) { if (cast(CB.CmpLHS)->isMinValue(true)) { Cond = DAG.getSetCC(MVT::i1, CmpOp, DAG.getConstant(High, VT), ISD::SETLE); } else { - SDValue SUB = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), + SDValue SUB = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, CmpOp, DAG.getConstant(Low, VT)); Cond = DAG.getSetCC(MVT::i1, SUB, DAG.getConstant(High-Low, VT), ISD::SETULE); @@ -1320,10 +1320,10 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) { if (CB.TrueBB == NextBlock) { std::swap(CB.TrueBB, CB.FalseBB); SDValue True = DAG.getConstant(1, Cond.getValueType()); - Cond = DAG.getNode(ISD::XOR, DAG.getCurDebugLoc(), + Cond = DAG.getNode(ISD::XOR, getCurDebugLoc(), Cond.getValueType(), Cond, True); } - SDValue BrCond = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(), + SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), MVT::Other, getControlRoot(), Cond, DAG.getBasicBlock(CB.TrueBB)); @@ -1339,7 +1339,7 @@ void SelectionDAGLowering::visitSwitchCase(CaseBlock &CB) { if (CB.FalseBB == NextBlock) DAG.setRoot(BrCond); else - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, BrCond, + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond, DAG.getBasicBlock(CB.FalseBB))); } } @@ -1351,7 +1351,7 @@ void SelectionDAGLowering::visitJumpTable(JumpTable &JT) { MVT PTy = TLI.getPointerTy(); SDValue Index = DAG.getCopyFromReg(getControlRoot(), JT.Reg, PTy); SDValue Table = DAG.getJumpTable(JT.JTI, PTy); - DAG.setRoot(DAG.getNode(ISD::BR_JT, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::BR_JT, getCurDebugLoc(), MVT::Other, Index.getValue(1), Table, Index)); } @@ -1365,7 +1365,7 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT, // difference between smallest and largest cases. SDValue SwitchOp = getValue(JTH.SValue); MVT VT = SwitchOp.getValueType(); - SDValue SUB = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), VT, SwitchOp, + SDValue SUB = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp, DAG.getConstant(JTH.First, VT)); // The SDNode we just created, which holds the value being switched on minus @@ -1374,10 +1374,10 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT, // This value may be smaller or larger than the target's pointer type, and // therefore require extension or truncating. if (VT.bitsGT(TLI.getPointerTy())) - SwitchOp = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), + SwitchOp = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), TLI.getPointerTy(), SUB); else - SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), + SwitchOp = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), TLI.getPointerTy(), SUB); unsigned JumpTableReg = FuncInfo.MakeReg(TLI.getPointerTy()); @@ -1398,14 +1398,14 @@ void SelectionDAGLowering::visitJumpTableHeader(JumpTable &JT, if (++BBI != CurMBB->getParent()->end()) NextBlock = BBI; - SDValue BrCond = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(), + SDValue BrCond = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), MVT::Other, CopyTo, CMP, DAG.getBasicBlock(JT.Default)); if (JT.MBB == NextBlock) DAG.setRoot(BrCond); else - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, BrCond, + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrCond, DAG.getBasicBlock(JT.MBB))); } @@ -1415,7 +1415,7 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { // Subtract the minimum value SDValue SwitchOp = getValue(B.SValue); MVT VT = SwitchOp.getValueType(); - SDValue SUB = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), VT, SwitchOp, + SDValue SUB = DAG.getNode(ISD::SUB, getCurDebugLoc(), VT, SwitchOp, DAG.getConstant(B.First, VT)); // Check range @@ -1425,10 +1425,10 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { SDValue ShiftOp; if (VT.bitsGT(TLI.getShiftAmountTy())) - ShiftOp = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), + ShiftOp = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), TLI.getShiftAmountTy(), SUB); else - ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), + ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), TLI.getShiftAmountTy(), SUB); B.Reg = FuncInfo.MakeReg(TLI.getShiftAmountTy()); @@ -1446,14 +1446,14 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { CurMBB->addSuccessor(B.Default); CurMBB->addSuccessor(MBB); - SDValue BrRange = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(), + SDValue BrRange = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), MVT::Other, CopyTo, RangeCmp, DAG.getBasicBlock(B.Default)); if (MBB == NextBlock) DAG.setRoot(BrRange); else - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, CopyTo, + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, CopyTo, DAG.getBasicBlock(MBB))); } @@ -1464,13 +1464,13 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, // Make desired shift SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), Reg, TLI.getShiftAmountTy()); - SDValue SwitchVal = DAG.getNode(ISD::SHL, DAG.getCurDebugLoc(), + SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), TLI.getPointerTy(), DAG.getConstant(1, TLI.getPointerTy()), ShiftOp); // Emit bit tests and jumps - SDValue AndOp = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), + SDValue AndOp = DAG.getNode(ISD::AND, getCurDebugLoc(), TLI.getPointerTy(), SwitchVal, DAG.getConstant(B.Mask, TLI.getPointerTy())); SDValue AndCmp = DAG.getSetCC(TLI.getSetCCResultType(AndOp.getValueType()), @@ -1480,7 +1480,7 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, CurMBB->addSuccessor(B.TargetBB); CurMBB->addSuccessor(NextMBB); - SDValue BrAnd = DAG.getNode(ISD::BRCOND, DAG.getCurDebugLoc(), + SDValue BrAnd = DAG.getNode(ISD::BRCOND, getCurDebugLoc(), MVT::Other, getControlRoot(), AndCmp, DAG.getBasicBlock(B.TargetBB)); @@ -1494,7 +1494,7 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, if (NextMBB == NextBlock) DAG.setRoot(BrAnd); else - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), MVT::Other, BrAnd, + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, BrAnd, DAG.getBasicBlock(NextMBB))); } @@ -1522,7 +1522,7 @@ void SelectionDAGLowering::visitInvoke(InvokeInst &I) { CurMBB->addSuccessor(LandingPad); // Drop into normal successor. - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, getControlRoot(), DAG.getBasicBlock(Return))); } @@ -2026,7 +2026,7 @@ void SelectionDAGLowering::visitSwitch(SwitchInst &SI) { // If this is not a fall-through branch, emit the branch. CurMBB->addSuccessor(Default); if (Default != NextBlock) - DAG.setRoot(DAG.getNode(ISD::BR, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::BR, getCurDebugLoc(), MVT::Other, getControlRoot(), DAG.getBasicBlock(Default))); return; @@ -2089,7 +2089,7 @@ void SelectionDAGLowering::visitSub(User &I) { Constant *CNZ = ConstantVector::get(&NZ[0], NZ.size()); if (CV == CNZ) { SDValue Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FNEG, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), Op2.getValueType(), Op2)); return; } @@ -2100,7 +2100,7 @@ void SelectionDAGLowering::visitSub(User &I) { if (ConstantFP *CFP = dyn_cast(I.getOperand(0))) if (CFP->isExactlyValue(ConstantFP::getNegativeZero(Ty)->getValueAPF())) { SDValue Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FNEG, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FNEG, getCurDebugLoc(), Op2.getValueType(), Op2)); return; } @@ -2113,7 +2113,7 @@ void SelectionDAGLowering::visitBinary(User &I, unsigned OpCode) { SDValue Op1 = getValue(I.getOperand(0)); SDValue Op2 = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(OpCode, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(OpCode, getCurDebugLoc(), Op1.getValueType(), Op1, Op2)); } @@ -2122,14 +2122,14 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) { SDValue Op2 = getValue(I.getOperand(1)); if (!isa(I.getType())) { if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType())) - Op2 = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), + Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), TLI.getShiftAmountTy(), Op2); else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType())) - Op2 = DAG.getNode(ISD::ANY_EXTEND, DAG.getCurDebugLoc(), + Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(), TLI.getShiftAmountTy(), Op2); } - setValue(&I, DAG.getNode(Opcode, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(), Op1.getValueType(), Op1, Op2)); } @@ -2194,12 +2194,12 @@ void SelectionDAGLowering::visitSelect(User &I) { SDValue FalseVal = getValue(I.getOperand(2)); for (unsigned i = 0; i != NumValues; ++i) - Values[i] = DAG.getNode(ISD::SELECT, DAG.getCurDebugLoc(), + Values[i] = DAG.getNode(ISD::SELECT, getCurDebugLoc(), TrueVal.getValueType(), Cond, SDValue(TrueVal.getNode(), TrueVal.getResNo() + i), SDValue(FalseVal.getNode(), FalseVal.getResNo() + i)); - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&ValueVTs[0], NumValues), &Values[0], NumValues)); } @@ -2210,7 +2210,7 @@ void SelectionDAGLowering::visitTrunc(User &I) { // TruncInst cannot be a no-op cast because sizeof(src) > sizeof(dest). SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitZExt(User &I) { @@ -2218,7 +2218,7 @@ void SelectionDAGLowering::visitZExt(User &I) { // ZExt also can't be a cast to bool for same reason. So, nothing much to do SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitSExt(User &I) { @@ -2226,14 +2226,14 @@ void SelectionDAGLowering::visitSExt(User &I) { // SExt also can't be a cast to bool for same reason. So, nothing much to do SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitFPTrunc(User &I) { // FPTrunc is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_ROUND, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FP_ROUND, getCurDebugLoc(), DestVT, N, DAG.getIntPtrConstant(0))); } @@ -2241,35 +2241,35 @@ void SelectionDAGLowering::visitFPExt(User &I){ // FPTrunc is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_EXTEND, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::FP_EXTEND, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitFPToUI(User &I) { // FPToUI is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_TO_UINT, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::FP_TO_UINT, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitFPToSI(User &I) { // FPToSI is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::FP_TO_SINT, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::FP_TO_SINT, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitUIToFP(User &I) { // UIToFP is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::UINT_TO_FP, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::UINT_TO_FP, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitSIToFP(User &I){ // SIToFP is never a no-op cast, no need to check SDValue N = getValue(I.getOperand(0)); MVT DestVT = TLI.getValueType(I.getType()); - setValue(&I, DAG.getNode(ISD::SINT_TO_FP, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::SINT_TO_FP, getCurDebugLoc(), DestVT, N)); } void SelectionDAGLowering::visitPtrToInt(User &I) { @@ -2280,10 +2280,10 @@ void SelectionDAGLowering::visitPtrToInt(User &I) { MVT DestVT = TLI.getValueType(I.getType()); SDValue Result; if (DestVT.bitsLT(SrcVT)) - Result = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), DestVT, N); + Result = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N); else // Note: ZERO_EXTEND can handle cases where the sizes are equal too - Result = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), DestVT, N); + Result = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N); setValue(&I, Result); } @@ -2294,10 +2294,10 @@ void SelectionDAGLowering::visitIntToPtr(User &I) { MVT SrcVT = N.getValueType(); MVT DestVT = TLI.getValueType(I.getType()); if (DestVT.bitsLT(SrcVT)) - setValue(&I, DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), DestVT, N)); + setValue(&I, DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), DestVT, N)); else // Note: ZERO_EXTEND can handle cases where the sizes are equal too - setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), DestVT, N)); } @@ -2308,7 +2308,7 @@ void SelectionDAGLowering::visitBitCast(User &I) { // BitCast assures us that source and destination are the same size so this // is either a BIT_CONVERT or a no-op. if (DestVT != N.getValueType()) - setValue(&I, DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), DestVT, N)); // convert types else setValue(&I, N); // noop cast. @@ -2317,21 +2317,21 @@ void SelectionDAGLowering::visitBitCast(User &I) { void SelectionDAGLowering::visitInsertElement(User &I) { SDValue InVec = getValue(I.getOperand(0)); SDValue InVal = getValue(I.getOperand(1)); - SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), + SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), TLI.getPointerTy(), getValue(I.getOperand(2))); - setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::INSERT_VECTOR_ELT, getCurDebugLoc(), TLI.getValueType(I.getType()), InVec, InVal, InIdx)); } void SelectionDAGLowering::visitExtractElement(User &I) { SDValue InVec = getValue(I.getOperand(0)); - SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), + SDValue InIdx = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), TLI.getPointerTy(), getValue(I.getOperand(1))); - setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), TLI.getValueType(I.getType()), InVec, InIdx)); } @@ -2361,7 +2361,7 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { int SrcNumElts = SrcVT.getVectorNumElements(); if (SrcNumElts == MaskNumElts) { - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(), VT, Src1, Src2, Mask)); return; } @@ -2375,14 +2375,14 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { // lengths match. if (SrcNumElts*2 == MaskNumElts && SequentialMask(Mask, 0)) { // The shuffle is concatenating two vectors together. - setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), VT, Src1, Src2)); return; } // Pad both vectors with undefs to make them the same length as the mask. unsigned NumConcat = MaskNumElts / SrcNumElts; - SDValue UndefVal = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), SrcVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), SrcVT); SDValue* MOps1 = new SDValue[NumConcat]; SDValue* MOps2 = new SDValue[NumConcat]; @@ -2392,9 +2392,9 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { MOps1[i] = UndefVal; MOps2[i] = UndefVal; } - Src1 = DAG.getNode(ISD::CONCAT_VECTORS, DAG.getCurDebugLoc(), + Src1 = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), VT, MOps1, NumConcat); - Src2 = DAG.getNode(ISD::CONCAT_VECTORS, DAG.getCurDebugLoc(), + Src2 = DAG.getNode(ISD::CONCAT_VECTORS, getCurDebugLoc(), VT, MOps2, NumConcat); delete [] MOps1; @@ -2414,11 +2414,11 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { MaskEltVT)); } } - Mask = DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), + Mask = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), Mask.getValueType(), &MappedOps[0], MappedOps.size()); - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(), VT, Src1, Src2, Mask)); return; } @@ -2485,7 +2485,7 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { if (RangeUse[0] == 0 && RangeUse[0] == 0) { setValue(&I, DAG.getNode(ISD::UNDEF, - DAG.getCurDebugLoc(), VT)); // Vectors are not used. + getCurDebugLoc(), VT)); // Vectors are not used. return; } else if (RangeUse[0] < 2 && RangeUse[1] < 2) { @@ -2493,9 +2493,9 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { for (int Input=0; Input < 2; ++Input) { SDValue& Src = Input == 0 ? Src1 : Src2; if (RangeUse[Input] == 0) { - Src = DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), VT); + Src = DAG.getNode(ISD::UNDEF, getCurDebugLoc(), VT); } else { - Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, DAG.getCurDebugLoc(), VT, + Src = DAG.getNode(ISD::EXTRACT_SUBVECTOR, getCurDebugLoc(), VT, Src, DAG.getIntPtrConstant(StartIdx[Input])); } } @@ -2515,10 +2515,10 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { } } } - Mask = DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), + Mask = DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), Mask.getValueType(), &MappedOps[0], MappedOps.size()); - setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::VECTOR_SHUFFLE, getCurDebugLoc(), VT, Src1, Src2, Mask)); return; } @@ -2533,20 +2533,20 @@ void SelectionDAGLowering::visitShuffleVector(User &I) { for (int i = 0; i != MaskNumElts; ++i) { SDValue Arg = Mask.getOperand(i); if (Arg.getOpcode() == ISD::UNDEF) { - Ops.push_back(DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), EltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, getCurDebugLoc(), EltVT)); } else { assert(isa(Arg) && "Invalid VECTOR_SHUFFLE mask!"); int Idx = cast(Arg)->getZExtValue(); if (Idx < SrcNumElts) - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), EltVT, Src1, DAG.getConstant(Idx, PtrVT))); else - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, DAG.getCurDebugLoc(), + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, getCurDebugLoc(), EltVT, Src2, DAG.getConstant(Idx - SrcNumElts, PtrVT))); } } - setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::BUILD_VECTOR, getCurDebugLoc(), VT, &Ops[0], Ops.size())); } @@ -2575,21 +2575,21 @@ void SelectionDAGLowering::visitInsertValue(InsertValueInst &I) { unsigned i = 0; // Copy the beginning value(s) from the original aggregate. for (; i != LinearIndex; ++i) - Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), + Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, getCurDebugLoc(), AggValueVTs[i]) : SDValue(Agg.getNode(), Agg.getResNo() + i); // Copy values from the inserted value(s). for (; i != LinearIndex + NumValValues; ++i) - Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), + Values[i] = FromUndef ? DAG.getNode(ISD::UNDEF, getCurDebugLoc(), AggValueVTs[i]) : SDValue(Val.getNode(), Val.getResNo() + i - LinearIndex); // Copy remaining value(s) from the original aggregate. for (; i != NumAggValues; ++i) - Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), + Values[i] = IntoUndef ? DAG.getNode(ISD::UNDEF, getCurDebugLoc(), AggValueVTs[i]) : SDValue(Agg.getNode(), Agg.getResNo() + i); - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&AggValueVTs[0], NumAggValues), &Values[0], NumAggValues)); } @@ -2614,11 +2614,11 @@ void SelectionDAGLowering::visitExtractValue(ExtractValueInst &I) { for (unsigned i = LinearIndex; i != LinearIndex + NumValValues; ++i) Values[i - LinearIndex] = OutOfUndef ? - DAG.getNode(ISD::UNDEF, DAG.getCurDebugLoc(), + DAG.getNode(ISD::UNDEF, getCurDebugLoc(), Agg.getNode()->getValueType(Agg.getResNo() + i)) : SDValue(Agg.getNode(), Agg.getResNo() + i); - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&ValValueVTs[0], NumValValues), &Values[0], NumValValues)); } @@ -2636,7 +2636,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { if (Field) { // N = N + Offset uint64_t Offset = TD->getStructLayout(StTy)->getElementOffset(Field); - N = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), N.getValueType(), N, + N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, DAG.getIntPtrConstant(Offset)); } Ty = StTy->getElementType(Field); @@ -2648,7 +2648,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { if (CI->getZExtValue() == 0) continue; uint64_t Offs = TD->getTypePaddedSize(Ty)*cast(CI)->getSExtValue(); - N = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), N.getValueType(), N, + N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, DAG.getIntPtrConstant(Offs)); continue; } @@ -2660,10 +2660,10 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { // If the index is smaller or larger than intptr_t, truncate or extend // it. if (IdxN.getValueType().bitsLT(N.getValueType())) - IdxN = DAG.getNode(ISD::SIGN_EXTEND, DAG.getCurDebugLoc(), + IdxN = DAG.getNode(ISD::SIGN_EXTEND, getCurDebugLoc(), N.getValueType(), IdxN); else if (IdxN.getValueType().bitsGT(N.getValueType())) - IdxN = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), + IdxN = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), N.getValueType(), IdxN); // If this is a multiply by a power of two, turn it into a shl @@ -2671,17 +2671,17 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { if (ElementSize != 1) { if (isPowerOf2_64(ElementSize)) { unsigned Amt = Log2_64(ElementSize); - IdxN = DAG.getNode(ISD::SHL, DAG.getCurDebugLoc(), + IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(), N.getValueType(), IdxN, DAG.getConstant(Amt, TLI.getShiftAmountTy())); } else { SDValue Scale = DAG.getIntPtrConstant(ElementSize); - IdxN = DAG.getNode(ISD::MUL, DAG.getCurDebugLoc(), + IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(), N.getValueType(), IdxN, Scale); } } - N = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), + N = DAG.getNode(ISD::ADD, getCurDebugLoc(), N.getValueType(), N, IdxN); } } @@ -2703,13 +2703,13 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { SDValue AllocSize = getValue(I.getArraySize()); MVT IntPtr = TLI.getPointerTy(); if (IntPtr.bitsLT(AllocSize.getValueType())) - AllocSize = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), + AllocSize = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), IntPtr, AllocSize); else if (IntPtr.bitsGT(AllocSize.getValueType())) - AllocSize = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), + AllocSize = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), IntPtr, AllocSize); - AllocSize = DAG.getNode(ISD::MUL, DAG.getCurDebugLoc(), IntPtr, AllocSize, + AllocSize = DAG.getNode(ISD::MUL, getCurDebugLoc(), IntPtr, AllocSize, DAG.getIntPtrConstant(TySize)); // Handle alignment. If the requested alignment is less than or equal to @@ -2722,18 +2722,18 @@ void SelectionDAGLowering::visitAlloca(AllocaInst &I) { // Round the size of the allocation up to the stack alignment size // by add SA-1 to the size. - AllocSize = DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), + AllocSize = DAG.getNode(ISD::ADD, getCurDebugLoc(), AllocSize.getValueType(), AllocSize, DAG.getIntPtrConstant(StackAlign-1)); // Mask out the low bits for alignment purposes. - AllocSize = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), + AllocSize = DAG.getNode(ISD::AND, getCurDebugLoc(), AllocSize.getValueType(), AllocSize, DAG.getIntPtrConstant(~(uint64_t)(StackAlign-1))); SDValue Ops[] = { getRoot(), AllocSize, DAG.getIntPtrConstant(Align) }; const MVT *VTs = DAG.getNodeValueTypes(AllocSize.getValueType(), MVT::Other); - SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, DAG.getCurDebugLoc(), + SDValue DSA = DAG.getNode(ISD::DYNAMIC_STACKALLOC, getCurDebugLoc(), VTs, 2, Ops, 3); setValue(&I, DSA); DAG.setRoot(DSA.getValue(1)); @@ -2776,8 +2776,8 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { SmallVector Chains(NumValues); MVT PtrVT = Ptr.getValueType(); for (unsigned i = 0; i != NumValues; ++i) { - SDValue L = DAG.getLoad(ValueVTs[i], DAG.getCurDebugLoc(), Root, - DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), + SDValue L = DAG.getLoad(ValueVTs[i], getCurDebugLoc(), Root, + DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, Ptr, DAG.getConstant(Offsets[i], PtrVT)), SV, Offsets[i], @@ -2787,7 +2787,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { } if (!ConstantMemory) { - SDValue Chain = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), + SDValue Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &Chains[0], NumValues); if (isVolatile) @@ -2796,7 +2796,7 @@ void SelectionDAGLowering::visitLoad(LoadInst &I) { PendingLoads.push_back(Chain); } - setValue(&I, DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::MERGE_VALUES, getCurDebugLoc(), DAG.getVTList(&ValueVTs[0], NumValues), &Values[0], NumValues)); } @@ -2825,15 +2825,15 @@ void SelectionDAGLowering::visitStore(StoreInst &I) { bool isVolatile = I.isVolatile(); unsigned Alignment = I.getAlignment(); for (unsigned i = 0; i != NumValues; ++i) - Chains[i] = DAG.getStore(Root, DAG.getCurDebugLoc(), + Chains[i] = DAG.getStore(Root, getCurDebugLoc(), SDValue(Src.getNode(), Src.getResNo() + i), - DAG.getNode(ISD::ADD, DAG.getCurDebugLoc(), + DAG.getNode(ISD::ADD, getCurDebugLoc(), PtrVT, Ptr, DAG.getConstant(Offsets[i], PtrVT)), PtrV, Offsets[i], isVolatile, Alignment); - DAG.setRoot(DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &Chains[0], NumValues)); } @@ -2894,7 +2894,7 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, SDValue Result; if (IsTgtIntrinsic) { // This is target intrinsic that touches memory - Result = DAG.getMemIntrinsicNode(Info.opc, DAG.getCurDebugLoc(), + Result = DAG.getMemIntrinsicNode(Info.opc, getCurDebugLoc(), VTList, VTs.size(), &Ops[0], Ops.size(), Info.memVT, Info.ptrVal, Info.offset, @@ -2902,15 +2902,15 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, Info.readMem, Info.writeMem); } else if (!HasChain) - Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, DAG.getCurDebugLoc(), + Result = DAG.getNode(ISD::INTRINSIC_WO_CHAIN, getCurDebugLoc(), VTList, VTs.size(), &Ops[0], Ops.size()); else if (I.getType() != Type::VoidTy) - Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, DAG.getCurDebugLoc(), + Result = DAG.getNode(ISD::INTRINSIC_W_CHAIN, getCurDebugLoc(), VTList, VTs.size(), &Ops[0], Ops.size()); else - Result = DAG.getNode(ISD::INTRINSIC_VOID, DAG.getCurDebugLoc(), + Result = DAG.getNode(ISD::INTRINSIC_VOID, getCurDebugLoc(), VTList, VTs.size(), &Ops[0], Ops.size()); @@ -2924,7 +2924,7 @@ void SelectionDAGLowering::visitTargetIntrinsic(CallInst &I, if (I.getType() != Type::VoidTy) { if (const VectorType *PTy = dyn_cast(I.getType())) { MVT VT = TLI.getValueType(PTy); - Result = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), VT, Result); + Result = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), VT, Result); } setValue(&I, Result); } @@ -3004,12 +3004,12 @@ void AddCatchInfo(CallInst &I, MachineModuleInfo *MMI, /// /// where Op is the hexidecimal representation of floating point value. static SDValue -GetSignificand(SelectionDAG &DAG, SDValue Op) { - SDValue t1 = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), MVT::i32, Op, +GetSignificand(SelectionDAG &DAG, SDValue Op, DebugLoc dl) { + SDValue t1 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, DAG.getConstant(0x007fffff, MVT::i32)); - SDValue t2 = DAG.getNode(ISD::OR, DAG.getCurDebugLoc(), MVT::i32, t1, + SDValue t2 = DAG.getNode(ISD::OR, dl, MVT::i32, t1, DAG.getConstant(0x3f800000, MVT::i32)); - return DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), MVT::f32, t2); + return DAG.getNode(ISD::BIT_CONVERT, dl, MVT::f32, t2); } /// GetExponent - Get the exponent: @@ -3018,14 +3018,15 @@ GetSignificand(SelectionDAG &DAG, SDValue Op) { /// /// where Op is the hexidecimal representation of floating point value. static SDValue -GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI) { - SDValue t0 = DAG.getNode(ISD::AND, DAG.getCurDebugLoc(), MVT::i32, Op, +GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI, + DebugLoc dl) { + SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, DAG.getConstant(0x7f800000, MVT::i32)); - SDValue t1 = DAG.getNode(ISD::SRL, DAG.getCurDebugLoc(), MVT::i32, t0, + SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0, DAG.getConstant(23, TLI.getShiftAmountTy())); - SDValue t2 = DAG.getNode(ISD::SUB, DAG.getCurDebugLoc(), MVT::i32, t1, + SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1, DAG.getConstant(127, MVT::i32)); - return DAG.getNode(ISD::SINT_TO_FP, MVT::f32, t2); + return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2); } /// getF32Constant - Get 32-bit floating point constant. @@ -3041,7 +3042,7 @@ const char * SelectionDAGLowering::implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op) { SDValue Root = getRoot(); SDValue L = - DAG.getAtomic(Op, DAG.getCurDebugLoc(), + DAG.getAtomic(Op, getCurDebugLoc(), getValue(I.getOperand(2)).getValueType().getSimpleVT(), Root, getValue(I.getOperand(1)), @@ -3061,7 +3062,7 @@ SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) { MVT ValueVTs[] = { Op1.getValueType(), MVT::i1 }; SDValue Ops[] = { Op1, Op2 }; - SDValue Result = DAG.getNode(Op, DAG.getCurDebugLoc(), + SDValue Result = DAG.getNode(Op, getCurDebugLoc(), DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); setValue(&I, Result); @@ -3073,7 +3074,7 @@ SelectionDAGLowering::implVisitAluOverflow(CallInst &I, ISD::NodeType Op) { void SelectionDAGLowering::visitExp(CallInst &I) { SDValue result; - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { @@ -3199,7 +3200,7 @@ SelectionDAGLowering::visitExp(CallInst &I) { void SelectionDAGLowering::visitLog(CallInst &I) { SDValue result; - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { @@ -3207,13 +3208,13 @@ SelectionDAGLowering::visitLog(CallInst &I) { SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); // Scale the exponent by log(2) [0.69314718f]. - SDValue Exp = GetExponent(DAG, Op1, TLI); + SDValue Exp = GetExponent(DAG, Op1, TLI, dl); SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp, getF32Constant(DAG, 0x3f317218)); // Get the significand and build it into a floating-point number with // exponent of 1. - SDValue X = GetSignificand(DAG, Op1); + SDValue X = GetSignificand(DAG, Op1, dl); if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: @@ -3309,7 +3310,7 @@ SelectionDAGLowering::visitLog(CallInst &I) { void SelectionDAGLowering::visitLog2(CallInst &I) { SDValue result; - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { @@ -3317,11 +3318,11 @@ SelectionDAGLowering::visitLog2(CallInst &I) { SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); // Get the exponent. - SDValue LogOfExponent = GetExponent(DAG, Op1, TLI); + SDValue LogOfExponent = GetExponent(DAG, Op1, TLI, dl); // Get the significand and build it into a floating-point number with // exponent of 1. - SDValue X = GetSignificand(DAG, Op1); + SDValue X = GetSignificand(DAG, Op1, dl); // Different possible minimax approximations of significand in // floating-point for various degrees of accuracy over [1,2]. @@ -3418,7 +3419,7 @@ SelectionDAGLowering::visitLog2(CallInst &I) { void SelectionDAGLowering::visitLog10(CallInst &I) { SDValue result; - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { @@ -3426,13 +3427,13 @@ SelectionDAGLowering::visitLog10(CallInst &I) { SDValue Op1 = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::i32, Op); // Scale the exponent by log10(2) [0.30102999f]. - SDValue Exp = GetExponent(DAG, Op1, TLI); + SDValue Exp = GetExponent(DAG, Op1, TLI, dl); SDValue LogOfExponent = DAG.getNode(ISD::FMUL, dl, MVT::f32, Exp, getF32Constant(DAG, 0x3e9a209a)); // Get the significand and build it into a floating-point number with // exponent of 1. - SDValue X = GetSignificand(DAG, Op1); + SDValue X = GetSignificand(DAG, Op1, dl); if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: @@ -3520,7 +3521,7 @@ SelectionDAGLowering::visitLog10(CallInst &I) { void SelectionDAGLowering::visitExp2(CallInst &I) { SDValue result; - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); if (getValue(I.getOperand(1)).getValueType() == MVT::f32 && LimitFloatPrecision > 0 && LimitFloatPrecision <= 18) { @@ -3635,7 +3636,7 @@ void SelectionDAGLowering::visitPow(CallInst &I) { SDValue result; Value *Val = I.getOperand(1); - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); bool IsExp10 = false; if (getValue(Val).getValueType() == MVT::f32 && @@ -3768,7 +3769,7 @@ SelectionDAGLowering::visitPow(CallInst &I) { /// otherwise lower it and return null. const char * SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { - DebugLoc dl = DAG.getCurDebugLoc(); + DebugLoc dl = getCurDebugLoc(); switch (Intrinsic) { default: // By default, turn this into a target intrinsic node. @@ -3845,7 +3846,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { getOrCreateDebugLocID(SrcFile, SPI.getLine(), SPI.getColumn()); - DAG.setCurDebugLoc(DebugLoc::get(idx)); + setCurDebugLoc(DebugLoc::get(idx)); } return 0; } @@ -3891,7 +3892,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DW->RecordSourceLine(Line, 0, SrcFile); if (DW->getRecordSourceLineCount() != 1) DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID)); - DAG.setCurDebugLoc(DebugLoc::get(DAG.getMachineFunction(). + setCurDebugLoc(DebugLoc::get(DAG.getMachineFunction(). getOrCreateDebugLocID(SrcFile, Line, 0))); } @@ -4171,7 +4172,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { SDValue FIN = DAG.getFrameIndex(FI, PtrTy); // Store the stack protector onto the stack. - SDValue Result = DAG.getStore(getRoot(), DAG.getCurDebugLoc(), Src, FIN, + SDValue Result = DAG.getStore(getRoot(), getCurDebugLoc(), Src, FIN, PseudoSourceValue::getFixedStack(FI), 0, true); setValue(&I, Result); @@ -4263,7 +4264,7 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { case Intrinsic::atomic_cmp_swap: { SDValue Root = getRoot(); SDValue L = - DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, DAG.getCurDebugLoc(), + DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, getCurDebugLoc(), getValue(I.getOperand(2)).getValueType().getSimpleVT(), Root, getValue(I.getOperand(1)), @@ -4344,7 +4345,7 @@ void SelectionDAGLowering::LowerCallTo(CallSite CS, SDValue Callee, CS.paramHasAttr(0, Attribute::InReg), CS.getCallingConv(), IsTailCall && PerformTailCallOpt, - Callee, Args, DAG, DAG.getCurDebugLoc()); + Callee, Args, DAG, getCurDebugLoc()); if (CS.getType() != Type::VoidTy) setValue(CS.getInstruction(), Result.first); DAG.setRoot(Result.second); @@ -4386,7 +4387,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { I.getType() == I.getOperand(2)->getType()) { SDValue LHS = getValue(I.getOperand(1)); SDValue RHS = getValue(I.getOperand(2)); - setValue(&I, DAG.getNode(ISD::FCOPYSIGN, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FCOPYSIGN, getCurDebugLoc(), LHS.getValueType(), LHS, RHS)); return; } @@ -4398,7 +4399,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FABS, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FABS, getCurDebugLoc(), Tmp.getValueType(), Tmp)); return; } @@ -4410,7 +4411,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FSIN, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FSIN, getCurDebugLoc(), Tmp.getValueType(), Tmp)); return; } @@ -4422,7 +4423,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { I.getOperand(1)->getType()->isFloatingPoint() && I.getType() == I.getOperand(1)->getType()) { SDValue Tmp = getValue(I.getOperand(1)); - setValue(&I, DAG.getNode(ISD::FCOS, DAG.getCurDebugLoc(), + setValue(&I, DAG.getNode(ISD::FCOS, getCurDebugLoc(), Tmp.getValueType(), Tmp)); return; } @@ -4447,7 +4448,7 @@ void SelectionDAGLowering::visitCall(CallInst &I) { /// this value and returns the result as a ValueVT value. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. /// If the Flag pointer is NULL, no flag is used. -SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, +SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, DebugLoc dl, SDValue &Chain, SDValue *Flag) const { // Assemble the legal parts into the final values. @@ -4505,8 +4506,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, isSExt = false, FromVT = MVT::i32; // ASSERT ZEXT 32 if (FromVT != MVT::Other) { - P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, - DAG.getCurDebugLoc(), + P = DAG.getNode(isSExt ? ISD::AssertSext : ISD::AssertZext, dl, RegisterVT, P, DAG.getValueType(FromVT)); } @@ -4516,13 +4516,13 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, Parts[i] = P; } - Values[Value] = getCopyFromParts(DAG, Parts.begin(), NumRegs, RegisterVT, - ValueVT); + Values[Value] = getCopyFromParts(DAG, dl, Parts.begin(), + NumRegs, RegisterVT, ValueVT); Part += NumRegs; Parts.clear(); } - return DAG.getNode(ISD::MERGE_VALUES, DAG.getCurDebugLoc(), + return DAG.getNode(ISD::MERGE_VALUES, dl, DAG.getVTList(&ValueVTs[0], ValueVTs.size()), &Values[0], ValueVTs.size()); } @@ -4531,7 +4531,7 @@ SDValue RegsForValue::getCopyFromRegs(SelectionDAG &DAG, /// specified value into the registers specified by this object. This uses /// Chain/Flag as the input and updates them for the output Chain/Flag. /// If the Flag pointer is NULL, no flag is used. -void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, +void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, DebugLoc dl, SDValue &Chain, SDValue *Flag) const { // Get the list of the values's legal parts. unsigned NumRegs = Regs.size(); @@ -4541,7 +4541,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, unsigned NumParts = TLI->getNumRegisters(ValueVT); MVT RegisterVT = RegVTs[Value]; - getCopyToParts(DAG, Val.getValue(Val.getResNo() + Value), + getCopyToParts(DAG, dl, Val.getValue(Val.getResNo() + Value), &Parts[Part], NumParts, RegisterVT); Part += NumParts; } @@ -4572,8 +4572,7 @@ void RegsForValue::getCopyToRegs(SDValue Val, SelectionDAG &DAG, // = op c3, ..., f2 Chain = Chains[NumRegs-1]; else - Chain = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), - MVT::Other, &Chains[0], NumRegs); + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Chains[0], NumRegs); } /// AddInlineAsmOperands - Add this value to the specified inlineasm node @@ -4785,7 +4784,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo, // vector types). MVT RegVT = *PhysReg.second->vt_begin(); if (RegVT.getSizeInBits() == OpInfo.ConstraintVT.getSizeInBits()) { - OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), RegVT, OpInfo.CallOperand); OpInfo.ConstraintVT = RegVT; } else if (RegVT.isInteger() && OpInfo.ConstraintVT.isFloatingPoint()) { @@ -4794,7 +4793,7 @@ GetRegistersForValue(SDISelAsmOperandInfo &OpInfo, // into i64, which can be passed with two i32 values on a 32-bit // machine. RegVT = MVT::getIntegerVT(OpInfo.ConstraintVT.getSizeInBits()); - OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + OpInfo.CallOperand = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), RegVT, OpInfo.CallOperand); OpInfo.ConstraintVT = RegVT; } @@ -5060,7 +5059,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { MachineFunction &MF = DAG.getMachineFunction(); int SSFI = MF.getFrameInfo()->CreateStackObject(TySize, Align); SDValue StackSlot = DAG.getFrameIndex(SSFI, TLI.getPointerTy()); - Chain = DAG.getStore(Chain, DAG.getCurDebugLoc(), + Chain = DAG.getStore(Chain, getCurDebugLoc(), OpInfo.CallOperand, StackSlot, NULL, 0); OpInfo.CallOperand = StackSlot; } @@ -5190,7 +5189,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { } // Use the produced MatchedRegs object to - MatchedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag); + MatchedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(), + Chain, &Flag); MatchedRegs.AddInlineAsmOperands(1 /*REGUSE*/, DAG, AsmNodeOperands); break; } else { @@ -5249,7 +5249,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { exit(1); } - OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, Chain, &Flag); + OpInfo.AssignedRegs.getCopyToRegs(InOperandVal, DAG, getCurDebugLoc(), + Chain, &Flag); OpInfo.AssignedRegs.AddInlineAsmOperands(1/*REGUSE*/, DAG, AsmNodeOperands); @@ -5270,7 +5271,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { AsmNodeOperands[0] = Chain; if (Flag.getNode()) AsmNodeOperands.push_back(Flag); - Chain = DAG.getNode(ISD::INLINEASM, DAG.getCurDebugLoc(), + Chain = DAG.getNode(ISD::INLINEASM, getCurDebugLoc(), DAG.getNodeValueTypes(MVT::Other, MVT::Flag), 2, &AsmNodeOperands[0], AsmNodeOperands.size()); Flag = Chain.getValue(1); @@ -5278,7 +5279,8 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // If this asm returns a register value, copy the result from that register // and set it as the value of the call. if (!RetValRegs.Regs.empty()) { - SDValue Val = RetValRegs.getCopyFromRegs(DAG, Chain, &Flag); + SDValue Val = RetValRegs.getCopyFromRegs(DAG, getCurDebugLoc(), + Chain, &Flag); // FIXME: Why don't we do this for inline asms with MRVs? if (CS.getType()->isSingleValueType() && CS.getType()->isSized()) { @@ -5290,7 +5292,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // not have the same VT as was expected. Convert it to the right type // with bit_convert. if (ResultType != Val.getValueType() && Val.getValueType().isVector()) { - Val = DAG.getNode(ISD::BIT_CONVERT, DAG.getCurDebugLoc(), + Val = DAG.getNode(ISD::BIT_CONVERT, getCurDebugLoc(), ResultType, Val); } else if (ResultType != Val.getValueType() && @@ -5298,7 +5300,7 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { // If a result value was tied to an input value, the computed result may // have a wider width than the expected result. Extract the relevant // portion. - Val = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), ResultType, Val); + Val = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), ResultType, Val); } assert(ResultType == Val.getValueType() && "Asm result value mismatch!"); @@ -5314,19 +5316,20 @@ void SelectionDAGLowering::visitInlineAsm(CallSite CS) { for (unsigned i = 0, e = IndirectStoresToEmit.size(); i != e; ++i) { RegsForValue &OutRegs = IndirectStoresToEmit[i].first; Value *Ptr = IndirectStoresToEmit[i].second; - SDValue OutVal = OutRegs.getCopyFromRegs(DAG, Chain, &Flag); + SDValue OutVal = OutRegs.getCopyFromRegs(DAG, getCurDebugLoc(), + Chain, &Flag); StoresToEmit.push_back(std::make_pair(OutVal, Ptr)); } // Emit the non-flagged stores from the physregs. SmallVector OutChains; for (unsigned i = 0, e = StoresToEmit.size(); i != e; ++i) - OutChains.push_back(DAG.getStore(Chain, DAG.getCurDebugLoc(), + OutChains.push_back(DAG.getStore(Chain, getCurDebugLoc(), StoresToEmit[i].first, getValue(StoresToEmit[i].second), StoresToEmit[i].second, 0)); if (!OutChains.empty()) - Chain = DAG.getNode(ISD::TokenFactor, DAG.getCurDebugLoc(), MVT::Other, + Chain = DAG.getNode(ISD::TokenFactor, getCurDebugLoc(), MVT::Other, &OutChains[0], OutChains.size()); DAG.setRoot(Chain); } @@ -5338,13 +5341,13 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) { MVT IntPtr = TLI.getPointerTy(); if (IntPtr.bitsLT(Src.getValueType())) - Src = DAG.getNode(ISD::TRUNCATE, DAG.getCurDebugLoc(), IntPtr, Src); + Src = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), IntPtr, Src); else if (IntPtr.bitsGT(Src.getValueType())) - Src = DAG.getNode(ISD::ZERO_EXTEND, DAG.getCurDebugLoc(), IntPtr, Src); + Src = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), IntPtr, Src); // Scale the source by the type size. uint64_t ElementSize = TD->getTypePaddedSize(I.getType()->getElementType()); - Src = DAG.getNode(ISD::MUL, DAG.getCurDebugLoc(), Src.getValueType(), + Src = DAG.getNode(ISD::MUL, getCurDebugLoc(), Src.getValueType(), Src, DAG.getIntPtrConstant(ElementSize)); TargetLowering::ArgListTy Args; @@ -5357,7 +5360,7 @@ void SelectionDAGLowering::visitMalloc(MallocInst &I) { TLI.LowerCallTo(getRoot(), I.getType(), false, false, false, false, CallingConv::C, PerformTailCallOpt, DAG.getExternalSymbol("malloc", IntPtr), - Args, DAG, DAG.getCurDebugLoc()); + Args, DAG, getCurDebugLoc()); setValue(&I, Result.first); // Pointers always fit in registers DAG.setRoot(Result.second); } @@ -5373,12 +5376,12 @@ void SelectionDAGLowering::visitFree(FreeInst &I) { TLI.LowerCallTo(getRoot(), Type::VoidTy, false, false, false, false, CallingConv::C, PerformTailCallOpt, DAG.getExternalSymbol("free", IntPtr), Args, DAG, - DAG.getCurDebugLoc()); + getCurDebugLoc()); DAG.setRoot(Result.second); } void SelectionDAGLowering::visitVAStart(CallInst &I) { - DAG.setRoot(DAG.getNode(ISD::VASTART, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::VASTART, getCurDebugLoc(), MVT::Other, getRoot(), getValue(I.getOperand(1)), DAG.getSrcValue(I.getOperand(1)))); @@ -5393,14 +5396,14 @@ void SelectionDAGLowering::visitVAArg(VAArgInst &I) { } void SelectionDAGLowering::visitVAEnd(CallInst &I) { - DAG.setRoot(DAG.getNode(ISD::VAEND, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::VAEND, getCurDebugLoc(), MVT::Other, getRoot(), getValue(I.getOperand(1)), DAG.getSrcValue(I.getOperand(1)))); } void SelectionDAGLowering::visitVACopy(CallInst &I) { - DAG.setRoot(DAG.getNode(ISD::VACOPY, DAG.getCurDebugLoc(), + DAG.setRoot(DAG.getNode(ISD::VACOPY, getCurDebugLoc(), MVT::Other, getRoot(), getValue(I.getOperand(1)), getValue(I.getOperand(2)), @@ -5529,8 +5532,8 @@ void TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG, else if (F.paramHasAttr(Idx, Attribute::ZExt)) AssertOp = ISD::AssertZext; - ArgValues.push_back(getCopyFromParts(DAG, &Parts[0], NumParts, PartVT, VT, - AssertOp)); + ArgValues.push_back(getCopyFromParts(DAG, dl, &Parts[0], NumParts, + PartVT, VT, AssertOp)); } } assert(i == NumArgRegs && "Argument register count mismatch!"); @@ -5604,7 +5607,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, else if (Args[i].isZExt) ExtendKind = ISD::ZERO_EXTEND; - getCopyToParts(DAG, Op, &Parts[0], NumParts, PartVT, ExtendKind); + getCopyToParts(DAG, dl, Op, &Parts[0], NumParts, PartVT, ExtendKind); for (unsigned i = 0; i != NumParts; ++i) { // if it isn't first piece, alignment must be 1 @@ -5666,7 +5669,7 @@ TargetLowering::LowerCallTo(SDValue Chain, const Type *RetTy, for (; RegNo != RegNoEnd; ++RegNo) Results.push_back(Res.getValue(RegNo)); SDValue ReturnValue = - getCopyFromParts(DAG, &Results[0], NumRegs, RegisterVT, VT, + getCopyFromParts(DAG, dl, &Results[0], NumRegs, RegisterVT, VT, AssertOp); ReturnValues.push_back(ReturnValue); } @@ -5702,7 +5705,7 @@ void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, unsigned Reg) { RegsForValue RFV(TLI, Reg, V->getType()); SDValue Chain = DAG.getEntryNode(); - RFV.getCopyToRegs(Op, DAG, Chain, 0); + RFV.getCopyToRegs(Op, DAG, getCurDebugLoc(), Chain, 0); PendingExports.push_back(Chain); } @@ -5714,7 +5717,7 @@ LowerArguments(BasicBlock *LLVMBB) { Function &F = *LLVMBB->getParent(); SDValue OldRoot = SDL->DAG.getRoot(); SmallVector Args; - TLI.LowerArguments(F, SDL->DAG, Args, SDL->DAG.getCurDebugLoc()); + TLI.LowerArguments(F, SDL->DAG, Args, SDL->getCurDebugLoc()); unsigned a = 0; for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end(); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h index 4d450cb60dbd..397f7b1a249d 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h @@ -164,6 +164,9 @@ public: class SelectionDAGLowering { MachineBasicBlock *CurMBB; + /// CurDebugLoc - current file + line number. Changes as we build the DAG. + DebugLoc CurDebugLoc; + DenseMap NodeMap; /// PendingLoads - Loads are not emitted to the program immediately. We bunch @@ -356,7 +359,8 @@ public: SelectionDAGLowering(SelectionDAG &dag, TargetLowering &tli, FunctionLoweringInfo &funcinfo) - : TLI(tli), DAG(dag), FuncInfo(funcinfo) { + : CurDebugLoc(DebugLoc::getUnknownLoc()), + TLI(tli), DAG(dag), FuncInfo(funcinfo) { } void init(GCFunctionInfo *gfi, AliasAnalysis &aa); @@ -382,6 +386,8 @@ public: /// SDValue getControlRoot(); + DebugLoc getCurDebugLoc() const { return CurDebugLoc; } + void CopyValueToVirtualRegister(Value *V, unsigned Reg); void visit(Instruction &I); @@ -531,6 +537,8 @@ private: const char *implVisitBinaryAtomic(CallInst& I, ISD::NodeType Op); const char *implVisitAluOverflow(CallInst &I, ISD::NodeType Op); + + void setCurDebugLoc(DebugLoc dl) { CurDebugLoc = dl; } }; /// AddCatchInfo - Extract the personality and type infos from an eh.selector -- GitLab From ec99c46d44f9bee7e7e9fba6e0b4b19ce4f076ca Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 02:28:54 +0000 Subject: [PATCH 566/682] Simplify and generalize the SROA "convert to scalar" transformation to be able to handle *ANY* alloca that is poked by loads and stores of bitcasts and GEPs with constant offsets. Before the code had a number of annoying limitations and caused it to miss cases such as storing into holes in structs and complex casts (as in bitfield-sroa) where we had unions of bitfields etc. This also handles a number of important cases that are exposed due to the ABI lowering stuff we do to pass stuff by value. One case that is pretty great is that we compile 2006-11-07-InvalidArrayPromote.ll into: define i32 @func(<4 x float> %v0, <4 x float> %v1) nounwind { %tmp10 = call <4 x i32> @llvm.x86.sse2.cvttps2dq(<4 x float> %v1) %tmp105 = bitcast <4 x i32> %tmp10 to i128 %tmp1056 = zext i128 %tmp105 to i256 %tmp.upgrd.43 = lshr i256 %tmp1056, 96 %tmp.upgrd.44 = trunc i256 %tmp.upgrd.43 to i32 ret i32 %tmp.upgrd.44 } which turns into: _func: subl $28, %esp cvttps2dq %xmm1, %xmm0 movaps %xmm0, (%esp) movl 12(%esp), %eax addl $28, %esp ret Which is pretty good code all things considering :). One effect of this is that SROA will start generating arbitrary bitwidth integers that are a multiple of 8 bits. In the case above, we got a 256 bit integer, but the codegen guys assure me that it can handle the simple and/or/shift/zext stuff that we're doing on these operations. This addresses rdar://6532315 llvm-svn: 63469 --- .../Scalar/ScalarReplAggregates.cpp | 491 +++++++----------- .../ScalarRepl/2003-05-29-ArrayFail.ll | 7 +- .../2006-11-07-InvalidArrayPromote.ll | 5 +- llvm/test/Transforms/ScalarRepl/badarray.ll | 2 +- .../Transforms/ScalarRepl/bitfield-sroa.ll | 16 + 5 files changed, 196 insertions(+), 325 deletions(-) create mode 100644 llvm/test/Transforms/ScalarRepl/bitfield-sroa.ll diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 589aa35d9c60..10d2e00911d3 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -125,13 +125,14 @@ namespace { void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocationInst *AI, SmallVector &NewElts); - const Type *CanConvertToScalar(Value *V, bool &IsNotTrivial); + bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&ResTy, + uint64_t Offset); void ConvertToScalar(AllocationInst *AI, const Type *Ty); - void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset); + void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset); Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, - unsigned Offset); + uint64_t Offset); Value *ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, - unsigned Offset); + uint64_t Offset); static Instruction *isOnlyCopiedFromConstantGlobal(AllocationInst *AI); }; } @@ -271,9 +272,15 @@ bool SROA::performScalarRepl(Function &F) { // If we can turn this aggregate value (potentially with casts) into a // simple scalar value that can be mem2reg'd into a register value. + // IsNotTrivial tracks whether this is something that mem2reg could have + // promoted itself. If so, we don't want to transform it needlessly. Note + // that we can't just check based on the type: the alloca may be of an i32 + // but that has pointer arithmetic to set byte 3 of it or something. bool IsNotTrivial = false; - if (const Type *ActualType = CanConvertToScalar(AI, IsNotTrivial)) - if (IsNotTrivial && ActualType != Type::VoidTy) { + const Type *ActualType = 0; + if (CanConvertToScalar(AI, IsNotTrivial, ActualType, 0)) + if (IsNotTrivial && ActualType && + TD->getTypeSizeInBits(ActualType) < SRThreshold*8) { ConvertToScalar(AI, ActualType); Changed = true; continue; @@ -1145,229 +1152,124 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) { } } -/// MergeInType - Add the 'In' type to the accumulated type so far. If the -/// types are incompatible, return true, otherwise update Accum and return -/// false. +/// MergeInType - Add the 'In' type to the accumulated type (Accum) so far at +/// the offset specified by Offset (which is specified in bytes). /// -/// There are three cases we handle here: -/// 1) An effectively-integer union, where the pieces are stored into as -/// smaller integers (common with byte swap and other idioms). -/// 2) A union of vector types of the same size and potentially its elements. +/// There are two cases we handle here: +/// 1) A union of vector types of the same size and potentially its elements. /// Here we turn element accesses into insert/extract element operations. -/// 3) A union of scalar types, such as int/float or int/pointer. Here we -/// merge together into integers, allowing the xform to work with #1 as -/// well. -static bool MergeInType(const Type *In, const Type *&Accum, +/// This promotes a <4 x float> with a store of float to the third element +/// into a <4 x float> that uses insert element. +/// 2) A fully general blob of memory, which we turn into some (potentially +/// large) integer type with extract and insert operations where the loads +/// and stores would mutate the memory. +static void MergeInType(const Type *In, uint64_t Offset, const Type *&Accum, const TargetData &TD) { // If this is our first type, just use it. - const VectorType *PTy; - if (Accum == Type::VoidTy || In == Accum) { + if (Accum == 0 || In == Type::VoidTy || + // Or if this is a same type, keep it. + (In == Accum && Offset == 0)) { Accum = In; - } else if (In == Type::VoidTy) { - // Noop. - } else if (In->isInteger() && Accum->isInteger()) { // integer union. - // Otherwise pick whichever type is larger. - if (cast(In)->getBitWidth() > - cast(Accum)->getBitWidth()) - Accum = In; - } else if (isa(In) && isa(Accum)) { - // Pointer unions just stay as one of the pointers. - } else if (isa(In) || isa(Accum)) { - if ((PTy = dyn_cast(Accum)) && - PTy->getElementType() == In) { - // Accum is a vector, and we are accessing an element: ok. - } else if ((PTy = dyn_cast(In)) && - PTy->getElementType() == Accum) { - // In is a vector, and accum is an element: ok, remember In. - Accum = In; - } else if ((PTy = dyn_cast(In)) && isa(Accum) && - PTy->getBitWidth() == cast(Accum)->getBitWidth()) { - // Two vectors of the same size: keep Accum. - } else { - // Cannot insert an short into a <4 x int> or handle - // <2 x int> -> <4 x int> - return true; - } - } else { - // Pointer/FP/Integer unions merge together as integers. - switch (Accum->getTypeID()) { - case Type::PointerTyID: Accum = TD.getIntPtrType(); break; - case Type::FloatTyID: Accum = Type::Int32Ty; break; - case Type::DoubleTyID: Accum = Type::Int64Ty; break; - case Type::X86_FP80TyID: return true; - case Type::FP128TyID: return true; - case Type::PPC_FP128TyID: return true; - default: - assert(Accum->isInteger() && "Unknown FP type!"); - break; - } - - switch (In->getTypeID()) { - case Type::PointerTyID: In = TD.getIntPtrType(); break; - case Type::FloatTyID: In = Type::Int32Ty; break; - case Type::DoubleTyID: In = Type::Int64Ty; break; - case Type::X86_FP80TyID: return true; - case Type::FP128TyID: return true; - case Type::PPC_FP128TyID: return true; - default: - assert(In->isInteger() && "Unknown FP type!"); - break; - } - return MergeInType(In, Accum, TD); + return; + } + + if (const VectorType *VATy = dyn_cast(Accum)) { + if (VATy->getElementType() == In && + Offset % TD.getTypePaddedSize(In) == 0 && + Offset < TD.getTypePaddedSize(VATy)) + return; // Accum is a vector, and we are accessing an element: ok. + if (const VectorType *VInTy = dyn_cast(In)) + if (VInTy->getBitWidth() == VATy->getBitWidth() && Offset == 0) + return; // Two vectors of the same size: keep either one of them. } - return false; -} -/// getIntAtLeastAsBigAs - Return an integer type that is at least as big as the -/// specified type. If there is no suitable type, this returns null. -const Type *getIntAtLeastAsBigAs(unsigned NumBits) { - if (NumBits > 64) return 0; - if (NumBits > 32) return Type::Int64Ty; - if (NumBits > 16) return Type::Int32Ty; - if (NumBits > 8) return Type::Int16Ty; - return Type::Int8Ty; + if (const VectorType *VInTy = dyn_cast(In)) { + // In is a vector, and we are accessing an element: keep V. + if (VInTy->getElementType() == Accum && + Offset % TD.getTypePaddedSize(Accum) == 0 && + Offset < TD.getTypePaddedSize(VInTy)) { + Accum = VInTy; + return; + } + } + + // Otherwise, we have a case that we can't handle with an optimized form. + // Convert the alloca to an integer that is as large as the largest store size + // of the value values. + uint64_t InSize = TD.getTypeStoreSizeInBits(In)+8*Offset; + uint64_t ASize = TD.getTypeStoreSizeInBits(Accum); + if (InSize > ASize) ASize = InSize; + Accum = IntegerType::get(ASize); } -/// CanConvertToScalar - V is a pointer. If we can convert the pointee to a -/// single scalar integer type, return that type. Further, if the use is not -/// a completely trivial use that mem2reg could promote, set IsNotTrivial. If -/// there are no uses of this pointer, return Type::VoidTy to differentiate from -/// failure. +/// CanConvertToScalar - V is a pointer. If we can convert the pointee and all +/// its accesses to use a to single scalar type, return true, and set ResTy to +/// the new type. Further, if the use is not a completely trivial use that +/// mem2reg could promote, set IsNotTrivial. Offset is the current offset from +/// the base of the alloca being analyzed. /// -const Type *SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial) { - const Type *UsedType = Type::VoidTy; // No uses, no forced type. - const PointerType *PTy = cast(V->getType()); - +bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, + const Type *&ResTy, uint64_t Offset) { for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) { Instruction *User = cast(*UI); if (LoadInst *LI = dyn_cast(User)) { + // Don't break volatile loads. if (LI->isVolatile()) - return 0; - - // FIXME: Loads of a first class aggregrate value could be converted to a - // series of loads and insertvalues - if (!LI->getType()->isSingleValueType()) - return 0; - - if (MergeInType(LI->getType(), UsedType, *TD)) - return 0; + return false; + MergeInType(LI->getType(), Offset, ResTy, *TD); continue; } if (StoreInst *SI = dyn_cast(User)) { // Storing the pointer, not into the value? if (SI->getOperand(0) == V || SI->isVolatile()) return 0; - - // FIXME: Stores of a first class aggregrate value could be converted to a - // series of extractvalues and stores - if (!SI->getOperand(0)->getType()->isSingleValueType()) - return 0; - - // NOTE: We could handle storing of FP imms into integers here! - - if (MergeInType(SI->getOperand(0)->getType(), UsedType, *TD)) - return 0; + MergeInType(SI->getOperand(0)->getType(), Offset, ResTy, *TD); continue; } - if (BitCastInst *CI = dyn_cast(User)) { + + if (BitCastInst *BCI = dyn_cast(User)) { + if (!CanConvertToScalar(BCI, IsNotTrivial, ResTy, Offset)) + return false; IsNotTrivial = true; - const Type *SubTy = CanConvertToScalar(CI, IsNotTrivial); - if (!SubTy || MergeInType(SubTy, UsedType, *TD)) return 0; continue; } if (GetElementPtrInst *GEP = dyn_cast(User)) { - // Check to see if this is stepping over an element: GEP Ptr, int C - if (GEP->getNumOperands() == 2 && isa(GEP->getOperand(1))) { - unsigned Idx = cast(GEP->getOperand(1))->getZExtValue(); - unsigned ElSize = TD->getTypePaddedSize(PTy->getElementType()); - unsigned BitOffset = Idx*ElSize*8; - if (BitOffset > 64 || !isPowerOf2_32(ElSize)) return 0; - - IsNotTrivial = true; - const Type *SubElt = CanConvertToScalar(GEP, IsNotTrivial); - if (SubElt == 0) return 0; - if (SubElt != Type::VoidTy && SubElt->isInteger()) { - const Type *NewTy = - getIntAtLeastAsBigAs(TD->getTypePaddedSizeInBits(SubElt)+BitOffset); - if (NewTy == 0 || MergeInType(NewTy, UsedType, *TD)) return 0; - continue; - } - // Cannot handle this! - return 0; - } + // If this is a GEP with a variable indices, we can't handle it. + if (!GEP->hasAllConstantIndices()) + return false; - if (GEP->getNumOperands() == 3 && - isa(GEP->getOperand(1)) && - isa(GEP->getOperand(2)) && - cast(GEP->getOperand(1))->isZero()) { - // We are stepping into an element, e.g. a structure or an array: - // GEP Ptr, i32 0, i32 Cst - const Type *AggTy = PTy->getElementType(); - unsigned Idx = cast(GEP->getOperand(2))->getZExtValue(); - - if (const ArrayType *ATy = dyn_cast(AggTy)) { - if (Idx >= ATy->getNumElements()) return 0; // Out of range. - } else if (const VectorType *VectorTy = dyn_cast(AggTy)) { - // Getting an element of the vector. - if (Idx >= VectorTy->getNumElements()) return 0; // Out of range. - - // Merge in the vector type. - if (MergeInType(VectorTy, UsedType, *TD)) return 0; - - const Type *SubTy = CanConvertToScalar(GEP, IsNotTrivial); - if (SubTy == 0) return 0; - - if (SubTy != Type::VoidTy && MergeInType(SubTy, UsedType, *TD)) - return 0; - - // We'll need to change this to an insert/extract element operation. - IsNotTrivial = true; - continue; // Everything looks ok - - } else if (isa(AggTy)) { - // Structs are always ok. - } else { - return 0; - } - const Type *NTy = - getIntAtLeastAsBigAs(TD->getTypePaddedSizeInBits(AggTy)); - if (NTy == 0 || MergeInType(NTy, UsedType, *TD)) return 0; - const Type *SubTy = CanConvertToScalar(GEP, IsNotTrivial); - if (SubTy == 0) return 0; - if (SubTy != Type::VoidTy && MergeInType(SubTy, UsedType, *TD)) - return 0; - continue; // Everything looks ok - } - return 0; + // Compute the offset that this GEP adds to the pointer. + SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); + uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), + &Indices[0], Indices.size()); + // See if all uses can be converted. + if (!CanConvertToScalar(GEP, IsNotTrivial, ResTy, Offset+GEPOffset)) + return false; + IsNotTrivial = true; + continue; } - // Cannot handle this! - return 0; + // Otherwise, we cannot handle this! + return false; } - return UsedType; + return true; } /// ConvertToScalar - The specified alloca passes the CanConvertToScalar /// predicate and is non-trivial. Convert it to something that can be trivially /// promoted into a register by mem2reg. void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) { - DOUT << "CONVERT TO SCALAR: " << *AI << " TYPE = " - << *ActualTy << "\n"; + DOUT << "CONVERT TO SCALAR: " << *AI << " TYPE = " << *ActualTy << "\n"; ++NumConverted; - BasicBlock *EntryBlock = AI->getParent(); - assert(EntryBlock == &EntryBlock->getParent()->getEntryBlock() && - "Not in the entry block!"); - EntryBlock->getInstList().remove(AI); // Take the alloca out of the program. - // Create and insert the alloca. AllocaInst *NewAI = new AllocaInst(ActualTy, 0, AI->getName(), - EntryBlock->begin()); + AI->getParent()->begin()); ConvertUsesToScalar(AI, NewAI, 0); - delete AI; + AI->eraseFromParent(); } @@ -1378,22 +1280,19 @@ void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) { /// /// Offset is an offset from the original alloca, in bits that need to be /// shifted to the right. By the end of this, there should be no uses of Ptr. -void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { +void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { while (!Ptr->use_empty()) { Instruction *User = cast(Ptr->use_back()); if (LoadInst *LI = dyn_cast(User)) { - Value *NV = ConvertUsesOfLoadToScalar(LI, NewAI, Offset); - LI->replaceAllUsesWith(NV); + LI->replaceAllUsesWith(ConvertUsesOfLoadToScalar(LI, NewAI, Offset)); LI->eraseFromParent(); continue; } if (StoreInst *SI = dyn_cast(User)) { assert(SI->getOperand(0) != Ptr && "Consistency error!"); - - Value *SV = ConvertUsesOfStoreToScalar(SI, NewAI, Offset); - new StoreInst(SV, NewAI, SI); + new StoreInst(ConvertUsesOfStoreToScalar(SI, NewAI, Offset), NewAI, SI); SI->eraseFromParent(); continue; } @@ -1405,45 +1304,14 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { } if (GetElementPtrInst *GEP = dyn_cast(User)) { - const PointerType *AggPtrTy = - cast(GEP->getOperand(0)->getType()); - unsigned AggSizeInBits = - TD->getTypePaddedSizeInBits(AggPtrTy->getElementType()); - - // Check to see if this is stepping over an element: GEP Ptr, int C - unsigned NewOffset = Offset; - if (GEP->getNumOperands() == 2) { - unsigned Idx = cast(GEP->getOperand(1))->getZExtValue(); - unsigned BitOffset = Idx*AggSizeInBits; - - NewOffset += BitOffset; - ConvertUsesToScalar(GEP, NewAI, NewOffset); - GEP->eraseFromParent(); - continue; - } - - assert(GEP->getNumOperands() == 3 && "Unsupported operation"); - - // We know that operand #2 is zero. - unsigned Idx = cast(GEP->getOperand(2))->getZExtValue(); - const Type *AggTy = AggPtrTy->getElementType(); - if (const SequentialType *SeqTy = dyn_cast(AggTy)) { - unsigned ElSizeBits = - TD->getTypePaddedSizeInBits(SeqTy->getElementType()); - - NewOffset += ElSizeBits*Idx; - } else { - const StructType *STy = cast(AggTy); - unsigned EltBitOffset = - TD->getStructLayout(STy)->getElementOffsetInBits(Idx); - - NewOffset += EltBitOffset; - } - ConvertUsesToScalar(GEP, NewAI, NewOffset); + // Compute the offset that this GEP adds to the pointer. + SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); + uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), + &Indices[0], Indices.size()); + ConvertUsesToScalar(GEP, NewAI, Offset+GEPOffset*8); GEP->eraseFromParent(); continue; } - assert(0 && "Unsupported operation!"); abort(); } @@ -1455,28 +1323,20 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, unsigned Offset) { /// single integer scalar, or when we are converting a "vector union" to a /// vector with insert/extractelement instructions. /// -/// Offset is an offset from the original alloca, in bits that need to be +/// Offset is an offset from the original alloca, in bytes that need to be /// shifted to the right. By the end of this, there should be no uses of Ptr. Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, - unsigned Offset) { + uint64_t Offset) { // The load is a bit extract from NewAI shifted right by Offset bits. Value *NV = new LoadInst(NewAI, LI->getName(), LI); - if (NV->getType() == LI->getType() && Offset == 0) { - // We win, no conversion needed. + // If the load is of the whole new alloca, no conversion is needed. + if (NV->getType() == LI->getType() && Offset == 0) return NV; - } - // If the result type of the 'union' is a pointer, then this must be ptr->ptr - // cast. Anything else would result in NV being an integer. - if (isa(NV->getType())) { - assert(isa(LI->getType())); - return new BitCastInst(NV, LI->getType(), LI->getName(), LI); - } - + // If the result alloca is a vector type, this is either an element + // access or a bitcast to another vector type of the same size. if (const VectorType *VTy = dyn_cast(NV->getType())) { - // If the result alloca is a vector type, this is either an element - // access or a bitcast to another vector type. if (isa(LI->getType())) return new BitCastInst(NV, LI->getType(), LI->getName(), LI); @@ -1485,16 +1345,14 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, if (Offset) { unsigned EltSize = TD->getTypePaddedSizeInBits(VTy->getElementType()); Elt = Offset/EltSize; - Offset -= EltSize*Elt; + assert(EltSize*Elt == Offset && "Invalid modulus in validity checking"); } - NV = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt), - "tmp", LI); - - // If we're done, return this element. - if (NV->getType() == LI->getType() && Offset == 0) - return NV; + // Return the element extracted out of it. + return new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt), + "tmp", LI); } + // Otherwise, this must be a union that was converted to an integer value. const IntegerType *NTy = cast(NV->getType()); // If this is a big-endian system and the load is narrower than the @@ -1514,12 +1372,12 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, // We do this to support (f.e.) loads off the end of a structure where // only some bits are used. if (ShAmt > 0 && (unsigned)ShAmt < NTy->getBitWidth()) - NV = BinaryOperator::CreateLShr(NV, - ConstantInt::get(NV->getType(),ShAmt), + NV = BinaryOperator::CreateLShr(NV, + ConstantInt::get(NV->getType(), ShAmt), LI->getName(), LI); else if (ShAmt < 0 && (unsigned)-ShAmt < NTy->getBitWidth()) - NV = BinaryOperator::CreateShl(NV, - ConstantInt::get(NV->getType(),-ShAmt), + NV = BinaryOperator::CreateShl(NV, + ConstantInt::get(NV->getType(), -ShAmt), LI->getName(), LI); // Finally, unconditionally truncate the integer to the right width. @@ -1531,7 +1389,8 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, // If the result is an integer, this is a trunc or bitcast. if (isa(LI->getType())) { // Should be done. - } else if (LI->getType()->isFloatingPoint()) { + } else if (LI->getType()->isFloatingPoint() || + isa(LI->getType())) { // Just do a bitcast, we know the sizes match up. NV = new BitCastInst(NV, LI->getType(), LI->getName(), LI); } else { @@ -1552,15 +1411,17 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, /// Offset is an offset from the original alloca, in bits that need to be /// shifted to the right. By the end of this, there should be no uses of Ptr. Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, - unsigned Offset) { + uint64_t Offset) { // Convert the stored type to the actual type, shift it left to insert // then 'or' into place. Value *SV = SI->getOperand(0); const Type *AllocaType = NewAI->getType()->getElementType(); if (SV->getType() == AllocaType && Offset == 0) { - // All is well. - } else if (const VectorType *PTy = dyn_cast(AllocaType)) { + return SV; + } + + if (const VectorType *VTy = dyn_cast(AllocaType)) { Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); // If the result alloca is a vector type, this is either an element @@ -1569,72 +1430,68 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, SV = new BitCastInst(SV, AllocaType, SV->getName(), SI); } else { // Must be an element insertion. - unsigned Elt = Offset/TD->getTypePaddedSizeInBits(PTy->getElementType()); + unsigned Elt = Offset/TD->getTypePaddedSizeInBits(VTy->getElementType()); SV = InsertElementInst::Create(Old, SV, ConstantInt::get(Type::Int32Ty, Elt), "tmp", SI); } - } else if (isa(AllocaType)) { - // If the alloca type is a pointer, then all the elements must be - // pointers. - if (SV->getType() != AllocaType) - SV = new BitCastInst(SV, AllocaType, SV->getName(), SI); + return SV; + } + + + Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); + + // If SV is a float, convert it to the appropriate integer type. + // If it is a pointer, do the same, and also handle ptr->ptr casts + // here. + unsigned SrcWidth = TD->getTypeSizeInBits(SV->getType()); + unsigned DestWidth = TD->getTypeSizeInBits(AllocaType); + unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType()); + unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType); + if (SV->getType()->isFloatingPoint() || isa(SV->getType())) + SV = new BitCastInst(SV, IntegerType::get(SrcWidth), SV->getName(), SI); + else if (isa(SV->getType())) + SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), SI); + + // Always zero extend the value if needed. + if (SV->getType() != AllocaType) + SV = new ZExtInst(SV, AllocaType, SV->getName(), SI); + + // If this is a big-endian system and the store is narrower than the + // full alloca type, we need to do a shift to get the right bits. + int ShAmt = 0; + if (TD->isBigEndian()) { + // On big-endian machines, the lowest bit is stored at the bit offset + // from the pointer given by getTypeStoreSizeInBits. This matters for + // integers with a bitwidth that is not a multiple of 8. + ShAmt = DestStoreWidth - SrcStoreWidth - Offset; } else { - Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); - - // If SV is a float, convert it to the appropriate integer type. - // If it is a pointer, do the same, and also handle ptr->ptr casts - // here. - unsigned SrcWidth = TD->getTypeSizeInBits(SV->getType()); - unsigned DestWidth = TD->getTypeSizeInBits(AllocaType); - unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType()); - unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType); - if (SV->getType()->isFloatingPoint()) - SV = new BitCastInst(SV, IntegerType::get(SrcWidth), - SV->getName(), SI); - else if (isa(SV->getType())) - SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), SI); - - // Always zero extend the value if needed. - if (SV->getType() != AllocaType) - SV = new ZExtInst(SV, AllocaType, SV->getName(), SI); - - // If this is a big-endian system and the store is narrower than the - // full alloca type, we need to do a shift to get the right bits. - int ShAmt = 0; - if (TD->isBigEndian()) { - // On big-endian machines, the lowest bit is stored at the bit offset - // from the pointer given by getTypeStoreSizeInBits. This matters for - // integers with a bitwidth that is not a multiple of 8. - ShAmt = DestStoreWidth - SrcStoreWidth - Offset; - } else { - ShAmt = Offset; - } - - // Note: we support negative bitwidths (with shr) which are not defined. - // We do this to support (f.e.) stores off the end of a structure where - // only some bits in the structure are set. - APInt Mask(APInt::getLowBitsSet(DestWidth, SrcWidth)); - if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) { - SV = BinaryOperator::CreateShl(SV, - ConstantInt::get(SV->getType(), ShAmt), - SV->getName(), SI); - Mask <<= ShAmt; - } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) { - SV = BinaryOperator::CreateLShr(SV, - ConstantInt::get(SV->getType(),-ShAmt), - SV->getName(), SI); - Mask = Mask.lshr(ShAmt); - } - - // Mask out the bits we are about to insert from the old value, and or - // in the new bits. - if (SrcWidth != DestWidth) { - assert(DestWidth > SrcWidth); - Old = BinaryOperator::CreateAnd(Old, ConstantInt::get(~Mask), - Old->getName()+".mask", SI); - SV = BinaryOperator::CreateOr(Old, SV, SV->getName()+".ins", SI); - } + ShAmt = Offset; + } + + // Note: we support negative bitwidths (with shr) which are not defined. + // We do this to support (f.e.) stores off the end of a structure where + // only some bits in the structure are set. + APInt Mask(APInt::getLowBitsSet(DestWidth, SrcWidth)); + if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) { + SV = BinaryOperator::CreateShl(SV, + ConstantInt::get(SV->getType(), ShAmt), + SV->getName(), SI); + Mask <<= ShAmt; + } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) { + SV = BinaryOperator::CreateLShr(SV, + ConstantInt::get(SV->getType(),-ShAmt), + SV->getName(), SI); + Mask = Mask.lshr(ShAmt); + } + + // Mask out the bits we are about to insert from the old value, and or + // in the new bits. + if (SrcWidth != DestWidth) { + assert(DestWidth > SrcWidth); + Old = BinaryOperator::CreateAnd(Old, ConstantInt::get(~Mask), + Old->getName()+".mask", SI); + SV = BinaryOperator::CreateOr(Old, SV, SV->getName()+".ins", SI); } return SV; } diff --git a/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll b/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll index adfa5f85d2eb..4b7d622cd392 100644 --- a/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll +++ b/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll @@ -1,9 +1,8 @@ -; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \ -; RUN: grep alloca | grep {4 x} +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {ret i32 undef} -; Test that an array is not incorrectly deconstructed... +; Test that an array is not incorrectly deconstructed. -define i32 @test() { +define i32 @test() nounwind { %X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1] %Y = getelementptr [4 x i32]* %X, i64 0, i64 0 ; [#uses=1] ; Must preserve arrayness! diff --git a/llvm/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll b/llvm/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll index 1f3df499c32f..f0253b7bea93 100644 --- a/llvm/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll +++ b/llvm/test/Transforms/ScalarRepl/2006-11-07-InvalidArrayPromote.ll @@ -1,7 +1,6 @@ -; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | \ -; RUN: grep -F {alloca \[2 x <4 x i32>\]} +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca -define i32 @func(<4 x float> %v0, <4 x float> %v1) { +define i32 @func(<4 x float> %v0, <4 x float> %v1) nounwind { %vsiidx = alloca [2 x <4 x i32>], align 16 ; <[2 x <4 x i32>]*> [#uses=3] %tmp = call <4 x i32> @llvm.x86.sse2.cvttps2dq( <4 x float> %v0 ) ; <<4 x i32>> [#uses=2] %tmp.upgrd.1 = bitcast <4 x i32> %tmp to <2 x i64> ; <<2 x i64>> [#uses=0] diff --git a/llvm/test/Transforms/ScalarRepl/badarray.ll b/llvm/test/Transforms/ScalarRepl/badarray.ll index 1e4714eae988..56ae04ce9174 100644 --- a/llvm/test/Transforms/ScalarRepl/badarray.ll +++ b/llvm/test/Transforms/ScalarRepl/badarray.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -scalarrepl -mem2reg | llvm-dis | grep alloca +; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 0} define i32 @test() { %X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1] diff --git a/llvm/test/Transforms/ScalarRepl/bitfield-sroa.ll b/llvm/test/Transforms/ScalarRepl/bitfield-sroa.ll new file mode 100644 index 000000000000..34dd120e3f8f --- /dev/null +++ b/llvm/test/Transforms/ScalarRepl/bitfield-sroa.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca +; rdar://6532315 +%t = type { { i32, i16, i8, i8 } } + +define i8 @foo(i64 %A) { + %ALL = alloca %t, align 8 + %tmp59172 = bitcast %t* %ALL to i64* + store i64 %A, i64* %tmp59172, align 8 + %C = getelementptr %t* %ALL, i32 0, i32 0, i32 1 + %D = bitcast i16* %C to i32* + %E = load i32* %D, align 4 + %F = bitcast %t* %ALL to i8* + %G = load i8* %F, align 8 + ret i8 %G +} + -- GitLab From c22f236e8144fb97fd7cc5b28fa1f190134aab88 Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Sat, 31 Jan 2009 02:43:27 +0000 Subject: [PATCH 567/682] Use target alignment API to set objc2's meta-data alignment. llvm-svn: 63470 --- clang/lib/CodeGen/CGObjCMac.cpp | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 4e6611bc554b..23d62097e64c 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -363,11 +363,6 @@ protected: /// defined. The return value has type ProtocolPtrTy. llvm::Constant *GetProtocolRef(const ObjCProtocolDecl *PD); - /// GetPointerAlign - get alignment of a pointer. - uint32_t GetPointerAlign(void) { - return CGM.getContext().getTypeAlign(CGM.getContext().VoidPtrTy) >> 3; - } - public: CGObjCCommonMac(CodeGen::CodeGenModule &cgm) : CGM(cgm) { } @@ -3341,7 +3336,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassRoTInitializer( std::string("\01l_OBJC_METACLASS_RO_$_")+ClassName : std::string("\01l_OBJC_CLASS_RO_$_")+ClassName, &CGM.getModule()); - CLASS_RO_GV->setAlignment(GetPointerAlign()); + CLASS_RO_GV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassRonfABITy)); CLASS_RO_GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(CLASS_RO_GV); return CLASS_RO_GV; @@ -3385,7 +3381,8 @@ llvm::GlobalVariable * CGObjCNonFragileABIMac::BuildClassMetaData( ClassName, &CGM.getModule()); GV->setSection("__DATA, __objc_data"); - GV->setAlignment(GetPointerAlign()); + GV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ClassnfABITy)); if (HiddenVisibility) GV->setVisibility(llvm::GlobalValue::HiddenVisibility); UsedGlobals.push_back(GV); @@ -3658,7 +3655,8 @@ void CGObjCNonFragileABIMac::GenerateCategory(const ObjCCategoryImplDecl *OCD) Init, ExtCatName, &CGM.getModule()); - GCATV->setAlignment(GetPointerAlign()); + GCATV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.CategorynfABITy)); GCATV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GCATV); DefinedCategories.push_back(GCATV); @@ -3715,7 +3713,8 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitMethodList( Init, Name, &CGM.getModule()); - GV->setAlignment(GetPointerAlign()); + GV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(Init->getType())); GV->setSection(Section); UsedGlobals.push_back(GV); return llvm::ConstantExpr::getBitCast(GV, @@ -3735,6 +3734,8 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( CGM.getModule().getGlobalVariable(ExternalName); if (IvarOffsetGV) { // ivar offset symbol already built due to user code referencing it. + IvarOffsetGV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.Int8PtrTy)); IvarOffsetGV->setInitializer(Init); UsedGlobals.push_back(IvarOffsetGV); return IvarOffsetGV; @@ -3747,6 +3748,8 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( Init, ExternalName, &CGM.getModule()); + IvarOffsetGV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.Int8PtrTy)); // @private and @package have hidden visibility. bool globalVisibility = (Ivar->getAccessControl() == ObjCIvarDecl::Public || Ivar->getAccessControl() == ObjCIvarDecl::Protected); @@ -3848,7 +3851,8 @@ llvm::Constant *CGObjCNonFragileABIMac::EmitIvarList( Init, Prefix + OID->getNameAsString(), &CGM.getModule()); - GV->setAlignment(GetPointerAlign()); + GV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(Init->getType())); GV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(GV); @@ -3974,7 +3978,8 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( Init, std::string("\01l_OBJC_PROTOCOL_$_")+ProtocolName, &CGM.getModule()); - Entry->setAlignment(GetPointerAlign()); + Entry->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.ProtocolnfABITy)); Entry->setSection("__DATA,__datacoal_nt,coalesced"); } Entry->setVisibility(llvm::GlobalValue::HiddenVisibility); @@ -3989,7 +3994,8 @@ llvm::Constant *CGObjCNonFragileABIMac::GetOrEmitProtocol( std::string("\01l_OBJC_LABEL_PROTOCOL_$_") +ProtocolName, &CGM.getModule()); - PTGV->setAlignment(GetPointerAlign()); + PTGV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(ptype)); PTGV->setSection("__DATA, __objc_protolist"); PTGV->setVisibility(llvm::GlobalValue::HiddenVisibility); UsedGlobals.push_back(PTGV); @@ -4038,7 +4044,8 @@ CGObjCNonFragileABIMac::EmitProtocolList(const std::string &Name, Name, &CGM.getModule()); GV->setSection("__DATA, __objc_const"); - GV->setAlignment(GetPointerAlign()); + GV->setAlignment( + CGM.getTargetData().getPrefTypeAlignment(Init->getType())); UsedGlobals.push_back(GV); return llvm::ConstantExpr::getBitCast(GV, ObjCTypes.ProtocolListnfABIPtrTy); } -- GitLab From a8b7f6bb13afee0f9b78e0040fcb6d1931ad9265 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 31 Jan 2009 02:54:56 +0000 Subject: [PATCH 568/682] Initialize CGFunctionInfo isVariadic bit correctly. llvm-svn: 63471 --- clang/lib/CodeGen/CGCall.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index b6c5d8d273ed..08d5da30fa35 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -1284,8 +1284,10 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, } llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); - bool isVariadic = false; // cast(Callee->getType())->isVarArg(); - CGFunctionInfo CallInfo(RetTy, CallArgs, isVariadic); + const llvm::Type *FnType = + cast(Callee->getType())->getElementType(); + CGFunctionInfo CallInfo(RetTy, CallArgs, + cast(FnType)->isVarArg()); // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. CodeGen::AttributeListType AttributeList; -- GitLab From 5df2b0baaa7e6aa3993d27703ce43613b4be9b5b Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Sat, 31 Jan 2009 03:05:44 +0000 Subject: [PATCH 569/682] Remove unused overload of GetFunctionType. llvm-svn: 63472 --- clang/lib/CodeGen/CGCall.cpp | 10 ++-------- clang/lib/CodeGen/CodeGenTypes.h | 9 +-------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 08d5da30fa35..7fc3176d2db6 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -874,17 +874,11 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, const llvm::FunctionType * CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { - return GetFunctionType(FI.argtypes_begin(), FI.argtypes_end(), - FI.isVariadic()); -} - -const llvm::FunctionType * -CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end, - bool IsVariadic) { std::vector ArgTys; const llvm::Type *ResultType = 0; + ArgTypeIterator begin = FI.argtypes_begin(), end = FI.argtypes_end(); QualType RetTy = *begin; ABIArgInfo RetAI = getABIReturnInfo(RetTy, *this); switch (RetAI.getKind()) { @@ -944,7 +938,7 @@ CodeGenTypes::GetFunctionType(ArgTypeIterator begin, ArgTypeIterator end, } } - return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic); + return llvm::FunctionType::get(ResultType, ArgTys, FI.isVariadic()); } bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) { diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 46ca79a3caa1..eb4244545b2e 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -143,15 +143,8 @@ public: /// memory representation is usually i8 or i32, depending on the target. const llvm::Type *ConvertTypeForMem(QualType T); - /// GetFunctionType - Get the LLVM function type from Info. + /// GetFunctionType - Get the LLVM function type for \arg Info. const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info); - - /// GetFunctionType - Get the LLVM function type for the given types - /// and variadicness. - // FIXME: Do we even need IsVariadic here? - const llvm::FunctionType *GetFunctionType(ArgTypeIterator begin, - ArgTypeIterator end, - bool IsVariadic); const CGRecordLayout *getCGRecordLayout(const TagDecl*) const; /// Returns a StructType representing an Objective-C object -- GitLab From 3b585af0ecddfa8b09f0e2d329138094c689164f Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Sat, 31 Jan 2009 03:12:48 +0000 Subject: [PATCH 570/682] Don't use DebugLoc::getUnknownLoc(). Default to something hopefully sensible. llvm-svn: 63473 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 113 +++++++++--------- 1 file changed, 55 insertions(+), 58 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 9b65d85ca36a..7240fb9a7175 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1947,7 +1947,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) { SDValue NewPtr = LN0->getBasePtr(); if (TLI.isBigEndian()) { - NewPtr = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), PtrType, + NewPtr = DAG.getNode(ISD::ADD, LN0->getDebugLoc(), PtrType, NewPtr, DAG.getConstant(PtrOff, PtrType)); Alignment = MinAlign(Alignment, PtrOff); } @@ -2636,9 +2636,11 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { uint64_t TruncC = TruncVT.getIntegerVTBitMask() & N101C->getZExtValue(); return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0, - DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), + DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, - DAG.getNode(ISD::TRUNCATE, TruncVT, N100), + DAG.getNode(ISD::TRUNCATE, + N->getDebugLoc(), + TruncVT, N100), DAG.getConstant(TruncC, TruncVT))); } } @@ -2759,9 +2761,11 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { uint64_t TruncC = TruncVT.getIntegerVTBitMask() & N101C->getZExtValue(); return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, - DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), + DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, - DAG.getNode(ISD::TRUNCATE, TruncVT, N100), + DAG.getNode(ISD::TRUNCATE, + N->getDebugLoc(), + TruncVT, N100), DAG.getConstant(TruncC, TruncVT))); } } @@ -3092,12 +3096,12 @@ SDValue DAGCombiner::visitSIGN_EXTEND(SDNode *N) { if (SOp == Trunc) Ops.push_back(ExtLoad); else - Ops.push_back(DAG.getNode(ISD::SIGN_EXTEND, DebugLoc::getUnknownLoc(), + Ops.push_back(DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, SOp)); } Ops.push_back(SetCC->getOperand(2)); - CombineTo(SetCC, DAG.getNode(ISD::SETCC, DebugLoc::getUnknownLoc(), + CombineTo(SetCC, DAG.getNode(ISD::SETCC, N->getDebugLoc(), SetCC->getValueType(0), &Ops[0], Ops.size())); } @@ -3174,9 +3178,9 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { (!LegalOperations || TLI.isOperationLegal(ISD::AND, VT))) { SDValue Op = N0.getOperand(0); if (Op.getValueType().bitsLT(VT)) { - Op = DAG.getNode(ISD::ANY_EXTEND, DebugLoc::getUnknownLoc(), VT, Op); + Op = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, Op); } else if (Op.getValueType().bitsGT(VT)) { - Op = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, Op); + Op = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, Op); } return DAG.getZeroExtendInReg(Op, N->getDebugLoc(), N0.getValueType()); } @@ -3187,9 +3191,9 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { N0.getOperand(1).getOpcode() == ISD::Constant) { SDValue X = N0.getOperand(0).getOperand(0); if (X.getValueType().bitsLT(VT)) { - X = DAG.getNode(ISD::ANY_EXTEND, DebugLoc::getUnknownLoc(), VT, X); + X = DAG.getNode(ISD::ANY_EXTEND, X.getDebugLoc(), VT, X); } else if (X.getValueType().bitsGT(VT)) { - X = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, X); + X = DAG.getNode(ISD::TRUNCATE, X.getDebugLoc(), VT, X); } APInt Mask = cast(N0.getOperand(1))->getAPIntValue(); Mask.zext(VT.getSizeInBits()); @@ -3228,11 +3232,12 @@ SDValue DAGCombiner::visitZERO_EXTEND(SDNode *N) { if (SOp == Trunc) Ops.push_back(ExtLoad); else - Ops.push_back(DAG.getNode(ISD::ZERO_EXTEND, VT, SOp)); + Ops.push_back(DAG.getNode(ISD::ZERO_EXTEND, + N->getDebugLoc(), VT, SOp)); } Ops.push_back(SetCC->getOperand(2)); - CombineTo(SetCC, DAG.getNode(ISD::SETCC, DebugLoc::getUnknownLoc(), + CombineTo(SetCC, DAG.getNode(ISD::SETCC, N->getDebugLoc(), SetCC->getValueType(0), &Ops[0], Ops.size())); } @@ -3317,9 +3322,9 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { N0.getOperand(1).getOpcode() == ISD::Constant) { SDValue X = N0.getOperand(0).getOperand(0); if (X.getValueType().bitsLT(VT)) { - X = DAG.getNode(ISD::ANY_EXTEND, DebugLoc::getUnknownLoc(), VT, X); + X = DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, X); } else if (X.getValueType().bitsGT(VT)) { - X = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, X); + X = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), VT, X); } APInt Mask = cast(N0.getOperand(1))->getAPIntValue(); Mask.zext(VT.getSizeInBits()); @@ -3476,7 +3481,7 @@ SDValue DAGCombiner::ReduceLoadWidth(SDNode *N) { uint64_t PtrOff = ShAmt / 8; unsigned NewAlign = MinAlign(LN0->getAlignment(), PtrOff); - SDValue NewPtr = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), + SDValue NewPtr = DAG.getNode(ISD::ADD, LN0->getDebugLoc(), PtrType, LN0->getBasePtr(), DAG.getConstant(PtrOff, PtrType)); AddToWorkList(NewPtr.getNode()); @@ -3773,34 +3778,34 @@ SDValue DAGCombiner::visitBIT_CONVERT(SDNode *N) { unsigned OrigXWidth = N0.getOperand(1).getValueType().getSizeInBits(); MVT IntXVT = MVT::getIntegerVT(OrigXWidth); if (TLI.isTypeLegal(IntXVT) || !LegalTypes) { - SDValue X = DAG.getNode(ISD::BIT_CONVERT, DebugLoc::getUnknownLoc(), + SDValue X = DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(), IntXVT, N0.getOperand(1)); AddToWorkList(X.getNode()); // If X has a different width than the result/lhs, sext it or truncate it. unsigned VTWidth = VT.getSizeInBits(); if (OrigXWidth < VTWidth) { - X = DAG.getNode(ISD::SIGN_EXTEND, DebugLoc::getUnknownLoc(), VT, X); + X = DAG.getNode(ISD::SIGN_EXTEND, N->getDebugLoc(), VT, X); AddToWorkList(X.getNode()); } else if (OrigXWidth > VTWidth) { // To get the sign bit in the right place, we have to shift it right // before truncating. - X = DAG.getNode(ISD::SRL, DebugLoc::getUnknownLoc(), + X = DAG.getNode(ISD::SRL, X.getDebugLoc(), X.getValueType(), X, DAG.getConstant(OrigXWidth-VTWidth, X.getValueType())); AddToWorkList(X.getNode()); - X = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), VT, X); + X = DAG.getNode(ISD::TRUNCATE, X.getDebugLoc(), VT, X); AddToWorkList(X.getNode()); } APInt SignBit = APInt::getSignBit(VT.getSizeInBits()); - X = DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), VT, + X = DAG.getNode(ISD::AND, X.getDebugLoc(), VT, X, DAG.getConstant(SignBit, VT)); AddToWorkList(X.getNode()); - SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, DebugLoc::getUnknownLoc(), + SDValue Cst = DAG.getNode(ISD::BIT_CONVERT, N0.getDebugLoc(), VT, N0.getOperand(0)); - Cst = DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), VT, + Cst = DAG.getNode(ISD::AND, Cst.getDebugLoc(), VT, Cst, DAG.getConstant(~SignBit, VT)); AddToWorkList(Cst.getNode()); @@ -3897,8 +3902,7 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { } if (EltIsUndef) - Ops.push_back(DAG.getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), - DstEltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, BV->getDebugLoc(), DstEltVT)); else Ops.push_back(DAG.getConstant(NewBits, DstEltVT)); } @@ -3918,8 +3922,7 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { if (BV->getOperand(i).getOpcode() == ISD::UNDEF) { for (unsigned j = 0; j != NumOutputsPerInput; ++j) - Ops.push_back(DAG.getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), - DstEltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, BV->getDebugLoc(), DstEltVT)); continue; } @@ -4136,8 +4139,7 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { } else { if (!LegalOperations || TLI.isOperationLegal(ISD::FNEG, VT)) return DAG.getNode(ISD::FNEG, N->getDebugLoc(), VT, - DAG.getNode(ISD::FABS, DebugLoc::getUnknownLoc(), - VT, N0)); + DAG.getNode(ISD::FABS, N0.getDebugLoc(), VT, N0)); } } @@ -4349,7 +4351,7 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) { SDValue Int = N0.getOperand(0); MVT IntVT = Int.getValueType(); if (IntVT.isInteger() && !IntVT.isVector()) { - Int = DAG.getNode(ISD::XOR, DebugLoc::getUnknownLoc(), IntVT, Int, + Int = DAG.getNode(ISD::XOR, N0.getDebugLoc(), IntVT, Int, DAG.getConstant(IntVT.getIntegerVTSignBit(), IntVT)); AddToWorkList(Int.getNode()); return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), @@ -4384,7 +4386,7 @@ SDValue DAGCombiner::visitFABS(SDNode *N) { SDValue Int = N0.getOperand(0); MVT IntVT = Int.getValueType(); if (IntVT.isInteger() && !IntVT.isVector()) { - Int = DAG.getNode(ISD::AND, DebugLoc::getUnknownLoc(), IntVT, Int, + Int = DAG.getNode(ISD::AND, N0.getDebugLoc(), IntVT, Int, DAG.getConstant(~IntVT.getIntegerVTSignBit(), IntVT)); AddToWorkList(Int.getNode()); return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), @@ -4807,8 +4809,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { WorkListRemover DeadNodes(*this); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 0), Undef, &DeadNodes); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 1), - DAG.getNode(ISD::UNDEF, DebugLoc::getUnknownLoc(), - N->getValueType(1)), + DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + N->getValueType(1)), &DeadNodes); DAG.ReplaceAllUsesOfValueWith(SDValue(N, 2), Chain, &DeadNodes); removeFromWorkList(N); @@ -5230,7 +5232,7 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { for (unsigned i = 0; i != NumInScalars; ++i) { if (N->getOperand(i).getOpcode() == ISD::UNDEF) { BuildVecIndices.push_back(DAG.getNode(ISD::UNDEF, - DebugLoc::getUnknownLoc(), + N->getDebugLoc(), TLI.getPointerTy())); continue; } @@ -5460,13 +5462,13 @@ SDValue DAGCombiner::XformToShuffleWithZero(SDNode *N) { MVT VT = MVT::getVectorVT(EVT, NumElts); MVT MaskVT = MVT::getVectorVT(TLI.getPointerTy(), NumElts); std::vector Ops; - LHS = DAG.getNode(ISD::BIT_CONVERT, DebugLoc::getUnknownLoc(), VT, LHS); + LHS = DAG.getNode(ISD::BIT_CONVERT, LHS.getDebugLoc(), VT, LHS); Ops.push_back(LHS); AddToWorkList(LHS.getNode()); std::vector ZeroOps(NumElts, DAG.getConstant(0, EVT)); - Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), + Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, &ZeroOps[0], ZeroOps.size())); - Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), + Ops.push_back(DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), MaskVT, &IdxOps[0], IdxOps.size())); SDValue Result = DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), VT, &Ops[0], Ops.size()); @@ -5525,7 +5527,7 @@ SDValue DAGCombiner::SimplifyVBinOp(SDNode *N) { break; } - Ops.push_back(DAG.getNode(N->getOpcode(), DebugLoc::getUnknownLoc(), + Ops.push_back(DAG.getNode(N->getOpcode(), LHS.getDebugLoc(), EltType, LHSOp, RHSOp)); AddToWorkList(Ops.back().getNode()); assert((Ops.back().getOpcode() == ISD::UNDEF || @@ -5721,28 +5723,26 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, unsigned ShCtV = N2C->getAPIntValue().logBase2(); ShCtV = XType.getSizeInBits()-ShCtV-1; SDValue ShCt = DAG.getConstant(ShCtV, TLI.getShiftAmountTy()); - SDValue Shift = DAG.getNode(ISD::SRL, DebugLoc::getUnknownLoc(), + SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0, ShCt); AddToWorkList(Shift.getNode()); if (XType.bitsGT(AType)) { - Shift = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), - AType, Shift); + Shift = DAG.getNode(ISD::TRUNCATE, DL, AType, Shift); AddToWorkList(Shift.getNode()); } return DAG.getNode(ISD::AND, DL, AType, Shift, N2); } - SDValue Shift = DAG.getNode(ISD::SRA, DebugLoc::getUnknownLoc(), + SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, TLI.getShiftAmountTy())); AddToWorkList(Shift.getNode()); if (XType.bitsGT(AType)) { - Shift = DAG.getNode(ISD::TRUNCATE, DebugLoc::getUnknownLoc(), - AType, Shift); + Shift = DAG.getNode(ISD::TRUNCATE, DL, AType, Shift); AddToWorkList(Shift.getNode()); } @@ -5765,18 +5765,16 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Temp, SCC; // cast from setcc result type to select result type if (LegalTypes) { - SCC = DAG.getSetCC(DebugLoc::getUnknownLoc(), - TLI.getSetCCResultType(N0.getValueType()), + SCC = DAG.getSetCC(DL, TLI.getSetCCResultType(N0.getValueType()), N0, N1, CC); if (N2.getValueType().bitsLT(SCC.getValueType())) - Temp = DAG.getZeroExtendInReg(SCC, DebugLoc::getUnknownLoc(), - N2.getValueType()); + Temp = DAG.getZeroExtendInReg(SCC, N2.getDebugLoc(), N2.getValueType()); else - Temp = DAG.getNode(ISD::ZERO_EXTEND, DebugLoc::getUnknownLoc(), + Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getDebugLoc(), N2.getValueType(), SCC); } else { - SCC = DAG.getSetCC(DebugLoc::getUnknownLoc(), MVT::i1, N0, N1, CC); - Temp = DAG.getNode(ISD::ZERO_EXTEND, DebugLoc::getUnknownLoc(), + SCC = DAG.getSetCC(N0.getDebugLoc(), MVT::i1, N0, N1, CC); + Temp = DAG.getNode(ISD::ZERO_EXTEND, N2.getDebugLoc(), N2.getValueType(), SCC); } @@ -5809,8 +5807,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, if (N1C && N1C->isNullValue() && CC == ISD::SETEQ && (!LegalOperations || TLI.isOperationLegal(ISD::CTLZ, XType))) { - SDValue Ctlz = DAG.getNode(ISD::CTLZ, DebugLoc::getUnknownLoc(), - XType, N0); + SDValue Ctlz = DAG.getNode(ISD::CTLZ, N0.getDebugLoc(), XType, N0); return DAG.getNode(ISD::SRL, DL, XType, Ctlz, DAG.getConstant(Log2_32(XType.getSizeInBits()), TLI.getShiftAmountTy())); @@ -5827,7 +5824,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, } // fold (setgt X, -1) -> (xor (srl (X, size(X)-1), 1)) if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT) { - SDValue Sign = DAG.getNode(ISD::SRL, DebugLoc::getUnknownLoc(), XType, N0, + SDValue Sign = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, TLI.getShiftAmountTy())); return DAG.getNode(ISD::XOR, DL, XType, Sign, DAG.getConstant(1, XType)); @@ -5840,10 +5837,10 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, N0 == N3 && N2.getOpcode() == ISD::SUB && N0 == N2.getOperand(1) && N2.getOperand(0) == N1 && N0.getValueType().isInteger()) { MVT XType = N0.getValueType(); - SDValue Shift = DAG.getNode(ISD::SRA, DebugLoc::getUnknownLoc(), XType, N0, + SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, TLI.getShiftAmountTy())); - SDValue Add = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), XType, + SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType, N0, Shift); AddToWorkList(Shift.getNode()); AddToWorkList(Add.getNode()); @@ -5856,11 +5853,11 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, if (ConstantSDNode *SubC = dyn_cast(N3.getOperand(0))) { MVT XType = N0.getValueType(); if (SubC->isNullValue() && XType.isInteger()) { - SDValue Shift = DAG.getNode(ISD::SRA, DebugLoc::getUnknownLoc(), XType, + SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, TLI.getShiftAmountTy())); - SDValue Add = DAG.getNode(ISD::ADD, DebugLoc::getUnknownLoc(), + SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType, N0, Shift); AddToWorkList(Shift.getNode()); AddToWorkList(Add.getNode()); -- GitLab From cf9ba823240ec6d3682ba2ddeab5cdcf04092c77 Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Sat, 31 Jan 2009 06:07:45 +0000 Subject: [PATCH 571/682] If unsafe FP optimization is not set, don't allow -(A-B) => B-A because when A==B, -0.0 != +0.0. llvm-svn: 63474 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 ++- llvm/test/CodeGen/X86/neg_fp.ll | 12 ++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 llvm/test/CodeGen/X86/neg_fp.ll diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index bda9d934a41c..f5287b0cf2c5 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -2357,7 +2357,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, return Operand.getOperand(0); break; case ISD::FNEG: - if (OpOpcode == ISD::FSUB) // -(X-Y) -> (Y-X) + // -(X-Y) -> (Y-X) is unsafe because when X==Y, -0.0 != +0.0 + if (UnsafeFPMath && OpOpcode == ISD::FSUB) return getNode(ISD::FSUB, VT, Operand.getNode()->getOperand(1), Operand.getNode()->getOperand(0)); if (OpOpcode == ISD::FNEG) // --X -> X diff --git a/llvm/test/CodeGen/X86/neg_fp.ll b/llvm/test/CodeGen/X86/neg_fp.ll new file mode 100644 index 000000000000..55c76549ffe2 --- /dev/null +++ b/llvm/test/CodeGen/X86/neg_fp.ll @@ -0,0 +1,12 @@ +; RUN: llvm-as < %s | llc -march=x86 -mattr=+sse41 -o %t -f +; RUN: grep xorps %t | count 1 + +; Test that when we don't -enable-unsafe-fp-math, we don't do the optimization +; -0 - (A - B) to (B - A) because A==B, -0 != 0 + +define float @negfp(float %a, float %b) { +entry: + %sub = sub float %a, %b ; [#uses=1] + %neg = sub float -0.000000e+00, %sub ; [#uses=1] + ret float %neg +} \ No newline at end of file -- GitLab From b6080cf943c43e10176c47f9cb50ee20f69cca3a Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Sat, 31 Jan 2009 06:50:54 +0000 Subject: [PATCH 572/682] Used "-enable-unsafe-fp-math" to allow this transformation - (a * b -c) = c - a *b. llvm-svn: 63475 --- llvm/test/CodeGen/CellSPU/sp_farith.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/CellSPU/sp_farith.ll b/llvm/test/CodeGen/CellSPU/sp_farith.ll index 949e69a5a3d4..df3baef85c9d 100644 --- a/llvm/test/CodeGen/CellSPU/sp_farith.ll +++ b/llvm/test/CodeGen/CellSPU/sp_farith.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as -o - %s | llc -march=cellspu > %t1.s +; RUN: llvm-as -o - %s | llc -march=cellspu -enable-unsafe-fp-math > %t1.s ; RUN: grep fa %t1.s | count 2 ; RUN: grep fs %t1.s | count 2 ; RUN: grep fm %t1.s | count 6 -- GitLab From 94cfb281c31748162b621b2c7a54a892be4472ce Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 07:04:22 +0000 Subject: [PATCH 573/682] make sure to set Changed=true when instcombine hacks on the code, not doing so prevents it from properly iterating and prevents it from deleting the entire body of dce-iterate.ll llvm-svn: 63476 --- .../Scalar/InstructionCombining.cpp | 14 +++++++---- .../Transforms/InstCombine/dce-iterate.ll | 24 +++++++++++++++++++ 2 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/dce-iterate.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 7f7592840a4d..6c571511e7cc 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -12356,6 +12356,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) { if (!I->use_empty()) I->replaceAllUsesWith(UndefValue::get(I->getType())); I->eraseFromParent(); + Changed = true; } } } @@ -12375,6 +12376,7 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) { I->eraseFromParent(); RemoveFromWorkList(I); + Changed = true; continue; } @@ -12389,17 +12391,19 @@ bool InstCombiner::DoOneIteration(Function &F, unsigned Iteration) { ++NumConstProp; I->eraseFromParent(); RemoveFromWorkList(I); + Changed = true; continue; } if (TD && I->getType()->getTypeID() == Type::VoidTyID) { // See if we can constant fold its operands. - for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) { - if (ConstantExpr *CE = dyn_cast(i)) { + for (User::op_iterator i = I->op_begin(), e = I->op_end(); i != e; ++i) + if (ConstantExpr *CE = dyn_cast(i)) if (Constant *NewC = ConstantFoldConstantExpression(CE, TD)) - i->set(NewC); - } - } + if (NewC != CE) { + i->set(NewC); + Changed = true; + } } // See if we can trivially sink this instruction to a successor basic block. diff --git a/llvm/test/Transforms/InstCombine/dce-iterate.ll b/llvm/test/Transforms/InstCombine/dce-iterate.ll new file mode 100644 index 000000000000..e222970df6d8 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/dce-iterate.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {ret double .sy} + +define internal double @ScaleObjectAdd(double %sx, double %sy, double %sz) nounwind { +entry: + %sx34 = bitcast double %sx to i64 ; [#uses=1] + %sx3435 = zext i64 %sx34 to i960 ; [#uses=1] + %sy22 = bitcast double %sy to i64 ; [#uses=1] + %sy2223 = zext i64 %sy22 to i960 ; [#uses=1] + %sy222324 = shl i960 %sy2223, 320 ; [#uses=1] + %sy222324.ins = or i960 %sx3435, %sy222324 ; [#uses=1] + %sz10 = bitcast double %sz to i64 ; [#uses=1] + %sz1011 = zext i64 %sz10 to i960 ; [#uses=1] + %sz101112 = shl i960 %sz1011, 640 ; [#uses=1] + %sz101112.ins = or i960 %sy222324.ins, %sz101112 + + %a = trunc i960 %sz101112.ins to i64 ; [#uses=1] + %b = bitcast i64 %a to double ; [#uses=1] + %c = lshr i960 %sz101112.ins, 320 ; [#uses=1] + %d = trunc i960 %c to i64 ; [#uses=1] + %e = bitcast i64 %d to double ; [#uses=1] + %f = add double %b, %e + + ret double %e +} -- GitLab From 585cfb2ce76197e3e64419cdd339db8c74a4222b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 07:26:06 +0000 Subject: [PATCH 574/682] minor cleanups llvm-svn: 63477 --- llvm/lib/Transforms/Scalar/InstructionCombining.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 6c571511e7cc..f084420b88d9 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -766,7 +766,7 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty, /// in DemandedMask. Note also that the bitwidth of V, DemandedMask, KnownZero /// and KnownOne must all be the same. bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, - APInt& KnownZero, APInt& KnownOne, + APInt &KnownZero, APInt &KnownOne, unsigned Depth) { assert(V != 0 && "Null pointer of Value???"); assert(Depth <= 6 && "Limit Search Depth"); @@ -784,7 +784,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, return false; } - KnownZero.clear(); + KnownZero.clear(); KnownOne.clear(); if (!V->hasOneUse()) { // Other users may use these bits. if (Depth != 0) { // Not at the root. @@ -796,7 +796,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // just set the DemandedMask to all bits. DemandedMask = APInt::getAllOnesValue(BitWidth); } else if (DemandedMask == 0) { // Not demanding any bits from V. - if (V != UndefValue::get(VTy)) + if (!isa(V)) return UpdateValueUsesWith(V, UndefValue::get(VTy)); return false; } else if (Depth == 6) { // Limit search depth. -- GitLab From 19efe30264ab4cfe72bfa33b26b443c564a9728b Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 07:34:19 +0000 Subject: [PATCH 575/682] add accessors llvm-svn: 63478 --- llvm/include/llvm/User.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/llvm/include/llvm/User.h b/llvm/include/llvm/User.h index 919693e08292..e25d19b563fe 100644 --- a/llvm/include/llvm/User.h +++ b/llvm/include/llvm/User.h @@ -100,6 +100,15 @@ public: "Cannot mutate a constant with setOperand!"); OperandList[i] = Val; } + const Use &getOperandUse(unsigned i) const { + assert(i < NumOperands && "getOperand() out of range!"); + return OperandList[i]; + } + Use &getOperandUse(unsigned i) { + assert(i < NumOperands && "getOperand() out of range!"); + return OperandList[i]; + } + unsigned getNumOperands() const { return NumOperands; } // --------------------------------------------------------------------------- -- GitLab From 83c6a141b8fbde66da6834ceac0c7048b5f30492 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 08:15:18 +0000 Subject: [PATCH 576/682] make some fairly meaty internal changes to how SimplifyDemandedBits works. Now, if it detects that "V" is the same as some other value, SimplifyDemandedBits returns the new value instead of RAUW'ing it immediately. This has two benefits: 1) simpler code in the recursive SimplifyDemandedBits routine. 2) it allows future fun stuff in instcombine where an operation has multiple uses and can be simplified in one context, but not all. #2 isn't implemented yet, this patch should have no functionality change. llvm-svn: 63479 --- .../Scalar/InstructionCombining.cpp | 378 ++++++++---------- 1 file changed, 172 insertions(+), 206 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index f084420b88d9..186d8378a497 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -303,23 +303,6 @@ namespace { } } - // UpdateValueUsesWith - This method is to be used when an value is - // found to be replacable with another preexisting expression or was - // updated. Here we add all uses of I to the worklist, replace all uses of - // I with the new value (unless the instruction was just updated), then - // return true, so that the inst combiner will know that I was modified. - // - bool UpdateValueUsesWith(Value *Old, Value *New) { - AddUsersToWorkList(*Old); // Add all modified instrs to worklist - if (Old != New) - Old->replaceAllUsesWith(New); - if (Instruction *I = dyn_cast(Old)) - AddToWorkList(I); - if (Instruction *I = dyn_cast(New)) - AddToWorkList(I); - return true; - } - // EraseInstFromFunction - When dealing with an instruction that has side // effects or produces a void value, we can't rely on DCE to delete the // instruction. Instead, visit methods should return the value returned by @@ -355,12 +338,20 @@ namespace { /// most-complex to least-complex order. bool SimplifyCompare(CmpInst &I); - /// SimplifyDemandedBits - Attempts to replace V with a simpler value based - /// on the demanded bits. - bool SimplifyDemandedBits(Value *V, APInt DemandedMask, + /// SimplifyDemandedUseBits - Attempts to replace V with a simpler value + /// based on the demanded bits. + Value *SimplifyDemandedUseBits(Value *V, APInt DemandedMask, + APInt& KnownZero, APInt& KnownOne, + unsigned Depth); + bool SimplifyDemandedBits(Use &U, APInt DemandedMask, APInt& KnownZero, APInt& KnownOne, - unsigned Depth = 0); - + unsigned Depth=0); + + /// SimplifyDemandedInstructionBits - Inst is an integer instruction that + /// SimplifyDemandedBits knows about. See if the instruction has any + /// properties that allow us to simplify its operands. + bool SimplifyDemandedInstructionBits(Instruction &Inst); + Value *SimplifyDemandedVectorElts(Value *V, uint64_t DemandedElts, uint64_t &UndefElts, unsigned Depth = 0); @@ -750,14 +741,44 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty, Max = KnownOne|UnknownBits; } -/// SimplifyDemandedBits - This function attempts to replace V with a simpler -/// value based on the demanded bits. When this function is called, it is known +/// SimplifyDemandedInstructionBits - Inst is an integer instruction that +/// SimplifyDemandedBits knows about. See if the instruction has any +/// properties that allow us to simplify its operands. +bool InstCombiner::SimplifyDemandedInstructionBits(Instruction &Inst) { + unsigned BitWidth = cast(Inst.getType())->getBitWidth(); + APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); + APInt DemandedMask(APInt::getAllOnesValue(BitWidth)); + + Value *V = SimplifyDemandedUseBits(&Inst, DemandedMask, + KnownZero, KnownOne, 0); + if (V == 0) return false; + if (V == &Inst) return true; + ReplaceInstUsesWith(Inst, V); + return true; +} + +/// SimplifyDemandedBits - This form of SimplifyDemandedBits simplifies the +/// specified instruction operand if possible, updating it in place. It returns +/// true if it made any change and false otherwise. +bool InstCombiner::SimplifyDemandedBits(Use &U, APInt DemandedMask, + APInt &KnownZero, APInt &KnownOne, + unsigned Depth) { + Value *NewVal = SimplifyDemandedUseBits(U.get(), DemandedMask, + KnownZero, KnownOne, Depth); + if (NewVal == 0) return false; + U.set(NewVal); + return true; +} + + +/// SimplifyDemandedUseBits - This function attempts to replace V with a simpler +/// value based on the demanded bits. When this function is called, it is known /// that only the bits set in DemandedMask of the result of V are ever used /// downstream. Consequently, depending on the mask and V, it may be possible /// to replace V with a constant or one of its operands. In such cases, this /// function does the replacement and returns true. In all other cases, it /// returns false after analyzing the expression and setting KnownOne and known -/// to be one in the expression. KnownZero contains all the bits that are known +/// to be one in the expression. KnownZero contains all the bits that are known /// to be zero in the expression. These are provided to potentially allow the /// caller (which might recursively be SimplifyDemandedBits itself) to simplify /// the expression. KnownOne and KnownZero always follow the invariant that @@ -765,9 +786,15 @@ static void ComputeUnsignedMinMaxValuesFromKnownBits(const Type *Ty, /// the bits in KnownOne and KnownZero may only be accurate for those bits set /// in DemandedMask. Note also that the bitwidth of V, DemandedMask, KnownZero /// and KnownOne must all be the same. -bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, - APInt &KnownZero, APInt &KnownOne, - unsigned Depth) { +/// +/// This returns null if it did not change anything and it permits no +/// simplification. This returns V itself if it did some simplification of V's +/// operands based on the information about what bits are demanded. This returns +/// some other non-null value if it found out that V is equal to another value +/// in the context where the specified bits are demanded, but not for all users. +Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, + APInt &KnownZero, APInt &KnownOne, + unsigned Depth) { assert(V != 0 && "Null pointer of Value???"); assert(Depth <= 6 && "Limit Search Depth"); uint32_t BitWidth = DemandedMask.getBitWidth(); @@ -781,69 +808,63 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // We know all of the bits for a constant! KnownOne = CI->getValue() & DemandedMask; KnownZero = ~KnownOne & DemandedMask; - return false; + return 0; } KnownZero.clear(); KnownOne.clear(); - if (!V->hasOneUse()) { // Other users may use these bits. + if (DemandedMask == 0) { // Not demanding any bits from V. + if (isa(V)) + return 0; + return UndefValue::get(VTy); + } else if (!V->hasOneUse()) { // Other users may use these bits. if (Depth != 0) { // Not at the root. // Just compute the KnownZero/KnownOne bits to simplify things downstream. ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth); - return false; + return 0; } // If this is the root being simplified, allow it to have multiple uses, // just set the DemandedMask to all bits. DemandedMask = APInt::getAllOnesValue(BitWidth); - } else if (DemandedMask == 0) { // Not demanding any bits from V. - if (!isa(V)) - return UpdateValueUsesWith(V, UndefValue::get(VTy)); - return false; } else if (Depth == 6) { // Limit search depth. - return false; + return 0; } Instruction *I = dyn_cast(V); - if (!I) return false; // Only analyze instructions. + if (!I) return 0; // Only analyze instructions. APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne; switch (I->getOpcode()) { default: - ComputeMaskedBits(V, DemandedMask, RHSKnownZero, RHSKnownOne, Depth); + ComputeMaskedBits(I, DemandedMask, RHSKnownZero, RHSKnownOne, Depth); break; case Instruction::And: // If either the LHS or the RHS are Zero, the result is zero. - if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, - RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); - - // If something is known zero on the RHS, the bits aren't demanded on the - // LHS. - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownZero, + if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(0), DemandedMask & ~RHSKnownZero, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; - assert((LHSKnownZero & LHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); + assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?"); // If all of the demanded bits are known 1 on one side, return the other. // These bits cannot contribute to the result of the 'and'. if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) == (DemandedMask & ~LHSKnownZero)) - return UpdateValueUsesWith(I, I->getOperand(0)); + return I->getOperand(0); if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) == (DemandedMask & ~RHSKnownZero)) - return UpdateValueUsesWith(I, I->getOperand(1)); + return I->getOperand(1); // If all of the demanded bits in the inputs are known zeros, return zero. if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask) - return UpdateValueUsesWith(I, Constant::getNullValue(VTy)); + return Constant::getNullValue(VTy); // If the RHS is a constant, see if we can simplify it. if (ShrinkDemandedConstant(I, 1, DemandedMask & ~LHSKnownZero)) - return UpdateValueUsesWith(I, I); + return I; // Output known-1 bits are only known if set in both the LHS & RHS. RHSKnownOne &= LHSKnownOne; @@ -852,40 +873,35 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, break; case Instruction::Or: // If either the LHS or the RHS are One, the result is One. - if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, - RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); - // If something is known one on the RHS, the bits aren't demanded on the - // LHS. - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask & ~RHSKnownOne, + if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(0), DemandedMask & ~RHSKnownOne, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; - assert((LHSKnownZero & LHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); + assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?"); // If all of the demanded bits are known zero on one side, return the other. // These bits cannot contribute to the result of the 'or'. if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) == (DemandedMask & ~LHSKnownOne)) - return UpdateValueUsesWith(I, I->getOperand(0)); + return I->getOperand(0); if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) == (DemandedMask & ~RHSKnownOne)) - return UpdateValueUsesWith(I, I->getOperand(1)); + return I->getOperand(1); // If all of the potentially set bits on one side are known to be set on // the other side, just use the 'other' side. if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) == (DemandedMask & (~RHSKnownZero))) - return UpdateValueUsesWith(I, I->getOperand(0)); + return I->getOperand(0); if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) == (DemandedMask & (~LHSKnownZero))) - return UpdateValueUsesWith(I, I->getOperand(1)); + return I->getOperand(1); // If the RHS is a constant, see if we can simplify it. if (ShrinkDemandedConstant(I, 1, DemandedMask)) - return UpdateValueUsesWith(I, I); + return I; // Output known-0 bits are only known if clear in both the LHS & RHS. RHSKnownZero &= LHSKnownZero; @@ -893,23 +909,20 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, RHSKnownOne |= LHSKnownOne; break; case Instruction::Xor: { - if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, - RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + if (SimplifyDemandedBits(I->getOperandUse(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(0), DemandedMask, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; - assert((LHSKnownZero & LHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); + assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?"); // If all of the demanded bits are known zero on one side, return the other. // These bits cannot contribute to the result of the 'xor'. if ((DemandedMask & RHSKnownZero) == DemandedMask) - return UpdateValueUsesWith(I, I->getOperand(0)); + return I->getOperand(0); if ((DemandedMask & LHSKnownZero) == DemandedMask) - return UpdateValueUsesWith(I, I->getOperand(1)); + return I->getOperand(1); // Output known-0 bits are known if clear or set in both the LHS & RHS. APInt KnownZeroOut = (RHSKnownZero & LHSKnownZero) | @@ -925,8 +938,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, Instruction *Or = BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1), I->getName()); - InsertNewInstBefore(Or, *I); - return UpdateValueUsesWith(I, Or); + return InsertNewInstBefore(Or, *I); } // If all of the demanded bits on one side are known, and all of the set @@ -939,92 +951,80 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, Constant *AndC = ConstantInt::get(~RHSKnownOne & DemandedMask); Instruction *And = BinaryOperator::CreateAnd(I->getOperand(0), AndC, "tmp"); - InsertNewInstBefore(And, *I); - return UpdateValueUsesWith(I, And); + return InsertNewInstBefore(And, *I); } } // If the RHS is a constant, see if we can simplify it. // FIXME: for XOR, we prefer to force bits to 1 if they will make a -1. if (ShrinkDemandedConstant(I, 1, DemandedMask)) - return UpdateValueUsesWith(I, I); + return I; RHSKnownZero = KnownZeroOut; RHSKnownOne = KnownOneOut; break; } case Instruction::Select: - if (SimplifyDemandedBits(I->getOperand(2), DemandedMask, - RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - if (SimplifyDemandedBits(I->getOperand(1), DemandedMask, + if (SimplifyDemandedBits(I->getOperandUse(2), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(1), DemandedMask, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); - assert((LHSKnownZero & LHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); + assert(!(LHSKnownZero & LHSKnownOne) && "Bits known to be one AND zero?"); // If the operands are constants, see if we can simplify them. - if (ShrinkDemandedConstant(I, 1, DemandedMask)) - return UpdateValueUsesWith(I, I); - if (ShrinkDemandedConstant(I, 2, DemandedMask)) - return UpdateValueUsesWith(I, I); + if (ShrinkDemandedConstant(I, 1, DemandedMask) || + ShrinkDemandedConstant(I, 2, DemandedMask)) + return I; // Only known if known in both the LHS and RHS. RHSKnownOne &= LHSKnownOne; RHSKnownZero &= LHSKnownZero; break; case Instruction::Trunc: { - uint32_t truncBf = - cast(I->getOperand(0)->getType())->getBitWidth(); + unsigned truncBf = I->getOperand(0)->getType()->getPrimitiveSizeInBits(); DemandedMask.zext(truncBf); RHSKnownZero.zext(truncBf); RHSKnownOne.zext(truncBf); - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; + return I; DemandedMask.trunc(BitWidth); RHSKnownZero.trunc(BitWidth); RHSKnownOne.trunc(BitWidth); - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); break; } case Instruction::BitCast: if (!I->getOperand(0)->getType()->isInteger()) - return false; - - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + return false; // vector->int or fp->int? + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); break; case Instruction::ZExt: { // Compute the bits in the result that are not present in the input. - const IntegerType *SrcTy = cast(I->getOperand(0)->getType()); - uint32_t SrcBitWidth = SrcTy->getBitWidth(); + unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits(); DemandedMask.trunc(SrcBitWidth); RHSKnownZero.trunc(SrcBitWidth); RHSKnownOne.trunc(SrcBitWidth); - if (SimplifyDemandedBits(I->getOperand(0), DemandedMask, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMask, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; + return I; DemandedMask.zext(BitWidth); RHSKnownZero.zext(BitWidth); RHSKnownOne.zext(BitWidth); - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); // The top bits are known to be zero. RHSKnownZero |= APInt::getHighBitsSet(BitWidth, BitWidth - SrcBitWidth); break; } case Instruction::SExt: { // Compute the bits in the result that are not present in the input. - const IntegerType *SrcTy = cast(I->getOperand(0)->getType()); - uint32_t SrcBitWidth = SrcTy->getBitWidth(); + unsigned SrcBitWidth =I->getOperand(0)->getType()->getPrimitiveSizeInBits(); APInt InputDemandedBits = DemandedMask & APInt::getLowBitsSet(BitWidth, SrcBitWidth); @@ -1038,25 +1038,23 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, InputDemandedBits.trunc(SrcBitWidth); RHSKnownZero.trunc(SrcBitWidth); RHSKnownOne.trunc(SrcBitWidth); - if (SimplifyDemandedBits(I->getOperand(0), InputDemandedBits, + if (SimplifyDemandedBits(I->getOperandUse(0), InputDemandedBits, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; + return I; InputDemandedBits.zext(BitWidth); RHSKnownZero.zext(BitWidth); RHSKnownOne.zext(BitWidth); - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); // If the sign bit of the input is known set or clear, then we know the // top bits of the result. // If the input sign bit is known zero, or if the NewBits are not demanded // convert this into a zero extension. - if (RHSKnownZero[SrcBitWidth-1] || (NewBits & ~DemandedMask) == NewBits) - { + if (RHSKnownZero[SrcBitWidth-1] || (NewBits & ~DemandedMask) == NewBits) { // Convert to ZExt cast - CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName(), I); - return UpdateValueUsesWith(I, NewCast); + CastInst *NewCast = new ZExtInst(I->getOperand(0), VTy, I->getName()); + return InsertNewInstBefore(NewCast, *I); } else if (RHSKnownOne[SrcBitWidth-1]) { // Input sign bit known set RHSKnownOne |= NewBits; } @@ -1066,7 +1064,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // Figure out what the input bits are. If the top bits of the and result // are not demanded, then the add doesn't demand them from its input // either. - uint32_t NLZ = DemandedMask.countLeadingZeros(); + unsigned NLZ = DemandedMask.countLeadingZeros(); // If there is a constant on the RHS, there are a variety of xformations // we can do. @@ -1081,14 +1079,14 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, APInt InDemandedBits(APInt::getLowBitsSet(BitWidth, BitWidth - NLZ)); // Find information about known zero/one bits in the input. - if (SimplifyDemandedBits(I->getOperand(0), InDemandedBits, + if (SimplifyDemandedBits(I->getOperandUse(0), InDemandedBits, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; + return I; // If the RHS of the add has bits set that can't affect the input, reduce // the constant. if (ShrinkDemandedConstant(I, 1, InDemandedBits)) - return UpdateValueUsesWith(I, I); + return I; // Avoid excess work. if (LHSKnownZero == 0 && LHSKnownOne == 0) @@ -1099,8 +1097,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, Instruction *Or = BinaryOperator::CreateOr(I->getOperand(0), I->getOperand(1), I->getName()); - InsertNewInstBefore(Or, *I); - return UpdateValueUsesWith(I, Or); + return InsertNewInstBefore(Or, *I); } // We can say something about the output known-zero and known-one bits, @@ -1112,7 +1109,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // To compute this, we first compute the potential carry bits. These are // the bits which may be modified. I'm not aware of a better way to do // this scan. - const APInt& RHSVal = RHS->getValue(); + const APInt &RHSVal = RHS->getValue(); APInt CarryBits((~LHSKnownZero + RHSVal) ^ (~LHSKnownZero ^ RHSVal)); // Now that we know which bits have carries, compute the known-1/0 sets. @@ -1132,12 +1129,11 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // Right fill the mask of bits for this ADD to demand the most // significant bit and all those below it. APInt DemandedFromOps(APInt::getLowBitsSet(BitWidth, BitWidth-NLZ)); - if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedFromOps, + LHSKnownZero, LHSKnownOne, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(1), DemandedFromOps, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; - if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps, - LHSKnownZero, LHSKnownOne, Depth+1)) - return true; + return I; } } break; @@ -1150,12 +1146,11 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // significant bit and all those below it. uint32_t NLZ = DemandedMask.countLeadingZeros(); APInt DemandedFromOps(APInt::getLowBitsSet(BitWidth, BitWidth-NLZ)); - if (SimplifyDemandedBits(I->getOperand(0), DemandedFromOps, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedFromOps, + LHSKnownZero, LHSKnownOne, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(1), DemandedFromOps, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; - if (SimplifyDemandedBits(I->getOperand(1), DemandedFromOps, - LHSKnownZero, LHSKnownOne, Depth+1)) - return true; + return I; } // Otherwise just hand the sub off to ComputeMaskedBits to fill in // the known zeros and ones. @@ -1165,11 +1160,10 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { uint64_t ShiftAmt = SA->getLimitedValue(BitWidth); APInt DemandedMaskIn(DemandedMask.lshr(ShiftAmt)); - if (SimplifyDemandedBits(I->getOperand(0), DemandedMaskIn, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); RHSKnownZero <<= ShiftAmt; RHSKnownOne <<= ShiftAmt; // low bits known zero. @@ -1184,11 +1178,10 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // Unsigned shift right. APInt DemandedMaskIn(DemandedMask.shl(ShiftAmt)); - if (SimplifyDemandedBits(I->getOperand(0), DemandedMaskIn, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt); RHSKnownOne = APIntOps::lshr(RHSKnownOne, ShiftAmt); if (ShiftAmt) { @@ -1205,16 +1198,15 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // the shift amount is >= the size of the datatype, which is undefined. if (DemandedMask == 1) { // Perform the logical shift right. - Value *NewVal = BinaryOperator::CreateLShr( + Instruction *NewVal = BinaryOperator::CreateLShr( I->getOperand(0), I->getOperand(1), I->getName()); - InsertNewInstBefore(cast(NewVal), *I); - return UpdateValueUsesWith(I, NewVal); + return InsertNewInstBefore(NewVal, *I); } // If the sign bit is the only bit demanded by this ashr, then there is no // need to do it, the shift doesn't change the high bit. if (DemandedMask.isSignBit()) - return UpdateValueUsesWith(I, I->getOperand(0)); + return I->getOperand(0); if (ConstantInt *SA = dyn_cast(I->getOperand(1))) { uint32_t ShiftAmt = SA->getLimitedValue(BitWidth); @@ -1225,12 +1217,10 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // demanded. if (DemandedMask.countLeadingZeros() <= ShiftAmt) DemandedMaskIn.set(BitWidth-1); - if (SimplifyDemandedBits(I->getOperand(0), - DemandedMaskIn, + if (SimplifyDemandedBits(I->getOperandUse(0), DemandedMaskIn, RHSKnownZero, RHSKnownOne, Depth+1)) - return true; - assert((RHSKnownZero & RHSKnownOne) == 0 && - "Bits known to be one AND zero?"); + return I; + assert(!(RHSKnownZero & RHSKnownOne) && "Bits known to be one AND zero?"); // Compute the new bits that are at the top now. APInt HighBits(APInt::getHighBitsSet(BitWidth, ShiftAmt)); RHSKnownZero = APIntOps::lshr(RHSKnownZero, ShiftAmt); @@ -1246,10 +1236,9 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, if (BitWidth <= ShiftAmt || RHSKnownZero[BitWidth-ShiftAmt-1] || (HighBits & ~DemandedMask) == HighBits) { // Perform the logical shift right. - Value *NewVal = BinaryOperator::CreateLShr( + Instruction *NewVal = BinaryOperator::CreateLShr( I->getOperand(0), SA, I->getName()); - InsertNewInstBefore(cast(NewVal), *I); - return UpdateValueUsesWith(I, NewVal); + return InsertNewInstBefore(NewVal, *I); } else if ((RHSKnownOne & SignBit) != 0) { // New bits are known one. RHSKnownOne |= HighBits; } @@ -1260,35 +1249,33 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, APInt RA = Rem->getValue().abs(); if (RA.isPowerOf2()) { if (DemandedMask.ule(RA)) // srem won't affect demanded bits - return UpdateValueUsesWith(I, I->getOperand(0)); + return I->getOperand(0); APInt LowBits = RA - 1; APInt Mask2 = LowBits | APInt::getSignBit(BitWidth); - if (SimplifyDemandedBits(I->getOperand(0), Mask2, + if (SimplifyDemandedBits(I->getOperandUse(0), Mask2, LHSKnownZero, LHSKnownOne, Depth+1)) - return true; + return I; if (LHSKnownZero[BitWidth-1] || ((LHSKnownZero & LowBits) == LowBits)) LHSKnownZero |= ~LowBits; KnownZero |= LHSKnownZero & DemandedMask; - assert((KnownZero & KnownOne) == 0&&"Bits known to be one AND zero?"); + assert(!(KnownZero & KnownOne) && "Bits known to be one AND zero?"); } } break; case Instruction::URem: { APInt KnownZero2(BitWidth, 0), KnownOne2(BitWidth, 0); APInt AllOnes = APInt::getAllOnesValue(BitWidth); - if (SimplifyDemandedBits(I->getOperand(0), AllOnes, + if (SimplifyDemandedBits(I->getOperandUse(0), AllOnes, + KnownZero2, KnownOne2, Depth+1) || + SimplifyDemandedBits(I->getOperandUse(1), AllOnes, KnownZero2, KnownOne2, Depth+1)) - return true; + return I; unsigned Leaders = KnownZero2.countLeadingOnes(); - if (SimplifyDemandedBits(I->getOperand(1), AllOnes, - KnownZero2, KnownOne2, Depth+1)) - return true; - Leaders = std::max(Leaders, KnownZero2.countLeadingOnes()); KnownZero = APInt::getHighBitsSet(BitWidth, Leaders) & DemandedMask; @@ -1324,8 +1311,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, NewVal = BinaryOperator::CreateShl(I->getOperand(1), ConstantInt::get(I->getType(), ResultBit-InputBit)); NewVal->takeName(I); - InsertNewInstBefore(NewVal, *I); - return UpdateValueUsesWith(I, NewVal); + return InsertNewInstBefore(NewVal, *I); } // TODO: Could compute known zero/one bits based on the input. @@ -1340,7 +1326,7 @@ bool InstCombiner::SimplifyDemandedBits(Value *V, APInt DemandedMask, // If the client is only demanding bits that we know, return the known // constant. if ((DemandedMask & (RHSKnownZero|RHSKnownOne)) == DemandedMask) - return UpdateValueUsesWith(I, ConstantInt::get(RHSKnownOne)); + return ConstantInt::get(RHSKnownOne); return false; } @@ -1993,12 +1979,8 @@ Instruction *InstCombiner::visitAdd(BinaryOperator &I) { // See if SimplifyDemandedBits can simplify this. This handles stuff like // (X & 254)+1 -> (X&254)|1 - if (!isa(I.getType())) { - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), - KnownZero, KnownOne)) - return &I; - } + if (!isa(I.getType()) && SimplifyDemandedInstructionBits(I)) + return &I; // zext(i1) - 1 -> select i1, 0, -1 if (ZExtInst *ZI = dyn_cast(LHS)) @@ -3002,10 +2984,7 @@ Instruction *InstCombiner::commonIRemTransforms(BinaryOperator &I) { } // See if we can fold away this rem instruction. - uint32_t BitWidth = cast(I.getType())->getBitWidth(); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), - KnownZero, KnownOne)) + if (SimplifyDemandedInstructionBits(I)) return &I; } } @@ -3786,10 +3765,7 @@ Instruction *InstCombiner::visitAnd(BinaryOperator &I) { // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. if (!isa(I.getType())) { - uint32_t BitWidth = cast(I.getType())->getBitWidth(); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), - KnownZero, KnownOne)) + if (SimplifyDemandedInstructionBits(I)) return &I; } else { if (ConstantVector *CP = dyn_cast(Op1)) { @@ -4496,10 +4472,7 @@ Instruction *InstCombiner::visitOr(BinaryOperator &I) { // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. if (!isa(I.getType())) { - uint32_t BitWidth = cast(I.getType())->getBitWidth(); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), - KnownZero, KnownOne)) + if (SimplifyDemandedInstructionBits(I)) return &I; } else if (isa(Op1)) { return ReplaceInstUsesWith(I, Op0); // X | <0,0> -> X @@ -4837,10 +4810,7 @@ Instruction *InstCombiner::visitXor(BinaryOperator &I) { // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. if (!isa(I.getType())) { - uint32_t BitWidth = cast(I.getType())->getBitWidth(); - APInt KnownZero(BitWidth, 0), KnownOne(BitWidth, 0); - if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(BitWidth), - KnownZero, KnownOne)) + if (SimplifyDemandedInstructionBits(I)) return &I; } else if (isa(Op1)) { return ReplaceInstUsesWith(I, Op0); // X ^ <0,0> -> X @@ -5826,7 +5796,7 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { bool UnusedBit; bool isSignBit = isSignBitCheck(I.getPredicate(), CI, UnusedBit); - if (SimplifyDemandedBits(Op0, + if (SimplifyDemandedBits(I.getOperandUse(0), isSignBit ? APInt::getSignBit(BitWidth) : APInt::getAllOnesValue(BitWidth), KnownZero, KnownOne, 0)) @@ -6995,9 +6965,7 @@ Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. uint32_t TypeBits = Op0->getType()->getPrimitiveSizeInBits(); - APInt KnownZero(TypeBits, 0), KnownOne(TypeBits, 0); - if (SimplifyDemandedBits(&I, APInt::getAllOnesValue(TypeBits), - KnownZero, KnownOne)) + if (SimplifyDemandedInstructionBits(I)) return &I; // shl uint X, 32 = 0 and shr ubyte Y, 9 = 0, ... just don't eliminate shr @@ -7828,9 +7796,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { // See if we can simplify any instructions used by the LHS whose sole // purpose is to compute bits we don't care about. - APInt KnownZero(DestBitSize, 0), KnownOne(DestBitSize, 0); - if (SimplifyDemandedBits(&CI, APInt::getAllOnesValue(DestBitSize), - KnownZero, KnownOne)) + if (SimplifyDemandedInstructionBits(CI)) return &CI; // If the source isn't an instruction or has more than one use then we -- GitLab From 3e2cb66c562006bc307b5bccc4f44df9e9937b43 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 08:24:16 +0000 Subject: [PATCH 577/682] simplify/clarify control flow and improve comments, no functionality change. llvm-svn: 63480 --- .../Scalar/InstructionCombining.cpp | 34 ++++++++++++------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 186d8378a497..f6679452e194 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -817,22 +817,30 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, if (isa(V)) return 0; return UndefValue::get(VTy); - } else if (!V->hasOneUse()) { // Other users may use these bits. - if (Depth != 0) { // Not at the root. - // Just compute the KnownZero/KnownOne bits to simplify things downstream. - ComputeMaskedBits(V, DemandedMask, KnownZero, KnownOne, Depth); - return 0; - } - // If this is the root being simplified, allow it to have multiple uses, - // just set the DemandedMask to all bits. - DemandedMask = APInt::getAllOnesValue(BitWidth); - } else if (Depth == 6) { // Limit search depth. - return 0; } + if (Depth == 6) // Limit search depth. + return 0; + Instruction *I = dyn_cast(V); if (!I) return 0; // Only analyze instructions. - + + // If there are multiple uses of this value and we aren't at the root, then + // we can't do any simplifications of the operands, because DemandedMask + // only reflects the bits demanded by *one* of the users. + if (Depth != 0 && !I->hasOneUse()) { + // Compute the KnownZero/KnownOne bits to simplify things downstream. + ComputeMaskedBits(I, DemandedMask, KnownZero, KnownOne, Depth); + return 0; + } + + // If this is the root being simplified, allow it to have multiple uses, + // just set the DemandedMask to all bits so that we can try to simplify the + // operands. This allows visitTruncInst (for example) to simplify the + // operand of a trunc without duplicating all the logic below. + if (Depth == 0 && !V->hasOneUse()) + DemandedMask = APInt::getAllOnesValue(BitWidth); + APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne; switch (I->getOpcode()) { @@ -6960,7 +6968,7 @@ Instruction *InstCombiner::commonShiftTransforms(BinaryOperator &I) { Instruction *InstCombiner::FoldShiftByConstant(Value *Op0, ConstantInt *Op1, BinaryOperator &I) { - bool isLeftShift = I.getOpcode() == Instruction::Shl; + bool isLeftShift = I.getOpcode() == Instruction::Shl; // See if we can simplify any instructions used by the instruction whose sole // purpose is to compute bits we don't care about. -- GitLab From 76a63ed0992d99dbd85649eb9d8336c6844b570e Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 08:40:03 +0000 Subject: [PATCH 578/682] now that all the pieces are in place, teach instcombine's simplifydemandedbits to simplify instructions with *multiple uses* in contexts where it can get away with it. This allows it to simplify the code in multi-use-or.ll into a single 'add double'. This change is particularly interesting because it will cover up for some common codegen bugs with large integers created due to the recent SROA patch. When working on fixing those bugs, this should be disabled. llvm-svn: 63481 --- .../Scalar/InstructionCombining.cpp | 60 ++++++++++++++++++- .../Transforms/InstCombine/multi-use-or.ll | 24 ++++++++ 2 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/multi-use-or.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index f6679452e194..2b0e0d1c9fae 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -825,10 +825,68 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, Instruction *I = dyn_cast(V); if (!I) return 0; // Only analyze instructions. + APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); + APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne; + // If there are multiple uses of this value and we aren't at the root, then // we can't do any simplifications of the operands, because DemandedMask // only reflects the bits demanded by *one* of the users. if (Depth != 0 && !I->hasOneUse()) { + // Despite the fact that we can't simplify this instruction in all User's + // context, we can at least compute the knownzero/knownone bits, and we can + // do simplifications that apply to *just* the one user if we know that + // this instruction has a simpler value in that context. + if (I->getOpcode() == Instruction::And) { + // If either the LHS or the RHS are Zero, the result is zero. + ComputeMaskedBits(I->getOperand(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1); + ComputeMaskedBits(I->getOperand(0), DemandedMask & ~RHSKnownZero, + LHSKnownZero, LHSKnownOne, Depth+1); + + // If all of the demanded bits are known 1 on one side, return the other. + // These bits cannot contribute to the result of the 'and' in this + // context. + if ((DemandedMask & ~LHSKnownZero & RHSKnownOne) == + (DemandedMask & ~LHSKnownZero)) + return I->getOperand(0); + if ((DemandedMask & ~RHSKnownZero & LHSKnownOne) == + (DemandedMask & ~RHSKnownZero)) + return I->getOperand(1); + + // If all of the demanded bits in the inputs are known zeros, return zero. + if ((DemandedMask & (RHSKnownZero|LHSKnownZero)) == DemandedMask) + return Constant::getNullValue(VTy); + + } else if (I->getOpcode() == Instruction::Or) { + // We can simplify (X|Y) -> X or Y in the user's context if we know that + // only bits from X or Y are demanded. + + // If either the LHS or the RHS are One, the result is One. + ComputeMaskedBits(I->getOperand(1), DemandedMask, + RHSKnownZero, RHSKnownOne, Depth+1); + ComputeMaskedBits(I->getOperand(0), DemandedMask & ~RHSKnownOne, + LHSKnownZero, LHSKnownOne, Depth+1); + + // If all of the demanded bits are known zero on one side, return the + // other. These bits cannot contribute to the result of the 'or' in this + // context. + if ((DemandedMask & ~LHSKnownOne & RHSKnownZero) == + (DemandedMask & ~LHSKnownOne)) + return I->getOperand(0); + if ((DemandedMask & ~RHSKnownOne & LHSKnownZero) == + (DemandedMask & ~RHSKnownOne)) + return I->getOperand(1); + + // If all of the potentially set bits on one side are known to be set on + // the other side, just use the 'other' side. + if ((DemandedMask & (~RHSKnownZero) & LHSKnownOne) == + (DemandedMask & (~RHSKnownZero))) + return I->getOperand(0); + if ((DemandedMask & (~LHSKnownZero) & RHSKnownOne) == + (DemandedMask & (~LHSKnownZero))) + return I->getOperand(1); + } + // Compute the KnownZero/KnownOne bits to simplify things downstream. ComputeMaskedBits(I, DemandedMask, KnownZero, KnownOne, Depth); return 0; @@ -841,8 +899,6 @@ Value *InstCombiner::SimplifyDemandedUseBits(Value *V, APInt DemandedMask, if (Depth == 0 && !V->hasOneUse()) DemandedMask = APInt::getAllOnesValue(BitWidth); - APInt LHSKnownZero(BitWidth, 0), LHSKnownOne(BitWidth, 0); - APInt &RHSKnownZero = KnownZero, &RHSKnownOne = KnownOne; switch (I->getOpcode()) { default: ComputeMaskedBits(I, DemandedMask, RHSKnownZero, RHSKnownOne, Depth); diff --git a/llvm/test/Transforms/InstCombine/multi-use-or.ll b/llvm/test/Transforms/InstCombine/multi-use-or.ll new file mode 100644 index 000000000000..85a8b34e2f6e --- /dev/null +++ b/llvm/test/Transforms/InstCombine/multi-use-or.ll @@ -0,0 +1,24 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {add double .sx, .sy} +; The 'or' has multiple uses, make sure that this doesn't prevent instcombine +; from propagating the extends to the truncs. + +define double @ScaleObjectAdd(double %sx, double %sy, double %sz) nounwind { +entry: + %sx34 = bitcast double %sx to i64 ; [#uses=1] + %sx3435 = zext i64 %sx34 to i192 ; [#uses=1] + %sy22 = bitcast double %sy to i64 ; [#uses=1] + %sy2223 = zext i64 %sy22 to i192 ; [#uses=1] + %sy222324 = shl i192 %sy2223, 128 ; [#uses=1] + %sy222324.ins = or i192 %sx3435, %sy222324 ; [#uses=1] + + + %a = trunc i192 %sy222324.ins to i64 ; [#uses=1] + %b = bitcast i64 %a to double ; [#uses=1] + %c = lshr i192 %sy222324.ins, 128 ; [#uses=1] + %d = trunc i192 %c to i64 ; [#uses=1] + %e = bitcast i64 %d to double ; [#uses=1] + %f = add double %b, %e + +; ret double %e + ret double %f +} -- GitLab From 41826036b14c224f6ae76cc3b8a89c4109214c79 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Sat, 31 Jan 2009 15:50:11 +0000 Subject: [PATCH 579/682] Fix PR3401: when using large integers, the type returned by getShiftAmountTy may be too small to hold shift values (it is an i8 on x86-32). Before and during type legalization, use a large but legal type for shift amounts: getPointerTy; afterwards use getShiftAmountTy, fixing up any shift amounts with a big type during operation legalization. Thanks to Dan for writing the original patch (which I shamelessly pillaged). llvm-svn: 63482 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 4 ++ llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 42 +++++++++------- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 45 ++++++++--------- .../SelectionDAG/LegalizeIntegerTypes.cpp | 48 +++++++++---------- .../CodeGen/SelectionDAG/LegalizeTypes.cpp | 7 ++- .../SelectionDAG/LegalizeVectorTypes.cpp | 5 -- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 14 ++++-- .../SelectionDAG/SelectionDAGBuild.cpp | 32 ++++++------- .../CodeGen/SelectionDAG/TargetLowering.cpp | 8 ++-- llvm/test/CodeGen/X86/2009-01-31-BigShift.ll | 9 ++++ llvm/test/CodeGen/X86/2009-01-31-BigShift2.ll | 11 +++++ llvm/test/CodeGen/X86/2009-01-31-BigShift3.ll | 31 ++++++++++++ 12 files changed, 155 insertions(+), 101 deletions(-) create mode 100644 llvm/test/CodeGen/X86/2009-01-31-BigShift.ll create mode 100644 llvm/test/CodeGen/X86/2009-01-31-BigShift2.ll create mode 100644 llvm/test/CodeGen/X86/2009-01-31-BigShift3.ll diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index f8be1679e7e4..4937df79b999 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -636,6 +636,10 @@ public: /// through the backend. SDValue getMemOperand(const MachineMemOperand &MO); + /// getShiftAmountOperand - Return the specified value casted to + /// the target's desired shift amount type. + SDValue getShiftAmountOperand(SDValue Op); + /// UpdateNodeOperands - *Mutate* the specified node in-place to have the /// specified operands. If the resultant node already exists in the DAG, /// this does not modify the specified node, instead it returns the node that diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 7240fb9a7175..1dbbf4f5a960 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -240,7 +240,13 @@ namespace { /// FindBetterChain - Walk up chain skipping non-aliasing memory nodes, /// looking for a better chain (aliasing node.) SDValue FindBetterChain(SDNode *N, SDValue Chain); - + + /// getShiftAmountTy - Returns a type large enough to hold any valid + /// shift amount - before type legalization these can be huge. + MVT getShiftAmountTy() { + return LegalTypes ? TLI.getShiftAmountTy() : TLI.getPointerTy(); + } + public: DAGCombiner(SelectionDAG &D, AliasAnalysis &A, bool fast) : DAG(D), @@ -1301,7 +1307,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { if (N1C && N1C->getAPIntValue().isPowerOf2()) return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, DAG.getConstant(N1C->getAPIntValue().logBase2(), - TLI.getShiftAmountTy())); + getShiftAmountTy())); // fold (mul x, -(1 << c)) -> -(x << c) or (-x) << c if (N1C && isPowerOf2_64(-N1C->getSExtValue())) // FIXME: If the input is something that is easily negated (e.g. a @@ -1310,7 +1316,7 @@ SDValue DAGCombiner::visitMUL(SDNode *N) { DAG.getConstant(0, VT), DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, DAG.getConstant(Log2_64(-N1C->getSExtValue()), - TLI.getShiftAmountTy()))); + getShiftAmountTy()))); // (mul (shl X, c1), c2) -> (mul X, c2 << c1) if (N1C && N0.getOpcode() == ISD::SHL && isa(N0.getOperand(1))) { @@ -1406,18 +1412,18 @@ SDValue DAGCombiner::visitSDIV(SDNode *N) { // Splat the sign bit into the register SDValue SGN = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0, DAG.getConstant(VT.getSizeInBits()-1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); AddToWorkList(SGN.getNode()); // Add (N0 < 0) ? abs2 - 1 : 0; SDValue SRL = DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, SGN, DAG.getConstant(VT.getSizeInBits() - lg2, - TLI.getShiftAmountTy())); + getShiftAmountTy())); SDValue ADD = DAG.getNode(ISD::ADD, N->getDebugLoc(), VT, N0, SRL); AddToWorkList(SRL.getNode()); AddToWorkList(ADD.getNode()); // Divide by pow2 SDValue SRA = DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, ADD, - DAG.getConstant(lg2, TLI.getShiftAmountTy())); + DAG.getConstant(lg2, getShiftAmountTy())); // If we're dividing by a positive value, we're done. Otherwise, we must // negate the result. @@ -1467,7 +1473,7 @@ SDValue DAGCombiner::visitUDIV(SDNode *N) { if (N1C && N1C->getAPIntValue().isPowerOf2()) return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, DAG.getConstant(N1C->getAPIntValue().logBase2(), - TLI.getShiftAmountTy())); + getShiftAmountTy())); // fold (udiv x, (shl c, y)) -> x >>u (log2(c)+y) iff c is power of 2 if (N1.getOpcode() == ISD::SHL) { if (ConstantSDNode *SHC = dyn_cast(N1.getOperand(0))) { @@ -1607,7 +1613,7 @@ SDValue DAGCombiner::visitMULHS(SDNode *N) { if (N1C && N1C->getAPIntValue() == 1) return DAG.getNode(ISD::SRA, N->getDebugLoc(), N0.getValueType(), N0, DAG.getConstant(N0.getValueType().getSizeInBits() - 1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); // fold (mulhs x, undef) -> 0 if (N0.getOpcode() == ISD::UNDEF || N1.getOpcode() == ISD::UNDEF) return DAG.getConstant(0, VT); @@ -2613,7 +2619,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { TLI.isOperationLegalOrCustom(ISD::TRUNCATE, VT) && TLI.isTruncateFree(VT, TruncVT)) { - SDValue Amt = DAG.getConstant(ShiftAmt, TLI.getShiftAmountTy()); + SDValue Amt = DAG.getConstant(ShiftAmt, getShiftAmountTy()); SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, N0.getOperand(0), Amt); SDValue Trunc = DAG.getNode(ISD::TRUNCATE, N0.getDebugLoc(), TruncVT, @@ -2740,7 +2746,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (ShAmt) { Op = DAG.getNode(ISD::SRL, N0.getDebugLoc(), VT, Op, - DAG.getConstant(ShAmt, TLI.getShiftAmountTy())); + DAG.getConstant(ShAmt, getShiftAmountTy())); AddToWorkList(Op.getNode()); } @@ -5722,7 +5728,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, if (N2C && ((N2C->getAPIntValue() & (N2C->getAPIntValue()-1)) == 0)) { unsigned ShCtV = N2C->getAPIntValue().logBase2(); ShCtV = XType.getSizeInBits()-ShCtV-1; - SDValue ShCt = DAG.getConstant(ShCtV, TLI.getShiftAmountTy()); + SDValue ShCt = DAG.getConstant(ShCtV, getShiftAmountTy()); SDValue Shift = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0, ShCt); AddToWorkList(Shift.getNode()); @@ -5738,7 +5744,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); AddToWorkList(Shift.getNode()); if (XType.bitsGT(AType)) { @@ -5787,7 +5793,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, // shl setcc result by log2 n2c return DAG.getNode(ISD::SHL, DL, N2.getValueType(), Temp, DAG.getConstant(N2C->getAPIntValue().logBase2(), - TLI.getShiftAmountTy())); + getShiftAmountTy())); } // Check to see if this is the equivalent of setcc @@ -5810,7 +5816,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Ctlz = DAG.getNode(ISD::CTLZ, N0.getDebugLoc(), XType, N0); return DAG.getNode(ISD::SRL, DL, XType, Ctlz, DAG.getConstant(Log2_32(XType.getSizeInBits()), - TLI.getShiftAmountTy())); + getShiftAmountTy())); } // fold (setgt X, 0) -> (srl (and (-X, ~X), size(X)-1)) if (N1C && N1C->isNullValue() && CC == ISD::SETGT) { @@ -5820,13 +5826,13 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, return DAG.getNode(ISD::SRL, DL, XType, DAG.getNode(ISD::AND, XType, NegN0, NotN0), DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); } // fold (setgt X, -1) -> (xor (srl (X, size(X)-1), 1)) if (N1C && N1C->isAllOnesValue() && CC == ISD::SETGT) { SDValue Sign = DAG.getNode(ISD::SRL, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); return DAG.getNode(ISD::XOR, DL, XType, Sign, DAG.getConstant(1, XType)); } } @@ -5839,7 +5845,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, MVT XType = N0.getValueType(); SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType, N0, Shift); AddToWorkList(Shift.getNode()); @@ -5856,7 +5862,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, SDValue Shift = DAG.getNode(ISD::SRA, N0.getDebugLoc(), XType, N0, DAG.getConstant(XType.getSizeInBits()-1, - TLI.getShiftAmountTy())); + getShiftAmountTy())); SDValue Add = DAG.getNode(ISD::ADD, N0.getDebugLoc(), XType, N0, Shift); AddToWorkList(Shift.getNode()); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 71fce0decfa1..4dd5dd254249 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -301,9 +301,6 @@ private: SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op); SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op); - - // Returns the legalized (truncated or extended) shift amount. - SDValue LegalizeShiftAmount(SDValue ShiftAmt); }; } @@ -903,8 +900,10 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { case ISD::SHL: case ISD::SRA: case ISD::SRL: + case ISD::ROTL: + case ISD::ROTR: Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Operands[0], - LegalizeShiftAmount(Operands[1]))); + DAG.getShiftAmountOperand(Operands[1]))); break; } } @@ -969,16 +968,6 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) { PseudoSourceValue::getFixedStack(SPFI), 0); } -SDValue SelectionDAGLegalize::LegalizeShiftAmount(SDValue ShiftAmt) { - if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType())) - return DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt); - - if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType())) - return DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), ShiftAmt); - - return ShiftAmt; -} - /// LegalizeOp - We know that the specified value has a legal type, and /// that its operands are legal. Now ensure that the operation itself @@ -3137,10 +3126,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::SRL_PARTS: { SmallVector Ops; bool Changed = false; - for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { + unsigned N = Node->getNumOperands(); + for (unsigned i = 0; i + 1 < N; ++i) { Ops.push_back(LegalizeOp(Node->getOperand(i))); Changed |= Ops.back() != Node->getOperand(i); } + Ops.push_back(LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(N-1)))); + Changed |= Ops.back() != Node->getOperand(N-1); if (Changed) Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); @@ -3191,23 +3183,24 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::FDIV: case ISD::FPOW: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS - switch (getTypeAction(Node->getOperand(1).getValueType())) { + Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS + + if ((Node->getOpcode() == ISD::SHL || + Node->getOpcode() == ISD::SRL || + Node->getOpcode() == ISD::SRA) && + !Node->getValueType(0).isVector()) + Tmp2 = DAG.getShiftAmountOperand(Tmp2); + + switch (getTypeAction(Tmp2.getValueType())) { case Expand: assert(0 && "Not possible"); case Legal: - Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS. + Tmp2 = LegalizeOp(Tmp2); // Legalize the RHS. break; case Promote: - Tmp2 = PromoteOp(Node->getOperand(1)); // Promote the RHS. + Tmp2 = PromoteOp(Tmp2); // Promote the RHS. break; } - if ((Node->getOpcode() == ISD::SHL || - Node->getOpcode() == ISD::SRL || - Node->getOpcode() == ISD::SRA) && - !Node->getValueType(0).isVector()) { - Tmp2 = LegalizeShiftAmount(Tmp2); - } - Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { @@ -3673,7 +3666,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::ROTL: case ISD::ROTR: Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS - Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS + Tmp2 = LegalizeOp(DAG.getShiftAmountOperand(Node->getOperand(1))); // RHS Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { default: diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index fac80a61496d..f28da3586934 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -230,7 +230,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) { unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); return DAG.getNode(ISD::SRL, dl, NVT, DAG.getNode(ISD::BSWAP, dl, NVT, Op), - DAG.getConstant(DiffBits, TLI.getShiftAmountTy())); + DAG.getConstant(DiffBits, TLI.getPointerTy())); } SDValue DAGTypeLegalizer::PromoteIntRes_BUILD_PAIR(SDNode *N) { @@ -327,7 +327,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { // Extract the element at OldIdx / 2 from the new vector. SDValue OldIdx = N->getOperand(1); SDValue NewIdx = DAG.getNode(ISD::SRL, dl, OldIdx.getValueType(), OldIdx, - DAG.getConstant(1, TLI.getShiftAmountTy())); + DAG.getConstant(1, TLI.getPointerTy())); SDValue Elt = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, NewIdx); // Select the appropriate half of the element: Lo if OldIdx was even, @@ -335,7 +335,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_EXTRACT_VECTOR_ELT(SDNode *N) { SDValue Lo = Elt; SDValue Hi = DAG.getNode(ISD::SRL, dl, NewVT, Elt, DAG.getConstant(OldVT.getSizeInBits(), - TLI.getShiftAmountTy())); + TLI.getPointerTy())); if (TLI.isBigEndian()) std::swap(Lo, Hi); @@ -621,7 +621,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_VAARG(SDNode *N) { // Shift it to the right position and "or" it in. Part = DAG.getNode(ISD::SHL, dl, NVT, Part, DAG.getConstant(i * RegVT.getSizeInBits(), - TLI.getShiftAmountTy())); + TLI.getPointerTy())); Res = DAG.getNode(ISD::OR, dl, NVT, Res, Part); } @@ -768,8 +768,7 @@ SDValue DAGTypeLegalizer::PromoteIntOp_BUILD_PAIR(SDNode *N) { DebugLoc dl = N->getDebugLoc(); Hi = DAG.getNode(ISD::SHL, dl, N->getValueType(0), Hi, - DAG.getConstant(OVT.getSizeInBits(), - TLI.getShiftAmountTy())); + DAG.getConstant(OVT.getSizeInBits(), TLI.getPointerTy())); return DAG.getNode(ISD::OR, dl, N->getValueType(0), Lo, Hi); } @@ -1329,7 +1328,7 @@ void DAGTypeLegalizer::ExpandIntRes_AssertSext(SDNode *N, Lo = DAG.getNode(ISD::AssertSext, dl, NVT, Lo, DAG.getValueType(EVT)); // The high part replicates the sign bit of Lo, make it explicit. Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, - DAG.getConstant(NVTBits-1, TLI.getShiftAmountTy())); + DAG.getConstant(NVTBits-1, TLI.getPointerTy())); } } @@ -1473,7 +1472,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, // lo part. unsigned LoSize = Lo.getValueType().getSizeInBits(); Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); + DAG.getConstant(LoSize-1, TLI.getPointerTy())); } else if (ExtType == ISD::ZEXTLOAD) { // The high part is just a zero. Hi = DAG.getConstant(0, NVT); @@ -1535,12 +1534,12 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, Lo = DAG.getNode(ISD::OR, dl, NVT, Lo, DAG.getNode(ISD::SHL, dl, NVT, Hi, DAG.getConstant(ExcessBits, - TLI.getShiftAmountTy()))); + TLI.getPointerTy()))); // Move high bits to the right position in Hi. Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, NVT, Hi, DAG.getConstant(NVT.getSizeInBits() - ExcessBits, - TLI.getShiftAmountTy())); + TLI.getPointerTy())); } } @@ -1762,7 +1761,7 @@ void DAGTypeLegalizer::ExpandIntRes_SIGN_EXTEND(SDNode *N, // The high part is obtained by SRA'ing all but one of the bits of low part. unsigned LoSize = NVT.getSizeInBits(); Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, - DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); + DAG.getConstant(LoSize-1, TLI.getPointerTy())); } else { // For example, extension of an i48 to an i64. The operand type necessarily // promotes to the result type, so will end up being expanded too. @@ -1795,7 +1794,7 @@ ExpandIntRes_SIGN_EXTEND_INREG(SDNode *N, SDValue &Lo, SDValue &Hi) { // things like sextinreg V:i64 from i8. Hi = DAG.getNode(ISD::SRA, dl, Hi.getValueType(), Lo, DAG.getConstant(Hi.getValueType().getSizeInBits()-1, - TLI.getShiftAmountTy())); + TLI.getPointerTy())); } else { // For example, extension of an i48 to an i64. Leave the low part alone, // sext_inreg the high part. @@ -1831,8 +1830,7 @@ void DAGTypeLegalizer::ExpandIntRes_TRUNCATE(SDNode *N, Lo = DAG.getNode(ISD::TRUNCATE, dl, NVT, N->getOperand(0)); Hi = DAG.getNode(ISD::SRL, dl, N->getOperand(0).getValueType(), N->getOperand(0), - DAG.getConstant(NVT.getSizeInBits(), - TLI.getShiftAmountTy())); + DAG.getConstant(NVT.getSizeInBits(), TLI.getPointerTy())); Hi = DAG.getNode(ISD::TRUNCATE, dl, NVT, Hi); } @@ -1922,20 +1920,18 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { assert(0 && "Do not know how to expand this operator's operand!"); abort(); - case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; case ISD::BIT_CONVERT: Res = ExpandOp_BIT_CONVERT(N); break; + case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; + case ISD::BUILD_VECTOR: Res = ExpandOp_BUILD_VECTOR(N); break; case ISD::EXTRACT_ELEMENT: Res = ExpandOp_EXTRACT_ELEMENT(N); break; case ISD::INSERT_VECTOR_ELT: Res = ExpandOp_INSERT_VECTOR_ELT(N); break; case ISD::SCALAR_TO_VECTOR: Res = ExpandOp_SCALAR_TO_VECTOR(N); break; - - case ISD::BR_CC: Res = ExpandIntOp_BR_CC(N); break; - case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break; - case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; - case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break; - case ISD::STORE: Res = ExpandIntOp_STORE(cast(N), OpNo); - break; - case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; - case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; + case ISD::SELECT_CC: Res = ExpandIntOp_SELECT_CC(N); break; + case ISD::SETCC: Res = ExpandIntOp_SETCC(N); break; + case ISD::SINT_TO_FP: Res = ExpandIntOp_SINT_TO_FP(N); break; + case ISD::STORE: Res = ExpandIntOp_STORE(cast(N), OpNo); break; + case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; + case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; } // If the result is null, the sub-method took care of registering results etc. @@ -2175,11 +2171,11 @@ SDValue DAGTypeLegalizer::ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo) { // Transfer high bits from the top of Lo to the bottom of Hi. Hi = DAG.getNode(ISD::SHL, dl, NVT, Hi, DAG.getConstant(NVT.getSizeInBits() - ExcessBits, - TLI.getShiftAmountTy())); + TLI.getPointerTy())); Hi = DAG.getNode(ISD::OR, dl, NVT, Hi, DAG.getNode(ISD::SRL, NVT, Lo, DAG.getConstant(ExcessBits, - TLI.getShiftAmountTy()))); + TLI.getPointerTy()))); } // Store both the high bits and maybe some of the low bits. diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index c88fd5d1dd83..3e79ecb50c5c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -942,8 +942,8 @@ SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Lo); Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, Hi); - Hi = DAG.getNode(ISD::SHL, NVT, Hi, DAG.getConstant(LVT.getSizeInBits(), - TLI.getShiftAmountTy())); + Hi = DAG.getNode(ISD::SHL, NVT, Hi, + DAG.getConstant(LVT.getSizeInBits(), TLI.getPointerTy())); return DAG.getNode(ISD::OR, NVT, Lo, Hi); } @@ -1028,8 +1028,7 @@ void DAGTypeLegalizer::SplitInteger(SDValue Op, Op.getValueType().getSizeInBits() && "Invalid integer splitting!"); Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op); Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, - DAG.getConstant(LoVT.getSizeInBits(), - TLI.getShiftAmountTy())); + DAG.getConstant(LoVT.getSizeInBits(), TLI.getPointerTy())); Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi); } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index 128dc3351e4c..ac814f285761 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -111,11 +111,6 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) { SDValue DAGTypeLegalizer::ScalarizeVecRes_ShiftOp(SDNode *N) { SDValue LHS = GetScalarizedVector(N->getOperand(0)); SDValue ShiftAmt = GetScalarizedVector(N->getOperand(1)); - if (TLI.getShiftAmountTy().bitsLT(ShiftAmt.getValueType())) - ShiftAmt = DAG.getNode(ISD::TRUNCATE, TLI.getShiftAmountTy(), ShiftAmt); - else if (TLI.getShiftAmountTy().bitsGT(ShiftAmt.getValueType())) - ShiftAmt = DAG.getNode(ISD::ZERO_EXTEND, TLI.getShiftAmountTy(), ShiftAmt); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, ShiftAmt); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index f5287b0cf2c5..1b0d61ca0a73 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1287,6 +1287,17 @@ SDValue SelectionDAG::getMemOperand(const MachineMemOperand &MO) { return SDValue(N, 0); } +/// getShiftAmountOperand - Return the specified value casted to +/// the target's desired shift amount type. +SDValue SelectionDAG::getShiftAmountOperand(SDValue Op) { + MVT OpTy = Op.getValueType(); + MVT ShTy = TLI.getShiftAmountTy(); + if (OpTy == ShTy || OpTy.isVector()) return Op; + + ISD::NodeType Opcode = OpTy.bitsGT(ShTy) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; + return getNode(Opcode, ShTy, Op); +} + /// CreateStackTemporary - Create a stack temporary, suitable for holding the /// specified value type. SDValue SelectionDAG::CreateStackTemporary(MVT VT, unsigned minAlign) { @@ -2529,9 +2540,6 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, "Shift operators return type must be the same as their first arg"); assert(VT.isInteger() && N2.getValueType().isInteger() && "Shifts only work on integers"); - assert((N2.getValueType() == TLI.getShiftAmountTy() || - (N2.getValueType().isVector() && N2.getValueType().isInteger())) && - "Wrong type for shift amount"); // Always fold shifts of i1 values so the code generator doesn't need to // handle them. Since we know the size of the shift has to be less than the diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 024cb4b92f4e..9057775a5cdd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -427,7 +427,7 @@ static SDValue getCopyFromParts(SelectionDAG &DAG, DebugLoc dl, Hi = DAG.getNode(ISD::ANY_EXTEND, dl, TotalVT, Hi); Hi = DAG.getNode(ISD::SHL, dl, TotalVT, Hi, DAG.getConstant(Lo.getValueType().getSizeInBits(), - TLI.getShiftAmountTy())); + TLI.getPointerTy())); Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, TotalVT, Lo); Val = DAG.getNode(ISD::OR, dl, TotalVT, Lo, Hi); } @@ -587,7 +587,7 @@ static void getCopyToParts(SelectionDAG &DAG, DebugLoc dl, SDValue Val, unsigned OddParts = NumParts - RoundParts; SDValue OddVal = DAG.getNode(ISD::SRL, dl, ValueVT, Val, DAG.getConstant(RoundBits, - TLI.getShiftAmountTy())); + TLI.getPointerTy())); getCopyToParts(DAG, dl, OddVal, Parts + RoundParts, OddParts, PartVT); if (TLI.isBigEndian()) // The odd parts were reversed by getCopyToParts - unreverse them. @@ -1424,14 +1424,14 @@ void SelectionDAGLowering::visitBitTestHeader(BitTestBlock &B) { ISD::SETUGT); SDValue ShiftOp; - if (VT.bitsGT(TLI.getShiftAmountTy())) + if (VT.bitsGT(TLI.getPointerTy())) ShiftOp = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), - TLI.getShiftAmountTy(), SUB); + TLI.getPointerTy(), SUB); else ShiftOp = DAG.getNode(ISD::ZERO_EXTEND, getCurDebugLoc(), - TLI.getShiftAmountTy(), SUB); + TLI.getPointerTy(), SUB); - B.Reg = FuncInfo.MakeReg(TLI.getShiftAmountTy()); + B.Reg = FuncInfo.MakeReg(TLI.getPointerTy()); SDValue CopyTo = DAG.getCopyToReg(getControlRoot(), B.Reg, ShiftOp); // Set NextBlock to be the MBB immediately after the current one, if any. @@ -1463,7 +1463,7 @@ void SelectionDAGLowering::visitBitTestCase(MachineBasicBlock* NextMBB, BitTestCase &B) { // Make desired shift SDValue ShiftOp = DAG.getCopyFromReg(getControlRoot(), Reg, - TLI.getShiftAmountTy()); + TLI.getPointerTy()); SDValue SwitchVal = DAG.getNode(ISD::SHL, getCurDebugLoc(), TLI.getPointerTy(), DAG.getConstant(1, TLI.getPointerTy()), @@ -2121,12 +2121,12 @@ void SelectionDAGLowering::visitShift(User &I, unsigned Opcode) { SDValue Op1 = getValue(I.getOperand(0)); SDValue Op2 = getValue(I.getOperand(1)); if (!isa(I.getType())) { - if (TLI.getShiftAmountTy().bitsLT(Op2.getValueType())) + if (TLI.getPointerTy().bitsLT(Op2.getValueType())) Op2 = DAG.getNode(ISD::TRUNCATE, getCurDebugLoc(), - TLI.getShiftAmountTy(), Op2); - else if (TLI.getShiftAmountTy().bitsGT(Op2.getValueType())) + TLI.getPointerTy(), Op2); + else if (TLI.getPointerTy().bitsGT(Op2.getValueType())) Op2 = DAG.getNode(ISD::ANY_EXTEND, getCurDebugLoc(), - TLI.getShiftAmountTy(), Op2); + TLI.getPointerTy(), Op2); } setValue(&I, DAG.getNode(Opcode, getCurDebugLoc(), @@ -2673,7 +2673,7 @@ void SelectionDAGLowering::visitGetElementPtr(User &I) { unsigned Amt = Log2_64(ElementSize); IdxN = DAG.getNode(ISD::SHL, getCurDebugLoc(), N.getValueType(), IdxN, - DAG.getConstant(Amt, TLI.getShiftAmountTy())); + DAG.getConstant(Amt, TLI.getPointerTy())); } else { SDValue Scale = DAG.getIntPtrConstant(ElementSize); IdxN = DAG.getNode(ISD::MUL, getCurDebugLoc(), @@ -3023,7 +3023,7 @@ GetExponent(SelectionDAG &DAG, SDValue Op, const TargetLowering &TLI, SDValue t0 = DAG.getNode(ISD::AND, dl, MVT::i32, Op, DAG.getConstant(0x7f800000, MVT::i32)); SDValue t1 = DAG.getNode(ISD::SRL, dl, MVT::i32, t0, - DAG.getConstant(23, TLI.getShiftAmountTy())); + DAG.getConstant(23, TLI.getPointerTy())); SDValue t2 = DAG.getNode(ISD::SUB, dl, MVT::i32, t1, DAG.getConstant(127, MVT::i32)); return DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, t2); @@ -3095,7 +3095,7 @@ SelectionDAGLowering::visitExp(CallInst &I) { // IntegerPartOfX <<= 23; IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX, - DAG.getConstant(23, TLI.getShiftAmountTy())); + DAG.getConstant(23, TLI.getPointerTy())); if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: @@ -3535,7 +3535,7 @@ SelectionDAGLowering::visitExp2(CallInst &I) { // IntegerPartOfX <<= 23; IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX, - DAG.getConstant(23, TLI.getShiftAmountTy())); + DAG.getConstant(23, TLI.getPointerTy())); if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: @@ -3668,7 +3668,7 @@ SelectionDAGLowering::visitPow(CallInst &I) { // IntegerPartOfX <<= 23; IntegerPartOfX = DAG.getNode(ISD::SHL, dl, MVT::i32, IntegerPartOfX, - DAG.getConstant(23, TLI.getShiftAmountTy())); + DAG.getConstant(23, TLI.getPointerTy())); if (LimitFloatPrecision <= 6) { // For floating-point precision of 6: diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index ebc5067c7047..7d524753cd4c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -1651,19 +1651,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, VT == N0.getValueType() && N0.getOpcode() == ISD::AND) if (ConstantSDNode *AndRHS = dyn_cast(N0.getOperand(1))) { + MVT ShiftTy = DCI.isBeforeLegalize() ? + getPointerTy() : getShiftAmountTy(); if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3 // Perform the xform if the AND RHS is a single bit. if (isPowerOf2_64(AndRHS->getZExtValue())) { return DAG.getNode(ISD::SRL, VT, N0, - DAG.getConstant(Log2_64(AndRHS->getZExtValue()), - getShiftAmountTy())); + DAG.getConstant(Log2_64(AndRHS->getZExtValue()), + ShiftTy)); } } else if (Cond == ISD::SETEQ && C1 == AndRHS->getZExtValue()) { // (X & 8) == 8 --> (X & 8) >> 3 // Perform the xform if C1 is a single bit. if (C1.isPowerOf2()) { return DAG.getNode(ISD::SRL, VT, N0, - DAG.getConstant(C1.logBase2(), getShiftAmountTy())); + DAG.getConstant(C1.logBase2(), ShiftTy)); } } } diff --git a/llvm/test/CodeGen/X86/2009-01-31-BigShift.ll b/llvm/test/CodeGen/X86/2009-01-31-BigShift.ll new file mode 100644 index 000000000000..360b4f0e46bf --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-01-31-BigShift.ll @@ -0,0 +1,9 @@ +; RUN: llvm-as < %s | llc -march=x86 | not grep and +; PR3401 + +define void @x(i288 %i) nounwind { + call void @add(i288 %i) + ret void +} + +declare void @add(i288) diff --git a/llvm/test/CodeGen/X86/2009-01-31-BigShift2.ll b/llvm/test/CodeGen/X86/2009-01-31-BigShift2.ll new file mode 100644 index 000000000000..2b5b18957830 --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-01-31-BigShift2.ll @@ -0,0 +1,11 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {mov.*56} +; PR3449 + +define void @test(<8 x double>* %P, i64* %Q) nounwind { + %A = load <8 x double>* %P ; <<8 x double>> [#uses=1] + %B = bitcast <8 x double> %A to i512 ; [#uses=1] + %C = lshr i512 %B, 448 ; [#uses=1] + %D = trunc i512 %C to i64 ; [#uses=1] + volatile store i64 %D, i64* %Q + ret void +} diff --git a/llvm/test/CodeGen/X86/2009-01-31-BigShift3.ll b/llvm/test/CodeGen/X86/2009-01-31-BigShift3.ll new file mode 100644 index 000000000000..c92c86a092a1 --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-01-31-BigShift3.ll @@ -0,0 +1,31 @@ +; RUN: llvm-as < %s | llc -march=x86 +; PR3450 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128" +target triple = "i386-apple-darwin7" + %struct.BitMap = type { i8* } + %struct.BitMapListStruct = type { %struct.BitMap, %struct.BitMapListStruct*, %struct.BitMapListStruct* } + %struct.Material = type { float, float, float, %struct.Material*, %struct.Material* } + %struct.ObjPoint = type { double, double, double, double, double, double } + %struct.ObjectStruct = type { [57 x i8], %struct.PointListStruct*, %struct.Poly3Struct*, %struct.Poly4Struct*, %struct.Texture*, %struct.Material*, %struct.Point, i32, i32, %struct.Point, %struct.Point, %struct.Point, %struct.ObjectStruct*, %struct.ObjectStruct*, i32, i32, i32, i32, i32, i32, i32, %struct.ObjectStruct*, %struct.ObjectStruct* } + %struct.Point = type { double, double, double } + %struct.PointListStruct = type { %struct.ObjPoint*, %struct.PointListStruct*, %struct.PointListStruct* } + %struct.Poly3Struct = type { [3 x %struct.ObjPoint*], %struct.Material*, %struct.Texture*, %struct.Poly3Struct*, %struct.Poly3Struct* } + %struct.Poly4Struct = type { [4 x %struct.ObjPoint*], %struct.Material*, %struct.Texture*, %struct.Poly4Struct*, %struct.Poly4Struct* } + %struct.Texture = type { %struct.Point, %struct.BitMapListStruct*, %struct.Point, %struct.Point, %struct.Point, %struct.Texture*, %struct.Texture* } + +define fastcc void @ScaleObjectAdd(%struct.ObjectStruct* %o, double %sx, double %sy, double %sz) nounwind { +entry: + %sz101112.ins = or i960 0, 0 ; [#uses=1] + br i1 false, label %return, label %bb1.preheader + +bb1.preheader: ; preds = %entry + %0 = lshr i960 %sz101112.ins, 640 ; [#uses=0] + br label %bb1 + +bb1: ; preds = %bb1, %bb1.preheader + br label %bb1 + +return: ; preds = %entry + ret void +} -- GitLab From 9e2b9f32347188ca8b759e889f45e79ef00c1f1f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 31 Jan 2009 19:05:27 +0000 Subject: [PATCH 580/682] Fix PR3452 (an infinite loop bootstrapping) by disabling the recent improvements to the EvaluateInDifferentType code. This code works by just inserted a bunch of new code and then seeing if it is useful. Instcombine is not allowed to do this: it can only insert new code if it is useful, and only when it is converging to a more canonical fixed point. Now that we iterate when DCE makes progress, this causes an infinite loop when the code ends up not being used. llvm-svn: 63483 --- .../Scalar/InstructionCombining.cpp | 22 +- .../InstCombine/2009-01-31-InfIterate.ll | 484 ++++++++++++++++++ .../Transforms/InstCombine/cast-sext-zext.ll | 1 + 3 files changed, 497 insertions(+), 10 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 2b0e0d1c9fae..8b9c59994779 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -7892,15 +7892,15 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { break; case Instruction::ZExt: { DoXForm = NumCastsRemoved >= 1; - if (!DoXForm) { + if (!DoXForm && 0) { // If it's unnecessary to issue an AND to clear the high bits, it's // always profitable to do this xform. - Value *TryRes = EvaluateInDifferentType(SrcI, DestTy, - CI.getOpcode() == Instruction::SExt); + Value *TryRes = EvaluateInDifferentType(SrcI, DestTy, false); APInt Mask(APInt::getBitsSet(DestBitSize, SrcBitSize, DestBitSize)); if (MaskedValueIsZero(TryRes, Mask)) return ReplaceInstUsesWith(CI, TryRes); - else if (Instruction *TryI = dyn_cast(TryRes)) + + if (Instruction *TryI = dyn_cast(TryRes)) if (TryI->use_empty()) EraseInstFromFunction(*TryI); } @@ -7908,7 +7908,7 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { } case Instruction::SExt: { DoXForm = NumCastsRemoved >= 2; - if (!DoXForm && !isa(SrcI)) { + if (!DoXForm && !isa(SrcI) && 0) { // If we do not have to emit the truncate + sext pair, then it's always // profitable to do this xform. // @@ -7918,12 +7918,12 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { // t3 = sext i16 t2 to i32 // != // i32 t1 - Value *TryRes = EvaluateInDifferentType(SrcI, DestTy, - CI.getOpcode() == Instruction::SExt); + Value *TryRes = EvaluateInDifferentType(SrcI, DestTy, true); unsigned NumSignBits = ComputeNumSignBits(TryRes); if (NumSignBits > (DestBitSize - SrcBitSize)) return ReplaceInstUsesWith(CI, TryRes); - else if (Instruction *TryI = dyn_cast(TryRes)) + + if (Instruction *TryI = dyn_cast(TryRes)) if (TryI->use_empty()) EraseInstFromFunction(*TryI); } @@ -7932,11 +7932,13 @@ Instruction *InstCombiner::commonIntCastTransforms(CastInst &CI) { } if (DoXForm) { + DOUT << "ICE: EvaluateInDifferentType converting expression type to avoid" + << " cast: " << CI; Value *Res = EvaluateInDifferentType(SrcI, DestTy, CI.getOpcode() == Instruction::SExt); if (JustReplace) - // Just replace this cast with the result. - return ReplaceInstUsesWith(CI, Res); + // Just replace this cast with the result. + return ReplaceInstUsesWith(CI, Res); assert(Res->getType() == DestTy); switch (CI.getOpcode()) { diff --git a/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll b/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll new file mode 100644 index 000000000000..5c26c06bfc4d --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll @@ -0,0 +1,484 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis +; PR3452 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" +@__clz_tab = external constant [256 x i8] ; <[256 x i8]*> [#uses=3] +@llvm.used = appending global [1 x i8*] [ i8* bitcast (void (i128, i128, i128*)* @__udivmodti4 to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] + +define fastcc void @__udivmodti4(i128 %n, i128 %d, i128* %rp) nounwind alwaysinline { +entry: + %tmp1 = trunc i128 %n to i64 ; [#uses=12] + %sroa.store.elt = lshr i128 %n, 64 ; [#uses=1] + %tmp2 = trunc i128 %sroa.store.elt to i64 ; [#uses=12] + %tmp3 = trunc i128 %d to i64 ; [#uses=12] + %sroa.store.elt16 = lshr i128 %d, 64 ; [#uses=1] + %tmp4 = trunc i128 %sroa.store.elt16 to i64 ; [#uses=7] + %tmp5 = icmp eq i64 %tmp4, 0 ; [#uses=1] + br i1 %tmp5, label %bb, label %bb86 + +bb: ; preds = %entry + %tmp6 = icmp ugt i64 %tmp3, %tmp2 ; [#uses=1] + br i1 %tmp6, label %bb33.thread, label %bb50 + +bb33.thread: ; preds = %bb + br label %bb31 + +bb31: ; preds = %bb33, %bb33.thread + %__a28.0.reg2mem.0 = phi i64 [ 56, %bb33.thread ], [ %tmp9, %bb33 ] ; [#uses=3] + %.cast = and i64 %__a28.0.reg2mem.0, 4294967288 ; [#uses=1] + %tmp = shl i64 255, %.cast ; [#uses=1] + %tmp7 = and i64 %tmp3, %tmp ; [#uses=1] + %tmp8 = icmp eq i64 %tmp7, 0 ; [#uses=1] + br i1 %tmp8, label %bb33, label %bb34 + +bb33: ; preds = %bb31 + %tmp9 = add i64 %__a28.0.reg2mem.0, -8 ; [#uses=3] + %tmp10 = icmp eq i64 %tmp9, 0 ; [#uses=1] + br i1 %tmp10, label %bb34, label %bb31 + +bb34: ; preds = %bb33, %bb31 + %__a28.0.reg2mem.1 = phi i64 [ %__a28.0.reg2mem.0, %bb31 ], [ %tmp9, %bb33 ] ; [#uses=2] + %.cast35 = and i64 %__a28.0.reg2mem.1, 4294967288 ; [#uses=1] + %tmp11 = lshr i64 %tmp3, %.cast35 ; [#uses=1] + %tmp12 = getelementptr [256 x i8]* @__clz_tab, i64 0, i64 %tmp11 ; [#uses=1] + %tmp13 = load i8* %tmp12, align 1 ; [#uses=1] + %tmp14 = zext i8 %tmp13 to i64 ; [#uses=1] + %tmp15 = add i64 %tmp14, %__a28.0.reg2mem.1 ; [#uses=2] + %tmp16 = sub i64 64, %tmp15 ; [#uses=7] + %tmp17 = icmp eq i64 %tmp15, 64 ; [#uses=1] + br i1 %tmp17, label %bb41, label %bb36 + +bb36: ; preds = %bb34 + %.cast37 = and i64 %tmp16, 4294967295 ; [#uses=1] + %tmp18 = shl i64 %tmp3, %.cast37 ; [#uses=1] + %.cast38 = and i64 %tmp16, 4294967295 ; [#uses=1] + %tmp19 = shl i64 %tmp2, %.cast38 ; [#uses=1] + %tmp20 = sub i64 64, %tmp16 ; [#uses=1] + %.cast39 = and i64 %tmp20, 4294967295 ; [#uses=1] + %tmp21 = lshr i64 %tmp1, %.cast39 ; [#uses=1] + %tmp22 = or i64 %tmp19, %tmp21 ; [#uses=1] + %.cast40 = and i64 %tmp16, 4294967295 ; [#uses=1] + %tmp23 = shl i64 %tmp1, %.cast40 ; [#uses=1] + br label %bb41 + +bb41: ; preds = %bb36, %bb34 + %n1.0 = phi i64 [ %tmp2, %bb34 ], [ %tmp22, %bb36 ] ; [#uses=2] + %n0.0 = phi i64 [ %tmp1, %bb34 ], [ %tmp23, %bb36 ] ; [#uses=2] + %d0.0 = phi i64 [ %tmp3, %bb34 ], [ %tmp18, %bb36 ] ; [#uses=8] + %tmp24 = lshr i64 %d0.0, 32 ; [#uses=4] + %tmp25 = and i64 %d0.0, 4294967295 ; [#uses=2] + %tmp26 = urem i64 %n1.0, %tmp24 ; [#uses=1] + %tmp27 = udiv i64 %n1.0, %tmp24 ; [#uses=1] + %tmp28 = mul i64 %tmp27, %tmp25 ; [#uses=3] + %tmp29 = shl i64 %tmp26, 32 ; [#uses=1] + %tmp30 = lshr i64 %n0.0, 32 ; [#uses=1] + %tmp31 = or i64 %tmp29, %tmp30 ; [#uses=3] + %tmp32 = icmp ult i64 %tmp31, %tmp28 ; [#uses=1] + br i1 %tmp32, label %bb42, label %bb45 + +bb42: ; preds = %bb41 + %tmp33 = add i64 %tmp31, %d0.0 ; [#uses=4] + %.not = icmp uge i64 %tmp33, %d0.0 ; [#uses=1] + %tmp34 = icmp ult i64 %tmp33, %tmp28 ; [#uses=1] + %or.cond = and i1 %tmp34, %.not ; [#uses=1] + br i1 %or.cond, label %bb44, label %bb45 + +bb44: ; preds = %bb42 + %tmp35 = add i64 %tmp33, %d0.0 ; [#uses=1] + br label %bb45 + +bb45: ; preds = %bb44, %bb42, %bb41 + %__r123.0 = phi i64 [ %tmp31, %bb41 ], [ %tmp33, %bb42 ], [ %tmp35, %bb44 ] ; [#uses=1] + %tmp36 = sub i64 %__r123.0, %tmp28 ; [#uses=2] + %tmp37 = urem i64 %tmp36, %tmp24 ; [#uses=1] + %tmp38 = udiv i64 %tmp36, %tmp24 ; [#uses=1] + %tmp39 = mul i64 %tmp38, %tmp25 ; [#uses=5] + %tmp40 = shl i64 %tmp37, 32 ; [#uses=1] + %tmp41 = and i64 %n0.0, 4294967295 ; [#uses=1] + %tmp42 = or i64 %tmp40, %tmp41 ; [#uses=3] + %tmp43 = icmp ult i64 %tmp42, %tmp39 ; [#uses=1] + br i1 %tmp43, label %bb46, label %bb83 + +bb46: ; preds = %bb45 + %tmp44 = add i64 %tmp42, %d0.0 ; [#uses=4] + %.not137 = icmp uge i64 %tmp44, %d0.0 ; [#uses=1] + %tmp45 = icmp ult i64 %tmp44, %tmp39 ; [#uses=1] + %or.cond138 = and i1 %tmp45, %.not137 ; [#uses=1] + br i1 %or.cond138, label %bb48, label %bb83 + +bb48: ; preds = %bb46 + %tmp46 = add i64 %tmp44, %d0.0 ; [#uses=1] + br label %bb83 + +bb50: ; preds = %bb + %tmp47 = icmp eq i64 %tmp3, 0 ; [#uses=1] + br i1 %tmp47, label %bb51, label %bb56.thread + +bb51: ; preds = %bb50 + %tmp48 = udiv i64 1, %tmp3 ; [#uses=1] + br label %bb56.thread + +bb53: ; preds = %bb56, %bb56.thread + %__a19.0.reg2mem.0 = phi i64 [ 56, %bb56.thread ], [ %tmp51, %bb56 ] ; [#uses=3] + %.cast54 = and i64 %__a19.0.reg2mem.0, 4294967288 ; [#uses=1] + %tmp133 = shl i64 255, %.cast54 ; [#uses=1] + %tmp49 = and i64 %d0.1.ph, %tmp133 ; [#uses=1] + %tmp50 = icmp eq i64 %tmp49, 0 ; [#uses=1] + br i1 %tmp50, label %bb56, label %bb57 + +bb56.thread: ; preds = %bb51, %bb50 + %d0.1.ph = phi i64 [ %tmp48, %bb51 ], [ %tmp3, %bb50 ] ; [#uses=5] + br label %bb53 + +bb56: ; preds = %bb53 + %tmp51 = add i64 %__a19.0.reg2mem.0, -8 ; [#uses=3] + %tmp52 = icmp eq i64 %tmp51, 0 ; [#uses=1] + br i1 %tmp52, label %bb57, label %bb53 + +bb57: ; preds = %bb56, %bb53 + %__a19.0.reg2mem.1 = phi i64 [ %__a19.0.reg2mem.0, %bb53 ], [ %tmp51, %bb56 ] ; [#uses=2] + %.cast58 = and i64 %__a19.0.reg2mem.1, 4294967288 ; [#uses=1] + %tmp53 = lshr i64 %d0.1.ph, %.cast58 ; [#uses=1] + %tmp54 = getelementptr [256 x i8]* @__clz_tab, i64 0, i64 %tmp53 ; [#uses=1] + %tmp55 = load i8* %tmp54, align 1 ; [#uses=1] + %tmp56 = zext i8 %tmp55 to i64 ; [#uses=1] + %tmp57 = add i64 %tmp56, %__a19.0.reg2mem.1 ; [#uses=2] + %tmp58 = sub i64 64, %tmp57 ; [#uses=7] + %tmp59 = icmp eq i64 %tmp57, 64 ; [#uses=1] + br i1 %tmp59, label %bb74, label %bb60 + +bb60: ; preds = %bb57 + %tmp60 = sub i64 64, %tmp58 ; [#uses=2] + %.cast61 = and i64 %tmp58, 4294967295 ; [#uses=1] + %tmp61 = shl i64 %d0.1.ph, %.cast61 ; [#uses=9] + %.cast62 = and i64 %tmp60, 4294967295 ; [#uses=1] + %tmp62 = lshr i64 %tmp2, %.cast62 ; [#uses=2] + %.cast63 = and i64 %tmp58, 4294967295 ; [#uses=1] + %tmp63 = shl i64 %tmp2, %.cast63 ; [#uses=1] + %.cast64 = and i64 %tmp60, 4294967295 ; [#uses=1] + %tmp64 = lshr i64 %tmp1, %.cast64 ; [#uses=1] + %tmp65 = or i64 %tmp63, %tmp64 ; [#uses=2] + %.cast65 = and i64 %tmp58, 4294967295 ; [#uses=1] + %tmp66 = shl i64 %tmp1, %.cast65 ; [#uses=1] + %tmp67 = lshr i64 %tmp61, 32 ; [#uses=4] + %tmp68 = and i64 %tmp61, 4294967295 ; [#uses=2] + %tmp69 = urem i64 %tmp62, %tmp67 ; [#uses=1] + %tmp70 = udiv i64 %tmp62, %tmp67 ; [#uses=1] + %tmp71 = mul i64 %tmp70, %tmp68 ; [#uses=3] + %tmp72 = shl i64 %tmp69, 32 ; [#uses=1] + %tmp73 = lshr i64 %tmp65, 32 ; [#uses=1] + %tmp74 = or i64 %tmp72, %tmp73 ; [#uses=3] + %tmp75 = icmp ult i64 %tmp74, %tmp71 ; [#uses=1] + br i1 %tmp75, label %bb66, label %bb69 + +bb66: ; preds = %bb60 + %tmp76 = add i64 %tmp74, %tmp61 ; [#uses=4] + %.not139 = icmp uge i64 %tmp76, %tmp61 ; [#uses=1] + %tmp77 = icmp ult i64 %tmp76, %tmp71 ; [#uses=1] + %or.cond140 = and i1 %tmp77, %.not139 ; [#uses=1] + br i1 %or.cond140, label %bb68, label %bb69 + +bb68: ; preds = %bb66 + %tmp78 = add i64 %tmp76, %tmp61 ; [#uses=1] + br label %bb69 + +bb69: ; preds = %bb68, %bb66, %bb60 + %__r114.0 = phi i64 [ %tmp74, %bb60 ], [ %tmp76, %bb66 ], [ %tmp78, %bb68 ] ; [#uses=1] + %tmp79 = sub i64 %__r114.0, %tmp71 ; [#uses=2] + %tmp80 = urem i64 %tmp79, %tmp67 ; [#uses=1] + %tmp81 = udiv i64 %tmp79, %tmp67 ; [#uses=1] + %tmp82 = mul i64 %tmp81, %tmp68 ; [#uses=3] + %tmp83 = shl i64 %tmp80, 32 ; [#uses=1] + %tmp84 = and i64 %tmp65, 4294967295 ; [#uses=1] + %tmp85 = or i64 %tmp83, %tmp84 ; [#uses=3] + %tmp86 = icmp ult i64 %tmp85, %tmp82 ; [#uses=1] + br i1 %tmp86, label %bb70, label %bb73 + +bb70: ; preds = %bb69 + %tmp87 = add i64 %tmp85, %tmp61 ; [#uses=4] + %.not141 = icmp uge i64 %tmp87, %tmp61 ; [#uses=1] + %tmp88 = icmp ult i64 %tmp87, %tmp82 ; [#uses=1] + %or.cond142 = and i1 %tmp88, %.not141 ; [#uses=1] + br i1 %or.cond142, label %bb72, label %bb73 + +bb72: ; preds = %bb70 + %tmp89 = add i64 %tmp87, %tmp61 ; [#uses=1] + br label %bb73 + +bb73: ; preds = %bb72, %bb70, %bb69 + %__r013.0 = phi i64 [ %tmp85, %bb69 ], [ %tmp87, %bb70 ], [ %tmp89, %bb72 ] ; [#uses=1] + br label %bb74 + +bb74: ; preds = %bb73, %bb57 + %__r013.0.pn = phi i64 [ %__r013.0, %bb73 ], [ %tmp2, %bb57 ] ; [#uses=1] + %.pn135 = phi i64 [ %tmp82, %bb73 ], [ %d0.1.ph, %bb57 ] ; [#uses=1] + %n0.2 = phi i64 [ %tmp66, %bb73 ], [ %tmp1, %bb57 ] ; [#uses=2] + %d0.2 = phi i64 [ %tmp61, %bb73 ], [ %d0.1.ph, %bb57 ] ; [#uses=8] + %n1.1 = sub i64 %__r013.0.pn, %.pn135 ; [#uses=2] + %tmp90 = lshr i64 %d0.2, 32 ; [#uses=4] + %tmp91 = and i64 %d0.2, 4294967295 ; [#uses=2] + %tmp92 = urem i64 %n1.1, %tmp90 ; [#uses=1] + %tmp93 = udiv i64 %n1.1, %tmp90 ; [#uses=1] + %tmp94 = mul i64 %tmp93, %tmp91 ; [#uses=3] + %tmp95 = shl i64 %tmp92, 32 ; [#uses=1] + %tmp96 = lshr i64 %n0.2, 32 ; [#uses=1] + %tmp97 = or i64 %tmp95, %tmp96 ; [#uses=3] + %tmp98 = icmp ult i64 %tmp97, %tmp94 ; [#uses=1] + br i1 %tmp98, label %bb75, label %bb78 + +bb75: ; preds = %bb74 + %tmp99 = add i64 %tmp97, %d0.2 ; [#uses=4] + %.not143 = icmp uge i64 %tmp99, %d0.2 ; [#uses=1] + %tmp100 = icmp ult i64 %tmp99, %tmp94 ; [#uses=1] + %or.cond144 = and i1 %tmp100, %.not143 ; [#uses=1] + br i1 %or.cond144, label %bb77, label %bb78 + +bb77: ; preds = %bb75 + %tmp101 = add i64 %tmp99, %d0.2 ; [#uses=1] + br label %bb78 + +bb78: ; preds = %bb77, %bb75, %bb74 + %__r17.0 = phi i64 [ %tmp97, %bb74 ], [ %tmp99, %bb75 ], [ %tmp101, %bb77 ] ; [#uses=1] + %tmp102 = sub i64 %__r17.0, %tmp94 ; [#uses=2] + %tmp103 = urem i64 %tmp102, %tmp90 ; [#uses=1] + %tmp104 = udiv i64 %tmp102, %tmp90 ; [#uses=1] + %tmp105 = mul i64 %tmp104, %tmp91 ; [#uses=5] + %tmp106 = shl i64 %tmp103, 32 ; [#uses=1] + %tmp107 = and i64 %n0.2, 4294967295 ; [#uses=1] + %tmp108 = or i64 %tmp106, %tmp107 ; [#uses=3] + %tmp109 = icmp ult i64 %tmp108, %tmp105 ; [#uses=1] + br i1 %tmp109, label %bb79, label %bb83 + +bb79: ; preds = %bb78 + %tmp110 = add i64 %tmp108, %d0.2 ; [#uses=4] + %.not145 = icmp uge i64 %tmp110, %d0.2 ; [#uses=1] + %tmp111 = icmp ult i64 %tmp110, %tmp105 ; [#uses=1] + %or.cond146 = and i1 %tmp111, %.not145 ; [#uses=1] + br i1 %or.cond146, label %bb81, label %bb83 + +bb81: ; preds = %bb79 + %tmp112 = add i64 %tmp110, %d0.2 ; [#uses=1] + br label %bb83 + +bb83: ; preds = %bb81, %bb79, %bb78, %bb48, %bb46, %bb45 + %bm.0 = phi i64 [ %tmp16, %bb46 ], [ %tmp16, %bb48 ], [ %tmp16, %bb45 ], [ %tmp58, %bb79 ], [ %tmp58, %bb81 ], [ %tmp58, %bb78 ] ; [#uses=1] + %__r06.0.pn = phi i64 [ %tmp42, %bb45 ], [ %tmp44, %bb46 ], [ %tmp46, %bb48 ], [ %tmp108, %bb78 ], [ %tmp110, %bb79 ], [ %tmp112, %bb81 ] ; [#uses=1] + %.pn = phi i64 [ %tmp39, %bb46 ], [ %tmp39, %bb48 ], [ %tmp39, %bb45 ], [ %tmp105, %bb79 ], [ %tmp105, %bb81 ], [ %tmp105, %bb78 ] ; [#uses=1] + %tmp113 = icmp eq i128* %rp, null ; [#uses=1] + br i1 %tmp113, label %bb131, label %bb84 + +bb84: ; preds = %bb83 + %n0.1 = sub i64 %__r06.0.pn, %.pn ; [#uses=1] + %.cast85 = and i64 %bm.0, 4294967295 ; [#uses=1] + %tmp114 = lshr i64 %n0.1, %.cast85 ; [#uses=1] + %tmp115 = zext i64 %tmp114 to i128 ; [#uses=1] + store i128 %tmp115, i128* %rp, align 16 + br label %bb131 + +bb86: ; preds = %entry + %tmp116 = icmp ugt i64 %tmp4, %tmp2 ; [#uses=1] + br i1 %tmp116, label %bb87, label %bb93.thread + +bb93.thread: ; preds = %bb86 + br label %bb90 + +bb87: ; preds = %bb86 + %tmp117 = icmp eq i128* %rp, null ; [#uses=1] + br i1 %tmp117, label %bb131, label %bb88 + +bb88: ; preds = %bb87 + store i128 %n, i128* %rp, align 16 + br label %bb131 + +bb90: ; preds = %bb93, %bb93.thread + %__a.0.reg2mem.0 = phi i64 [ 56, %bb93.thread ], [ %tmp120, %bb93 ] ; [#uses=3] + %.cast91 = and i64 %__a.0.reg2mem.0, 4294967288 ; [#uses=1] + %tmp136 = shl i64 255, %.cast91 ; [#uses=1] + %tmp118 = and i64 %tmp4, %tmp136 ; [#uses=1] + %tmp119 = icmp eq i64 %tmp118, 0 ; [#uses=1] + br i1 %tmp119, label %bb93, label %bb94 + +bb93: ; preds = %bb90 + %tmp120 = add i64 %__a.0.reg2mem.0, -8 ; [#uses=3] + %tmp121 = icmp eq i64 %tmp120, 0 ; [#uses=1] + br i1 %tmp121, label %bb94, label %bb90 + +bb94: ; preds = %bb93, %bb90 + %__a.0.reg2mem.1 = phi i64 [ %__a.0.reg2mem.0, %bb90 ], [ %tmp120, %bb93 ] ; [#uses=2] + %.cast95 = and i64 %__a.0.reg2mem.1, 4294967288 ; [#uses=1] + %tmp122 = lshr i64 %tmp4, %.cast95 ; [#uses=1] + %tmp123 = getelementptr [256 x i8]* @__clz_tab, i64 0, i64 %tmp122 ; [#uses=1] + %tmp124 = load i8* %tmp123, align 1 ; [#uses=1] + %tmp125 = zext i8 %tmp124 to i64 ; [#uses=1] + %tmp126 = add i64 %tmp125, %__a.0.reg2mem.1 ; [#uses=2] + %tmp127 = sub i64 64, %tmp126 ; [#uses=7] + %tmp128 = icmp eq i64 %tmp126, 64 ; [#uses=1] + br i1 %tmp128, label %bb96, label %bb103 + +bb96: ; preds = %bb94 + %tmp129 = icmp ugt i64 %tmp2, %tmp4 ; [#uses=1] + %tmp130 = icmp uge i64 %tmp1, %tmp3 ; [#uses=1] + %tmp131 = or i1 %tmp129, %tmp130 ; [#uses=1] + br i1 %tmp131, label %bb99, label %bb101 + +bb99: ; preds = %bb96 + %tmp132 = sub i64 %tmp1, %tmp3 ; [#uses=2] + %tmp134 = sub i64 %tmp2, %tmp4 ; [#uses=1] + %tmp135 = icmp ugt i64 %tmp132, %tmp1 ; [#uses=1] + %tmp137 = zext i1 %tmp135 to i64 ; [#uses=1] + %tmp138 = sub i64 %tmp134, %tmp137 ; [#uses=1] + br label %bb101 + +bb101: ; preds = %bb99, %bb96 + %tmp139 = phi i64 [ %tmp138, %bb99 ], [ %tmp2, %bb96 ] ; [#uses=1] + %n0.3 = phi i64 [ %tmp132, %bb99 ], [ %tmp1, %bb96 ] ; [#uses=1] + %tmp140 = icmp eq i128* %rp, null ; [#uses=1] + br i1 %tmp140, label %bb131, label %bb102 + +bb102: ; preds = %bb101 + %tmp141 = zext i64 %n0.3 to i128 ; [#uses=1] + %tmp142 = zext i64 %tmp139 to i128 ; [#uses=1] + %tmp143 = shl i128 %tmp142, 64 ; [#uses=1] + %tmp144 = or i128 %tmp143, %tmp141 ; [#uses=1] + store i128 %tmp144, i128* %rp, align 16 + br label %bb131 + +bb103: ; preds = %bb94 + %tmp145 = sub i64 64, %tmp127 ; [#uses=4] + %.cast104 = and i64 %tmp127, 4294967295 ; [#uses=1] + %tmp146 = shl i64 %tmp4, %.cast104 ; [#uses=1] + %.cast105 = and i64 %tmp145, 4294967295 ; [#uses=1] + %tmp147 = lshr i64 %tmp3, %.cast105 ; [#uses=1] + %tmp148 = or i64 %tmp146, %tmp147 ; [#uses=9] + %.cast106 = and i64 %tmp127, 4294967295 ; [#uses=1] + %tmp149 = shl i64 %tmp3, %.cast106 ; [#uses=3] + %.cast107 = and i64 %tmp145, 4294967295 ; [#uses=1] + %tmp150 = lshr i64 %tmp2, %.cast107 ; [#uses=2] + %.cast108 = and i64 %tmp127, 4294967295 ; [#uses=1] + %tmp151 = shl i64 %tmp2, %.cast108 ; [#uses=1] + %.cast109 = and i64 %tmp145, 4294967295 ; [#uses=1] + %tmp152 = lshr i64 %tmp1, %.cast109 ; [#uses=1] + %tmp153 = or i64 %tmp151, %tmp152 ; [#uses=2] + %.cast110 = and i64 %tmp127, 4294967295 ; [#uses=1] + %tmp154 = shl i64 %tmp1, %.cast110 ; [#uses=3] + %tmp155 = lshr i64 %tmp148, 32 ; [#uses=4] + %tmp156 = and i64 %tmp148, 4294967295 ; [#uses=2] + %tmp157 = urem i64 %tmp150, %tmp155 ; [#uses=1] + %tmp158 = udiv i64 %tmp150, %tmp155 ; [#uses=4] + %tmp159 = mul i64 %tmp158, %tmp156 ; [#uses=3] + %tmp160 = shl i64 %tmp157, 32 ; [#uses=1] + %tmp161 = lshr i64 %tmp153, 32 ; [#uses=1] + %tmp162 = or i64 %tmp160, %tmp161 ; [#uses=3] + %tmp163 = icmp ult i64 %tmp162, %tmp159 ; [#uses=1] + br i1 %tmp163, label %bb111, label %bb114 + +bb111: ; preds = %bb103 + %tmp164 = add i64 %tmp158, -1 ; [#uses=1] + %tmp165 = add i64 %tmp162, %tmp148 ; [#uses=4] + %.not147 = icmp uge i64 %tmp165, %tmp148 ; [#uses=1] + %tmp166 = icmp ult i64 %tmp165, %tmp159 ; [#uses=1] + %or.cond148 = and i1 %tmp166, %.not147 ; [#uses=1] + br i1 %or.cond148, label %bb113, label %bb114 + +bb113: ; preds = %bb111 + %tmp167 = add i64 %tmp158, -2 ; [#uses=1] + %tmp168 = add i64 %tmp165, %tmp148 ; [#uses=1] + br label %bb114 + +bb114: ; preds = %bb113, %bb111, %bb103 + %__q1.0 = phi i64 [ %tmp158, %bb103 ], [ %tmp164, %bb111 ], [ %tmp167, %bb113 ] ; [#uses=1] + %__r1.0 = phi i64 [ %tmp162, %bb103 ], [ %tmp165, %bb111 ], [ %tmp168, %bb113 ] ; [#uses=1] + %tmp169 = sub i64 %__r1.0, %tmp159 ; [#uses=2] + %tmp170 = urem i64 %tmp169, %tmp155 ; [#uses=1] + %tmp171 = udiv i64 %tmp169, %tmp155 ; [#uses=4] + %tmp172 = mul i64 %tmp171, %tmp156 ; [#uses=3] + %tmp173 = shl i64 %tmp170, 32 ; [#uses=1] + %tmp174 = and i64 %tmp153, 4294967295 ; [#uses=1] + %tmp175 = or i64 %tmp173, %tmp174 ; [#uses=3] + %tmp176 = icmp ult i64 %tmp175, %tmp172 ; [#uses=1] + br i1 %tmp176, label %bb115, label %bb118 + +bb115: ; preds = %bb114 + %tmp177 = add i64 %tmp171, -1 ; [#uses=1] + %tmp178 = add i64 %tmp175, %tmp148 ; [#uses=4] + %.not149 = icmp uge i64 %tmp178, %tmp148 ; [#uses=1] + %tmp179 = icmp ult i64 %tmp178, %tmp172 ; [#uses=1] + %or.cond150 = and i1 %tmp179, %.not149 ; [#uses=1] + br i1 %or.cond150, label %bb117, label %bb118 + +bb117: ; preds = %bb115 + %tmp180 = add i64 %tmp171, -2 ; [#uses=1] + %tmp181 = add i64 %tmp178, %tmp148 ; [#uses=1] + br label %bb118 + +bb118: ; preds = %bb117, %bb115, %bb114 + %__q0.0 = phi i64 [ %tmp171, %bb114 ], [ %tmp177, %bb115 ], [ %tmp180, %bb117 ] ; [#uses=2] + %__r0.0 = phi i64 [ %tmp175, %bb114 ], [ %tmp178, %bb115 ], [ %tmp181, %bb117 ] ; [#uses=1] + %tmp182 = sub i64 %__r0.0, %tmp172 ; [#uses=3] + %tmp183 = shl i64 %__q1.0, 32 ; [#uses=1] + %tmp184 = or i64 %tmp183, %__q0.0 ; [#uses=1] + %tmp185 = and i64 %__q0.0, 4294967295 ; [#uses=2] + %tmp186 = lshr i64 %tmp184, 32 ; [#uses=2] + %tmp187 = and i64 %tmp149, 4294967295 ; [#uses=2] + %tmp188 = lshr i64 %tmp149, 32 ; [#uses=2] + %tmp189 = mul i64 %tmp185, %tmp187 ; [#uses=2] + %tmp190 = mul i64 %tmp185, %tmp188 ; [#uses=1] + %tmp191 = mul i64 %tmp186, %tmp187 ; [#uses=2] + %tmp192 = mul i64 %tmp186, %tmp188 ; [#uses=1] + %tmp193 = lshr i64 %tmp189, 32 ; [#uses=1] + %tmp194 = add i64 %tmp193, %tmp190 ; [#uses=1] + %tmp195 = add i64 %tmp194, %tmp191 ; [#uses=3] + %tmp196 = icmp ult i64 %tmp195, %tmp191 ; [#uses=1] + %tmp197 = select i1 %tmp196, i64 4294967296, i64 0 ; [#uses=1] + %__x3.0 = add i64 %tmp192, %tmp197 ; [#uses=1] + %tmp198 = lshr i64 %tmp195, 32 ; [#uses=1] + %tmp199 = add i64 %tmp198, %__x3.0 ; [#uses=4] + %tmp200 = shl i64 %tmp195, 32 ; [#uses=1] + %tmp201 = and i64 %tmp189, 4294967295 ; [#uses=1] + %tmp202 = or i64 %tmp200, %tmp201 ; [#uses=4] + %tmp203 = icmp ugt i64 %tmp199, %tmp182 ; [#uses=1] + br i1 %tmp203, label %bb125, label %bb121 + +bb121: ; preds = %bb118 + %tmp204 = icmp eq i64 %tmp199, %tmp182 ; [#uses=1] + %tmp205 = icmp ugt i64 %tmp202, %tmp154 ; [#uses=1] + %tmp206 = and i1 %tmp204, %tmp205 ; [#uses=1] + br i1 %tmp206, label %bb125, label %bb126 + +bb125: ; preds = %bb121, %bb118 + %tmp207 = sub i64 %tmp202, %tmp149 ; [#uses=2] + %tmp208 = sub i64 %tmp199, %tmp148 ; [#uses=1] + %tmp209 = icmp ugt i64 %tmp207, %tmp202 ; [#uses=1] + %tmp210 = zext i1 %tmp209 to i64 ; [#uses=1] + %tmp211 = sub i64 %tmp208, %tmp210 ; [#uses=1] + br label %bb126 + +bb126: ; preds = %bb125, %bb121 + %m1.0 = phi i64 [ %tmp199, %bb121 ], [ %tmp211, %bb125 ] ; [#uses=1] + %m0.0 = phi i64 [ %tmp202, %bb121 ], [ %tmp207, %bb125 ] ; [#uses=1] + %tmp212 = icmp eq i128* %rp, null ; [#uses=1] + br i1 %tmp212, label %bb131, label %bb127 + +bb127: ; preds = %bb126 + %tmp213 = sub i64 %tmp154, %m0.0 ; [#uses=2] + %tmp214 = sub i64 %tmp182, %m1.0 ; [#uses=1] + %tmp215 = icmp ugt i64 %tmp213, %tmp154 ; [#uses=1] + %tmp216 = zext i1 %tmp215 to i64 ; [#uses=1] + %tmp217 = sub i64 %tmp214, %tmp216 ; [#uses=2] + %.cast128 = and i64 %tmp145, 4294967295 ; [#uses=1] + %tmp218 = shl i64 %tmp217, %.cast128 ; [#uses=1] + %.cast129 = and i64 %tmp127, 4294967295 ; [#uses=1] + %tmp219 = lshr i64 %tmp213, %.cast129 ; [#uses=1] + %tmp220 = or i64 %tmp218, %tmp219 ; [#uses=1] + %.cast130 = and i64 %tmp127, 4294967295 ; [#uses=1] + %tmp221 = lshr i64 %tmp217, %.cast130 ; [#uses=1] + %tmp222 = zext i64 %tmp220 to i128 ; [#uses=1] + %tmp223 = zext i64 %tmp221 to i128 ; [#uses=1] + %tmp224 = shl i128 %tmp223, 64 ; [#uses=1] + %tmp225 = or i128 %tmp224, %tmp222 ; [#uses=1] + store i128 %tmp225, i128* %rp, align 16 + br label %bb131 + +bb131: ; preds = %bb127, %bb126, %bb102, %bb101, %bb88, %bb87, %bb84, %bb83 + ret void +} diff --git a/llvm/test/Transforms/InstCombine/cast-sext-zext.ll b/llvm/test/Transforms/InstCombine/cast-sext-zext.ll index da5e7facfad6..1acd7582100f 100644 --- a/llvm/test/Transforms/InstCombine/cast-sext-zext.ll +++ b/llvm/test/Transforms/InstCombine/cast-sext-zext.ll @@ -1,4 +1,5 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep sext +; XFAIL: * define zeroext i16 @t(i8 zeroext %on_off, i16* nocapture %puls) nounwind readonly { entry: -- GitLab From 12beab7085bc869e0ec17ee309f1c0ffc84aaaf5 Mon Sep 17 00:00:00 2001 From: Anders Carlsson Date: Sat, 31 Jan 2009 19:07:49 +0000 Subject: [PATCH 581/682] Forgot to add this test. llvm-svn: 63484 --- clang/test/Sema/attr-cleanup.c | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 clang/test/Sema/attr-cleanup.c diff --git a/clang/test/Sema/attr-cleanup.c b/clang/test/Sema/attr-cleanup.c new file mode 100644 index 000000000000..c58d17b7ef4b --- /dev/null +++ b/clang/test/Sema/attr-cleanup.c @@ -0,0 +1,31 @@ +// RUN: clang %s -verify -fsyntax-only + +void c1(int *a); + +extern int g1 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}} +int g2 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}} +static int g3 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}} + +void t1() +{ + int v1 __attribute((cleanup)); // expected-error {{attribute requires 1 argument(s)}} + int v2 __attribute((cleanup(1, 2))); // expected-error {{attribute requires 1 argument(s)}} + + static int v3 __attribute((cleanup(c1))); // expected-warning {{cleanup attribute ignored}} + + int v4 __attribute((cleanup(h))); // expected-error {{'cleanup' argument 'h' not found}} + + int v5 __attribute((cleanup(c1))); + int v6 __attribute((cleanup(v3))); // expected-error {{'cleanup' argument 'v3' is not a function}} +} + +struct s { + int a, b; +}; + +void c2(); + +void t2() +{ + int v1 __attribute__((cleanup(c2))); // expected-error {{'cleanup' function 'c2' must take 1 parameter}} +} \ No newline at end of file -- GitLab From 4d9fa9e71d30db08b9c49a55d332c635907678ad Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 20:01:02 +0000 Subject: [PATCH 582/682] DebugLoc propagation. Done with file. llvm-svn: 63485 --- .../CodeGen/SelectionDAG/LegalizeTypes.cpp | 38 +++++++++++-------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp index 3e79ecb50c5c..83712eec737c 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -852,18 +852,20 @@ void DAGTypeLegalizer::SetIgnoredNodeResult(SDNode* N) { /// BitConvertToInteger - Convert to an integer of the same size. SDValue DAGTypeLegalizer::BitConvertToInteger(SDValue Op) { unsigned BitWidth = Op.getValueType().getSizeInBits(); - return DAG.getNode(ISD::BIT_CONVERT, MVT::getIntegerVT(BitWidth), Op); + return DAG.getNode(ISD::BIT_CONVERT, Op.getNode()->getDebugLoc(), + MVT::getIntegerVT(BitWidth), Op); } SDValue DAGTypeLegalizer::CreateStackStoreLoad(SDValue Op, MVT DestVT) { + DebugLoc dl = Op.getNode()->getDebugLoc(); // Create the stack frame object. Make sure it is aligned for both // the source and destination types. SDValue StackPtr = DAG.CreateStackTemporary(Op.getValueType(), DestVT); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), Op, StackPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Op, StackPtr, NULL, 0); // Result is a load from the stack slot. - return DAG.getLoad(DestVT, Store, StackPtr, NULL, 0); + return DAG.getLoad(DestVT, dl, Store, StackPtr, NULL, 0); } /// CustomLowerResults - Replace the node's results with custom code provided @@ -920,31 +922,35 @@ void DAGTypeLegalizer::GetSplitDestVTs(MVT InVT, MVT &LoVT, MVT &HiVT) { SDValue DAGTypeLegalizer::GetVectorElementPointer(SDValue VecPtr, MVT EltVT, SDValue Index) { + DebugLoc dl = Index.getNode()->getDebugLoc(); // Make sure the index type is big enough to compute in. if (Index.getValueType().bitsGT(TLI.getPointerTy())) - Index = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Index); + Index = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Index); else - Index = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Index); + Index = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Index); // Calculate the element offset and add it to the pointer. unsigned EltSize = EltVT.getSizeInBits() / 8; // FIXME: should be ABI size. - Index = DAG.getNode(ISD::MUL, Index.getValueType(), Index, + Index = DAG.getNode(ISD::MUL, dl, Index.getValueType(), Index, DAG.getConstant(EltSize, Index.getValueType())); - return DAG.getNode(ISD::ADD, Index.getValueType(), Index, VecPtr); + return DAG.getNode(ISD::ADD, dl, Index.getValueType(), Index, VecPtr); } /// JoinIntegers - Build an integer with low bits Lo and high bits Hi. SDValue DAGTypeLegalizer::JoinIntegers(SDValue Lo, SDValue Hi) { + // Arbitrarily use dlHi for result DebugLoc + DebugLoc dlHi = Hi.getNode()->getDebugLoc(); + DebugLoc dlLo = Lo.getNode()->getDebugLoc(); MVT LVT = Lo.getValueType(); MVT HVT = Hi.getValueType(); MVT NVT = MVT::getIntegerVT(LVT.getSizeInBits() + HVT.getSizeInBits()); - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Lo); - Hi = DAG.getNode(ISD::ANY_EXTEND, NVT, Hi); - Hi = DAG.getNode(ISD::SHL, NVT, Hi, + Lo = DAG.getNode(ISD::ZERO_EXTEND, dlLo, NVT, Lo); + Hi = DAG.getNode(ISD::ANY_EXTEND, dlHi, NVT, Hi); + Hi = DAG.getNode(ISD::SHL, dlHi, NVT, Hi, DAG.getConstant(LVT.getSizeInBits(), TLI.getPointerTy())); - return DAG.getNode(ISD::OR, NVT, Lo, Hi); + return DAG.getNode(ISD::OR, dlHi, NVT, Lo, Hi); } /// LibCallify - Convert the node into a libcall with the same prototype. @@ -998,6 +1004,7 @@ SDValue DAGTypeLegalizer::MakeLibCall(RTLIB::Libcall LC, MVT RetVT, /// of the given type. A target boolean is an integer value, not necessarily of /// type i1, the bits of which conform to getBooleanContents. SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) { + DebugLoc dl = Bool.getNode()->getDebugLoc(); ISD::NodeType ExtendCode; switch (TLI.getBooleanContents()) { default: @@ -1016,7 +1023,7 @@ SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) { break; } } - return DAG.getNode(ExtendCode, VT, Bool); + return DAG.getNode(ExtendCode, dl, VT, Bool); } /// SplitInteger - Return the lower LoVT bits of Op in Lo and the upper HiVT @@ -1024,12 +1031,13 @@ SDValue DAGTypeLegalizer::PromoteTargetBoolean(SDValue Bool, MVT VT) { void DAGTypeLegalizer::SplitInteger(SDValue Op, MVT LoVT, MVT HiVT, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = Op.getNode()->getDebugLoc(); assert(LoVT.getSizeInBits() + HiVT.getSizeInBits() == Op.getValueType().getSizeInBits() && "Invalid integer splitting!"); - Lo = DAG.getNode(ISD::TRUNCATE, LoVT, Op); - Hi = DAG.getNode(ISD::SRL, Op.getValueType(), Op, + Lo = DAG.getNode(ISD::TRUNCATE, dl, LoVT, Op); + Hi = DAG.getNode(ISD::SRL, dl, Op.getValueType(), Op, DAG.getConstant(LoVT.getSizeInBits(), TLI.getPointerTy())); - Hi = DAG.getNode(ISD::TRUNCATE, HiVT, Hi); + Hi = DAG.getNode(ISD::TRUNCATE, dl, HiVT, Hi); } /// SplitInteger - Return the lower and upper halves of Op's bits in a value -- GitLab From 5f98ea28ca3d332ce5b0060c6b0710acc4ecb104 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 21:04:24 +0000 Subject: [PATCH 583/682] DebugLoc propagation. Done with file. llvm-svn: 63486 --- .../SelectionDAG/LegalizeTypesGeneric.cpp | 106 ++++++++++-------- 1 file changed, 61 insertions(+), 45 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index fb86875a5cdb..e1e539acd0af 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -36,6 +36,7 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, MVT NOutVT = TLI.getTypeToTransformTo(OutVT); SDValue InOp = N->getOperand(0); MVT InVT = InOp.getValueType(); + DebugLoc dl = N->getDebugLoc(); // Handle some special cases efficiently. switch (getTypeAction(InVT)) { @@ -47,15 +48,15 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, case SoftenFloat: // Convert the integer operand instead. SplitInteger(GetSoftenedFloat(InOp), Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi); return; case ExpandInteger: case ExpandFloat: // Convert the expanded pieces of the input. GetExpandedOp(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi); return; case SplitVector: // Convert the split parts of the input if it was split in two. @@ -63,16 +64,16 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, if (Lo.getValueType() == Hi.getValueType()) { if (TLI.isBigEndian()) std::swap(Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi); return; } break; case ScalarizeVector: // Convert the element instead. SplitInteger(BitConvertToInteger(GetScalarizedVector(InOp)), Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NOutVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, Hi); return; } @@ -88,18 +89,18 @@ void DAGTypeLegalizer::ExpandRes_BIT_CONVERT(SDNode *N, SDValue &Lo, const Value *SV = PseudoSourceValue::getFixedStack(SPFI); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, StackPtr, SV, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, StackPtr, SV, 0); // Load the first half from the stack slot. - Lo = DAG.getLoad(NOutVT, Store, StackPtr, SV, 0); + Lo = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, 0); // Increment the pointer to the other half. unsigned IncrementSize = NOutVT.getSizeInBits() / 8; - StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr, + StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, DAG.getIntPtrConstant(IncrementSize)); // Load the second half from the stack slot. - Hi = DAG.getLoad(NOutVT, Store, StackPtr, SV, IncrementSize, false, + Hi = DAG.getLoad(NOutVT, dl, Store, StackPtr, SV, IncrementSize, false, MinAlign(Alignment, IncrementSize)); // Handle endianness of the load. @@ -119,14 +120,15 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_ELEMENT(SDNode *N, SDValue &Lo, GetExpandedOp(N->getOperand(0), Lo, Hi); SDValue Part = cast(N->getOperand(1))->getZExtValue() ? Hi : Lo; + DebugLoc dl = N->getDebugLoc(); assert(Part.getValueType() == N->getValueType(0) && "Type twice as big as expanded type not itself expanded!"); MVT NVT = TLI.getTypeToTransformTo(N->getValueType(0)); - Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Part, + Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Part, DAG.getConstant(0, TLI.getPointerTy())); - Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, NVT, Part, + Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Part, DAG.getConstant(1, TLI.getPointerTy())); } @@ -134,13 +136,14 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue OldVec = N->getOperand(0); unsigned OldElts = OldVec.getValueType().getVectorNumElements(); + DebugLoc dl = N->getDebugLoc(); // Convert to a vector of the expanded element type, for example // <3 x i64> -> <6 x i32>. MVT OldVT = N->getValueType(0); MVT NewVT = TLI.getTypeToTransformTo(OldVT); - SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, + SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, MVT::getVectorVT(NewVT, 2*OldElts), OldVec); @@ -149,14 +152,14 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo, // Make sure the type of Idx is big enough to hold the new values. if (Idx.getValueType().bitsLT(TLI.getPointerTy())) - Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx); + Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx); - Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); + Lo = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx); - Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, + Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, DAG.getConstant(1, Idx.getValueType())); - Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, NewVec, Idx); + Hi = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, NewVec, Idx); if (TLI.isBigEndian()) std::swap(Lo, Hi); @@ -165,6 +168,7 @@ void DAGTypeLegalizer::ExpandRes_EXTRACT_VECTOR_ELT(SDNode *N, SDValue &Lo, void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo, SDValue &Hi) { assert(ISD::isNormalLoad(N) && "This routine only for normal loads!"); + DebugLoc dl = N->getDebugLoc(); LoadSDNode *LD = cast(N); MVT NVT = TLI.getTypeToTransformTo(LD->getValueType(0)); @@ -176,19 +180,20 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo, assert(NVT.isByteSized() && "Expanded type not byte sized!"); - Lo = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset, + Lo = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset, isVolatile, Alignment); // Increment the pointer to the other half. unsigned IncrementSize = NVT.getSizeInBits() / 8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getLoad(NVT, Chain, Ptr, LD->getSrcValue(), SVOffset+IncrementSize, + Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), + SVOffset+IncrementSize, isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. - Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Chain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); // Handle endianness of the load. @@ -223,6 +228,7 @@ void DAGTypeLegalizer::ExpandRes_VAARG(SDNode *N, SDValue &Lo, SDValue &Hi) { //===--------------------------------------------------------------------===// SDValue DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); if (N->getValueType(0).isVector()) { // An illegal expanding type is being converted to a legal vector type. // Make a two element vector out of the expanded parts and convert that @@ -239,8 +245,8 @@ SDValue DAGTypeLegalizer::ExpandOp_BIT_CONVERT(SDNode *N) { if (TLI.isBigEndian()) std::swap(Parts[0], Parts[1]); - SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, NVT, Parts, 2); - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Vec); + SDValue Vec = DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, Parts, 2); + return DAG.getNode(ISD::BIT_CONVERT, dl, N->getValueType(0), Vec); } } @@ -254,6 +260,7 @@ SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) { unsigned NumElts = VecVT.getVectorNumElements(); MVT OldVT = N->getOperand(0).getValueType(); MVT NewVT = TLI.getTypeToTransformTo(OldVT); + DebugLoc dl = N->getDebugLoc(); // Build a vector of twice the length out of the expanded elements. // For example <3 x i64> -> <6 x i32>. @@ -269,12 +276,12 @@ SDValue DAGTypeLegalizer::ExpandOp_BUILD_VECTOR(SDNode *N) { NewElts.push_back(Hi); } - SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, + SDValue NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::getVectorVT(NewVT, NewElts.size()), &NewElts[0], NewElts.size()); // Convert the new vector to the old vector type. - return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec); + return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); } SDValue DAGTypeLegalizer::ExpandOp_EXTRACT_ELEMENT(SDNode *N) { @@ -287,6 +294,7 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) { // The vector type is legal but the element type needs expansion. MVT VecVT = N->getValueType(0); unsigned NumElts = VecVT.getVectorNumElements(); + DebugLoc dl = N->getDebugLoc(); SDValue Val = N->getOperand(1); MVT OldEVT = Val.getValueType(); @@ -298,7 +306,8 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) { // Bitconvert to a vector of twice the length with elements of the expanded // type, insert the expanded vector elements, and then convert back. MVT NewVecVT = MVT::getVectorVT(NewEVT, NumElts*2); - SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, N->getOperand(0)); + SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, + NewVecVT, N->getOperand(0)); SDValue Lo, Hi; GetExpandedOp(Val, Lo, Hi); @@ -306,29 +315,32 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) { std::swap(Lo, Hi); SDValue Idx = N->getOperand(2); - Idx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, Idx); - NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, NewVec, Lo, Idx); - Idx = DAG.getNode(ISD::ADD,Idx.getValueType(), Idx, DAG.getIntPtrConstant(1)); - NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, NewVec, Hi, Idx); + Idx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, Idx); + NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Lo, Idx); + Idx = DAG.getNode(ISD::ADD, dl, + Idx.getValueType(), Idx, DAG.getIntPtrConstant(1)); + NewVec = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, NewVec, Hi, Idx); // Convert the new vector to the old vector type. - return DAG.getNode(ISD::BIT_CONVERT, VecVT, NewVec); + return DAG.getNode(ISD::BIT_CONVERT, dl, VecVT, NewVec); } SDValue DAGTypeLegalizer::ExpandOp_SCALAR_TO_VECTOR(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); MVT VT = N->getValueType(0); unsigned NumElts = VT.getVectorNumElements(); SmallVector Ops(NumElts); Ops[0] = N->getOperand(0); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, Ops[0].getValueType()); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, Ops[0].getValueType()); for (unsigned i = 1; i < NumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts); } SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { assert(ISD::isNormalStore(N) && "This routine only for normal stores!"); assert(OpNo == 1 && "Can only expand the stored value so far"); + DebugLoc dl = N->getDebugLoc(); StoreSDNode *St = cast(N); MVT NVT = TLI.getTypeToTransformTo(St->getValue().getValueType()); @@ -347,16 +359,17 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { if (TLI.isBigEndian()) std::swap(Lo, Hi); - Lo = DAG.getStore(Chain, Lo, Ptr, St->getSrcValue(), SVOffset, + Lo = DAG.getStore(Chain, dl, Lo, Ptr, St->getSrcValue(), SVOffset, isVolatile, Alignment); - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); - Hi = DAG.getStore(Chain, Hi, Ptr, St->getSrcValue(), SVOffset + IncrementSize, + Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(), + SVOffset + IncrementSize, isVolatile, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } @@ -393,29 +406,32 @@ void DAGTypeLegalizer::SplitRes_MERGE_VALUES(SDNode *N, void DAGTypeLegalizer::SplitRes_SELECT(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue LL, LH, RL, RH; + DebugLoc dl = N->getDebugLoc(); GetSplitOp(N->getOperand(1), LL, LH); GetSplitOp(N->getOperand(2), RL, RH); SDValue Cond = N->getOperand(0); - Lo = DAG.getNode(ISD::SELECT, LL.getValueType(), Cond, LL, RL); - Hi = DAG.getNode(ISD::SELECT, LH.getValueType(), Cond, LH, RH); + Lo = DAG.getNode(ISD::SELECT, dl, LL.getValueType(), Cond, LL, RL); + Hi = DAG.getNode(ISD::SELECT, dl, LH.getValueType(), Cond, LH, RH); } void DAGTypeLegalizer::SplitRes_SELECT_CC(SDNode *N, SDValue &Lo, SDValue &Hi) { SDValue LL, LH, RL, RH; + DebugLoc dl = N->getDebugLoc(); GetSplitOp(N->getOperand(2), LL, LH); GetSplitOp(N->getOperand(3), RL, RH); - Lo = DAG.getNode(ISD::SELECT_CC, LL.getValueType(), N->getOperand(0), + Lo = DAG.getNode(ISD::SELECT_CC, dl, LL.getValueType(), N->getOperand(0), N->getOperand(1), LL, RL, N->getOperand(4)); - Hi = DAG.getNode(ISD::SELECT_CC, LH.getValueType(), N->getOperand(0), + Hi = DAG.getNode(ISD::SELECT_CC, dl, LH.getValueType(), N->getOperand(0), N->getOperand(1), LH, RH, N->getOperand(4)); } void DAGTypeLegalizer::SplitRes_UNDEF(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT LoVT, HiVT; + DebugLoc dl = N->getDebugLoc(); GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); - Lo = DAG.getNode(ISD::UNDEF, LoVT); - Hi = DAG.getNode(ISD::UNDEF, HiVT); + Lo = DAG.getNode(ISD::UNDEF, dl, LoVT); + Hi = DAG.getNode(ISD::UNDEF, dl, HiVT); } -- GitLab From f23908151ab246c9ddbc55aea7345801fbdf531e Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Sat, 31 Jan 2009 21:30:05 +0000 Subject: [PATCH 584/682] Reinstate this optimization to fold icmp of xor when possible. Don't try to turn icmp eq a+x, b+x into icmp eq a, b if a+x or b+x has other uses. This may have been increasing register pressure leading to the bzip2 slowdown. llvm-svn: 63487 --- .../Scalar/InstructionCombining.cpp | 55 +++++++++++++++++-- .../InstCombine/2008-08-17-ICmpXorSignbit.ll | 1 - .../InstCombine/2009-01-31-Pressure.ll | 22 ++++++++ 3 files changed, 72 insertions(+), 6 deletions(-) create mode 100644 llvm/test/Transforms/InstCombine/2009-01-31-Pressure.ll diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index 8b9c59994779..a1cb3dc39fc4 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -6095,18 +6095,40 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { if (BinaryOperator *Op0I = dyn_cast(Op0)) { if (BinaryOperator *Op1I = dyn_cast(Op1)) { if (Op0I->getOpcode() == Op1I->getOpcode() && Op0I->hasOneUse() && - Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1) && - I.isEquality()) { + Op1I->hasOneUse() && Op0I->getOperand(1) == Op1I->getOperand(1)) { switch (Op0I->getOpcode()) { default: break; case Instruction::Add: case Instruction::Sub: case Instruction::Xor: - // a+x icmp eq/ne b+x --> a icmp b - return new ICmpInst(I.getPredicate(), Op0I->getOperand(0), - Op1I->getOperand(0)); + if (I.isEquality()) { + // a+x icmp eq/ne b+x --> a icmp b + return new ICmpInst(I.getPredicate(), Op0I->getOperand(0), + Op1I->getOperand(0)); + } else { + // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b + if (ConstantInt *CI = dyn_cast(Op0I->getOperand(1))) { + if (CI->getValue().isSignBit()) { + ICmpInst::Predicate Pred = I.isSignedPredicate() + ? I.getUnsignedPredicate() + : I.getSignedPredicate(); + return new ICmpInst(Pred, Op0I->getOperand(0), + Op1I->getOperand(0)); + } else if ((~CI->getValue()).isSignBit()) { + ICmpInst::Predicate Pred = I.isSignedPredicate() + ? I.getUnsignedPredicate() + : I.getSignedPredicate(); + Pred = I.getSwappedPredicate(Pred); + return new ICmpInst(Pred, Op0I->getOperand(0), + Op1I->getOperand(0)); + } + } + } break; case Instruction::Mul: + if (!I.isEquality()) + break; + if (ConstantInt *CI = dyn_cast(Op0I->getOperand(1))) { // a * Cst icmp eq/ne b * Cst --> a & Mask icmp b & Mask // Mask = -1 >> count-trailing-zeros(Cst). @@ -6425,6 +6447,29 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, else return new ICmpInst(ICmpInst::ICMP_SLT, CompareVal, AddOne(RHS)); } + + if (LHSI->hasOneUse()) { + // (icmp u/s (xor A SignBit), C) -> (icmp s/u A, (xor C SignBit)) + if (!ICI.isEquality() && XorCST->getValue().isSignBit()) { + const APInt &SignBit = XorCST->getValue(); + ICmpInst::Predicate Pred = ICI.isSignedPredicate() + ? ICI.getUnsignedPredicate() + : ICI.getSignedPredicate(); + return new ICmpInst(Pred, LHSI->getOperand(0), + ConstantInt::get(RHSV ^ SignBit)); + } + + // (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A) + if (!ICI.isEquality() && (~XorCST->getValue()).isSignBit()) { + const APInt &NotSignBit = XorCST->getValue(); + ICmpInst::Predicate Pred = ICI.isSignedPredicate() + ? ICI.getUnsignedPredicate() + : ICI.getSignedPredicate(); + Pred = ICI.getSwappedPredicate(Pred); + return new ICmpInst(Pred, LHSI->getOperand(0), + ConstantInt::get(RHSV ^ NotSignBit)); + } + } } break; case Instruction::And: // (icmp pred (and X, AndCST), RHS) diff --git a/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll b/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll index 1540d41a2652..428a35947d1d 100644 --- a/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll +++ b/llvm/test/Transforms/InstCombine/2008-08-17-ICmpXorSignbit.ll @@ -1,5 +1,4 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis | not grep xor -; XFAIL: * define i1 @test1(i8 %x, i8 %y) { %X = xor i8 %x, 128 diff --git a/llvm/test/Transforms/InstCombine/2009-01-31-Pressure.ll b/llvm/test/Transforms/InstCombine/2009-01-31-Pressure.ll new file mode 100644 index 000000000000..0c3066bb90c9 --- /dev/null +++ b/llvm/test/Transforms/InstCombine/2009-01-31-Pressure.ll @@ -0,0 +1,22 @@ +; RUN: llvm-as < %s | opt -instcombine | llvm-dis | grep {%B = add i8 %b, %x} +; PR2698 + +declare void @use1(i1) +declare void @use8(i8) + +define void @test1(i8 %a, i8 %b, i8 %x) { + %A = add i8 %a, %x + %B = add i8 %b, %x + %C = icmp eq i8 %A, %B + call void @use1(i1 %C) + ret void +} + +define void @test2(i8 %a, i8 %b, i8 %x) { + %A = add i8 %a, %x + %B = add i8 %b, %x + %C = icmp eq i8 %A, %B + call void @use1(i1 %C) + call void @use8(i8 %A) + ret void +} -- GitLab From dfbb6a1a9aa3a05e4dd3a35e1f0b2e242e9aa4f8 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Sat, 31 Jan 2009 22:04:51 +0000 Subject: [PATCH 585/682] DebugLoc propagation. llvm-svn: 63488 --- llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 6 +- .../SelectionDAG/LegalizeVectorTypes.cpp | 406 ++++++++++-------- 2 files changed, 233 insertions(+), 179 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index cdbf231911a7..4fe5ae217b73 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -631,11 +631,12 @@ private: /// isVolatile: volatile load. /// LdWidth: width of memory that we want to load. /// ResType: the wider result result type for the resulting vector. + /// dl: DebugLoc to be applied to new nodes SDValue GenWidenVectorLoads(SmallVector& LdChain, SDValue Chain, SDValue BasePtr, const Value *SV, int SVOffset, unsigned Alignment, bool isVolatile, unsigned LdWidth, - MVT ResType); + MVT ResType, DebugLoc dl); /// Helper genWidenVectorStores - Helper function to generate a set of /// stores to store a widen vector into non widen memory @@ -649,11 +650,12 @@ private: /// isVolatile: volatile lod /// ValOp: value to store /// StWidth: width of memory that we want to store + /// dl: DebugLoc to be applied to new nodes void GenWidenVectorStores(SmallVector& StChain, SDValue Chain, SDValue BasePtr, const Value *SV, int SVOffset, unsigned Alignment, bool isVolatile, SDValue ValOp, - unsigned StWidth); + unsigned StWidth, DebugLoc dl); /// Modifies a vector input (widen or narrows) to a vector of NVT. The /// input vector must have the same element type as NVT. diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index ac814f285761..dac4fc5c1f6e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -105,18 +105,21 @@ void DAGTypeLegalizer::ScalarizeVectorResult(SDNode *N, unsigned ResNo) { SDValue DAGTypeLegalizer::ScalarizeVecRes_BinOp(SDNode *N) { SDValue LHS = GetScalarizedVector(N->getOperand(0)); SDValue RHS = GetScalarizedVector(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, RHS); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), + LHS.getValueType(), LHS, RHS); } SDValue DAGTypeLegalizer::ScalarizeVecRes_ShiftOp(SDNode *N) { SDValue LHS = GetScalarizedVector(N->getOperand(0)); SDValue ShiftAmt = GetScalarizedVector(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), LHS.getValueType(), LHS, ShiftAmt); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), + LHS.getValueType(), LHS, ShiftAmt); } SDValue DAGTypeLegalizer::ScalarizeVecRes_BIT_CONVERT(SDNode *N) { MVT NewVT = N->getValueType(0).getVectorElementType(); - return DAG.getNode(ISD::BIT_CONVERT, NewVT, N->getOperand(0)); + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), + NewVT, N->getOperand(0)); } SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) { @@ -130,14 +133,15 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_CONVERT_RNDSAT(SDNode *N) { } SDValue DAGTypeLegalizer::ScalarizeVecRes_EXTRACT_SUBVECTOR(SDNode *N) { - return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(), N->getValueType(0).getVectorElementType(), N->getOperand(0), N->getOperand(1)); } SDValue DAGTypeLegalizer::ScalarizeVecRes_FPOWI(SDNode *N) { SDValue Op = GetScalarizedVector(N->getOperand(0)); - return DAG.getNode(ISD::FPOWI, Op.getValueType(), Op, N->getOperand(1)); + return DAG.getNode(ISD::FPOWI, N->getDebugLoc(), + Op.getValueType(), Op, N->getOperand(1)); } SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) { @@ -147,17 +151,18 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_INSERT_VECTOR_ELT(SDNode *N) { MVT EltVT = N->getValueType(0).getVectorElementType(); if (Op.getValueType() != EltVT) // FIXME: Can this happen for floating point types? - Op = DAG.getNode(ISD::TRUNCATE, EltVT, Op); + Op = DAG.getNode(ISD::TRUNCATE, N->getDebugLoc(), EltVT, Op); return Op; } SDValue DAGTypeLegalizer::ScalarizeVecRes_LOAD(LoadSDNode *N) { assert(N->isUnindexed() && "Indexed vector load?"); - SDValue Result = DAG.getLoad(ISD::UNINDEXED, N->getExtensionType(), + SDValue Result = DAG.getLoad(ISD::UNINDEXED, N->getDebugLoc(), + N->getExtensionType(), N->getValueType(0).getVectorElementType(), N->getChain(), N->getBasePtr(), - DAG.getNode(ISD::UNDEF, + DAG.getNode(ISD::UNDEF, N->getDebugLoc(), N->getBasePtr().getValueType()), N->getSrcValue(), N->getSrcValueOffset(), N->getMemoryVT().getVectorElementType(), @@ -173,7 +178,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_UnaryOp(SDNode *N) { // Get the dest type - it doesn't always match the input type, e.g. int_to_fp. MVT DestVT = N->getValueType(0).getVectorElementType(); SDValue Op = GetScalarizedVector(N->getOperand(0)); - return DAG.getNode(N->getOpcode(), DestVT, Op); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), DestVT, Op); } SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) { @@ -182,27 +187,30 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_SCALAR_TO_VECTOR(SDNode *N) { SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT(SDNode *N) { SDValue LHS = GetScalarizedVector(N->getOperand(1)); - return DAG.getNode(ISD::SELECT, LHS.getValueType(), N->getOperand(0), LHS, + return DAG.getNode(ISD::SELECT, N->getDebugLoc(), + LHS.getValueType(), N->getOperand(0), LHS, GetScalarizedVector(N->getOperand(2))); } SDValue DAGTypeLegalizer::ScalarizeVecRes_SELECT_CC(SDNode *N) { SDValue LHS = GetScalarizedVector(N->getOperand(2)); - return DAG.getNode(ISD::SELECT_CC, LHS.getValueType(), + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), LHS.getValueType(), N->getOperand(0), N->getOperand(1), LHS, GetScalarizedVector(N->getOperand(3)), N->getOperand(4)); } SDValue DAGTypeLegalizer::ScalarizeVecRes_UNDEF(SDNode *N) { - return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType()); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + N->getValueType(0).getVectorElementType()); } SDValue DAGTypeLegalizer::ScalarizeVecRes_VECTOR_SHUFFLE(SDNode *N) { // Figure out if the scalar is the LHS or RHS and return it. SDValue Arg = N->getOperand(2).getOperand(0); if (Arg.getOpcode() == ISD::UNDEF) - return DAG.getNode(ISD::UNDEF, N->getValueType(0).getVectorElementType()); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + N->getValueType(0).getVectorElementType()); unsigned Op = !cast(Arg)->isNullValue(); return GetScalarizedVector(N->getOperand(Op)); } @@ -212,9 +220,10 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) { SDValue RHS = GetScalarizedVector(N->getOperand(1)); MVT NVT = N->getValueType(0).getVectorElementType(); MVT SVT = TLI.getSetCCResultType(LHS.getValueType()); + DebugLoc dl = N->getDebugLoc(); // Turn it into a scalar SETCC. - SDValue Res = DAG.getNode(ISD::SETCC, SVT, LHS, RHS, N->getOperand(2)); + SDValue Res = DAG.getNode(ISD::SETCC, dl, SVT, LHS, RHS, N->getOperand(2)); // VSETCC always returns a sign-extended value, while SETCC may not. The // SETCC result type may not match the vector element type. Correct these. @@ -223,18 +232,18 @@ SDValue DAGTypeLegalizer::ScalarizeVecRes_VSETCC(SDNode *N) { // Ensure the SETCC result is sign-extended. if (TLI.getBooleanContents() != TargetLowering::ZeroOrNegativeOneBooleanContent) - Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, SVT, Res, + Res = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, SVT, Res, DAG.getValueType(MVT::i1)); // Truncate to the final type. - return DAG.getNode(ISD::TRUNCATE, NVT, Res); + return DAG.getNode(ISD::TRUNCATE, dl, NVT, Res); } else { // The SETCC result type is smaller than the vector element type. // If the SetCC result is not sign-extended, chop it down to MVT::i1. if (TLI.getBooleanContents() != TargetLowering::ZeroOrNegativeOneBooleanContent) - Res = DAG.getNode(ISD::TRUNCATE, MVT::i1, Res); + Res = DAG.getNode(ISD::TRUNCATE, dl, MVT::i1, Res); // Sign extend to the final type. - return DAG.getNode(ISD::SIGN_EXTEND, NVT, Res); + return DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Res); } } @@ -291,7 +300,8 @@ bool DAGTypeLegalizer::ScalarizeVectorOperand(SDNode *N, unsigned OpNo) { /// to be scalarized, it must be <1 x ty>. Convert the element instead. SDValue DAGTypeLegalizer::ScalarizeVecOp_BIT_CONVERT(SDNode *N) { SDValue Elt = GetScalarizedVector(N->getOperand(0)); - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), Elt); + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), + N->getValueType(0), Elt); } /// ScalarizeVecOp_CONCAT_VECTORS - The vectors to concatenate have length one - @@ -300,7 +310,7 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_CONCAT_VECTORS(SDNode *N) { SmallVector Ops(N->getNumOperands()); for (unsigned i = 0, e = N->getNumOperands(); i < e; ++i) Ops[i] = GetScalarizedVector(N->getOperand(i)); - return DAG.getNode(ISD::BUILD_VECTOR, N->getValueType(0), + return DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), N->getValueType(0), &Ops[0], Ops.size()); } @@ -316,16 +326,17 @@ SDValue DAGTypeLegalizer::ScalarizeVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDValue DAGTypeLegalizer::ScalarizeVecOp_STORE(StoreSDNode *N, unsigned OpNo){ assert(N->isUnindexed() && "Indexed store of one-element vector?"); assert(OpNo == 1 && "Do not know how to scalarize this operand!"); + DebugLoc dl = N->getDebugLoc(); if (N->isTruncatingStore()) - return DAG.getTruncStore(N->getChain(), + return DAG.getTruncStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)), N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), N->getMemoryVT().getVectorElementType(), N->isVolatile(), N->getAlignment()); - return DAG.getStore(N->getChain(), GetScalarizedVector(N->getOperand(1)), + return DAG.getStore(N->getChain(), dl, GetScalarizedVector(N->getOperand(1)), N->getBasePtr(), N->getSrcValue(), N->getSrcValueOffset(), N->isVolatile(), N->getAlignment()); } @@ -421,9 +432,10 @@ void DAGTypeLegalizer::SplitVecRes_BinOp(SDNode *N, SDValue &Lo, GetSplitVector(N->getOperand(0), LHSLo, LHSHi); SDValue RHSLo, RHSHi; GetSplitVector(N->getOperand(1), RHSLo, RHSHi); + DebugLoc dl = N->getDebugLoc(); - Lo = DAG.getNode(N->getOpcode(), LHSLo.getValueType(), LHSLo, RHSLo); - Hi = DAG.getNode(N->getOpcode(), LHSHi.getValueType(), LHSHi, RHSHi); + Lo = DAG.getNode(N->getOpcode(), dl, LHSLo.getValueType(), LHSLo, RHSLo); + Hi = DAG.getNode(N->getOpcode(), dl, LHSHi.getValueType(), LHSHi, RHSHi); } void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo, @@ -432,6 +444,7 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo, // scalar value. MVT LoVT, HiVT; GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); + DebugLoc dl = N->getDebugLoc(); SDValue InOp = N->getOperand(0); MVT InVT = InOp.getValueType(); @@ -454,8 +467,8 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo, GetExpandedOp(InOp, Lo, Hi); if (TLI.isBigEndian()) std::swap(Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi); return; } break; @@ -463,8 +476,8 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo, // If the input is a vector that needs to be split, convert each split // piece of the input now. GetSplitVector(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi); return; } @@ -478,25 +491,27 @@ void DAGTypeLegalizer::SplitVecRes_BIT_CONVERT(SDNode *N, SDValue &Lo, if (TLI.isBigEndian()) std::swap(Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, LoVT, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, HiVT, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, LoVT, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, HiVT, Hi); } void DAGTypeLegalizer::SplitVecRes_BUILD_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT LoVT, HiVT; + DebugLoc dl = N->getDebugLoc(); GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); unsigned LoNumElts = LoVT.getVectorNumElements(); SmallVector LoOps(N->op_begin(), N->op_begin()+LoNumElts); - Lo = DAG.getNode(ISD::BUILD_VECTOR, LoVT, &LoOps[0], LoOps.size()); + Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, LoVT, &LoOps[0], LoOps.size()); SmallVector HiOps(N->op_begin()+LoNumElts, N->op_end()); - Hi = DAG.getNode(ISD::BUILD_VECTOR, HiVT, &HiOps[0], HiOps.size()); + Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, HiVT, &HiOps[0], HiOps.size()); } void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, SDValue &Hi) { assert(!(N->getNumOperands() & 1) && "Unsupported CONCAT_VECTORS"); + DebugLoc dl = N->getDebugLoc(); unsigned NumSubvectors = N->getNumOperands() / 2; if (NumSubvectors == 1) { Lo = N->getOperand(0); @@ -508,10 +523,10 @@ void DAGTypeLegalizer::SplitVecRes_CONCAT_VECTORS(SDNode *N, SDValue &Lo, GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); SmallVector LoOps(N->op_begin(), N->op_begin()+NumSubvectors); - Lo = DAG.getNode(ISD::CONCAT_VECTORS, LoVT, &LoOps[0], LoOps.size()); + Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, LoVT, &LoOps[0], LoOps.size()); SmallVector HiOps(N->op_begin()+NumSubvectors, N->op_end()); - Hi = DAG.getNode(ISD::CONCAT_VECTORS, HiVT, &HiOps[0], HiOps.size()); + Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, HiVT, &HiOps[0], HiOps.size()); } void DAGTypeLegalizer::SplitVecRes_CONVERT_RNDSAT(SDNode *N, SDValue &Lo, @@ -538,6 +553,7 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, SDValue Vec = N->getOperand(0); SDValue Idx = N->getOperand(1); MVT IdxVT = Idx.getValueType(); + DebugLoc dl = N->getDebugLoc(); MVT LoVT, HiVT; GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); @@ -545,17 +561,18 @@ void DAGTypeLegalizer::SplitVecRes_EXTRACT_SUBVECTOR(SDNode *N, SDValue &Lo, // size unless the original vector type was split in two. assert(LoVT == HiVT && "Non power-of-two vectors not supported!"); - Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, LoVT, Vec, Idx); - Idx = DAG.getNode(ISD::ADD, IdxVT, Idx, + Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, LoVT, Vec, Idx); + Idx = DAG.getNode(ISD::ADD, dl, IdxVT, Idx, DAG.getConstant(LoVT.getVectorNumElements(), IdxVT)); - Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, HiVT, Vec, Idx); + Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, HiVT, Vec, Idx); } void DAGTypeLegalizer::SplitVecRes_FPOWI(SDNode *N, SDValue &Lo, SDValue &Hi) { + DebugLoc dl = N->getDebugLoc(); GetSplitVector(N->getOperand(0), Lo, Hi); - Lo = DAG.getNode(ISD::FPOWI, Lo.getValueType(), Lo, N->getOperand(1)); - Hi = DAG.getNode(ISD::FPOWI, Hi.getValueType(), Hi, N->getOperand(1)); + Lo = DAG.getNode(ISD::FPOWI, dl, Lo.getValueType(), Lo, N->getOperand(1)); + Hi = DAG.getNode(ISD::FPOWI, dl, Hi.getValueType(), Hi, N->getOperand(1)); } void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, @@ -563,15 +580,17 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, SDValue Vec = N->getOperand(0); SDValue Elt = N->getOperand(1); SDValue Idx = N->getOperand(2); + DebugLoc dl = N->getDebugLoc(); GetSplitVector(Vec, Lo, Hi); if (ConstantSDNode *CIdx = dyn_cast(Idx)) { unsigned IdxVal = CIdx->getZExtValue(); unsigned LoNumElts = Lo.getValueType().getVectorNumElements(); if (IdxVal < LoNumElts) - Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, Lo.getValueType(), Lo, Elt, Idx); + Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, + Lo.getValueType(), Lo, Elt, Idx); else - Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, Hi.getValueType(), Hi, Elt, + Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, Hi.getValueType(), Hi, Elt, DAG.getIntPtrConstant(IdxVal - LoNumElts)); return; } @@ -580,40 +599,42 @@ void DAGTypeLegalizer::SplitVecRes_INSERT_VECTOR_ELT(SDNode *N, SDValue &Lo, MVT VecVT = Vec.getValueType(); MVT EltVT = VecVT.getVectorElementType(); SDValue StackPtr = DAG.CreateStackTemporary(VecVT); - SDValue Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); // Store the new element. This may be larger than the vector element type, // so use a truncating store. SDValue EltPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); unsigned Alignment = TLI.getTargetData()->getPrefTypeAlignment(VecVT.getTypeForMVT()); - Store = DAG.getTruncStore(Store, Elt, EltPtr, NULL, 0, EltVT); + Store = DAG.getTruncStore(Store, dl, Elt, EltPtr, NULL, 0, EltVT); // Load the Lo part from the stack slot. - Lo = DAG.getLoad(Lo.getValueType(), Store, StackPtr, NULL, 0); + Lo = DAG.getLoad(Lo.getValueType(), dl, Store, StackPtr, NULL, 0); // Increment the pointer to the other part. unsigned IncrementSize = Lo.getValueType().getSizeInBits() / 8; - StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr, + StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, DAG.getIntPtrConstant(IncrementSize)); // Load the Hi part from the stack slot. - Hi = DAG.getLoad(Hi.getValueType(), Store, StackPtr, NULL, 0, false, + Hi = DAG.getLoad(Hi.getValueType(), dl, Store, StackPtr, NULL, 0, false, MinAlign(Alignment, IncrementSize)); } void DAGTypeLegalizer::SplitVecRes_SCALAR_TO_VECTOR(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT LoVT, HiVT; + DebugLoc dl = N->getDebugLoc(); GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); - Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, LoVT, N->getOperand(0)); - Hi = DAG.getNode(ISD::UNDEF, HiVT); + Lo = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, LoVT, N->getOperand(0)); + Hi = DAG.getNode(ISD::UNDEF, dl, HiVT); } void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, SDValue &Hi) { assert(ISD::isUNINDEXEDLoad(LD) && "Indexed load during type legalization!"); MVT LoVT, HiVT; + DebugLoc dl = LD->getDebugLoc(); GetSplitDestVTs(LD->getValueType(0), LoVT, HiVT); ISD::LoadExtType ExtType = LD->getExtensionType(); @@ -629,20 +650,20 @@ void DAGTypeLegalizer::SplitVecRes_LOAD(LoadSDNode *LD, SDValue &Lo, MVT LoMemVT, HiMemVT; GetSplitDestVTs(MemoryVT, LoMemVT, HiMemVT); - Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, LoVT, Ch, Ptr, Offset, + Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, LoVT, Ch, Ptr, Offset, SV, SVOffset, LoMemVT, isVolatile, Alignment); unsigned IncrementSize = LoMemVT.getSizeInBits()/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; Alignment = MinAlign(Alignment, IncrementSize); - Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, HiVT, Ch, Ptr, Offset, + Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, HiVT, Ch, Ptr, Offset, SV, SVOffset, HiMemVT, isVolatile, Alignment); // Build a factor node to remember that this load is independent of the // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); // Legalized the chain result - switch anything that used the old chain to @@ -654,6 +675,7 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo, SDValue &Hi) { // Get the dest types - they may not match the input types, e.g. int_to_fp. MVT LoVT, HiVT; + DebugLoc dl = N->getDebugLoc(); GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); // Split the input. @@ -664,9 +686,9 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo, assert(LoVT == HiVT && "Legal non-power-of-two vector type?"); MVT InNVT = MVT::getVectorVT(InVT.getVectorElementType(), LoVT.getVectorNumElements()); - Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, InNVT, N->getOperand(0), + Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0), DAG.getIntPtrConstant(0)); - Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, InNVT, N->getOperand(0), + Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InNVT, N->getOperand(0), DAG.getIntPtrConstant(InNVT.getVectorNumElements())); break; } @@ -675,14 +697,15 @@ void DAGTypeLegalizer::SplitVecRes_UnaryOp(SDNode *N, SDValue &Lo, break; } - Lo = DAG.getNode(N->getOpcode(), LoVT, Lo); - Hi = DAG.getNode(N->getOpcode(), HiVT, Hi); + Lo = DAG.getNode(N->getOpcode(), dl, LoVT, Lo); + Hi = DAG.getNode(N->getOpcode(), dl, HiVT, Hi); } void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, SDValue &Hi) { // The low and high parts of the original input give four input vectors. SDValue Inputs[4]; + DebugLoc dl = N->getDebugLoc(); GetSplitVector(N->getOperand(0), Inputs[0], Inputs[1]); GetSplitVector(N->getOperand(1), Inputs[2], Inputs[3]); MVT NewVT = Inputs[0].getValueType(); @@ -719,7 +742,7 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, if (Input >= array_lengthof(Inputs)) { // The mask element does not index into any input vector. - Ops.push_back(DAG.getNode(ISD::UNDEF, IdxVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, dl, IdxVT)); continue; } @@ -767,7 +790,7 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, if (Input >= array_lengthof(Inputs)) { // The mask element is "undef" or indexes off the end of the input. - Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT)); continue; } @@ -775,25 +798,25 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, Idx -= Input * NewElts; // Extract the vector element by hand. - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Inputs[Input], DAG.getIntPtrConstant(Idx))); } // Construct the Lo/Hi output using a BUILD_VECTOR. - Output = DAG.getNode(ISD::BUILD_VECTOR, NewVT, &Ops[0], Ops.size()); + Output = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT, &Ops[0], Ops.size()); } else if (InputUsed[0] == -1U) { // No input vectors were used! The result is undefined. - Output = DAG.getNode(ISD::UNDEF, NewVT); + Output = DAG.getNode(ISD::UNDEF, dl, NewVT); } else { // At least one input vector was used. Create a new shuffle vector. - SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, + SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::getVectorVT(IdxVT, Ops.size()), &Ops[0], Ops.size()); SDValue Op0 = Inputs[InputUsed[0]]; // If only one input was used, use an undefined vector for the other. SDValue Op1 = InputUsed[1] == -1U ? - DAG.getNode(ISD::UNDEF, NewVT) : Inputs[InputUsed[1]]; - Output = DAG.getNode(ISD::VECTOR_SHUFFLE, NewVT, Op0, Op1, NewMask); + DAG.getNode(ISD::UNDEF, dl, NewVT) : Inputs[InputUsed[1]]; + Output = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, NewVT, Op0, Op1, NewMask); } Ops.clear(); @@ -803,14 +826,15 @@ void DAGTypeLegalizer::SplitVecRes_VECTOR_SHUFFLE(SDNode *N, SDValue &Lo, void DAGTypeLegalizer::SplitVecRes_VSETCC(SDNode *N, SDValue &Lo, SDValue &Hi) { MVT LoVT, HiVT; + DebugLoc dl = N->getDebugLoc(); GetSplitDestVTs(N->getValueType(0), LoVT, HiVT); SDValue LL, LH, RL, RH; GetSplitVector(N->getOperand(0), LL, LH); GetSplitVector(N->getOperand(1), RL, RH); - Lo = DAG.getNode(ISD::VSETCC, LoVT, LL, RL, N->getOperand(2)); - Hi = DAG.getNode(ISD::VSETCC, HiVT, LH, RH, N->getOperand(2)); + Lo = DAG.getNode(ISD::VSETCC, dl, LoVT, LL, RL, N->getOperand(2)); + Hi = DAG.getNode(ISD::VSETCC, dl, HiVT, LH, RH, N->getOperand(2)); } @@ -873,6 +897,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) { // The result has a legal vector type, but the input needs splitting. MVT ResVT = N->getValueType(0); SDValue Lo, Hi; + DebugLoc dl = N->getDebugLoc(); GetSplitVector(N->getOperand(0), Lo, Hi); assert(Lo.getValueType() == Hi.getValueType() && "Returns legal non-power-of-two vector type?"); @@ -881,10 +906,10 @@ SDValue DAGTypeLegalizer::SplitVecOp_UnaryOp(SDNode *N) { MVT OutVT = MVT::getVectorVT(ResVT.getVectorElementType(), InVT.getVectorNumElements()); - Lo = DAG.getNode(N->getOpcode(), OutVT, Lo); - Hi = DAG.getNode(N->getOpcode(), OutVT, Hi); + Lo = DAG.getNode(N->getOpcode(), dl, OutVT, Lo); + Hi = DAG.getNode(N->getOpcode(), dl, OutVT, Hi); - return DAG.getNode(ISD::CONCAT_VECTORS, ResVT, Lo, Hi); + return DAG.getNode(ISD::CONCAT_VECTORS, dl, ResVT, Lo, Hi); } SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) { @@ -899,7 +924,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_BIT_CONVERT(SDNode *N) { if (TLI.isBigEndian()) std::swap(Lo, Hi); - return DAG.getNode(ISD::BIT_CONVERT, N->getValueType(0), + return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), JoinIntegers(Lo, Hi)); } @@ -908,6 +933,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) { // is a constant. MVT SubVT = N->getValueType(0); SDValue Idx = N->getOperand(1); + DebugLoc dl = N->getDebugLoc(); SDValue Lo, Hi; GetSplitVector(N->getOperand(0), Lo, Hi); @@ -917,9 +943,9 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_SUBVECTOR(SDNode *N) { if (IdxVal < LoElts) { assert(IdxVal + SubVT.getVectorNumElements() <= LoElts && "Extracted subvector crosses vector split!"); - return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Lo, Idx); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Lo, Idx); } else { - return DAG.getNode(ISD::EXTRACT_SUBVECTOR, SubVT, Hi, + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, SubVT, Hi, DAG.getConstant(IdxVal - LoElts, Idx.getValueType())); } } @@ -948,17 +974,19 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { // Store the vector to the stack. MVT EltVT = VecVT.getVectorElementType(); + DebugLoc dl = N->getDebugLoc(); SDValue StackPtr = DAG.CreateStackTemporary(VecVT); - SDValue Store = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); // Load back the required element. StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); - return DAG.getLoad(EltVT, Store, StackPtr, NULL, 0); + return DAG.getLoad(EltVT, dl, Store, StackPtr, NULL, 0); } SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { assert(N->isUnindexed() && "Indexed store of vector?"); assert(OpNo == 1 && "Can only split the stored value"); + DebugLoc dl = N->getDebugLoc(); bool isTruncating = N->isTruncatingStore(); SDValue Ch = N->getChain(); @@ -976,31 +1004,32 @@ SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { unsigned IncrementSize = LoMemVT.getSizeInBits()/8; if (isTruncating) - Lo = DAG.getTruncStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, + Lo = DAG.getTruncStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, LoMemVT, isVol, Alignment); else - Lo = DAG.getStore(Ch, Lo, Ptr, N->getSrcValue(), SVOffset, + Lo = DAG.getStore(Ch, dl, Lo, Ptr, N->getSrcValue(), SVOffset, isVol, Alignment); // Increment the pointer to the other half. - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); if (isTruncating) - Hi = DAG.getTruncStore(Ch, Hi, Ptr, + Hi = DAG.getTruncStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, HiMemVT, isVol, MinAlign(Alignment, IncrementSize)); else - Hi = DAG.getStore(Ch, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, + Hi = DAG.getStore(Ch, dl, Hi, Ptr, N->getSrcValue(), SVOffset+IncrementSize, isVol, MinAlign(Alignment, IncrementSize)); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) { assert(OpNo == 2 && "Shuffle source type differs from result type?"); SDValue Mask = N->getOperand(2); + DebugLoc dl = N->getDebugLoc(); unsigned MaskLength = Mask.getValueType().getVectorNumElements(); unsigned LargestMaskEntryPlusOne = 2 * MaskLength; unsigned MinimumBitWidth = Log2_32_Ceil(LargestMaskEntryPlusOne); @@ -1039,7 +1068,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) { for (unsigned i = 0; i < MaskLength; ++i) { SDValue Arg = Mask.getOperand(i); if (Arg.getOpcode() == ISD::UNDEF) { - Ops[i] = DAG.getNode(ISD::UNDEF, OpVT); + Ops[i] = DAG.getNode(ISD::UNDEF, dl, OpVT); } else { uint64_t Idx = cast(Arg)->getZExtValue(); Ops[i] = DAG.getConstant(Idx, OpVT); @@ -1047,7 +1076,7 @@ SDValue DAGTypeLegalizer::SplitVecOp_VECTOR_SHUFFLE(SDNode *N, unsigned OpNo) { } return DAG.UpdateNodeOperands(SDValue(N,0), N->getOperand(0), N->getOperand(1), - DAG.getNode(ISD::BUILD_VECTOR, + DAG.getNode(ISD::BUILD_VECTOR, dl, VecVT, &Ops[0], Ops.size())); } @@ -1147,11 +1176,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_Binary(SDNode *N) { MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue InOp1 = GetWidenedVector(N->getOperand(0)); SDValue InOp2 = GetWidenedVector(N->getOperand(1)); - return DAG.getNode(N->getOpcode(), WidenVT, InOp1, InOp2); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp1, InOp2); } SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { SDValue InOp = N->getOperand(0); + DebugLoc dl = N->getDebugLoc(); MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0)); unsigned WidenNumElts = WidenVT.getVectorNumElements(); @@ -1168,7 +1198,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { InVT = InOp.getValueType(); InVTNumElts = InVT.getVectorNumElements(); if (InVTNumElts == WidenNumElts) - return DAG.getNode(Opcode, WidenVT, InOp); + return DAG.getNode(Opcode, dl, WidenVT, InOp); } if (TLI.isTypeLegal(InWidenVT)) { @@ -1182,19 +1212,19 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { unsigned NumConcat = WidenNumElts/InVTNumElts; SmallVector Ops(NumConcat); Ops[0] = InOp; - SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT); for (unsigned i = 1; i != NumConcat; ++i) Ops[i] = UndefVal; - return DAG.getNode(Opcode, WidenVT, - DAG.getNode(ISD::CONCAT_VECTORS, InWidenVT, + return DAG.getNode(Opcode, dl, WidenVT, + DAG.getNode(ISD::CONCAT_VECTORS, dl, InWidenVT, &Ops[0], NumConcat)); } if (InVTNumElts % WidenNumElts == 0) { // Extract the input and convert the shorten input vector. - return DAG.getNode(Opcode, WidenVT, - DAG.getNode(ISD::EXTRACT_SUBVECTOR, InWidenVT, InOp, - DAG.getIntPtrConstant(0))); + return DAG.getNode(Opcode, dl, WidenVT, + DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, InWidenVT, + InOp, DAG.getIntPtrConstant(0))); } } @@ -1204,15 +1234,15 @@ SDValue DAGTypeLegalizer::WidenVecRes_Convert(SDNode *N) { unsigned MinElts = std::min(InVTNumElts, WidenNumElts); unsigned i; for (i=0; i < MinElts; ++i) - Ops[i] = DAG.getNode(Opcode, EltVT, - DAG.getNode(ISD::EXTRACT_VECTOR_ELT, InEltVT, InOp, + Ops[i] = DAG.getNode(Opcode, dl, EltVT, + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, DAG.getIntPtrConstant(i))); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT); for (; i < WidenNumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) { @@ -1230,14 +1260,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_Shift(SDNode *N) { if (ShVT != ShWidenVT) ShOp = ModifyToType(ShOp, ShWidenVT); - return DAG.getNode(N->getOpcode(), WidenVT, InOp, ShOp); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp, ShOp); } SDValue DAGTypeLegalizer::WidenVecRes_Unary(SDNode *N) { // Unary op widening. MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0)); SDValue InOp = GetWidenedVector(N->getOperand(0)); - return DAG.getNode(N->getOpcode(), WidenVT, InOp); + return DAG.getNode(N->getOpcode(), N->getDebugLoc(), WidenVT, InOp); } SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { @@ -1245,6 +1275,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { MVT InVT = InOp.getValueType(); MVT VT = N->getValueType(0); MVT WidenVT = TLI.getTypeToTransformTo(VT); + DebugLoc dl = N->getDebugLoc(); switch (getTypeAction(InVT)) { default: @@ -1258,7 +1289,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { InOp = GetPromotedInteger(InOp); InVT = InOp.getValueType(); if (WidenVT.bitsEq(InVT)) - return DAG.getNode(ISD::BIT_CONVERT, WidenVT, InOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, InOp); break; case SoftenFloat: case ExpandInteger: @@ -1273,7 +1304,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { InVT = InOp.getValueType(); if (WidenVT.bitsEq(InVT)) // The input widens to the same size. Convert to the widen value. - return DAG.getNode(ISD::BIT_CONVERT, WidenVT, InOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, InOp); break; } @@ -1306,10 +1337,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { SDValue NewVec; if (InVT.isVector()) - NewVec = DAG.getNode(ISD::CONCAT_VECTORS, NewInVT, &Ops[0], NewNumElts); + NewVec = DAG.getNode(ISD::CONCAT_VECTORS, dl, + NewInVT, &Ops[0], NewNumElts); else - NewVec = DAG.getNode(ISD::BUILD_VECTOR, NewInVT, &Ops[0], NewNumElts); - return DAG.getNode(ISD::BIT_CONVERT, WidenVT, NewVec); + NewVec = DAG.getNode(ISD::BUILD_VECTOR, dl, + NewInVT, &Ops[0], NewNumElts); + return DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, NewVec); } } @@ -1319,13 +1352,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { SDValue FIPtr = DAG.CreateStackTemporary(InVT, WidenVT); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, NULL, 0); // Result is a load from the stack slot. - return DAG.getLoad(WidenVT, Store, FIPtr, NULL, 0); + return DAG.getLoad(WidenVT, dl, Store, FIPtr, NULL, 0); } SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) { + DebugLoc dl = N->getDebugLoc(); // Build a vector with undefined for the new nodes. MVT VT = N->getValueType(0); MVT EltVT = VT.getVectorElementType(); @@ -1337,14 +1371,15 @@ SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) { SmallVector NewOps(N->op_begin(), N->op_end()); NewOps.reserve(WidenNumElts); for (unsigned i = NumElts; i < WidenNumElts; ++i) - NewOps.push_back(DAG.getNode(ISD::UNDEF, EltVT)); + NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT)); - return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &NewOps[0], NewOps.size()); + return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &NewOps[0], NewOps.size()); } SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { MVT InVT = N->getOperand(0).getValueType(); MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0)); + DebugLoc dl = N->getDebugLoc(); unsigned WidenNumElts = WidenVT.getVectorNumElements(); unsigned NumOperands = N->getNumOperands(); @@ -1354,13 +1389,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { // Add undef vectors to widen to correct length. unsigned NumConcat = WidenVT.getVectorNumElements() / InVT.getVectorNumElements(); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT); SmallVector Ops(NumConcat); for (unsigned i=0; i < NumOperands; ++i) Ops[i] = N->getOperand(i); for (unsigned i = NumOperands; i != NumConcat; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::CONCAT_VECTORS, WidenVT, &Ops[0], NumConcat); + return DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &Ops[0], NumConcat); } } else { InputWidened = true; @@ -1384,10 +1419,10 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { MaskOps[i] = DAG.getConstant(i, PtrVT); MaskOps[i+WidenNumElts/2] = DAG.getConstant(i+WidenNumElts, PtrVT); } - SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, + SDValue Mask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::getVectorVT(PtrVT, WidenNumElts), &MaskOps[0], WidenNumElts); - return DAG.getNode(ISD::VECTOR_SHUFFLE, WidenVT, + return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, GetWidenedVector(N->getOperand(0)), GetWidenedVector(N->getOperand(1)), Mask); } @@ -1404,13 +1439,13 @@ SDValue DAGTypeLegalizer::WidenVecRes_CONCAT_VECTORS(SDNode *N) { if (InputWidened) InOp = GetWidenedVector(InOp); for (unsigned j=0; j < NumInElts; ++j) - Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, + Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, DAG.getIntPtrConstant(j)); } - SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT); for (; Idx < WidenNumElts; ++Idx) Ops[Idx] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_CONVERT_RNDSAT(SDNode *N) { @@ -1496,6 +1531,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { unsigned WidenNumElts = WidenVT.getVectorNumElements(); SDValue InOp = N->getOperand(0); SDValue Idx = N->getOperand(1); + DebugLoc dl = N->getDebugLoc(); if (getTypeAction(InOp.getValueType()) == WidenVector) InOp = GetWidenedVector(InOp); @@ -1512,7 +1548,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { // Check if we can extract from the vector. unsigned InNumElts = InVT.getVectorNumElements(); if (IdxVal % WidenNumElts == 0 && IdxVal + WidenNumElts < InNumElts) - return DAG.getNode(ISD::EXTRACT_SUBVECTOR, WidenVT, InOp, Idx); + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, InOp, Idx); } // We could try widening the input to the right length but for now, extract @@ -1525,26 +1561,27 @@ SDValue DAGTypeLegalizer::WidenVecRes_EXTRACT_SUBVECTOR(SDNode *N) { if (CIdx) { unsigned IdxVal = CIdx->getZExtValue(); for (i=0; i < NumElts; ++i) - Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, + Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, DAG.getConstant(IdxVal+i, IdxVT)); } else { - Ops[0] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, Idx); + Ops[0] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, Idx); for (i=1; i < NumElts; ++i) { - SDValue NewIdx = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, + SDValue NewIdx = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, DAG.getConstant(i, IdxVT)); - Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, NewIdx); + Ops[i] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, NewIdx); } } - SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT); for (; i < WidenNumElts; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], WidenNumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], WidenNumElts); } SDValue DAGTypeLegalizer::WidenVecRes_INSERT_VECTOR_ELT(SDNode *N) { SDValue InOp = GetWidenedVector(N->getOperand(0)); - return DAG.getNode(ISD::INSERT_VECTOR_ELT, InOp.getValueType(), InOp, + return DAG.getNode(ISD::INSERT_VECTOR_ELT, N->getDebugLoc(), + InOp.getValueType(), InOp, N->getOperand(1), N->getOperand(2)); } @@ -1552,6 +1589,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { LoadSDNode *LD = cast(N); MVT WidenVT = TLI.getTypeToTransformTo(LD->getValueType(0)); MVT LdVT = LD->getMemoryVT(); + DebugLoc dl = N->getDebugLoc(); assert(LdVT.isVector() && WidenVT.isVector()); // Load information @@ -1577,30 +1615,30 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { unsigned WidenNumElts = WidenVT.getVectorNumElements(); SmallVector Ops(WidenNumElts); unsigned Increment = LdEltVT.getSizeInBits() / 8; - Ops[0] = DAG.getExtLoad(ExtType, EltVT, Chain, BasePtr, SV, SVOffset, + Ops[0] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, BasePtr, SV, SVOffset, LdEltVT, isVolatile, Align); LdChain.push_back(Ops[0].getValue(1)); unsigned i = 0, Offset = Increment; for (i=1; i < NumElts; ++i, Offset += Increment) { - SDValue NewBasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), + SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Offset)); - Ops[i] = DAG.getExtLoad(ExtType, EltVT, Chain, NewBasePtr, SV, + Ops[i] = DAG.getExtLoad(ExtType, dl, EltVT, Chain, NewBasePtr, SV, SVOffset + Offset, LdEltVT, isVolatile, Align); LdChain.push_back(Ops[i].getValue(1)); } // Fill the rest with undefs - SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT); for (; i != WidenNumElts; ++i) Ops[i] = UndefVal; - Result = DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &Ops[0], Ops.size()); + Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, &Ops[0], Ops.size()); } else { assert(LdVT.getVectorElementType() == WidenVT.getVectorElementType()); unsigned int LdWidth = LdVT.getSizeInBits(); Result = GenWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset, - Align, isVolatile, LdWidth, WidenVT); -} + Align, isVolatile, LdWidth, WidenVT, dl); + } // If we generate a single load, we can use that for the chain. Otherwise, // build a factor node to remember the multiple loads are independent and @@ -1609,7 +1647,7 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { if (LdChain.size() == 1) NewChain = LdChain[0]; else - NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, &LdChain[0], + NewChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &LdChain[0], LdChain.size()); // Modified the chain - switch anything that used the old chain to use @@ -1621,7 +1659,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_LOAD(SDNode *N) { SDValue DAGTypeLegalizer::WidenVecRes_SCALAR_TO_VECTOR(SDNode *N) { MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0)); - return DAG.getNode(ISD::SCALAR_TO_VECTOR, WidenVT, N->getOperand(0)); + return DAG.getNode(ISD::SCALAR_TO_VECTOR, N->getDebugLoc(), + WidenVT, N->getOperand(0)); } SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) { @@ -1643,24 +1682,27 @@ SDValue DAGTypeLegalizer::WidenVecRes_SELECT(SDNode *N) { SDValue InOp1 = GetWidenedVector(N->getOperand(1)); SDValue InOp2 = GetWidenedVector(N->getOperand(2)); assert(InOp1.getValueType() == WidenVT && InOp2.getValueType() == WidenVT); - return DAG.getNode(ISD::SELECT, WidenVT, Cond1, InOp1, InOp2); + return DAG.getNode(ISD::SELECT, N->getDebugLoc(), + WidenVT, Cond1, InOp1, InOp2); } SDValue DAGTypeLegalizer::WidenVecRes_SELECT_CC(SDNode *N) { SDValue InOp1 = GetWidenedVector(N->getOperand(2)); SDValue InOp2 = GetWidenedVector(N->getOperand(3)); - return DAG.getNode(ISD::SELECT_CC, InOp1.getValueType(), N->getOperand(0), + return DAG.getNode(ISD::SELECT_CC, N->getDebugLoc(), + InOp1.getValueType(), N->getOperand(0), N->getOperand(1), InOp1, InOp2, N->getOperand(4)); } SDValue DAGTypeLegalizer::WidenVecRes_UNDEF(SDNode *N) { MVT WidenVT = TLI.getTypeToTransformTo(N->getValueType(0)); - return DAG.getNode(ISD::UNDEF, WidenVT); + return DAG.getNode(ISD::UNDEF, N->getDebugLoc(), WidenVT); } SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) { MVT VT = N->getValueType(0); unsigned NumElts = VT.getVectorNumElements(); + DebugLoc dl = N->getDebugLoc(); MVT WidenVT = TLI.getTypeToTransformTo(VT); unsigned WidenNumElts = WidenVT.getVectorNumElements(); @@ -1685,12 +1727,12 @@ SDValue DAGTypeLegalizer::WidenVecRes_VECTOR_SHUFFLE(SDNode *N) { } } for (unsigned i = NumElts; i < WidenNumElts; ++i) - MaskOps[i] = DAG.getNode(ISD::UNDEF, IdxVT); - SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, + MaskOps[i] = DAG.getNode(ISD::UNDEF, dl, IdxVT); + SDValue NewMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::getVectorVT(IdxVT, WidenNumElts), &MaskOps[0], WidenNumElts); - return DAG.getNode(ISD::VECTOR_SHUFFLE, WidenVT, InOp1, InOp2, NewMask); + return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, InOp1, InOp2, NewMask); } SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { @@ -1709,7 +1751,8 @@ SDValue DAGTypeLegalizer::WidenVecRes_VSETCC(SDNode *N) { assert(InOp1.getValueType() == WidenInVT && InOp2.getValueType() == WidenInVT && "Input not widened to expected type!"); - return DAG.getNode(ISD::VSETCC, WidenVT, InOp1, InOp2, N->getOperand(2)); + return DAG.getNode(ISD::VSETCC, N->getDebugLoc(), + WidenVT, InOp1, InOp2, N->getOperand(2)); } @@ -1765,6 +1808,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { // into some scalar code and create a nasty build vector. MVT VT = N->getValueType(0); MVT EltVT = VT.getVectorElementType(); + DebugLoc dl = N->getDebugLoc(); unsigned NumElts = VT.getVectorNumElements(); SDValue InOp = N->getOperand(0); if (getTypeAction(InOp.getValueType()) == WidenVector) @@ -1775,17 +1819,18 @@ SDValue DAGTypeLegalizer::WidenVecOp_Convert(SDNode *N) { unsigned Opcode = N->getOpcode(); SmallVector Ops(NumElts); for (unsigned i=0; i < NumElts; ++i) - Ops[i] = DAG.getNode(Opcode, EltVT, - DAG.getNode(ISD::EXTRACT_VECTOR_ELT, InEltVT, InOp, + Ops[i] = DAG.getNode(Opcode, dl, EltVT, + DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, InEltVT, InOp, DAG.getIntPtrConstant(i))); - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts); } SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) { MVT VT = N->getValueType(0); SDValue InOp = GetWidenedVector(N->getOperand(0)); MVT InWidenVT = InOp.getValueType(); + DebugLoc dl = N->getDebugLoc(); // Check if we can convert between two legal vector types and extract. unsigned InWidenSize = InWidenVT.getSizeInBits(); @@ -1794,8 +1839,8 @@ SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) { unsigned NewNumElts = InWidenSize / Size; MVT NewVT = MVT::getVectorVT(VT, NewNumElts); if (TLI.isTypeLegal(NewVT)) { - SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, NewVT, InOp); - return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, VT, BitOp, + SDValue BitOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT, InOp); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, VT, BitOp, DAG.getIntPtrConstant(0)); } } @@ -1806,10 +1851,10 @@ SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) { SDValue FIPtr = DAG.CreateStackTemporary(InWidenVT, VT); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), InOp, FIPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, NULL, 0); // Result is a load from the stack slot. - return DAG.getLoad(VT, Store, FIPtr, NULL, 0); + return DAG.getLoad(VT, dl, Store, FIPtr, NULL, 0); } SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { @@ -1818,6 +1863,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { // nasty build vector. MVT VT = N->getValueType(0); MVT EltVT = VT.getVectorElementType(); + DebugLoc dl = N->getDebugLoc(); unsigned NumElts = VT.getVectorNumElements(); SmallVector Ops(NumElts); @@ -1831,16 +1877,17 @@ SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { if (getTypeAction(InOp.getValueType()) == WidenVector) InOp = GetWidenedVector(InOp); for (unsigned j=0; j < NumInElts; ++j) - Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, + Ops[Idx++] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, DAG.getIntPtrConstant(j)); } - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElts); } SDValue DAGTypeLegalizer::WidenVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { SDValue InOp = GetWidenedVector(N->getOperand(0)); MVT EltVT = InOp.getValueType().getVectorElementType(); - return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, N->getOperand(1)); + return DAG.getNode(ISD::EXTRACT_VECTOR_ELT, N->getDebugLoc(), + EltVT, InOp, N->getOperand(1)); } SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { @@ -1854,6 +1901,7 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { unsigned Align = ST->getAlignment(); bool isVolatile = ST->isVolatile(); SDValue ValOp = GetWidenedVector(ST->getValue()); + DebugLoc dl = N->getDebugLoc(); MVT StVT = ST->getMemoryVT(); MVT ValVT = ValOp.getValueType(); @@ -1871,18 +1919,18 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { MVT ValEltVT = ValVT.getVectorElementType(); unsigned Increment = ValEltVT.getSizeInBits() / 8; unsigned NumElts = StVT.getVectorNumElements(); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, ValEltVT, ValOp, + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, DAG.getIntPtrConstant(0)); - StChain.push_back(DAG.getTruncStore(Chain, EOp, BasePtr, SV, + StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, BasePtr, SV, SVOffset, StEltVT, isVolatile, Align)); unsigned Offset = Increment; for (unsigned i=1; i < NumElts; ++i, Offset += Increment) { - SDValue NewBasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), + SDValue NewBasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Offset)); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, ValEltVT, ValOp, + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, ValEltVT, ValOp, DAG.getIntPtrConstant(0)); - StChain.push_back(DAG.getTruncStore(Chain, EOp, NewBasePtr, SV, + StChain.push_back(DAG.getTruncStore(Chain, dl, EOp, NewBasePtr, SV, SVOffset + Offset, StEltVT, isVolatile, MinAlign(Align, Offset))); } @@ -1891,12 +1939,13 @@ SDValue DAGTypeLegalizer::WidenVecOp_STORE(SDNode *N) { assert(StVT.getVectorElementType() == ValVT.getVectorElementType()); // Store value GenWidenVectorStores(StChain, Chain, BasePtr, SV, SVOffset, - Align, isVolatile, ValOp, StVT.getSizeInBits()); + Align, isVolatile, ValOp, StVT.getSizeInBits(), dl); } if (StChain.size() == 1) return StChain[0]; else - return DAG.getNode(ISD::TokenFactor, MVT::Other,&StChain[0],StChain.size()); + return DAG.getNode(ISD::TokenFactor, dl, + MVT::Other,&StChain[0],StChain.size()); } //===----------------------------------------------------------------------===// @@ -1955,7 +2004,8 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector& LdChain, unsigned Alignment, bool isVolatile, unsigned LdWidth, - MVT ResType) { + MVT ResType, + DebugLoc dl) { // The strategy assumes that we can efficiently load powers of two widths. // The routines chops the vector into the largest power of 2 load and // can be inserted into a legal vector and then cast the result into the @@ -1970,14 +2020,14 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector& LdChain, FindAssocWidenVecType(TLI, LdWidth, ResType, NewEltVT, NewVecVT); NewEltVTWidth = NewEltVT.getSizeInBits(); - SDValue LdOp = DAG.getLoad(NewEltVT, Chain, BasePtr, SV, SVOffset, isVolatile, - Alignment); - SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, NewVecVT, LdOp); + SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, SVOffset, + isVolatile, Alignment); + SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, NewVecVT, LdOp); LdChain.push_back(LdOp.getValue(1)); // Check if we can load the element with one instruction if (LdWidth == NewEltVTWidth) { - return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp); } unsigned Idx = 1; @@ -1987,7 +2037,7 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector& LdChain, while (LdWidth > 0) { unsigned Increment = NewEltVTWidth / 8; Offset += Increment; - BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr, + BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Increment)); if (LdWidth < NewEltVTWidth) { @@ -1998,20 +2048,20 @@ SDValue DAGTypeLegalizer::GenWidenVectorLoads(SmallVector& LdChain, NewEltVTWidth = NewEltVT.getSizeInBits(); // Readjust position and vector position based on new load type Idx = Idx * (oNewEltVTWidth/NewEltVTWidth); - VecOp = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, VecOp); + VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp); } - SDValue LdOp = DAG.getLoad(NewEltVT, Chain, BasePtr, SV, + SDValue LdOp = DAG.getLoad(NewEltVT, dl, Chain, BasePtr, SV, SVOffset+Offset, isVolatile, MinAlign(Alignment, Offset)); LdChain.push_back(LdOp.getValue(1)); - VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVecVT, VecOp, LdOp, + VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVecVT, VecOp, LdOp, DAG.getIntPtrConstant(Idx++)); LdWidth -= NewEltVTWidth; } - return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp); } void DAGTypeLegalizer::GenWidenVectorStores(SmallVector& StChain, @@ -2022,7 +2072,8 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector& StChain, unsigned Alignment, bool isVolatile, SDValue ValOp, - unsigned StWidth) { + unsigned StWidth, + DebugLoc dl) { // Breaks the stores into a series of power of 2 width stores. For any // width, we convert the vector to the vector of element size that we // want to store. This avoids requiring a stack convert. @@ -2034,10 +2085,10 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector& StChain, FindAssocWidenVecType(TLI, StWidth, WidenVT, NewEltVT, NewVecVT); unsigned NewEltVTWidth = NewEltVT.getSizeInBits(); - SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, ValOp); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, VecOp, + SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, ValOp); + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp, DAG.getIntPtrConstant(0)); - SDValue StOp = DAG.getStore(Chain, EOp, BasePtr, SV, SVOffset, + SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset, isVolatile, Alignment); StChain.push_back(StOp); @@ -2053,7 +2104,7 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector& StChain, while (StWidth > 0) { unsigned Increment = NewEltVTWidth / 8; Offset += Increment; - BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr, + BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Increment)); if (StWidth < NewEltVTWidth) { @@ -2064,12 +2115,12 @@ void DAGTypeLegalizer::GenWidenVectorStores(SmallVector& StChain, NewEltVTWidth = NewEltVT.getSizeInBits(); // Readjust position and vector position based on new load type Idx = Idx * (oNewEltVTWidth/NewEltVTWidth); - VecOp = DAG.getNode(ISD::BIT_CONVERT, NewVecVT, VecOp); + VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, VecOp); } - EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, VecOp, + EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, VecOp, DAG.getIntPtrConstant(Idx++)); - StChain.push_back(DAG.getStore(Chain, EOp, BasePtr, SV, + StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset + Offset, isVolatile, MinAlign(Alignment, Offset))); StWidth -= NewEltVTWidth; @@ -2084,6 +2135,7 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) { MVT InVT = InOp.getValueType(); assert(InVT.getVectorElementType() == NVT.getVectorElementType() && "input and widen element type must match"); + DebugLoc dl = InOp.getNode()->getDebugLoc(); // Check if InOp already has the right width. if (InVT == NVT) @@ -2094,16 +2146,16 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) { if (WidenNumElts > InNumElts && WidenNumElts % InNumElts == 0) { unsigned NumConcat = WidenNumElts / InNumElts; SmallVector Ops(NumConcat); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT); Ops[0] = InOp; for (unsigned i = 1; i != NumConcat; ++i) Ops[i] = UndefVal; - return DAG.getNode(ISD::CONCAT_VECTORS, NVT, &Ops[0], NumConcat); + return DAG.getNode(ISD::CONCAT_VECTORS, dl, NVT, &Ops[0], NumConcat); } if (WidenNumElts < InNumElts && InNumElts % WidenNumElts) - return DAG.getNode(ISD::EXTRACT_SUBVECTOR, NVT, InOp, + return DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NVT, InOp, DAG.getIntPtrConstant(0)); // Fall back to extract and build. @@ -2112,11 +2164,11 @@ SDValue DAGTypeLegalizer::ModifyToType(SDValue InOp, MVT NVT) { unsigned MinNumElts = std::min(WidenNumElts, InNumElts); unsigned Idx; for (Idx = 0; Idx < MinNumElts; ++Idx) - Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, InOp, + Ops[Idx] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, InOp, DAG.getIntPtrConstant(Idx)); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, EltVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, EltVT); for ( ; Idx < WidenNumElts; ++Idx) Ops[Idx] = UndefVal; - return DAG.getNode(ISD::BUILD_VECTOR, NVT, &Ops[0], WidenNumElts); + return DAG.getNode(ISD::BUILD_VECTOR, dl, NVT, &Ops[0], WidenNumElts); } -- GitLab From 676130f2e1979ea11c171848eab24bc7a3b1877e Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Sun, 1 Feb 2009 06:42:27 +0000 Subject: [PATCH 586/682] Fix PR3423: Link llvm on ARM EABI machines. Patch by Robert Schuster. llvm-svn: 63489 --- llvm/lib/ExecutionEngine/JIT/JIT.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JIT/JIT.cpp b/llvm/lib/ExecutionEngine/JIT/JIT.cpp index 7fc7b2fdceb4..9595099c3c07 100644 --- a/llvm/lib/ExecutionEngine/JIT/JIT.cpp +++ b/llvm/lib/ExecutionEngine/JIT/JIT.cpp @@ -65,7 +65,7 @@ namespace llvm { } -#if defined (__GNUC__) +#if defined(__GNUC__) && !defined(__ARM__EABI__) // libgcc defines the __register_frame function to dynamically register new // dwarf frames for exception handling. This functionality is not portable @@ -86,7 +86,7 @@ namespace llvm { extern "C" void __register_frame(void*); -#if defined (__APPLE__) +#if defined(__APPLE__) namespace { @@ -225,7 +225,7 @@ JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji, } // Register routine for informing unwinding runtime about new EH frames -#if defined(__GNUC__) +#if defined(__GNUC__) && !defined(__ARM_EABI__) #if defined(__APPLE__) struct LibgccObjectInfo* LOI = (struct LibgccObjectInfo*) _keymgr_get_and_lock_processwide_ptr(KEYMGR_GCC3_DW2_OBJ_LIST); -- GitLab From 66838e9a2707d822ce2eaa1211c5e85118e47860 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sun, 1 Feb 2009 07:06:00 +0000 Subject: [PATCH 587/682] Fix an issue in PHI construction that was exposed by GCC 4.2 producing a different set iteration order for the reg_iterator. llvm-svn: 63490 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 67 +++++++++++--------------- 1 file changed, 27 insertions(+), 40 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 1180dee7b793..dc4a42ae375e 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -467,39 +467,26 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( unsigned StartIndex = LIs->getMBBStartIdx(MBB); - if (MBB->pred_size() == 1) { - Phis[MBB] = ret = PerformPHIConstruction((*MBB->pred_begin())->end(), - *(MBB->pred_begin()), LI, Visited, - Defs, Uses, NewVNs, LiveOut, Phis, - false, false); - unsigned EndIndex = 0; - if (intrablock) { - EndIndex = LIs->getInstructionIndex(use); - EndIndex = LiveIntervals::getUseIndex(EndIndex); - } else - EndIndex = LIs->getMBBEndIdx(MBB); - - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); - if (intrablock) - LI->addKill(ret, EndIndex); - } else { - Phis[MBB] = ret = LI->getNextValue(~0U, /*FIXME*/ 0, + Phis[MBB] = ret = LI->getNextValue(~0U, /*FIXME*/ 0, LIs->getVNInfoAllocator()); - if (!intrablock) LiveOut[MBB] = ret; + if (!intrablock) LiveOut[MBB] = ret; - // If there are no uses or defs between our starting point and the - // beginning of the block, then recursive perform phi construction - // on our predecessors. - DenseMap IncomingVNs; - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI, - Visited, Defs, Uses, NewVNs, - LiveOut, Phis, false, false); - if (Incoming != 0) - IncomingVNs[*PI] = Incoming; - } + // If there are no uses or defs between our starting point and the + // beginning of the block, then recursive perform phi construction + // on our predecessors. + DenseMap IncomingVNs; + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI, + Visited, Defs, Uses, NewVNs, + LiveOut, Phis, false, false); + if (Incoming != 0) + IncomingVNs[*PI] = Incoming; + } + if (MBB->pred_size() == 1 && !ret->hasPHIKill) { + LI->MergeValueNumberInto(ret, IncomingVNs.begin()->second); + } else { // Otherwise, merge the incoming VNInfos with a phi join. Create a new // VNInfo to represent the joined value. for (DenseMap::iterator I = @@ -509,17 +496,17 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( if (!LiveInterval::isKill(I->second, KillIndex)) LI->addKill(I->second, KillIndex); } - - unsigned EndIndex = 0; - if (intrablock) { - EndIndex = LIs->getInstructionIndex(use); - EndIndex = LiveIntervals::getUseIndex(EndIndex); - } else - EndIndex = LIs->getMBBEndIdx(MBB); - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); - if (intrablock) - LI->addKill(ret, EndIndex); } + + unsigned EndIndex = 0; + if (intrablock) { + EndIndex = LIs->getInstructionIndex(use); + EndIndex = LiveIntervals::getUseIndex(EndIndex); + } else + EndIndex = LIs->getMBBEndIdx(MBB); + LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); + if (intrablock) + LI->addKill(ret, EndIndex); } else if (ContainsDefs && !ContainsUses) { SmallPtrSet& BlockDefs = Defs[MBB]; -- GitLab From 1f90fe17f91f22ed6df24da747a632f9a7a925bd Mon Sep 17 00:00:00 2001 From: Eli Friedman Date: Sun, 1 Feb 2009 08:12:19 +0000 Subject: [PATCH 588/682] Fix for PR3447: use padded sizes for computations on struct/union constants. llvm-svn: 63491 --- clang/lib/CodeGen/CGExprConstant.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp index 604090e2b35b..838452d476c1 100644 --- a/clang/lib/CodeGen/CGExprConstant.cpp +++ b/clang/lib/CodeGen/CGExprConstant.cpp @@ -124,7 +124,7 @@ public: // Calculate information about the relevant field const llvm::Type* Ty = CI->getType(); const llvm::TargetData &TD = CGM.getTypes().getTargetData(); - unsigned size = TD.getTypeStoreSizeInBits(Ty); + unsigned size = TD.getTypePaddedSizeInBits(Ty); unsigned fieldOffset = CGM.getTypes().getLLVMFieldNo(Field) * size; CodeGenTypes::BitFieldInfo bitFieldInfo = CGM.getTypes().getBitFieldInfo(Field); @@ -135,11 +135,11 @@ public: // FIXME: This won't work if the struct isn't completely packed! unsigned offset = 0, i = 0; while (offset < (fieldOffset & -8)) - offset += TD.getTypeStoreSizeInBits(Elts[i++]->getType()); + offset += TD.getTypePaddedSizeInBits(Elts[i++]->getType()); // Advance over 0 sized elements (must terminate in bounds since // the bitfield must have a size). - while (TD.getTypeStoreSizeInBits(Elts[i]->getType()) == 0) + while (TD.getTypePaddedSizeInBits(Elts[i]->getType()) == 0) ++i; // Promote the size of V if necessary @@ -223,8 +223,8 @@ public: std::vector Types; Elts.push_back(C); Types.push_back(C->getType()); - unsigned CurSize = CGM.getTargetData().getTypeStoreSize(C->getType()); - unsigned TotalSize = CGM.getTargetData().getTypeStoreSize(Ty); + unsigned CurSize = CGM.getTargetData().getTypePaddedSize(C->getType()); + unsigned TotalSize = CGM.getTargetData().getTypePaddedSize(Ty); while (CurSize < TotalSize) { Elts.push_back(llvm::Constant::getNullValue(llvm::Type::Int8Ty)); Types.push_back(llvm::Type::Int8Ty); -- GitLab From 19616c08a0e36f172edc02a7af308697aaab90a8 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Sun, 1 Feb 2009 08:41:54 +0000 Subject: [PATCH 589/682] Fix test failures causes by my previous commit. llvm-svn: 63492 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index dc4a42ae375e..4061859f740c 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -486,6 +486,7 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( if (MBB->pred_size() == 1 && !ret->hasPHIKill) { LI->MergeValueNumberInto(ret, IncomingVNs.begin()->second); + Phis[MBB] = ret = IncomingVNs.begin()->second; } else { // Otherwise, merge the incoming VNInfos with a phi join. Create a new // VNInfo to represent the joined value. -- GitLab From a6c75ffd73a72fb9d5e9a5e5ec9344a7d96cdfd3 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Sun, 1 Feb 2009 11:19:36 +0000 Subject: [PATCH 590/682] Forgot some more DebugLoc propagations. llvm-svn: 63493 --- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 39 +++++++++++-------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 1dbbf4f5a960..eb433aa88089 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -1787,7 +1787,7 @@ SDValue DAGCombiner::visitAND(SDNode *N) { return DAG.FoldConstantArithmetic(ISD::AND, VT, N0C, N1C); // canonicalize constant to RHS if (N0C && !N1C) - return DAG.getNode(ISD::AND, VT, N1, N0); + return DAG.getNode(ISD::AND, N->getDebugLoc(), VT, N1, N0); // fold (and x, -1) -> x if (N1C && N1C->isAllOnesValue()) return N0; @@ -2510,8 +2510,10 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { uint64_t TruncC = TruncVT.getIntegerVTBitMask() & N101C->getZExtValue(); return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, - DAG.getNode(ISD::AND, TruncVT, - DAG.getNode(ISD::TRUNCATE, TruncVT, N100), + DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, + DAG.getNode(ISD::TRUNCATE, + N->getDebugLoc(), + TruncVT, N100), DAG.getConstant(TruncC, TruncVT))); } } @@ -3292,7 +3294,7 @@ SDValue DAGCombiner::visitANY_EXTEND(SDNode *N) { // fold (aext c1) -> c1 if (isa(N0)) - return DAG.getNode(ISD::ANY_EXTEND, VT, N0); + return DAG.getNode(ISD::ANY_EXTEND, N->getDebugLoc(), VT, N0); // fold (aext (aext x)) -> (aext x) // fold (aext (zext x)) -> (zext x) // fold (aext (sext x)) -> (sext x) @@ -3546,7 +3548,7 @@ SDValue DAGCombiner::visitSIGN_EXTEND_INREG(SDNode *N) { // fold (sext_in_reg x) -> (zext_in_reg x) if the sign bit is known zero. if (DAG.MaskedValueIsZero(N0, APInt::getBitsSet(VTBits, EVTBits-1, EVTBits))) - return DAG.getZeroExtendInReg(N0, EVT); + return DAG.getZeroExtendInReg(N0, N->getDebugLoc(), EVT); // fold operands of sext_in_reg based on knowledge that the top bits are not // demanded. @@ -3852,7 +3854,8 @@ ConstantFoldBIT_CONVERTofBUILD_VECTOR(SDNode *BV, MVT DstEltVT) { if (SrcBitSize == DstBitSize) { SmallVector Ops; for (unsigned i = 0, e = BV->getNumOperands(); i != e; ++i) { - Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, DstEltVT, BV->getOperand(i))); + Ops.push_back(DAG.getNode(ISD::BIT_CONVERT, BV->getDebugLoc(), + DstEltVT, BV->getOperand(i))); AddToWorkList(Ops.back().getNode()); } MVT VT = MVT::getVectorVT(DstEltVT, @@ -3988,7 +3991,8 @@ SDValue DAGCombiner::visitFADD(SDNode *N) { if (UnsafeFPMath && N1CFP && N0.getOpcode() == ISD::FADD && N0.getNode()->hasOneUse() && isa(N0.getOperand(1))) return DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, N0.getOperand(0), - DAG.getNode(ISD::FADD, VT, N0.getOperand(1), N1)); + DAG.getNode(ISD::FADD, N->getDebugLoc(), VT, + N0.getOperand(1), N1)); return SDValue(); } @@ -4008,7 +4012,7 @@ SDValue DAGCombiner::visitFSUB(SDNode *N) { // fold (fsub c1, c2) -> c1-c2 if (N0CFP && N1CFP && VT != MVT::ppcf128) - return DAG.getNode(ISD::FSUB, VT, N0, N1); + return DAG.getNode(ISD::FSUB, N->getDebugLoc(), VT, N0, N1); // fold (fsub A, 0) -> A if (UnsafeFPMath && N1CFP && N1CFP->getValueAPF().isZero()) return N0; @@ -4133,7 +4137,7 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { MVT VT = N->getValueType(0); if (N0CFP && N1CFP && VT != MVT::ppcf128) // Constant fold - return DAG.getNode(ISD::FCOPYSIGN, VT, N0, N1); + return DAG.getNode(ISD::FCOPYSIGN, N->getDebugLoc(), VT, N0, N1); if (N1CFP) { const APFloat& V = N1CFP->getValueAPF(); @@ -4175,8 +4179,6 @@ SDValue DAGCombiner::visitFCOPYSIGN(SDNode *N) { return SDValue(); } - - SDValue DAGCombiner::visitSINT_TO_FP(SDNode *N) { SDValue N0 = N->getOperand(0); ConstantSDNode *N0C = dyn_cast(N0); @@ -4808,7 +4810,8 @@ SDValue DAGCombiner::visitLOAD(SDNode *N) { // Indexed loads. assert(N->getValueType(2) == MVT::Other && "Malformed indexed loads?"); if (N->hasNUsesOfValue(0, 0) && N->hasNUsesOfValue(0, 1)) { - SDValue Undef = DAG.getNode(ISD::UNDEF, N->getValueType(0)); + SDValue Undef = DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + N->getValueType(0)); DOUT << "\nReplacing.6 "; DEBUG(N->dump(&DAG)); DOUT << "\nWith: "; DEBUG(Undef.getNode()->dump(&DAG)); DOUT << " and 2 other values\n"; @@ -5270,7 +5273,8 @@ SDValue DAGCombiner::visitBUILD_VECTOR(SDNode *N) { } else { // Use an undef build_vector as input for the second operand. std::vector UnOps(NumInScalars, - DAG.getNode(ISD::UNDEF, EltType)); + DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + EltType)); Ops[1] = DAG.getNode(ISD::BUILD_VECTOR, N->getDebugLoc(), VT, &UnOps[0], UnOps.size()); AddToWorkList(Ops[1].getNode()); @@ -5426,7 +5430,8 @@ SDValue DAGCombiner::visitVECTOR_SHUFFLE(SDNode *N) { AddToWorkList(ShufMask.getNode()); return DAG.getNode(ISD::VECTOR_SHUFFLE, N->getDebugLoc(), N->getValueType(0), N0, - DAG.getNode(ISD::UNDEF, N->getValueType(0)), + DAG.getNode(ISD::UNDEF, N->getDebugLoc(), + N->getValueType(0)), ShufMask); } @@ -5824,7 +5829,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, XType, DAG.getConstant(0, XType), N0); SDValue NotN0 = DAG.getNOT(N0.getDebugLoc(), N0, XType); return DAG.getNode(ISD::SRL, DL, XType, - DAG.getNode(ISD::AND, XType, NegN0, NotN0), + DAG.getNode(ISD::AND, DL, XType, NegN0, NotN0), DAG.getConstant(XType.getSizeInBits()-1, getShiftAmountTy())); } @@ -6086,8 +6091,8 @@ SDValue DAGCombiner::FindBetterChain(SDNode *N, SDValue OldChain) { } // Construct a custom tailored token factor. - SDValue NewChain = DAG.getNode(ISD::TokenFactor, MVT::Other, - &Aliases[0], Aliases.size()); + SDValue NewChain = DAG.getNode(ISD::TokenFactor, N->getDebugLoc(), MVT::Other, + &Aliases[0], Aliases.size()); // Make sure the old chain gets cleaned up. if (NewChain != OldChain) AddToWorkList(OldChain.getNode()); -- GitLab From 3ed768868db9f0023f2e4b07e2ccb285d2f821be Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Sun, 1 Feb 2009 18:06:53 +0000 Subject: [PATCH 591/682] Fix PR3453 and probably a bunch of other potential crashes or wrong code with codegen of large integers: eliminate the legacy getIntegerVTBitMask and getIntegerVTSignBit methods, which returned their value as a uint64_t, so couldn't handle huge types. llvm-svn: 63494 --- llvm/include/llvm/CodeGen/ValueTypes.h | 18 ----------- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 27 +++++++--------- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 10 +++--- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 7 ++-- llvm/lib/Target/X86/X86ISelLowering.cpp | 3 +- llvm/test/CodeGen/X86/2009-02-01-LargeMask.ll | 32 +++++++++++++++++++ llvm/utils/TableGen/CodeGenDAGPatterns.cpp | 2 +- 7 files changed, 57 insertions(+), 42 deletions(-) create mode 100644 llvm/test/CodeGen/X86/2009-02-01-LargeMask.ll diff --git a/llvm/include/llvm/CodeGen/ValueTypes.h b/llvm/include/llvm/CodeGen/ValueTypes.h index 2846eb02db28..3c6f04253633 100644 --- a/llvm/include/llvm/CodeGen/ValueTypes.h +++ b/llvm/include/llvm/CodeGen/ValueTypes.h @@ -439,24 +439,6 @@ namespace llvm { else { return *this; } - } - - /// getIntegerVTBitMask - Return an integer with 1's every place there are - /// bits in the specified integer value type. FIXME: Should return an apint. - uint64_t getIntegerVTBitMask() const { - assert(isInteger() && "Only applies to integers!"); - MVT EltVT = isVector() ? getVectorElementType() : *this; - assert(EltVT.getSizeInBits() <= 64 && - "getIntegerVTBitMask doesn't use APInt!"); - return ~uint64_t(0UL) >> (64-EltVT.getSizeInBits()); - } - - /// getIntegerVTSignBit - Return an integer with a 1 in the position of the - /// sign bit for the specified integer value type. FIXME: Should return an - /// apint. - uint64_t getIntegerVTSignBit() const { - assert(isInteger() && !isVector() && "Only applies to int scalars!"); - return uint64_t(1UL) << (getSizeInBits()-1); } /// getMVTString - This function returns value type as a string, diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index eb433aa88089..7d18a864ab76 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -2498,8 +2498,7 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { if (DAG.MaskedValueIsZero(SDValue(N, 0), APInt::getAllOnesValue(VT.getSizeInBits()))) return DAG.getConstant(0, VT); - // fold (shl x, (trunc (and y, c))) -> (shl x, (and (trunc y), c)) - // iff (trunc c) == c + // fold (shl x, (trunc (and y, c))) -> (shl x, (and (trunc y), (trunc c))). if (N1.getOpcode() == ISD::TRUNCATE && N1.getOperand(0).getOpcode() == ISD::AND && N1.hasOneUse() && N1.getOperand(0).hasOneUse()) { @@ -2507,8 +2506,8 @@ SDValue DAGCombiner::visitSHL(SDNode *N) { if (ConstantSDNode *N101C = dyn_cast(N101)) { MVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); - uint64_t TruncC = TruncVT.getIntegerVTBitMask() & - N101C->getZExtValue(); + APInt TruncC = N101C->getAPIntValue(); + TruncC.trunc(TruncVT.getSizeInBits()); return DAG.getNode(ISD::SHL, N->getDebugLoc(), VT, N0, DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, DAG.getNode(ISD::TRUNCATE, @@ -2632,8 +2631,7 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { } } - // fold (sra x, (trunc (and y, c))) -> (sra x, (and (trunc y), c)) - // iff (trunc c) == c + // fold (sra x, (trunc (and y, c))) -> (sra x, (and (trunc y), (trunc c))). if (N1.getOpcode() == ISD::TRUNCATE && N1.getOperand(0).getOpcode() == ISD::AND && N1.hasOneUse() && N1.getOperand(0).hasOneUse()) { @@ -2641,8 +2639,8 @@ SDValue DAGCombiner::visitSRA(SDNode *N) { if (ConstantSDNode *N101C = dyn_cast(N101)) { MVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); - uint64_t TruncC = TruncVT.getIntegerVTBitMask() & - N101C->getZExtValue(); + APInt TruncC = N101C->getAPIntValue(); + TruncC.trunc(TruncVT.getSizeInBits()); return DAG.getNode(ISD::SRA, N->getDebugLoc(), VT, N0, DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, @@ -2757,8 +2755,7 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { } } - // fold (srl x, (trunc (and y, c))) -> (srl x, (and (trunc y), c)) - // iff (trunc c) == c + // fold (srl x, (trunc (and y, c))) -> (srl x, (and (trunc y), (trunc c))). if (N1.getOpcode() == ISD::TRUNCATE && N1.getOperand(0).getOpcode() == ISD::AND && N1.hasOneUse() && N1.getOperand(0).hasOneUse()) { @@ -2766,8 +2763,8 @@ SDValue DAGCombiner::visitSRL(SDNode *N) { if (ConstantSDNode *N101C = dyn_cast(N101)) { MVT TruncVT = N1.getValueType(); SDValue N100 = N1.getOperand(0).getOperand(0); - uint64_t TruncC = TruncVT.getIntegerVTBitMask() & - N101C->getZExtValue(); + APInt TruncC = N101C->getAPIntValue(); + TruncC.trunc(TruncVT.getSizeInBits()); return DAG.getNode(ISD::SRL, N->getDebugLoc(), VT, N0, DAG.getNode(ISD::AND, N->getDebugLoc(), TruncVT, @@ -4359,8 +4356,8 @@ SDValue DAGCombiner::visitFNEG(SDNode *N) { SDValue Int = N0.getOperand(0); MVT IntVT = Int.getValueType(); if (IntVT.isInteger() && !IntVT.isVector()) { - Int = DAG.getNode(ISD::XOR, N0.getDebugLoc(), IntVT, Int, - DAG.getConstant(IntVT.getIntegerVTSignBit(), IntVT)); + Int = DAG.getNode(ISD::XOR, N0.getDebugLoc(), IntVT, Int, + DAG.getConstant(APInt::getSignBit(IntVT.getSizeInBits()), IntVT)); AddToWorkList(Int.getNode()); return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), Int); @@ -4395,7 +4392,7 @@ SDValue DAGCombiner::visitFABS(SDNode *N) { MVT IntVT = Int.getValueType(); if (IntVT.isInteger() && !IntVT.isVector()) { Int = DAG.getNode(ISD::AND, N0.getDebugLoc(), IntVT, Int, - DAG.getConstant(~IntVT.getIntegerVTSignBit(), IntVT)); + DAG.getConstant(~APInt::getSignBit(IntVT.getSizeInBits()), IntVT)); AddToWorkList(Int.getNode()); return DAG.getNode(ISD::BIT_CONVERT, N->getDebugLoc(), N->getValueType(0), Int); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 4dd5dd254249..0b3d979b8e01 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -3110,9 +3110,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT, Tmp2, DAG.getIntPtrConstant(i)), CC); - Ops[i] = DAG.getNode(ISD::SELECT, EltVT, Ops[i], - DAG.getConstant(EltVT.getIntegerVTBitMask(),EltVT), - DAG.getConstant(0, EltVT)); + Ops[i] = DAG.getNode(ISD::SELECT, EltVT, Ops[i], DAG.getConstant( + APInt::getAllOnesValue(EltVT.getSizeInBits()), + EltVT), DAG.getConstant(0, EltVT)); } Result = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElems); break; @@ -6291,7 +6291,9 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { unsigned len = VT.getSizeInBits(); for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8]) - SDValue Tmp2 = DAG.getConstant(VT.getIntegerVTBitMask() & mask[i], VT); + unsigned EltSize = VT.isVector() ? + VT.getVectorElementType().getSizeInBits() : len; + SDValue Tmp2 = DAG.getConstant(APInt(EltSize, mask[i]), VT); SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2), DAG.getNode(ISD::AND, VT, diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 1b0d61ca0a73..d8f895dac2f2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -845,12 +845,13 @@ SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) { SDValue NegOne; if (VT.isVector()) { MVT EltVT = VT.getVectorElementType(); - SDValue NegOneElt = getConstant(EltVT.getIntegerVTBitMask(), EltVT); + SDValue NegOneElt = + getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT); std::vector NegOnes(VT.getVectorNumElements(), NegOneElt); NegOne = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), VT, &NegOnes[0], NegOnes.size()); } else { - NegOne = getConstant(VT.getIntegerVTBitMask(), VT); + NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); } return getNode(ISD::XOR, DL, VT, Val, NegOne); @@ -2772,7 +2773,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, return N1; case ISD::OR: if (!VT.isVector()) - return getConstant(VT.getIntegerVTBitMask(), VT); + return getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); // For vectors, we can't easily build an all one vector, just return // the LHS. return N1; diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 2c79da5bf541..111269f928c7 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5268,7 +5268,8 @@ SDValue X86TargetLowering::LowerVSETCC(SDValue Op, SelectionDAG &DAG) { // bits of the inputs before performing those operations. if (FlipSigns) { MVT EltVT = VT.getVectorElementType(); - SDValue SignBit = DAG.getConstant(EltVT.getIntegerVTSignBit(), EltVT); + SDValue SignBit = DAG.getConstant(APInt::getSignBit(EltVT.getSizeInBits()), + EltVT); std::vector SignBits(VT.getVectorNumElements(), SignBit); SDValue SignVec = DAG.getNode(ISD::BUILD_VECTOR, VT, &SignBits[0], SignBits.size()); diff --git a/llvm/test/CodeGen/X86/2009-02-01-LargeMask.ll b/llvm/test/CodeGen/X86/2009-02-01-LargeMask.ll new file mode 100644 index 000000000000..f2a964f208ce --- /dev/null +++ b/llvm/test/CodeGen/X86/2009-02-01-LargeMask.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | llc -march=x86 +; PR3453 + +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i386-pc-linux-gnu" + %struct.cl_engine = type { i32, i16, i32, i8**, i8**, i8*, i8*, i8*, i8*, i8*, i8*, i8* } + %struct.cl_limits = type { i32, i32, i32, i32, i16, i32 } + %struct.cli_ac_alt = type { i8, i8*, i16, i16, %struct.cli_ac_alt* } + %struct.cli_ac_node = type { i8, i8, %struct.cli_ac_patt*, %struct.cli_ac_node**, %struct.cli_ac_node* } + %struct.cli_ac_patt = type { i16*, i16*, i16, i16, i8, i32, i32, i8*, i8*, i32, i16, i16, i16, i16, %struct.cli_ac_alt**, i8, i16, %struct.cli_ac_patt*, %struct.cli_ac_patt* } + %struct.cli_bm_patt = type { i8*, i8*, i16, i16, i8*, i8*, i8, %struct.cli_bm_patt*, i16 } + %struct.cli_ctx = type { i8**, i32*, %struct.cli_matcher*, %struct.cl_engine*, %struct.cl_limits*, i32, i32, i32, i32, %struct.cli_dconf* } + %struct.cli_dconf = type { i32, i32, i32, i32, i32, i32, i32 } + %struct.cli_matcher = type { i16, i8, i8*, %struct.cli_bm_patt**, i32*, i32, i8, i8, %struct.cli_ac_node*, %struct.cli_ac_node**, %struct.cli_ac_patt**, i32, i32, i32 } + +define fastcc i32 @cli_scanautoit(i32 %desc, %struct.cli_ctx* %ctx, i32 %offset) nounwind { +entry: + br i1 false, label %bb.i49.i72, label %bb14 + +bb.i49.i72: ; preds = %bb.i49.i72, %entry + %UNP.i1482.0 = phi i288 [ %.ins659, %bb.i49.i72 ], [ undef, %entry ] ; [#uses=1] + %0 = load i32* null, align 4 ; [#uses=1] + %1 = xor i32 %0, 17834 ; [#uses=1] + %2 = zext i32 %1 to i288 ; [#uses=1] + %3 = shl i288 %2, 160 ; [#uses=1] + %UNP.i1482.in658.mask = and i288 %UNP.i1482.0, -6277101733925179126504886505003981583386072424808101969921 ; [#uses=1] + %.ins659 = or i288 %3, %UNP.i1482.in658.mask ; [#uses=1] + br label %bb.i49.i72 + +bb14: ; preds = %entry + ret i32 -123 +} diff --git a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp index e70bdb6f6026..f3bdb4fab3f6 100644 --- a/llvm/utils/TableGen/CodeGenDAGPatterns.cpp +++ b/llvm/utils/TableGen/CodeGenDAGPatterns.cpp @@ -842,7 +842,7 @@ bool TreePatternNode::ApplyTypeConstraints(TreePattern &TP, bool NotRegisters) { // If sign-extended doesn't fit, does it fit as unsigned? unsigned ValueMask; unsigned UnsignedVal; - ValueMask = unsigned(MVT(VT).getIntegerVTBitMask()); + ValueMask = unsigned(~uint32_t(0UL) >> (32-Size)); UnsignedVal = unsigned(II->getValue()); if ((ValueMask & UnsignedVal) != UnsignedVal) { -- GitLab From a2d1f35e9a01bf0994b600675c1231534a430ddb Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sun, 1 Feb 2009 18:15:56 +0000 Subject: [PATCH 592/682] Implement -mno-sse: if SSE is disabled on x86-64, don't store XMM on stack for var-args, and don't allow FP return values llvm-svn: 63495 --- llvm/lib/Target/X86/X86CallingConv.td | 8 ++-- llvm/lib/Target/X86/X86ISelLowering.cpp | 19 +++++++++- llvm/lib/Target/X86/X86Subtarget.cpp | 2 +- llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll | 2 - llvm/test/CodeGen/X86/nosse-varargs.ll | 46 +++++++++++++++++++++++ 5 files changed, 70 insertions(+), 7 deletions(-) create mode 100644 llvm/test/CodeGen/X86/nosse-varargs.ll diff --git a/llvm/lib/Target/X86/X86CallingConv.td b/llvm/lib/Target/X86/X86CallingConv.td index db92a0cdc02d..6742a90058a2 100644 --- a/llvm/lib/Target/X86/X86CallingConv.td +++ b/llvm/lib/Target/X86/X86CallingConv.td @@ -49,7 +49,7 @@ def RetCC_X86_32_C : CallingConv<[ // weirdly; this is really the sse-regparm calling convention) in which // case they use XMM0, otherwise it is the same as the common X86 calling // conv. - CCIfInReg>>>, CCIfType<[f32,f64], CCAssignToReg<[ST0, ST1]>>, CCDelegateTo @@ -134,7 +134,8 @@ def CC_X86_64_C : CallingConv<[ // The first 8 FP/Vector arguments are passed in XMM registers. CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>, + CCIfSubtarget<"hasSSE1()", + CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>, // The first 8 MMX (except for v1i64) vector arguments are passed in XMM // registers on Darwin. @@ -223,7 +224,8 @@ def CC_X86_64_TailCall : CallingConv<[ // The first 8 FP/Vector arguments are passed in XMM registers. CCIfType<[f32, f64, v16i8, v8i16, v4i32, v2i64, v4f32, v2f64], - CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>, + CCIfSubtarget<"hasSSE1()", + CCAssignToReg<[XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7]>>>, // The first 8 MMX (except for v1i64) vector arguments are passed in XMM // registers on Darwin. diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 111269f928c7..19d5aedf6936 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -1031,6 +1031,7 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, // Assign locations to each value returned by this call. SmallVector RVLocs; bool isVarArg = TheCall->isVarArg(); + bool Is64Bit = Subtarget->is64Bit(); CCState CCInfo(CallingConv, isVarArg, getTargetMachine(), RVLocs); CCInfo.AnalyzeCallResult(TheCall, RetCC_X86); @@ -1039,7 +1040,14 @@ LowerCallResult(SDValue Chain, SDValue InFlag, CallSDNode *TheCall, // Copy all of the result registers out of their specified physreg. for (unsigned i = 0; i != RVLocs.size(); ++i) { MVT CopyVT = RVLocs[i].getValVT(); - + + // If this is x86-64, and we disabled SSE, we can't return FP values + if ((CopyVT == MVT::f32 || CopyVT == MVT::f64) && + ((Is64Bit || TheCall->isInreg()) && !Subtarget->hasSSE1())) { + cerr << "SSE register return with SSE disabled\n"; + exit(1); + } + // If this is a call to a function that returns an fp value on the floating // point stack, but where we prefer to use the value in xmm registers, copy // it out as F80 and use a truncate to move it from fp stack reg to xmm reg. @@ -1382,6 +1390,13 @@ X86TargetLowering::LowerFORMAL_ARGUMENTS(SDValue Op, SelectionDAG &DAG) { unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, TotalNumXMMRegs); + assert((Subtarget->hasSSE1() || !NumXMMRegs) && + "SSE register cannot be used when SSE is disabled!"); + if (!Subtarget->hasSSE1()) { + // Kernel mode asks for SSE to be disabled, so don't push them + // on the stack. + TotalNumXMMRegs = 0; + } // For X86-64, if there are vararg parameters that are passed via // registers, then we must store them to their spots on the stack so they // may be loaded by deferencing the result of va_next. @@ -1675,6 +1690,8 @@ SDValue X86TargetLowering::LowerCALL(SDValue Op, SelectionDAG &DAG) { X86::XMM4, X86::XMM5, X86::XMM6, X86::XMM7 }; unsigned NumXMMRegs = CCInfo.getFirstUnallocated(XMMArgRegs, 8); + assert((Subtarget->hasSSE1() || !NumXMMRegs) + && "SSE registers cannot be used when SSE is disabled"); Chain = DAG.getCopyToReg(Chain, X86::AL, DAG.getConstant(NumXMMRegs, MVT::i8), InFlag); diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 7034c555ccc3..ff7f72be134c 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -331,7 +331,7 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // are enabled. These are available on all x86-64 CPUs. if (Is64Bit) { HasX86_64 = true; -#if 1 +#if 0 if (X86SSELevel < SSE2) X86SSELevel = SSE2; #endif diff --git a/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll b/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll index 99826dd7159a..b12e4137dbd5 100644 --- a/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll +++ b/llvm/test/CodeGen/X86/2009-01-25-NoSSE.ll @@ -1,7 +1,5 @@ ; RUN: llvm-as < %s | llc -march=x86-64 -mattr=-sse,-sse2 | not grep xmm ; PR3402 -; reverted -; XFAIL: * target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" target triple = "x86_64-unknown-linux-gnu" diff --git a/llvm/test/CodeGen/X86/nosse-varargs.ll b/llvm/test/CodeGen/X86/nosse-varargs.ll new file mode 100644 index 000000000000..e6da0ab5e371 --- /dev/null +++ b/llvm/test/CodeGen/X86/nosse-varargs.ll @@ -0,0 +1,46 @@ +; RUN: llvm-as < %s > %t +; RUN: llc -march=x86-64 -mattr=-sse < %t | not grep xmm +; RUN: llc -march=x86-64 < %t | grep xmm +; PR3403 +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" + %struct.__va_list_tag = type { i32, i32, i8*, i8* } + +define i32 @foo(float %a, i8* nocapture %fmt, ...) nounwind { +entry: + %ap = alloca [1 x %struct.__va_list_tag], align 8 ; <[1 x %struct.__va_list_tag]*> [#uses=4] + %ap12 = bitcast [1 x %struct.__va_list_tag]* %ap to i8* ; [#uses=2] + call void @llvm.va_start(i8* %ap12) + %0 = getelementptr [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 0 ; [#uses=2] + %1 = load i32* %0, align 8 ; [#uses=3] + %2 = icmp ult i32 %1, 48 ; [#uses=1] + br i1 %2, label %bb, label %bb3 + +bb: ; preds = %entry + %3 = getelementptr [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 3 ; [#uses=1] + %4 = load i8** %3, align 8 ; [#uses=1] + %5 = inttoptr i32 %1 to i8* ; [#uses=1] + %6 = ptrtoint i8* %5 to i64 ; [#uses=1] + %ctg2 = getelementptr i8* %4, i64 %6 ; [#uses=1] + %7 = add i32 %1, 8 ; [#uses=1] + store i32 %7, i32* %0, align 8 + br label %bb4 + +bb3: ; preds = %entry + %8 = getelementptr [1 x %struct.__va_list_tag]* %ap, i64 0, i64 0, i32 2 ; [#uses=2] + %9 = load i8** %8, align 8 ; [#uses=2] + %10 = getelementptr i8* %9, i64 8 ; [#uses=1] + store i8* %10, i8** %8, align 8 + br label %bb4 + +bb4: ; preds = %bb3, %bb + %addr.0.0 = phi i8* [ %ctg2, %bb ], [ %9, %bb3 ] ; [#uses=1] + %11 = bitcast i8* %addr.0.0 to i32* ; [#uses=1] + %12 = load i32* %11, align 4 ; [#uses=1] + call void @llvm.va_end(i8* %ap12) + ret i32 %12 +} + +declare void @llvm.va_start(i8*) nounwind + +declare void @llvm.va_end(i8*) nounwind -- GitLab From c418287974f527c110745e293ee1a8c553cdb020 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Sun, 1 Feb 2009 18:24:20 +0000 Subject: [PATCH 593/682] add 2 more testcases for -mattr=-sse (r63495). --This line, and those below, will be ignaored-- A test/CodeGen/X86/nosse-error1.ll A test/CodeGen/X86/nosse-error2.ll llvm-svn: 63496 --- llvm/test/CodeGen/X86/nosse-error1.ll | 33 +++++++++++++++++++++++++++ llvm/test/CodeGen/X86/nosse-error2.ll | 33 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) create mode 100644 llvm/test/CodeGen/X86/nosse-error1.ll create mode 100644 llvm/test/CodeGen/X86/nosse-error2.ll diff --git a/llvm/test/CodeGen/X86/nosse-error1.ll b/llvm/test/CodeGen/X86/nosse-error1.ll new file mode 100644 index 000000000000..16cbb732af0e --- /dev/null +++ b/llvm/test/CodeGen/X86/nosse-error1.ll @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s > %t1 +; RUN: not llc -march=x86-64 -mattr=-sse < %t1 2> %t2 +; RUN: grep "SSE register return with SSE disabled" %t2 +; RUN: llc -march=x86-64 < %t1 | grep xmm +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" +target triple = "x86_64-unknown-linux-gnu" +@f = external global float ; [#uses=4] +@d = external global double ; [#uses=4] + +define void @test() nounwind { +entry: + %0 = load float* @f, align 4 ; [#uses=1] + %1 = tail call float @foo1(float %0) nounwind ; [#uses=1] + store float %1, float* @f, align 4 + %2 = load double* @d, align 8 ; [#uses=1] + %3 = tail call double @foo2(double %2) nounwind ; [#uses=1] + store double %3, double* @d, align 8 + %4 = load float* @f, align 4 ; [#uses=1] + %5 = tail call float @foo3(float %4) nounwind ; [#uses=1] + store float %5, float* @f, align 4 + %6 = load double* @d, align 8 ; [#uses=1] + %7 = tail call double @foo4(double %6) nounwind ; [#uses=1] + store double %7, double* @d, align 8 + ret void +} + +declare float @foo1(float) + +declare double @foo2(double) + +declare float @foo3(float) + +declare double @foo4(double) diff --git a/llvm/test/CodeGen/X86/nosse-error2.ll b/llvm/test/CodeGen/X86/nosse-error2.ll new file mode 100644 index 000000000000..45a5eaf3a415 --- /dev/null +++ b/llvm/test/CodeGen/X86/nosse-error2.ll @@ -0,0 +1,33 @@ +; RUN: llvm-as < %s > %t1 +; RUN: not llc -march=x86 -mcpu=i686 -mattr=-sse < %t1 2> %t2 +; RUN: grep "SSE register return with SSE disabled" %t2 +; RUN: llc -march=x86 -mcpu=i686 -mattr=+sse < %t1 | grep xmm +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i386-unknown-linux-gnu" +@f = external global float ; [#uses=4] +@d = external global double ; [#uses=4] + +define void @test() nounwind { +entry: + %0 = load float* @f, align 4 ; [#uses=1] + %1 = tail call inreg float @foo1(float inreg %0) nounwind ; [#uses=1] + store float %1, float* @f, align 4 + %2 = load double* @d, align 8 ; [#uses=1] + %3 = tail call inreg double @foo2(double inreg %2) nounwind ; [#uses=1] + store double %3, double* @d, align 8 + %4 = load float* @f, align 4 ; [#uses=1] + %5 = tail call inreg float @foo3(float inreg %4) nounwind ; [#uses=1] + store float %5, float* @f, align 4 + %6 = load double* @d, align 8 ; [#uses=1] + %7 = tail call inreg double @foo4(double inreg %6) nounwind ; [#uses=1] + store double %7, double* @d, align 8 + ret void +} + +declare inreg float @foo1(float inreg) + +declare inreg double @foo2(double inreg) + +declare inreg float @foo3(float inreg) + +declare inreg double @foo4(double inreg) -- GitLab From cc866c955c9137be887825f0754ab3bda45f51e3 Mon Sep 17 00:00:00 2001 From: Mon P Wang Date: Mon, 2 Feb 2009 06:37:55 +0000 Subject: [PATCH 594/682] Preserve more SourceValue information. llvm-svn: 63498 --- .../SelectionDAG/LegalizeIntegerTypes.cpp | 7 +++++-- .../SelectionDAG/LegalizeVectorTypes.cpp | 19 +++++++++++++------ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f28da3586934..f549ecea69fa 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -19,6 +19,7 @@ //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" +#include "llvm/CodeGen/PseudoSourceValue.h" using namespace llvm; //===----------------------------------------------------------------------===// @@ -214,12 +215,14 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { // Create the stack frame object. Make sure it is aligned for both // the source and destination types. SDValue FIPtr = DAG.CreateStackTemporary(InVT, OutVT); + int FI = cast(FIPtr.getNode())->getIndex(); + const Value *SV = PseudoSourceValue::getFixedStack(FI); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0); // Result is an extending load from the stack slot. - return DAG.getExtLoad(ISD::EXTLOAD, dl, NOutVT, Store, FIPtr, NULL, 0, OutVT); + return DAG.getExtLoad(ISD::EXTLOAD, dl, NOutVT, Store, FIPtr, SV, 0, OutVT); } SDValue DAGTypeLegalizer::PromoteIntRes_BSWAP(SDNode *N) { diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp index dac4fc5c1f6e..8ae42ababc89 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeVectorTypes.cpp @@ -21,6 +21,7 @@ //===----------------------------------------------------------------------===// #include "LegalizeTypes.h" +#include "llvm/CodeGen/PseudoSourceValue.h" #include "llvm/Target/TargetData.h" using namespace llvm; @@ -976,11 +977,13 @@ SDValue DAGTypeLegalizer::SplitVecOp_EXTRACT_VECTOR_ELT(SDNode *N) { MVT EltVT = VecVT.getVectorElementType(); DebugLoc dl = N->getDebugLoc(); SDValue StackPtr = DAG.CreateStackTemporary(VecVT); - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); + int SPFI = cast(StackPtr.getNode())->getIndex(); + const Value *SV = PseudoSourceValue::getFixedStack(SPFI); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, SV, 0); // Load back the required element. StackPtr = GetVectorElementPointer(StackPtr, EltVT, Idx); - return DAG.getLoad(EltVT, dl, Store, StackPtr, NULL, 0); + return DAG.getLoad(EltVT, dl, Store, StackPtr, SV, 0); } SDValue DAGTypeLegalizer::SplitVecOp_STORE(StoreSDNode *N, unsigned OpNo) { @@ -1350,12 +1353,14 @@ SDValue DAGTypeLegalizer::WidenVecRes_BIT_CONVERT(SDNode *N) { // from the stack. Create the stack frame object. Make sure it is aligned // for both the source and destination types. SDValue FIPtr = DAG.CreateStackTemporary(InVT, WidenVT); + int FI = cast(FIPtr.getNode())->getIndex(); + const Value *SV = PseudoSourceValue::getFixedStack(FI); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0); // Result is a load from the stack slot. - return DAG.getLoad(WidenVT, dl, Store, FIPtr, NULL, 0); + return DAG.getLoad(WidenVT, dl, Store, FIPtr, SV, 0); } SDValue DAGTypeLegalizer::WidenVecRes_BUILD_VECTOR(SDNode *N) { @@ -1849,12 +1854,14 @@ SDValue DAGTypeLegalizer::WidenVecOp_BIT_CONVERT(SDNode *N) { // frame object. Make sure it is aligned for both the source and destination // types. SDValue FIPtr = DAG.CreateStackTemporary(InWidenVT, VT); + int FI = cast(FIPtr.getNode())->getIndex(); + const Value *SV = PseudoSourceValue::getFixedStack(FI); // Emit a store to the stack slot. - SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, NULL, 0); + SDValue Store = DAG.getStore(DAG.getEntryNode(), dl, InOp, FIPtr, SV, 0); // Result is a load from the stack slot. - return DAG.getLoad(VT, dl, Store, FIPtr, NULL, 0); + return DAG.getLoad(VT, dl, Store, FIPtr, SV, 0); } SDValue DAGTypeLegalizer::WidenVecOp_CONCAT_VECTORS(SDNode *N) { -- GitLab From c4eb63d412af104e790fb0d16755eb5e61ab1096 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 06:55:45 +0000 Subject: [PATCH 595/682] reduce testcase. llvm-svn: 63499 --- .../InstCombine/2009-01-31-InfIterate.ll | 498 +----------------- 1 file changed, 18 insertions(+), 480 deletions(-) diff --git a/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll b/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll index 5c26c06bfc4d..6620e4fadd64 100644 --- a/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll +++ b/llvm/test/Transforms/InstCombine/2009-01-31-InfIterate.ll @@ -1,484 +1,22 @@ ; RUN: llvm-as < %s | opt -instcombine | llvm-dis ; PR3452 -target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" -target triple = "x86_64-unknown-linux-gnu" -@__clz_tab = external constant [256 x i8] ; <[256 x i8]*> [#uses=3] -@llvm.used = appending global [1 x i8*] [ i8* bitcast (void (i128, i128, i128*)* @__udivmodti4 to i8*) ], section "llvm.metadata" ; <[1 x i8*]*> [#uses=0] - -define fastcc void @__udivmodti4(i128 %n, i128 %d, i128* %rp) nounwind alwaysinline { +define i128 @test(i64 %A, i64 %B, i1 %C, i128 %Z, i128 %Y, i64* %P, i64* %Q) { entry: - %tmp1 = trunc i128 %n to i64 ; [#uses=12] - %sroa.store.elt = lshr i128 %n, 64 ; [#uses=1] - %tmp2 = trunc i128 %sroa.store.elt to i64 ; [#uses=12] - %tmp3 = trunc i128 %d to i64 ; [#uses=12] - %sroa.store.elt16 = lshr i128 %d, 64 ; [#uses=1] - %tmp4 = trunc i128 %sroa.store.elt16 to i64 ; [#uses=7] - %tmp5 = icmp eq i64 %tmp4, 0 ; [#uses=1] - br i1 %tmp5, label %bb, label %bb86 - -bb: ; preds = %entry - %tmp6 = icmp ugt i64 %tmp3, %tmp2 ; [#uses=1] - br i1 %tmp6, label %bb33.thread, label %bb50 - -bb33.thread: ; preds = %bb - br label %bb31 - -bb31: ; preds = %bb33, %bb33.thread - %__a28.0.reg2mem.0 = phi i64 [ 56, %bb33.thread ], [ %tmp9, %bb33 ] ; [#uses=3] - %.cast = and i64 %__a28.0.reg2mem.0, 4294967288 ; [#uses=1] - %tmp = shl i64 255, %.cast ; [#uses=1] - %tmp7 = and i64 %tmp3, %tmp ; [#uses=1] - %tmp8 = icmp eq i64 %tmp7, 0 ; [#uses=1] - br i1 %tmp8, label %bb33, label %bb34 - -bb33: ; preds = %bb31 - %tmp9 = add i64 %__a28.0.reg2mem.0, -8 ; [#uses=3] - %tmp10 = icmp eq i64 %tmp9, 0 ; [#uses=1] - br i1 %tmp10, label %bb34, label %bb31 - -bb34: ; preds = %bb33, %bb31 - %__a28.0.reg2mem.1 = phi i64 [ %__a28.0.reg2mem.0, %bb31 ], [ %tmp9, %bb33 ] ; [#uses=2] - %.cast35 = and i64 %__a28.0.reg2mem.1, 4294967288 ; [#uses=1] - %tmp11 = lshr i64 %tmp3, %.cast35 ; [#uses=1] - %tmp12 = getelementptr [256 x i8]* @__clz_tab, i64 0, i64 %tmp11 ; [#uses=1] - %tmp13 = load i8* %tmp12, align 1 ; [#uses=1] - %tmp14 = zext i8 %tmp13 to i64 ; [#uses=1] - %tmp15 = add i64 %tmp14, %__a28.0.reg2mem.1 ; [#uses=2] - %tmp16 = sub i64 64, %tmp15 ; [#uses=7] - %tmp17 = icmp eq i64 %tmp15, 64 ; [#uses=1] - br i1 %tmp17, label %bb41, label %bb36 - -bb36: ; preds = %bb34 - %.cast37 = and i64 %tmp16, 4294967295 ; [#uses=1] - %tmp18 = shl i64 %tmp3, %.cast37 ; [#uses=1] - %.cast38 = and i64 %tmp16, 4294967295 ; [#uses=1] - %tmp19 = shl i64 %tmp2, %.cast38 ; [#uses=1] - %tmp20 = sub i64 64, %tmp16 ; [#uses=1] - %.cast39 = and i64 %tmp20, 4294967295 ; [#uses=1] - %tmp21 = lshr i64 %tmp1, %.cast39 ; [#uses=1] - %tmp22 = or i64 %tmp19, %tmp21 ; [#uses=1] - %.cast40 = and i64 %tmp16, 4294967295 ; [#uses=1] - %tmp23 = shl i64 %tmp1, %.cast40 ; [#uses=1] - br label %bb41 - -bb41: ; preds = %bb36, %bb34 - %n1.0 = phi i64 [ %tmp2, %bb34 ], [ %tmp22, %bb36 ] ; [#uses=2] - %n0.0 = phi i64 [ %tmp1, %bb34 ], [ %tmp23, %bb36 ] ; [#uses=2] - %d0.0 = phi i64 [ %tmp3, %bb34 ], [ %tmp18, %bb36 ] ; [#uses=8] - %tmp24 = lshr i64 %d0.0, 32 ; [#uses=4] - %tmp25 = and i64 %d0.0, 4294967295 ; [#uses=2] - %tmp26 = urem i64 %n1.0, %tmp24 ; [#uses=1] - %tmp27 = udiv i64 %n1.0, %tmp24 ; [#uses=1] - %tmp28 = mul i64 %tmp27, %tmp25 ; [#uses=3] - %tmp29 = shl i64 %tmp26, 32 ; [#uses=1] - %tmp30 = lshr i64 %n0.0, 32 ; [#uses=1] - %tmp31 = or i64 %tmp29, %tmp30 ; [#uses=3] - %tmp32 = icmp ult i64 %tmp31, %tmp28 ; [#uses=1] - br i1 %tmp32, label %bb42, label %bb45 - -bb42: ; preds = %bb41 - %tmp33 = add i64 %tmp31, %d0.0 ; [#uses=4] - %.not = icmp uge i64 %tmp33, %d0.0 ; [#uses=1] - %tmp34 = icmp ult i64 %tmp33, %tmp28 ; [#uses=1] - %or.cond = and i1 %tmp34, %.not ; [#uses=1] - br i1 %or.cond, label %bb44, label %bb45 - -bb44: ; preds = %bb42 - %tmp35 = add i64 %tmp33, %d0.0 ; [#uses=1] - br label %bb45 - -bb45: ; preds = %bb44, %bb42, %bb41 - %__r123.0 = phi i64 [ %tmp31, %bb41 ], [ %tmp33, %bb42 ], [ %tmp35, %bb44 ] ; [#uses=1] - %tmp36 = sub i64 %__r123.0, %tmp28 ; [#uses=2] - %tmp37 = urem i64 %tmp36, %tmp24 ; [#uses=1] - %tmp38 = udiv i64 %tmp36, %tmp24 ; [#uses=1] - %tmp39 = mul i64 %tmp38, %tmp25 ; [#uses=5] - %tmp40 = shl i64 %tmp37, 32 ; [#uses=1] - %tmp41 = and i64 %n0.0, 4294967295 ; [#uses=1] - %tmp42 = or i64 %tmp40, %tmp41 ; [#uses=3] - %tmp43 = icmp ult i64 %tmp42, %tmp39 ; [#uses=1] - br i1 %tmp43, label %bb46, label %bb83 - -bb46: ; preds = %bb45 - %tmp44 = add i64 %tmp42, %d0.0 ; [#uses=4] - %.not137 = icmp uge i64 %tmp44, %d0.0 ; [#uses=1] - %tmp45 = icmp ult i64 %tmp44, %tmp39 ; [#uses=1] - %or.cond138 = and i1 %tmp45, %.not137 ; [#uses=1] - br i1 %or.cond138, label %bb48, label %bb83 - -bb48: ; preds = %bb46 - %tmp46 = add i64 %tmp44, %d0.0 ; [#uses=1] - br label %bb83 - -bb50: ; preds = %bb - %tmp47 = icmp eq i64 %tmp3, 0 ; [#uses=1] - br i1 %tmp47, label %bb51, label %bb56.thread - -bb51: ; preds = %bb50 - %tmp48 = udiv i64 1, %tmp3 ; [#uses=1] - br label %bb56.thread - -bb53: ; preds = %bb56, %bb56.thread - %__a19.0.reg2mem.0 = phi i64 [ 56, %bb56.thread ], [ %tmp51, %bb56 ] ; [#uses=3] - %.cast54 = and i64 %__a19.0.reg2mem.0, 4294967288 ; [#uses=1] - %tmp133 = shl i64 255, %.cast54 ; [#uses=1] - %tmp49 = and i64 %d0.1.ph, %tmp133 ; [#uses=1] - %tmp50 = icmp eq i64 %tmp49, 0 ; [#uses=1] - br i1 %tmp50, label %bb56, label %bb57 - -bb56.thread: ; preds = %bb51, %bb50 - %d0.1.ph = phi i64 [ %tmp48, %bb51 ], [ %tmp3, %bb50 ] ; [#uses=5] - br label %bb53 - -bb56: ; preds = %bb53 - %tmp51 = add i64 %__a19.0.reg2mem.0, -8 ; [#uses=3] - %tmp52 = icmp eq i64 %tmp51, 0 ; [#uses=1] - br i1 %tmp52, label %bb57, label %bb53 - -bb57: ; preds = %bb56, %bb53 - %__a19.0.reg2mem.1 = phi i64 [ %__a19.0.reg2mem.0, %bb53 ], [ %tmp51, %bb56 ] ; [#uses=2] - %.cast58 = and i64 %__a19.0.reg2mem.1, 4294967288 ; [#uses=1] - %tmp53 = lshr i64 %d0.1.ph, %.cast58 ; [#uses=1] - %tmp54 = getelementptr [256 x i8]* @__clz_tab, i64 0, i64 %tmp53 ; [#uses=1] - %tmp55 = load i8* %tmp54, align 1 ; [#uses=1] - %tmp56 = zext i8 %tmp55 to i64 ; [#uses=1] - %tmp57 = add i64 %tmp56, %__a19.0.reg2mem.1 ; [#uses=2] - %tmp58 = sub i64 64, %tmp57 ; [#uses=7] - %tmp59 = icmp eq i64 %tmp57, 64 ; [#uses=1] - br i1 %tmp59, label %bb74, label %bb60 - -bb60: ; preds = %bb57 - %tmp60 = sub i64 64, %tmp58 ; [#uses=2] - %.cast61 = and i64 %tmp58, 4294967295 ; [#uses=1] - %tmp61 = shl i64 %d0.1.ph, %.cast61 ; [#uses=9] - %.cast62 = and i64 %tmp60, 4294967295 ; [#uses=1] - %tmp62 = lshr i64 %tmp2, %.cast62 ; [#uses=2] - %.cast63 = and i64 %tmp58, 4294967295 ; [#uses=1] - %tmp63 = shl i64 %tmp2, %.cast63 ; [#uses=1] - %.cast64 = and i64 %tmp60, 4294967295 ; [#uses=1] - %tmp64 = lshr i64 %tmp1, %.cast64 ; [#uses=1] - %tmp65 = or i64 %tmp63, %tmp64 ; [#uses=2] - %.cast65 = and i64 %tmp58, 4294967295 ; [#uses=1] - %tmp66 = shl i64 %tmp1, %.cast65 ; [#uses=1] - %tmp67 = lshr i64 %tmp61, 32 ; [#uses=4] - %tmp68 = and i64 %tmp61, 4294967295 ; [#uses=2] - %tmp69 = urem i64 %tmp62, %tmp67 ; [#uses=1] - %tmp70 = udiv i64 %tmp62, %tmp67 ; [#uses=1] - %tmp71 = mul i64 %tmp70, %tmp68 ; [#uses=3] - %tmp72 = shl i64 %tmp69, 32 ; [#uses=1] - %tmp73 = lshr i64 %tmp65, 32 ; [#uses=1] - %tmp74 = or i64 %tmp72, %tmp73 ; [#uses=3] - %tmp75 = icmp ult i64 %tmp74, %tmp71 ; [#uses=1] - br i1 %tmp75, label %bb66, label %bb69 - -bb66: ; preds = %bb60 - %tmp76 = add i64 %tmp74, %tmp61 ; [#uses=4] - %.not139 = icmp uge i64 %tmp76, %tmp61 ; [#uses=1] - %tmp77 = icmp ult i64 %tmp76, %tmp71 ; [#uses=1] - %or.cond140 = and i1 %tmp77, %.not139 ; [#uses=1] - br i1 %or.cond140, label %bb68, label %bb69 - -bb68: ; preds = %bb66 - %tmp78 = add i64 %tmp76, %tmp61 ; [#uses=1] - br label %bb69 - -bb69: ; preds = %bb68, %bb66, %bb60 - %__r114.0 = phi i64 [ %tmp74, %bb60 ], [ %tmp76, %bb66 ], [ %tmp78, %bb68 ] ; [#uses=1] - %tmp79 = sub i64 %__r114.0, %tmp71 ; [#uses=2] - %tmp80 = urem i64 %tmp79, %tmp67 ; [#uses=1] - %tmp81 = udiv i64 %tmp79, %tmp67 ; [#uses=1] - %tmp82 = mul i64 %tmp81, %tmp68 ; [#uses=3] - %tmp83 = shl i64 %tmp80, 32 ; [#uses=1] - %tmp84 = and i64 %tmp65, 4294967295 ; [#uses=1] - %tmp85 = or i64 %tmp83, %tmp84 ; [#uses=3] - %tmp86 = icmp ult i64 %tmp85, %tmp82 ; [#uses=1] - br i1 %tmp86, label %bb70, label %bb73 - -bb70: ; preds = %bb69 - %tmp87 = add i64 %tmp85, %tmp61 ; [#uses=4] - %.not141 = icmp uge i64 %tmp87, %tmp61 ; [#uses=1] - %tmp88 = icmp ult i64 %tmp87, %tmp82 ; [#uses=1] - %or.cond142 = and i1 %tmp88, %.not141 ; [#uses=1] - br i1 %or.cond142, label %bb72, label %bb73 - -bb72: ; preds = %bb70 - %tmp89 = add i64 %tmp87, %tmp61 ; [#uses=1] - br label %bb73 - -bb73: ; preds = %bb72, %bb70, %bb69 - %__r013.0 = phi i64 [ %tmp85, %bb69 ], [ %tmp87, %bb70 ], [ %tmp89, %bb72 ] ; [#uses=1] - br label %bb74 - -bb74: ; preds = %bb73, %bb57 - %__r013.0.pn = phi i64 [ %__r013.0, %bb73 ], [ %tmp2, %bb57 ] ; [#uses=1] - %.pn135 = phi i64 [ %tmp82, %bb73 ], [ %d0.1.ph, %bb57 ] ; [#uses=1] - %n0.2 = phi i64 [ %tmp66, %bb73 ], [ %tmp1, %bb57 ] ; [#uses=2] - %d0.2 = phi i64 [ %tmp61, %bb73 ], [ %d0.1.ph, %bb57 ] ; [#uses=8] - %n1.1 = sub i64 %__r013.0.pn, %.pn135 ; [#uses=2] - %tmp90 = lshr i64 %d0.2, 32 ; [#uses=4] - %tmp91 = and i64 %d0.2, 4294967295 ; [#uses=2] - %tmp92 = urem i64 %n1.1, %tmp90 ; [#uses=1] - %tmp93 = udiv i64 %n1.1, %tmp90 ; [#uses=1] - %tmp94 = mul i64 %tmp93, %tmp91 ; [#uses=3] - %tmp95 = shl i64 %tmp92, 32 ; [#uses=1] - %tmp96 = lshr i64 %n0.2, 32 ; [#uses=1] - %tmp97 = or i64 %tmp95, %tmp96 ; [#uses=3] - %tmp98 = icmp ult i64 %tmp97, %tmp94 ; [#uses=1] - br i1 %tmp98, label %bb75, label %bb78 - -bb75: ; preds = %bb74 - %tmp99 = add i64 %tmp97, %d0.2 ; [#uses=4] - %.not143 = icmp uge i64 %tmp99, %d0.2 ; [#uses=1] - %tmp100 = icmp ult i64 %tmp99, %tmp94 ; [#uses=1] - %or.cond144 = and i1 %tmp100, %.not143 ; [#uses=1] - br i1 %or.cond144, label %bb77, label %bb78 - -bb77: ; preds = %bb75 - %tmp101 = add i64 %tmp99, %d0.2 ; [#uses=1] - br label %bb78 - -bb78: ; preds = %bb77, %bb75, %bb74 - %__r17.0 = phi i64 [ %tmp97, %bb74 ], [ %tmp99, %bb75 ], [ %tmp101, %bb77 ] ; [#uses=1] - %tmp102 = sub i64 %__r17.0, %tmp94 ; [#uses=2] - %tmp103 = urem i64 %tmp102, %tmp90 ; [#uses=1] - %tmp104 = udiv i64 %tmp102, %tmp90 ; [#uses=1] - %tmp105 = mul i64 %tmp104, %tmp91 ; [#uses=5] - %tmp106 = shl i64 %tmp103, 32 ; [#uses=1] - %tmp107 = and i64 %n0.2, 4294967295 ; [#uses=1] - %tmp108 = or i64 %tmp106, %tmp107 ; [#uses=3] - %tmp109 = icmp ult i64 %tmp108, %tmp105 ; [#uses=1] - br i1 %tmp109, label %bb79, label %bb83 - -bb79: ; preds = %bb78 - %tmp110 = add i64 %tmp108, %d0.2 ; [#uses=4] - %.not145 = icmp uge i64 %tmp110, %d0.2 ; [#uses=1] - %tmp111 = icmp ult i64 %tmp110, %tmp105 ; [#uses=1] - %or.cond146 = and i1 %tmp111, %.not145 ; [#uses=1] - br i1 %or.cond146, label %bb81, label %bb83 - -bb81: ; preds = %bb79 - %tmp112 = add i64 %tmp110, %d0.2 ; [#uses=1] - br label %bb83 - -bb83: ; preds = %bb81, %bb79, %bb78, %bb48, %bb46, %bb45 - %bm.0 = phi i64 [ %tmp16, %bb46 ], [ %tmp16, %bb48 ], [ %tmp16, %bb45 ], [ %tmp58, %bb79 ], [ %tmp58, %bb81 ], [ %tmp58, %bb78 ] ; [#uses=1] - %__r06.0.pn = phi i64 [ %tmp42, %bb45 ], [ %tmp44, %bb46 ], [ %tmp46, %bb48 ], [ %tmp108, %bb78 ], [ %tmp110, %bb79 ], [ %tmp112, %bb81 ] ; [#uses=1] - %.pn = phi i64 [ %tmp39, %bb46 ], [ %tmp39, %bb48 ], [ %tmp39, %bb45 ], [ %tmp105, %bb79 ], [ %tmp105, %bb81 ], [ %tmp105, %bb78 ] ; [#uses=1] - %tmp113 = icmp eq i128* %rp, null ; [#uses=1] - br i1 %tmp113, label %bb131, label %bb84 - -bb84: ; preds = %bb83 - %n0.1 = sub i64 %__r06.0.pn, %.pn ; [#uses=1] - %.cast85 = and i64 %bm.0, 4294967295 ; [#uses=1] - %tmp114 = lshr i64 %n0.1, %.cast85 ; [#uses=1] - %tmp115 = zext i64 %tmp114 to i128 ; [#uses=1] - store i128 %tmp115, i128* %rp, align 16 - br label %bb131 - -bb86: ; preds = %entry - %tmp116 = icmp ugt i64 %tmp4, %tmp2 ; [#uses=1] - br i1 %tmp116, label %bb87, label %bb93.thread - -bb93.thread: ; preds = %bb86 - br label %bb90 - -bb87: ; preds = %bb86 - %tmp117 = icmp eq i128* %rp, null ; [#uses=1] - br i1 %tmp117, label %bb131, label %bb88 - -bb88: ; preds = %bb87 - store i128 %n, i128* %rp, align 16 - br label %bb131 - -bb90: ; preds = %bb93, %bb93.thread - %__a.0.reg2mem.0 = phi i64 [ 56, %bb93.thread ], [ %tmp120, %bb93 ] ; [#uses=3] - %.cast91 = and i64 %__a.0.reg2mem.0, 4294967288 ; [#uses=1] - %tmp136 = shl i64 255, %.cast91 ; [#uses=1] - %tmp118 = and i64 %tmp4, %tmp136 ; [#uses=1] - %tmp119 = icmp eq i64 %tmp118, 0 ; [#uses=1] - br i1 %tmp119, label %bb93, label %bb94 - -bb93: ; preds = %bb90 - %tmp120 = add i64 %__a.0.reg2mem.0, -8 ; [#uses=3] - %tmp121 = icmp eq i64 %tmp120, 0 ; [#uses=1] - br i1 %tmp121, label %bb94, label %bb90 - -bb94: ; preds = %bb93, %bb90 - %__a.0.reg2mem.1 = phi i64 [ %__a.0.reg2mem.0, %bb90 ], [ %tmp120, %bb93 ] ; [#uses=2] - %.cast95 = and i64 %__a.0.reg2mem.1, 4294967288 ; [#uses=1] - %tmp122 = lshr i64 %tmp4, %.cast95 ; [#uses=1] - %tmp123 = getelementptr [256 x i8]* @__clz_tab, i64 0, i64 %tmp122 ; [#uses=1] - %tmp124 = load i8* %tmp123, align 1 ; [#uses=1] - %tmp125 = zext i8 %tmp124 to i64 ; [#uses=1] - %tmp126 = add i64 %tmp125, %__a.0.reg2mem.1 ; [#uses=2] - %tmp127 = sub i64 64, %tmp126 ; [#uses=7] - %tmp128 = icmp eq i64 %tmp126, 64 ; [#uses=1] - br i1 %tmp128, label %bb96, label %bb103 - -bb96: ; preds = %bb94 - %tmp129 = icmp ugt i64 %tmp2, %tmp4 ; [#uses=1] - %tmp130 = icmp uge i64 %tmp1, %tmp3 ; [#uses=1] - %tmp131 = or i1 %tmp129, %tmp130 ; [#uses=1] - br i1 %tmp131, label %bb99, label %bb101 - -bb99: ; preds = %bb96 - %tmp132 = sub i64 %tmp1, %tmp3 ; [#uses=2] - %tmp134 = sub i64 %tmp2, %tmp4 ; [#uses=1] - %tmp135 = icmp ugt i64 %tmp132, %tmp1 ; [#uses=1] - %tmp137 = zext i1 %tmp135 to i64 ; [#uses=1] - %tmp138 = sub i64 %tmp134, %tmp137 ; [#uses=1] - br label %bb101 - -bb101: ; preds = %bb99, %bb96 - %tmp139 = phi i64 [ %tmp138, %bb99 ], [ %tmp2, %bb96 ] ; [#uses=1] - %n0.3 = phi i64 [ %tmp132, %bb99 ], [ %tmp1, %bb96 ] ; [#uses=1] - %tmp140 = icmp eq i128* %rp, null ; [#uses=1] - br i1 %tmp140, label %bb131, label %bb102 - -bb102: ; preds = %bb101 - %tmp141 = zext i64 %n0.3 to i128 ; [#uses=1] - %tmp142 = zext i64 %tmp139 to i128 ; [#uses=1] - %tmp143 = shl i128 %tmp142, 64 ; [#uses=1] - %tmp144 = or i128 %tmp143, %tmp141 ; [#uses=1] - store i128 %tmp144, i128* %rp, align 16 - br label %bb131 - -bb103: ; preds = %bb94 - %tmp145 = sub i64 64, %tmp127 ; [#uses=4] - %.cast104 = and i64 %tmp127, 4294967295 ; [#uses=1] - %tmp146 = shl i64 %tmp4, %.cast104 ; [#uses=1] - %.cast105 = and i64 %tmp145, 4294967295 ; [#uses=1] - %tmp147 = lshr i64 %tmp3, %.cast105 ; [#uses=1] - %tmp148 = or i64 %tmp146, %tmp147 ; [#uses=9] - %.cast106 = and i64 %tmp127, 4294967295 ; [#uses=1] - %tmp149 = shl i64 %tmp3, %.cast106 ; [#uses=3] - %.cast107 = and i64 %tmp145, 4294967295 ; [#uses=1] - %tmp150 = lshr i64 %tmp2, %.cast107 ; [#uses=2] - %.cast108 = and i64 %tmp127, 4294967295 ; [#uses=1] - %tmp151 = shl i64 %tmp2, %.cast108 ; [#uses=1] - %.cast109 = and i64 %tmp145, 4294967295 ; [#uses=1] - %tmp152 = lshr i64 %tmp1, %.cast109 ; [#uses=1] - %tmp153 = or i64 %tmp151, %tmp152 ; [#uses=2] - %.cast110 = and i64 %tmp127, 4294967295 ; [#uses=1] - %tmp154 = shl i64 %tmp1, %.cast110 ; [#uses=3] - %tmp155 = lshr i64 %tmp148, 32 ; [#uses=4] - %tmp156 = and i64 %tmp148, 4294967295 ; [#uses=2] - %tmp157 = urem i64 %tmp150, %tmp155 ; [#uses=1] - %tmp158 = udiv i64 %tmp150, %tmp155 ; [#uses=4] - %tmp159 = mul i64 %tmp158, %tmp156 ; [#uses=3] - %tmp160 = shl i64 %tmp157, 32 ; [#uses=1] - %tmp161 = lshr i64 %tmp153, 32 ; [#uses=1] - %tmp162 = or i64 %tmp160, %tmp161 ; [#uses=3] - %tmp163 = icmp ult i64 %tmp162, %tmp159 ; [#uses=1] - br i1 %tmp163, label %bb111, label %bb114 - -bb111: ; preds = %bb103 - %tmp164 = add i64 %tmp158, -1 ; [#uses=1] - %tmp165 = add i64 %tmp162, %tmp148 ; [#uses=4] - %.not147 = icmp uge i64 %tmp165, %tmp148 ; [#uses=1] - %tmp166 = icmp ult i64 %tmp165, %tmp159 ; [#uses=1] - %or.cond148 = and i1 %tmp166, %.not147 ; [#uses=1] - br i1 %or.cond148, label %bb113, label %bb114 - -bb113: ; preds = %bb111 - %tmp167 = add i64 %tmp158, -2 ; [#uses=1] - %tmp168 = add i64 %tmp165, %tmp148 ; [#uses=1] - br label %bb114 - -bb114: ; preds = %bb113, %bb111, %bb103 - %__q1.0 = phi i64 [ %tmp158, %bb103 ], [ %tmp164, %bb111 ], [ %tmp167, %bb113 ] ; [#uses=1] - %__r1.0 = phi i64 [ %tmp162, %bb103 ], [ %tmp165, %bb111 ], [ %tmp168, %bb113 ] ; [#uses=1] - %tmp169 = sub i64 %__r1.0, %tmp159 ; [#uses=2] - %tmp170 = urem i64 %tmp169, %tmp155 ; [#uses=1] - %tmp171 = udiv i64 %tmp169, %tmp155 ; [#uses=4] - %tmp172 = mul i64 %tmp171, %tmp156 ; [#uses=3] - %tmp173 = shl i64 %tmp170, 32 ; [#uses=1] - %tmp174 = and i64 %tmp153, 4294967295 ; [#uses=1] - %tmp175 = or i64 %tmp173, %tmp174 ; [#uses=3] - %tmp176 = icmp ult i64 %tmp175, %tmp172 ; [#uses=1] - br i1 %tmp176, label %bb115, label %bb118 - -bb115: ; preds = %bb114 - %tmp177 = add i64 %tmp171, -1 ; [#uses=1] - %tmp178 = add i64 %tmp175, %tmp148 ; [#uses=4] - %.not149 = icmp uge i64 %tmp178, %tmp148 ; [#uses=1] - %tmp179 = icmp ult i64 %tmp178, %tmp172 ; [#uses=1] - %or.cond150 = and i1 %tmp179, %.not149 ; [#uses=1] - br i1 %or.cond150, label %bb117, label %bb118 - -bb117: ; preds = %bb115 - %tmp180 = add i64 %tmp171, -2 ; [#uses=1] - %tmp181 = add i64 %tmp178, %tmp148 ; [#uses=1] - br label %bb118 - -bb118: ; preds = %bb117, %bb115, %bb114 - %__q0.0 = phi i64 [ %tmp171, %bb114 ], [ %tmp177, %bb115 ], [ %tmp180, %bb117 ] ; [#uses=2] - %__r0.0 = phi i64 [ %tmp175, %bb114 ], [ %tmp178, %bb115 ], [ %tmp181, %bb117 ] ; [#uses=1] - %tmp182 = sub i64 %__r0.0, %tmp172 ; [#uses=3] - %tmp183 = shl i64 %__q1.0, 32 ; [#uses=1] - %tmp184 = or i64 %tmp183, %__q0.0 ; [#uses=1] - %tmp185 = and i64 %__q0.0, 4294967295 ; [#uses=2] - %tmp186 = lshr i64 %tmp184, 32 ; [#uses=2] - %tmp187 = and i64 %tmp149, 4294967295 ; [#uses=2] - %tmp188 = lshr i64 %tmp149, 32 ; [#uses=2] - %tmp189 = mul i64 %tmp185, %tmp187 ; [#uses=2] - %tmp190 = mul i64 %tmp185, %tmp188 ; [#uses=1] - %tmp191 = mul i64 %tmp186, %tmp187 ; [#uses=2] - %tmp192 = mul i64 %tmp186, %tmp188 ; [#uses=1] - %tmp193 = lshr i64 %tmp189, 32 ; [#uses=1] - %tmp194 = add i64 %tmp193, %tmp190 ; [#uses=1] - %tmp195 = add i64 %tmp194, %tmp191 ; [#uses=3] - %tmp196 = icmp ult i64 %tmp195, %tmp191 ; [#uses=1] - %tmp197 = select i1 %tmp196, i64 4294967296, i64 0 ; [#uses=1] - %__x3.0 = add i64 %tmp192, %tmp197 ; [#uses=1] - %tmp198 = lshr i64 %tmp195, 32 ; [#uses=1] - %tmp199 = add i64 %tmp198, %__x3.0 ; [#uses=4] - %tmp200 = shl i64 %tmp195, 32 ; [#uses=1] - %tmp201 = and i64 %tmp189, 4294967295 ; [#uses=1] - %tmp202 = or i64 %tmp200, %tmp201 ; [#uses=4] - %tmp203 = icmp ugt i64 %tmp199, %tmp182 ; [#uses=1] - br i1 %tmp203, label %bb125, label %bb121 - -bb121: ; preds = %bb118 - %tmp204 = icmp eq i64 %tmp199, %tmp182 ; [#uses=1] - %tmp205 = icmp ugt i64 %tmp202, %tmp154 ; [#uses=1] - %tmp206 = and i1 %tmp204, %tmp205 ; [#uses=1] - br i1 %tmp206, label %bb125, label %bb126 - -bb125: ; preds = %bb121, %bb118 - %tmp207 = sub i64 %tmp202, %tmp149 ; [#uses=2] - %tmp208 = sub i64 %tmp199, %tmp148 ; [#uses=1] - %tmp209 = icmp ugt i64 %tmp207, %tmp202 ; [#uses=1] - %tmp210 = zext i1 %tmp209 to i64 ; [#uses=1] - %tmp211 = sub i64 %tmp208, %tmp210 ; [#uses=1] - br label %bb126 - -bb126: ; preds = %bb125, %bb121 - %m1.0 = phi i64 [ %tmp199, %bb121 ], [ %tmp211, %bb125 ] ; [#uses=1] - %m0.0 = phi i64 [ %tmp202, %bb121 ], [ %tmp207, %bb125 ] ; [#uses=1] - %tmp212 = icmp eq i128* %rp, null ; [#uses=1] - br i1 %tmp212, label %bb131, label %bb127 - -bb127: ; preds = %bb126 - %tmp213 = sub i64 %tmp154, %m0.0 ; [#uses=2] - %tmp214 = sub i64 %tmp182, %m1.0 ; [#uses=1] - %tmp215 = icmp ugt i64 %tmp213, %tmp154 ; [#uses=1] - %tmp216 = zext i1 %tmp215 to i64 ; [#uses=1] - %tmp217 = sub i64 %tmp214, %tmp216 ; [#uses=2] - %.cast128 = and i64 %tmp145, 4294967295 ; [#uses=1] - %tmp218 = shl i64 %tmp217, %.cast128 ; [#uses=1] - %.cast129 = and i64 %tmp127, 4294967295 ; [#uses=1] - %tmp219 = lshr i64 %tmp213, %.cast129 ; [#uses=1] - %tmp220 = or i64 %tmp218, %tmp219 ; [#uses=1] - %.cast130 = and i64 %tmp127, 4294967295 ; [#uses=1] - %tmp221 = lshr i64 %tmp217, %.cast130 ; [#uses=1] - %tmp222 = zext i64 %tmp220 to i128 ; [#uses=1] - %tmp223 = zext i64 %tmp221 to i128 ; [#uses=1] - %tmp224 = shl i128 %tmp223, 64 ; [#uses=1] - %tmp225 = or i128 %tmp224, %tmp222 ; [#uses=1] - store i128 %tmp225, i128* %rp, align 16 - br label %bb131 - -bb131: ; preds = %bb127, %bb126, %bb102, %bb101, %bb88, %bb87, %bb84, %bb83 - ret void + %tmp2 = trunc i128 %Z to i64 + %tmp4 = trunc i128 %Y to i64 + store i64 %tmp2, i64* %P + store i64 %tmp4, i64* %Q + %x = sub i64 %tmp2, %tmp4 + %c = sub i64 %tmp2, %tmp4 + %tmp137 = zext i1 %C to i64 + %tmp138 = sub i64 %c, %tmp137 + br label %T + +T: + %G = phi i64 [%tmp138, %entry], [%tmp2, %Fal] + %F = zext i64 %G to i128 + ret i128 %F + +Fal: + br label %T } -- GitLab From 1aafe4ceceeeb8ff57fc43f40f93ab3591a98e70 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 07:15:30 +0000 Subject: [PATCH 596/682] reduce indentation, (~XorCST->getValue()).isSignBit() -> isMaxSignedValue() llvm-svn: 63500 --- .../Scalar/InstructionCombining.cpp | 39 +++++++++---------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp index a1cb3dc39fc4..77a7d93d4103 100644 --- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp +++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp @@ -6101,27 +6101,26 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { case Instruction::Add: case Instruction::Sub: case Instruction::Xor: - if (I.isEquality()) { - // a+x icmp eq/ne b+x --> a icmp b + if (I.isEquality()) // a+x icmp eq/ne b+x --> a icmp b return new ICmpInst(I.getPredicate(), Op0I->getOperand(0), Op1I->getOperand(0)); - } else { - // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b - if (ConstantInt *CI = dyn_cast(Op0I->getOperand(1))) { - if (CI->getValue().isSignBit()) { - ICmpInst::Predicate Pred = I.isSignedPredicate() - ? I.getUnsignedPredicate() - : I.getSignedPredicate(); - return new ICmpInst(Pred, Op0I->getOperand(0), - Op1I->getOperand(0)); - } else if ((~CI->getValue()).isSignBit()) { - ICmpInst::Predicate Pred = I.isSignedPredicate() - ? I.getUnsignedPredicate() - : I.getSignedPredicate(); - Pred = I.getSwappedPredicate(Pred); - return new ICmpInst(Pred, Op0I->getOperand(0), - Op1I->getOperand(0)); - } + // icmp u/s (a ^ signbit), (b ^ signbit) --> icmp s/u a, b + if (ConstantInt *CI = dyn_cast(Op0I->getOperand(1))) { + if (CI->getValue().isSignBit()) { + ICmpInst::Predicate Pred = I.isSignedPredicate() + ? I.getUnsignedPredicate() + : I.getSignedPredicate(); + return new ICmpInst(Pred, Op0I->getOperand(0), + Op1I->getOperand(0)); + } + + if (CI->getValue().isMaxSignedValue()) { + ICmpInst::Predicate Pred = I.isSignedPredicate() + ? I.getUnsignedPredicate() + : I.getSignedPredicate(); + Pred = I.getSwappedPredicate(Pred); + return new ICmpInst(Pred, Op0I->getOperand(0), + Op1I->getOperand(0)); } } break; @@ -6460,7 +6459,7 @@ Instruction *InstCombiner::visitICmpInstWithInstAndIntCst(ICmpInst &ICI, } // (icmp u/s (xor A ~SignBit), C) -> (icmp s/u (xor C ~SignBit), A) - if (!ICI.isEquality() && (~XorCST->getValue()).isSignBit()) { + if (!ICI.isEquality() && XorCST->getValue().isMaxSignedValue()) { const APInt &NotSignBit = XorCST->getValue(); ICmpInst::Predicate Pred = ICI.isSignedPredicate() ? ICI.getUnsignedPredicate() -- GitLab From 1f386b8ec8de5d24f2eaaa676db0737fe298bccf Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 07:24:28 +0000 Subject: [PATCH 597/682] Fix PR3372 llvm-svn: 63501 --- llvm/lib/AsmParser/LLParser.cpp | 5 +++-- llvm/test/Assembler/2009-02-01-UnnamedForwardRef.ll | 6 ++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Assembler/2009-02-01-UnnamedForwardRef.ll diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 401dc39ca539..943f1d002568 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -471,8 +471,9 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc, GlobalVariable *GV = 0; // See if the global was forward referenced, if so, use the global. - if (!Name.empty() && (GV = M->getGlobalVariable(Name, true))) { - if (!ForwardRefVals.erase(Name)) + if (!Name.empty()) { + if ((GV = M->getGlobalVariable(Name, true)) && + !ForwardRefVals.erase(Name)) return Error(NameLoc, "redefinition of global '@" + Name + "'"); } else { std::map >::iterator diff --git a/llvm/test/Assembler/2009-02-01-UnnamedForwardRef.ll b/llvm/test/Assembler/2009-02-01-UnnamedForwardRef.ll new file mode 100644 index 000000000000..9c6e20d7335e --- /dev/null +++ b/llvm/test/Assembler/2009-02-01-UnnamedForwardRef.ll @@ -0,0 +1,6 @@ +; RUN: llvm-as < %s | llvm-dis +; PR3372 + +@X = global i32* @0 +global i32 4 + -- GitLab From cf7a58434129bac25d3a9c856613ec948a804887 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 07:32:36 +0000 Subject: [PATCH 598/682] =?UTF-8?q?Document=20type=20upreferences=20(PR338?= =?UTF-8?q?0),=20patch=20by=20Stein=20Roger=20Skafl=C3=B8tten=20with=20enh?= =?UTF-8?q?ancements=20and=20corrections=20by=20me.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit llvm-svn: 63502 --- llvm/docs/LangRef.html | 54 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/llvm/docs/LangRef.html b/llvm/docs/LangRef.html index 35f83b48d4f5..8d9b60da2a68 100644 --- a/llvm/docs/LangRef.html +++ b/llvm/docs/LangRef.html @@ -55,6 +55,7 @@
    • Opaque Type
    • +
    • Type Up-references
    • Constants @@ -722,7 +723,6 @@ change.

    • -
      Global Variables @@ -1646,6 +1646,58 @@ structure type).

      + + + +
      +
      Overview:
      +

      +An "up reference" allows you to refer to a lexically enclosing type without +requiring it to have a name. For instance, a structure declaration may contain a +pointer to any of the types it is lexically a member of. Example of up +references (with their equivalent as named type declarations) include:

      + +
      +   { \2 * }                %x = type { %t* }
      +   { \2 }*                 %y = type { %y }*
      +   \1*                     %z = type %z*
      +
      + +

      +An up reference is needed by the asmprinter for printing out cyclic types when +there is no declared name for a type in the cycle. Because the asmprinter does +not want to print out an infinite type string, it needs a syntax to handle +recursive types that have no names (all names are optional in llvm IR). +

      + +
      Syntax:
      +
      +   \<level>
      +
      + +

      +The level is the count of the lexical type that is being referred to. +

      + +
      Examples:
      + + + + + + + + + + +
      \1*Self-referential pointer.
      { { \3*, i8 }, i32 }Recursive structure where the upref refers to the out-most + structure.
      +
      + + + -- GitLab From 5e66858152544e7e93fe7af81193bdf4a32b1f75 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 07:33:15 +0000 Subject: [PATCH 599/682] validation error fix. llvm-svn: 63503 --- llvm/docs/LangRef.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/llvm/docs/LangRef.html b/llvm/docs/LangRef.html index 8d9b60da2a68..88970f971eca 100644 --- a/llvm/docs/LangRef.html +++ b/llvm/docs/LangRef.html @@ -1696,8 +1696,6 @@ The level is the count of the lexical type that is being referred to. - - -- GitLab From b2b177393cf26e74566bf723c2470e5c88b70ba5 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 07:40:17 +0000 Subject: [PATCH 600/682] reject things like: zext <4 x i32> %tmp to i256 llvm-svn: 63504 --- llvm/lib/VMCore/Verifier.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/llvm/lib/VMCore/Verifier.cpp b/llvm/lib/VMCore/Verifier.cpp index 384aa3ec4bce..62d2930ae072 100644 --- a/llvm/lib/VMCore/Verifier.cpp +++ b/llvm/lib/VMCore/Verifier.cpp @@ -715,6 +715,8 @@ void Verifier::visitTruncInst(TruncInst &I) { Assert1(SrcTy->isIntOrIntVector(), "Trunc only operates on integer", &I); Assert1(DestTy->isIntOrIntVector(), "Trunc only produces integer", &I); + Assert1(isa(SrcTy) == isa(DestTy), + "trunc source and destination must both be a vector or neither", &I); Assert1(SrcBitSize > DestBitSize,"DestTy too big for Trunc", &I); visitInstruction(I); @@ -728,6 +730,8 @@ void Verifier::visitZExtInst(ZExtInst &I) { // Get the size of the types in bits, we'll need this later Assert1(SrcTy->isIntOrIntVector(), "ZExt only operates on integer", &I); Assert1(DestTy->isIntOrIntVector(), "ZExt only produces an integer", &I); + Assert1(isa(SrcTy) == isa(DestTy), + "zext source and destination must both be a vector or neither", &I); unsigned SrcBitSize = SrcTy->getPrimitiveSizeInBits(); unsigned DestBitSize = DestTy->getPrimitiveSizeInBits(); @@ -747,6 +751,8 @@ void Verifier::visitSExtInst(SExtInst &I) { Assert1(SrcTy->isIntOrIntVector(), "SExt only operates on integer", &I); Assert1(DestTy->isIntOrIntVector(), "SExt only produces an integer", &I); + Assert1(isa(SrcTy) == isa(DestTy), + "sext source and destination must both be a vector or neither", &I); Assert1(SrcBitSize < DestBitSize,"Type too small for SExt", &I); visitInstruction(I); @@ -762,6 +768,8 @@ void Verifier::visitFPTruncInst(FPTruncInst &I) { Assert1(SrcTy->isFPOrFPVector(),"FPTrunc only operates on FP", &I); Assert1(DestTy->isFPOrFPVector(),"FPTrunc only produces an FP", &I); + Assert1(isa(SrcTy) == isa(DestTy), + "fptrunc source and destination must both be a vector or neither",&I); Assert1(SrcBitSize > DestBitSize,"DestTy too big for FPTrunc", &I); visitInstruction(I); @@ -778,6 +786,8 @@ void Verifier::visitFPExtInst(FPExtInst &I) { Assert1(SrcTy->isFPOrFPVector(),"FPExt only operates on FP", &I); Assert1(DestTy->isFPOrFPVector(),"FPExt only produces an FP", &I); + Assert1(isa(SrcTy) == isa(DestTy), + "fpext source and destination must both be a vector or neither", &I); Assert1(SrcBitSize < DestBitSize,"DestTy too small for FPExt", &I); visitInstruction(I); -- GitLab From 50e15bdf81fc54b1ddaca3c5f149f4087f6d8b08 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 2 Feb 2009 08:07:36 +0000 Subject: [PATCH 601/682] Teach LowerBRCOND to recognize (xor (setcc x), 1). The xor inverts the condition. It's normally transformed by the dag combiner, unless the condition is set by a arithmetic op with overflow. llvm-svn: 63505 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 21 +++++++++++++++++ llvm/test/CodeGen/X86/smul-with-overflow-3.ll | 23 +++++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 llvm/test/CodeGen/X86/smul-with-overflow-3.ll diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 19d5aedf6936..7590c2e4da99 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5366,6 +5366,17 @@ static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) { Op.getOperand(1).hasOneUse()); } +static bool isXor1OfSetCC(SDValue Op) { + if (Op.getOpcode() != ISD::XOR) + return false; + ConstantSDNode *N1C = dyn_cast(Op.getOperand(1)); + if (N1C && N1C->getAPIntValue() == 1) { + return Op.getOperand(0).getOpcode() == X86ISD::SETCC && + Op.getOperand(0).hasOneUse(); + } + return false; +} + SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { bool addTest = true; SDValue Chain = Op.getOperand(0); @@ -5460,6 +5471,16 @@ SDValue X86TargetLowering::LowerBRCOND(SDValue Op, SelectionDAG &DAG) { } } } + } else if (Cond.hasOneUse() && isXor1OfSetCC(Cond)) { + // Recognize for xorb (setcc), 1 patterns. The xor inverts the condition. + // It should be transformed during dag combiner except when the condition + // is set by a arithmetics with overflow node. + X86::CondCode CCode = + (X86::CondCode)Cond.getOperand(0).getConstantOperandVal(0); + CCode = X86::GetOppositeBranchCondition(CCode); + CC = DAG.getConstant(CCode, MVT::i8); + Cond = Cond.getOperand(0).getOperand(1); + addTest = false; } } diff --git a/llvm/test/CodeGen/X86/smul-with-overflow-3.ll b/llvm/test/CodeGen/X86/smul-with-overflow-3.ll new file mode 100644 index 000000000000..aa5e67a02998 --- /dev/null +++ b/llvm/test/CodeGen/X86/smul-with-overflow-3.ll @@ -0,0 +1,23 @@ +; RUN: llvm-as < %s | llc -march=x86 | grep {jno} | count 1 + +@ok = internal constant [4 x i8] c"%d\0A\00" +@no = internal constant [4 x i8] c"no\0A\00" + +define i1 @func1(i32 %v1, i32 %v2) nounwind { +entry: + %t = call {i32, i1} @llvm.smul.with.overflow.i32(i32 %v1, i32 %v2) + %sum = extractvalue {i32, i1} %t, 0 + %obit = extractvalue {i32, i1} %t, 1 + br i1 %obit, label %overflow, label %normal + +overflow: + %t2 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @no, i32 0, i32 0) ) nounwind + ret i1 false + +normal: + %t1 = tail call i32 (i8*, ...)* @printf( i8* getelementptr ([4 x i8]* @ok, i32 0, i32 0), i32 %sum ) nounwind + ret i1 true +} + +declare i32 @printf(i8*, ...) nounwind +declare {i32, i1} @llvm.smul.with.overflow.i32(i32, i32) -- GitLab From 4988c597b361d4a5cca5e146a41012d4cbd49e1e Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 2 Feb 2009 08:19:07 +0000 Subject: [PATCH 602/682] Add comment. llvm-svn: 63506 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 7590c2e4da99..846acd021979 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -5366,6 +5366,8 @@ static bool isAndOrOfSetCCs(SDValue Op, unsigned &Opc) { Op.getOperand(1).hasOneUse()); } +// isXor1OfSetCC - Return true if node is an ISD::XOR of a X86ISD::SETCC and +// 1 and that the SETCC node has a single use. static bool isXor1OfSetCC(SDValue Op) { if (Op.getOpcode() != ISD::XOR) return false; -- GitLab From dca376ff07c3689b66f969d7774c67eb904e1042 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 2 Feb 2009 09:07:13 +0000 Subject: [PATCH 603/682] Make the XFAIL line actually match x86-32 targets. llvm-svn: 63507 --- llvm/test/FrontendC/x86-64-red-zone.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/FrontendC/x86-64-red-zone.c b/llvm/test/FrontendC/x86-64-red-zone.c index e3e3cab2ff81..de9ebbe09b2c 100644 --- a/llvm/test/FrontendC/x86-64-red-zone.c +++ b/llvm/test/FrontendC/x86-64-red-zone.c @@ -6,6 +6,6 @@ // RUN: grep subq %t | count 1 // RUN: grep addq %t | count 1 // This is a test for x86-64, add your target below if it FAILs. -// XFAIL: alpha|ia64|arm|powerpc|sparc|x86 +// XFAIL: alpha|ia64|arm|powerpc|sparc|i.86 long double f0(float f) { return f; } -- GitLab From 7e4cb0a1cf0f2add6de6748825d9267a97feae5b Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 2 Feb 2009 09:10:57 +0000 Subject: [PATCH 604/682] This passes on x86-32 linux at least. llvm-svn: 63508 --- llvm/test/FrontendC++/2006-11-30-Pubnames.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp b/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp index 9693169e578a..5dd1439224ce 100644 --- a/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp +++ b/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp @@ -7,7 +7,6 @@ // RUN: echo {break main\nrun\np Pubnames::pubname} > %t.in // RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | grep {\$1 = 10} // XFAIL: alpha|ia64|arm -// XFAIL: * struct Pubnames { static int pubname; }; -- GitLab From dc636c4080bfe77b1377ba7fe8b3b98c87676d87 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 2 Feb 2009 09:15:04 +0000 Subject: [PATCH 605/682] ADD / SUB / SMUL / UMUL with overflow second result top bits must be zero. llvm-svn: 63509 --- llvm/lib/Target/X86/X86ISelLowering.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp index 846acd021979..7a4d34d10a4d 100644 --- a/llvm/lib/Target/X86/X86ISelLowering.cpp +++ b/llvm/lib/Target/X86/X86ISelLowering.cpp @@ -7515,6 +7515,14 @@ void X86TargetLowering::computeMaskedBitsForTargetNode(const SDValue Op, KnownZero = KnownOne = APInt(Mask.getBitWidth(), 0); // Don't know anything. switch (Opc) { default: break; + case X86ISD::ADD: + case X86ISD::SUB: + case X86ISD::SMUL: + case X86ISD::UMUL: + // These nodes' second result is a boolean. + if (Op.getResNo() == 0) + break; + // Fallthrough case X86ISD::SETCC: KnownZero |= APInt::getHighBitsSet(Mask.getBitWidth(), Mask.getBitWidth() - 1); -- GitLab From 33d6e97e337106c5ef17409921ed41c34233619b Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 2 Feb 2009 09:53:14 +0000 Subject: [PATCH 606/682] Fix an obvious thinko. llvm-svn: 63510 --- llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 10d2e00911d3..8f36317e8ca1 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1482,7 +1482,7 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, SV = BinaryOperator::CreateLShr(SV, ConstantInt::get(SV->getType(),-ShAmt), SV->getName(), SI); - Mask = Mask.lshr(ShAmt); + Mask = Mask.lshr(-ShAmt); } // Mask out the bits we are about to insert from the old value, and or -- GitLab From 6f361ff3450b5e61e53500269fbef5a7555f0f05 Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 2 Feb 2009 10:06:20 +0000 Subject: [PATCH 607/682] Fix a comment (bytes -> bits), reformat a comment and remove trailing whitespace. No functionality change. llvm-svn: 63511 --- .../Scalar/ScalarReplAggregates.cpp | 58 +++++++++---------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 8f36317e8ca1..29970ecb444f 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1283,26 +1283,26 @@ void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) { void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { while (!Ptr->use_empty()) { Instruction *User = cast(Ptr->use_back()); - + if (LoadInst *LI = dyn_cast(User)) { LI->replaceAllUsesWith(ConvertUsesOfLoadToScalar(LI, NewAI, Offset)); LI->eraseFromParent(); continue; } - + if (StoreInst *SI = dyn_cast(User)) { assert(SI->getOperand(0) != Ptr && "Consistency error!"); new StoreInst(ConvertUsesOfStoreToScalar(SI, NewAI, Offset), NewAI, SI); SI->eraseFromParent(); continue; } - + if (BitCastInst *CI = dyn_cast(User)) { ConvertUsesToScalar(CI, NewAI, Offset); CI->eraseFromParent(); continue; } - + if (GetElementPtrInst *GEP = dyn_cast(User)) { // Compute the offset that this GEP adds to the pointer. SmallVector Indices(GEP->op_begin()+1, GEP->op_end()); @@ -1317,19 +1317,19 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { } } -/// ConvertUsesOfLoadToScalar - Convert all of the users the specified load to -/// use the new alloca directly, returning the value that should replace the -/// load. This happens when we are converting an "integer union" to a -/// single integer scalar, or when we are converting a "vector union" to a -/// vector with insert/extractelement instructions. +/// ConvertUsesOfLoadToScalar - Convert all of the users of the specified load +/// to use the new alloca directly, returning the value that should replace the +/// load. This happens when we are converting an "integer union" to a single +/// integer scalar, or when we are converting a "vector union" to a vector with +/// insert/extractelement instructions. /// -/// Offset is an offset from the original alloca, in bytes that need to be +/// Offset is an offset from the original alloca, in bits that need to be /// shifted to the right. By the end of this, there should be no uses of Ptr. -Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, +Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, uint64_t Offset) { // The load is a bit extract from NewAI shifted right by Offset bits. Value *NV = new LoadInst(NewAI, LI->getName(), LI); - + // If the load is of the whole new alloca, no conversion is needed. if (NV->getType() == LI->getType() && Offset == 0) return NV; @@ -1351,10 +1351,10 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, return new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt), "tmp", LI); } - + // Otherwise, this must be a union that was converted to an integer value. const IntegerType *NTy = cast(NV->getType()); - + // If this is a big-endian system and the load is narrower than the // full alloca type, we need to do a shift to get the right bits. int ShAmt = 0; @@ -1367,7 +1367,7 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, } else { ShAmt = Offset; } - + // Note: we support negative bitwidths (with shl) which are not defined. // We do this to support (f.e.) loads off the end of a structure where // only some bits are used. @@ -1379,13 +1379,13 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, NV = BinaryOperator::CreateShl(NV, ConstantInt::get(NV->getType(), -ShAmt), LI->getName(), LI); - + // Finally, unconditionally truncate the integer to the right width. unsigned LIBitWidth = TD->getTypeSizeInBits(LI->getType()); if (LIBitWidth < NTy->getBitWidth()) NV = new TruncInst(NV, IntegerType::get(LIBitWidth), LI->getName(), LI); - + // If the result is an integer, this is a trunc or bitcast. if (isa(LI->getType())) { // Should be done. @@ -1410,9 +1410,9 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, /// /// Offset is an offset from the original alloca, in bits that need to be /// shifted to the right. By the end of this, there should be no uses of Ptr. -Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, +Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, uint64_t Offset) { - + // Convert the stored type to the actual type, shift it left to insert // then 'or' into place. Value *SV = SI->getOperand(0); @@ -1420,10 +1420,10 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, if (SV->getType() == AllocaType && Offset == 0) { return SV; } - + if (const VectorType *VTy = dyn_cast(AllocaType)) { Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); - + // If the result alloca is a vector type, this is either an element // access or a bitcast to another vector type. if (isa(SV->getType())) { @@ -1437,10 +1437,10 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, } return SV; } - - + + Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); - + // If SV is a float, convert it to the appropriate integer type. // If it is a pointer, do the same, and also handle ptr->ptr casts // here. @@ -1452,11 +1452,11 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, SV = new BitCastInst(SV, IntegerType::get(SrcWidth), SV->getName(), SI); else if (isa(SV->getType())) SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), SI); - + // Always zero extend the value if needed. if (SV->getType() != AllocaType) SV = new ZExtInst(SV, AllocaType, SV->getName(), SI); - + // If this is a big-endian system and the store is narrower than the // full alloca type, we need to do a shift to get the right bits. int ShAmt = 0; @@ -1468,13 +1468,13 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, } else { ShAmt = Offset; } - + // Note: we support negative bitwidths (with shr) which are not defined. // We do this to support (f.e.) stores off the end of a structure where // only some bits in the structure are set. APInt Mask(APInt::getLowBitsSet(DestWidth, SrcWidth)); if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) { - SV = BinaryOperator::CreateShl(SV, + SV = BinaryOperator::CreateShl(SV, ConstantInt::get(SV->getType(), ShAmt), SV->getName(), SI); Mask <<= ShAmt; @@ -1484,7 +1484,7 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, SV->getName(), SI); Mask = Mask.lshr(-ShAmt); } - + // Mask out the bits we are about to insert from the old value, and or // in the new bits. if (SrcWidth != DestWidth) { -- GitLab From 8877f99f9de829690bd14edded2fadbfe2675aec Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 2 Feb 2009 15:00:55 +0000 Subject: [PATCH 608/682] fix PR3459: improve compatibility with gcc when checking for constant exprs llvm-svn: 63517 --- clang/lib/Sema/SemaDecl.cpp | 7 +++---- clang/test/Sema/struct-decl.c | 10 ++++++++++ 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 clang/test/Sema/struct-decl.c diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 5dd45fb072d9..7d7badd2cb6c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3128,10 +3128,9 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, assert(EvalResult.Val.isInt() && "Size expressions must be integers!"); llvm::APSInt &Res = EvalResult.Val.getInt(); - if (Res > llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) - return Context.getConstantArrayType(VLATy->getElementType(), - Res, ArrayType::Normal, 0); - return QualType(); + + return Context.getConstantArrayType(VLATy->getElementType(), + Res, ArrayType::Normal, 0); } bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, diff --git a/clang/test/Sema/struct-decl.c b/clang/test/Sema/struct-decl.c new file mode 100644 index 000000000000..cacd84765826 --- /dev/null +++ b/clang/test/Sema/struct-decl.c @@ -0,0 +1,10 @@ +// RUN: clang -fsyntax-only -verify %s + +// PR3459 +struct bar { + char n[1]; +}; + +struct foo { + char name[(int)&((struct bar *)0)->n]; +}; -- GitLab From 0c92d25f2b23bc4119fe1f1382567d4f3b6355b4 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 2 Feb 2009 15:33:56 +0000 Subject: [PATCH 609/682] avoid creating tmp files elsewhere llvm-svn: 63518 --- clang/test/Driver/dependency-gen.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/test/Driver/dependency-gen.c b/clang/test/Driver/dependency-gen.c index ad9029f9f147..cd668f1ab5ea 100644 --- a/clang/test/Driver/dependency-gen.c +++ b/clang/test/Driver/dependency-gen.c @@ -1,5 +1,5 @@ // rdar://6533411 -// RUN: clang -MD -MF /tmp/null.d -x c /dev/null +// RUN: clang -MD -MF %t.d -x c /dev/null -- GitLab From 598afdcfe758846b5e248a5e9b457a3c1f2d9901 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 2 Feb 2009 16:07:41 +0000 Subject: [PATCH 610/682] allow cast from array to int to be considered as constant llvm-svn: 63519 --- clang/lib/Sema/SemaDecl.cpp | 3 +-- clang/test/Sema/static-init.c | 14 +++++++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 7d7badd2cb6c..fe7ab92b6a92 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2075,8 +2075,7 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { if (SubExpr->getType()->isPointerType()) { const Expr* Base = FindExpressionBaseAddress(SubExpr); // If the pointer has a null base, this is an offsetof-like construct - if (!Base) - return CheckAddressConstantExpression(SubExpr); + return Base ? false : CheckAddressConstantExpression(SubExpr); } InitializerElementNotConstant(Init); diff --git a/clang/test/Sema/static-init.c b/clang/test/Sema/static-init.c index 2f1380062d32..a4035e69df46 100644 --- a/clang/test/Sema/static-init.c +++ b/clang/test/Sema/static-init.c @@ -2,6 +2,18 @@ static int f = 10; static int b = f; // expected-error {{initializer element is not a compile-time constant}} -float r = (float) &r; // expected-error {{initializer element is not a compile-time constant}} +float r = (float) &r; // FIXME: should give an error: ptr value used where a float was expected long long s = (long long) &s; _Bool t = &t; + + +union bar { + int i; +}; + +struct foo { + unsigned ptr; +}; + +union bar u[1]; +struct foo x = {(int) u}; // no-error -- GitLab From 50aeb12d806a4e1aca9a3bd903d71ee3c01660db Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Mon, 2 Feb 2009 16:53:06 +0000 Subject: [PATCH 611/682] Made the common case of default address space directive as non-virtual for performance reasons. Provide a single virtual interface for directives of all sizes in non-default address spaces. llvm-svn: 63521 --- llvm/include/llvm/Target/TargetAsmInfo.h | 26 +++++++++---- llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp | 41 +++++++++----------- llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h | 7 ++-- 3 files changed, 40 insertions(+), 34 deletions(-) diff --git a/llvm/include/llvm/Target/TargetAsmInfo.h b/llvm/include/llvm/Target/TargetAsmInfo.h index 1cd55d0fcd1d..0e44666e5c12 100644 --- a/llvm/include/llvm/Target/TargetAsmInfo.h +++ b/llvm/include/llvm/Target/TargetAsmInfo.h @@ -298,6 +298,15 @@ namespace llvm { const char *Data32bitsDirective; // Defaults to "\t.long\t" const char *Data64bitsDirective; // Defaults to "\t.quad\t" + /// getASDirective - Targets can override it to provide different data + /// directives for various sizes and non-default address spaces. + virtual const char *getASDirective(unsigned size, + unsigned AS) const { + assert (AS > 0 + && "Dont know the directives for default addr space"); + return NULL; + } + //===--- Alignment Information ----------------------------------------===// /// AlignDirective - The directive used to emit round up to an alignment @@ -600,19 +609,20 @@ namespace llvm { // Data directive accessors // - virtual const char *getData8bitsDirective(unsigned AddrSpace = 0) const { - return Data8bitsDirective; + const char *getData8bitsDirective(unsigned AS = 0) const { + return AS == 0 ? Data8bitsDirective : getASDirective(8, AS); } - virtual const char *getData16bitsDirective(unsigned AddrSpace = 0) const { - return Data16bitsDirective; + const char *getData16bitsDirective(unsigned AS = 0) const { + return AS == 0 ? Data16bitsDirective : getASDirective(16, AS); } - virtual const char *getData32bitsDirective(unsigned AddrSpace = 0) const { - return Data32bitsDirective; + const char *getData32bitsDirective(unsigned AS = 0) const { + return AS == 0 ? Data32bitsDirective : getASDirective(32, AS); } - virtual const char *getData64bitsDirective(unsigned AddrSpace = 0) const { - return Data64bitsDirective; + const char *getData64bitsDirective(unsigned AS = 0) const { + return AS == 0 ? Data64bitsDirective : getASDirective(64, AS); } + // Accessors. // const Section *getTextSection() const { diff --git a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp index b86576be896e..d40f2065b828 100644 --- a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp +++ b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.cpp @@ -26,7 +26,7 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM) Data32bitsDirective = " dl "; RomData8bitsDirective = " dw "; RomData16bitsDirective = " rom_di "; - RomData8bitsDirective = " rom_dl "; + RomData32bitsDirective = " rom_dl "; ZeroDirective = NULL; AsciiDirective = " dt "; AscizDirective = NULL; @@ -37,27 +37,24 @@ PIC16TargetAsmInfo(const PIC16TargetMachine &TM) SwitchToSectionDirective = ""; } -const char *PIC16TargetAsmInfo::getData8bitsDirective(unsigned AddrSpace) - const { - if (AddrSpace == PIC16ISD::ROM_SPACE) - return RomData8bitsDirective; - else - return Data8bitsDirective; - } +const char *PIC16TargetAsmInfo::getRomDirective(unsigned size) const +{ + if (size == 8) + return RomData8bitsDirective; + else if (size == 16) + return RomData16bitsDirective; + else if (size == 32) + return RomData32bitsDirective; + else + return NULL; +} -const char *PIC16TargetAsmInfo::getData16bitsDirective(unsigned AddrSpace) - const { - if (AddrSpace == PIC16ISD::ROM_SPACE) - return RomData16bitsDirective; - else - return Data16bitsDirective; - } -const char *PIC16TargetAsmInfo::getData32bitsDirective(unsigned AddrSpace) - const { - if (AddrSpace == PIC16ISD::ROM_SPACE) - return RomData32bitsDirective; - else - return Data32bitsDirective; - } +const char *PIC16TargetAsmInfo::getASDirective(unsigned size, + unsigned AS) const { + if (AS == PIC16ISD::ROM_SPACE) + return getRomDirective(size); + else + return NULL; +} diff --git a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h index b75699ba8c4b..305e74d5a301 100644 --- a/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h +++ b/llvm/lib/Target/PIC16/PIC16TargetAsmInfo.h @@ -23,13 +23,12 @@ namespace llvm { struct PIC16TargetAsmInfo : public TargetAsmInfo { PIC16TargetAsmInfo(const PIC16TargetMachine &TM); + private: const char *RomData8bitsDirective; const char *RomData16bitsDirective; const char *RomData32bitsDirective; - public : - virtual const char *getData8bitsDirective(unsigned AddrSpace = 0) const; - virtual const char *getData16bitsDirective(unsigned AddrSpace = 0) const; - virtual const char *getData32bitsDirective(unsigned AddrSpace = 0) const; + const char *getRomDirective(unsigned size) const; + virtual const char *getASDirective(unsigned size, unsigned AS) const; }; } // namespace llvm -- GitLab From f26a1d4ef7a29b06559c64f3a5e0d04c8386b5b8 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 2 Feb 2009 17:19:26 +0000 Subject: [PATCH 612/682] RewriteObjC::RewriteBlockDeclRefExpr(): Add parens to enforce precedence. This fixes clang ObjC rewriter: Need parenthesis around dereferences in rewritten Blocks. Also changed RewriteObjC::SynthesizeBlockFunc() to declare a pointer to the block argument even when there are no user-supplied arguments to the block. llvm-svn: 63522 --- clang/Driver/RewriteObjC.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/clang/Driver/RewriteObjC.cpp b/clang/Driver/RewriteObjC.cpp index e2ddafe8d192..f18a0c53ce54 100644 --- a/clang/Driver/RewriteObjC.cpp +++ b/clang/Driver/RewriteObjC.cpp @@ -3458,7 +3458,9 @@ std::string RewriteObjC::SynthesizeBlockFunc(BlockExpr *CE, int i, BlockDecl *BD = CE->getBlockDecl(); if (isa(AFT)) { - S += "()"; + // No user-supplied arguments. Still need to pass in a pointer to the + // block (to reference imported block decl refs). + S += "(" + StructRef + " *__cself)"; } else if (BD->param_empty()) { S += "(" + StructRef + " *__cself)"; } else { @@ -3842,7 +3844,12 @@ void RewriteObjC::RewriteBlockCall(CallExpr *Exp) { void RewriteObjC::RewriteBlockDeclRefExpr(BlockDeclRefExpr *BDRE) { // FIXME: Add more elaborate code generation required by the ABI. - InsertText(BDRE->getLocStart(), "*", 1); + Expr *DerefExpr = new UnaryOperator(BDRE, UnaryOperator::Deref, + Context->getPointerType(BDRE->getType()), + SourceLocation()); + // Need parens to enforce precedence. + ParenExpr *PE = new ParenExpr(SourceLocation(), SourceLocation(), DerefExpr); + ReplaceStmt(BDRE, PE); } void RewriteObjC::RewriteCastExpr(CStyleCastExpr *CE) { -- GitLab From 8e56d1898bb41cbf17cd81c679e70268029e4711 Mon Sep 17 00:00:00 2001 From: Sanjiv Gupta Date: Mon, 2 Feb 2009 17:19:39 +0000 Subject: [PATCH 613/682] Duncan's patch. Further to 64382. Takes care of illegal types for shift amount. llvm-svn: 63523 --- .../SelectionDAG/LegalizeIntegerTypes.cpp | 26 +++++++++++++++++++ llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h | 2 ++ 2 files changed, 28 insertions(+) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f549ecea69fa..e4d111843d08 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -684,6 +684,12 @@ bool DAGTypeLegalizer::PromoteIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::TRUNCATE: Res = PromoteIntOp_TRUNCATE(N); break; case ISD::UINT_TO_FP: Res = PromoteIntOp_UINT_TO_FP(N); break; case ISD::ZERO_EXTEND: Res = PromoteIntOp_ZERO_EXTEND(N); break; + + case ISD::SHL: + case ISD::SRA: + case ISD::SRL: + case ISD::ROTL: + case ISD::ROTR: Res = PromoteIntOp_Shift(N); break; } // If the result is null, the sub-method took care of registering results etc. @@ -890,6 +896,11 @@ SDValue DAGTypeLegalizer::PromoteIntOp_SETCC(SDNode *N, unsigned OpNo) { return DAG.UpdateNodeOperands(SDValue(N, 0), LHS, RHS, N->getOperand(2)); } +SDValue DAGTypeLegalizer::PromoteIntOp_Shift(SDNode *N) { + return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), + ZExtPromotedInteger(N->getOperand(1))); +} + SDValue DAGTypeLegalizer::PromoteIntOp_SIGN_EXTEND(SDNode *N) { SDValue Op = GetPromotedInteger(N->getOperand(0)); DebugLoc dl = N->getDebugLoc(); @@ -1935,6 +1946,12 @@ bool DAGTypeLegalizer::ExpandIntegerOperand(SDNode *N, unsigned OpNo) { case ISD::STORE: Res = ExpandIntOp_STORE(cast(N), OpNo); break; case ISD::TRUNCATE: Res = ExpandIntOp_TRUNCATE(N); break; case ISD::UINT_TO_FP: Res = ExpandIntOp_UINT_TO_FP(N); break; + + case ISD::SHL: + case ISD::SRA: + case ISD::SRL: + case ISD::ROTL: + case ISD::ROTR: Res = ExpandIntOp_Shift(N); break; } // If the result is null, the sub-method took care of registering results etc. @@ -2108,6 +2125,15 @@ SDValue DAGTypeLegalizer::ExpandIntOp_SETCC(SDNode *N) { DAG.getCondCode(CCCode)); } +SDValue DAGTypeLegalizer::ExpandIntOp_Shift(SDNode *N) { + // The value being shifted is legal, but the shift amount is too big. + // It follows that either the result of the shift is undefined, or the + // upper half of the shift amount is zero. Just use the lower half. + SDValue Lo, Hi; + GetExpandedInteger(N->getOperand(1), Lo, Hi); + return DAG.UpdateNodeOperands(SDValue(N, 0), N->getOperand(0), Lo); +} + SDValue DAGTypeLegalizer::ExpandIntOp_SINT_TO_FP(SDNode *N) { SDValue Op = N->getOperand(0); MVT DstVT = N->getValueType(0); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h index 4fe5ae217b73..f2d7a71f742a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypes.h @@ -293,6 +293,7 @@ private: SDValue PromoteIntOp_SELECT(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SELECT_CC(SDNode *N, unsigned OpNo); SDValue PromoteIntOp_SETCC(SDNode *N, unsigned OpNo); + SDValue PromoteIntOp_Shift(SDNode *N); SDValue PromoteIntOp_SIGN_EXTEND(SDNode *N); SDValue PromoteIntOp_SINT_TO_FP(SDNode *N); SDValue PromoteIntOp_STORE(StoreSDNode *N, unsigned OpNo); @@ -356,6 +357,7 @@ private: SDValue ExpandIntOp_EXTRACT_ELEMENT(SDNode *N); SDValue ExpandIntOp_SELECT_CC(SDNode *N); SDValue ExpandIntOp_SETCC(SDNode *N); + SDValue ExpandIntOp_Shift(SDNode *N); SDValue ExpandIntOp_SINT_TO_FP(SDNode *N); SDValue ExpandIntOp_STORE(StoreSDNode *N, unsigned OpNo); SDValue ExpandIntOp_TRUNCATE(SDNode *N); -- GitLab From a5c9e1ae939aeae19acd075b18049bf2268e3e56 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 17:43:21 +0000 Subject: [PATCH 614/682] Check value-initializations that occur when an initializer list provides too few elements. llvm-svn: 63525 --- clang/include/clang/AST/Expr.h | 2 + clang/lib/Sema/Sema.h | 1 + clang/lib/Sema/SemaDeclCXX.cpp | 13 ++- clang/lib/Sema/SemaInit.cpp | 123 +++++++++++++++++++++++---- clang/test/SemaCXX/dcl_init_aggr.cpp | 15 ++++ 5 files changed, 134 insertions(+), 20 deletions(-) diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index 94beaf31e2c7..c933a0c94bb5 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -1725,6 +1725,8 @@ public: return LBraceLoc.isValid() && RBraceLoc.isValid(); } + void setRBraceLoc(SourceLocation Loc) { RBraceLoc = Loc; } + /// @brief Retrieve the initializer list that describes the /// syntactic form of the initializer. /// diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 6108f9447fdb..60362054889d 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -1715,6 +1715,7 @@ public: StringLiteral *IsStringLiteralInit(Expr *Init, QualType DeclType); bool CheckStringLiteralInit(StringLiteral *strLiteral, QualType &DeclT); + bool CheckValueInitialization(QualType Type, SourceLocation Loc); // type checking C++ declaration initializers (C++ [dcl.init]). diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index f3bb9a5dfbc8..296adc1a9419 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -1592,13 +1592,20 @@ Sema::PerformInitializationByConstructor(QualType ClassType, return cast(Best->Function); case OR_No_Viable_Function: - Diag(Loc, diag::err_ovl_no_viable_function_in_init) - << InitEntity << (unsigned)CandidateSet.size() << Range; + if (InitEntity) + Diag(Loc, diag::err_ovl_no_viable_function_in_init) + << InitEntity << (unsigned)CandidateSet.size() << Range; + else + Diag(Loc, diag::err_ovl_no_viable_function_in_init) + << ClassType << (unsigned)CandidateSet.size() << Range; PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/false); return 0; case OR_Ambiguous: - Diag(Loc, diag::err_ovl_ambiguous_init) << InitEntity << Range; + if (InitEntity) + Diag(Loc, diag::err_ovl_ambiguous_init) << InitEntity << Range; + else + Diag(Loc, diag::err_ovl_ambiguous_init) << ClassType << Range; PrintOverloadCandidates(CandidateSet, /*OnlyViable=*/true); return 0; } diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 3440d04f07bc..8bc3496a19fb 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -127,6 +127,10 @@ public: void InitListChecker::FillInValueInitializations(InitListExpr *ILE) { assert((ILE->getType() != SemaRef->Context.VoidTy) && "Should not have void type"); + SourceLocation Loc = ILE->getSourceRange().getBegin(); + if (ILE->getSyntacticForm()) + Loc = ILE->getSyntacticForm()->getSourceRange().getBegin(); + if (const RecordType *RType = ILE->getType()->getAsRecordType()) { unsigned Init = 0, NumInits = ILE->getNumInits(); for (RecordDecl::field_iterator Field = RType->getDecl()->field_begin(), @@ -135,24 +139,32 @@ void InitListChecker::FillInValueInitializations(InitListExpr *ILE) { if (Field->isUnnamedBitfield()) continue; - if (Init >= NumInits) { + if (Init >= NumInits || !ILE->getInit(Init)) { if (Field->getType()->isReferenceType()) { // C++ [dcl.init.aggr]p9: // If an incomplete or empty initializer-list leaves a // member of reference type uninitialized, the program is // ill-formed. - SemaRef->Diag(ILE->getSyntacticForm()->getLocStart(), - diag::err_init_reference_member_uninitialized) + SemaRef->Diag(Loc, diag::err_init_reference_member_uninitialized) << Field->getType() << ILE->getSyntacticForm()->getSourceRange(); SemaRef->Diag(Field->getLocation(), diag::note_uninit_reference_member); hadError = true; + return; + } else if (SemaRef->CheckValueInitialization(Field->getType(), Loc)) { + hadError = true; + return; } - } else if (!ILE->getInit(Init)) - ILE->setInit(Init, - new (SemaRef->Context) ImplicitValueInitExpr(Field->getType())); - else if (InitListExpr *InnerILE + + // FIXME: If value-initialization involves calling a + // constructor, should we make that call explicit in the + // representation (even when it means extending the + // initializer list)? + if (Init < NumInits && !hadError) + ILE->setInit(Init, + new (SemaRef->Context) ImplicitValueInitExpr(Field->getType())); + } else if (InitListExpr *InnerILE = dyn_cast(ILE->getInit(Init))) FillInValueInitializations(InnerILE); ++Init; @@ -167,18 +179,33 @@ void InitListChecker::FillInValueInitializations(InitListExpr *ILE) { QualType ElementType; - if (const ArrayType *AType = SemaRef->Context.getAsArrayType(ILE->getType())) + unsigned NumInits = ILE->getNumInits(); + unsigned NumElements = NumInits; + if (const ArrayType *AType = SemaRef->Context.getAsArrayType(ILE->getType())) { ElementType = AType->getElementType(); - else if (const VectorType *VType = ILE->getType()->getAsVectorType()) + if (const ConstantArrayType *CAType = dyn_cast(AType)) + NumElements = CAType->getSize().getZExtValue(); + } else if (const VectorType *VType = ILE->getType()->getAsVectorType()) { ElementType = VType->getElementType(); - else + NumElements = VType->getNumElements(); + } else ElementType = ILE->getType(); - for (unsigned Init = 0, NumInits = ILE->getNumInits(); Init != NumInits; - ++Init) { - if (!ILE->getInit(Init)) - ILE->setInit(Init, - new (SemaRef->Context) ImplicitValueInitExpr(ElementType)); + for (unsigned Init = 0; Init != NumElements; ++Init) { + if (Init >= NumInits || !ILE->getInit(Init)) { + if (SemaRef->CheckValueInitialization(ElementType, Loc)) { + hadError = true; + return; + } + + // FIXME: If value-initialization involves calling a + // constructor, should we make that call explicit in the + // representation (even when it means extending the + // initializer list)? + if (Init < NumInits && !hadError) + ILE->setInit(Init, + new (SemaRef->Context) ImplicitValueInitExpr(ElementType)); + } else if (InitListExpr *InnerILE =dyn_cast(ILE->getInit(Init))) FillInValueInitializations(InnerILE); } @@ -254,9 +281,19 @@ void InitListChecker::CheckImplicitInitList(InitListExpr *ParentIList, unsigned StructuredSubobjectInitIndex = 0; // Check the element types and build the structural subobject. + unsigned StartIndex = Index; CheckListElementTypes(ParentIList, T, false, Index, StructuredSubobjectInitList, StructuredSubobjectInitIndex); + unsigned EndIndex = (Index == StartIndex? StartIndex : Index - 1); + + // Update the structured sub-object initialize so that it's ending + // range corresponds with the end of the last initializer it used. + if (EndIndex < ParentIList->getNumInits()) { + SourceLocation EndLoc + = ParentIList->getInit(EndIndex)->getSourceRange().getEnd(); + StructuredSubobjectInitList->setRBraceLoc(EndLoc); + } } void InitListChecker::CheckExplicitInitList(InitListExpr *IList, QualType &T, @@ -1102,9 +1139,12 @@ InitListChecker::getStructuredSubobjectInit(InitListExpr *IList, unsigned Index, << ExistingInit->getSourceRange(); } + SourceLocation StartLoc; + if (Index < IList->getNumInits()) + StartLoc = IList->getInit(Index)->getSourceRange().getBegin(); InitListExpr *Result - = new (SemaRef->Context) InitListExpr(SourceLocation(), 0, 0, - SourceLocation()); + = new (SemaRef->Context) InitListExpr(StartLoc, 0, 0, + IList->getSourceRange().getEnd()); Result->setType(CurrentObjectType); // Link this new initializer list into the structured initializer @@ -1257,3 +1297,52 @@ bool Sema::CheckInitList(InitListExpr *&InitList, QualType &DeclType) { return CheckInitList.HadError(); } + +/// \brief Diagnose any semantic errors with value-initialization of +/// the given type. +/// +/// Value-initialization effectively zero-initializes any types +/// without user-declared constructors, and calls the default +/// constructor for a for any type that has a user-declared +/// constructor (C++ [dcl.init]p5). Value-initialization can fail when +/// a type with a user-declared constructor does not have an +/// accessible, non-deleted default constructor. In C, everything can +/// be value-initialized, which corresponds to C's notion of +/// initializing objects with static storage duration when no +/// initializer is provided for that object. +/// +/// \returns true if there was an error, false otherwise. +bool Sema::CheckValueInitialization(QualType Type, SourceLocation Loc) { + // C++ [dcl.init]p5: + // + // To value-initialize an object of type T means: + + // -- if T is an array type, then each element is value-initialized; + if (const ArrayType *AT = Context.getAsArrayType(Type)) + return CheckValueInitialization(AT->getElementType(), Loc); + + if (const RecordType *RT = Type->getAsRecordType()) { + if (const CXXRecordType *CXXRec = dyn_cast(RT)) { + // -- if T is a class type (clause 9) with a user-declared + // constructor (12.1), then the default constructor for T is + // called (and the initialization is ill-formed if T has no + // accessible default constructor); + if (CXXRec->getDecl()->hasUserDeclaredConstructor()) + // FIXME: Eventually, we'll need to put the constructor decl + // into the AST. + return PerformInitializationByConstructor(Type, 0, 0, Loc, + SourceRange(Loc), + DeclarationName(), + IK_Direct); + } + } + + if (Type->isReferenceType()) { + // C++ [dcl.init]p5: + // [...] A program that calls for default-initialization or + // value-initialization of an entity of reference type is + // ill-formed. [...] + } + + return false; +} diff --git a/clang/test/SemaCXX/dcl_init_aggr.cpp b/clang/test/SemaCXX/dcl_init_aggr.cpp index c2c9d67a4d52..e5015fab030d 100644 --- a/clang/test/SemaCXX/dcl_init_aggr.cpp +++ b/clang/test/SemaCXX/dcl_init_aggr.cpp @@ -40,6 +40,21 @@ char cv[4] = { 'a', 's', 'd', 'f', 0 }; // expected-error{{excess elements in ar struct TooFew { int a; char* b; int c; }; TooFew too_few = { 1, "asdf" }; // okay +struct NoDefaultConstructor { // expected-note{{candidate function}} + NoDefaultConstructor(int); // expected-note{{candidate function}} +}; +struct TooFewError { + int a; + NoDefaultConstructor nodef; +}; +TooFewError too_few_okay = { 1, 1 }; +TooFewError too_few_error = { 1 }; // expected-error{{no matching constructor}} + +TooFewError too_few_okay2[2] = { 1, 1 }; +TooFewError too_few_error2[2] = { 1 }; // expected-error{{no matching constructor}} + +NoDefaultConstructor too_few_error3[3] = { }; // expected-error{{no matching constructor}} + // C++ [dcl.init.aggr]p8 struct Empty { }; struct EmptyTest { -- GitLab From e7a112111a80ee8499b5212da148dc7c340e442f Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 2 Feb 2009 17:50:43 +0000 Subject: [PATCH 615/682] Make this test case smaller. llvm-svn: 63526 --- llvm/test/DebugInfo/2009-01-28-ArrayType.ll | 102 +++----------------- 1 file changed, 16 insertions(+), 86 deletions(-) diff --git a/llvm/test/DebugInfo/2009-01-28-ArrayType.ll b/llvm/test/DebugInfo/2009-01-28-ArrayType.ll index cff4fd8a4732..81905953b717 100644 --- a/llvm/test/DebugInfo/2009-01-28-ArrayType.ll +++ b/llvm/test/DebugInfo/2009-01-28-ArrayType.ll @@ -1,93 +1,23 @@ -; RUN: llvm-as < %s | llc -mtriple=i686-apple-darwin | grep 0x49 | count 7 +; RUN: llvm-as < %s | llc | grep 0x49 | count 3 ; Count number of DW_AT_Type attributes. +target triple = "i386-apple-darwin*" %llvm.dbg.anchor.type = type { i32, i32 } - %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32, i8*, i8* } - %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i8* } - %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }*, i8*, i8* } - %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, i8*, i8* } - %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, i8*, i8* } + %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } + %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* } + %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* } + %llvm.dbg.global_variable.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1, { }* } %llvm.dbg.subrange.type = type { i32, i64, i64 } - %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }*, i8*, i8* } @llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] -@.str = internal constant [4 x i8] c"a.c\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@.str = internal constant [8 x i8] c"array.c\00", section "llvm.metadata" ; <[8 x i8]*> [#uses=1] @.str1 = internal constant [26 x i8] c"/Volumes/Nanpura/dbg.test\00", section "llvm.metadata" ; <[26 x i8]*> [#uses=1] @.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] -@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] +@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 1, i8* getelementptr ([8 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] +@c = common global [3 x i32] zeroinitializer ; <[3 x i32]*> [#uses=1] +@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 2 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1] +@llvm.dbg.array = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] @.str3 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] -@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] -@.str4 = internal constant [5 x i8] c"char\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] -@llvm.dbg.basictype5 = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 8, i64 8, i64 0, i32 0, i32 6, i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] -@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] -@llvm.dbg.derivedtype6 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] -@llvm.dbg.array = internal constant [3 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] -@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] -@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] -@.str7 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] -@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str7, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str7, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true, i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] -@.str8 = internal constant [5 x i8] c"argc\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] -@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([5 x i8]* @.str8, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] -@.str9 = internal constant [5 x i8] c"argv\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] -@llvm.dbg.variable10 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([5 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] -@llvm.dbg.subrange = internal constant %llvm.dbg.subrange.type { i32 458785, i64 0, i64 5 }, section "llvm.metadata" ; <%llvm.dbg.subrange.type*> [#uses=1] -@llvm.dbg.array11 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.subrange.type* @llvm.dbg.subrange to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] -@llvm.dbg.composite12 = internal constant %llvm.dbg.composite.type { i32 458753, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 48, i64 8, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype5 to { }*), { }* bitcast ([1 x { }*]* @llvm.dbg.array11 to { }*), i8* null, i8* null }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] -@.str13 = internal constant [5 x i8] c"str1\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] -@llvm.dbg.variable14 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*), i8* getelementptr ([5 x i8]* @.str13, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 4, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite12 to { }*), i8* getelementptr ([4 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([26 x i8]* @.str1, i32 0, i32 0) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] -@"\01LC" = internal constant [6 x i8] c"a.out\00" ; <[6 x i8]*> [#uses=6] - -define i32 @main(i32 %argc, i8** %argv) nounwind { -entry: - %argc_addr = alloca i32 ; [#uses=2] - %argv_addr = alloca i8** ; [#uses=2] - %retval = alloca i32 ; [#uses=2] - %str1 = alloca [6 x i8] ; <[6 x i8]*> [#uses=7] - %0 = alloca i32 ; [#uses=2] - %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] - call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - %1 = bitcast i32* %argc_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) - store i32 %argc, i32* %argc_addr - %2 = bitcast i8*** %argv_addr to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %2, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable10 to { }*)) - store i8** %argv, i8*** %argv_addr - %3 = bitcast [6 x i8]* %str1 to { }* ; <{ }*> [#uses=1] - call void @llvm.dbg.declare({ }* %3, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable14 to { }*)) - call void @llvm.dbg.stoppoint(i32 4, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - %4 = getelementptr [6 x i8]* %str1, i32 0, i32 0 ; [#uses=1] - %5 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 0), align 1 ; [#uses=1] - store i8 %5, i8* %4, align 1 - %6 = getelementptr [6 x i8]* %str1, i32 0, i32 1 ; [#uses=1] - %7 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 1), align 1 ; [#uses=1] - store i8 %7, i8* %6, align 1 - %8 = getelementptr [6 x i8]* %str1, i32 0, i32 2 ; [#uses=1] - %9 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 2), align 1 ; [#uses=1] - store i8 %9, i8* %8, align 1 - %10 = getelementptr [6 x i8]* %str1, i32 0, i32 3 ; [#uses=1] - %11 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 3), align 1 ; [#uses=1] - store i8 %11, i8* %10, align 1 - %12 = getelementptr [6 x i8]* %str1, i32 0, i32 4 ; [#uses=1] - %13 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 4), align 1 ; [#uses=1] - store i8 %13, i8* %12, align 1 - %14 = getelementptr [6 x i8]* %str1, i32 0, i32 5 ; [#uses=1] - %15 = load i8* getelementptr ([6 x i8]* @"\01LC", i32 0, i32 5), align 1 ; [#uses=1] - store i8 %15, i8* %14, align 1 - call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - store i32 0, i32* %0, align 4 - %16 = load i32* %0, align 4 ; [#uses=1] - store i32 %16, i32* %retval, align 4 - br label %return - -return: ; preds = %entry - %retval1 = load i32* %retval ; [#uses=1] - call void @llvm.dbg.stoppoint(i32 5, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) - call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*)) - ret i32 %retval1 -} - -declare void @llvm.dbg.func.start({ }*) nounwind - -declare void @llvm.dbg.declare({ }*, { }*) nounwind - -declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind - -declare void @llvm.dbg.region.end({ }*) nounwind +@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] +@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458753, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 96, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*), { }* bitcast ([1 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 52 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str4 = internal constant [2 x i8] c"c\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] +@llvm.dbg.global_variable = internal constant %llvm.dbg.global_variable.type { i32 458804, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.global_variables to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str4, i32 0, i32 0), i8* getelementptr ([2 x i8]* @.str4, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 2, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true, { }* bitcast ([3 x i32]* @c to { }*) }, section "llvm.metadata" ; <%llvm.dbg.global_variable.type*> [#uses=0] -- GitLab From 97ba824ad9b68515df631e3c5a565c87ef1c3671 Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 2 Feb 2009 17:51:41 +0000 Subject: [PATCH 616/682] Do not add redundant arguments in a method definition DIE. llvm-svn: 63527 --- llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp | 29 +++--- llvm/test/DebugInfo/2009-01-30-Method.ll | 103 ++++++++++++++++++++ 2 files changed, 121 insertions(+), 11 deletions(-) create mode 100644 llvm/test/DebugInfo/2009-01-30-Method.ll diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp index 95990cfe6718..638def2b0620 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfWriter.cpp @@ -1914,18 +1914,20 @@ private: // Add Return Type. if (!IsConstructor) AddType(DW_Unit, SPDie, DIType(Args.getElement(0).getGV())); - - // Add arguments. - if (!Args.isNull()) - for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { - DIE *Arg = new DIE(DW_TAG_formal_parameter); - AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV())); - AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ??? - SPDie->AddChild(Arg); - } - if (!SP.isDefinition()) - AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1); + if (!SP.isDefinition()) { + AddUInt(SPDie, DW_AT_declaration, DW_FORM_flag, 1); + // Add arguments. + // Do not add arguments for subprogram definition. They will be + // handled through RecordVariable. + if (!Args.isNull()) + for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) { + DIE *Arg = new DIE(DW_TAG_formal_parameter); + AddType(DW_Unit, Arg, DIType(Args.getElement(i).getGV())); + AddUInt(Arg, DW_AT_artificial, DW_FORM_flag, 1); // ??? + SPDie->AddChild(Arg); + } + } if (!SP.isLocalToUnit()) AddUInt(SPDie, DW_AT_external, DW_FORM_flag, 1); @@ -2856,6 +2858,11 @@ private: DIE *&Slot = Unit->getDieMapSlotFor(SP.getGV()); if (Slot) continue; + if (!SP.isDefinition()) + // This is a method declaration which will be handled while + // constructing class type. + continue; + DIE *SubprogramDie = CreateSubprogramDIE(Unit, SP); //Add to map. diff --git a/llvm/test/DebugInfo/2009-01-30-Method.ll b/llvm/test/DebugInfo/2009-01-30-Method.ll new file mode 100644 index 000000000000..6b2a8b98ce68 --- /dev/null +++ b/llvm/test/DebugInfo/2009-01-30-Method.ll @@ -0,0 +1,103 @@ +; RUN: llvm-as < %s | llc | grep "\\"foo" | count 3 +; 1 declaration, 1 definition and 1 pubnames entry. +target triple = "i386-apple-darwin*" + %llvm.dbg.anchor.type = type { i32, i32 } + %llvm.dbg.basictype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, i32 } + %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8* } + %llvm.dbg.composite.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }*, { }* } + %llvm.dbg.derivedtype.type = type { i32, { }*, i8*, { }*, i32, i64, i64, i64, i32, { }* } + %llvm.dbg.subprogram.type = type { i32, { }*, { }*, i8*, i8*, i8*, { }*, i32, { }*, i1, i1 } + %llvm.dbg.variable.type = type { i32, { }*, i8*, { }*, i32, { }* } + %struct.Fibonancci = type { i32 } +@llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 17 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str = internal constant [10 x i8] c"method.cc\00", section "llvm.metadata" ; <[10 x i8]*> [#uses=1] +@.str1 = internal constant [64 x i8] c"/Volumes/Nanpura/mainline/llvmgcc42.build/gcc/../../../dbg.test\00", section "llvm.metadata" ; <[64 x i8]*> [#uses=1] +@.str2 = internal constant [52 x i8] c"4.2.1 (Based on Apple Inc. build 5636) (LLVM build)\00", section "llvm.metadata" ; <[52 x i8]*> [#uses=1] +@llvm.dbg.compile_unit = internal constant %llvm.dbg.compile_unit.type { i32 458769, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.compile_units to { }*), i32 4, i8* getelementptr ([10 x i8]* @.str, i32 0, i32 0), i8* getelementptr ([64 x i8]* @.str1, i32 0, i32 0), i8* getelementptr ([52 x i8]* @.str2, i32 0, i32 0), i1 true, i1 false, i8* null }, section "llvm.metadata" ; <%llvm.dbg.compile_unit.type*> [#uses=1] +@.str3 = internal constant [11 x i8] c"Fibonancci\00", section "llvm.metadata" ; <[11 x i8]*> [#uses=1] +@.str4 = internal constant [4 x i8] c"int\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@llvm.dbg.basictype = internal constant %llvm.dbg.basictype.type { i32 458788, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str4, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, i32 5 }, section "llvm.metadata" ; <%llvm.dbg.basictype.type*> [#uses=1] +@.str5 = internal constant [2 x i8] c"N\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] +@llvm.dbg.derivedtype = internal constant %llvm.dbg.derivedtype.type { i32 458765, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([2 x i8]* @.str5, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 5, i64 32, i64 32, i64 0, i32 1, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@llvm.dbg.derivedtype6 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@llvm.dbg.array = internal constant [3 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype6 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] +@llvm.dbg.composite7 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { i32 458752, i32 46 }, section "llvm.metadata" ; <%llvm.dbg.anchor.type*> [#uses=1] +@.str8 = internal constant [4 x i8] c"foo\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@.str9 = internal constant [22 x i8] c"_ZN10Fibonancci3fooEi\00", section "llvm.metadata" ; <[22 x i8]*> [#uses=1] +@llvm.dbg.subprogram = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite7 to { }*), i1 false, i1 false }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@llvm.dbg.array10 = internal constant [2 x { }*] [ { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype to { }*), { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram to { }*) ], section "llvm.metadata" ; <[2 x { }*]*> [#uses=1] +@llvm.dbg.composite11 = internal constant %llvm.dbg.composite.type { i32 458771, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([11 x i8]* @.str3, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 3, i64 32, i64 32, i64 0, i32 0, { }* null, { }* bitcast ([2 x { }*]* @llvm.dbg.array10 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@llvm.dbg.derivedtype12 = internal constant %llvm.dbg.derivedtype.type { i32 458767, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@llvm.dbg.array13 = internal constant [3 x { }*] [ { }* null, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*), { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[3 x { }*]*> [#uses=1] +@llvm.dbg.composite = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([3 x { }*]* @llvm.dbg.array13 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@llvm.dbg.subprogram14 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([4 x i8]* @.str8, i32 0, i32 0), i8* getelementptr ([22 x i8]* @.str9, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@llvm.dbg.derivedtype15 = internal constant %llvm.dbg.derivedtype.type { i32 458790, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 32, i64 32, i64 0, i32 0, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype12 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.derivedtype.type*> [#uses=1] +@.str16 = internal constant [5 x i8] c"this\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.variable = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram14 to { }*), i8* getelementptr ([5 x i8]* @.str16, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.derivedtype.type* @llvm.dbg.derivedtype15 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@.str17 = internal constant [2 x i8] c"i\00", section "llvm.metadata" ; <[2 x i8]*> [#uses=1] +@llvm.dbg.variable18 = internal constant %llvm.dbg.variable.type { i32 459009, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram14 to { }*), i8* getelementptr ([2 x i8]* @.str17, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 10, { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] +@llvm.dbg.array19 = internal constant [1 x { }*] [ { }* bitcast (%llvm.dbg.basictype.type* @llvm.dbg.basictype to { }*) ], section "llvm.metadata" ; <[1 x { }*]*> [#uses=1] +@llvm.dbg.composite20 = internal constant %llvm.dbg.composite.type { i32 458773, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 0, i64 0, i64 0, i64 0, i32 0, { }* null, { }* bitcast ([1 x { }*]* @llvm.dbg.array19 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.composite.type*> [#uses=1] +@.str21 = internal constant [5 x i8] c"main\00", section "llvm.metadata" ; <[5 x i8]*> [#uses=1] +@llvm.dbg.subprogram22 = internal constant %llvm.dbg.subprogram.type { i32 458798, { }* bitcast (%llvm.dbg.anchor.type* @llvm.dbg.subprograms to { }*), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i8* getelementptr ([5 x i8]* @.str21, i32 0, i32 0), i8* getelementptr ([5 x i8]* @.str21, i32 0, i32 0), i8* null, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 14, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite20 to { }*), i1 false, i1 true }, section "llvm.metadata" ; <%llvm.dbg.subprogram.type*> [#uses=1] +@.str23 = internal constant [4 x i8] c"fib\00", section "llvm.metadata" ; <[4 x i8]*> [#uses=1] +@llvm.dbg.variable24 = internal constant %llvm.dbg.variable.type { i32 459008, { }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram22 to { }*), i8* getelementptr ([4 x i8]* @.str23, i32 0, i32 0), { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*), i32 15, { }* bitcast (%llvm.dbg.composite.type* @llvm.dbg.composite11 to { }*) }, section "llvm.metadata" ; <%llvm.dbg.variable.type*> [#uses=1] + +define void @_ZN10Fibonancci3fooEi(%struct.Fibonancci* %this, i32 %i) nounwind { +entry: + %this_addr = alloca %struct.Fibonancci* ; <%struct.Fibonancci**> [#uses=3] + %i_addr = alloca i32 ; [#uses=3] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram14 to { }*)) + %0 = bitcast %struct.Fibonancci** %this_addr to { }* ; <{ }*> [#uses=1] + call void @llvm.dbg.declare({ }* %0, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable to { }*)) + store %struct.Fibonancci* %this, %struct.Fibonancci** %this_addr + %1 = bitcast i32* %i_addr to { }* ; <{ }*> [#uses=1] + call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable18 to { }*)) + store i32 %i, i32* %i_addr + call void @llvm.dbg.stoppoint(i32 11, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + %2 = load %struct.Fibonancci** %this_addr, align 4 ; <%struct.Fibonancci*> [#uses=1] + %3 = getelementptr %struct.Fibonancci* %2, i32 0, i32 0 ; [#uses=1] + %4 = load i32* %i_addr, align 4 ; [#uses=1] + store i32 %4, i32* %3, align 4 + call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + br label %return + +return: ; preds = %entry + call void @llvm.dbg.stoppoint(i32 12, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram14 to { }*)) + ret void +} + +declare void @llvm.dbg.func.start({ }*) nounwind + +declare void @llvm.dbg.declare({ }*, { }*) nounwind + +declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind + +declare void @llvm.dbg.region.end({ }*) nounwind + +define i32 @main() nounwind { +entry: + %retval = alloca i32 ; [#uses=2] + %fib = alloca %struct.Fibonancci ; <%struct.Fibonancci*> [#uses=2] + %0 = alloca i32 ; [#uses=2] + %"alloca point" = bitcast i32 0 to i32 ; [#uses=0] + call void @llvm.dbg.func.start({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram22 to { }*)) + %1 = bitcast %struct.Fibonancci* %fib to { }* ; <{ }*> [#uses=1] + call void @llvm.dbg.declare({ }* %1, { }* bitcast (%llvm.dbg.variable.type* @llvm.dbg.variable24 to { }*)) + call void @llvm.dbg.stoppoint(i32 16, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + call void @_ZN10Fibonancci3fooEi(%struct.Fibonancci* %fib, i32 42) nounwind + call void @llvm.dbg.stoppoint(i32 17, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + store i32 0, i32* %0, align 4 + %2 = load i32* %0, align 4 ; [#uses=1] + store i32 %2, i32* %retval, align 4 + br label %return + +return: ; preds = %entry + %retval1 = load i32* %retval ; [#uses=1] + call void @llvm.dbg.stoppoint(i32 17, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit to { }*)) + call void @llvm.dbg.region.end({ }* bitcast (%llvm.dbg.subprogram.type* @llvm.dbg.subprogram22 to { }*)) + ret i32 %retval1 +} -- GitLab From 7946ef9fe0a2a612b39dc1bf0eb914ae691f9bc8 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 17:56:05 +0000 Subject: [PATCH 617/682] Slim down the specific_decl_iterator, since NULL denotes the end of the range. Good eyes, Chris llvm-svn: 63528 --- clang/include/clang/AST/Decl.h | 8 ++++---- clang/include/clang/AST/DeclBase.h | 25 +++++++++++-------------- clang/include/clang/AST/DeclObjC.h | 20 ++++++++------------ 3 files changed, 23 insertions(+), 30 deletions(-) diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 18d1c0546791..23f06f14f569 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -927,11 +927,11 @@ public: typedef specific_decl_iterator enumerator_iterator; enumerator_iterator enumerator_begin() const { - return enumerator_iterator(this->decls_begin(), this->decls_end()); + return enumerator_iterator(this->decls_begin()); } enumerator_iterator enumerator_end() const { - return enumerator_iterator(this->decls_end(), this->decls_end()); + return enumerator_iterator(this->decls_end()); } /// getIntegerType - Return the integer type this enum decl corresponds to. @@ -1022,10 +1022,10 @@ public: typedef specific_decl_iterator field_iterator; field_iterator field_begin() const { - return field_iterator(decls_begin(), decls_end()); + return field_iterator(decls_begin()); } field_iterator field_end() const { - return field_iterator(decls_end(), decls_end()); + return field_iterator(decls_end()); } // field_empty - Whether there are any fields (non-static data diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 8d203cc2c2c6..2c15c870c3b1 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -640,13 +640,10 @@ public: template class specific_decl_iterator { /// Current - The current, underlying declaration iterator, which - /// will either be the same as End or will point to a declaration of + /// will either be NULL or will point to a declaration of /// type SpecificDecl. DeclContext::decl_iterator Current; - /// End - One past the last declaration within the DeclContext. - DeclContext::decl_iterator End; - /// Acceptable - If non-NULL, points to a member function that /// will determine if a particular declaration of type /// SpecificDecl should be visited by the iteration. @@ -656,7 +653,7 @@ public: /// declaration of type SpecificDecl that also meets the criteria /// required by Acceptable. void SkipToNextDecl() { - while (Current != End && + while (*Current && (!isa(*Current) || (Acceptable && !(cast(*Current)->*Acceptable)()))) ++Current; @@ -670,19 +667,19 @@ public: difference_type; typedef std::forward_iterator_tag iterator_category; - specific_decl_iterator() : Current(), End(), Acceptable(0) { } + specific_decl_iterator() : Current(), Acceptable(0) { } /// specific_decl_iterator - Construct a new iterator over a - /// subset of the declarations in [C, E). If A is non-NULL, it is - /// a pointer to a member function of SpecificDecl that should - /// return true for all of the SpecificDecl instances that will be - /// in the subset of iterators. For example, if you want - /// Objective-C instance methods, SpecificDecl will be - /// ObjCMethodDecl and A will be &ObjCMethodDecl::isInstanceMethod. + /// subset of the declarations the range [C, + /// end-of-declarations). If A is non-NULL, it is a pointer to a + /// member function of SpecificDecl that should return true for + /// all of the SpecificDecl instances that will be in the subset + /// of iterators. For example, if you want Objective-C instance + /// methods, SpecificDecl will be ObjCMethodDecl and A will be + /// &ObjCMethodDecl::isInstanceMethod. specific_decl_iterator(DeclContext::decl_iterator C, - DeclContext::decl_iterator E, bool (SpecificDecl::*A)() const = 0) - : Current(C), End(E), Acceptable(A) { + : Current(C), Acceptable(A) { SkipToNextDecl(); } diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index fcf6e5864e51..cda9bddbcc34 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -264,39 +264,35 @@ public: // Iterator access to properties. typedef specific_decl_iterator prop_iterator; prop_iterator prop_begin() const { - return prop_iterator(decls_begin(), decls_end()); + return prop_iterator(decls_begin()); } prop_iterator prop_end() const { - return prop_iterator(decls_end(), decls_end()); + return prop_iterator(decls_end()); } // Iterator access to instance/class methods. typedef specific_decl_iterator method_iterator; method_iterator meth_begin() const { - return method_iterator(decls_begin(), decls_end()); + return method_iterator(decls_begin()); } method_iterator meth_end() const { - return method_iterator(decls_end(), decls_end()); + return method_iterator(decls_end()); } typedef method_iterator instmeth_iterator; instmeth_iterator instmeth_begin() const { - return instmeth_iterator(decls_begin(), decls_end(), - &ObjCMethodDecl::isInstanceMethod); + return instmeth_iterator(decls_begin(), &ObjCMethodDecl::isInstanceMethod); } instmeth_iterator instmeth_end() const { - return instmeth_iterator(decls_end(), decls_end(), - &ObjCMethodDecl::isInstanceMethod); + return instmeth_iterator(decls_end(), &ObjCMethodDecl::isInstanceMethod); } typedef method_iterator classmeth_iterator; classmeth_iterator classmeth_begin() const { - return classmeth_iterator(decls_begin(), decls_end(), - &ObjCMethodDecl::isClassMethod); + return classmeth_iterator(decls_begin(), &ObjCMethodDecl::isClassMethod); } classmeth_iterator classmeth_end() const { - return classmeth_iterator(decls_end(), decls_end(), - &ObjCMethodDecl::isClassMethod); + return classmeth_iterator(decls_end(), &ObjCMethodDecl::isClassMethod); } // Get the local instance/class method declared in this interface. -- GitLab From 18eba4f2119b5c0e2d13824a76d641b104617515 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 18:02:59 +0000 Subject: [PATCH 618/682] Fix a bug which caused us to miscompile a couple of Ada tests. Thanks for the beautiful reduced testcase Duncan! llvm-svn: 63529 --- .../Transforms/Scalar/ScalarReplAggregates.cpp | 7 ++++++- .../2009-02-02-ScalarPromoteOutOfRange.ll | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 llvm/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 29970ecb444f..0765e12876b8 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -1166,12 +1166,17 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) { static void MergeInType(const Type *In, uint64_t Offset, const Type *&Accum, const TargetData &TD) { // If this is our first type, just use it. - if (Accum == 0 || In == Type::VoidTy || + if ((Accum == 0 && Offset == 0) || In == Type::VoidTy || // Or if this is a same type, keep it. (In == Accum && Offset == 0)) { Accum = In; return; } + + // Merging something like i32 into offset 8 means that a "field" is merged in + // before the basic type is. Make sure to consider the offset below. + if (Accum == 0) + Accum = Type::Int8Ty; if (const VectorType *VATy = dyn_cast(Accum)) { if (VATy->getElementType() == In && diff --git a/llvm/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll b/llvm/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll new file mode 100644 index 000000000000..af34baa0c5cf --- /dev/null +++ b/llvm/test/Transforms/ScalarRepl/2009-02-02-ScalarPromoteOutOfRange.ll @@ -0,0 +1,16 @@ +; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 %x} +target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32" +target triple = "i386-pc-linux-gnu" + +%pair = type { [1 x i32], i32 } + +define i32 @f(i32 %x, i32 %y) { + %instance = alloca %pair + %first = getelementptr %pair* %instance, i32 0, i32 0 + %cast = bitcast [1 x i32]* %first to i32* + store i32 %x, i32* %cast + %second = getelementptr %pair* %instance, i32 0, i32 1 + store i32 %y, i32* %second + %v = load i32* %cast + ret i32 %v +} -- GitLab From 2171f5aeec1ac43492c817502a49ea5882d4a5fd Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 2 Feb 2009 18:04:24 +0000 Subject: [PATCH 619/682] Reposition the DebugLoc field to reduce padding space on LP64 hosts. llvm-svn: 63530 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index aec6b62650e3..06e507ba653f 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1090,9 +1090,6 @@ private: /// NodeId - Unique id per SDNode in the DAG. int NodeId; - /// debugLoc - source line information. - DebugLoc debugLoc; - /// OperandList - The values that are used by this operation. /// SDUse *OperandList; @@ -1101,12 +1098,15 @@ private: /// define multiple values simultaneously. const MVT *ValueList; - /// NumOperands/NumValues - The number of entries in the Operand/Value list. - unsigned short NumOperands, NumValues; - /// UseList - List of uses for this SDNode. SDUse *UseList; + /// NumOperands/NumValues - The number of entries in the Operand/Value list. + unsigned short NumOperands, NumValues; + + /// debugLoc - source line information. + DebugLoc debugLoc; + /// getValueTypeList - Return a pointer to the specified value type. static const MVT *getValueTypeList(MVT VT); @@ -1353,11 +1353,12 @@ protected: /// for new code. SDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()), + NodeId(-1), OperandList(NumOps ? new SDUse[NumOps] : 0), ValueList(VTs.VTs), + UseList(NULL), NumOperands(NumOps), NumValues(VTs.NumVTs), - UseList(NULL) { + debugLoc(DebugLoc::getUnknownLoc()) { for (unsigned i = 0; i != NumOps; ++i) { OperandList[i].setUser(this); OperandList[i].setInitial(Ops[i]); @@ -1368,9 +1369,9 @@ protected: /// set later with InitOperands. SDNode(unsigned Opc, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), - NodeId(-1), debugLoc(DebugLoc::getUnknownLoc()), OperandList(0), - ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs), - UseList(NULL) {} + NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL), + NumOperands(0), NumValues(VTs.NumVTs), + debugLoc(DebugLoc::getUnknownLoc()) {} /// The next two constructors specify DebugLoc explicitly; the intent /// is that they will replace the above two over time, and eventually @@ -1378,11 +1379,11 @@ protected: SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs, const SDValue *Ops, unsigned NumOps) : NodeType(Opc), OperandsNeedDelete(true), SubclassData(0), - NodeId(-1), debugLoc(dl), + NodeId(-1), OperandList(NumOps ? new SDUse[NumOps] : 0), - ValueList(VTs.VTs), + ValueList(VTs.VTs), UseList(NULL), NumOperands(NumOps), NumValues(VTs.NumVTs), - UseList(NULL) { + debugLoc(dl) { for (unsigned i = 0; i != NumOps; ++i) { OperandList[i].setUser(this); OperandList[i].setInitial(Ops[i]); @@ -1393,9 +1394,9 @@ protected: /// set later with InitOperands. SDNode(unsigned Opc, const DebugLoc dl, SDVTList VTs) : NodeType(Opc), OperandsNeedDelete(false), SubclassData(0), - NodeId(-1), debugLoc(dl), OperandList(0), - ValueList(VTs.VTs), NumOperands(0), NumValues(VTs.NumVTs), - UseList(NULL) {} + NodeId(-1), OperandList(0), ValueList(VTs.VTs), UseList(NULL), + NumOperands(0), NumValues(VTs.NumVTs), + debugLoc(dl) {} /// InitOperands - Initialize the operands list of this with 1 operand. void InitOperands(SDUse *Ops, const SDValue &Op0) { -- GitLab From 50f520171c8d3171ccd6c83c38923acbb71d1acb Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 2 Feb 2009 18:06:39 +0000 Subject: [PATCH 620/682] Add FIXME. llvm-svn: 63531 --- clang/lib/CodeGen/CGCall.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 7fc3176d2db6..c08b93bd84aa 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -482,6 +482,10 @@ void X86_64ABIInfo::classify(QualType Ty, ASTContext &Context, uint64_t OffsetBase, Class &Lo, Class &Hi) const { + // FIXME: This code can be simplified by introducing a simple value + // class for Class pairs with appropriate constructor methods for + // the various situations. + Lo = Hi = NoClass; Class &Current = OffsetBase < 64 ? Lo : Hi; -- GitLab From 64217e6a28aa0bc4d5e0d09af1ad380726307a7a Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 18:12:58 +0000 Subject: [PATCH 621/682] update test llvm-svn: 63532 --- llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll b/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll index 4b7d622cd392..a8a76bc53b5e 100644 --- a/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll +++ b/llvm/test/Transforms/ScalarRepl/2003-05-29-ArrayFail.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {ret i32 undef} +; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 undef} ; Test that an array is not incorrectly deconstructed. -- GitLab From c81fdd1773c8d7c3b9edd541b3e462d59f4e5400 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 18:15:33 +0000 Subject: [PATCH 622/682] xfail this for now, will fix shortly. llvm-svn: 63533 --- llvm/test/CodeGen/X86/vec_ins_extract.ll | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/test/CodeGen/X86/vec_ins_extract.ll b/llvm/test/CodeGen/X86/vec_ins_extract.ll index 86f13069de29..6f6c977db64b 100644 --- a/llvm/test/CodeGen/X86/vec_ins_extract.ll +++ b/llvm/test/CodeGen/X86/vec_ins_extract.ll @@ -1,5 +1,6 @@ ; RUN: llvm-as < %s | opt -scalarrepl -instcombine | \ ; RUN: llc -march=x86 -mcpu=yonah | not grep sub.*esp +; XFAIL: * ; This checks that various insert/extract idiom work without going to the ; stack. -- GitLab From 49140cb544bea6c57527f60ca7153721bfa86b97 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 2 Feb 2009 18:24:29 +0000 Subject: [PATCH 623/682] Change the ObjC type encoding for block pointer types to "@?" (for consistency with GCC). This fixes clang ObjC rewriter: Wrong encoding emitted for methods with Block parameters. llvm-svn: 63534 --- clang/lib/AST/ASTContext.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index c43ae78c9f58..7892c84f92bb 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -2100,7 +2100,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, else S += 'i'; } else if (T->isBlockPointerType()) { - S += '^'; // This type string is the same as general pointers. + S += "@?"; // Unlike a pointer-to-function, which is "^?". } else if (T->isObjCInterfaceType()) { // @encode(class_name) ObjCInterfaceDecl *OI = T->getAsObjCInterfaceType()->getDecl(); -- GitLab From 62d27986ea9de96877b1438264c55cf3f521a033 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 18:25:48 +0000 Subject: [PATCH 624/682] Split specific_decl_iterator, which had a run-time field for determining what decls are acceptable, into specific_decl_iterator (in which all decls matching the SpecificDecl type requirements are acceptable) and filtered_decl_iterator (which also does a run-time check via a member pointer non-type template parameter). This saves some space in the iterators. llvm-svn: 63535 --- clang/include/clang/AST/DeclBase.h | 97 ++++++++++++++++++++++++------ clang/include/clang/AST/DeclObjC.h | 16 +++-- 2 files changed, 89 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 2c15c870c3b1..0175af66510b 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -630,13 +630,9 @@ public: /// specific_decl_iterator - Iterates over a subrange of /// declarations stored in a DeclContext, providing only those that - /// are of type SpecificDecl (or a class derived from it) and, - /// optionally, that meet some additional run-time criteria. This + /// are of type SpecificDecl (or a class derived from it). This /// iterator is used, for example, to provide iteration over just - /// the fields within a RecordDecl (with SpecificDecl = FieldDecl) - /// or the instance methods within an Objective-C interface (with - /// SpecificDecl = ObjCMethodDecl and using - /// ObjCMethodDecl::isInstanceMethod as the run-time criteria). + /// the fields within a RecordDecl (with SpecificDecl = FieldDecl). template class specific_decl_iterator { /// Current - The current, underlying declaration iterator, which @@ -644,18 +640,11 @@ public: /// type SpecificDecl. DeclContext::decl_iterator Current; - /// Acceptable - If non-NULL, points to a member function that - /// will determine if a particular declaration of type - /// SpecificDecl should be visited by the iteration. - bool (SpecificDecl::*Acceptable)() const; - /// SkipToNextDecl - Advances the current position up to the next /// declaration of type SpecificDecl that also meets the criteria /// required by Acceptable. void SkipToNextDecl() { - while (*Current && - (!isa(*Current) || - (Acceptable && !(cast(*Current)->*Acceptable)()))) + while (*Current && !isa(*Current)) ++Current; } @@ -667,7 +656,7 @@ public: difference_type; typedef std::forward_iterator_tag iterator_category; - specific_decl_iterator() : Current(), Acceptable(0) { } + specific_decl_iterator() : Current() { } /// specific_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -677,9 +666,7 @@ public: /// of iterators. For example, if you want Objective-C instance /// methods, SpecificDecl will be ObjCMethodDecl and A will be /// &ObjCMethodDecl::isInstanceMethod. - specific_decl_iterator(DeclContext::decl_iterator C, - bool (SpecificDecl::*A)() const = 0) - : Current(C), Acceptable(A) { + explicit specific_decl_iterator(DeclContext::decl_iterator C) : Current(C) { SkipToNextDecl(); } @@ -709,6 +696,80 @@ public: } }; + /// \brief Iterates over a filtered subrange of declarations stored + /// in a DeclContext. + /// + /// This iterator visits only those declarations that are of type + /// SpecificDecl (or a class derived from it) and that meet some + /// additional run-time criteria. This iterator is used, for + /// example, to provide access to the instance methods within an + /// Objective-C interface (with SpecificDecl = ObjCMethodDecl and + /// Acceptable = ObjCMethodDecl::isInstanceMethod). + template + class filtered_decl_iterator { + /// Current - The current, underlying declaration iterator, which + /// will either be NULL or will point to a declaration of + /// type SpecificDecl. + DeclContext::decl_iterator Current; + + /// SkipToNextDecl - Advances the current position up to the next + /// declaration of type SpecificDecl that also meets the criteria + /// required by Acceptable. + void SkipToNextDecl() { + while (*Current && + (!isa(*Current) || + (Acceptable && !(cast(*Current)->*Acceptable)()))) + ++Current; + } + + public: + typedef SpecificDecl* value_type; + typedef SpecificDecl* reference; + typedef SpecificDecl* pointer; + typedef std::iterator_traits::difference_type + difference_type; + typedef std::forward_iterator_tag iterator_category; + + filtered_decl_iterator() : Current() { } + + /// specific_decl_iterator - Construct a new iterator over a + /// subset of the declarations the range [C, + /// end-of-declarations). If A is non-NULL, it is a pointer to a + /// member function of SpecificDecl that should return true for + /// all of the SpecificDecl instances that will be in the subset + /// of iterators. For example, if you want Objective-C instance + /// methods, SpecificDecl will be ObjCMethodDecl and A will be + /// &ObjCMethodDecl::isInstanceMethod. + explicit filtered_decl_iterator(DeclContext::decl_iterator C) : Current(C) { + SkipToNextDecl(); + } + + reference operator*() const { return cast(*Current); } + pointer operator->() const { return cast(*Current); } + + filtered_decl_iterator& operator++() { + ++Current; + SkipToNextDecl(); + return *this; + } + + filtered_decl_iterator operator++(int) { + filtered_decl_iterator tmp(*this); + ++(*this); + return tmp; + } + + friend bool + operator==(const filtered_decl_iterator& x, const filtered_decl_iterator& y) { + return x.Current == y.Current; + } + + friend bool + operator!=(const filtered_decl_iterator& x, const filtered_decl_iterator& y) { + return x.Current != y.Current; + } + }; + /// @brief Add the declaration D into this context. /// /// This routine should be invoked when the declaration D has first diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h index cda9bddbcc34..c77cc15e754f 100644 --- a/clang/include/clang/AST/DeclObjC.h +++ b/clang/include/clang/AST/DeclObjC.h @@ -279,20 +279,24 @@ public: return method_iterator(decls_end()); } - typedef method_iterator instmeth_iterator; + typedef filtered_decl_iterator + instmeth_iterator; instmeth_iterator instmeth_begin() const { - return instmeth_iterator(decls_begin(), &ObjCMethodDecl::isInstanceMethod); + return instmeth_iterator(decls_begin()); } instmeth_iterator instmeth_end() const { - return instmeth_iterator(decls_end(), &ObjCMethodDecl::isInstanceMethod); + return instmeth_iterator(decls_end()); } - typedef method_iterator classmeth_iterator; + typedef filtered_decl_iterator + classmeth_iterator; classmeth_iterator classmeth_begin() const { - return classmeth_iterator(decls_begin(), &ObjCMethodDecl::isClassMethod); + return classmeth_iterator(decls_begin()); } classmeth_iterator classmeth_end() const { - return classmeth_iterator(decls_end(), &ObjCMethodDecl::isClassMethod); + return classmeth_iterator(decls_end()); } // Get the local instance/class method declared in this interface. -- GitLab From 03f862579c02d812157dfcd6f23db40afc2f2853 Mon Sep 17 00:00:00 2001 From: Evan Cheng Date: Mon, 2 Feb 2009 18:33:18 +0000 Subject: [PATCH 625/682] Refactor PerformPHIConstruction, no functionality changes. llvm-svn: 63536 --- llvm/lib/CodeGen/PreAllocSplitting.cpp | 290 ++++++++++++++----------- 1 file changed, 165 insertions(+), 125 deletions(-) diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index 4061859f740c..a538db8be086 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -164,16 +164,24 @@ namespace { bool removeDeadSpills(SmallPtrSet& split); unsigned getNumberOfNonSpills(SmallPtrSet& MIs, unsigned Reg, int FrameIndex, bool& TwoAddr); - VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator use, - MachineBasicBlock* MBB, - LiveInterval* LI, + VNInfo* PerformPHIConstruction(MachineBasicBlock::iterator Use, + MachineBasicBlock* MBB, LiveInterval* LI, SmallPtrSet& Visited, DenseMap >& Defs, DenseMap >& Uses, DenseMap& NewVNs, DenseMap& LiveOut, DenseMap& Phis, - bool toplevel, bool intrablock); + bool IsTopLevel, bool IsIntraBlock); + VNInfo* PerformPHIConstructionFallBack(MachineBasicBlock::iterator Use, + MachineBasicBlock* MBB, LiveInterval* LI, + SmallPtrSet& Visited, + DenseMap >& Defs, + DenseMap >& Uses, + DenseMap& NewVNs, + DenseMap& LiveOut, + DenseMap& Phis, + bool IsTopLevel, bool IsIntraBlock); }; } // end anonymous namespace @@ -431,83 +439,35 @@ PreAllocSplitting::UpdateSpillSlotInterval(VNInfo *ValNo, unsigned SpillIndex, /// PerformPHIConstruction - From properly set up use and def lists, use a PHI /// construction algorithm to compute the ranges and valnos for an interval. -VNInfo* PreAllocSplitting::PerformPHIConstruction( - MachineBasicBlock::iterator use, - MachineBasicBlock* MBB, - LiveInterval* LI, +VNInfo* +PreAllocSplitting::PerformPHIConstruction(MachineBasicBlock::iterator UseI, + MachineBasicBlock* MBB, LiveInterval* LI, SmallPtrSet& Visited, DenseMap >& Defs, DenseMap >& Uses, DenseMap& NewVNs, DenseMap& LiveOut, DenseMap& Phis, - bool toplevel, bool intrablock) { + bool IsTopLevel, bool IsIntraBlock) { // Return memoized result if it's available. - if (toplevel && Visited.count(use) && NewVNs.count(use)) - return NewVNs[use]; - else if (!toplevel && intrablock && NewVNs.count(use)) - return NewVNs[use]; - else if (!intrablock && LiveOut.count(MBB)) + if (IsTopLevel && Visited.count(UseI) && NewVNs.count(UseI)) + return NewVNs[UseI]; + else if (!IsTopLevel && IsIntraBlock && NewVNs.count(UseI)) + return NewVNs[UseI]; + else if (!IsIntraBlock && LiveOut.count(MBB)) return LiveOut[MBB]; - typedef DenseMap > RegMap; - // Check if our block contains any uses or defs. bool ContainsDefs = Defs.count(MBB); bool ContainsUses = Uses.count(MBB); - VNInfo* ret = 0; + VNInfo* RetVNI = 0; // Enumerate the cases of use/def contaning blocks. if (!ContainsDefs && !ContainsUses) { - Fallback: - // NOTE: Because this is the fallback case from other cases, we do NOT - // assume that we are not intrablock here. - if (Phis.count(MBB)) return Phis[MBB]; - - unsigned StartIndex = LIs->getMBBStartIdx(MBB); - - Phis[MBB] = ret = LI->getNextValue(~0U, /*FIXME*/ 0, - LIs->getVNInfoAllocator()); - if (!intrablock) LiveOut[MBB] = ret; - - // If there are no uses or defs between our starting point and the - // beginning of the block, then recursive perform phi construction - // on our predecessors. - DenseMap IncomingVNs; - for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), - PE = MBB->pred_end(); PI != PE; ++PI) { - VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI, - Visited, Defs, Uses, NewVNs, - LiveOut, Phis, false, false); - if (Incoming != 0) - IncomingVNs[*PI] = Incoming; - } - - if (MBB->pred_size() == 1 && !ret->hasPHIKill) { - LI->MergeValueNumberInto(ret, IncomingVNs.begin()->second); - Phis[MBB] = ret = IncomingVNs.begin()->second; - } else { - // Otherwise, merge the incoming VNInfos with a phi join. Create a new - // VNInfo to represent the joined value. - for (DenseMap::iterator I = - IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) { - I->second->hasPHIKill = true; - unsigned KillIndex = LIs->getMBBEndIdx(I->first); - if (!LiveInterval::isKill(I->second, KillIndex)) - LI->addKill(I->second, KillIndex); - } - } - - unsigned EndIndex = 0; - if (intrablock) { - EndIndex = LIs->getInstructionIndex(use); - EndIndex = LiveIntervals::getUseIndex(EndIndex); - } else - EndIndex = LIs->getMBBEndIdx(MBB); - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); - if (intrablock) - LI->addKill(ret, EndIndex); + return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, Uses, + NewVNs, LiveOut, Phis, + IsTopLevel, IsIntraBlock); } else if (ContainsDefs && !ContainsUses) { SmallPtrSet& BlockDefs = Defs[MBB]; @@ -515,71 +475,75 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( // instruction we care about, go to the fallback case. Note that that // should never happen: this cannot be intrablock, so use should // always be an end() iterator. - assert(use == MBB->end() && "No use marked in intrablock"); + assert(UseI == MBB->end() && "No use marked in intrablock"); - MachineBasicBlock::iterator walker = use; - --walker; - while (walker != MBB->begin()) - if (BlockDefs.count(walker)) { + MachineBasicBlock::iterator Walker = UseI; + --Walker; + while (Walker != MBB->begin()) { + if (BlockDefs.count(Walker)) break; - } else - --walker; + --Walker; + } // Once we've found it, extend its VNInfo to our instruction. - unsigned DefIndex = LIs->getInstructionIndex(walker); + unsigned DefIndex = LIs->getInstructionIndex(Walker); DefIndex = LiveIntervals::getDefIndex(DefIndex); unsigned EndIndex = LIs->getMBBEndIdx(MBB); - ret = NewVNs[walker]; - LI->addRange(LiveRange(DefIndex, EndIndex+1, ret)); + RetVNI = NewVNs[Walker]; + LI->addRange(LiveRange(DefIndex, EndIndex+1, RetVNI)); } else if (!ContainsDefs && ContainsUses) { SmallPtrSet& BlockUses = Uses[MBB]; // Search for the use in this block that precedes the instruction we care - // about, going to the fallback case if we don't find it. - - if (use == MBB->begin()) - goto Fallback; + // about, going to the fallback case if we don't find it. + if (UseI == MBB->begin()) + return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, + Uses, NewVNs, LiveOut, Phis, + IsTopLevel, IsIntraBlock); - MachineBasicBlock::iterator walker = use; - --walker; + MachineBasicBlock::iterator Walker = UseI; + --Walker; bool found = false; - while (walker != MBB->begin()) - if (BlockUses.count(walker)) { + while (Walker != MBB->begin()) { + if (BlockUses.count(Walker)) { found = true; break; - } else - --walker; + } + --Walker; + } // Must check begin() too. if (!found) { - if (BlockUses.count(walker)) + if (BlockUses.count(Walker)) found = true; else - goto Fallback; + return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, + Uses, NewVNs, LiveOut, Phis, + IsTopLevel, IsIntraBlock); } - unsigned UseIndex = LIs->getInstructionIndex(walker); + unsigned UseIndex = LIs->getInstructionIndex(Walker); UseIndex = LiveIntervals::getUseIndex(UseIndex); unsigned EndIndex = 0; - if (intrablock) { - EndIndex = LIs->getInstructionIndex(use); + if (IsIntraBlock) { + EndIndex = LIs->getInstructionIndex(UseI); EndIndex = LiveIntervals::getUseIndex(EndIndex); } else EndIndex = LIs->getMBBEndIdx(MBB); // Now, recursively phi construct the VNInfo for the use we found, // and then extend it to include the instruction we care about - ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, - NewVNs, LiveOut, Phis, false, true); + RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses, + NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(UseIndex, EndIndex+1, ret)); + LI->addRange(LiveRange(UseIndex, EndIndex+1, RetVNI)); // FIXME: Need to set kills properly for inter-block stuff. - if (LI->isKill(ret, UseIndex)) LI->removeKill(ret, UseIndex); - if (intrablock) - LI->addKill(ret, EndIndex); - } else if (ContainsDefs && ContainsUses){ + if (LI->isKill(RetVNI, UseIndex)) LI->removeKill(RetVNI, UseIndex); + if (IsIntraBlock) + LI->addKill(RetVNI, EndIndex); + } else if (ContainsDefs && ContainsUses) { SmallPtrSet& BlockDefs = Defs[MBB]; SmallPtrSet& BlockUses = Uses[MBB]; @@ -587,67 +551,143 @@ VNInfo* PreAllocSplitting::PerformPHIConstruction( // special note that checking for defs must take precedence over checking // for uses, because of two-address instructions. - if (use == MBB->begin()) - goto Fallback; + if (UseI == MBB->begin()) + return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, Uses, + NewVNs, LiveOut, Phis, + IsTopLevel, IsIntraBlock); - MachineBasicBlock::iterator walker = use; - --walker; + MachineBasicBlock::iterator Walker = UseI; + --Walker; bool foundDef = false; bool foundUse = false; - while (walker != MBB->begin()) - if (BlockDefs.count(walker)) { + while (Walker != MBB->begin()) { + if (BlockDefs.count(Walker)) { foundDef = true; break; - } else if (BlockUses.count(walker)) { + } else if (BlockUses.count(Walker)) { foundUse = true; break; - } else - --walker; + } + --Walker; + } // Must check begin() too. if (!foundDef && !foundUse) { - if (BlockDefs.count(walker)) + if (BlockDefs.count(Walker)) foundDef = true; - else if (BlockUses.count(walker)) + else if (BlockUses.count(Walker)) foundUse = true; else - goto Fallback; + return PerformPHIConstructionFallBack(UseI, MBB, LI, Visited, Defs, + Uses, NewVNs, LiveOut, Phis, + IsTopLevel, IsIntraBlock); } - unsigned StartIndex = LIs->getInstructionIndex(walker); + unsigned StartIndex = LIs->getInstructionIndex(Walker); StartIndex = foundDef ? LiveIntervals::getDefIndex(StartIndex) : LiveIntervals::getUseIndex(StartIndex); unsigned EndIndex = 0; - if (intrablock) { - EndIndex = LIs->getInstructionIndex(use); + if (IsIntraBlock) { + EndIndex = LIs->getInstructionIndex(UseI); EndIndex = LiveIntervals::getUseIndex(EndIndex); } else EndIndex = LIs->getMBBEndIdx(MBB); if (foundDef) - ret = NewVNs[walker]; + RetVNI = NewVNs[Walker]; else - ret = PerformPHIConstruction(walker, MBB, LI, Visited, Defs, Uses, - NewVNs, LiveOut, Phis, false, true); + RetVNI = PerformPHIConstruction(Walker, MBB, LI, Visited, Defs, Uses, + NewVNs, LiveOut, Phis, false, true); - LI->addRange(LiveRange(StartIndex, EndIndex+1, ret)); + LI->addRange(LiveRange(StartIndex, EndIndex+1, RetVNI)); - if (foundUse && LI->isKill(ret, StartIndex)) - LI->removeKill(ret, StartIndex); - if (intrablock) { - LI->addKill(ret, EndIndex); + if (foundUse && LI->isKill(RetVNI, StartIndex)) + LI->removeKill(RetVNI, StartIndex); + if (IsIntraBlock) { + LI->addKill(RetVNI, EndIndex); } } // Memoize results so we don't have to recompute them. - if (!intrablock) LiveOut[MBB] = ret; + if (!IsIntraBlock) LiveOut[MBB] = RetVNI; + else { + if (!NewVNs.count(UseI)) + NewVNs[UseI] = RetVNI; + Visited.insert(UseI); + } + + return RetVNI; +} + +/// PerformPHIConstructionFallBack - PerformPHIConstruction fall back path. +/// +VNInfo* +PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator UseI, + MachineBasicBlock* MBB, LiveInterval* LI, + SmallPtrSet& Visited, + DenseMap >& Defs, + DenseMap >& Uses, + DenseMap& NewVNs, + DenseMap& LiveOut, + DenseMap& Phis, + bool IsTopLevel, bool IsIntraBlock) { + // NOTE: Because this is the fallback case from other cases, we do NOT + // assume that we are not intrablock here. + if (Phis.count(MBB)) return Phis[MBB]; + + unsigned StartIndex = LIs->getMBBStartIdx(MBB); + VNInfo *RetVNI = Phis[MBB] = LI->getNextValue(~0U, /*FIXME*/ 0, + LIs->getVNInfoAllocator()); + if (!IsIntraBlock) LiveOut[MBB] = RetVNI; + + // If there are no uses or defs between our starting point and the + // beginning of the block, then recursive perform phi construction + // on our predecessors. + DenseMap IncomingVNs; + for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), + PE = MBB->pred_end(); PI != PE; ++PI) { + VNInfo* Incoming = PerformPHIConstruction((*PI)->end(), *PI, LI, + Visited, Defs, Uses, NewVNs, + LiveOut, Phis, false, false); + if (Incoming != 0) + IncomingVNs[*PI] = Incoming; + } + + if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill) { + LI->MergeValueNumberInto(RetVNI, IncomingVNs.begin()->second); + Phis[MBB] = RetVNI = IncomingVNs.begin()->second; + } else { + // Otherwise, merge the incoming VNInfos with a phi join. Create a new + // VNInfo to represent the joined value. + for (DenseMap::iterator I = + IncomingVNs.begin(), E = IncomingVNs.end(); I != E; ++I) { + I->second->hasPHIKill = true; + unsigned KillIndex = LIs->getMBBEndIdx(I->first); + if (!LiveInterval::isKill(I->second, KillIndex)) + LI->addKill(I->second, KillIndex); + } + } + + unsigned EndIndex = 0; + if (IsIntraBlock) { + EndIndex = LIs->getInstructionIndex(UseI); + EndIndex = LiveIntervals::getUseIndex(EndIndex); + } else + EndIndex = LIs->getMBBEndIdx(MBB); + LI->addRange(LiveRange(StartIndex, EndIndex+1, RetVNI)); + if (IsIntraBlock) + LI->addKill(RetVNI, EndIndex); + + // Memoize results so we don't have to recompute them. + if (!IsIntraBlock) + LiveOut[MBB] = RetVNI; else { - if (!NewVNs.count(use)) - NewVNs[use] = ret; - Visited.insert(use); + if (!NewVNs.count(UseI)) + NewVNs[UseI] = RetVNI; + Visited.insert(UseI); } - return ret; + return RetVNI; } /// ReconstructLiveInterval - Recompute a live interval from scratch. -- GitLab From 8525d83aacc8a9d8b021eae1132dd73de68f2fde Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 2 Feb 2009 19:03:57 +0000 Subject: [PATCH 626/682] DebugLoc propagation for int<->fp conversions. llvm-svn: 63537 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 163 ++++++++++-------- 1 file changed, 89 insertions(+), 74 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 0b3d979b8e01..f7376ec30746 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -282,15 +282,19 @@ private: SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned, SDValue &Hi); - SDValue ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source); + SDValue ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl); SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT); SDValue ExpandBUILD_VECTOR(SDNode *Node); SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node); - SDValue LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op); - SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, MVT DestVT); - SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, bool isSigned); - SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, bool isSigned); + SDValue LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, + SDValue Op, DebugLoc dl); + SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, MVT DestVT, + DebugLoc dl); + SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, bool isSigned, + DebugLoc dl); + SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, bool isSigned, + DebugLoc dl); SDValue ExpandBSWAP(SDValue Op); SDValue ExpandBitCount(unsigned Opc, SDValue Op); @@ -4004,7 +4008,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::UINT_TO_FP: { bool isSigned = Node->getOpcode() == ISD::SINT_TO_FP; Result = LegalizeINT_TO_FP(Result, isSigned, - Node->getValueType(0), Node->getOperand(0)); + Node->getValueType(0), Node->getOperand(0), dl); break; } case ISD::TRUNCATE: @@ -4063,7 +4067,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case TargetLowering::Promote: Result = PromoteLegalFP_TO_INT(Tmp1, Node->getValueType(0), - Node->getOpcode() == ISD::FP_TO_SINT); + Node->getOpcode() == ISD::FP_TO_SINT, + dl); break; case TargetLowering::Expand: if (Node->getOpcode() == ISD::FP_TO_UINT) { @@ -4075,15 +4080,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { APInt x = APInt::getSignBit(NVT.getSizeInBits()); (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven); Tmp2 = DAG.getConstantFP(apf, VT); - Tmp3 = DAG.getSetCC(TLI.getSetCCResultType(VT), Node->getOperand(0), + Tmp3 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), + Node->getOperand(0), Tmp2, ISD::SETLT); - True = DAG.getNode(ISD::FP_TO_SINT, NVT, Node->getOperand(0)); - False = DAG.getNode(ISD::FP_TO_SINT, NVT, - DAG.getNode(ISD::FSUB, VT, Node->getOperand(0), - Tmp2)); - False = DAG.getNode(ISD::XOR, NVT, False, + True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0)); + False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, + DAG.getNode(ISD::FSUB, dl, VT, + Node->getOperand(0), Tmp2)); + False = DAG.getNode(ISD::XOR, dl, NVT, False, DAG.getConstant(x, NVT)); - Result = DAG.getNode(ISD::SELECT, NVT, Tmp3, True, False); + Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp3, True, False); break; } else { assert(0 && "Do not know how to expand FP_TO_SINT yet!"); @@ -4097,24 +4103,25 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Convert ppcf128 to i32 if (OVT == MVT::ppcf128 && VT == MVT::i32) { if (Node->getOpcode() == ISD::FP_TO_SINT) { - Result = DAG.getNode(ISD::FP_ROUND_INREG, MVT::ppcf128, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, Node->getOperand(0), DAG.getValueType(MVT::f64)); - Result = DAG.getNode(ISD::FP_ROUND, MVT::f64, Result, + Result = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Result, DAG.getIntPtrConstant(1)); - Result = DAG.getNode(ISD::FP_TO_SINT, VT, Result); + Result = DAG.getNode(ISD::FP_TO_SINT, dl, VT, Result); } else { const uint64_t TwoE31[] = {0x41e0000000000000LL, 0}; APFloat apf = APFloat(APInt(128, 2, TwoE31)); Tmp2 = DAG.getConstantFP(apf, OVT); // X>=2^31 ? (int)(X-2^31)+0x80000000 : (int)X // FIXME: generated code sucks. - Result = DAG.getNode(ISD::SELECT_CC, VT, Node->getOperand(0), Tmp2, - DAG.getNode(ISD::ADD, MVT::i32, - DAG.getNode(ISD::FP_TO_SINT, VT, - DAG.getNode(ISD::FSUB, OVT, + Result = DAG.getNode(ISD::SELECT_CC, dl, VT, Node->getOperand(0), + Tmp2, + DAG.getNode(ISD::ADD, dl, MVT::i32, + DAG.getNode(ISD::FP_TO_SINT, dl, VT, + DAG.getNode(ISD::FSUB, dl, OVT, Node->getOperand(0), Tmp2)), DAG.getConstant(0x80000000, MVT::i32)), - DAG.getNode(ISD::FP_TO_SINT, VT, + DAG.getNode(ISD::FP_TO_SINT, dl, VT, Node->getOperand(0)), DAG.getCondCode(ISD::SETGE)); } @@ -4601,7 +4608,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { break; case Expand: Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, NVT, - Node->getOperand(0)); + Node->getOperand(0), Node->getDebugLoc()); // Round if we cannot tolerate excess precision. if (NoExcessFPPrecision) Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, @@ -5808,7 +5815,8 @@ SDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, /// LegalizeINT_TO_FP - Legalize a [US]INT_TO_FP operation. /// SDValue SelectionDAGLegalize:: -LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) { +LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op, + DebugLoc dl) { bool isCustom = false; SDValue Tmp1; switch (getTypeAction(Op.getValueType())) { @@ -5824,7 +5832,7 @@ LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) { if (Result.getNode()) Result = DAG.UpdateNodeOperands(Result, Tmp1); else - Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, + Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, dl, DestTy, Tmp1); if (isCustom) { Tmp1 = TLI.LowerOperation(Result, DAG); @@ -5832,29 +5840,29 @@ LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) { } break; case TargetLowering::Expand: - Result = ExpandLegalINT_TO_FP(isSigned, LegalizeOp(Op), DestTy); + Result = ExpandLegalINT_TO_FP(isSigned, LegalizeOp(Op), DestTy, dl); break; case TargetLowering::Promote: - Result = PromoteLegalINT_TO_FP(LegalizeOp(Op), DestTy, isSigned); + Result = PromoteLegalINT_TO_FP(LegalizeOp(Op), DestTy, isSigned, dl); break; } break; case Expand: - Result = ExpandIntToFP(isSigned, DestTy, Op); + Result = ExpandIntToFP(isSigned, DestTy, Op, dl) ; break; case Promote: Tmp1 = PromoteOp(Op); if (isSigned) { - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, Tmp1.getValueType(), + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Tmp1.getValueType(), Tmp1, DAG.getValueType(Op.getValueType())); } else { - Tmp1 = DAG.getZeroExtendInReg(Tmp1, + Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, Op.getValueType()); } if (Result.getNode()) Result = DAG.UpdateNodeOperands(Result, Tmp1); else - Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, + Result = DAG.getNode(isSigned ? ISD::SINT_TO_FP : ISD::UINT_TO_FP, dl, DestTy, Tmp1); Result = LegalizeOp(Result); // The 'op' is not necessarily legal! break; @@ -5865,7 +5873,7 @@ LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, SDValue Op) { /// ExpandIntToFP - Expand a [US]INT_TO_FP operation. /// SDValue SelectionDAGLegalize:: -ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { +ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl) { MVT SourceVT = Source.getValueType(); bool ExpandSource = getTypeAction(SourceVT) == Expand; @@ -5877,16 +5885,18 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { if (DestTy.getVectorNumElements() == 1) { SDValue Scalar = ScalarizeVectorOp(Source); SDValue Result = LegalizeINT_TO_FP(SDValue(), isSigned, - DestEltTy, Scalar); - return DAG.getNode(ISD::BUILD_VECTOR, DestTy, Result); + DestEltTy, Scalar, dl); + return DAG.getNode(ISD::BUILD_VECTOR, dl, DestTy, Result); } SDValue Lo, Hi; SplitVectorOp(Source, Lo, Hi); MVT SplitDestTy = MVT::getVectorVT(DestEltTy, DestTy.getVectorNumElements() / 2); - SDValue LoResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy, Lo); - SDValue HiResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy, Hi); - return LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, DestTy, LoResult, + SDValue LoResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy, + Lo, dl); + SDValue HiResult = LegalizeINT_TO_FP(SDValue(), isSigned, SplitDestTy, + Hi, dl); + return LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, dl, DestTy, LoResult, HiResult)); } @@ -5899,7 +5909,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { if (ExpandSource) { SDValue Lo; ExpandOp(Source, Lo, Hi); - Source = DAG.getNode(ISD::BUILD_PAIR, SourceVT, Lo, Hi); + Source = DAG.getNode(ISD::BUILD_PAIR, dl, SourceVT, Lo, Hi); } else { // The comparison for the sign bit will use the entire operand. Hi = Source; @@ -5923,13 +5933,14 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { // If this is unsigned, and not supported, first perform the conversion to // signed, then adjust the result if the sign bit is set. - SDValue SignedConv = ExpandIntToFP(true, DestTy, Source); + SDValue SignedConv = ExpandIntToFP(true, DestTy, Source, dl); - SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Hi.getValueType()), + SDValue SignSet = DAG.getSetCC(dl, + TLI.getSetCCResultType(Hi.getValueType()), Hi, DAG.getConstant(0, Hi.getValueType()), ISD::SETLT); SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); - SDValue CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), + SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet, Four, Zero); uint64_t FF = 0x5f800000ULL; if (TLI.isLittleEndian()) FF <<= 32; @@ -5937,16 +5948,16 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); unsigned Alignment = 1 << cast(CPIdx)->getAlignment(); - CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); + CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); Alignment = std::min(Alignment, 4u); SDValue FudgeInReg; if (DestTy == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, + FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, false, Alignment); else if (DestTy.bitsGT(MVT::f32)) // FIXME: Avoid the extend by construction the right constantpool? - FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, DestTy, DAG.getEntryNode(), + FudgeInReg = DAG.getExtLoad(ISD::EXTLOAD, dl, DestTy, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, MVT::f32, false, Alignment); @@ -5959,12 +5970,12 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { // constructing will be expanded into a libcall. if (SCVT.getSizeInBits() != DestTy.getSizeInBits()) { assert(SCVT.getSizeInBits() * 2 == DestTy.getSizeInBits()); - SignedConv = DAG.getNode(ISD::BUILD_PAIR, DestTy, + SignedConv = DAG.getNode(ISD::BUILD_PAIR, dl, DestTy, SignedConv, SignedConv.getValue(1)); } - SignedConv = DAG.getNode(ISD::BIT_CONVERT, DestTy, SignedConv); + SignedConv = DAG.getNode(ISD::BIT_CONVERT, dl, DestTy, SignedConv); } - return DAG.getNode(ISD::FADD, DestTy, SignedConv, FudgeInReg); + return DAG.getNode(ISD::FADD, dl, DestTy, SignedConv, FudgeInReg); } // Check to see if the target has a custom way to lower this. If so, use it. @@ -5974,7 +5985,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { case TargetLowering::Expand: break; // This case is handled below. case TargetLowering::Custom: { - SDValue NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, DestTy, + SDValue NV = TLI.LowerOperation(DAG.getNode(ISD::SINT_TO_FP, dl, DestTy, Source), DAG); if (NV.getNode()) return LegalizeOp(NV); @@ -5987,7 +5998,7 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { if (ExpandSource) { SDValue SrcLo, SrcHi; ExpandOp(Source, SrcLo, SrcHi); - Source = DAG.getNode(ISD::BUILD_PAIR, SourceVT, SrcLo, SrcHi); + Source = DAG.getNode(ISD::BUILD_PAIR, dl, SourceVT, SrcLo, SrcHi); } RTLIB::Libcall LC = isSigned ? @@ -5995,11 +6006,11 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { RTLIB::getUINTTOFP(SourceVT, DestTy); assert(LC != RTLIB::UNKNOWN_LIBCALL && "Unknown int value type"); - Source = DAG.getNode(ISD::SINT_TO_FP, DestTy, Source); + Source = DAG.getNode(ISD::SINT_TO_FP, dl, DestTy, Source); SDValue HiPart; SDValue Result = ExpandLibCall(LC, Source.getNode(), isSigned, HiPart); if (Result.getValueType() != DestTy && HiPart.getNode()) - Result = DAG.getNode(ISD::BUILD_PAIR, DestTy, Result, HiPart); + Result = DAG.getNode(ISD::BUILD_PAIR, dl, DestTy, Result, HiPart); return Result; } @@ -6009,7 +6020,8 @@ ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source) { /// legal for the target. SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, SDValue Op0, - MVT DestVT) { + MVT DestVT, + DebugLoc dl) { if (Op0.getValueType() == MVT::i32) { // simple 32-bit [signed|unsigned] integer to float/double expansion @@ -6020,7 +6032,8 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, SDValue WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy()); // set up Hi and Lo (into buffer) address based on endian SDValue Hi = StackSlot; - SDValue Lo = DAG.getNode(ISD::ADD, TLI.getPointerTy(), StackSlot,WordOff); + SDValue Lo = DAG.getNode(ISD::ADD, dl, + TLI.getPointerTy(), StackSlot,WordOff); if (TLI.isLittleEndian()) std::swap(Hi, Lo); @@ -6029,26 +6042,26 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, if (isSigned) { // constant used to invert sign bit (signed to unsigned mapping) SDValue SignBit = DAG.getConstant(0x80000000u, MVT::i32); - Op0Mapped = DAG.getNode(ISD::XOR, MVT::i32, Op0, SignBit); + Op0Mapped = DAG.getNode(ISD::XOR, dl, MVT::i32, Op0, SignBit); } else { Op0Mapped = Op0; } // store the lo of the constructed double - based on integer input - SDValue Store1 = DAG.getStore(DAG.getEntryNode(), + SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, Op0Mapped, Lo, NULL, 0); // initial hi portion of constructed double SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32); // store the hi of the constructed double - biased exponent - SDValue Store2=DAG.getStore(Store1, InitialHi, Hi, NULL, 0); + SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0); // load the constructed double - SDValue Load = DAG.getLoad(MVT::f64, Store2, StackSlot, NULL, 0); + SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0); // FP constant to bias correct the final result SDValue Bias = DAG.getConstantFP(isSigned ? BitsToDouble(0x4330000080000000ULL) : BitsToDouble(0x4330000000000000ULL), MVT::f64); // subtract the bias - SDValue Sub = DAG.getNode(ISD::FSUB, MVT::f64, Load, Bias); + SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Load, Bias); // final result SDValue Result; // handle final rounding @@ -6056,21 +6069,21 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, // do nothing Result = Sub; } else if (DestVT.bitsLT(MVT::f64)) { - Result = DAG.getNode(ISD::FP_ROUND, DestVT, Sub, + Result = DAG.getNode(ISD::FP_ROUND, dl, DestVT, Sub, DAG.getIntPtrConstant(0)); } else if (DestVT.bitsGT(MVT::f64)) { - Result = DAG.getNode(ISD::FP_EXTEND, DestVT, Sub); + Result = DAG.getNode(ISD::FP_EXTEND, dl, DestVT, Sub); } return Result; } assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet"); - SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, DestVT, Op0); + SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0); - SDValue SignSet = DAG.getSetCC(TLI.getSetCCResultType(Op0.getValueType()), + SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()), Op0, DAG.getConstant(0, Op0.getValueType()), ISD::SETLT); SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); - SDValue CstOffset = DAG.getNode(ISD::SELECT, Zero.getValueType(), + SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), SignSet, Four, Zero); // If the sign bit of the integer is set, the large number will be treated @@ -6089,22 +6102,22 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); unsigned Alignment = 1 << cast(CPIdx)->getAlignment(); - CPIdx = DAG.getNode(ISD::ADD, TLI.getPointerTy(), CPIdx, CstOffset); + CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); Alignment = std::min(Alignment, 4u); SDValue FudgeInReg; if (DestVT == MVT::f32) - FudgeInReg = DAG.getLoad(MVT::f32, DAG.getEntryNode(), CPIdx, + FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, false, Alignment); else { FudgeInReg = - LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, DestVT, + LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, MVT::f32, false, Alignment)); } - return DAG.getNode(ISD::FADD, DestVT, Tmp1, FudgeInReg); + return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg); } /// PromoteLegalINT_TO_FP - This function is responsible for legalizing a @@ -6114,7 +6127,8 @@ SDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, /// operation that takes a larger input. SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, - bool isSigned) { + bool isSigned, + DebugLoc dl) { // First step, figure out the appropriate *INT_TO_FP operation to use. MVT NewInTy = LegalOp.getValueType(); @@ -6157,9 +6171,9 @@ SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, // Okay, we found the operation and type to use. Zero extend our input to the // desired type then run the operation on it. - return DAG.getNode(OpToUse, DestVT, + return DAG.getNode(OpToUse, dl, DestVT, DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, - NewInTy, LegalOp)); + dl, NewInTy, LegalOp)); } /// PromoteLegalFP_TO_INT - This function is responsible for legalizing a @@ -6169,7 +6183,8 @@ SDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, /// operation that returns a larger result. SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, - bool isSigned) { + bool isSigned, + DebugLoc dl) { // First step, figure out the appropriate FP_TO*INT operation to use. MVT NewOutTy = DestVT; @@ -6211,7 +6226,7 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, // Okay, we found the operation and type to use. - SDValue Operation = DAG.getNode(OpToUse, NewOutTy, LegalOp); + SDValue Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp); // If the operation produces an invalid type, it must be custom lowered. Use // the target lowering hooks to expand it. Just keep the low part of the @@ -6225,7 +6240,7 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, // Truncate the result of the extended FP_TO_*INT operation to the desired // size. - return DAG.getNode(ISD::TRUNCATE, DestVT, Operation); + return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation); } /// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. @@ -7368,7 +7383,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ } Lo = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, VT, - Node->getOperand(0)); + Node->getOperand(0), Node->getDebugLoc()); if (getTypeAction(Lo.getValueType()) == Expand) // float to i32 etc. can be 'expanded' to a single node. ExpandOp(Lo, Lo, Hi); -- GitLab From f5589ac5a917c845475d64cf288c4739d44ca48b Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 2 Feb 2009 19:06:38 +0000 Subject: [PATCH 627/682] Shuffle some functions around, no functionality change. llvm-svn: 63538 --- clang/lib/CodeGen/CGCall.cpp | 130 +++++++++++++++++------------------ 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c08b93bd84aa..4c423ea5f106 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -874,6 +874,71 @@ CodeGenFunction::ExpandTypeToArgs(QualType Ty, RValue RV, } } +/// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as +/// a pointer to an object of type \arg Ty. +/// +/// This safely handles the case when the src type is smaller than the +/// destination type; in this situation the values of bits which not +/// present in the src are undefined. +static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr, + const llvm::Type *Ty, + CodeGenFunction &CGF) { + const llvm::Type *SrcTy = + cast(SrcPtr->getType())->getElementType(); + uint64_t SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy); + uint64_t DstSize = CGF.CGM.getTargetData().getTypePaddedSize(Ty); + + // If load is legal, just bitcase the src pointer. + if (SrcSize == DstSize) { + llvm::Value *Casted = + CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty)); + return CGF.Builder.CreateLoad(Casted); + } else { + assert(SrcSize < DstSize && "Coercion is losing source bits!"); + + // Otherwise do coercion through memory. This is stupid, but + // simple. + llvm::Value *Tmp = CGF.CreateTempAlloca(Ty); + llvm::Value *Casted = + CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(SrcTy)); + CGF.Builder.CreateStore(CGF.Builder.CreateLoad(SrcPtr), Casted); + return CGF.Builder.CreateLoad(Tmp); + } +} + +/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src, +/// where the source and destination may have different types. +/// +/// This safely handles the case when the src type is larger than the +/// destination type; the upper bits of the src will be lost. +static void CreateCoercedStore(llvm::Value *Src, + llvm::Value *DstPtr, + CodeGenFunction &CGF) { + const llvm::Type *SrcTy = Src->getType(); + const llvm::Type *DstTy = + cast(DstPtr->getType())->getElementType(); + + uint64_t SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy); + uint64_t DstSize = CGF.CGM.getTargetData().getTypePaddedSize(DstTy); + + // If store is legal, just bitcase the src pointer. + if (SrcSize == DstSize) { + llvm::Value *Casted = + CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy)); + CGF.Builder.CreateStore(Src, Casted); + } else { + assert(SrcSize > DstSize && "Coercion is missing bits!"); + + // Otherwise do coercion through memory. This is stupid, but + // simple. + llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy); + CGF.Builder.CreateStore(Src, Tmp); + llvm::Value *Casted = + CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(DstTy)); + CGF.Builder.CreateStore(CGF.Builder.CreateLoad(Casted), DstPtr); + } +} + /***/ const llvm::FunctionType * @@ -1112,71 +1177,6 @@ void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, assert(AI == Fn->arg_end() && "Argument mismatch!"); } -/// CreateCoercedLoad - Create a load from \arg SrcPtr interpreted as -/// a pointer to an object of type \arg Ty. -/// -/// This safely handles the case when the src type is smaller than the -/// destination type; in this situation the values of bits which not -/// present in the src are undefined. -static llvm::Value *CreateCoercedLoad(llvm::Value *SrcPtr, - const llvm::Type *Ty, - CodeGenFunction &CGF) { - const llvm::Type *SrcTy = - cast(SrcPtr->getType())->getElementType(); - uint64_t SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy); - uint64_t DstSize = CGF.CGM.getTargetData().getTypePaddedSize(Ty); - - // If load is legal, just bitcase the src pointer. - if (SrcSize == DstSize) { - llvm::Value *Casted = - CGF.Builder.CreateBitCast(SrcPtr, llvm::PointerType::getUnqual(Ty)); - return CGF.Builder.CreateLoad(Casted); - } else { - assert(SrcSize < DstSize && "Coercion is losing source bits!"); - - // Otherwise do coercion through memory. This is stupid, but - // simple. - llvm::Value *Tmp = CGF.CreateTempAlloca(Ty); - llvm::Value *Casted = - CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(SrcTy)); - CGF.Builder.CreateStore(CGF.Builder.CreateLoad(SrcPtr), Casted); - return CGF.Builder.CreateLoad(Tmp); - } -} - -/// CreateCoercedStore - Create a store to \arg DstPtr from \arg Src, -/// where the source and destination may have different types. -/// -/// This safely handles the case when the src type is larger than the -/// destination type; the upper bits of the src will be lost. -static void CreateCoercedStore(llvm::Value *Src, - llvm::Value *DstPtr, - CodeGenFunction &CGF) { - const llvm::Type *SrcTy = Src->getType(); - const llvm::Type *DstTy = - cast(DstPtr->getType())->getElementType(); - - uint64_t SrcSize = CGF.CGM.getTargetData().getTypePaddedSize(SrcTy); - uint64_t DstSize = CGF.CGM.getTargetData().getTypePaddedSize(DstTy); - - // If store is legal, just bitcase the src pointer. - if (SrcSize == DstSize) { - llvm::Value *Casted = - CGF.Builder.CreateBitCast(DstPtr, llvm::PointerType::getUnqual(SrcTy)); - CGF.Builder.CreateStore(Src, Casted); - } else { - assert(SrcSize > DstSize && "Coercion is missing bits!"); - - // Otherwise do coercion through memory. This is stupid, but - // simple. - llvm::Value *Tmp = CGF.CreateTempAlloca(SrcTy); - CGF.Builder.CreateStore(Src, Tmp); - llvm::Value *Casted = - CGF.Builder.CreateBitCast(Tmp, llvm::PointerType::getUnqual(DstTy)); - CGF.Builder.CreateStore(CGF.Builder.CreateLoad(Casted), DstPtr); - } -} - void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, llvm::Value *ReturnValue) { llvm::Value *RV = 0; -- GitLab From 9ff3d9a1b479c7b12b75bc054cfe983955e5353b Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Mon, 2 Feb 2009 19:22:02 +0000 Subject: [PATCH 628/682] Update hand-crafted VC++ build. - Add PACKAGE_STRING definition to Windows config.h. llvm-svn: 63539 --- llvm/win32/config.h | 1 + 1 file changed, 1 insertion(+) diff --git a/llvm/win32/config.h b/llvm/win32/config.h index 90958169f24f..62d4c05d62a9 100644 --- a/llvm/win32/config.h +++ b/llvm/win32/config.h @@ -3,6 +3,7 @@ #define PACKAGE_NAME "LLVM (win32 vc8.0)" #define PACKAGE_VERSION 2.4 +#define PACKAGE_STRING "llvm 2.6svn" #define LLVM_HOSTTRIPLE "i686-pc-win32" #define HAVE_WINDOWS_H 1 #define HAVE_LIMITS_H 1 -- GitLab From dab7be8774b2d9052949e7d5ffce2dc30326f27e Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Mon, 2 Feb 2009 19:46:41 +0000 Subject: [PATCH 629/682] Remove trailing spaces. llvm-svn: 63540 --- .../CodeGen/SelectionDAG/LegalizeFloatTypes.cpp | 10 +++++----- .../CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp | 14 +++++++------- .../CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp | 6 +++--- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp index 648e9e6302c3..53a252baa4b8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeFloatTypes.cpp @@ -851,7 +851,7 @@ void DAGTypeLegalizer::ExpandFloatRes_FDIV(SDNode *N, SDValue &Lo, RTLIB::DIV_F64, RTLIB::DIV_F80, RTLIB::DIV_PPCF128), - N->getValueType(0), Ops, 2, false, + N->getValueType(0), Ops, 2, false, N->getDebugLoc()); assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); @@ -932,7 +932,7 @@ void DAGTypeLegalizer::ExpandFloatRes_FMUL(SDNode *N, SDValue &Lo, RTLIB::MUL_F64, RTLIB::MUL_F80, RTLIB::MUL_PPCF128), - N->getValueType(0), Ops, 2, false, + N->getValueType(0), Ops, 2, false, N->getDebugLoc()); assert(Call.getNode()->getOpcode() == ISD::BUILD_PAIR && "Call lowered wrongly!"); @@ -1148,7 +1148,7 @@ void DAGTypeLegalizer::ExpandFloatRes_XINT_TO_FP(SDNode *N, SDValue &Lo, Lo = DAG.getNode(ISD::FADD, dl, VT, Hi, DAG.getConstantFP(APFloat(APInt(128, 2, Parts)), MVT::ppcf128)); - Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), + Lo = DAG.getNode(ISD::SELECT_CC, dl, VT, Src, DAG.getConstant(0, SrcVT), Lo, Hi, DAG.getCondCode(ISD::SETLT)); Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(1)); Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, NVT, Lo, DAG.getIntPtrConstant(0)); @@ -1275,7 +1275,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_ROUND(SDNode *N) { SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { MVT RVT = N->getValueType(0); DebugLoc dl = N->getDebugLoc(); - + // Expand ppcf128 to i32 by hand for the benefit of llvm-gcc bootstrap on // PPC (the libcall is not available). FIXME: Do this in a less hacky way. if (RVT == MVT::i32) { @@ -1283,7 +1283,7 @@ SDValue DAGTypeLegalizer::ExpandFloatOp_FP_TO_SINT(SDNode *N) { "Logic only correct for ppcf128!"); SDValue Res = DAG.getNode(ISD::FP_ROUND_INREG, dl, MVT::ppcf128, N->getOperand(0), DAG.getValueType(MVT::f64)); - Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, + Res = DAG.getNode(ISD::FP_ROUND, dl, MVT::f64, Res, DAG.getIntPtrConstant(1)); return DAG.getNode(ISD::FP_TO_SINT, dl, MVT::i32, Res); } diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index e4d111843d08..f803cb5a64dc 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -137,7 +137,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_AssertZext(SDNode *N) { SDValue DAGTypeLegalizer::PromoteIntRes_Atomic1(AtomicSDNode *N) { SDValue Op2 = GetPromotedInteger(N->getOperand(2)); - SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), + SDValue Res = DAG.getAtomic(N->getOpcode(), N->getDebugLoc(), N->getMemoryVT(), N->getChain(), N->getBasePtr(), Op2, N->getSrcValue(), N->getAlignment()); @@ -176,7 +176,7 @@ SDValue DAGTypeLegalizer::PromoteIntRes_BIT_CONVERT(SDNode *N) { case PromoteInteger: if (NOutVT.bitsEq(NInVT)) // The input promotes to the same size. Convert the promoted value. - return DAG.getNode(ISD::BIT_CONVERT, dl, + return DAG.getNode(ISD::BIT_CONVERT, dl, NOutVT, GetPromotedInteger(InOp)); break; case SoftenFloat: @@ -1047,7 +1047,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, Lo = Hi = DAG.getConstant(0, NVT); } else if (Amt > NVTBits) { Lo = DAG.getConstant(0, NVT); - Hi = DAG.getNode(ISD::SHL, dl, + Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Amt-NVTBits,ShTy)); } else if (Amt == NVTBits) { Lo = DAG.getConstant(0, NVT); @@ -1077,7 +1077,7 @@ void DAGTypeLegalizer::ExpandShiftByConstant(SDNode *N, unsigned Amt, Lo = DAG.getConstant(0, NVT); Hi = DAG.getConstant(0, NVT); } else if (Amt > NVTBits) { - Lo = DAG.getNode(ISD::SRL, dl, + Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Amt-NVTBits,ShTy)); Hi = DAG.getConstant(0, NVT); } else if (Amt == NVTBits) { @@ -1550,7 +1550,7 @@ void DAGTypeLegalizer::ExpandIntRes_LOAD(LoadSDNode *N, DAG.getConstant(ExcessBits, TLI.getPointerTy()))); // Move high bits to the right position in Hi. - Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, + Hi = DAG.getNode(ExtType == ISD::SEXTLOAD ? ISD::SRA : ISD::SRL, dl, NVT, Hi, DAG.getConstant(NVT.getSizeInBits() - ExcessBits, TLI.getPointerTy())); @@ -1986,7 +1986,7 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) { if (RHSCST->isAllOnesValue()) { // Equality comparison to -1. - NewLHS = DAG.getNode(ISD::AND, dl, + NewLHS = DAG.getNode(ISD::AND, dl, LHSLo.getValueType(), LHSLo, LHSHi); NewRHS = RHSLo; return; @@ -2262,7 +2262,7 @@ SDValue DAGTypeLegalizer::ExpandIntOp_UINT_TO_FP(SDNode *N) { // Check whether the sign bit is set. SDValue Lo, Hi; GetExpandedInteger(Op, Lo, Hi); - SDValue SignSet = DAG.getSetCC(dl, + SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Hi.getValueType()), Hi, DAG.getConstant(0, Hi.getValueType()), ISD::SETLT); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp index e1e539acd0af..916e9c6845b7 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeTypesGeneric.cpp @@ -187,7 +187,7 @@ void DAGTypeLegalizer::ExpandRes_NormalLoad(SDNode *N, SDValue &Lo, unsigned IncrementSize = NVT.getSizeInBits() / 8; Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), + Hi = DAG.getLoad(NVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset+IncrementSize, isVolatile, MinAlign(Alignment, IncrementSize)); @@ -306,7 +306,7 @@ SDValue DAGTypeLegalizer::ExpandOp_INSERT_VECTOR_ELT(SDNode *N) { // Bitconvert to a vector of twice the length with elements of the expanded // type, insert the expanded vector elements, and then convert back. MVT NewVecVT = MVT::getVectorVT(NewEVT, NumElts*2); - SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, + SDValue NewVec = DAG.getNode(ISD::BIT_CONVERT, dl, NewVecVT, N->getOperand(0)); SDValue Lo, Hi; @@ -365,7 +365,7 @@ SDValue DAGTypeLegalizer::ExpandOp_NormalStore(SDNode *N, unsigned OpNo) { Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Ptr.getValueType()) && "Pointers must be legal!"); - Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(), + Hi = DAG.getStore(Chain, dl, Hi, Ptr, St->getSrcValue(), SVOffset + IncrementSize, isVolatile, MinAlign(Alignment, IncrementSize)); -- GitLab From 9f84b78ac13940c0e11b18fec0e67351769c7c2b Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Mon, 2 Feb 2009 20:02:29 +0000 Subject: [PATCH 630/682] Refactored code gen for ivar access in preparation for objc2 nonfragile ivar access code gen. llvm-svn: 63541 --- clang/lib/CodeGen/CGExpr.cpp | 3 ++- clang/lib/CodeGen/CGObjCGNU.cpp | 16 ++++++++++++++++ clang/lib/CodeGen/CGObjCMac.cpp | 26 ++++++++++++++++++++++++++ clang/lib/CodeGen/CGObjCRuntime.h | 7 +++++++ 4 files changed, 51 insertions(+), 1 deletion(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5c304d19a579..726755dc84ca 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1034,7 +1034,8 @@ LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue, return EmitLValueForBitfield(BaseValue, const_cast(Field), CVRQualifiers, Index); } - llvm::Value *V = Builder.CreateStructGEP(BaseValue, Index, "tmp"); + llvm::Value *V = CGM.getObjCRuntime().EmitObjCValueForIvar(*this, + BaseValue, Ivar, Field, CVRQualifiers); LValue LV = LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers); SetVarDeclObjCAttribute(getContext(), Ivar, Ivar->getType(), LV); LValue::SetObjCIvar(LV, true); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 10ceee9c6b20..bfe92b303efd 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -140,6 +140,11 @@ public: llvm::Value *src, llvm::Value *dest); virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); + virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers); }; } // end anonymous namespace @@ -1028,6 +1033,17 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, return; } +llvm::Value *CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers) { + // TODO: Add a special case for isa (index 0) + unsigned Index = CGM.getTypes().getLLVMFieldNo(Field); + llvm::Value *V = CGF.Builder.CreateStructGEP(BaseValue, Index, "tmp"); + return V; +} + CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){ return new CGObjCGNU(CGM); } diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 23d62097e64c..1bea633589ca 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -549,6 +549,12 @@ private: llvm::Value *src, llvm::Value *dest); virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); + + virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers); }; class CGObjCNonFragileABIMac : public CGObjCCommonMac { @@ -669,6 +675,13 @@ public: virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest) { return; } + virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers) + { return 0; } + }; } // end anonymous namespace @@ -2097,6 +2110,19 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, return; } +/// EmitObjCValueForIvar - Code Gen for ivar reference. +/// +llvm::Value *CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers) { + // TODO: Add a special case for isa (index 0) + unsigned Index = CGM.getTypes().getLLVMFieldNo(Field); + llvm::Value *V = CGF.Builder.CreateStructGEP(BaseValue, Index, "tmp"); + return V; +} + /* *** Private Interface *** */ /// EmitImageInfo - Emit the image info marker used to encode some module diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index 01543c53e24f..ded1db2c0b13 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -47,6 +47,7 @@ namespace CodeGen { class ObjCMethodDecl; class ObjCProtocolDecl; class Selector; + class ObjCIvarDecl; namespace CodeGen { class CodeGenModule; @@ -155,6 +156,12 @@ public: llvm::Value *src, llvm::Value *dest) = 0; virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest) = 0; + + virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers) = 0; }; /// Creates an instance of an Objective-C runtime class. -- GitLab From 5dbd26ae0f6b728b9a708ed5e3efaa14bd1f0df3 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Mon, 2 Feb 2009 20:23:02 +0000 Subject: [PATCH 631/682] remove #if 0 code on Bill's request. llvm-svn: 63542 --- llvm/lib/Target/X86/X86Subtarget.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index ff7f72be134c..99708e04cf9c 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -331,10 +331,6 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // are enabled. These are available on all x86-64 CPUs. if (Is64Bit) { HasX86_64 = true; -#if 0 - if (X86SSELevel < SSE2) - X86SSELevel = SSE2; -#endif } DOUT << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel -- GitLab From ad00f6e01082e19252769d2ac4b6d0444934d0c8 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 2 Feb 2009 20:41:04 +0000 Subject: [PATCH 632/682] More DebugLoc propagation. llvm-svn: 63543 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 236 ++++++++++-------- 1 file changed, 127 insertions(+), 109 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index f7376ec30746..4c49724bb7d6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -169,7 +169,7 @@ private: /// is necessary to spill the vector being inserted into to memory, perform /// the insert there, and then read the result back. SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, - SDValue Idx); + SDValue Idx, DebugLoc dl); /// PromoteOp - Given an operation that produces a value in an invalid type, /// promote it to compute the value into a larger type. The produced value @@ -273,11 +273,14 @@ private: bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, SmallPtrSet &NodesLeadingTo); - void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC); - void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC); - void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC) { - LegalizeSetCCOperands(LHS, RHS, CC); - LegalizeSetCCCondCode(VT, LHS, RHS, CC); + void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC, + DebugLoc dl); + void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, + DebugLoc dl); + void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, + DebugLoc dl) { + LegalizeSetCCOperands(LHS, RHS, CC, dl); + LegalizeSetCCCondCode(VT, LHS, RHS, CC, dl); } SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned, @@ -337,14 +340,16 @@ SDNode *SelectionDAGLegalize::isShuffleLegal(MVT VT, SDValue Mask) const { SDValue InOp = Mask.getOperand(i); for (unsigned j = 0; j != NumEltsGrowth; ++j) { if (InOp.getOpcode() == ISD::UNDEF) - Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, + InOp.getNode()->getDebugLoc(), EltVT)); else { unsigned InEltNo = cast(InOp)->getZExtValue(); Ops.push_back(DAG.getConstant(InEltNo*NumEltsGrowth+j, EltVT)); } } } - Mask = DAG.getNode(ISD::BUILD_VECTOR, NVT, &Ops[0], Ops.size()); + Mask = DAG.getNode(ISD::BUILD_VECTOR, Mask.getNode()->getDebugLoc(), + NVT, &Ops[0], Ops.size()); } VT = NVT; break; @@ -594,6 +599,7 @@ static SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT, SelectionDAG &DAG, const TargetLowering &TLI) { + DebugLoc dl = Node->getDebugLoc(); MVT VT = Node->getValueType(0); MVT SrcVT = Node->getOperand(1).getValueType(); assert((SrcVT == MVT::f32 || SrcVT == MVT::f64) && @@ -604,18 +610,19 @@ SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT, SDValue Mask1 = (SrcVT == MVT::f64) ? DAG.getConstantFP(BitsToDouble(1ULL << 63), SrcVT) : DAG.getConstantFP(BitsToFloat(1U << 31), SrcVT); - Mask1 = DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Mask1); - SDValue SignBit= DAG.getNode(ISD::BIT_CONVERT, SrcNVT, Node->getOperand(1)); - SignBit = DAG.getNode(ISD::AND, SrcNVT, SignBit, Mask1); + Mask1 = DAG.getNode(ISD::BIT_CONVERT, dl, SrcNVT, Mask1); + SDValue SignBit= DAG.getNode(ISD::BIT_CONVERT, dl, SrcNVT, + Node->getOperand(1)); + SignBit = DAG.getNode(ISD::AND, dl, SrcNVT, SignBit, Mask1); // Shift right or sign-extend it if the two operands have different types. int SizeDiff = SrcNVT.getSizeInBits() - NVT.getSizeInBits(); if (SizeDiff > 0) { - SignBit = DAG.getNode(ISD::SRL, SrcNVT, SignBit, + SignBit = DAG.getNode(ISD::SRL, dl, SrcNVT, SignBit, DAG.getConstant(SizeDiff, TLI.getShiftAmountTy())); - SignBit = DAG.getNode(ISD::TRUNCATE, NVT, SignBit); + SignBit = DAG.getNode(ISD::TRUNCATE, dl, NVT, SignBit); } else if (SizeDiff < 0) { - SignBit = DAG.getNode(ISD::ZERO_EXTEND, NVT, SignBit); - SignBit = DAG.getNode(ISD::SHL, NVT, SignBit, + SignBit = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, SignBit); + SignBit = DAG.getNode(ISD::SHL, dl, NVT, SignBit, DAG.getConstant(-SizeDiff, TLI.getShiftAmountTy())); } @@ -623,12 +630,12 @@ SDValue ExpandFCOPYSIGNToBitwiseOps(SDNode *Node, MVT NVT, SDValue Mask2 = (VT == MVT::f64) ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT) : DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT); - Mask2 = DAG.getNode(ISD::BIT_CONVERT, NVT, Mask2); - SDValue Result = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0)); - Result = DAG.getNode(ISD::AND, NVT, Result, Mask2); + Mask2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask2); + SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0)); + Result = DAG.getNode(ISD::AND, dl, NVT, Result, Mask2); // Or the value with the sign bit. - Result = DAG.getNode(ISD::OR, NVT, Result, SignBit); + Result = DAG.getNode(ISD::OR, dl, NVT, Result, SignBit); return Result; } @@ -642,6 +649,7 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, MVT VT = Val.getValueType(); int Alignment = ST->getAlignment(); int SVOffset = ST->getSrcValueOffset(); + DebugLoc dl = ST->getDebugLoc(); if (ST->getMemoryVT().isFloatingPoint() || ST->getMemoryVT().isVector()) { MVT intVT = MVT::getIntegerVT(VT.getSizeInBits()); @@ -649,8 +657,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // Expand to a bitconvert of the value to the integer type of the // same size, then a (misaligned) int store. // FIXME: Does not handle truncating floating point stores! - SDValue Result = DAG.getNode(ISD::BIT_CONVERT, intVT, Val); - return DAG.getStore(Chain, Result, Ptr, ST->getSrcValue(), + SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, intVT, Val); + return DAG.getStore(Chain, dl, Result, Ptr, ST->getSrcValue(), SVOffset, ST->isVolatile(), Alignment); } else { // Do a (aligned) store to a stack slot, then copy from the stack slot @@ -666,7 +674,8 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT); // Perform the original store, only redirected to the stack slot. - SDValue Store = DAG.getTruncStore(Chain, Val, StackPtr, NULL, 0,StoredVT); + SDValue Store = DAG.getTruncStore(Chain, dl, + Val, StackPtr, NULL, 0,StoredVT); SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); SmallVector Stores; unsigned Offset = 0; @@ -674,17 +683,17 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // Do all but one copies using the full register width. for (unsigned i = 1; i < NumRegs; i++) { // Load one integer register's worth from the stack slot. - SDValue Load = DAG.getLoad(RegVT, Store, StackPtr, NULL, 0); + SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0); // Store it to the final location. Remember the store. - Stores.push_back(DAG.getStore(Load.getValue(1), Load, Ptr, + Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr, ST->getSrcValue(), SVOffset + Offset, ST->isVolatile(), MinAlign(ST->getAlignment(), Offset))); // Increment the pointers. Offset += RegBytes; - StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr, + StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, Increment); - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Increment); + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); } // The last store may be partial. Do a truncating store. On big-endian @@ -693,15 +702,15 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, MVT MemVT = MVT::getIntegerVT(8 * (StoredBytes - Offset)); // Load from the stack slot. - SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, RegVT, Store, StackPtr, + SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr, NULL, 0, MemVT); - Stores.push_back(DAG.getTruncStore(Load.getValue(1), Load, Ptr, + Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr, ST->getSrcValue(), SVOffset + Offset, MemVT, ST->isVolatile(), MinAlign(ST->getAlignment(), Offset))); // The order of the stores doesn't matter - say it with a TokenFactor. - return DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], Stores.size()); } } @@ -717,21 +726,21 @@ SDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, // Divide the stored value in two parts. SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy()); SDValue Lo = Val; - SDValue Hi = DAG.getNode(ISD::SRL, VT, Val, ShiftAmount); + SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount); // Store the two parts SDValue Store1, Store2; - Store1 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Lo:Hi, Ptr, + Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr, ST->getSrcValue(), SVOffset, NewStoredVT, ST->isVolatile(), Alignment); - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); Alignment = MinAlign(Alignment, IncrementSize); - Store2 = DAG.getTruncStore(Chain, TLI.isLittleEndian()?Hi:Lo, Ptr, + Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr, ST->getSrcValue(), SVOffset + IncrementSize, NewStoredVT, ST->isVolatile(), Alignment); - return DAG.getNode(ISD::TokenFactor, MVT::Other, Store1, Store2); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); } /// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads. @@ -743,20 +752,21 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, SDValue Ptr = LD->getBasePtr(); MVT VT = LD->getValueType(0); MVT LoadedVT = LD->getMemoryVT(); + DebugLoc dl = LD->getDebugLoc(); if (VT.isFloatingPoint() || VT.isVector()) { MVT intVT = MVT::getIntegerVT(LoadedVT.getSizeInBits()); if (TLI.isTypeLegal(intVT)) { // Expand to a (misaligned) integer load of the same size, // then bitconvert to floating point or vector. - SDValue newLoad = DAG.getLoad(intVT, Chain, Ptr, LD->getSrcValue(), + SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset, LD->isVolatile(), LD->getAlignment()); - SDValue Result = DAG.getNode(ISD::BIT_CONVERT, LoadedVT, newLoad); + SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, LoadedVT, newLoad); if (VT.isFloatingPoint() && LoadedVT != VT) - Result = DAG.getNode(ISD::FP_EXTEND, VT, Result); + Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result); SDValue Ops[] = { Result, Chain }; - return DAG.getMergeValues(Ops, 2); + return DAG.getMergeValues(Ops, 2, dl); } else { // Copy the value to a (aligned) stack slot using (unaligned) integer // loads and stores, then do a (aligned) load from the stack slot. @@ -776,42 +786,42 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, // Do all but one copies using the full register width. for (unsigned i = 1; i < NumRegs; i++) { // Load one integer register's worth from the original location. - SDValue Load = DAG.getLoad(RegVT, Chain, Ptr, LD->getSrcValue(), + SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, LD->getSrcValue(), SVOffset + Offset, LD->isVolatile(), MinAlign(LD->getAlignment(), Offset)); // Follow the load with a store to the stack slot. Remember the store. - Stores.push_back(DAG.getStore(Load.getValue(1), Load, StackPtr, + Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr, NULL, 0)); // Increment the pointers. Offset += RegBytes; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, Increment); - StackPtr = DAG.getNode(ISD::ADD, StackPtr.getValueType(), StackPtr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); + StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, Increment); } // The last copy may be partial. Do an extending load. MVT MemVT = MVT::getIntegerVT(8 * (LoadedBytes - Offset)); - SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, RegVT, Chain, Ptr, + SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr, LD->getSrcValue(), SVOffset + Offset, MemVT, LD->isVolatile(), MinAlign(LD->getAlignment(), Offset)); // Follow the load with a store to the stack slot. Remember the store. // On big-endian machines this requires a truncating store to ensure // that the bits end up in the right place. - Stores.push_back(DAG.getTruncStore(Load.getValue(1), Load, StackPtr, + Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr, NULL, 0, MemVT)); // The order of the stores doesn't matter - say it with a TokenFactor. - SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, &Stores[0], + SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], Stores.size()); // Finally, perform the original load only redirected to the stack slot. - Load = DAG.getExtLoad(LD->getExtensionType(), VT, TF, StackBase, + Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase, NULL, 0, LoadedVT); // Callers expect a MERGE_VALUES node. SDValue Ops[] = { Load, TF }; - return DAG.getMergeValues(Ops, 2); + return DAG.getMergeValues(Ops, 2, dl); } } assert(LoadedVT.isInteger() && !LoadedVT.isVector() && @@ -835,33 +845,33 @@ SDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, // Load the value in two parts SDValue Lo, Hi; if (TLI.isLittleEndian()) { - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(), + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(), SVOffset, NewLoadedVT, LD->isVolatile(), Alignment); - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); - Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), + Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), MinAlign(Alignment, IncrementSize)); } else { - Hi = DAG.getExtLoad(HiExtType, VT, Chain, Ptr, LD->getSrcValue(), SVOffset, - NewLoadedVT,LD->isVolatile(), Alignment); - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(), + SVOffset, NewLoadedVT,LD->isVolatile(), Alignment); + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getConstant(IncrementSize, TLI.getPointerTy())); - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, VT, Chain, Ptr, LD->getSrcValue(), + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(), SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), MinAlign(Alignment, IncrementSize)); } // aggregate the two parts SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy()); - SDValue Result = DAG.getNode(ISD::SHL, VT, Hi, ShiftAmount); - Result = DAG.getNode(ISD::OR, VT, Result, Lo); + SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount); + Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo); - SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); SDValue Ops[] = { Result, TF }; - return DAG.getMergeValues(Ops, 2); + return DAG.getMergeValues(Ops, 2, dl); } /// UnrollVectorOp - We know that the given vector has a legal type, however @@ -876,6 +886,7 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { "Can't unroll a vector with multiple results!"); unsigned NE = VT.getVectorNumElements(); MVT EltVT = VT.getVectorElementType(); + DebugLoc dl = Op.getNode()->getDebugLoc(); SmallVector Scalars; SmallVector Operands(Op.getNumOperands()); @@ -886,7 +897,7 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { if (OperandVT.isVector()) { // A vector operand; extract a single element. MVT OperandEltVT = OperandVT.getVectorElementType(); - Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, + Operands[j] = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, OperandEltVT, Operand, DAG.getConstant(i, MVT::i32)); @@ -898,7 +909,7 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { switch (Op.getOpcode()) { default: - Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, + Scalars.push_back(DAG.getNode(Op.getOpcode(), dl, EltVT, &Operands[0], Operands.size())); break; case ISD::SHL: @@ -906,13 +917,13 @@ SDValue SelectionDAGLegalize::UnrollVectorOp(SDValue Op) { case ISD::SRL: case ISD::ROTL: case ISD::ROTR: - Scalars.push_back(DAG.getNode(Op.getOpcode(), EltVT, Operands[0], + Scalars.push_back(DAG.getNode(Op.getOpcode(), dl, EltVT, Operands[0], DAG.getShiftAmountOperand(Operands[1]))); break; } } - return DAG.getNode(ISD::BUILD_VECTOR, VT, &Scalars[0], Scalars.size()); + return DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Scalars[0], Scalars.size()); } /// GetFPLibCall - Return the right libcall for the given floating point type. @@ -934,7 +945,8 @@ static RTLIB::Libcall GetFPLibCall(MVT VT, /// is necessary to spill the vector being inserted into to memory, perform /// the insert there, and then read the result back. SDValue SelectionDAGLegalize:: -PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) { +PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, + DebugLoc dl) { SDValue Tmp1 = Vec; SDValue Tmp2 = Val; SDValue Tmp3 = Idx; @@ -954,21 +966,21 @@ PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx) { int SPFI = cast(StackPtr.getNode())->getIndex(); // Store the vector. - SDValue Ch = DAG.getStore(DAG.getEntryNode(), Tmp1, StackPtr, + SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr, PseudoSourceValue::getFixedStack(SPFI), 0); // Truncate or zero extend offset to target pointer type. unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; - Tmp3 = DAG.getNode(CastOpc, PtrVT, Tmp3); + Tmp3 = DAG.getNode(CastOpc, dl, PtrVT, Tmp3); // Add the offset to the index. unsigned EltSize = EltVT.getSizeInBits()/8; - Tmp3 = DAG.getNode(ISD::MUL, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); - SDValue StackPtr2 = DAG.getNode(ISD::ADD, IdxVT, Tmp3, StackPtr); + Tmp3 = DAG.getNode(ISD::MUL, dl, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); + SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr); // Store the scalar value. - Ch = DAG.getTruncStore(Ch, Tmp2, StackPtr2, + Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2, PseudoSourceValue::getFixedStack(SPFI), 0, EltVT); // Load the updated vector. - return DAG.getLoad(VT, Ch, StackPtr, + return DAG.getLoad(VT, dl, Ch, StackPtr, PseudoSourceValue::getFixedStack(SPFI), 0); } @@ -1657,7 +1669,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; } } - Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3); + Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3, dl); break; } } @@ -2093,7 +2105,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp3 = Node->getOperand(3); // RHS Tmp4 = Node->getOperand(1); // CC - LegalizeSetCC(TLI.getSetCCResultType(Tmp2.getValueType()), Tmp2, Tmp3,Tmp4); + LegalizeSetCC(TLI.getSetCCResultType(Tmp2.getValueType()), + Tmp2, Tmp3, Tmp4, dl); LastCALLSEQ_END = DAG.getEntryNode(); // If we didn't get both a LHS and RHS back from LegalizeSetCC, @@ -2995,7 +3008,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp4 = LegalizeOp(Node->getOperand(3)); // False SDValue CC = Node->getOperand(4); - LegalizeSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC); + LegalizeSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), + Tmp1, Tmp2, CC, dl); // If we didn't get both a LHS and RHS back from LegalizeSetCC, // the LHS is a legal SETCC itself. In this case, we need to compare @@ -3021,7 +3035,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp1 = Node->getOperand(0); Tmp2 = Node->getOperand(1); Tmp3 = Node->getOperand(2); - LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3); + LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3, dl); // If we had to Expand the SetCC operands into a SELECT node, then it may // not always be possible to return a true LHS & RHS. In this case, just @@ -4953,6 +4967,7 @@ SDValue SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDValue Op) { // lower to a store then an indexed load. SDValue Vec = Op.getOperand(0); SDValue Idx = Op.getOperand(1); + DebugLoc dl = Op.getNode()->getDebugLoc(); MVT TVT = Vec.getValueType(); unsigned NumElems = TVT.getVectorNumElements(); @@ -5004,21 +5019,21 @@ SDValue SelectionDAGLegalize::ExpandEXTRACT_VECTOR_ELT(SDValue Op) { // Store the value to a temporary stack slot, then LOAD the scalar // element back out. SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); - SDValue Ch = DAG.getStore(DAG.getEntryNode(), Vec, StackPtr, NULL, 0); + SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); // Add the offset to the index. unsigned EltSize = Op.getValueType().getSizeInBits()/8; - Idx = DAG.getNode(ISD::MUL, Idx.getValueType(), Idx, + Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, DAG.getConstant(EltSize, Idx.getValueType())); if (Idx.getValueType().bitsGT(TLI.getPointerTy())) - Idx = DAG.getNode(ISD::TRUNCATE, TLI.getPointerTy(), Idx); + Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); else - Idx = DAG.getNode(ISD::ZERO_EXTEND, TLI.getPointerTy(), Idx); + Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); - StackPtr = DAG.getNode(ISD::ADD, Idx.getValueType(), Idx, StackPtr); + StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); - Op = DAG.getLoad(Op.getValueType(), Ch, StackPtr, NULL, 0); + Op = DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0); } return Op; } @@ -5062,7 +5077,8 @@ SDValue SelectionDAGLegalize::ExpandEXTRACT_SUBVECTOR(SDValue Op) { /// LHS, and the SDValue returned in RHS has a nil SDNode value. void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, - SDValue &CC) { + SDValue &CC, + DebugLoc dl) { SDValue Tmp1, Tmp2, Tmp3, Result; switch (getTypeAction(LHS.getValueType())) { @@ -5094,16 +5110,16 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, // ALL of these operations will work if we either sign or zero extend // the operands (including the unsigned comparisons!). Zero extend is // usually a simpler/cheaper operation, so prefer it. - Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT); - Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT); + Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT); + Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, VT); break; case ISD::SETGE: case ISD::SETGT: case ISD::SETLT: case ISD::SETLE: - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1, DAG.getValueType(VT)); - Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, + Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp2, DAG.getValueType(VT)); Tmp1 = LegalizeOp(Tmp1); // Relegalize new nodes. Tmp2 = LegalizeOp(Tmp2); // Relegalize new nodes. @@ -5175,20 +5191,20 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, SDValue Dummy; SDValue Ops[2] = { LHS, RHS }; - Tmp1 = ExpandLibCall(LC1, DAG.getMergeValues(Ops, 2).getNode(), + Tmp1 = ExpandLibCall(LC1, DAG.getMergeValues(Ops, 2, dl).getNode(), false /*sign irrelevant*/, Dummy); Tmp2 = DAG.getConstant(0, MVT::i32); CC = DAG.getCondCode(TLI.getCmpLibcallCC(LC1)); if (LC2 != RTLIB::UNKNOWN_LIBCALL) { - Tmp1 = DAG.getNode(ISD::SETCC, + Tmp1 = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, CC); - LHS = ExpandLibCall(LC2, DAG.getMergeValues(Ops, 2).getNode(), + LHS = ExpandLibCall(LC2, DAG.getMergeValues(Ops, 2, dl).getNode(), false /*sign irrelevant*/, Dummy); - Tmp2 = DAG.getNode(ISD::SETCC, + Tmp2 = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(LHS.getValueType()), LHS, Tmp2, DAG.getCondCode(TLI.getCmpLibcallCC(LC2))); - Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp1 = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp2); Tmp2 = SDValue(); } LHS = LegalizeOp(Tmp1); @@ -5207,17 +5223,17 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, // BNE crN, L: // FCMPU crN, lo1, lo2 // The following can be improved, but not that much. - Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETOEQ); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()), + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, CCCode); - Tmp3 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp3 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETUNE); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, CCCode); - Tmp1 = DAG.getNode(ISD::AND, Tmp1.getValueType(), Tmp1, Tmp2); - Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp3); + Tmp1 = DAG.getNode(ISD::AND, dl, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp1 = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp3); Tmp2 = SDValue(); break; } @@ -5229,14 +5245,14 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, if (ConstantSDNode *RHSCST = dyn_cast(RHSLo)) if (RHSCST->isAllOnesValue()) { // Comparison to -1. - Tmp1 = DAG.getNode(ISD::AND, LHSLo.getValueType(), LHSLo, LHSHi); + Tmp1 = DAG.getNode(ISD::AND, dl,LHSLo.getValueType(), LHSLo, LHSHi); Tmp2 = RHSLo; break; } - Tmp1 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSLo, RHSLo); - Tmp2 = DAG.getNode(ISD::XOR, LHSLo.getValueType(), LHSHi, RHSHi); - Tmp1 = DAG.getNode(ISD::OR, Tmp1.getValueType(), Tmp1, Tmp2); + Tmp1 = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSLo, RHSLo); + Tmp2 = DAG.getNode(ISD::XOR, dl, LHSLo.getValueType(), LHSHi, RHSHi); + Tmp1 = DAG.getNode(ISD::OR, dl, Tmp1.getValueType(), Tmp1, Tmp2); Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); break; default: @@ -5276,12 +5292,12 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, LowCC, false, DagCombineInfo); if (!Tmp1.getNode()) - Tmp1 = DAG.getSetCC(TLI.getSetCCResultType(LHSLo.getValueType()), + Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, LowCC); Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, CCCode, false, DagCombineInfo); if (!Tmp2.getNode()) - Tmp2 = DAG.getNode(ISD::SETCC, + Tmp2 = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi,CC); @@ -5304,9 +5320,9 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, LHSHi, RHSHi, ISD::SETEQ, false, DagCombineInfo); if (!Result.getNode()) - Result=DAG.getSetCC(TLI.getSetCCResultType(LHSHi.getValueType()), + Result=DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETEQ); - Result = LegalizeOp(DAG.getNode(ISD::SELECT, Tmp1.getValueType(), + Result = LegalizeOp(DAG.getNode(ISD::SELECT, dl, Tmp1.getValueType(), Result, Tmp1, Tmp2)); Tmp1 = Result; Tmp2 = SDValue(); @@ -5324,7 +5340,8 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, /// illegal condition code into AND / OR of multiple SETCC values. void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, - SDValue &CC) { + SDValue &CC, + DebugLoc dl) { MVT OpVT = LHS.getValueType(); ISD::CondCode CCCode = cast(CC)->get(); switch (TLI.getCondCodeAction(CCCode, OpVT)) { @@ -5352,9 +5369,9 @@ void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT, // FIXME: Implement more expansions. } - SDValue SetCC1 = DAG.getSetCC(VT, LHS, RHS, CC1); - SDValue SetCC2 = DAG.getSetCC(VT, LHS, RHS, CC2); - LHS = DAG.getNode(Opc, VT, SetCC1, SetCC2); + SDValue SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1); + SDValue SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2); + LHS = DAG.getNode(Opc, dl, VT, SetCC1, SetCC2); RHS = SDValue(); CC = SDValue(); break; @@ -7413,6 +7430,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue &Hi) { assert(Op.getValueType().isVector() && "Cannot split non-vector type!"); SDNode *Node = Op.getNode(); + DebugLoc dl = Node->getDebugLoc(); unsigned NumElements = Op.getValueType().getVectorNumElements(); assert(NumElements > 1 && "Cannot split a single element vector!"); @@ -7462,7 +7480,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, } SDValue Tmp = PerformInsertVectorEltInMemory(Node->getOperand(0), Node->getOperand(1), - Node->getOperand(2)); + Node->getOperand(2), dl); SplitVectorOp(Tmp, Lo, Hi); break; } -- GitLab From 43cecd7c261d679d3da4ae0584f0768ec397ff5f Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Mon, 2 Feb 2009 20:44:45 +0000 Subject: [PATCH 633/682] inline SROA::ConvertToScalar, no functionality change. llvm-svn: 63544 --- .../Scalar/ScalarReplAggregates.cpp | 34 ++++++++----------- 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 0765e12876b8..012769568d33 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -127,7 +127,6 @@ namespace { bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&ResTy, uint64_t Offset); - void ConvertToScalar(AllocationInst *AI, const Type *Ty); void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset); Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, uint64_t Offset); @@ -269,6 +268,8 @@ bool SROA::performScalarRepl(Function &F) { Changed = true; continue; } + + // If we can turn this aggregate value (potentially with casts) into a // simple scalar value that can be mem2reg'd into a register value. @@ -277,11 +278,18 @@ bool SROA::performScalarRepl(Function &F) { // that we can't just check based on the type: the alloca may be of an i32 // but that has pointer arithmetic to set byte 3 of it or something. bool IsNotTrivial = false; - const Type *ActualType = 0; - if (CanConvertToScalar(AI, IsNotTrivial, ActualType, 0)) - if (IsNotTrivial && ActualType && - TD->getTypeSizeInBits(ActualType) < SRThreshold*8) { - ConvertToScalar(AI, ActualType); + const Type *ActualTy = 0; + if (CanConvertToScalar(AI, IsNotTrivial, ActualTy, 0)) + if (IsNotTrivial && ActualTy && + TD->getTypeSizeInBits(ActualTy) < SRThreshold*8) { + DOUT << "CONVERT TO SCALAR: " << *AI << " TYPE = " << *ActualTy <<"\n"; + ++NumConverted; + + // Create and insert the alloca. + AllocaInst *NewAI = new AllocaInst(ActualTy, 0, AI->getName(), + AI->getParent()->begin()); + ConvertUsesToScalar(AI, NewAI, 0); + AI->eraseFromParent(); Changed = true; continue; } @@ -1263,20 +1271,6 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, return true; } -/// ConvertToScalar - The specified alloca passes the CanConvertToScalar -/// predicate and is non-trivial. Convert it to something that can be trivially -/// promoted into a register by mem2reg. -void SROA::ConvertToScalar(AllocationInst *AI, const Type *ActualTy) { - DOUT << "CONVERT TO SCALAR: " << *AI << " TYPE = " << *ActualTy << "\n"; - ++NumConverted; - - // Create and insert the alloca. - AllocaInst *NewAI = new AllocaInst(ActualTy, 0, AI->getName(), - AI->getParent()->begin()); - ConvertUsesToScalar(AI, NewAI, 0); - AI->eraseFromParent(); -} - /// ConvertUsesToScalar - Convert all of the users of Ptr to use the new alloca /// directly. This happens when we are converting an "integer union" to a -- GitLab From ae7992a33387aab4e26045b5672681a041902c6d Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 2 Feb 2009 20:47:48 +0000 Subject: [PATCH 634/682] Commit missing files. llvm-svn: 63545 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 1 + llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 14 ++++++++++++++ 2 files changed, 15 insertions(+) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index 4937df79b999..d6039120f931 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -568,6 +568,7 @@ public: /// getMergeValues - Create a MERGE_VALUES node from the given operands. SDValue getMergeValues(const SDValue *Ops, unsigned NumOps); + SDValue getMergeValues(const SDValue *Ops, unsigned NumOps, DebugLoc dl); /// getCall - Create a CALL node from the given information. /// diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index d8f895dac2f2..32f55439ec64 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -3547,6 +3547,20 @@ SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps) { return getNode(ISD::MERGE_VALUES, getVTList(&VTs[0], NumOps), Ops, NumOps); } +/// DebugLoc-aware version. +SDValue SelectionDAG::getMergeValues(const SDValue *Ops, unsigned NumOps, + DebugLoc dl) { + if (NumOps == 1) + return Ops[0]; + + SmallVector VTs; + VTs.reserve(NumOps); + for (unsigned i = 0; i < NumOps; ++i) + VTs.push_back(Ops[i].getValueType()); + return getNode(ISD::MERGE_VALUES, dl, getVTList(&VTs[0], NumOps), + Ops, NumOps); +} + SDValue SelectionDAG::getMemIntrinsicNode(unsigned Opcode, const MVT *VTs, unsigned NumVTs, -- GitLab From bb70c08c8d389d7fb68be37a0c510b08a326ef6f Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 2 Feb 2009 20:52:40 +0000 Subject: [PATCH 635/682] AnalysisConsumer: - Pass "Actions" vector by reference. - Remove guard against checking macro-generated code. llvm-svn: 63546 --- clang/Driver/AnalysisConsumer.cpp | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/clang/Driver/AnalysisConsumer.cpp b/clang/Driver/AnalysisConsumer.cpp index 171ffbf2df66..49ebde71c8f6 100644 --- a/clang/Driver/AnalysisConsumer.cpp +++ b/clang/Driver/AnalysisConsumer.cpp @@ -124,7 +124,7 @@ namespace { virtual void HandleTopLevelDecl(Decl *D); virtual void HandleTranslationUnit(TranslationUnit &TU); - void HandleCode(Decl* D, Stmt* Body, Actions actions); + void HandleCode(Decl* D, Stmt* Body, Actions& actions); }; @@ -365,21 +365,15 @@ void AnalysisConsumer::HandleTranslationUnit(TranslationUnit& TU) { } } -void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions actions) { +void AnalysisConsumer::HandleCode(Decl* D, Stmt* Body, Actions& actions) { // Don't run the actions if an error has occured with parsing the file. if (Diags.hasErrorOccurred()) return; - - SourceLocation Loc = D->getLocation(); - - // Only run actions on declarations defined in actual source. - if (!Loc.isFileID()) - return; - + // Don't run the actions on declarations in header files unless // otherwise specified. - if (!AnalyzeAll && !Ctx->getSourceManager().isFromMainFile(Loc)) + if (!AnalyzeAll && !Ctx->getSourceManager().isFromMainFile(D->getLocation())) return; // Create an AnalysisManager that will manage the state for analyzing -- GitLab From dd5dbca59c708cf84913e08b6187c000259157de Mon Sep 17 00:00:00 2001 From: Devang Patel Date: Mon, 2 Feb 2009 21:09:36 +0000 Subject: [PATCH 636/682] Run dsymutil on darwin, when it is expected, before running gdb test. llvm-svn: 63548 --- llvm/test/FrontendC++/2006-11-30-Pubnames.cpp | 1 + llvm/test/Makefile | 8 ++++++++ llvm/test/lib/llvm.exp | 4 +++- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp b/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp index 5dd1439224ce..8af99e37c989 100644 --- a/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp +++ b/llvm/test/FrontendC++/2006-11-30-Pubnames.cpp @@ -4,6 +4,7 @@ // RUN: llc --disable-fp-elim -o %t.s -f // RUN: %compile_c %t.s -o %t.o // RUN: %link %t.o -o %t.exe +// RUN: %llvmdsymutil %t.exe // RUN: echo {break main\nrun\np Pubnames::pubname} > %t.in // RUN: gdb -q -batch -n -x %t.in %t.exe | tee %t.out | grep {\$1 = 10} // XFAIL: alpha|ia64|arm diff --git a/llvm/test/Makefile b/llvm/test/Makefile index b6067c372fae..7ce4086f1af4 100644 --- a/llvm/test/Makefile +++ b/llvm/test/Makefile @@ -81,6 +81,13 @@ endif clean:: $(RM) -rf `find $(LLVM_OBJ_ROOT)/test -name Output -type d -print` +# dsymutil is used on the Darwin to manipulate DWARF debugging information. +ifeq ($(OS),Darwin) +DSYMUTIL=dsymutil +else +DSYMUTIL=true +endif + FORCE: site.exp: FORCE @@ -112,6 +119,7 @@ site.exp: FORCE @echo 'set valgrind "$(VALGRIND)"' >> site.tmp @echo 'set grep "$(GREP)"' >>site.tmp @echo 'set gas "$(GAS)"' >>site.tmp + @echo 'set llvmdsymutil "$(DSYMUTIL)"' >>site.tmp @echo '## All variables above are generated by configure. Do Not Edit ## ' >>site.tmp @test ! -f site.exp || \ sed '1,/^## All variables above are.*##/ d' site.exp >> site.tmp diff --git a/llvm/test/lib/llvm.exp b/llvm/test/lib/llvm.exp index b5d5cffae1e0..ab8522ab6a28 100644 --- a/llvm/test/lib/llvm.exp +++ b/llvm/test/lib/llvm.exp @@ -48,7 +48,7 @@ proc execOneLine { test PRS outcome lineno line } { proc substitute { line test tmpFile } { global srcroot objroot srcdir objdir subdir target_triplet prcontext global llvmgcc llvmgxx llvmgcc_version llvmgccmajvers ocamlc - global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir + global gccpath gxxpath compile_c compile_cxx link shlibext llvmlibsdir llvmdsymutil global valgrind grep gas set path [file join $srcdir $subdir] @@ -73,6 +73,8 @@ proc substitute { line test tmpFile } { regsub -all {%shlibext} $new_line "$shlibext" new_line #replace %ocamlc with ocaml compiler command regsub -all {%ocamlc} $new_line "$ocamlc" new_line + #replace %llvmdsymutil with dsymutil command + regsub -all {%llvmdsymutil} $new_line "$llvmdsymutil" new_line #replace %llvmlibsdir with configure library directory regsub -all {%llvmlibsdir} $new_line "$llvmlibsdir" new_line #replace %p with path to source, -- GitLab From 0e8fc3c773e20c66e8fd11284c5d2c9c3278afee Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 21:35:47 +0000 Subject: [PATCH 637/682] Add iterators to LookupResult, allowing one to iterate over the non-ambiguous name lookup results without allocating any memory, e.g., for sets of overloaded functions. llvm-svn: 63549 --- clang/lib/Sema/Sema.h | 49 ++++++++++++++++++++++++++++ clang/lib/Sema/SemaDecl.cpp | 37 +++++++-------------- clang/lib/Sema/SemaInit.cpp | 2 ++ clang/lib/Sema/SemaLookup.cpp | 60 +++++++++++++++++++++++++++++++++++ clang/test/Sema/init.c | 10 ++++++ 5 files changed, 133 insertions(+), 25 deletions(-) diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 60362054889d..b0a0a5e9ee1c 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -735,6 +735,55 @@ public: Decl* getAsDecl() const; BasePaths *getBasePaths() const; + + /// \brief Iterate over the results of name lookup. + /// + /// The @c iterator class provides iteration over the results of a + /// non-ambiguous name lookup. + class iterator { + /// The LookupResult structure we're iterating through. + LookupResult *Result; + + /// The current position of this iterator within the sequence of + /// results. This value will have the same representation as the + /// @c First field in the LookupResult structure. + mutable uintptr_t Current; + + public: + typedef Decl * value_type; + typedef Decl * reference; + typedef Decl * pointer; + typedef std::ptrdiff_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + iterator() : Result(0), Current(0) { } + + iterator(LookupResult *Res, uintptr_t Cur) : Result(Res), Current(Cur) { } + + reference operator*() const; + + pointer operator->() const { return **this; } + + iterator &operator++(); + + iterator operator++(int) { + iterator tmp(*this); + ++(*this); + return tmp; + } + + friend inline bool operator==(iterator const& x, iterator const& y) { + return x.Current == y.Current; + } + + friend inline bool operator!=(iterator const& x, iterator const& y) { + return x.Current != y.Current; + } + }; + friend class iterator; + + iterator begin(); + iterator end(); }; /// Determines whether D is a suitable lookup result according to the diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index fe7ab92b6a92..d03879e907e5 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -1666,35 +1666,22 @@ Sema::ActOnFunctionDeclarator(Scope* S, Declarator& D, DeclContext* DC, << D.getCXXScopeSpec().getRange(); InvalidDecl = true; - PrevDecl = LookupQualifiedName(DC, Name, LookupOrdinaryName); - if (!PrevDecl) { - // Nothing to suggest. - } else if (OverloadedFunctionDecl *Ovl - = dyn_cast(PrevDecl)) { - for (OverloadedFunctionDecl::function_iterator - Func = Ovl->function_begin(), - FuncEnd = Ovl->function_end(); - Func != FuncEnd; ++Func) { - if (isNearlyMatchingMemberFunction(Context, *Func, NewFD)) - Diag((*Func)->getLocation(), diag::note_member_def_close_match); - - } - } else if (CXXMethodDecl *Method = dyn_cast(PrevDecl)) { - // Suggest this no matter how mismatched it is; it's the only - // thing we have. - unsigned diag; - if (isNearlyMatchingMemberFunction(Context, Method, NewFD)) - diag = diag::note_member_def_close_match; - else if (Method->getBody()) - diag = diag::note_previous_definition; - else - diag = diag::note_previous_declaration; - Diag(Method->getLocation(), diag); + LookupResult Prev = LookupQualifiedName(DC, Name, LookupOrdinaryName, + true); + assert(!Prev.isAmbiguous() && + "Cannot have an ambiguity in previous-declaration lookup"); + for (LookupResult::iterator Func = Prev.begin(), FuncEnd = Prev.end(); + Func != FuncEnd; ++Func) { + if (isa(*Func) && + isNearlyMatchingMemberFunction(Context, cast(*Func), + NewFD)) + Diag((*Func)->getLocation(), diag::note_member_def_close_match); } - + PrevDecl = 0; } } + // Handle attributes. We need to have merged decls when handling attributes // (for example to check for conflicts, etc). ProcessDeclAttributes(NewFD, D); diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 8bc3496a19fb..5ef6de3bf3c5 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1342,6 +1342,8 @@ bool Sema::CheckValueInitialization(QualType Type, SourceLocation Loc) { // [...] A program that calls for default-initialization or // value-initialization of an entity of reference type is // ill-formed. [...] + // FIXME: Once we have code that goes through this path, add an + // actual diagnostic :) } return false; diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index abb265da49be..da2deec02ad6 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -181,6 +181,66 @@ BasePaths *Sema::LookupResult::getBasePaths() const { return reinterpret_cast(First); } +Sema::LookupResult::iterator::reference +Sema::LookupResult::iterator::operator*() const { + switch (Result->StoredKind) { + case SingleDecl: + return reinterpret_cast(Current); + + case OverloadedDeclFromIdResolver: + return *IdentifierResolver::iterator::getFromOpaqueValue(Current); + + case OverloadedDeclFromDeclContext: + return *reinterpret_cast(Current); + + case AmbiguousLookup: + assert(false && "Cannot look into ambiguous lookup results"); + break; + } + + return 0; +} + +Sema::LookupResult::iterator& Sema::LookupResult::iterator::operator++() { + switch (Result->StoredKind) { + case SingleDecl: + Current = reinterpret_cast((Decl*)0); + break; + + case OverloadedDeclFromIdResolver: { + IdentifierResolver::iterator I + = IdentifierResolver::iterator::getFromOpaqueValue(Current); + ++I; + Current = I.getAsOpaqueValue(); + break; + } + + case OverloadedDeclFromDeclContext: { + DeclContext::lookup_iterator I + = reinterpret_cast(Current); + ++I; + Current = reinterpret_cast(I); + break; + } + + case AmbiguousLookup: + assert(false && "Cannot look into ambiguous lookup results"); + break; + } + + return *this; +} + +Sema::LookupResult::iterator Sema::LookupResult::begin() { + assert(StoredKind != AmbiguousLookup && "Lookup into an ambiguous result"); + return iterator(this, First); +} + +Sema::LookupResult::iterator Sema::LookupResult::end() { + assert(StoredKind != AmbiguousLookup && "Lookup into an ambiguous result"); + return iterator(this, Last); +} + // Retrieve the set of identifier namespaces that correspond to a // specific kind of name lookup. inline unsigned diff --git a/clang/test/Sema/init.c b/clang/test/Sema/init.c index 41ca6244ff29..3c8f3fe13490 100644 --- a/clang/test/Sema/init.c +++ b/clang/test/Sema/init.c @@ -96,3 +96,13 @@ struct { int a; int z[2]; } y = { .z = {} }; + +int bbb[10]; + +struct foo2 { + unsigned a; +}; + +struct foo2 bar2[] = { + { (int)bbb } +}; -- GitLab From 7633cbf005da7f40bf203630f0acc97483b7dfb0 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 2 Feb 2009 21:43:58 +0000 Subject: [PATCH 638/682] ABI handling API changes. - Lift CGFunctionInfo creation up to callers of EmitCall. - Move isVariadic bit out of CGFunctionInfo, take as argument to GetFunctionType instead. No functionality change. llvm-svn: 63550 --- clang/lib/CodeGen/CGCall.cpp | 51 +++++++++++++---------------- clang/lib/CodeGen/CGCall.h | 13 +++----- clang/lib/CodeGen/CGExpr.cpp | 2 +- clang/lib/CodeGen/CGObjC.cpp | 5 +-- clang/lib/CodeGen/CGObjCGNU.cpp | 7 ++-- clang/lib/CodeGen/CGObjCMac.cpp | 12 +++---- clang/lib/CodeGen/CodeGenFunction.h | 3 +- clang/lib/CodeGen/CodeGenTypes.cpp | 9 +++-- clang/lib/CodeGen/CodeGenTypes.h | 3 +- 9 files changed, 51 insertions(+), 54 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 4c423ea5f106..a592ace68a13 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -31,40 +31,30 @@ using namespace CodeGen; // FIXME: Use iterator and sidestep silly type array creation. -CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP) - : IsVariadic(true) -{ +CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP) { ArgTypes.push_back(FTNP->getResultType()); } -CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP) - : IsVariadic(FTP->isVariadic()) -{ +CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP) { ArgTypes.push_back(FTP->getResultType()); for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTypes.push_back(FTP->getArgType(i)); } // FIXME: Is there really any reason to have this still? -CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD) -{ +CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD) { const FunctionType *FTy = FD->getType()->getAsFunctionType(); const FunctionTypeProto *FTP = dyn_cast(FTy); ArgTypes.push_back(FTy->getResultType()); if (FTP) { - IsVariadic = FTP->isVariadic(); for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) ArgTypes.push_back(FTP->getArgType(i)); - } else { - IsVariadic = true; } } CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD, - const ASTContext &Context) - : IsVariadic(MD->isVariadic()) -{ + const ASTContext &Context) { ArgTypes.push_back(MD->getResultType()); ArgTypes.push_back(MD->getSelfDecl()->getType()); ArgTypes.push_back(Context.getObjCSelType()); @@ -73,16 +63,20 @@ CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD, ArgTypes.push_back((*i)->getType()); } -CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args, - bool _IsVariadic) - : IsVariadic(_IsVariadic) -{ +CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args) { ArgTypes.push_back(ResTy); for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) ArgTypes.push_back(i->second); } +CGFunctionInfo::CGFunctionInfo(QualType ResTy, const FunctionArgList &Args) { + ArgTypes.push_back(ResTy); + for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); + i != e; ++i) + ArgTypes.push_back(i->second); +} + ArgTypeIterator CGFunctionInfo::argtypes_begin() const { return ArgTypes.begin(); } @@ -941,8 +935,12 @@ static void CreateCoercedStore(llvm::Value *Src, /***/ +bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) { + return getABIReturnInfo(RetTy, getTypes()).isStructRet(); +} + const llvm::FunctionType * -CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { +CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { std::vector ArgTys; const llvm::Type *ResultType = 0; @@ -1007,11 +1005,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI) { } } - return llvm::FunctionType::get(ResultType, ArgTys, FI.isVariadic()); -} - -bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) { - return getABIReturnInfo(RetTy, getTypes()).isStructRet(); + return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic); } void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, @@ -1116,6 +1110,8 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, QualType RetTy, const FunctionArgList &Args) { + CGFunctionInfo FnInfo(RetTy, Args); + // Emit allocs for param decls. Give the LLVM Argument nodes names. llvm::Function::arg_iterator AI = Fn->arg_begin(); @@ -1225,12 +1221,13 @@ void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, } RValue CodeGenFunction::EmitCall(llvm::Value *Callee, - QualType RetTy, + const CGFunctionInfo &CallInfo, const CallArgList &CallArgs) { llvm::SmallVector Args; // Handle struct-return functions by passing a pointer to the // location that we would like to return into. + QualType RetTy = CallInfo.getReturnType(); ABIArgInfo RetAI = getABIReturnInfo(RetTy, CGM.getTypes()); switch (RetAI.getKind()) { case ABIArgInfo::StructRet: @@ -1282,10 +1279,6 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, } llvm::CallInst *CI = Builder.CreateCall(Callee,&Args[0],&Args[0]+Args.size()); - const llvm::Type *FnType = - cast(Callee->getType())->getElementType(); - CGFunctionInfo CallInfo(RetTy, CallArgs, - cast(FnType)->isVarArg()); // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. CodeGen::AttributeListType AttributeList; diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index fd6eb481598e..7ca5f26a8f8c 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -54,23 +54,20 @@ namespace CodeGen { /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. class CGFunctionInfo { - bool IsVariadic; - llvm::SmallVector ArgTypes; public: CGFunctionInfo(const FunctionTypeNoProto *FTNP); CGFunctionInfo(const FunctionTypeProto *FTP); CGFunctionInfo(const FunctionDecl *FD); - CGFunctionInfo(const ObjCMethodDecl *MD, - const ASTContext &Context); - CGFunctionInfo(QualType ResTy, const CallArgList &Args, - bool _IsVariadic); - - bool isVariadic() const { return IsVariadic; } + CGFunctionInfo(const ObjCMethodDecl *MD, const ASTContext &Context); + CGFunctionInfo(QualType ResTy, const CallArgList &Args); + CGFunctionInfo(QualType ResTy, const FunctionArgList &Args); ArgTypeIterator argtypes_begin() const; ArgTypeIterator argtypes_end() const; + + QualType getReturnType() const { return ArgTypes[0]; } }; } // end namespace CodeGen } // end namespace clang diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 726755dc84ca..0e13a8ddcd6d 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1102,5 +1102,5 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType CalleeType, Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), I->getType())); - return EmitCall(Callee, ResultType, Args); + return EmitCall(Callee, CGFunctionInfo(ResultType, Args), Args); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index eafb8586210e..0c0b2510e9eb 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -183,7 +183,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy)); Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); - RValue RV = EmitCall(GetPropertyFn, PD->getType(), Args); + RValue RV = EmitCall(GetPropertyFn, CGFunctionInfo(PD->getType(), Args), + Args); // We need to fix the type here. Ivars with copy & retain are // always objects so we don't need to worry about complex or // aggregates. @@ -267,7 +268,7 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, getContext().BoolTy)); Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), getContext().BoolTy)); - EmitCall(SetPropertyFn, PD->getType(), Args); + EmitCall(SetPropertyFn, CGFunctionInfo(PD->getType(), Args), Args); } else { SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index bfe92b303efd..6eca3f127196 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -311,7 +311,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(imp, ResultType, ActualArgs); + return CGF.EmitCall(imp, CGFunctionInfo(ResultType, ActualArgs), ActualArgs); } /// Generate code for a message send expression. @@ -358,7 +358,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(imp, ResultType, ActualArgs); + return CGF.EmitCall(imp, CGFunctionInfo(ResultType, ActualArgs), ActualArgs); } /// Generates a MethodList. Used in construction of a objc_class and @@ -970,7 +970,8 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, bool isClassMethod = !OMD->isInstanceMethod(); const llvm::FunctionType *MethodTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext())); + CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()), + OMD->isVariadic()); std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, MethodName, isClassMethod); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 1bea633589ca..6bc03fe08590 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -806,9 +806,8 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - const llvm::FunctionType *FTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(ResultType, ActualArgs, - false)); + CGFunctionInfo FnInfo(ResultType, ActualArgs); + const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FnInfo, false); llvm::Constant *Fn; if (CGM.ReturnTypeUsesSret(ResultType)) { @@ -821,7 +820,7 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, Fn = ObjCTypes.getSendFn(IsSuper); } Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy)); - return CGF.EmitCall(Fn, ResultType, ActualArgs); + return CGF.EmitCall(Fn, FnInfo, ActualArgs); } llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, @@ -1665,12 +1664,13 @@ llvm::Constant *CGObjCMac::EmitMethodList(const std::string &Name, } llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, - const ObjCContainerDecl *CD) { + const ObjCContainerDecl *CD) { std::string Name; GetNameForMethod(OMD, CD, Name); const llvm::FunctionType *MethodTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext())); + CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()), + OMD->isVariadic()); llvm::Function *Method = llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index e736fe5e167d..1bacff2480bf 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -55,6 +55,7 @@ namespace clang { namespace CodeGen { class CodeGenModule; class CodeGenTypes; + class CGFunctionInfo; class CGRecordLayout; /// CodeGenFunction - This class organizes the per-function state that is used @@ -543,7 +544,7 @@ public: /// specifies both the LLVM arguments and the types they were /// derived from. RValue EmitCall(llvm::Value *Callee, - QualType ResultType, + const CGFunctionInfo &FnInfo, const CallArgList &Args); RValue EmitCallExpr(const CallExpr *E); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index edd16087fd43..bcb3cc559158 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -256,9 +256,12 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { VT.getNumElements()); } case Type::FunctionNoProto: - return GetFunctionType(CGFunctionInfo(cast(&Ty))); - case Type::FunctionProto: - return GetFunctionType(CGFunctionInfo(cast(&Ty))); + return GetFunctionType(CGFunctionInfo(cast(&Ty)), + true); + case Type::FunctionProto: { + const FunctionTypeProto *FTP = cast(&Ty); + return GetFunctionType(CGFunctionInfo(FTP), FTP->isVariadic()); + } case Type::ASQual: return diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index eb4244545b2e..60c2946f131f 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -144,7 +144,8 @@ public: const llvm::Type *ConvertTypeForMem(QualType T); /// GetFunctionType - Get the LLVM function type for \arg Info. - const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info); + const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info, + bool IsVariadic); const CGRecordLayout *getCGRecordLayout(const TagDecl*) const; /// Returns a StructType representing an Objective-C object -- GitLab From e9aee88eed40fb4e8798e1870fac0ccdae7f206b Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 2 Feb 2009 21:45:32 +0000 Subject: [PATCH 639/682] Clean up indentation. llvm-svn: 63551 --- clang/lib/Driver/PlistDiagnostics.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/clang/lib/Driver/PlistDiagnostics.cpp b/clang/lib/Driver/PlistDiagnostics.cpp index 72d64ed1a88f..b7e8385409b0 100644 --- a/clang/lib/Driver/PlistDiagnostics.cpp +++ b/clang/lib/Driver/PlistDiagnostics.cpp @@ -98,7 +98,7 @@ static void EmitRange(llvm::raw_ostream& o, SourceManager* SM, SourceRange R, static void ReportDiag(llvm::raw_ostream& o, const PathDiagnosticPiece& P, const FIDMap& FM, SourceManager* SM) { - unsigned indent = 2; + unsigned indent = 4; Indent(o, indent) << "\n"; ++indent; @@ -115,7 +115,9 @@ static void ReportDiag(llvm::raw_ostream& o, const PathDiagnosticPiece& P, if (RI != RE) { Indent(o, indent) << "ranges\n"; Indent(o, indent) << "\n"; + ++indent; for ( ; RI != RE; ++RI ) EmitRange(o, SM, *RI, FM, indent+1); + --indent; Indent(o, indent) << "\n"; } @@ -223,7 +225,7 @@ PlistDiagnostics::~PlistDiagnostics() { o << " \n"; // Output the bug type and bug category. - o << " description\n " << D->getDescription() + o << " description\n " << D->getDescription() << "\n" << " category\n " << D->getCategory() << "\n" -- GitLab From e83866065b206f90aae6a25724dd3c1274720269 Mon Sep 17 00:00:00 2001 From: Torok Edwin Date: Mon, 2 Feb 2009 21:57:34 +0000 Subject: [PATCH 640/682] Only force SSE level if it is not correct. Add an assert to check HasX86_64 status. llvm-svn: 63552 --- llvm/lib/Target/X86/X86Subtarget.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 99708e04cf9c..185f45b4cf1b 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -322,16 +322,23 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // If feature string is not empty, parse features string. std::string CPU = GetCurrentX86CPU(); ParseSubtargetFeatures(FS, CPU); + // All X86-64 CPUs also have SSE2, however user might request no SSE via + // -mattr, so don't force SSELevel here. } else { // Otherwise, use CPUID to auto-detect feature set. AutoDetectSubtargetFeatures(); + if (Is64Bit && X86SSELevel < SSE2) { + // Make sure SSE2 is enabled, it is available on all X86-64 CPUs. + X86SSELevel = SSE2; + } } - // If requesting codegen for X86-64, make sure that 64-bit and SSE2 features - // are enabled. These are available on all x86-64 CPUs. + // If requesting codegen for X86-64, make sure that 64-bit features + // are enabled. if (Is64Bit) { - HasX86_64 = true; + HasX86_64 = true; } + assert(!Is64Bit || HasX86_64); DOUT << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel << ", 64bit " << HasX86_64 << "\n"; -- GitLab From d931a87f902a045aa82797228ad5a0963da2c6f4 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 2 Feb 2009 22:03:45 +0000 Subject: [PATCH 641/682] More ABI API cleanup. - Lift CGFunctionInfo creation above ReturnTypeUsesSret and EmitFunction{Epi,Pro}log. llvm-svn: 63553 --- clang/lib/CodeGen/CGCall.cpp | 25 ++++++++++++------------- clang/lib/CodeGen/CGExpr.cpp | 2 +- clang/lib/CodeGen/CGObjC.cpp | 6 +++--- clang/lib/CodeGen/CGObjCGNU.cpp | 4 ++-- clang/lib/CodeGen/CGObjCMac.cpp | 4 ++-- clang/lib/CodeGen/CodeGenFunction.cpp | 6 ++++-- clang/lib/CodeGen/CodeGenFunction.h | 11 ++++++----- clang/lib/CodeGen/CodeGenModule.cpp | 2 +- clang/lib/CodeGen/CodeGenModule.h | 6 +++--- 9 files changed, 34 insertions(+), 32 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index a592ace68a13..c7b2a5dc895f 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -935,8 +935,8 @@ static void CreateCoercedStore(llvm::Value *Src, /***/ -bool CodeGenModule::ReturnTypeUsesSret(QualType RetTy) { - return getABIReturnInfo(RetTy, getTypes()).isStructRet(); +bool CodeGenModule::ReturnTypeUsesSret(const CGFunctionInfo &FI) { + return getABIReturnInfo(FI.getReturnType(), getTypes()).isStructRet(); } const llvm::FunctionType * @@ -1008,8 +1008,8 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic); } -void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, - const CGFunctionInfo &Info, +void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &Info, + const Decl *TargetDecl, AttributeListType &PAL) { unsigned FuncAttrs = 0; unsigned RetAttrs = 0; @@ -1107,16 +1107,14 @@ void CodeGenModule::ConstructAttributeList(const Decl *TargetDecl, } -void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, - QualType RetTy, +void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI, + llvm::Function *Fn, const FunctionArgList &Args) { - CGFunctionInfo FnInfo(RetTy, Args); - // Emit allocs for param decls. Give the LLVM Argument nodes names. llvm::Function::arg_iterator AI = Fn->arg_begin(); // Name the struct return argument. - if (CGM.ReturnTypeUsesSret(RetTy)) { + if (CGM.ReturnTypeUsesSret(FI)) { AI->setName("agg.result"); ++AI; } @@ -1173,12 +1171,13 @@ void CodeGenFunction::EmitFunctionProlog(llvm::Function *Fn, assert(AI == Fn->arg_end() && "Argument mismatch!"); } -void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, +void CodeGenFunction::EmitFunctionEpilog(const CGFunctionInfo &FI, llvm::Value *ReturnValue) { llvm::Value *RV = 0; // Functions with no result always return void. if (ReturnValue) { + QualType RetTy = FI.getReturnType(); ABIArgInfo RetAI = getABIReturnInfo(RetTy, CGM.getTypes()); switch (RetAI.getKind()) { @@ -1220,8 +1219,8 @@ void CodeGenFunction::EmitFunctionEpilog(QualType RetTy, } } -RValue CodeGenFunction::EmitCall(llvm::Value *Callee, - const CGFunctionInfo &CallInfo, +RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo, + llvm::Value *Callee, const CallArgList &CallArgs) { llvm::SmallVector Args; @@ -1282,7 +1281,7 @@ RValue CodeGenFunction::EmitCall(llvm::Value *Callee, // FIXME: Provide TargetDecl so nounwind, noreturn, etc, etc get set. CodeGen::AttributeListType AttributeList; - CGM.ConstructAttributeList(0, CallInfo, AttributeList); + CGM.ConstructAttributeList(CallInfo, 0, AttributeList); CI->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(), AttributeList.size())); diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 0e13a8ddcd6d..5ed215164b7e 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1102,5 +1102,5 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType CalleeType, Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), I->getType())); - return EmitCall(Callee, CGFunctionInfo(ResultType, Args), Args); + return EmitCall(CGFunctionInfo(ResultType, Args), Callee, Args); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 0c0b2510e9eb..cf37886e6d37 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -183,8 +183,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy)); Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); - RValue RV = EmitCall(GetPropertyFn, CGFunctionInfo(PD->getType(), Args), - Args); + RValue RV = EmitCall(CGFunctionInfo(PD->getType(), Args), + GetPropertyFn, Args); // We need to fix the type here. Ivars with copy & retain are // always objects so we don't need to worry about complex or // aggregates. @@ -268,7 +268,7 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, getContext().BoolTy)); Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), getContext().BoolTy)); - EmitCall(SetPropertyFn, CGFunctionInfo(PD->getType(), Args), Args); + EmitCall(CGFunctionInfo(PD->getType(), Args), SetPropertyFn, Args); } else { SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 6eca3f127196..e6ae6f36b4e1 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -311,7 +311,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(imp, CGFunctionInfo(ResultType, ActualArgs), ActualArgs); + return CGF.EmitCall(CGFunctionInfo(ResultType, ActualArgs), imp, ActualArgs); } /// Generate code for a message send expression. @@ -358,7 +358,7 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(imp, CGFunctionInfo(ResultType, ActualArgs), ActualArgs); + return CGF.EmitCall(CGFunctionInfo(ResultType, ActualArgs), imp, ActualArgs); } /// Generates a MethodList. Used in construction of a objc_class and diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index 6bc03fe08590..d8e873b84592 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -810,7 +810,7 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FnInfo, false); llvm::Constant *Fn; - if (CGM.ReturnTypeUsesSret(ResultType)) { + if (CGM.ReturnTypeUsesSret(FnInfo)) { Fn = ObjCTypes.getSendStretFn(IsSuper); } else if (ResultType->isFloatingType()) { // FIXME: Sadly, this is wrong. This actually depends on the @@ -820,7 +820,7 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, Fn = ObjCTypes.getSendFn(IsSuper); } Fn = llvm::ConstantExpr::getBitCast(Fn, llvm::PointerType::getUnqual(FTy)); - return CGF.EmitCall(Fn, FnInfo, ActualArgs); + return CGF.EmitCall(FnInfo, Fn, ActualArgs); } llvm::Value *CGObjCMac::GenerateProtocolRef(CGBuilderTy &Builder, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 5d34f65fc14d..fe28b3aeccdd 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -125,7 +125,7 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) { DI->EmitRegionEnd(CurFn, Builder); } - EmitFunctionEpilog(FnRetTy, ReturnValue); + EmitFunctionEpilog(*CurFnInfo, ReturnValue); // Remove the AllocaInsertPt instruction, which is just a convenience for us. AllocaInsertPt->eraseFromParent(); @@ -171,7 +171,9 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, } } - EmitFunctionProlog(CurFn, FnRetTy, Args); + // FIXME: Leaked. + CurFnInfo = new CGFunctionInfo(FnRetTy, Args); + EmitFunctionProlog(*CurFnInfo, CurFn, Args); // If any of the arguments have a variably modified type, make sure to // emit the type size. diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 1bacff2480bf..9033a65be26b 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -70,6 +70,7 @@ public: // Holds the Decl for the current function or method const Decl *CurFuncDecl; + const CGFunctionInfo *CurFnInfo; QualType FnRetTy; llvm::Function *CurFn; @@ -219,13 +220,13 @@ public: /// EmitFunctionProlog - Emit the target specific LLVM code to load /// the arguments for the given function. This is also responsible /// for naming the LLVM function arguments. - void EmitFunctionProlog(llvm::Function *Fn, QualType RetTy, + void EmitFunctionProlog(const CGFunctionInfo &FI, + llvm::Function *Fn, const FunctionArgList &Args); /// EmitFunctionEpilog - Emit the target specific LLVM code to /// return the given temporary. - void EmitFunctionEpilog(QualType RetTy, - llvm::Value *ReturnValue); + void EmitFunctionEpilog(const CGFunctionInfo &FI, llvm::Value *ReturnValue); const llvm::Type *ConvertType(QualType T); @@ -543,8 +544,8 @@ public: /// given result type, and using the given argument list which /// specifies both the LLVM arguments and the types they were /// derived from. - RValue EmitCall(llvm::Value *Callee, - const CGFunctionInfo &FnInfo, + RValue EmitCall(const CGFunctionInfo &FnInfo, + llvm::Value *Callee, const CallArgList &Args); RValue EmitCallExpr(const CallExpr *E); diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index bdb99d6439b7..d02812ac5d9c 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -265,7 +265,7 @@ void CodeGenModule::SetFunctionAttributes(const Decl *D, const CGFunctionInfo &Info, llvm::Function *F) { AttributeListType AttributeList; - ConstructAttributeList(D, Info, AttributeList); + ConstructAttributeList(Info, D, AttributeList); F->setAttributes(llvm::AttrListPtr::get(AttributeList.begin(), AttributeList.size())); diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 724ca28b886f..bedefcaa3f99 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -244,10 +244,10 @@ public: /// ReturnTypeUsesSret - Return true iff the given type uses 'sret' /// when used as a return type. - bool ReturnTypeUsesSret(QualType RetTy); + bool ReturnTypeUsesSret(const CGFunctionInfo &FI); - void ConstructAttributeList(const Decl *TargetDecl, - const CGFunctionInfo &Info, + void ConstructAttributeList(const CGFunctionInfo &Info, + const Decl *TargetDecl, AttributeListType &PAL); private: -- GitLab From bb2e688396e63030fbf57bd92f54875025763fe0 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 22:11:10 +0000 Subject: [PATCH 642/682] Steve set me straight on this one. GCC was right, EDG was wrong: the direct-initialization following a user-defined conversion can select any constructor; it just can't employ any user-defined conversions. So we ban those conversions and classify the constructor call based on the relationship between the "from" and "to" types in the conversion. llvm-svn: 63554 --- clang/lib/Sema/SemaOverload.cpp | 8 +++++--- clang/test/SemaCXX/user-defined-conversions.cpp | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp index 1fa703c775ab..7219f19a97cc 100644 --- a/clang/lib/Sema/SemaOverload.cpp +++ b/clang/lib/Sema/SemaOverload.cpp @@ -383,7 +383,10 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType, // called for those cases. if (CXXConstructorDecl *Constructor = dyn_cast(ICS.UserDefined.ConversionFunction)) { - if (Constructor->isCopyConstructor(Context)) { + QualType FromCanon + = Context.getCanonicalType(From->getType().getUnqualifiedType()); + QualType ToCanon = Context.getCanonicalType(ToType).getUnqualifiedType(); + if (FromCanon == ToCanon || IsDerivedFrom(FromCanon, ToCanon)) { // Turn this into a "standard" conversion sequence, so that it // gets ranked with standard conversion sequences. ICS.ConversionKind = ImplicitConversionSequence::StandardConversion; @@ -391,8 +394,7 @@ Sema::TryImplicitConversion(Expr* From, QualType ToType, ICS.Standard.FromTypePtr = From->getType().getAsOpaquePtr(); ICS.Standard.ToTypePtr = ToType.getAsOpaquePtr(); ICS.Standard.CopyConstructor = Constructor; - if (IsDerivedFrom(From->getType().getUnqualifiedType(), - ToType.getUnqualifiedType())) + if (ToCanon != FromCanon) ICS.Standard.Second = ICK_Derived_To_Base; } } diff --git a/clang/test/SemaCXX/user-defined-conversions.cpp b/clang/test/SemaCXX/user-defined-conversions.cpp index e4b12fc3f713..c6941b947ee1 100644 --- a/clang/test/SemaCXX/user-defined-conversions.cpp +++ b/clang/test/SemaCXX/user-defined-conversions.cpp @@ -65,5 +65,5 @@ void test_conversion(ConvertibleToBase ctb, ConvertibleToDerived ctd, Base b2(ctb); Base b3 = ctd; Base b4(ctd); - Base b5 = ctfd; // expected-error{{cannot initialize 'b5' with an lvalue of type 'struct ConvertibleToFunkyDerived'}} + Base b5 = ctfd; } -- GitLab From a02e45ca19ad664d8d99f7c2647a3d49b855b2d9 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 2 Feb 2009 22:12:50 +0000 Subject: [PATCH 643/682] DebugLoc propagation. ExpandOp and PromoteOp, among others. llvm-svn: 63555 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 637 +++++++++--------- 1 file changed, 330 insertions(+), 307 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 4c49724bb7d6..47450eab939b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -287,7 +287,7 @@ private: SDValue &Hi); SDValue ExpandIntToFP(bool isSigned, MVT DestTy, SDValue Source, DebugLoc dl); - SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT); + SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT, DebugLoc dl); SDValue ExpandBUILD_VECTOR(SDNode *Node); SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node); SDValue LegalizeINT_TO_FP(SDValue Result, bool isSigned, MVT DestTy, @@ -299,12 +299,12 @@ private: SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, bool isSigned, DebugLoc dl); - SDValue ExpandBSWAP(SDValue Op); - SDValue ExpandBitCount(unsigned Opc, SDValue Op); + SDValue ExpandBSWAP(SDValue Op, DebugLoc dl); + SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl); bool ExpandShift(unsigned Opc, SDValue Op, SDValue Amt, - SDValue &Lo, SDValue &Hi); + SDValue &Lo, SDValue &Hi, DebugLoc dl); void ExpandShiftParts(unsigned NodeOp, SDValue Op, SDValue Amt, - SDValue &Lo, SDValue &Hi); + SDValue &Lo, SDValue &Hi, DebugLoc dl); SDValue ExpandEXTRACT_SUBVECTOR(SDValue Op); SDValue ExpandEXTRACT_VECTOR_ELT(SDValue Op); @@ -3725,7 +3725,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; } case TargetLowering::Expand: - Result = ExpandBSWAP(Tmp1); + Result = ExpandBSWAP(Tmp1, dl); break; } break; @@ -3776,7 +3776,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; } case TargetLowering::Expand: - Result = ExpandBitCount(Node->getOpcode(), Tmp1); + Result = ExpandBitCount(Node->getOpcode(), Tmp1, dl); break; } break; @@ -3933,7 +3933,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::BIT_CONVERT: if (!isTypeLegal(Node->getOperand(0).getValueType())) { Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), - Node->getValueType(0)); + Node->getValueType(0), dl); } else if (Op.getOperand(0).getValueType().isVector()) { // The input has to be a vector type, we have to either scalarize it, pack // it, or convert it based on whether the input vector type is legal. @@ -3965,7 +3965,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { default: assert(0 && "Unknown operation action!"); case TargetLowering::Expand: Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), - Node->getValueType(0)); + Node->getValueType(0), dl); break; case TargetLowering::Legal: Tmp1 = LegalizeOp(Node->getOperand(0)); @@ -4163,7 +4163,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (TLI.getConvertAction(SrcVT, DstVT) == TargetLowering::Expand) { // The only other way we can lower this is to turn it into a STORE, // LOAD pair, targetting a temporary location (a stack slot). - Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT); + Result = EmitStackConvert(Node->getOperand(0), SrcVT, DstVT, dl); break; } switch (getTypeAction(Node->getOperand(0).getValueType())) { @@ -4193,7 +4193,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { } // The only other way we can lower this is to turn it into a STORE, // LOAD pair, targetting a temporary location (a stack slot). - Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT); + Result = EmitStackConvert(Node->getOperand(0), DstVT, DstVT, dl); break; } switch (getTypeAction(Node->getOperand(0).getValueType())) { @@ -4278,7 +4278,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // slots and always reusing the same one. We currently always create // new ones, as reuse may inhibit scheduling. Result = EmitStackConvert(Node->getOperand(0), ExtraVT, - Node->getValueType(0)); + Node->getValueType(0), dl); } else { assert(0 && "Unknown op"); } @@ -4483,6 +4483,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { SDValue Tmp1, Tmp2, Tmp3; SDValue Result; SDNode *Node = Op.getNode(); + DebugLoc dl = Node->getDebugLoc(); DenseMap::iterator I = PromotedNodes.find(Op); if (I != PromotedNodes.end()) return I->second; @@ -4497,17 +4498,17 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { assert(0 && "Do not know how to promote this operator!"); abort(); case ISD::UNDEF: - Result = DAG.getNode(ISD::UNDEF, NVT); + Result = DAG.getNode(ISD::UNDEF, dl, NVT); break; case ISD::Constant: if (VT != MVT::i1) - Result = DAG.getNode(ISD::SIGN_EXTEND, NVT, Op); + Result = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Op); else - Result = DAG.getNode(ISD::ZERO_EXTEND, NVT, Op); + Result = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Op); assert(isa(Result) && "Didn't constant fold zext?"); break; case ISD::ConstantFP: - Result = DAG.getNode(ISD::FP_EXTEND, NVT, Op); + Result = DAG.getNode(ISD::FP_EXTEND, dl, NVT, Op); assert(isa(Result) && "Didn't constant fold fp_extend?"); break; @@ -4515,7 +4516,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { MVT VT0 = Node->getOperand(0).getValueType(); assert(isTypeLegal(TLI.getSetCCResultType(VT0)) && "SetCC type is not legal??"); - Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(VT0), + Result = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(VT0), Node->getOperand(0), Node->getOperand(1), Node->getOperand(2)); break; @@ -4527,7 +4528,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { assert(Result.getValueType().bitsGE(NVT) && "This truncation doesn't make sense!"); if (Result.getValueType().bitsGT(NVT)) // Truncate to NVT instead of VT - Result = DAG.getNode(ISD::TRUNCATE, NVT, Result); + Result = DAG.getNode(ISD::TRUNCATE, dl, NVT, Result); break; case Promote: // The truncation is not required, because we don't guarantee anything @@ -4537,7 +4538,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case Expand: ExpandOp(Node->getOperand(0), Tmp1, Tmp2); // Truncate the low part of the expanded value to the result type - Result = DAG.getNode(ISD::TRUNCATE, NVT, Tmp1); + Result = DAG.getNode(ISD::TRUNCATE, dl, NVT, Tmp1); } break; case ISD::SIGN_EXTEND: @@ -4547,17 +4548,17 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case Expand: assert(0 && "BUG: Smaller reg should have been promoted!"); case Legal: // Input is legal? Just do extend all the way to the larger type. - Result = DAG.getNode(Node->getOpcode(), NVT, Node->getOperand(0)); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Node->getOperand(0)); break; case Promote: // Promote the reg if it's smaller. Result = PromoteOp(Node->getOperand(0)); // The high bits are not guaranteed to be anything. Insert an extend. if (Node->getOpcode() == ISD::SIGN_EXTEND) - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result, + Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Result, DAG.getValueType(Node->getOperand(0).getValueType())); else if (Node->getOpcode() == ISD::ZERO_EXTEND) - Result = DAG.getZeroExtendInReg(Result, + Result = DAG.getZeroExtendInReg(Result, dl, Node->getOperand(0).getValueType()); break; } @@ -4577,7 +4578,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { } case ISD::BIT_CONVERT: Result = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), - Node->getValueType(0)); + Node->getValueType(0), dl); Result = PromoteOp(Result); break; @@ -4590,11 +4591,11 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case Legal: if (Node->getConstantOperandVal(1) == 0) { // Input is legal? Do an FP_ROUND_INREG. - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Node->getOperand(0), + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Node->getOperand(0), DAG.getValueType(VT)); } else { // Just remove the truncate, it isn't affecting the value. - Result = DAG.getNode(ISD::FP_ROUND, NVT, Node->getOperand(0), + Result = DAG.getNode(ISD::FP_ROUND, dl, NVT, Node->getOperand(0), Node->getOperand(1)); } break; @@ -4605,27 +4606,27 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { switch (getTypeAction(Node->getOperand(0).getValueType())) { case Legal: // No extra round required here. - Result = DAG.getNode(Node->getOpcode(), NVT, Node->getOperand(0)); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Node->getOperand(0)); break; case Promote: Result = PromoteOp(Node->getOperand(0)); if (Node->getOpcode() == ISD::SINT_TO_FP) - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), + Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Result.getValueType(), Result, DAG.getValueType(Node->getOperand(0).getValueType())); else - Result = DAG.getZeroExtendInReg(Result, + Result = DAG.getZeroExtendInReg(Result, dl, Node->getOperand(0).getValueType()); // No extra round required here. - Result = DAG.getNode(Node->getOpcode(), NVT, Result); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Result); break; case Expand: Result = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, NVT, - Node->getOperand(0), Node->getDebugLoc()); + Node->getOperand(0), dl); // Round if we cannot tolerate excess precision. if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, DAG.getValueType(VT)); break; } @@ -4633,7 +4634,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case ISD::SIGN_EXTEND_INREG: Result = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Result, + Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Result, Node->getOperand(1)); break; case ISD::FP_TO_SINT: @@ -4658,9 +4659,9 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { !TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NVT) && (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NVT) || TLI.getOperationAction(ISD::FP_TO_SINT, NVT)==TargetLowering::Custom)){ - Result = DAG.getNode(ISD::FP_TO_SINT, NVT, Tmp1); + Result = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Tmp1); } else { - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); } break; @@ -4668,7 +4669,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case ISD::FNEG: Tmp1 = PromoteOp(Node->getOperand(0)); assert(Tmp1.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); // NOTE: we do not have to do any extra rounding here for // NoExcessFPPrecision, because we know the input will have the appropriate // precision, and these operations don't modify precision at all. @@ -4689,9 +4690,9 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case ISD::FNEARBYINT: Tmp1 = PromoteOp(Node->getOperand(0)); assert(Tmp1.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, DAG.getValueType(VT)); break; @@ -4704,9 +4705,9 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { if (Node->getOpcode() == ISD::FPOW) Tmp2 = PromoteOp(Tmp2); assert(Tmp1.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, DAG.getValueType(VT)); break; } @@ -4715,7 +4716,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { AtomicSDNode* AtomNode = cast(Node); Tmp2 = PromoteOp(Node->getOperand(2)); Tmp3 = PromoteOp(Node->getOperand(3)); - Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getMemoryVT(), + Result = DAG.getAtomic(Node->getOpcode(), dl, AtomNode->getMemoryVT(), AtomNode->getChain(), AtomNode->getBasePtr(), Tmp2, Tmp3, AtomNode->getSrcValue(), @@ -4737,7 +4738,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case ISD::ATOMIC_SWAP: { AtomicSDNode* AtomNode = cast(Node); Tmp2 = PromoteOp(Node->getOperand(2)); - Result = DAG.getAtomic(Node->getOpcode(), AtomNode->getMemoryVT(), + Result = DAG.getAtomic(Node->getOpcode(), dl, AtomNode->getMemoryVT(), AtomNode->getChain(), AtomNode->getBasePtr(), Tmp2, AtomNode->getSrcValue(), @@ -4759,7 +4760,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { Tmp1 = PromoteOp(Node->getOperand(0)); Tmp2 = PromoteOp(Node->getOperand(1)); assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); break; case ISD::FADD: case ISD::FSUB: @@ -4767,7 +4768,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { Tmp1 = PromoteOp(Node->getOperand(0)); Tmp2 = PromoteOp(Node->getOperand(1)); assert(Tmp1.getValueType() == NVT && Tmp2.getValueType() == NVT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); // Floating point operations will give excess precision that we may not be // able to tolerate. If we DO allow excess precision, just leave it, @@ -4775,7 +4776,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { // FIXME: Why would we need to round FP ops more than integer ones? // Is Round(Add(Add(A,B),C)) != Round(Add(Round(Add(A,B)), C)) if (NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, DAG.getValueType(VT)); break; @@ -4785,16 +4786,16 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { Tmp1 = PromoteOp(Node->getOperand(0)); Tmp2 = PromoteOp(Node->getOperand(1)); if (NVT.isInteger()) { - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1, DAG.getValueType(VT)); - Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp2, + Tmp2 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp2, DAG.getValueType(VT)); } - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); // Perform FP_ROUND: this is probably overly pessimistic. if (NVT.isFloatingPoint() && NoExcessFPPrecision) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, DAG.getValueType(VT)); break; case ISD::FDIV: @@ -4811,11 +4812,11 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case Legal: Tmp2 = LegalizeOp(Node->getOperand(1)); break; case Promote: Tmp2 = PromoteOp(Node->getOperand(1)); break; } - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); // Perform FP_ROUND: this is probably overly pessimistic. if (NoExcessFPPrecision && Node->getOpcode() != ISD::FCOPYSIGN) - Result = DAG.getNode(ISD::FP_ROUND_INREG, NVT, Result, + Result = DAG.getNode(ISD::FP_ROUND_INREG, dl, NVT, Result, DAG.getValueType(VT)); break; @@ -4825,27 +4826,27 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { Tmp1 = PromoteOp(Node->getOperand(0)); Tmp2 = PromoteOp(Node->getOperand(1)); assert(NVT.isInteger() && "Operators don't apply to FP!"); - Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT); - Tmp2 = DAG.getZeroExtendInReg(Tmp2, VT); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT); + Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, VT); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); break; case ISD::SHL: Tmp1 = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::SHL, NVT, Tmp1, Node->getOperand(1)); + Result = DAG.getNode(ISD::SHL, dl, NVT, Tmp1, Node->getOperand(1)); break; case ISD::SRA: // The input value must be properly sign extended. Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Tmp1, + Tmp1 = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Tmp1, DAG.getValueType(VT)); - Result = DAG.getNode(ISD::SRA, NVT, Tmp1, Node->getOperand(1)); + Result = DAG.getNode(ISD::SRA, dl, NVT, Tmp1, Node->getOperand(1)); break; case ISD::SRL: // The input value must be properly zero extended. Tmp1 = PromoteOp(Node->getOperand(0)); - Tmp1 = DAG.getZeroExtendInReg(Tmp1, VT); - Result = DAG.getNode(ISD::SRL, NVT, Tmp1, Node->getOperand(1)); + Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, VT); + Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, Node->getOperand(1)); break; case ISD::VAARG: @@ -4858,13 +4859,13 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { const Value *V = cast(Node->getOperand(2))->getValue(); SDValue VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0); // Increment the pointer, VAList, to the next vaarg - Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, + Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, DAG.getConstant(VT.getSizeInBits()/8, TLI.getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0); + Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0); // Load the actual argument out of the pointer VAList - Result = DAG.getExtLoad(ISD::EXTLOAD, NVT, Tmp3, VAList, NULL, 0, VT); + Result = DAG.getExtLoad(ISD::EXTLOAD, dl, NVT, Tmp3, VAList, NULL, 0, VT); } // Remember that we legalized the chain. AddLegalizedOperand(Op.getValue(1), LegalizeOp(Result.getValue(1))); @@ -4874,7 +4875,7 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { LoadSDNode *LD = cast(Node); ISD::LoadExtType ExtType = ISD::isNON_EXTLoad(Node) ? ISD::EXTLOAD : LD->getExtensionType(); - Result = DAG.getExtLoad(ExtType, NVT, + Result = DAG.getExtLoad(ExtType, dl, NVT, LD->getChain(), LD->getBasePtr(), LD->getSrcValue(), LD->getSrcValueOffset(), LD->getMemoryVT(), @@ -4894,20 +4895,20 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { // Ensure that the resulting node is at least the same size as the operands' // value types, because we cannot assume that TLI.getSetCCValueType() is // constant. - Result = DAG.getNode(ISD::SELECT, VT2, Node->getOperand(0), Tmp2, Tmp3); + Result = DAG.getNode(ISD::SELECT, dl, VT2, Node->getOperand(0), Tmp2, Tmp3); break; } case ISD::SELECT_CC: Tmp2 = PromoteOp(Node->getOperand(2)); // True Tmp3 = PromoteOp(Node->getOperand(3)); // False - Result = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0), + Result = DAG.getNode(ISD::SELECT_CC, dl, NVT, Node->getOperand(0), Node->getOperand(1), Tmp2, Tmp3, Node->getOperand(4)); break; case ISD::BSWAP: Tmp1 = Node->getOperand(0); - Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1); - Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1); - Result = DAG.getNode(ISD::SRL, NVT, Tmp1, + Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1); + Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); + Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, DAG.getConstant(NVT.getSizeInBits() - VT.getSizeInBits(), TLI.getShiftAmountTy())); @@ -4916,24 +4917,24 @@ SDValue SelectionDAGLegalize::PromoteOp(SDValue Op) { case ISD::CTTZ: case ISD::CTLZ: // Zero extend the argument - Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Node->getOperand(0)); + Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); // Perform the larger operation, then subtract if needed. - Tmp1 = DAG.getNode(Node->getOpcode(), NVT, Tmp1); + Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); switch(Node->getOpcode()) { case ISD::CTPOP: Result = Tmp1; break; case ISD::CTTZ: // if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT), ISD::SETEQ); - Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, + Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, DAG.getConstant(VT.getSizeInBits(), NVT), Tmp1); break; case ISD::CTLZ: //Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) - Result = DAG.getNode(ISD::SUB, NVT, Tmp1, + Result = DAG.getNode(ISD::SUB, dl, NVT, Tmp1, DAG.getConstant(NVT.getSizeInBits() - VT.getSizeInBits(), NVT)); break; @@ -5385,7 +5386,8 @@ void SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT, /// The resultant code need not be legal. SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, MVT SlotVT, - MVT DestVT) { + MVT DestVT, + DebugLoc dl) { // Create the stack frame object. unsigned SrcAlign = TLI.getTargetData()->getPrefTypeAlignment( SrcOp.getValueType().getTypeForMVT()); @@ -5406,24 +5408,25 @@ SDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, SDValue Store; if (SrcSize > SlotSize) - Store = DAG.getTruncStore(DAG.getEntryNode(), SrcOp, FIPtr, + Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, SV, 0, SlotVT, false, SrcAlign); else { assert(SrcSize == SlotSize && "Invalid store"); - Store = DAG.getStore(DAG.getEntryNode(), SrcOp, FIPtr, + Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, SV, 0, false, SrcAlign); } // Result is a load from the stack slot. if (SlotSize == DestSize) - return DAG.getLoad(DestVT, Store, FIPtr, SV, 0, false, DestAlign); + return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, DestAlign); assert(SlotSize < DestSize && "Unknown extension!"); - return DAG.getExtLoad(ISD::EXTLOAD, DestVT, Store, FIPtr, SV, 0, SlotVT, + return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, SV, 0, SlotVT, false, DestAlign); } SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { + DebugLoc dl = Node->getDebugLoc(); // Create a vector sized/aligned stack slot, store the value to element #0, // then load the whole vector back out. SDValue StackPtr = DAG.CreateStackTemporary(Node->getValueType(0)); @@ -5431,9 +5434,10 @@ SDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { FrameIndexSDNode *StackPtrFI = cast(StackPtr); int SPFI = StackPtrFI->getIndex(); - SDValue Ch = DAG.getStore(DAG.getEntryNode(), Node->getOperand(0), StackPtr, + SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Node->getOperand(0), + StackPtr, PseudoSourceValue::getFixedStack(SPFI), 0); - return DAG.getLoad(Node->getValueType(0), Ch, StackPtr, + return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr, PseudoSourceValue::getFixedStack(SPFI), 0); } @@ -5447,6 +5451,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { unsigned NumElems = Node->getNumOperands(); bool isOnlyLowElement = true; SDValue SplatValue = Node->getOperand(0); + DebugLoc dl = Node->getDebugLoc(); // FIXME: it would be far nicer to change this into map // and use a bitmask instead of a list of elements. @@ -5475,9 +5480,9 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { if (isOnlyLowElement) { // If the low element is an undef too, then this whole things is an undef. if (Node->getOperand(0).getOpcode() == ISD::UNDEF) - return DAG.getNode(ISD::UNDEF, Node->getValueType(0)); + return DAG.getNode(ISD::UNDEF, dl, Node->getValueType(0)); // Otherwise, turn this into a scalar_to_vector node. - return DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), + return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, Node->getValueType(0), Node->getOperand(0)); } @@ -5502,7 +5507,7 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { Constant *CP = ConstantVector::get(CV); SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); unsigned Alignment = 1 << cast(CPIdx)->getAlignment(); - return DAG.getLoad(VT, DAG.getEntryNode(), CPIdx, + return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, PseudoSourceValue::getConstantPool(), 0, false, Alignment); } @@ -5512,17 +5517,19 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { MVT MaskVT = MVT::getIntVectorWithNumElements(NumElems); SDValue Zero = DAG.getConstant(0, MaskVT.getVectorElementType()); std::vector ZeroVec(NumElems, Zero); - SDValue SplatMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, + SDValue SplatMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT, &ZeroVec[0], ZeroVec.size()); // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it. if (isShuffleLegal(Node->getValueType(0), SplatMask)) { // Get the splatted value into the low element of a vector register. SDValue LowValVec = - DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), SplatValue); + DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, + Node->getValueType(0), SplatValue); // Return shuffle(LowValVec, undef, <0,0,0,0>) - return DAG.getNode(ISD::VECTOR_SHUFFLE, Node->getValueType(0), LowValVec, + return DAG.getNode(ISD::VECTOR_SHUFFLE, dl, + Node->getValueType(0), LowValVec, DAG.getNode(ISD::UNDEF, Node->getValueType(0)), SplatMask); } @@ -5561,21 +5568,21 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { if (Val2.getOpcode() != ISD::UNDEF) MaskVec[Val2Elts[i]] = DAG.getConstant(NumElems, MaskEltVT); else - MaskVec[Val2Elts[i]] = DAG.getNode(ISD::UNDEF, MaskEltVT); + MaskVec[Val2Elts[i]] = DAG.getNode(ISD::UNDEF, dl, MaskEltVT); - SDValue ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, MaskVT, + SDValue ShuffleMask = DAG.getNode(ISD::BUILD_VECTOR, dl, MaskVT, &MaskVec[0], MaskVec.size()); // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it. if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, Node->getValueType(0)) && isShuffleLegal(Node->getValueType(0), ShuffleMask)) { - Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val1); - Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, Node->getValueType(0), Val2); + Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,Node->getValueType(0), Val1); + Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl,Node->getValueType(0), Val2); SDValue Ops[] = { Val1, Val2, ShuffleMask }; // Return shuffle(LoValVec, HiValVec, <0,1,0,1>) - return DAG.getNode(ISD::VECTOR_SHUFFLE, Node->getValueType(0), Ops, 3); + return DAG.getNode(ISD::VECTOR_SHUFFLE, dl,Node->getValueType(0), Ops, 3); } } @@ -5599,33 +5606,34 @@ SDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { unsigned Offset = TypeByteSize*i; SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType()); - Idx = DAG.getNode(ISD::ADD, FIPtr.getValueType(), FIPtr, Idx); + Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx); - Stores.push_back(DAG.getStore(DAG.getEntryNode(), Node->getOperand(i), Idx, - SV, Offset)); + Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, Node->getOperand(i), + Idx, SV, Offset)); } SDValue StoreChain; if (!Stores.empty()) // Not all undef elements? - StoreChain = DAG.getNode(ISD::TokenFactor, MVT::Other, + StoreChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], Stores.size()); else StoreChain = DAG.getEntryNode(); // Result is a load from the stack slot. - return DAG.getLoad(VT, StoreChain, FIPtr, SV, 0); + return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0); } void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp, SDValue Op, SDValue Amt, - SDValue &Lo, SDValue &Hi) { + SDValue &Lo, SDValue &Hi, + DebugLoc dl) { // Expand the subcomponents. SDValue LHSL, LHSH; ExpandOp(Op, LHSL, LHSH); SDValue Ops[] = { LHSL, LHSH, Amt }; MVT VT = LHSL.getValueType(); - Lo = DAG.getNode(NodeOp, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); + Lo = DAG.getNode(NodeOp, dl, DAG.getNodeValueTypes(VT, VT), 2, Ops, 3); Hi = Lo.getValue(1); } @@ -5635,7 +5643,8 @@ void SelectionDAGLegalize::ExpandShiftParts(unsigned NodeOp, /// libcall on this target, return false. Otherwise, return true with the /// low-parts expanded into Lo and Hi. bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, - SDValue &Lo, SDValue &Hi) { + SDValue &Lo, SDValue &Hi, + DebugLoc dl) { assert((Opc == ISD::SHL || Opc == ISD::SRA || Opc == ISD::SRL) && "This is not a shift!"); @@ -5659,15 +5668,17 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, Hi = DAG.getConstant(0, NVT); } else if (Cst > NVTBits) { Lo = DAG.getConstant(0, NVT); - Hi = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst-NVTBits,ShTy)); + Hi = DAG.getNode(ISD::SHL, dl, + NVT, InL, DAG.getConstant(Cst-NVTBits,ShTy)); } else if (Cst == NVTBits) { Lo = DAG.getConstant(0, NVT); Hi = InL; } else { - Lo = DAG.getNode(ISD::SHL, NVT, InL, DAG.getConstant(Cst, ShTy)); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(Cst, ShTy)), - DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(NVTBits-Cst, ShTy))); + Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, DAG.getConstant(Cst, ShTy)); + Hi = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SHL, dl, NVT, InH, DAG.getConstant(Cst, ShTy)), + DAG.getNode(ISD::SRL, dl, NVT, InL, + DAG.getConstant(NVTBits-Cst, ShTy))); } return true; case ISD::SRL: @@ -5675,36 +5686,39 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, Lo = DAG.getConstant(0, NVT); Hi = DAG.getConstant(0, NVT); } else if (Cst > NVTBits) { - Lo = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst-NVTBits,ShTy)); + Lo = DAG.getNode(ISD::SRL, dl, NVT, + InH, DAG.getConstant(Cst-NVTBits,ShTy)); Hi = DAG.getConstant(0, NVT); } else if (Cst == NVTBits) { Lo = InH; Hi = DAG.getConstant(0, NVT); } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy))); - Hi = DAG.getNode(ISD::SRL, NVT, InH, DAG.getConstant(Cst, ShTy)); + Lo = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(Cst, ShTy)), + DAG.getNode(ISD::SHL, dl, NVT, InH, + DAG.getConstant(NVTBits-Cst, ShTy))); + Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, DAG.getConstant(Cst, ShTy)); } return true; case ISD::SRA: if (Cst > VTBits) { - Hi = Lo = DAG.getNode(ISD::SRA, NVT, InH, + Hi = Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); } else if (Cst > NVTBits) { - Lo = DAG.getNode(ISD::SRA, NVT, InH, + Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Cst-NVTBits, ShTy)); - Hi = DAG.getNode(ISD::SRA, NVT, InH, + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); } else if (Cst == NVTBits) { Lo = InH; - Hi = DAG.getNode(ISD::SRA, NVT, InH, + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(NVTBits-1, ShTy)); } else { - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, DAG.getConstant(Cst, ShTy)), - DAG.getNode(ISD::SHL, NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy))); - Hi = DAG.getNode(ISD::SRA, NVT, InH, DAG.getConstant(Cst, ShTy)); + Lo = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SRL, dl, NVT, InL, DAG.getConstant(Cst, ShTy)), + DAG.getNode(ISD::SHL, dl, + NVT, InH, DAG.getConstant(NVTBits-Cst, ShTy))); + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, DAG.getConstant(Cst, ShTy)); } return true; } @@ -5720,7 +5734,7 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, // we can do this as a couple of simple shifts. if (KnownOne.intersects(Mask)) { // Mask out the high bit, which we know is set. - Amt = DAG.getNode(ISD::AND, Amt.getValueType(), Amt, + Amt = DAG.getNode(ISD::AND, dl, Amt.getValueType(), Amt, DAG.getConstant(~Mask, Amt.getValueType())); // Expand the incoming operand to be shifted, so that we have its parts @@ -5729,16 +5743,16 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, switch(Opc) { case ISD::SHL: Lo = DAG.getConstant(0, NVT); // Low part is zero. - Hi = DAG.getNode(ISD::SHL, NVT, InL, Amt); // High part from Lo part. + Hi = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); // High part from Lo part. return true; case ISD::SRL: Hi = DAG.getConstant(0, NVT); // Hi part is zero. - Lo = DAG.getNode(ISD::SRL, NVT, InH, Amt); // Lo part from Hi part. + Lo = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); // Lo part from Hi part. return true; case ISD::SRA: - Hi = DAG.getNode(ISD::SRA, NVT, InH, // Sign extend high part. + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, // Sign extend high part. DAG.getConstant(NVTBits-1, Amt.getValueType())); - Lo = DAG.getNode(ISD::SRA, NVT, InH, Amt); // Lo part from Hi part. + Lo = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); // Lo part from Hi part. return true; } } @@ -5747,7 +5761,7 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, // do this as a couple of simple shifts. if ((KnownZero & Mask) == Mask) { // Compute 32-amt. - SDValue Amt2 = DAG.getNode(ISD::SUB, Amt.getValueType(), + SDValue Amt2 = DAG.getNode(ISD::SUB, dl, Amt.getValueType(), DAG.getConstant(NVTBits, Amt.getValueType()), Amt); @@ -5756,22 +5770,22 @@ bool SelectionDAGLegalize::ExpandShift(unsigned Opc, SDValue Op,SDValue Amt, ExpandOp(Op, InL, InH); switch(Opc) { case ISD::SHL: - Lo = DAG.getNode(ISD::SHL, NVT, InL, Amt); - Hi = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SHL, NVT, InH, Amt), - DAG.getNode(ISD::SRL, NVT, InL, Amt2)); + Lo = DAG.getNode(ISD::SHL, dl, NVT, InL, Amt); + Hi = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SHL, dl, NVT, InH, Amt), + DAG.getNode(ISD::SRL, dl, NVT, InL, Amt2)); return true; case ISD::SRL: - Hi = DAG.getNode(ISD::SRL, NVT, InH, Amt); - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, Amt), - DAG.getNode(ISD::SHL, NVT, InH, Amt2)); + Hi = DAG.getNode(ISD::SRL, dl, NVT, InH, Amt); + Lo = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SRL, dl, NVT, InL, Amt), + DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2)); return true; case ISD::SRA: - Hi = DAG.getNode(ISD::SRA, NVT, InH, Amt); - Lo = DAG.getNode(ISD::OR, NVT, - DAG.getNode(ISD::SRL, NVT, InL, Amt), - DAG.getNode(ISD::SHL, NVT, InH, Amt2)); + Hi = DAG.getNode(ISD::SRA, dl, NVT, InH, Amt); + Lo = DAG.getNode(ISD::OR, dl, NVT, + DAG.getNode(ISD::SRL, dl, NVT, InL, Amt), + DAG.getNode(ISD::SHL, dl, NVT, InH, Amt2)); return true; } } @@ -6262,54 +6276,55 @@ SDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, /// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. /// -SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op) { +SDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) { MVT VT = Op.getValueType(); MVT SHVT = TLI.getShiftAmountTy(); SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8; switch (VT.getSimpleVT()) { default: assert(0 && "Unhandled Expand type in BSWAP!"); abort(); case MVT::i16: - Tmp2 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT)); - Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT)); - return DAG.getNode(ISD::OR, VT, Tmp1, Tmp2); + Tmp2 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); + Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); + return DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2); case MVT::i32: - Tmp4 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT)); - Tmp3 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT)); - Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT)); - Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT)); - Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(0xFF0000, VT)); - Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(0xFF00, VT)); - Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3); - Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1); - return DAG.getNode(ISD::OR, VT, Tmp4, Tmp2); + Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); + Tmp3 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); + Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); + Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); + Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(0xFF0000, VT)); + Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, VT)); + Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); + Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); + return DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); case MVT::i64: - Tmp8 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(56, SHVT)); - Tmp7 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(40, SHVT)); - Tmp6 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(24, SHVT)); - Tmp5 = DAG.getNode(ISD::SHL, VT, Op, DAG.getConstant(8, SHVT)); - Tmp4 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(8, SHVT)); - Tmp3 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(24, SHVT)); - Tmp2 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(40, SHVT)); - Tmp1 = DAG.getNode(ISD::SRL, VT, Op, DAG.getConstant(56, SHVT)); - Tmp7 = DAG.getNode(ISD::AND, VT, Tmp7, DAG.getConstant(255ULL<<48, VT)); - Tmp6 = DAG.getNode(ISD::AND, VT, Tmp6, DAG.getConstant(255ULL<<40, VT)); - Tmp5 = DAG.getNode(ISD::AND, VT, Tmp5, DAG.getConstant(255ULL<<32, VT)); - Tmp4 = DAG.getNode(ISD::AND, VT, Tmp4, DAG.getConstant(255ULL<<24, VT)); - Tmp3 = DAG.getNode(ISD::AND, VT, Tmp3, DAG.getConstant(255ULL<<16, VT)); - Tmp2 = DAG.getNode(ISD::AND, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT)); - Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp7); - Tmp6 = DAG.getNode(ISD::OR, VT, Tmp6, Tmp5); - Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp3); - Tmp2 = DAG.getNode(ISD::OR, VT, Tmp2, Tmp1); - Tmp8 = DAG.getNode(ISD::OR, VT, Tmp8, Tmp6); - Tmp4 = DAG.getNode(ISD::OR, VT, Tmp4, Tmp2); - return DAG.getNode(ISD::OR, VT, Tmp8, Tmp4); + Tmp8 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(56, SHVT)); + Tmp7 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(40, SHVT)); + Tmp6 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); + Tmp5 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); + Tmp4 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); + Tmp3 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); + Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(40, SHVT)); + Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(56, SHVT)); + Tmp7 = DAG.getNode(ISD::AND, dl, VT, Tmp7, DAG.getConstant(255ULL<<48, VT)); + Tmp6 = DAG.getNode(ISD::AND, dl, VT, Tmp6, DAG.getConstant(255ULL<<40, VT)); + Tmp5 = DAG.getNode(ISD::AND, dl, VT, Tmp5, DAG.getConstant(255ULL<<32, VT)); + Tmp4 = DAG.getNode(ISD::AND, dl, VT, Tmp4, DAG.getConstant(255ULL<<24, VT)); + Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(255ULL<<16, VT)); + Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT)); + Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp7); + Tmp6 = DAG.getNode(ISD::OR, dl, VT, Tmp6, Tmp5); + Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); + Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); + Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp6); + Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); + return DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp4); } } /// ExpandBitCount - Expand the specified bitcount instruction into operations. /// -SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { +SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, + DebugLoc dl) { switch (Opc) { default: assert(0 && "Cannot expand this yet!"); case ISD::CTPOP: { @@ -6327,9 +6342,10 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { VT.getVectorElementType().getSizeInBits() : len; SDValue Tmp2 = DAG.getConstant(APInt(EltSize, mask[i]), VT); SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); - Op = DAG.getNode(ISD::ADD, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2), - DAG.getNode(ISD::AND, VT, - DAG.getNode(ISD::SRL, VT, Op, Tmp3),Tmp2)); + Op = DAG.getNode(ISD::ADD, dl, VT, DAG.getNode(ISD::AND, VT, Op, Tmp2), + DAG.getNode(ISD::AND, dl, VT, + DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3), + Tmp2)); } return Op; } @@ -6348,10 +6364,11 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { unsigned len = VT.getSizeInBits(); for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); - Op = DAG.getNode(ISD::OR, VT, Op, DAG.getNode(ISD::SRL, VT, Op, Tmp3)); + Op = DAG.getNode(ISD::OR, dl, VT, Op, + DAG.getNode(ISD::SRL, VT, Op, Tmp3)); } - Op = DAG.getNOT(DebugLoc::getUnknownLoc(), Op, VT); - return DAG.getNode(ISD::CTPOP, VT, Op); + Op = DAG.getNOT(dl, Op, VT); + return DAG.getNode(ISD::CTPOP, dl, VT, Op); } case ISD::CTTZ: { // for now, we use: { return popcount(~x & (x - 1)); } @@ -6359,17 +6376,17 @@ SDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op) { // { return 32 - nlz(~x & (x-1)); } // see also http://www.hackersdelight.org/HDcode/ntz.cc MVT VT = Op.getValueType(); - SDValue Tmp3 = DAG.getNode(ISD::AND, VT, - DAG.getNOT(DebugLoc::getUnknownLoc(), Op, VT), - DAG.getNode(ISD::SUB, VT, Op, + SDValue Tmp3 = DAG.getNode(ISD::AND, dl, VT, + DAG.getNOT(dl, Op, VT), + DAG.getNode(ISD::SUB, dl, VT, Op, DAG.getConstant(1, VT))); // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) - return DAG.getNode(ISD::SUB, VT, + return DAG.getNode(ISD::SUB, dl, VT, DAG.getConstant(VT.getSizeInBits(), VT), - DAG.getNode(ISD::CTLZ, VT, Tmp3)); - return DAG.getNode(ISD::CTPOP, VT, Tmp3); + DAG.getNode(ISD::CTLZ, dl, VT, Tmp3)); + return DAG.getNode(ISD::CTPOP, dl, VT, Tmp3); } } } @@ -6383,6 +6400,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ MVT VT = Op.getValueType(); MVT NVT = TLI.getTypeToTransformTo(VT); SDNode *Node = Op.getNode(); + DebugLoc dl = Node->getDebugLoc(); assert(getTypeAction(VT) == Expand && "Not an expanded type!"); assert(((NVT.isInteger() && NVT.bitsLT(VT)) || VT.isFloatingPoint() || VT.isVector()) && "Cannot expand to FP value or to larger int value!"); @@ -6405,9 +6423,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ TargetLowering::Custom) { SDValue SrcLo, SrcHi, Src; ExpandOp(Op.getOperand(0), SrcLo, SrcHi); - Src = DAG.getNode(ISD::BUILD_PAIR, VT, SrcLo, SrcHi); + Src = DAG.getNode(ISD::BUILD_PAIR, dl, VT, SrcLo, SrcHi); SDValue Result = TLI.LowerOperation( - DAG.getNode(ISD::FP_ROUND_INREG, VT, Src, Op.getOperand(1)), DAG); + DAG.getNode(ISD::FP_ROUND_INREG, dl, VT, Src, Op.getOperand(1)), DAG); assert(Result.getNode()->getOpcode() == ISD::BUILD_PAIR); Lo = Result.getNode()->getOperand(0); Hi = Result.getNode()->getOperand(1); @@ -6430,8 +6448,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ Lo = ExpandEXTRACT_VECTOR_ELT(Op); return ExpandOp(Lo, Lo, Hi); case ISD::UNDEF: - Lo = DAG.getNode(ISD::UNDEF, NVT); - Hi = DAG.getNode(ISD::UNDEF, NVT); + Lo = DAG.getNode(ISD::UNDEF, dl, NVT); + Hi = DAG.getNode(ISD::UNDEF, dl, NVT); break; case ISD::Constant: { unsigned NVTBits = NVT.getSizeInBits(); @@ -6478,28 +6496,28 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ case ISD::SIGN_EXTEND_INREG: ExpandOp(Node->getOperand(0), Lo, Hi); // sext_inreg the low part if needed. - Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, NVT, Lo, Node->getOperand(1)); + Lo = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, NVT, Lo, Node->getOperand(1)); // The high part gets the sign extension from the lo-part. This handles // things like sextinreg V:i64 from i8. - Hi = DAG.getNode(ISD::SRA, NVT, Lo, + Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, DAG.getConstant(NVT.getSizeInBits()-1, TLI.getShiftAmountTy())); break; case ISD::BSWAP: { ExpandOp(Node->getOperand(0), Lo, Hi); - SDValue TempLo = DAG.getNode(ISD::BSWAP, NVT, Hi); - Hi = DAG.getNode(ISD::BSWAP, NVT, Lo); + SDValue TempLo = DAG.getNode(ISD::BSWAP, dl, NVT, Hi); + Hi = DAG.getNode(ISD::BSWAP, dl, NVT, Lo); Lo = TempLo; break; } case ISD::CTPOP: ExpandOp(Node->getOperand(0), Lo, Hi); - Lo = DAG.getNode(ISD::ADD, NVT, // ctpop(HL) -> ctpop(H)+ctpop(L) - DAG.getNode(ISD::CTPOP, NVT, Lo), - DAG.getNode(ISD::CTPOP, NVT, Hi)); + Lo = DAG.getNode(ISD::ADD, dl, NVT, // ctpop(HL) -> ctpop(H)+ctpop(L) + DAG.getNode(ISD::CTPOP, dl, NVT, Lo), + DAG.getNode(ISD::CTPOP, dl, NVT, Hi)); Hi = DAG.getConstant(0, NVT); break; @@ -6507,13 +6525,13 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // ctlz (HL) -> ctlz(H) != 32 ? ctlz(H) : (ctlz(L)+32) ExpandOp(Node->getOperand(0), Lo, Hi); SDValue BitsC = DAG.getConstant(NVT.getSizeInBits(), NVT); - SDValue HLZ = DAG.getNode(ISD::CTLZ, NVT, Hi); - SDValue TopNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), HLZ, BitsC, - ISD::SETNE); - SDValue LowPart = DAG.getNode(ISD::CTLZ, NVT, Lo); - LowPart = DAG.getNode(ISD::ADD, NVT, LowPart, BitsC); + SDValue HLZ = DAG.getNode(ISD::CTLZ, dl, NVT, Hi); + SDValue TopNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), HLZ, + BitsC, ISD::SETNE); + SDValue LowPart = DAG.getNode(ISD::CTLZ, dl, NVT, Lo); + LowPart = DAG.getNode(ISD::ADD, dl, NVT, LowPart, BitsC); - Lo = DAG.getNode(ISD::SELECT, NVT, TopNotZero, HLZ, LowPart); + Lo = DAG.getNode(ISD::SELECT, dl, NVT, TopNotZero, HLZ, LowPart); Hi = DAG.getConstant(0, NVT); break; } @@ -6522,13 +6540,13 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // cttz (HL) -> cttz(L) != 32 ? cttz(L) : (cttz(H)+32) ExpandOp(Node->getOperand(0), Lo, Hi); SDValue BitsC = DAG.getConstant(NVT.getSizeInBits(), NVT); - SDValue LTZ = DAG.getNode(ISD::CTTZ, NVT, Lo); - SDValue BotNotZero = DAG.getSetCC(TLI.getSetCCResultType(NVT), LTZ, BitsC, - ISD::SETNE); - SDValue HiPart = DAG.getNode(ISD::CTTZ, NVT, Hi); - HiPart = DAG.getNode(ISD::ADD, NVT, HiPart, BitsC); + SDValue LTZ = DAG.getNode(ISD::CTTZ, dl, NVT, Lo); + SDValue BotNotZero = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), LTZ, + BitsC, ISD::SETNE); + SDValue HiPart = DAG.getNode(ISD::CTTZ, dl, NVT, Hi); + HiPart = DAG.getNode(ISD::ADD, dl, NVT, HiPart, BitsC); - Lo = DAG.getNode(ISD::SELECT, NVT, BotNotZero, LTZ, HiPart); + Lo = DAG.getNode(ISD::SELECT, dl, NVT, BotNotZero, LTZ, HiPart); Hi = DAG.getConstant(0, NVT); break; } @@ -6558,7 +6576,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ bool isVolatile = LD->isVolatile(); if (ExtType == ISD::NON_EXTLOAD) { - Lo = DAG.getLoad(NVT, Ch, Ptr, SV, SVOffset, + Lo = DAG.getLoad(NVT, dl, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); if (VT == MVT::f32 || VT == MVT::f64) { // f32->i32 or f64->i64 one to one expansion. @@ -6572,16 +6590,16 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // Increment the pointer to the other half. unsigned IncrementSize = Lo.getValueType().getSizeInBits()/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; Alignment = MinAlign(Alignment, IncrementSize); - Hi = DAG.getLoad(NVT, Ch, Ptr, SV, SVOffset, + Hi = DAG.getLoad(NVT, dl, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); // Build a factor node to remember that this load is independent of the // other one. - SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); // Remember that we legalized the chain. @@ -6594,19 +6612,19 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ if ((VT == MVT::f64 && EVT == MVT::f32) || (VT == MVT::ppcf128 && (EVT==MVT::f64 || EVT==MVT::f32))) { // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND - SDValue Load = DAG.getLoad(EVT, Ch, Ptr, SV, + SDValue Load = DAG.getLoad(EVT, dl, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); // Remember that we legalized the chain. AddLegalizedOperand(SDValue(Node, 1), LegalizeOp(Load.getValue(1))); - ExpandOp(DAG.getNode(ISD::FP_EXTEND, VT, Load), Lo, Hi); + ExpandOp(DAG.getNode(ISD::FP_EXTEND, dl, VT, Load), Lo, Hi); break; } if (EVT == NVT) - Lo = DAG.getLoad(NVT, Ch, Ptr, SV, + Lo = DAG.getLoad(NVT, dl, Ch, Ptr, SV, SVOffset, isVolatile, Alignment); else - Lo = DAG.getExtLoad(ExtType, NVT, Ch, Ptr, SV, + Lo = DAG.getExtLoad(ExtType, dl, NVT, Ch, Ptr, SV, SVOffset, EVT, isVolatile, Alignment); @@ -6617,14 +6635,14 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // The high part is obtained by SRA'ing all but one of the bits of the // lo part. unsigned LoSize = Lo.getValueType().getSizeInBits(); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, + Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); } else if (ExtType == ISD::ZEXTLOAD) { // The high part is just a zero. Hi = DAG.getConstant(0, NVT); } else /* if (ExtType == ISD::EXTLOAD) */ { // The high part is undefined. - Hi = DAG.getNode(ISD::UNDEF, NVT); + Hi = DAG.getNode(ISD::UNDEF, dl, NVT); } } break; @@ -6635,8 +6653,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ SDValue LL, LH, RL, RH; ExpandOp(Node->getOperand(0), LL, LH); ExpandOp(Node->getOperand(1), RL, RH); - Lo = DAG.getNode(Node->getOpcode(), NVT, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NVT, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), dl, NVT, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), dl, NVT, LH, RH); break; } case ISD::SELECT: { @@ -6645,9 +6663,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ ExpandOp(Node->getOperand(2), RL, RH); if (getTypeAction(NVT) == Expand) NVT = TLI.getTypeToExpandTo(NVT); - Lo = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), LL, RL); + Lo = DAG.getNode(ISD::SELECT, dl, NVT, Node->getOperand(0), LL, RL); if (VT != MVT::f32) - Hi = DAG.getNode(ISD::SELECT, NVT, Node->getOperand(0), LH, RH); + Hi = DAG.getNode(ISD::SELECT, dl, NVT, Node->getOperand(0), LH, RH); break; } case ISD::SELECT_CC: { @@ -6656,35 +6674,35 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ ExpandOp(Node->getOperand(3), FL, FH); if (getTypeAction(NVT) == Expand) NVT = TLI.getTypeToExpandTo(NVT); - Lo = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0), + Lo = DAG.getNode(ISD::SELECT_CC, dl, NVT, Node->getOperand(0), Node->getOperand(1), TL, FL, Node->getOperand(4)); if (VT != MVT::f32) - Hi = DAG.getNode(ISD::SELECT_CC, NVT, Node->getOperand(0), + Hi = DAG.getNode(ISD::SELECT_CC, dl, NVT, Node->getOperand(0), Node->getOperand(1), TH, FH, Node->getOperand(4)); break; } case ISD::ANY_EXTEND: // The low part is any extension of the input (which degenerates to a copy). - Lo = DAG.getNode(ISD::ANY_EXTEND, NVT, Node->getOperand(0)); + Lo = DAG.getNode(ISD::ANY_EXTEND, dl, NVT, Node->getOperand(0)); // The high part is undefined. - Hi = DAG.getNode(ISD::UNDEF, NVT); + Hi = DAG.getNode(ISD::UNDEF, dl, NVT); break; case ISD::SIGN_EXTEND: { // The low part is just a sign extension of the input (which degenerates to // a copy). - Lo = DAG.getNode(ISD::SIGN_EXTEND, NVT, Node->getOperand(0)); + Lo = DAG.getNode(ISD::SIGN_EXTEND, dl, NVT, Node->getOperand(0)); // The high part is obtained by SRA'ing all but one of the bits of the lo // part. unsigned LoSize = Lo.getValueType().getSizeInBits(); - Hi = DAG.getNode(ISD::SRA, NVT, Lo, + Hi = DAG.getNode(ISD::SRA, dl, NVT, Lo, DAG.getConstant(LoSize-1, TLI.getShiftAmountTy())); break; } case ISD::ZERO_EXTEND: // The low part is just a zero extension of the input (which degenerates to // a copy). - Lo = DAG.getNode(ISD::ZERO_EXTEND, NVT, Node->getOperand(0)); + Lo = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); // The high part is just a zero. Hi = DAG.getConstant(0, NVT); @@ -6698,7 +6716,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // The low part is now either the right size, or it is closer. If not the // right size, make an illegal truncate so we recursively expand it. if (NewLo.getValueType() != Node->getValueType(0)) - NewLo = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), NewLo); + NewLo = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), NewLo); ExpandOp(NewLo, Lo, Hi); break; } @@ -6712,12 +6730,12 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ case Legal: Tmp = LegalizeOp(Node->getOperand(0)); break; case Promote: Tmp = PromoteOp (Node->getOperand(0)); break; } - Tmp = TLI.LowerOperation(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp), DAG); + Tmp = TLI.LowerOperation(DAG.getNode(ISD::BIT_CONVERT, dl, VT, Tmp), DAG); } // f32 / f64 must be expanded to i32 / i64. if (VT == MVT::f32 || VT == MVT::f64) { - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0)); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0)); if (getTypeAction(NVT) == Expand) ExpandOp(Lo, Lo, Hi); break; @@ -6733,7 +6751,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // Turn this into a load/store pair by default. if (Tmp.getNode() == 0) - Tmp = EmitStackConvert(Node->getOperand(0), VT, VT); + Tmp = EmitStackConvert(Node->getOperand(0), VT, VT, dl); ExpandOp(Tmp, Lo, Hi); break; @@ -6772,10 +6790,10 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // so substitute a target-dependent pseudo and expand that later. SDValue In2Lo, In2Hi, In2; ExpandOp(Op.getOperand(2), In2Lo, In2Hi); - In2 = DAG.getNode(ISD::BUILD_PAIR, VT, In2Lo, In2Hi); + In2 = DAG.getNode(ISD::BUILD_PAIR, dl, VT, In2Lo, In2Hi); AtomicSDNode* Anode = cast(Node); SDValue Replace = - DAG.getAtomic(Op.getOpcode(), Anode->getMemoryVT(), + DAG.getAtomic(Op.getOpcode(), dl, Anode->getMemoryVT(), Op.getOperand(0), Op.getOperand(1), In2, Anode->getSrcValue(), Anode->getAlignment()); SDValue Result = TLI.LowerOperation(Replace, DAG); @@ -6796,7 +6814,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ case Promote: Op = PromoteOp (Node->getOperand(0)); break; } - Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_SINT, VT, Op), DAG); + Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_SINT, dl, VT, Op), DAG); // Now that the custom expander is done, expand the result, which is still // VT. @@ -6822,7 +6840,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ case Promote: Op = PromoteOp (Node->getOperand(0)); break; } - Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_UINT, VT, Op), DAG); + Op = TLI.LowerOperation(DAG.getNode(ISD::FP_TO_UINT, dl, VT, Op), DAG); // Now that the custom expander is done, expand the result. if (Op.getNode()) { @@ -6842,7 +6860,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // If the target wants custom lowering, do so. SDValue ShiftAmt = LegalizeOp(Node->getOperand(1)); if (TLI.getOperationAction(ISD::SHL, VT) == TargetLowering::Custom) { - SDValue Op = DAG.getNode(ISD::SHL, VT, Node->getOperand(0), ShiftAmt); + SDValue Op = DAG.getNode(ISD::SHL, dl, VT, Node->getOperand(0), ShiftAmt); Op = TLI.LowerOperation(Op, DAG); if (Op.getNode()) { // Now that the custom expander is done, expand the result, which is @@ -6862,17 +6880,17 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ ExpandOp(Node->getOperand(0), LoOps[0], HiOps[0]); SDVTList VTList = DAG.getVTList(LoOps[0].getValueType(), MVT::Flag); LoOps[1] = LoOps[0]; - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[1] = HiOps[0]; HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); break; } } // If we can emit an efficient shift operation, do so now. - if (ExpandShift(ISD::SHL, Node->getOperand(0), ShiftAmt, Lo, Hi)) + if (ExpandShift(ISD::SHL, Node->getOperand(0), ShiftAmt, Lo, Hi, dl)) break; // If this target supports SHL_PARTS, use it. @@ -6880,7 +6898,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ TLI.getOperationAction(ISD::SHL_PARTS, NVT); if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || Action == TargetLowering::Custom) { - ExpandShiftParts(ISD::SHL_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi); + ExpandShiftParts(ISD::SHL_PARTS, Node->getOperand(0), + ShiftAmt, Lo, Hi, dl); break; } @@ -6904,7 +6923,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ } // If we can emit an efficient shift operation, do so now. - if (ExpandShift(ISD::SRA, Node->getOperand(0), ShiftAmt, Lo, Hi)) + if (ExpandShift(ISD::SRA, Node->getOperand(0), ShiftAmt, Lo, Hi, dl)) break; // If this target supports SRA_PARTS, use it. @@ -6912,7 +6931,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ TLI.getOperationAction(ISD::SRA_PARTS, NVT); if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || Action == TargetLowering::Custom) { - ExpandShiftParts(ISD::SRA_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi); + ExpandShiftParts(ISD::SRA_PARTS, Node->getOperand(0), + ShiftAmt, Lo, Hi, dl); break; } @@ -6925,7 +6945,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // If the target wants custom lowering, do so. SDValue ShiftAmt = LegalizeOp(Node->getOperand(1)); if (TLI.getOperationAction(ISD::SRL, VT) == TargetLowering::Custom) { - SDValue Op = DAG.getNode(ISD::SRL, VT, Node->getOperand(0), ShiftAmt); + SDValue Op = DAG.getNode(ISD::SRL, dl, VT, Node->getOperand(0), ShiftAmt); Op = TLI.LowerOperation(Op, DAG); if (Op.getNode()) { // Now that the custom expander is done, expand the result, which is @@ -6936,7 +6956,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ } // If we can emit an efficient shift operation, do so now. - if (ExpandShift(ISD::SRL, Node->getOperand(0), ShiftAmt, Lo, Hi)) + if (ExpandShift(ISD::SRL, Node->getOperand(0), ShiftAmt, Lo, Hi, dl)) break; // If this target supports SRL_PARTS, use it. @@ -6944,7 +6964,8 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ TLI.getOperationAction(ISD::SRL_PARTS, NVT); if ((Action == TargetLowering::Legal && TLI.isTypeLegal(NVT)) || Action == TargetLowering::Custom) { - ExpandShiftParts(ISD::SRL_PARTS, Node->getOperand(0), ShiftAmt, Lo, Hi); + ExpandShiftParts(ISD::SRL_PARTS, + Node->getOperand(0), ShiftAmt, Lo, Hi, dl); break; } @@ -6988,38 +7009,38 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ if(hasCarry) { SDVTList VTList = DAG.getVTList(LHSL.getValueType(), MVT::Flag); if (Node->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); } break; } else { if (Node->getOpcode() == ISD::ADD) { - Lo = DAG.getNode(ISD::ADD, NVT, LoOps, 2); - Hi = DAG.getNode(ISD::ADD, NVT, HiOps, 2); - SDValue Cmp1 = DAG.getSetCC(TLI.getSetCCResultType(NVT), + Lo = DAG.getNode(ISD::ADD, dl, NVT, LoOps, 2); + Hi = DAG.getNode(ISD::ADD, dl, NVT, HiOps, 2); + SDValue Cmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[0], ISD::SETULT); - SDValue Carry1 = DAG.getNode(ISD::SELECT, NVT, Cmp1, + SDValue Carry1 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp1, DAG.getConstant(1, NVT), DAG.getConstant(0, NVT)); - SDValue Cmp2 = DAG.getSetCC(TLI.getSetCCResultType(NVT), + SDValue Cmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), Lo, LoOps[1], ISD::SETULT); - SDValue Carry2 = DAG.getNode(ISD::SELECT, NVT, Cmp2, + SDValue Carry2 = DAG.getNode(ISD::SELECT, dl, NVT, Cmp2, DAG.getConstant(1, NVT), Carry1); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, Carry2); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, Carry2); } else { - Lo = DAG.getNode(ISD::SUB, NVT, LoOps, 2); - Hi = DAG.getNode(ISD::SUB, NVT, HiOps, 2); - SDValue Cmp = DAG.getSetCC(NVT, LoOps[0], LoOps[1], ISD::SETULT); - SDValue Borrow = DAG.getNode(ISD::SELECT, NVT, Cmp, + Lo = DAG.getNode(ISD::SUB, dl, NVT, LoOps, 2); + Hi = DAG.getNode(ISD::SUB, dl, NVT, HiOps, 2); + SDValue Cmp = DAG.getSetCC(dl, NVT, LoOps[0], LoOps[1], ISD::SETULT); + SDValue Borrow = DAG.getNode(ISD::SELECT, dl, NVT, Cmp, DAG.getConstant(1, NVT), DAG.getConstant(0, NVT)); - Hi = DAG.getNode(ISD::SUB, NVT, Hi, Borrow); + Hi = DAG.getNode(ISD::SUB, dl, NVT, Hi, Borrow); } break; } @@ -7036,13 +7057,13 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ SDValue HiOps[3] = { LHSH, RHSH }; if (Node->getOpcode() == ISD::ADDC) { - Lo = DAG.getNode(ISD::ADDC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::ADDC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::ADDE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::ADDE, dl, VTList, HiOps, 3); } else { - Lo = DAG.getNode(ISD::SUBC, VTList, LoOps, 2); + Lo = DAG.getNode(ISD::SUBC, dl, VTList, LoOps, 2); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(ISD::SUBE, VTList, HiOps, 3); + Hi = DAG.getNode(ISD::SUBE, dl, VTList, HiOps, 3); } // Remember that we legalized the flag. AddLegalizedOperand(Op.getValue(1), LegalizeOp(Hi.getValue(1))); @@ -7058,9 +7079,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ SDValue LoOps[3] = { LHSL, RHSL, Node->getOperand(2) }; SDValue HiOps[3] = { LHSH, RHSH }; - Lo = DAG.getNode(Node->getOpcode(), VTList, LoOps, 3); + Lo = DAG.getNode(Node->getOpcode(), dl, VTList, LoOps, 3); HiOps[2] = Lo.getValue(1); - Hi = DAG.getNode(Node->getOpcode(), VTList, HiOps, 3); + Hi = DAG.getNode(Node->getOpcode(), dl, VTList, HiOps, 3); // Remember that we legalized the flag. AddLegalizedOperand(Op.getValue(1), LegalizeOp(Hi.getValue(1))); @@ -7094,14 +7115,14 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // The inputs are both zero-extended. if (HasUMUL_LOHI) { // We can emit a umul_lohi. - Lo = DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Lo = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); Hi = SDValue(Lo.getNode(), 1); break; } if (HasMULHU) { // We can emit a mulhu+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); + Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); break; } } @@ -7109,36 +7130,36 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ // The input values are both sign-extended. if (HasSMUL_LOHI) { // We can emit a smul_lohi. - Lo = DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(NVT, NVT), LL, RL); + Lo = DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); Hi = SDValue(Lo.getNode(), 1); break; } if (HasMULHS) { // We can emit a mulhs+mul. - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHS, NVT, LL, RL); + Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHS, dl, NVT, LL, RL); break; } } if (HasUMUL_LOHI) { // Lo,Hi = umul LHS, RHS. - SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, + SDValue UMulLOHI = DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(NVT, NVT), LL, RL); Lo = UMulLOHI; Hi = UMulLOHI.getValue(1); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); break; } if (HasMULHU) { - Lo = DAG.getNode(ISD::MUL, NVT, LL, RL); - Hi = DAG.getNode(ISD::MULHU, NVT, LL, RL); - RH = DAG.getNode(ISD::MUL, NVT, LL, RH); - LH = DAG.getNode(ISD::MUL, NVT, LH, RL); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, RH); - Hi = DAG.getNode(ISD::ADD, NVT, Hi, LH); + Lo = DAG.getNode(ISD::MUL, dl, NVT, LL, RL); + Hi = DAG.getNode(ISD::MULHU, dl, NVT, LL, RL); + RH = DAG.getNode(ISD::MUL, dl, NVT, LL, RH); + LH = DAG.getNode(ISD::MUL, dl, NVT, LH, RL); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, RH); + Hi = DAG.getNode(ISD::ADD, dl, NVT, Hi, LH); break; } } @@ -7194,7 +7215,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ Node->getOperand(0).getValueType()==MVT::f64); const uint64_t zero = 0; if (Node->getOperand(0).getValueType()==MVT::f32) - Hi = DAG.getNode(ISD::FP_EXTEND, MVT::f64, Node->getOperand(0)); + Hi = DAG.getNode(ISD::FP_EXTEND, dl, MVT::f64, Node->getOperand(0)); else Hi = Node->getOperand(0); Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); @@ -7298,19 +7319,19 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ if (VT == MVT::ppcf128) { SDValue Tmp; ExpandOp(Node->getOperand(0), Lo, Tmp); - Hi = DAG.getNode(ISD::FABS, NVT, Tmp); + Hi = DAG.getNode(ISD::FABS, dl, NVT, Tmp); // lo = hi==fabs(hi) ? lo : -lo; - Lo = DAG.getNode(ISD::SELECT_CC, NVT, Hi, Tmp, - Lo, DAG.getNode(ISD::FNEG, NVT, Lo), + Lo = DAG.getNode(ISD::SELECT_CC, dl, NVT, Hi, Tmp, + Lo, DAG.getNode(ISD::FNEG, dl, NVT, Lo), DAG.getCondCode(ISD::SETEQ)); break; } SDValue Mask = (VT == MVT::f64) ? DAG.getConstantFP(BitsToDouble(~(1ULL << 63)), VT) : DAG.getConstantFP(BitsToFloat(~(1U << 31)), VT); - Mask = DAG.getNode(ISD::BIT_CONVERT, NVT, Mask); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0)); - Lo = DAG.getNode(ISD::AND, NVT, Lo, Mask); + Mask = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0)); + Lo = DAG.getNode(ISD::AND, dl, NVT, Lo, Mask); if (getTypeAction(NVT) == Expand) ExpandOp(Lo, Lo, Hi); break; @@ -7318,16 +7339,16 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ case ISD::FNEG: { if (VT == MVT::ppcf128) { ExpandOp(Node->getOperand(0), Lo, Hi); - Lo = DAG.getNode(ISD::FNEG, MVT::f64, Lo); - Hi = DAG.getNode(ISD::FNEG, MVT::f64, Hi); + Lo = DAG.getNode(ISD::FNEG, dl, MVT::f64, Lo); + Hi = DAG.getNode(ISD::FNEG, dl, MVT::f64, Hi); break; } SDValue Mask = (VT == MVT::f64) ? DAG.getConstantFP(BitsToDouble(1ULL << 63), VT) : DAG.getConstantFP(BitsToFloat(1U << 31), VT); - Mask = DAG.getNode(ISD::BIT_CONVERT, NVT, Mask); - Lo = DAG.getNode(ISD::BIT_CONVERT, NVT, Node->getOperand(0)); - Lo = DAG.getNode(ISD::XOR, NVT, Lo, Mask); + Mask = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Mask); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Node->getOperand(0)); + Lo = DAG.getNode(ISD::XOR, dl, NVT, Lo, Mask); if (getTypeAction(NVT) == Expand) ExpandOp(Lo, Lo, Hi); break; @@ -7348,9 +7369,9 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ if (getTypeAction(SrcVT) == Promote) { SDValue Tmp = PromoteOp(Node->getOperand(0)); Tmp = isSigned - ? DAG.getNode(ISD::SIGN_EXTEND_INREG, Tmp.getValueType(), Tmp, + ? DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Tmp.getValueType(), Tmp, DAG.getValueType(SrcVT)) - : DAG.getZeroExtendInReg(Tmp, SrcVT); + : DAG.getZeroExtendInReg(Tmp, dl, SrcVT); Node = DAG.UpdateNodeOperands(Op, Tmp).getNode(); SrcVT = Node->getOperand(0).getValueType(); } @@ -7358,19 +7379,20 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ if (VT == MVT::ppcf128 && SrcVT == MVT::i32) { static const uint64_t zero = 0; if (isSigned) { - Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64, + Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f64, Node->getOperand(0))); Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); } else { static const uint64_t TwoE32[] = { 0x41f0000000000000LL, 0 }; - Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, MVT::f64, + Hi = LegalizeOp(DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f64, Node->getOperand(0))); Lo = DAG.getConstantFP(APFloat(APInt(64, 1, &zero)), MVT::f64); - Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); + Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); // X>=0 ? {(f64)x, 0} : {(f64)x, 0} + 2^32 - ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0), + ExpandOp(DAG.getNode(ISD::SELECT_CC, dl, + MVT::ppcf128, Node->getOperand(0), DAG.getConstant(0, MVT::i32), - DAG.getNode(ISD::FADD, MVT::ppcf128, Hi, + DAG.getNode(ISD::FADD, dl, MVT::ppcf128, Hi, DAG.getConstantFP( APFloat(APInt(128, 2, TwoE32)), MVT::ppcf128)), @@ -7383,13 +7405,14 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ if (VT == MVT::ppcf128 && SrcVT == MVT::i64 && !isSigned) { // si64->ppcf128 done by libcall, below static const uint64_t TwoE64[] = { 0x43f0000000000000LL, 0 }; - ExpandOp(DAG.getNode(ISD::SINT_TO_FP, MVT::ppcf128, Node->getOperand(0)), - Lo, Hi); - Hi = DAG.getNode(ISD::BUILD_PAIR, VT, Lo, Hi); + ExpandOp(DAG.getNode(ISD::SINT_TO_FP, dl, MVT::ppcf128, + Node->getOperand(0)), Lo, Hi); + Hi = DAG.getNode(ISD::BUILD_PAIR, dl, VT, Lo, Hi); // x>=0 ? (ppcf128)(i64)x : (ppcf128)(i64)x + 2^64 - ExpandOp(DAG.getNode(ISD::SELECT_CC, MVT::ppcf128, Node->getOperand(0), + ExpandOp(DAG.getNode(ISD::SELECT_CC, dl, MVT::ppcf128, + Node->getOperand(0), DAG.getConstant(0, MVT::i64), - DAG.getNode(ISD::FADD, MVT::ppcf128, Hi, + DAG.getNode(ISD::FADD, dl, MVT::ppcf128, Hi, DAG.getConstantFP( APFloat(APInt(128, 2, TwoE64)), MVT::ppcf128)), @@ -7400,7 +7423,7 @@ void SelectionDAGLegalize::ExpandOp(SDValue Op, SDValue &Lo, SDValue &Hi){ } Lo = ExpandIntToFP(Node->getOpcode() == ISD::SINT_TO_FP, VT, - Node->getOperand(0), Node->getDebugLoc()); + Node->getOperand(0), dl); if (getTypeAction(Lo.getValueType()) == Expand) // float to i32 etc. can be 'expanded' to a single node. ExpandOp(Lo, Lo, Hi); -- GitLab From 026bcde14b17595782b2bcb95138eee1d077c3ee Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 2 Feb 2009 22:32:08 +0000 Subject: [PATCH 644/682] fix TryToFixInvalidVariablyModifiedType to reject negative array sizes llvm-svn: 63557 --- clang/lib/Sema/SemaDecl.cpp | 7 ++++--- clang/test/Sema/struct-decl.c | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d03879e907e5..21fe6e1ce492 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3114,9 +3114,10 @@ static QualType TryToFixInvalidVariablyModifiedType(QualType T, assert(EvalResult.Val.isInt() && "Size expressions must be integers!"); llvm::APSInt &Res = EvalResult.Val.getInt(); - - return Context.getConstantArrayType(VLATy->getElementType(), - Res, ArrayType::Normal, 0); + if (Res >= llvm::APSInt(Res.getBitWidth(), Res.isUnsigned())) + return Context.getConstantArrayType(VLATy->getElementType(), + Res, ArrayType::Normal, 0); + return QualType(); } bool Sema::VerifyBitField(SourceLocation FieldLoc, IdentifierInfo *FieldName, diff --git a/clang/test/Sema/struct-decl.c b/clang/test/Sema/struct-decl.c index cacd84765826..7d7961b16c83 100644 --- a/clang/test/Sema/struct-decl.c +++ b/clang/test/Sema/struct-decl.c @@ -7,4 +7,5 @@ struct bar { struct foo { char name[(int)&((struct bar *)0)->n]; + char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{fields must have a constant size}} }; -- GitLab From 4eda2cbe5f554ec6f6a3884747004caac8d86ec4 Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 2 Feb 2009 22:42:01 +0000 Subject: [PATCH 645/682] MergeValueInto is too smart: it might choose to do the merge the opposite direction. Live interval reconstruction needs to account for this, and scour its maps to prevent dangling references. llvm-svn: 63558 --- llvm/include/llvm/CodeGen/LiveInterval.h | 2 +- llvm/lib/CodeGen/LiveInterval.cpp | 4 +++- llvm/lib/CodeGen/PreAllocSplitting.cpp | 20 ++++++++++++++++++-- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/llvm/include/llvm/CodeGen/LiveInterval.h b/llvm/include/llvm/CodeGen/LiveInterval.h index 7bcc4c7cb88f..fb7448635711 100644 --- a/llvm/include/llvm/CodeGen/LiveInterval.h +++ b/llvm/include/llvm/CodeGen/LiveInterval.h @@ -276,7 +276,7 @@ namespace llvm { /// are found to be equivalent. This eliminates V1, replacing all /// LiveRanges with the V1 value number with the V2 value number. This can /// cause merging of V1/V2 values numbers and compaction of the value space. - void MergeValueNumberInto(VNInfo *V1, VNInfo *V2); + VNInfo* MergeValueNumberInto(VNInfo *V1, VNInfo *V2); /// MergeInClobberRanges - For any live ranges that are not defined in the /// current interval, but are defined in the Clobbers interval, mark them diff --git a/llvm/lib/CodeGen/LiveInterval.cpp b/llvm/lib/CodeGen/LiveInterval.cpp index 6341b9cd5071..40f8cd4388d8 100644 --- a/llvm/lib/CodeGen/LiveInterval.cpp +++ b/llvm/lib/CodeGen/LiveInterval.cpp @@ -591,7 +591,7 @@ void LiveInterval::MergeInClobberRanges(const LiveInterval &Clobbers, /// are found to be equivalent. This eliminates V1, replacing all /// LiveRanges with the V1 value number with the V2 value number. This can /// cause merging of V1/V2 values numbers and compaction of the value space. -void LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { +VNInfo* LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { assert(V1 != V2 && "Identical value#'s are always equivalent!"); // This code actually merges the (numerically) larger value number into the @@ -652,6 +652,8 @@ void LiveInterval::MergeValueNumberInto(VNInfo *V1, VNInfo *V2) { } else { V1->def = ~1U; } + + return V2; } void LiveInterval::Copy(const LiveInterval &RHS, diff --git a/llvm/lib/CodeGen/PreAllocSplitting.cpp b/llvm/lib/CodeGen/PreAllocSplitting.cpp index a538db8be086..99fdb840cc74 100644 --- a/llvm/lib/CodeGen/PreAllocSplitting.cpp +++ b/llvm/lib/CodeGen/PreAllocSplitting.cpp @@ -654,8 +654,24 @@ PreAllocSplitting::PerformPHIConstructionFallBack(MachineBasicBlock::iterator Us } if (MBB->pred_size() == 1 && !RetVNI->hasPHIKill) { - LI->MergeValueNumberInto(RetVNI, IncomingVNs.begin()->second); - Phis[MBB] = RetVNI = IncomingVNs.begin()->second; + VNInfo* OldVN = RetVNI; + VNInfo* NewVN = IncomingVNs.begin()->second; + VNInfo* MergedVN = LI->MergeValueNumberInto(OldVN, NewVN); + if (MergedVN == OldVN) std::swap(OldVN, NewVN); + + for (DenseMap::iterator LOI = LiveOut.begin(), + LOE = LiveOut.end(); LOI != LOE; ++LOI) + if (LOI->second == OldVN) + LOI->second = MergedVN; + for (DenseMap::iterator NVI = NewVNs.begin(), + NVE = NewVNs.end(); NVI != NVE; ++NVI) + if (NVI->second == OldVN) + NVI->second = MergedVN; + for (DenseMap::iterator PI = Phis.begin(), + PE = Phis.end(); PI != PE; ++PI) + if (PI->second == OldVN) + PI->second = MergedVN; + RetVNI = MergedVN; } else { // Otherwise, merge the incoming VNInfos with a phi join. Create a new // VNInfo to represent the joined value. -- GitLab From b92f839f9c2b961bc92601eda81bed503997a811 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Mon, 2 Feb 2009 22:48:49 +0000 Subject: [PATCH 646/682] Improve -fno-opt style option processing to not require an extra option to make the -fno- form on the option. We also document the new form in the CommandLine documentation. llvm-svn: 63559 --- llvm/docs/CommandLine.html | 16 ++++++- llvm/include/llvm/Support/CommandLine.h | 59 +++++++++++-------------- llvm/lib/Support/CommandLine.cpp | 21 +-------- 3 files changed, 42 insertions(+), 54 deletions(-) diff --git a/llvm/docs/CommandLine.html b/llvm/docs/CommandLine.html index 97df9f787cdc..013ff27d1921 100644 --- a/llvm/docs/CommandLine.html +++ b/llvm/docs/CommandLine.html @@ -1447,6 +1447,16 @@ unrecognized option strings to it as values instead of signaling an error. As with cl::CommaSeparated, this modifier only makes sense with a cl::list option. +
    • The cl::AllowInverse +modifier can be used on options that have the form -fopt to +automatically create a corresponding +-fno-opt option. The f can be any single +character, and the opt can be any one or more characters. +The value of the created option is the logical complement of the value +that would have been used if the base form of the option was used. +This modifier only makes sense with an option that uses +a bool parser.
    • +
    @@ -1745,7 +1755,11 @@ for any data type.
  • The parser<bool> specialization is used to convert boolean strings to a boolean value. Currently accepted strings are "true", "TRUE", "True", "1", -"false", "FALSE", "False", and "0".
  • +"false", "FALSE", "False", and "0". The +cl::AllowInverse modifier can be used on an option of the form +-fopt that uses the parser<bool> specialization +to create a corresponding option with the form -fno-opt. See +cl::AllowInverse for details.
  • The parser<boolOrDefault> specialization is used for cases where the value is boolean, diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h index 9b218dab031c..def5ce750140 100644 --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -126,7 +126,8 @@ enum MiscFlags { // Miscellaneous flags to adjust argument CommaSeparated = 0x200, // Should this cl::list split between commas? PositionalEatsArgs = 0x400, // Should this positional cl::list eat -args? Sink = 0x800, // Should this cl::list eat all unknown options? - MiscMask = 0xE00 // Union of the above flags. + AllowInverse = 0x1000, // Can this option take a -Xno- form? + MiscMask = 0x1E00 // Union of the above flags. }; @@ -302,12 +303,6 @@ struct LocationClass { template LocationClass location(Ty &L) { return LocationClass(L); } -// opposite_of - Allow the user to specify which other option this -// option is the opposite of. -// -template -LocationClass opposite_of(Ty &O) { return location(O.getValue()); } - //===----------------------------------------------------------------------===// // Enum valued command line option @@ -542,10 +537,33 @@ struct basic_parser : public basic_parser_impl { // template<> class parser : public basic_parser { + bool IsInvertable; // Should we synthezise a -xno- style option? + const char *ArgStr; public: + void getExtraOptionNames(std::vector &OptionNames) { + if (IsInvertable) { + char *s = new char [strlen(ArgStr) + 3 + 1]; + s[0] = ArgStr[0]; + s[1] = 'n'; + s[2] = 'o'; + s[3] = '-'; + strcpy(&s[4], ArgStr+1); + OptionNames.push_back(s); + } + } + // parse - Return true on error. bool parse(Option &O, const char *ArgName, const std::string &Arg, bool &Val); + template + void initialize(Opt &O) { + if (O.getMiscFlags() & llvm::cl::AllowInverse) + IsInvertable = true; + else + IsInvertable = false; + ArgStr = O.ArgStr; + } + enum ValueExpected getValueExpectedFlagDefault() const { return ValueOptional; } @@ -582,30 +600,6 @@ public: EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); -//-------------------------------------------------- -// parser -class boolInverse { }; -template<> -class parser : public basic_parser { -public: - typedef bool parser_data_type; - // parse - Return true on error. - bool parse(Option &O, const char *ArgName, const std::string &Arg, - bool &Val); - - enum ValueExpected getValueExpectedFlagDefault() const { - return ValueOptional; - } - - // getValueName - Do not print = at all. - virtual const char *getValueName() const { return 0; } - - // An out-of-line virtual method to provide a 'home' for this class. - virtual void anchor(); -}; - -EXTERN_TEMPLATE_INSTANTIATION(class basic_parser); - //-------------------------------------------------- // parser // @@ -947,9 +941,6 @@ EXTERN_TEMPLATE_INSTANTIATION(class opt); EXTERN_TEMPLATE_INSTANTIATION(class opt); EXTERN_TEMPLATE_INSTANTIATION(class opt); -class boolInverse; -typedef opt > inverse_opt; - //===----------------------------------------------------------------------===// // list_storage class diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp index e06f324c8715..2c56e0ffb87e 100644 --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -40,7 +40,6 @@ using namespace cl; // TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); -TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); TEMPLATE_INSTANTIATION(class basic_parser); @@ -56,7 +55,6 @@ void Option::anchor() {} void basic_parser_impl::anchor() {} void parser::anchor() {} void parser::anchor() {} -void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} void parser::anchor() {} @@ -874,6 +872,8 @@ bool parser::parse(Option &O, const char *ArgName, return O.error(": '" + Arg + "' is invalid value for boolean argument! Try 0 or 1"); } + if (IsInvertable && strncmp(ArgName+1, "no-", 3) == 0) + Value = !Value; return false; } @@ -894,23 +894,6 @@ bool parser::parse(Option &O, const char *ArgName, return false; } -// parser implementation -// -bool parser::parse(Option &O, const char *ArgName, - const std::string &Arg, bool &Value) { - if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" || - Arg == "1") { - Value = false; - } else if (Arg == "false" || Arg == "FALSE" - || Arg == "False" || Arg == "0") { - Value = true; - } else { - return O.error(": '" + Arg + - "' is invalid value for boolean argument! Try 0 or 1"); - } - return false; -} - // parser implementation // bool parser::parse(Option &O, const char *ArgName, -- GitLab From b5dd922a926afd22bced94d7e9d176cfccba62ab Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 2 Feb 2009 22:49:46 +0000 Subject: [PATCH 647/682] More DebugLoc propagation. This should be everything except LegalizeOp itself. llvm-svn: 63560 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 212 +++++++++--------- 1 file changed, 112 insertions(+), 100 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index 47450eab939b..ece572a9f013 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -231,7 +231,7 @@ private: SDValue BasePtr, const Value *SV, int SVOffset, unsigned Alignment, bool isVolatile, unsigned LdWidth, - MVT ResType); + MVT ResType, DebugLoc dl); /// StoreWidenVectorOp - Stores a widen vector into non widen memory /// location. It takes @@ -257,7 +257,7 @@ private: SDValue BasePtr, const Value *SV, int SVOffset, unsigned Alignment, bool isVolatile, SDValue ValOp, - unsigned StWidth); + unsigned StWidth, DebugLoc dl); /// isShuffleLegal - Return non-null if a vector shuffle is legal with the /// specified mask and type. Targets can specify exactly which masks they @@ -7481,8 +7481,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, #endif assert(0 && "Unhandled operation in SplitVectorOp!"); case ISD::UNDEF: - Lo = DAG.getNode(ISD::UNDEF, NewVT_Lo); - Hi = DAG.getNode(ISD::UNDEF, NewVT_Hi); + Lo = DAG.getNode(ISD::UNDEF, dl, NewVT_Lo); + Hi = DAG.getNode(ISD::UNDEF, dl, NewVT_Hi); break; case ISD::BUILD_PAIR: Lo = Node->getOperand(0); @@ -7494,10 +7494,10 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, unsigned Index = Idx->getZExtValue(); SDValue ScalarOp = Node->getOperand(1); if (Index < NewNumElts_Lo) - Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Lo, Lo, ScalarOp, + Lo = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVT_Lo, Lo, ScalarOp, DAG.getIntPtrConstant(Index)); else - Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, NewVT_Hi, Hi, ScalarOp, + Hi = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, NewVT_Hi, Hi, ScalarOp, DAG.getIntPtrConstant(Index - NewNumElts_Lo)); break; } @@ -7519,7 +7519,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, for (unsigned i = 0; i != NewNumElts_Lo; ++i) { SDValue IdxNode = Mask.getOperand(i); if (IdxNode.getOpcode() == ISD::UNDEF) { - Ops.push_back(DAG.getNode(ISD::UNDEF, NewEltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, dl, NewEltVT)); continue; } unsigned Idx = cast(IdxNode)->getZExtValue(); @@ -7528,16 +7528,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, InVec = Node->getOperand(1); Idx -= NumElements; } - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec, + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec, DAG.getConstant(Idx, PtrVT))); } - Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &Ops[0], Ops.size()); + Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &Ops[0], Ops.size()); Ops.clear(); for (unsigned i = NewNumElts_Lo; i != NumElements; ++i) { SDValue IdxNode = Mask.getOperand(i); if (IdxNode.getOpcode() == ISD::UNDEF) { - Ops.push_back(DAG.getNode(ISD::UNDEF, NewEltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, dl, NewEltVT)); continue; } unsigned Idx = cast(IdxNode)->getZExtValue(); @@ -7546,20 +7546,20 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, InVec = Node->getOperand(1); Idx -= NumElements; } - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewEltVT, InVec, + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewEltVT, InVec, DAG.getConstant(Idx, PtrVT))); } - Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &Ops[0], Ops.size()); + Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &Ops[0], Ops.size()); break; } case ISD::BUILD_VECTOR: { SmallVector LoOps(Node->op_begin(), Node->op_begin()+NewNumElts_Lo); - Lo = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Lo, &LoOps[0], LoOps.size()); + Lo = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Lo, &LoOps[0], LoOps.size()); SmallVector HiOps(Node->op_begin()+NewNumElts_Lo, Node->op_end()); - Hi = DAG.getNode(ISD::BUILD_VECTOR, NewVT_Hi, &HiOps[0], HiOps.size()); + Hi = DAG.getNode(ISD::BUILD_VECTOR, dl, NewVT_Hi, &HiOps[0], HiOps.size()); break; } case ISD::CONCAT_VECTORS: { @@ -7571,11 +7571,13 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, } else { SmallVector LoOps(Node->op_begin(), Node->op_begin()+NewNumSubvectors); - Lo = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Lo, &LoOps[0], LoOps.size()); + Lo = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewVT_Lo, + &LoOps[0], LoOps.size()); SmallVector HiOps(Node->op_begin()+NewNumSubvectors, Node->op_end()); - Hi = DAG.getNode(ISD::CONCAT_VECTORS, NewVT_Hi, &HiOps[0], HiOps.size()); + Hi = DAG.getNode(ISD::CONCAT_VECTORS, dl, NewVT_Hi, + &HiOps[0], HiOps.size()); } break; } @@ -7584,16 +7586,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue Idx = Op.getOperand(1); MVT IdxVT = Idx.getValueType(); - Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, NewVT_Lo, Vec, Idx); + Lo = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT_Lo, Vec, Idx); ConstantSDNode *CIdx = dyn_cast(Idx); if (CIdx) { - Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, NewVT_Hi, Vec, + Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT_Hi, Vec, DAG.getConstant(CIdx->getZExtValue() + NewNumElts_Lo, IdxVT)); } else { - Idx = DAG.getNode(ISD::ADD, IdxVT, Idx, + Idx = DAG.getNode(ISD::ADD, dl, IdxVT, Idx, DAG.getConstant(NewNumElts_Lo, IdxVT)); - Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, NewVT_Hi, Vec, Idx); + Hi = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, NewVT_Hi, Vec, Idx); } break; } @@ -7608,12 +7610,12 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, // Handle a vector merge. SDValue CL, CH; SplitVectorOp(Cond, CL, CH); - Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, CL, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, CH, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, CL, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, CH, LH, RH); } else { // Handle a simple select with vector operands. - Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, Cond, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, Cond, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, Cond, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, Cond, LH, RH); } break; } @@ -7627,9 +7629,9 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SplitVectorOp(Node->getOperand(3), RL, RH); // Handle a simple select with vector operands. - Lo = DAG.getNode(ISD::SELECT_CC, NewVT_Lo, CondLHS, CondRHS, + Lo = DAG.getNode(ISD::SELECT_CC, dl, NewVT_Lo, CondLHS, CondRHS, LL, RL, CondCode); - Hi = DAG.getNode(ISD::SELECT_CC, NewVT_Hi, CondLHS, CondRHS, + Hi = DAG.getNode(ISD::SELECT_CC, dl, NewVT_Hi, CondLHS, CondRHS, LH, RH, CondCode); break; } @@ -7637,8 +7639,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue LL, LH, RL, RH; SplitVectorOp(Node->getOperand(0), LL, LH); SplitVectorOp(Node->getOperand(1), RL, RH); - Lo = DAG.getNode(ISD::VSETCC, NewVT_Lo, LL, RL, Node->getOperand(2)); - Hi = DAG.getNode(ISD::VSETCC, NewVT_Hi, LH, RH, Node->getOperand(2)); + Lo = DAG.getNode(ISD::VSETCC, dl, NewVT_Lo, LL, RL, Node->getOperand(2)); + Hi = DAG.getNode(ISD::VSETCC, dl, NewVT_Hi, LH, RH, Node->getOperand(2)); break; } case ISD::ADD: @@ -7664,8 +7666,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SplitVectorOp(Node->getOperand(0), LL, LH); SplitVectorOp(Node->getOperand(1), RL, RH); - Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, LL, RL); - Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, LH, RH); + Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, LL, RL); + Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, LH, RH); break; } case ISD::FP_ROUND: @@ -7673,8 +7675,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue L, H; SplitVectorOp(Node->getOperand(0), L, H); - Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L, Node->getOperand(1)); - Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H, Node->getOperand(1)); + Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, L, Node->getOperand(1)); + Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, H, Node->getOperand(1)); break; } case ISD::CTTZ: @@ -7702,8 +7704,8 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue L, H; SplitVectorOp(Node->getOperand(0), L, H); - Lo = DAG.getNode(Node->getOpcode(), NewVT_Lo, L); - Hi = DAG.getNode(Node->getOpcode(), NewVT_Hi, H); + Lo = DAG.getNode(Node->getOpcode(), dl, NewVT_Lo, L); + Hi = DAG.getNode(Node->getOpcode(), dl, NewVT_Hi, H); break; } case ISD::CONVERT_RNDSAT: { @@ -7736,27 +7738,27 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, bool isVolatile = LD->isVolatile(); assert(LD->isUnindexed() && "Indexed vector loads are not supported yet!"); - SDValue Offset = DAG.getNode(ISD::UNDEF, Ptr.getValueType()); + SDValue Offset = DAG.getNode(ISD::UNDEF, dl, Ptr.getValueType()); MVT MemNewEltVT = MemoryVT.getVectorElementType(); MVT MemNewVT_Lo = MVT::getVectorVT(MemNewEltVT, NewNumElts_Lo); MVT MemNewVT_Hi = MVT::getVectorVT(MemNewEltVT, NewNumElts_Hi); - Lo = DAG.getLoad(ISD::UNINDEXED, ExtType, + Lo = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, NewVT_Lo, Ch, Ptr, Offset, SV, SVOffset, MemNewVT_Lo, isVolatile, Alignment); unsigned IncrementSize = NewNumElts_Lo * MemNewEltVT.getSizeInBits()/8; - Ptr = DAG.getNode(ISD::ADD, Ptr.getValueType(), Ptr, + Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, DAG.getIntPtrConstant(IncrementSize)); SVOffset += IncrementSize; Alignment = MinAlign(Alignment, IncrementSize); - Hi = DAG.getLoad(ISD::UNINDEXED, ExtType, + Hi = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, NewVT_Hi, Ch, Ptr, Offset, SV, SVOffset, MemNewVT_Hi, isVolatile, Alignment); // Build a factor node to remember that this load is independent of the // other one. - SDValue TF = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); // Remember that we legalized the chain. @@ -7777,16 +7779,16 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue Ptr = DAG.CreateStackTemporary(InOp.getValueType(), LdAlign); int FI = cast(Ptr.getNode())->getIndex(); - SDValue St = DAG.getStore(DAG.getEntryNode(), + SDValue St = DAG.getStore(DAG.getEntryNode(), dl, InOp, Ptr, PseudoSourceValue::getFixedStack(FI), 0); - InOp = DAG.getLoad(Op.getValueType(), St, Ptr, + InOp = DAG.getLoad(Op.getValueType(), dl, St, Ptr, PseudoSourceValue::getFixedStack(FI), 0); } // Split the vector and convert each of the pieces now. SplitVectorOp(InOp, Lo, Hi); - Lo = DAG.getNode(ISD::BIT_CONVERT, NewVT_Lo, Lo); - Hi = DAG.getNode(ISD::BIT_CONVERT, NewVT_Hi, Hi); + Lo = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT_Lo, Lo); + Hi = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT_Hi, Hi); break; } } @@ -7805,6 +7807,7 @@ void SelectionDAGLegalize::SplitVectorOp(SDValue Op, SDValue &Lo, SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { assert(Op.getValueType().isVector() && "Bad ScalarizeVectorOp invocation!"); SDNode *Node = Op.getNode(); + DebugLoc dl = Node->getDebugLoc(); MVT NewVT = Op.getValueType().getVectorElementType(); assert(Op.getValueType().getVectorNumElements() == 1); @@ -7835,7 +7838,7 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { case ISD::AND: case ISD::OR: case ISD::XOR: - Result = DAG.getNode(Node->getOpcode(), + Result = DAG.getNode(Node->getOpcode(), dl, NewVT, ScalarizeVectorOp(Node->getOperand(0)), ScalarizeVectorOp(Node->getOperand(1))); @@ -7859,7 +7862,7 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { case ISD::ANY_EXTEND: case ISD::TRUNCATE: case ISD::FP_EXTEND: - Result = DAG.getNode(Node->getOpcode(), + Result = DAG.getNode(Node->getOpcode(), dl, NewVT, ScalarizeVectorOp(Node->getOperand(0))); break; @@ -7875,7 +7878,7 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { } case ISD::FPOWI: case ISD::FP_ROUND: - Result = DAG.getNode(Node->getOpcode(), + Result = DAG.getNode(Node->getOpcode(), dl, NewVT, ScalarizeVectorOp(Node->getOperand(0)), Node->getOperand(1)); @@ -7892,9 +7895,9 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { bool isVolatile = LD->isVolatile(); assert(LD->isUnindexed() && "Indexed vector loads are not supported yet!"); - SDValue Offset = DAG.getNode(ISD::UNDEF, Ptr.getValueType()); + SDValue Offset = DAG.getNode(ISD::UNDEF, dl, Ptr.getValueType()); - Result = DAG.getLoad(ISD::UNINDEXED, ExtType, + Result = DAG.getLoad(ISD::UNINDEXED, dl, ExtType, NewVT, Ch, Ptr, Offset, SV, SVOffset, MemoryVT.getVectorElementType(), isVolatile, Alignment); @@ -7925,23 +7928,23 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { break; } case ISD::EXTRACT_SUBVECTOR: - Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, NewVT, Node->getOperand(0), - Node->getOperand(1)); + Result = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, NewVT, + Node->getOperand(0), Node->getOperand(1)); break; case ISD::BIT_CONVERT: { SDValue Op0 = Op.getOperand(0); if (Op0.getValueType().getVectorNumElements() == 1) Op0 = ScalarizeVectorOp(Op0); - Result = DAG.getNode(ISD::BIT_CONVERT, NewVT, Op0); + Result = DAG.getNode(ISD::BIT_CONVERT, dl, NewVT, Op0); break; } case ISD::SELECT: - Result = DAG.getNode(ISD::SELECT, NewVT, Op.getOperand(0), + Result = DAG.getNode(ISD::SELECT, dl, NewVT, Op.getOperand(0), ScalarizeVectorOp(Op.getOperand(1)), ScalarizeVectorOp(Op.getOperand(2))); break; case ISD::SELECT_CC: - Result = DAG.getNode(ISD::SELECT_CC, NewVT, Node->getOperand(0), + Result = DAG.getNode(ISD::SELECT_CC, dl, NewVT, Node->getOperand(0), Node->getOperand(1), ScalarizeVectorOp(Op.getOperand(2)), ScalarizeVectorOp(Op.getOperand(3)), @@ -7950,9 +7953,10 @@ SDValue SelectionDAGLegalize::ScalarizeVectorOp(SDValue Op) { case ISD::VSETCC: { SDValue Op0 = ScalarizeVectorOp(Op.getOperand(0)); SDValue Op1 = ScalarizeVectorOp(Op.getOperand(1)); - Result = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(Op0.getValueType()), + Result = DAG.getNode(ISD::SETCC, dl, + TLI.getSetCCResultType(Op0.getValueType()), Op0, Op1, Op.getOperand(2)); - Result = DAG.getNode(ISD::SELECT, NewVT, Result, + Result = DAG.getNode(ISD::SELECT, dl, NewVT, Result, DAG.getConstant(-1ULL, NewVT), DAG.getConstant(0ULL, NewVT)); break; @@ -7977,6 +7981,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { SDValue Result; SDNode *Node = Op.getNode(); + DebugLoc dl = Node->getDebugLoc(); MVT EVT = VT.getVectorElementType(); unsigned NumElts = VT.getVectorNumElements(); @@ -8012,20 +8017,21 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { assert(0 && "Unexpected operation in WidenVectorOp!"); break; case ISD::UNDEF: - Result = DAG.getNode(ISD::UNDEF, WidenVT); + Result = DAG.getNode(ISD::UNDEF, dl, WidenVT); break; case ISD::BUILD_VECTOR: { // Build a vector with undefined for the new nodes SDValueVector NewOps(Node->op_begin(), Node->op_end()); for (unsigned i = NumElts; i < NewNumElts; ++i) { - NewOps.push_back(DAG.getNode(ISD::UNDEF,EVT)); + NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, EVT)); } - Result = DAG.getNode(ISD::BUILD_VECTOR, WidenVT, &NewOps[0], NewOps.size()); + Result = DAG.getNode(ISD::BUILD_VECTOR, dl, WidenVT, + &NewOps[0], NewOps.size()); break; } case ISD::INSERT_VECTOR_ELT: { SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); - Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, WidenVT, Tmp1, + Result = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, WidenVT, Tmp1, Node->getOperand(1), Node->getOperand(2)); break; } @@ -8054,14 +8060,14 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { } } for (unsigned i = NumElts; i < NewNumElts; ++i) { - NewOps.push_back(DAG.getNode(ISD::UNDEF,PVT)); + NewOps.push_back(DAG.getNode(ISD::UNDEF, dl, PVT)); } - SDValue Tmp3 = DAG.getNode(ISD::BUILD_VECTOR, + SDValue Tmp3 = DAG.getNode(ISD::BUILD_VECTOR, dl, MVT::getVectorVT(PVT, NewOps.size()), &NewOps[0], NewOps.size()); - Result = DAG.getNode(ISD::VECTOR_SHUFFLE, WidenVT, Tmp1, Tmp2, Tmp3); + Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, WidenVT, Tmp1, Tmp2, Tmp3); break; } case ISD::LOAD: { @@ -8090,7 +8096,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { MVT NewInWidenVT = MVT::getVectorVT(InEltVT, WidenSize / InEltSize); Tmp1 = WidenVectorOp(Tmp1, NewInWidenVT); assert(Tmp1.getValueType().getSizeInBits() == WidenVT.getSizeInBits()); - Result = DAG.getNode(ISD::BIT_CONVERT, WidenVT, Tmp1); + Result = DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, Tmp1); } else { // If the result size is a multiple of the input size, widen the input // and then convert. @@ -8099,14 +8105,14 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { "can not widen bit convert that are not multiple of element type"); unsigned NewNumElts = WidenSize / InSize; SmallVector Ops(NewNumElts); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, InVT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, InVT); Ops[0] = Tmp1; for (unsigned i = 1; i < NewNumElts; ++i) Ops[i] = UndefVal; MVT NewInVT = MVT::getVectorVT(InVT, NewNumElts); - Result = DAG.getNode(ISD::BUILD_VECTOR, NewInVT, &Ops[0], NewNumElts); - Result = DAG.getNode(ISD::BIT_CONVERT, WidenVT, Result); + Result = DAG.getNode(ISD::BUILD_VECTOR, dl, NewInVT, &Ops[0], NewNumElts); + Result = DAG.getNode(ISD::BIT_CONVERT, dl, WidenVT, Result); } break; } @@ -8125,7 +8131,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { MVT TWidenVT = MVT::getVectorVT(TEVT, NewNumElts); Tmp1 = WidenVectorOp(Tmp1, TWidenVT); assert(Tmp1.getValueType().getVectorNumElements() == NewNumElts); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1); + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1); break; } @@ -8148,7 +8154,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { SDValue Tmp1; Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); assert(Tmp1.getValueType() == WidenVT); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1); + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1); break; } case ISD::CONVERT_RNDSAT: { @@ -8198,7 +8204,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), WidenVT); assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1, Tmp2); break; } @@ -8213,14 +8219,14 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { WidenVT.getVectorNumElements()); ShOp = WidenVectorOp(ShOp, NewShVT); assert(ShOp.getValueType() == NewShVT); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, ShOp); + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1, ShOp); break; } case ISD::EXTRACT_VECTOR_ELT: { SDValue Tmp1 = WidenVectorOp(Node->getOperand(0), WidenVT); assert(Tmp1.getValueType() == WidenVT); - Result = DAG.getNode(Node->getOpcode(), EVT, Tmp1, Node->getOperand(1)); + Result = DAG.getNode(Node->getOpcode(), dl, EVT, Tmp1, Node->getOperand(1)); break; } case ISD::CONCAT_VECTORS: { @@ -8228,13 +8234,13 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { // We could widen on a multiple of the incoming operand if necessary. unsigned NumConcat = NewNumElts / NumElts; assert(NewNumElts % NumElts == 0 && "Can widen only a multiple of vector"); - SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, VT); SmallVector MOps; MOps.push_back(Op); for (unsigned i = 1; i != NumConcat; ++i) { MOps.push_back(UndefVal); } - Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, WidenVT, + Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &MOps[0], MOps.size())); break; } @@ -8253,18 +8259,18 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { if (Tmp1VTNumElts < NewNumElts) Result = WidenVectorOp(Tmp1, WidenVT); else - Result = DAG.getNode(ISD::EXTRACT_SUBVECTOR, WidenVT, Tmp1, Idx); + Result = DAG.getNode(ISD::EXTRACT_SUBVECTOR, dl, WidenVT, Tmp1, Idx); } } else if (NewNumElts % NumElts == 0) { // Widen the extracted subvector. unsigned NumConcat = NewNumElts / NumElts; - SDValue UndefVal = DAG.getNode(ISD::UNDEF, VT); + SDValue UndefVal = DAG.getNode(ISD::UNDEF, dl, VT); SmallVector MOps; MOps.push_back(Op); for (unsigned i = 1; i != NumConcat; ++i) { MOps.push_back(UndefVal); } - Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, WidenVT, + Result = LegalizeOp(DAG.getNode(ISD::CONCAT_VECTORS, dl, WidenVT, &MOps[0], MOps.size())); } else { assert(0 && "can not widen extract subvector"); @@ -8287,7 +8293,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { SDValue Tmp1 = WidenVectorOp(Node->getOperand(1), WidenVT); SDValue Tmp2 = WidenVectorOp(Node->getOperand(2), WidenVT); assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Tmp1, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Cond1, Tmp1, Tmp2); break; } @@ -8309,7 +8315,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { SDValue Tmp2 = WidenVectorOp(Node->getOperand(3), WidenVT); assert(Tmp1.getValueType() == WidenVT && Tmp2.getValueType() == WidenVT && "operands not widen"); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Cond1, Cond2, Tmp1, + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Cond1, Cond2, Tmp1, Tmp2, Node->getOperand(4)); break; } @@ -8322,7 +8328,7 @@ SDValue SelectionDAGLegalize::WidenVectorOp(SDValue Op, MVT WidenVT) { MVT TmpWidenVT = MVT::getVectorVT(TmpEVT, NewNumElts); Tmp1 = WidenVectorOp(Tmp1, TmpWidenVT); SDValue Tmp2 = WidenVectorOp(Node->getOperand(1), TmpWidenVT); - Result = DAG.getNode(Node->getOpcode(), WidenVT, Tmp1, Tmp2, + Result = DAG.getNode(Node->getOpcode(), dl, WidenVT, Tmp1, Tmp2, Node->getOperand(2)); break; } @@ -8389,7 +8395,8 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain, unsigned Alignment, bool isVolatile, unsigned LdWidth, - MVT ResType) { + MVT ResType, + DebugLoc dl) { // We assume that we have good rules to handle loading power of two loads so // we break down the operations to power of 2 loads. The strategy is to // load the largest power of 2 that we can easily transform to a legal vector @@ -8403,14 +8410,14 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain, FindWidenVecType(TLI, LdWidth, ResType, EVT, VecEVT); EVTWidth = EVT.getSizeInBits(); - SDValue LdOp = DAG.getLoad(EVT, Chain, BasePtr, SV, SVOffset, + SDValue LdOp = DAG.getLoad(EVT, dl, Chain, BasePtr, SV, SVOffset, isVolatile, Alignment); - SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, VecEVT, LdOp); + SDValue VecOp = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VecEVT, LdOp); LdChain.push_back(LdOp.getValue(1)); // Check if we can load the element with one instruction if (LdWidth == EVTWidth) { - return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp); } // The vector element order is endianness dependent. @@ -8421,7 +8428,7 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain, while (LdWidth > 0) { unsigned Increment = EVTWidth / 8; Offset += Increment; - BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr, + BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Increment)); if (LdWidth < EVTWidth) { @@ -8432,20 +8439,20 @@ SDValue SelectionDAGLegalize::genWidenVectorLoads(SDValueVector& LdChain, EVTWidth = EVT.getSizeInBits(); // Readjust position and vector position based on new load type Idx = Idx * (oEVTWidth/EVTWidth); - VecOp = DAG.getNode(ISD::BIT_CONVERT, VecEVT, VecOp); + VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, VecEVT, VecOp); } - SDValue LdOp = DAG.getLoad(EVT, Chain, BasePtr, SV, + SDValue LdOp = DAG.getLoad(EVT, dl, Chain, BasePtr, SV, SVOffset+Offset, isVolatile, MinAlign(Alignment, Offset)); LdChain.push_back(LdOp.getValue(1)); - VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, VecEVT, VecOp, LdOp, + VecOp = DAG.getNode(ISD::INSERT_VECTOR_ELT, dl, VecEVT, VecOp, LdOp, DAG.getIntPtrConstant(Idx++)); LdWidth -= EVTWidth; } - return DAG.getNode(ISD::BIT_CONVERT, ResType, VecOp); + return DAG.getNode(ISD::BIT_CONVERT, dl, ResType, VecOp); } bool SelectionDAGLegalize::LoadWidenVectorOp(SDValue& Result, @@ -8461,6 +8468,7 @@ bool SelectionDAGLegalize::LoadWidenVectorOp(SDValue& Result, // we need to load from. LoadSDNode *LD = cast(Op.getNode()); MVT LdVT = LD->getMemoryVT(); + DebugLoc dl = LD->getDebugLoc(); assert(LdVT.isVector() && NVT.isVector()); assert(LdVT.getVectorElementType() == NVT.getVectorElementType()); @@ -8476,14 +8484,15 @@ bool SelectionDAGLegalize::LoadWidenVectorOp(SDValue& Result, // Load value as a large register SDValueVector LdChain; Result = genWidenVectorLoads(LdChain, Chain, BasePtr, SV, SVOffset, - Alignment, isVolatile, LdWidth, NVT); + Alignment, isVolatile, LdWidth, NVT, dl); if (LdChain.size() == 1) { TFOp = LdChain[0]; return true; } else { - TFOp=DAG.getNode(ISD::TokenFactor, MVT::Other, &LdChain[0], LdChain.size()); + TFOp=DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &LdChain[0], LdChain.size()); return false; } } @@ -8497,7 +8506,8 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain, unsigned Alignment, bool isVolatile, SDValue ValOp, - unsigned StWidth) { + unsigned StWidth, + DebugLoc dl) { // Breaks the stores into a series of power of 2 width stores. For any // width, we convert the vector to the vector of element size that we // want to store. This avoids requiring a stack convert. @@ -8509,10 +8519,10 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain, FindWidenVecType(TLI, StWidth, VVT, EVT, VecEVT); EVTWidth = EVT.getSizeInBits(); - SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, VecEVT, ValOp); - SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EVT, VecOp, + SDValue VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, VecEVT, ValOp); + SDValue EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EVT, VecOp, DAG.getIntPtrConstant(0)); - SDValue StOp = DAG.getStore(Chain, EOp, BasePtr, SV, SVOffset, + SDValue StOp = DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset, isVolatile, Alignment); StChain.push_back(StOp); @@ -8528,7 +8538,7 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain, while (StWidth > 0) { unsigned Increment = EVTWidth / 8; Offset += Increment; - BasePtr = DAG.getNode(ISD::ADD, BasePtr.getValueType(), BasePtr, + BasePtr = DAG.getNode(ISD::ADD, dl, BasePtr.getValueType(), BasePtr, DAG.getIntPtrConstant(Increment)); if (StWidth < EVTWidth) { @@ -8539,12 +8549,12 @@ void SelectionDAGLegalize::genWidenVectorStores(SDValueVector& StChain, EVTWidth = EVT.getSizeInBits(); // Readjust position and vector position based on new load type Idx = Idx * (oEVTWidth/EVTWidth); - VecOp = DAG.getNode(ISD::BIT_CONVERT, VecEVT, VecOp); + VecOp = DAG.getNode(ISD::BIT_CONVERT, dl, VecEVT, VecOp); } - EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EVT, VecOp, + EOp = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EVT, VecOp, DAG.getIntPtrConstant(Idx++)); - StChain.push_back(DAG.getStore(Chain, EOp, BasePtr, SV, + StChain.push_back(DAG.getStore(Chain, dl, EOp, BasePtr, SV, SVOffset + Offset, isVolatile, MinAlign(Alignment, Offset))); StWidth -= EVTWidth; @@ -8563,6 +8573,7 @@ SDValue SelectionDAGLegalize::StoreWidenVectorOp(StoreSDNode *ST, MVT StVT = ST->getMemoryVT(); SDValue ValOp = ST->getValue(); + DebugLoc dl = ST->getDebugLoc(); // Check if we have widen this node with another value std::map::iterator I = WidenNodes.find(ValOp); @@ -8581,11 +8592,12 @@ SDValue SelectionDAGLegalize::StoreWidenVectorOp(StoreSDNode *ST, SDValueVector StChain; genWidenVectorStores(StChain, Chain, BasePtr, ST->getSrcValue(), ST->getSrcValueOffset(), ST->getAlignment(), - ST->isVolatile(), ValOp, StVT.getSizeInBits()); + ST->isVolatile(), ValOp, StVT.getSizeInBits(), dl); if (StChain.size() == 1) return StChain[0]; else - return DAG.getNode(ISD::TokenFactor, MVT::Other,&StChain[0],StChain.size()); + return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + &StChain[0], StChain.size()); } -- GitLab From e862b3dd96a033e88b9d60f2fcecfa656a0405f0 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 2 Feb 2009 22:50:08 +0000 Subject: [PATCH 648/682] Yonah does not support x86-64. Change the -mcpu value to one that does. llvm-svn: 63561 --- llvm/test/CodeGen/X86/extractelement-load.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/CodeGen/X86/extractelement-load.ll b/llvm/test/CodeGen/X86/extractelement-load.ll index 4850eba60928..601690ef7cab 100644 --- a/llvm/test/CodeGen/X86/extractelement-load.ll +++ b/llvm/test/CodeGen/X86/extractelement-load.ll @@ -1,5 +1,5 @@ ; RUN: llvm-as %s -o - | llc -march=x86 -mattr=+sse2 -mcpu=yonah | not grep movd -; RUN: llvm-as %s -o - | llc -march=x86-64 -mattr=+sse2 -mcpu=yonah | not grep movd +; RUN: llvm-as %s -o - | llc -march=x86-64 -mattr=+sse2 -mcpu=core2 | not grep movd define i32 @t(<2 x i64>* %val) nounwind { %tmp2 = load <2 x i64>* %val, align 16 ; <<2 x i64>> [#uses=1] -- GitLab From 7cffb63a9d1d7a8d0b75b23ed2f859ede20a06a3 Mon Sep 17 00:00:00 2001 From: Nuno Lopes Date: Mon, 2 Feb 2009 22:57:15 +0000 Subject: [PATCH 649/682] emit diagnostic when casting a ptr to a small int when doing static initialization (addresses Eli's comments I believe) llvm-svn: 63562 --- clang/lib/Sema/SemaDecl.cpp | 15 ++++++++++++--- clang/test/Sema/static-init.c | 3 ++- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 21fe6e1ce492..d2140b226757 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2055,14 +2055,23 @@ bool Sema::CheckArithmeticConstantExpression(const Expr* Init) { } case Expr::ImplicitCastExprClass: case Expr::CStyleCastExprClass: { - const Expr *SubExpr = cast(Init)->getSubExpr(); + const CastExpr *CE = cast(Init); + const Expr *SubExpr = CE->getSubExpr(); + if (SubExpr->getType()->isArithmeticType()) return CheckArithmeticConstantExpression(SubExpr); if (SubExpr->getType()->isPointerType()) { const Expr* Base = FindExpressionBaseAddress(SubExpr); - // If the pointer has a null base, this is an offsetof-like construct - return Base ? false : CheckAddressConstantExpression(SubExpr); + if (Base) { + // the cast is only valid if done to a wide enough type + if (Context.getTypeSize(CE->getType()) >= + Context.getTypeSize(SubExpr->getType())) + return false; + } else { + // If the pointer has a null base, this is an offsetof-like construct + return CheckAddressConstantExpression(SubExpr); + } } InitializerElementNotConstant(Init); diff --git a/clang/test/Sema/static-init.c b/clang/test/Sema/static-init.c index a4035e69df46..b3c8d0f9f181 100644 --- a/clang/test/Sema/static-init.c +++ b/clang/test/Sema/static-init.c @@ -16,4 +16,5 @@ struct foo { }; union bar u[1]; -struct foo x = {(int) u}; // no-error +struct foo x = {(long) u}; // no-error +struct foo y = {(char) u}; // expected-error {{initializer element is not a compile-time constant}} -- GitLab From f126e590429416744279d7efc9a8956af455ba43 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Mon, 2 Feb 2009 22:57:57 +0000 Subject: [PATCH 650/682] Use the updated CommandLine api for -fno-blocks. llvm-svn: 63563 --- clang/Driver/clang.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/clang/Driver/clang.cpp b/clang/Driver/clang.cpp index fe5e7f834441..c6fee1f09e5d 100644 --- a/clang/Driver/clang.cpp +++ b/clang/Driver/clang.cpp @@ -490,14 +490,15 @@ NoLaxVectorConversions("fno-lax-vector-conversions", llvm::cl::desc("Disallow implicit conversions between " "vectors with a different number of " "elements or different element types")); -static llvm::cl::opt -EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature"), llvm::cl::ValueDisallowed); -static llvm::cl::inverse_opt -DisableBlocks("fno-blocks", llvm::cl::opposite_of(EnableBlocks), llvm::cl::ValueDisallowed); +static llvm::cl::opt +EnableBlocks("fblocks", llvm::cl::desc("enable the 'blocks' language feature"), + llvm::cl::ValueDisallowed, llvm::cl::AllowInverse, + llvm::cl::ZeroOrMore); static llvm::cl::opt -ObjCNonFragileABI("fobjc-nonfragile-abi", llvm::cl::desc("enable objective-c's nonfragile abi")); +ObjCNonFragileABI("fobjc-nonfragile-abi", + llvm::cl::desc("enable objective-c's nonfragile abi")); // FIXME: This (and all GCC -f options) really come in -f... and @@ -623,7 +624,7 @@ static void InitializeLanguageStandard(LangOptions &Options, LangKind LK, if (NoLaxVectorConversions.getPosition()) Options.LaxVectorConversions = 0; Options.Exceptions = Exceptions; - if (EnableBlocks.getPosition() || DisableBlocks.getPosition()) + if (EnableBlocks.getPosition()) Options.Blocks = EnableBlocks; // Override the default runtime if the user requested it. -- GitLab From bf8c24ad89f39c91a36f711ab7c0eced68864987 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 2 Feb 2009 23:23:47 +0000 Subject: [PATCH 651/682] Thread CGFunctionInfo construction through CodeGenTypes. - Inefficient & leaks memory currently, will be cleaned up subsequently. llvm-svn: 63567 --- clang/lib/CodeGen/CGCall.cpp | 72 +++++++++++++++++---------- clang/lib/CodeGen/CGCall.h | 8 +-- clang/lib/CodeGen/CGExpr.cpp | 3 +- clang/lib/CodeGen/CGObjC.cpp | 5 +- clang/lib/CodeGen/CGObjCGNU.cpp | 10 ++-- clang/lib/CodeGen/CGObjCMac.cpp | 9 ++-- clang/lib/CodeGen/CodeGenFunction.cpp | 2 +- clang/lib/CodeGen/CodeGenModule.cpp | 4 +- clang/lib/CodeGen/CodeGenTypes.cpp | 4 +- clang/lib/CodeGen/CodeGenTypes.h | 14 ++++++ 10 files changed, 83 insertions(+), 48 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index c7b2a5dc895f..7e2592206e0b 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -31,50 +31,70 @@ using namespace CodeGen; // FIXME: Use iterator and sidestep silly type array creation. -CGFunctionInfo::CGFunctionInfo(const FunctionTypeNoProto *FTNP) { - ArgTypes.push_back(FTNP->getResultType()); +const +CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeNoProto *FTNP) { + return getFunctionInfo(FTNP->getResultType(), + llvm::SmallVector()); } -CGFunctionInfo::CGFunctionInfo(const FunctionTypeProto *FTP) { - ArgTypes.push_back(FTP->getResultType()); +const +CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionTypeProto *FTP) { + llvm::SmallVector ArgTys; + // FIXME: Kill copy. for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) - ArgTypes.push_back(FTP->getArgType(i)); + ArgTys.push_back(FTP->getArgType(i)); + return getFunctionInfo(FTP->getResultType(), ArgTys); } -// FIXME: Is there really any reason to have this still? -CGFunctionInfo::CGFunctionInfo(const FunctionDecl *FD) { +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const FunctionDecl *FD) { const FunctionType *FTy = FD->getType()->getAsFunctionType(); - const FunctionTypeProto *FTP = dyn_cast(FTy); - - ArgTypes.push_back(FTy->getResultType()); - if (FTP) { - for (unsigned i = 0, e = FTP->getNumArgs(); i != e; ++i) - ArgTypes.push_back(FTP->getArgType(i)); - } + if (const FunctionTypeProto *FTP = dyn_cast(FTy)) + return getFunctionInfo(FTP); + return getFunctionInfo(cast(FTy)); } -CGFunctionInfo::CGFunctionInfo(const ObjCMethodDecl *MD, - const ASTContext &Context) { - ArgTypes.push_back(MD->getResultType()); - ArgTypes.push_back(MD->getSelfDecl()->getType()); - ArgTypes.push_back(Context.getObjCSelType()); +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(const ObjCMethodDecl *MD) { + llvm::SmallVector ArgTys; + ArgTys.push_back(MD->getSelfDecl()->getType()); + ArgTys.push_back(Context.getObjCSelType()); + // FIXME: Kill copy? for (ObjCMethodDecl::param_const_iterator i = MD->param_begin(), e = MD->param_end(); i != e; ++i) - ArgTypes.push_back((*i)->getType()); + ArgTys.push_back((*i)->getType()); + return getFunctionInfo(MD->getResultType(), ArgTys); } -CGFunctionInfo::CGFunctionInfo(QualType ResTy, const CallArgList &Args) { - ArgTypes.push_back(ResTy); +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, + const CallArgList &Args) { + // FIXME: Kill copy. + llvm::SmallVector ArgTys; for (CallArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) - ArgTypes.push_back(i->second); + ArgTys.push_back(i->second); + return getFunctionInfo(ResTy, ArgTys); } -CGFunctionInfo::CGFunctionInfo(QualType ResTy, const FunctionArgList &Args) { - ArgTypes.push_back(ResTy); +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, + const FunctionArgList &Args) { + // FIXME: Kill copy. + llvm::SmallVector ArgTys; for (FunctionArgList::const_iterator i = Args.begin(), e = Args.end(); i != e; ++i) - ArgTypes.push_back(i->second); + ArgTys.push_back(i->second); + return getFunctionInfo(ResTy, ArgTys); +} + +const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, + const llvm::SmallVector &ArgTys) { + return *new CGFunctionInfo(ResTy, ArgTys); +} + +/***/ + +CGFunctionInfo::CGFunctionInfo(QualType ResTy, + const llvm::SmallVector &ArgTys) { + ArgTypes.push_back(ResTy); + ArgTypes.insert(ArgTypes.end(), ArgTys.begin(), ArgTys.end()); } ArgTypeIterator CGFunctionInfo::argtypes_begin() const { diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index 7ca5f26a8f8c..f8fb32b15a4e 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -57,12 +57,8 @@ namespace CodeGen { llvm::SmallVector ArgTypes; public: - CGFunctionInfo(const FunctionTypeNoProto *FTNP); - CGFunctionInfo(const FunctionTypeProto *FTP); - CGFunctionInfo(const FunctionDecl *FD); - CGFunctionInfo(const ObjCMethodDecl *MD, const ASTContext &Context); - CGFunctionInfo(QualType ResTy, const CallArgList &Args); - CGFunctionInfo(QualType ResTy, const FunctionArgList &Args); + CGFunctionInfo(QualType ResTy, + const llvm::SmallVector &ArgTys); ArgTypeIterator argtypes_begin() const; ArgTypeIterator argtypes_end() const; diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 5ed215164b7e..2c16c1940b55 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1102,5 +1102,6 @@ RValue CodeGenFunction::EmitCallExpr(llvm::Value *Callee, QualType CalleeType, Args.push_back(std::make_pair(EmitAnyExprToTemp(*I), I->getType())); - return EmitCall(CGFunctionInfo(ResultType, Args), Callee, Args); + return EmitCall(CGM.getTypes().getFunctionInfo(ResultType, Args), + Callee, Args); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index cf37886e6d37..9dc45efc6872 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -183,7 +183,7 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, Args.push_back(std::make_pair(RValue::get(CmdVal), Cmd->getType())); Args.push_back(std::make_pair(RValue::get(Offset), getContext().LongTy)); Args.push_back(std::make_pair(RValue::get(True), getContext().BoolTy)); - RValue RV = EmitCall(CGFunctionInfo(PD->getType(), Args), + RValue RV = EmitCall(Types.getFunctionInfo(PD->getType(), Args), GetPropertyFn, Args); // We need to fix the type here. Ivars with copy & retain are // always objects so we don't need to worry about complex or @@ -268,7 +268,8 @@ void CodeGenFunction::GenerateObjCSetter(ObjCImplementationDecl *IMP, getContext().BoolTy)); Args.push_back(std::make_pair(RValue::get(IsCopy ? True : False), getContext().BoolTy)); - EmitCall(CGFunctionInfo(PD->getType(), Args), SetPropertyFn, Args); + EmitCall(Types.getFunctionInfo(PD->getType(), Args), + SetPropertyFn, Args); } else { SourceLocation Loc = PD->getLocation(); ValueDecl *Self = OMD->getSelfDecl(); diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index e6ae6f36b4e1..1ce28bf91d40 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -311,7 +311,8 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(CGFunctionInfo(ResultType, ActualArgs), imp, ActualArgs); + return CGF.EmitCall(CGM.getTypes().getFunctionInfo(ResultType, ActualArgs), + imp, ActualArgs); } /// Generate code for a message send expression. @@ -358,7 +359,8 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, ActualArgs.push_back(std::make_pair(RValue::get(cmd), CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - return CGF.EmitCall(CGFunctionInfo(ResultType, ActualArgs), imp, ActualArgs); + return CGF.EmitCall(CGM.getTypes().getFunctionInfo(ResultType, ActualArgs), + imp, ActualArgs); } /// Generates a MethodList. Used in construction of a objc_class and @@ -969,9 +971,9 @@ llvm::Function *CGObjCGNU::GenerateMethod(const ObjCMethodDecl *OMD, std::string MethodName = OMD->getSelector().getAsString(); bool isClassMethod = !OMD->isInstanceMethod(); + CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *MethodTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()), - OMD->isVariadic()); + Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); std::string FunctionName = SymbolNameForMethod(ClassName, CategoryName, MethodName, isClassMethod); diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index d8e873b84592..a577bd03cb26 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -806,8 +806,9 @@ CodeGen::RValue CGObjCMac::EmitMessageSend(CodeGen::CodeGenFunction &CGF, CGF.getContext().getObjCSelType())); ActualArgs.insert(ActualArgs.end(), CallArgs.begin(), CallArgs.end()); - CGFunctionInfo FnInfo(ResultType, ActualArgs); - const llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FnInfo, false); + CodeGenTypes &Types = CGM.getTypes(); + const CGFunctionInfo &FnInfo = Types.getFunctionInfo(ResultType, ActualArgs); + const llvm::FunctionType *FTy = Types.GetFunctionType(FnInfo, false); llvm::Constant *Fn; if (CGM.ReturnTypeUsesSret(FnInfo)) { @@ -1668,9 +1669,9 @@ llvm::Function *CGObjCCommonMac::GenerateMethod(const ObjCMethodDecl *OMD, std::string Name; GetNameForMethod(OMD, CD, Name); + CodeGenTypes &Types = CGM.getTypes(); const llvm::FunctionType *MethodTy = - CGM.getTypes().GetFunctionType(CGFunctionInfo(OMD, CGM.getContext()), - OMD->isVariadic()); + Types.GetFunctionType(Types.getFunctionInfo(OMD), OMD->isVariadic()); llvm::Function *Method = llvm::Function::Create(MethodTy, llvm::GlobalValue::InternalLinkage, diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index fe28b3aeccdd..866b8826241c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -172,7 +172,7 @@ void CodeGenFunction::StartFunction(const Decl *D, QualType RetTy, } // FIXME: Leaked. - CurFnInfo = new CGFunctionInfo(FnRetTy, Args); + CurFnInfo = &CGM.getTypes().getFunctionInfo(FnRetTy, Args); EmitFunctionProlog(*CurFnInfo, CurFn, Args); // If any of the arguments have a variably modified type, make sure to diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index d02812ac5d9c..18870722fa28 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -299,14 +299,14 @@ void CodeGenModule::SetFunctionAttributesForDefinition(const Decl *D, void CodeGenModule::SetMethodAttributes(const ObjCMethodDecl *MD, llvm::Function *F) { - SetFunctionAttributes(MD, CGFunctionInfo(MD, Context), F); + SetFunctionAttributes(MD, getTypes().getFunctionInfo(MD), F); SetFunctionAttributesForDefinition(MD, F); } void CodeGenModule::SetFunctionAttributes(const FunctionDecl *FD, llvm::Function *F) { - SetFunctionAttributes(FD, CGFunctionInfo(FD), F); + SetFunctionAttributes(FD, getTypes().getFunctionInfo(FD), F); SetGlobalValueAttributes(FD, FD->getStorageClass() == FunctionDecl::Static, FD->isInline(), F, false); diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp index bcb3cc559158..0b74e1e636fb 100644 --- a/clang/lib/CodeGen/CodeGenTypes.cpp +++ b/clang/lib/CodeGen/CodeGenTypes.cpp @@ -256,11 +256,11 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) { VT.getNumElements()); } case Type::FunctionNoProto: - return GetFunctionType(CGFunctionInfo(cast(&Ty)), + return GetFunctionType(getFunctionInfo(cast(&Ty)), true); case Type::FunctionProto: { const FunctionTypeProto *FTP = cast(&Ty); - return GetFunctionType(CGFunctionInfo(FTP), FTP->isVariadic()); + return GetFunctionType(getFunctionInfo(FTP), FTP->isVariadic()); } case Type::ASQual: diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index 60c2946f131f..d41c23d37476 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -158,6 +158,20 @@ public: /// UpdateCompletedType - When we find the full definition for a TagDecl, /// replace the 'opaque' type we previously made for it if applicable. void UpdateCompletedType(const TagDecl *TD); + + /// getFunctionInfo - Get the CGFunctionInfo for this function signature. + const CGFunctionInfo &getFunctionInfo(QualType RetTy, + const llvm::SmallVector + &ArgTys); + + const CGFunctionInfo &getFunctionInfo(const FunctionTypeNoProto *FTNP); + const CGFunctionInfo &getFunctionInfo(const FunctionTypeProto *FTP); + const CGFunctionInfo &getFunctionInfo(const FunctionDecl *FD); + const CGFunctionInfo &getFunctionInfo(const ObjCMethodDecl *MD); + const CGFunctionInfo &getFunctionInfo(QualType ResTy, + const CallArgList &Args); + const CGFunctionInfo &getFunctionInfo(QualType ResTy, + const FunctionArgList &Args); public: // These are internal details of CGT that shouldn't be used externally. /// addFieldInfo - Assign field number to field FD. -- GitLab From 8bd3c2ebaccc7c226282750eb23ef622f05ad0ce Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 2 Feb 2009 23:39:07 +0000 Subject: [PATCH 652/682] Add a macro-based enumeration of all of the Decl nodes (like we do with Stmt/Expr nodes), and convert some of the more mundane switch-on-all-decl-kinds uses over to use this new file. llvm-svn: 63570 --- clang/include/clang/AST/Decl.h | 16 +- clang/include/clang/AST/DeclBase.h | 100 +------ clang/include/clang/AST/DeclNodes.def | 149 +++++++++++ .../Analysis/Visitors/CFGRecStmtDeclVisitor.h | 4 +- clang/lib/AST/Decl.cpp | 8 +- clang/lib/AST/DeclBase.cpp | 252 ++---------------- clang/lib/AST/DeclSerialization.cpp | 12 +- clang/lib/Sema/SemaDeclObjC.cpp | 8 +- 8 files changed, 213 insertions(+), 336 deletions(-) create mode 100644 clang/include/clang/AST/DeclNodes.def diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h index 23f06f14f569..530541330062 100644 --- a/clang/include/clang/AST/Decl.h +++ b/clang/include/clang/AST/Decl.h @@ -443,38 +443,38 @@ protected: friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); }; -/// ParmVarWithOriginalTypeDecl - Represent a parameter to a function, when +/// OriginalParmVarDecl - Represent a parameter to a function, when /// the type of the parameter has been promoted. This node represents the /// parameter to the function with its original type. /// -class ParmVarWithOriginalTypeDecl : public ParmVarDecl { +class OriginalParmVarDecl : public ParmVarDecl { friend class ParmVarDecl; protected: QualType OriginalType; private: - ParmVarWithOriginalTypeDecl(DeclContext *DC, SourceLocation L, + OriginalParmVarDecl(DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, QualType OT, StorageClass S, Expr *DefArg) : ParmVarDecl(OriginalParmVar, DC, L, Id, T, S, DefArg), OriginalType(OT) {} public: - static ParmVarWithOriginalTypeDecl *Create(ASTContext &C, DeclContext *DC, + static OriginalParmVarDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,IdentifierInfo *Id, QualType T, QualType OT, StorageClass S, Expr *DefArg); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == OriginalParmVar; } - static bool classof(const ParmVarWithOriginalTypeDecl *D) { return true; } + static bool classof(const OriginalParmVarDecl *D) { return true; } protected: - /// EmitImpl - Serialize this ParmVarWithOriginalTypeDecl. + /// EmitImpl - Serialize this OriginalParmVarDecl. /// Called by Decl::Emit. virtual void EmitImpl(llvm::Serializer& S) const; - /// CreateImpl - Deserialize a ParmVarWithOriginalTypeDecl. + /// CreateImpl - Deserialize a OriginalParmVarDecl. /// Called by Decl::Create. - static ParmVarWithOriginalTypeDecl* CreateImpl(llvm::Deserializer& D, + static OriginalParmVarDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index 0175af66510b..23bcd58a2a3b 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -30,6 +30,7 @@ class FunctionDecl; class CXXRecordDecl; class EnumDecl; class ObjCMethodDecl; +class ObjCContainerDecl; class ObjCInterfaceDecl; class ObjCCategoryDecl; class ObjCProtocolDecl; @@ -44,67 +45,14 @@ class DeclarationName; /// class Decl { public: + /// \brief Lists the kind of concrete classes of Decl. enum Kind { - // This lists the concrete classes of Decl in order of the inheritance - // hierarchy. This allows us to do efficient classof tests based on the - // enums below. The commented out names are abstract class names. - // [DeclContext] indicates that the class also inherits from DeclContext. - - // Decl - TranslationUnit, // [DeclContext] - // NamedDecl - OverloadedFunction, - Field, - ObjCIvar, - ObjCAtDefsField, - Namespace, // [DeclContext] - // TypeDecl - Typedef, - // TagDecl // [DeclContext] - Enum, - Record, - CXXRecord, - TemplateTypeParm, - // ValueDecl - EnumConstant, - Function, // [DeclContext] - CXXMethod, - CXXConstructor, - CXXDestructor, - CXXConversion, - Var, - ImplicitParam, - CXXClassVar, - ParmVar, - OriginalParmVar, - NonTypeTemplateParm, - ObjCMethod, // [DeclContext] - ObjCContainer, // [DeclContext] - ObjCCategory, - ObjCProtocol, - ObjCInterface, - ObjCCategoryImpl, // [DeclContext] - ObjCProperty, - ObjCCompatibleAlias, - LinkageSpec, // [DeclContext] - ObjCPropertyImpl, - ObjCImplementation, // [DeclContext] - ObjCForwardProtocol, - ObjCClass, - FileScopeAsm, - Block, // [DeclContext] - - // For each non-leaf class, we now define a mapping to the first/last member - // of the class, to allow efficient classof. - NamedFirst = OverloadedFunction, NamedLast = ObjCCompatibleAlias, - ObjCContainerFirst = ObjCContainer, ObjCContainerLast = ObjCInterface, - FieldFirst = Field , FieldLast = ObjCAtDefsField, - TypeFirst = Typedef , TypeLast = TemplateTypeParm, - TagFirst = Enum , TagLast = CXXRecord, - RecordFirst = Record , RecordLast = CXXRecord, - ValueFirst = EnumConstant , ValueLast = NonTypeTemplateParm, - FunctionFirst = Function , FunctionLast = CXXConversion, - VarFirst = Var , VarLast = NonTypeTemplateParm +#define DECL(Derived, Base) Derived, +#define DECL_RANGE(CommonBase, Start, End) \ + CommonBase##First = Start, CommonBase##Last = End, +#define LAST_DECL_RANGE(CommonBase, Start, End) \ + CommonBase##First = Start, CommonBase##Last = End +#include "clang/AST/DeclNodes.def" }; /// IdentifierNamespace - According to C99 6.2.3, there are four namespaces, @@ -822,19 +770,8 @@ public: static bool classof(const Decl *D) { switch (D->getKind()) { - case Decl::TranslationUnit: - case Decl::Namespace: - case Decl::Enum: - case Decl::Record: - case Decl::CXXRecord: - case Decl::ObjCMethod: - case Decl::ObjCInterface: - case Decl::ObjCCategory: - case Decl::ObjCProtocol: - case Decl::ObjCImplementation: - case Decl::ObjCCategoryImpl: - case Decl::LinkageSpec: - case Decl::Block: +#define DECL_CONTEXT(Name) case Decl::Name: +#include "clang/AST/DeclNodes.def" return true; default: if (D->getKind() >= Decl::FunctionFirst && @@ -844,20 +781,9 @@ public: } } static bool classof(const DeclContext *D) { return true; } - static bool classof(const TranslationUnitDecl *D) { return true; } - static bool classof(const NamespaceDecl *D) { return true; } - static bool classof(const FunctionDecl *D) { return true; } - static bool classof(const RecordDecl *D) { return true; } - static bool classof(const CXXRecordDecl *D) { return true; } - static bool classof(const EnumDecl *D) { return true; } - static bool classof(const ObjCMethodDecl *D) { return true; } - static bool classof(const ObjCInterfaceDecl *D) { return true; } - static bool classof(const ObjCCategoryDecl *D) { return true; } - static bool classof(const ObjCProtocolDecl *D) { return true; } - static bool classof(const ObjCImplementationDecl *D) { return true; } - static bool classof(const ObjCCategoryImplDecl *D) { return true; } - static bool classof(const LinkageSpecDecl *D) { return true; } - static bool classof(const BlockDecl *D) { return true; } +#define DECL_CONTEXT(Name) \ + static bool classof(const Name##Decl *D) { return true; } +#include "clang/AST/DeclNodes.def" private: void buildLookup(DeclContext *DCtx); diff --git a/clang/include/clang/AST/DeclNodes.def b/clang/include/clang/AST/DeclNodes.def new file mode 100644 index 000000000000..94c40f8e73dc --- /dev/null +++ b/clang/include/clang/AST/DeclNodes.def @@ -0,0 +1,149 @@ +//===-- DeclNodes.def - Metadata about Decl AST nodes -----------*- 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 the declaration nodes within the AST. The +// description of the declaration nodes uses six macros: +// +// DECL(Derived, Base) describes a normal declaration type Derived +// and specifies its base class. Note that Derived should not have +// the Decl suffix on it, while Base should. +// +// LAST_DECL(Derived, Base) is like DECL, but is used for the last +// declaration in the list. +// +// ABSTRACT_DECL(Derived, Base) describes an abstract class that is +// used to specify a classification of declarations. For example, +// TagDecl is an abstract class used to describe the various kinds of +// "tag" declarations (unions, structs, classes, enums). +// +// DECL_CONTEXT(Decl) specifies that Decl is a kind of declaration +// that is also a DeclContext. +// +// LAST_DECL_CONTEXT(Decl) is like DECL_CONTEXT, but is used for the +// last declaration context. +// +// DECL_RANGE(CommonBase, Start, End) specifies a range of +// declaration values that have a common (potentially indirect) base +// class. +// +// LAST_DECL_RANGE(CommonBase, Start, End) is like DECL_RANGE, but is +// used for the last declaration range. +// +// Note that, due to the use of ranges, the order of the these +// declarations is significant. A declaration should be listed under +// its base class. +// ===----------------------------------------------------------------------===// + +#ifndef DECL +# define DECL(Derived, Base) +#endif + +#ifndef LAST_DECL +# define LAST_DECL(Derived, Base) DECL(Derived, Base) +#endif + +#ifndef ABSTRACT_DECL +# define ABSTRACT_DECL(Derived, Base) +#endif + +#ifndef DECL_CONTEXT +# define DECL_CONTEXT(Decl) +#endif + +#ifndef LAST_DECL_CONTEXT +# define LAST_DECL_CONTEXT(Decl) DECL_CONTEXT(Decl) +#endif + +#ifndef DECL_RANGE +# define DECL_RANGE(CommonBase, Start, End) +#endif + +#ifndef LAST_DECL_RANGE +# define LAST_DECL_RANGE(CommonBase, Start, End) \ + DECL_RANGE(CommonBase, Start, End) +#endif + +DECL(TranslationUnit, Decl) +ABSTRACT_DECL(Named, Decl) + DECL(OverloadedFunction, NamedDecl) + DECL(Field, NameDecl) + DECL(ObjCIvar, FieldDecl) + DECL(ObjCAtDefsField, FieldDecl) + DECL(Namespace, NamedDecl) + ABSTRACT_DECL(Type, NamedDecl) + DECL(Typedef, TypeDecl) + ABSTRACT_DECL(Tag, TypeDecl) + DECL(Enum, TagDecl) + DECL(Record, TagDecl) + DECL(CXXRecord, RecordDecl) + DECL(TemplateTypeParm, TypeDecl) + ABSTRACT_DECL(Value, NamedDecl) + DECL(EnumConstant, ValueDecl) + DECL(Function, ValueDecl) + DECL(CXXMethod, FunctionDecl) + DECL(CXXConstructor, CXXMethodDecl) + DECL(CXXDestructor, CXXMethodDecl) + DECL(CXXConversion, CXXMethodDecl) + DECL(Var, ValueDecl) + DECL(ImplicitParam, VarDecl) + DECL(CXXClassVar, VarDecl) + DECL(ParmVar, VarDecl) + DECL(OriginalParmVar, ParmVarDecl) + DECL(NonTypeTemplateParm, VarDecl) + DECL(ObjCMethod, NamedDecl) + DECL(ObjCContainer, NamedDecl) + DECL(ObjCCategory, ObjCContainerDecl) + DECL(ObjCProtocol, ObjCContainerDecl) + DECL(ObjCInterface, ObjCContainerDecl) + DECL(ObjCCategoryImpl, NamedDecl) + DECL(ObjCProperty, NamedDecl) + DECL(ObjCCompatibleAlias, NamedDecl) +DECL(LinkageSpec, Decl) +DECL(ObjCPropertyImpl, Decl) +DECL(ObjCImplementation, Decl) +DECL(ObjCForwardProtocol, Decl) +DECL(ObjCClass, Decl) +DECL(FileScopeAsm, Decl) +LAST_DECL(Block, Decl) + +// Declaration contexts +DECL_CONTEXT(TranslationUnit) +DECL_CONTEXT(Namespace) +DECL_CONTEXT(Enum) +DECL_CONTEXT(Record) +DECL_CONTEXT(CXXRecord) +DECL_CONTEXT(Function) +DECL_CONTEXT(ObjCMethod) +DECL_CONTEXT(ObjCContainer) +DECL_CONTEXT(ObjCInterface) +DECL_CONTEXT(ObjCProtocol) +DECL_CONTEXT(ObjCCategory) +DECL_CONTEXT(ObjCCategoryImpl) +DECL_CONTEXT(LinkageSpec) +DECL_CONTEXT(ObjCImplementation) +LAST_DECL_CONTEXT(Block) + +// Declaration ranges +DECL_RANGE(Named, OverloadedFunction, ObjCCompatibleAlias) +DECL_RANGE(ObjCContainer, ObjCContainer, ObjCInterface) +DECL_RANGE(Field, Field, ObjCAtDefsField) +DECL_RANGE(Type, Typedef, TemplateTypeParm) +DECL_RANGE(Tag, Enum, CXXRecord) +DECL_RANGE(Record, Record, CXXRecord) +DECL_RANGE(Value, EnumConstant, NonTypeTemplateParm) +DECL_RANGE(Function, Function, CXXConversion) +LAST_DECL_RANGE(Var, Var, NonTypeTemplateParm) + +#undef LAST_DECL_RANGE +#undef DECL_RANGE +#undef LAST_DECL_CONTEXT +#undef DECL_CONTEXT +#undef ABSTRACT_DECL +#undef LAST_DECL +#undef DECL diff --git a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h index 345ea385ed6d..89b365c5b648 100644 --- a/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h +++ b/clang/include/clang/Analysis/Visitors/CFGRecStmtDeclVisitor.h @@ -58,7 +58,7 @@ public: DISPATCH_CASE(Function,FunctionDecl) DISPATCH_CASE(Var,VarDecl) DISPATCH_CASE(ParmVar,ParmVarDecl) // FIXME: (same) - DISPATCH_CASE(OriginalParmVar,ParmVarWithOriginalTypeDecl) // FIXME: (same) + DISPATCH_CASE(OriginalParmVar,OriginalParmVarDecl) // FIXME: (same) DISPATCH_CASE(ImplicitParam,ImplicitParamDecl) DISPATCH_CASE(EnumConstant,EnumConstantDecl) DISPATCH_CASE(Typedef,TypedefDecl) @@ -71,7 +71,7 @@ public: DEFAULT_DISPATCH(VarDecl) DEFAULT_DISPATCH(FunctionDecl) - DEFAULT_DISPATCH_VARDECL(ParmVarWithOriginalTypeDecl) + DEFAULT_DISPATCH_VARDECL(OriginalParmVarDecl) DEFAULT_DISPATCH_VARDECL(ParmVarDecl) DEFAULT_DISPATCH(ImplicitParamDecl) DEFAULT_DISPATCH(EnumConstantDecl) diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 25317dbeb109..0a3801a78f56 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -54,18 +54,18 @@ ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, } QualType ParmVarDecl::getOriginalType() const { - if (const ParmVarWithOriginalTypeDecl *PVD = - dyn_cast(this)) + if (const OriginalParmVarDecl *PVD = + dyn_cast(this)) return PVD->OriginalType; return getType(); } -ParmVarWithOriginalTypeDecl *ParmVarWithOriginalTypeDecl::Create( +OriginalParmVarDecl *OriginalParmVarDecl::Create( ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, QualType OT, StorageClass S, Expr *DefArg) { - return new (C) ParmVarWithOriginalTypeDecl(DC, L, Id, T, OT, S, DefArg); + return new (C) OriginalParmVarDecl(DC, L, Id, T, OT, S, DefArg); } FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp index 983c726c228f..6d0cda1fcea6 100644 --- a/clang/lib/AST/DeclBase.cpp +++ b/clang/lib/AST/DeclBase.cpp @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "clang/AST/DeclBase.h" +#include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/ASTContext.h" @@ -26,35 +27,8 @@ using namespace clang; // Statistics //===----------------------------------------------------------------------===// -// temporary statistics gathering -static unsigned nFuncs = 0; -static unsigned nVars = 0; -static unsigned nParmVars = 0; -static unsigned nOriginalParmVars = 0; -static unsigned nSUC = 0; -static unsigned nCXXSUC = 0; -static unsigned nEnumConst = 0; -static unsigned nEnumDecls = 0; -static unsigned nNamespaces = 0; -static unsigned nOverFuncs = 0; -static unsigned nTypedef = 0; -static unsigned nFieldDecls = 0; -static unsigned nInterfaceDecls = 0; -static unsigned nClassDecls = 0; -static unsigned nMethodDecls = 0; -static unsigned nProtocolDecls = 0; -static unsigned nForwardProtocolDecls = 0; -static unsigned nCategoryDecls = 0; -static unsigned nIvarDecls = 0; -static unsigned nAtDefsFieldDecls = 0; -static unsigned nObjCImplementationDecls = 0; -static unsigned nObjCCategoryImpl = 0; -static unsigned nObjCCompatibleAlias = 0; -static unsigned nObjCPropertyDecl = 0; -static unsigned nObjCPropertyImplDecl = 0; -static unsigned nLinkageSpecDecl = 0; -static unsigned nFileScopeAsmDecl = 0; -static unsigned nBlockDecls = 0; +#define DECL(Derived, Base) static int n##Derived##s = 0; +#include "clang/AST/DeclNodes.def" static bool StatSwitch = false; @@ -66,58 +40,17 @@ static DeclAttrMapTy *DeclAttrs = 0; const char *Decl::getDeclKindName() const { switch (DeclKind) { - default: assert(0 && "Unknown decl kind!"); - case Namespace: return "Namespace"; - case OverloadedFunction: return "OverloadedFunction"; - case Typedef: return "Typedef"; - case Function: return "Function"; - case Var: return "Var"; - case ParmVar: return "ParmVar"; - case OriginalParmVar: return "OriginalParmVar"; - case EnumConstant: return "EnumConstant"; - case ObjCIvar: return "ObjCIvar"; - case ObjCInterface: return "ObjCInterface"; - case ObjCImplementation: return "ObjCImplementation"; - case ObjCClass: return "ObjCClass"; - case ObjCMethod: return "ObjCMethod"; - case ObjCProtocol: return "ObjCProtocol"; - case ObjCProperty: return "ObjCProperty"; - case ObjCPropertyImpl: return "ObjCPropertyImpl"; - case ObjCForwardProtocol: return "ObjCForwardProtocol"; - case Record: return "Record"; - case CXXRecord: return "CXXRecord"; - case Enum: return "Enum"; - case Block: return "Block"; - case Field: return "Field"; + default: assert(0 && "Declaration not in DeclNodes.def!"); +#define DECL(Derived, Base) case Derived: return #Derived; +#include "clang/AST/DeclNodes.def" } } const char *DeclContext::getDeclKindName() const { switch (DeclKind) { - default: assert(0 && "Unknown decl kind!"); - case Decl::TranslationUnit: return "TranslationUnit"; - case Decl::Namespace: return "Namespace"; - case Decl::OverloadedFunction: return "OverloadedFunction"; - case Decl::Typedef: return "Typedef"; - case Decl::Function: return "Function"; - case Decl::Var: return "Var"; - case Decl::ParmVar: return "ParmVar"; - case Decl::OriginalParmVar: return "OriginalParmVar"; - case Decl::EnumConstant: return "EnumConstant"; - case Decl::ObjCIvar: return "ObjCIvar"; - case Decl::ObjCInterface: return "ObjCInterface"; - case Decl::ObjCImplementation: return "ObjCImplementation"; - case Decl::ObjCClass: return "ObjCClass"; - case Decl::ObjCMethod: return "ObjCMethod"; - case Decl::ObjCProtocol: return "ObjCProtocol"; - case Decl::ObjCProperty: return "ObjCProperty"; - case Decl::ObjCPropertyImpl: return "ObjCPropertyImpl"; - case Decl::ObjCForwardProtocol: return "ObjCForwardProtocol"; - case Decl::Record: return "Record"; - case Decl::CXXRecord: return "CXXRecord"; - case Decl::Enum: return "Enum"; - case Decl::Block: return "Block"; - case Decl::Field: return "Field"; + default: assert(0 && "Declaration context not in DeclNodes.def!"); +#define DECL_CONTEXT(Node) case Decl::Node: return #Node; +#include "clang/AST/DeclNodes.def" } } @@ -129,161 +62,30 @@ bool Decl::CollectingStats(bool Enable) { void Decl::PrintStats() { fprintf(stderr, "*** Decl Stats:\n"); - fprintf(stderr, " %d decls total.\n", - int(nFuncs+nVars+nParmVars+nOriginalParmVars+nFieldDecls+nSUC+nCXXSUC+ - nEnumDecls+nEnumConst+nTypedef+nInterfaceDecls+nClassDecls+ - nMethodDecls+nProtocolDecls+nCategoryDecls+nIvarDecls+ - nAtDefsFieldDecls+nNamespaces+nOverFuncs)); - fprintf(stderr, " %d namespace decls, %d each (%d bytes)\n", - nNamespaces, (int)sizeof(NamespaceDecl), - int(nNamespaces*sizeof(NamespaceDecl))); - fprintf(stderr, " %d overloaded function decls, %d each (%d bytes)\n", - nOverFuncs, (int)sizeof(OverloadedFunctionDecl), - int(nOverFuncs*sizeof(OverloadedFunctionDecl))); - fprintf(stderr, " %d function decls, %d each (%d bytes)\n", - nFuncs, (int)sizeof(FunctionDecl), int(nFuncs*sizeof(FunctionDecl))); - fprintf(stderr, " %d variable decls, %d each (%d bytes)\n", - nVars, (int)sizeof(VarDecl), - int(nVars*sizeof(VarDecl))); - fprintf(stderr, " %d parameter variable decls, %d each (%d bytes)\n", - nParmVars, (int)sizeof(ParmVarDecl), - int(nParmVars*sizeof(ParmVarDecl))); - fprintf(stderr, " %d original parameter variable decls, %d each (%d bytes)\n", - nOriginalParmVars, (int)sizeof(ParmVarWithOriginalTypeDecl), - int(nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl))); - fprintf(stderr, " %d field decls, %d each (%d bytes)\n", - nFieldDecls, (int)sizeof(FieldDecl), - int(nFieldDecls*sizeof(FieldDecl))); - fprintf(stderr, " %d @defs generated field decls, %d each (%d bytes)\n", - nAtDefsFieldDecls, (int)sizeof(ObjCAtDefsFieldDecl), - int(nAtDefsFieldDecls*sizeof(ObjCAtDefsFieldDecl))); - fprintf(stderr, " %d struct/union/class decls, %d each (%d bytes)\n", - nSUC, (int)sizeof(RecordDecl), - int(nSUC*sizeof(RecordDecl))); - fprintf(stderr, " %d C++ struct/union/class decls, %d each (%d bytes)\n", - nCXXSUC, (int)sizeof(CXXRecordDecl), - int(nCXXSUC*sizeof(CXXRecordDecl))); - fprintf(stderr, " %d enum decls, %d each (%d bytes)\n", - nEnumDecls, (int)sizeof(EnumDecl), - int(nEnumDecls*sizeof(EnumDecl))); - fprintf(stderr, " %d enum constant decls, %d each (%d bytes)\n", - nEnumConst, (int)sizeof(EnumConstantDecl), - int(nEnumConst*sizeof(EnumConstantDecl))); - fprintf(stderr, " %d typedef decls, %d each (%d bytes)\n", - nTypedef, (int)sizeof(TypedefDecl),int(nTypedef*sizeof(TypedefDecl))); - // Objective-C decls... - fprintf(stderr, " %d interface decls, %d each (%d bytes)\n", - nInterfaceDecls, (int)sizeof(ObjCInterfaceDecl), - int(nInterfaceDecls*sizeof(ObjCInterfaceDecl))); - fprintf(stderr, " %d instance variable decls, %d each (%d bytes)\n", - nIvarDecls, (int)sizeof(ObjCIvarDecl), - int(nIvarDecls*sizeof(ObjCIvarDecl))); - fprintf(stderr, " %d class decls, %d each (%d bytes)\n", - nClassDecls, (int)sizeof(ObjCClassDecl), - int(nClassDecls*sizeof(ObjCClassDecl))); - fprintf(stderr, " %d method decls, %d each (%d bytes)\n", - nMethodDecls, (int)sizeof(ObjCMethodDecl), - int(nMethodDecls*sizeof(ObjCMethodDecl))); - fprintf(stderr, " %d protocol decls, %d each (%d bytes)\n", - nProtocolDecls, (int)sizeof(ObjCProtocolDecl), - int(nProtocolDecls*sizeof(ObjCProtocolDecl))); - fprintf(stderr, " %d forward protocol decls, %d each (%d bytes)\n", - nForwardProtocolDecls, (int)sizeof(ObjCForwardProtocolDecl), - int(nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl))); - fprintf(stderr, " %d category decls, %d each (%d bytes)\n", - nCategoryDecls, (int)sizeof(ObjCCategoryDecl), - int(nCategoryDecls*sizeof(ObjCCategoryDecl))); - - fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n", - nObjCImplementationDecls, (int)sizeof(ObjCImplementationDecl), - int(nObjCImplementationDecls*sizeof(ObjCImplementationDecl))); - - fprintf(stderr, " %d class implementation decls, %d each (%d bytes)\n", - nObjCCategoryImpl, (int)sizeof(ObjCCategoryImplDecl), - int(nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl))); - - fprintf(stderr, " %d compatibility alias decls, %d each (%d bytes)\n", - nObjCCompatibleAlias, (int)sizeof(ObjCCompatibleAliasDecl), - int(nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl))); - fprintf(stderr, " %d property decls, %d each (%d bytes)\n", - nObjCPropertyDecl, (int)sizeof(ObjCPropertyDecl), - int(nObjCPropertyDecl*sizeof(ObjCPropertyDecl))); - - fprintf(stderr, " %d property implementation decls, %d each (%d bytes)\n", - nObjCPropertyImplDecl, (int)sizeof(ObjCPropertyImplDecl), - int(nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl))); + int totalDecls = 0; +#define DECL(Derived, Base) totalDecls += n##Derived##s; +#include "clang/AST/DeclNodes.def" + fprintf(stderr, " %d decls total.\n", totalDecls); + + int totalBytes = 0; +#define DECL(Derived, Base) \ + if (n##Derived##s > 0) { \ + totalBytes += (int)(n##Derived##s * sizeof(Derived##Decl)); \ + fprintf(stderr, " %d " #Derived " decls, %d each (%d bytes)\n", \ + n##Derived##s, (int)sizeof(Derived##Decl), \ + (int)(n##Derived##s * sizeof(Derived##Decl))); \ + } +#include "clang/AST/DeclNodes.def" - fprintf(stderr, "Total bytes = %d\n", - int(nFuncs*sizeof(FunctionDecl)+ - nVars*sizeof(VarDecl)+nParmVars*sizeof(ParmVarDecl)+ - nOriginalParmVars*sizeof(ParmVarWithOriginalTypeDecl)+ - nFieldDecls*sizeof(FieldDecl)+nSUC*sizeof(RecordDecl)+ - nCXXSUC*sizeof(CXXRecordDecl)+ - nEnumDecls*sizeof(EnumDecl)+nEnumConst*sizeof(EnumConstantDecl)+ - nTypedef*sizeof(TypedefDecl)+ - nInterfaceDecls*sizeof(ObjCInterfaceDecl)+ - nIvarDecls*sizeof(ObjCIvarDecl)+ - nClassDecls*sizeof(ObjCClassDecl)+ - nMethodDecls*sizeof(ObjCMethodDecl)+ - nProtocolDecls*sizeof(ObjCProtocolDecl)+ - nForwardProtocolDecls*sizeof(ObjCForwardProtocolDecl)+ - nCategoryDecls*sizeof(ObjCCategoryDecl)+ - nObjCImplementationDecls*sizeof(ObjCImplementationDecl)+ - nObjCCategoryImpl*sizeof(ObjCCategoryImplDecl)+ - nObjCCompatibleAlias*sizeof(ObjCCompatibleAliasDecl)+ - nObjCPropertyDecl*sizeof(ObjCPropertyDecl)+ - nObjCPropertyImplDecl*sizeof(ObjCPropertyImplDecl)+ - nLinkageSpecDecl*sizeof(LinkageSpecDecl)+ - nFileScopeAsmDecl*sizeof(FileScopeAsmDecl)+ - nNamespaces*sizeof(NamespaceDecl)+ - nOverFuncs*sizeof(OverloadedFunctionDecl))); - + fprintf(stderr, "Total bytes = %d\n", totalBytes); } void Decl::addDeclKind(Kind k) { switch (k) { - case Namespace: nNamespaces++; break; - case OverloadedFunction: nOverFuncs++; break; - case Typedef: nTypedef++; break; - case Function: nFuncs++; break; - case Var: nVars++; break; - case ParmVar: nParmVars++; break; - case OriginalParmVar: nOriginalParmVars++; break; - case EnumConstant: nEnumConst++; break; - case Field: nFieldDecls++; break; - case Record: nSUC++; break; - case Enum: nEnumDecls++; break; - case ObjCContainer: break; // is abstract...no need to account for. - case ObjCInterface: nInterfaceDecls++; break; - case ObjCClass: nClassDecls++; break; - case ObjCMethod: nMethodDecls++; break; - case ObjCProtocol: nProtocolDecls++; break; - case ObjCForwardProtocol: nForwardProtocolDecls++; break; - case ObjCCategory: nCategoryDecls++; break; - case ObjCIvar: nIvarDecls++; break; - case ObjCAtDefsField: nAtDefsFieldDecls++; break; - case ObjCImplementation: nObjCImplementationDecls++; break; - case ObjCCategoryImpl: nObjCCategoryImpl++; break; - case ObjCCompatibleAlias: nObjCCompatibleAlias++; break; - case ObjCProperty: nObjCPropertyDecl++; break; - case ObjCPropertyImpl: nObjCPropertyImplDecl++; break; - case LinkageSpec: nLinkageSpecDecl++; break; - case FileScopeAsm: nFileScopeAsmDecl++; break; - case Block: nBlockDecls++; break; - case ImplicitParam: - case TranslationUnit: break; - - case CXXRecord: nCXXSUC++; break; - // FIXME: Statistics for C++ decls. - case TemplateTypeParm: - case NonTypeTemplateParm: - case CXXMethod: - case CXXConstructor: - case CXXDestructor: - case CXXConversion: - case CXXClassVar: - break; + default: assert(0 && "Declaration not in DeclNodes.def!"); +#define DECL(Derived, Base) case Derived: ++n##Derived##s; break; +#include "clang/AST/DeclNodes.def" } } diff --git a/clang/lib/AST/DeclSerialization.cpp b/clang/lib/AST/DeclSerialization.cpp index 662de369a7f3..5b881f21862f 100644 --- a/clang/lib/AST/DeclSerialization.cpp +++ b/clang/lib/AST/DeclSerialization.cpp @@ -90,7 +90,7 @@ Decl* Decl::Create(Deserializer& D, ASTContext& C) { break; case OriginalParmVar: - Dcl = ParmVarWithOriginalTypeDecl::CreateImpl(D, C); + Dcl = OriginalParmVarDecl::CreateImpl(D, C); break; case Function: @@ -361,18 +361,18 @@ ParmVarDecl* ParmVarDecl::CreateImpl(Deserializer& D, ASTContext& C) { } //===----------------------------------------------------------------------===// -// ParmVarWithOriginalTypeDecl Serialization. +// OriginalParmVarDecl Serialization. //===----------------------------------------------------------------------===// -void ParmVarWithOriginalTypeDecl::EmitImpl(llvm::Serializer& S) const { +void OriginalParmVarDecl::EmitImpl(llvm::Serializer& S) const { ParmVarDecl::EmitImpl(S); S.Emit(OriginalType); } -ParmVarWithOriginalTypeDecl* ParmVarWithOriginalTypeDecl::CreateImpl( +OriginalParmVarDecl* OriginalParmVarDecl::CreateImpl( Deserializer& D, ASTContext& C) { - ParmVarWithOriginalTypeDecl* decl = new (C) - ParmVarWithOriginalTypeDecl(0, SourceLocation(), NULL, QualType(), + OriginalParmVarDecl* decl = new (C) + OriginalParmVarDecl(0, SourceLocation(), NULL, QualType(), QualType(), None, NULL); decl->ParmVarDecl::ReadImpl(D, C); diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp index c3519f8f010e..3b0265e7033f 100644 --- a/clang/lib/Sema/SemaDeclObjC.cpp +++ b/clang/lib/Sema/SemaDeclObjC.cpp @@ -1362,10 +1362,10 @@ Sema::DeclTy *Sema::ActOnMethodDeclaration( ArgNames[i], argType, VarDecl::None, 0); else - Param = ParmVarWithOriginalTypeDecl::Create(Context, ObjCMethod, - SourceLocation(/*FIXME*/), - ArgNames[i], argType, originalArgType, - VarDecl::None, 0); + Param = OriginalParmVarDecl::Create(Context, ObjCMethod, + SourceLocation(/*FIXME*/), + ArgNames[i], argType, originalArgType, + VarDecl::None, 0); Param->setObjCDeclQualifier( CvtQTToAstBitMask(ArgQT[i].getObjCDeclQualifier())); -- GitLab From 3668cb2d3c0437c4f339a1596cab9e82b6af93c7 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Mon, 2 Feb 2009 23:43:58 +0000 Subject: [PATCH 653/682] Change CGFunctionInfo args iterator to not include the return type. llvm-svn: 63571 --- clang/lib/CodeGen/CGCall.cpp | 28 ++++++++++++++-------------- clang/lib/CodeGen/CGCall.h | 10 ++++------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 7e2592206e0b..898c780aaecc 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -97,11 +97,11 @@ CGFunctionInfo::CGFunctionInfo(QualType ResTy, ArgTypes.insert(ArgTypes.end(), ArgTys.begin(), ArgTys.end()); } -ArgTypeIterator CGFunctionInfo::argtypes_begin() const { - return ArgTypes.begin(); +CGFunctionInfo::arg_iterator CGFunctionInfo::arg_begin() const { + return ArgTypes.begin()+1; } -ArgTypeIterator CGFunctionInfo::argtypes_end() const { +CGFunctionInfo::arg_iterator CGFunctionInfo::arg_end() const { return ArgTypes.end(); } @@ -965,8 +965,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { const llvm::Type *ResultType = 0; - ArgTypeIterator begin = FI.argtypes_begin(), end = FI.argtypes_end(); - QualType RetTy = *begin; + QualType RetTy = FI.getReturnType(); ABIArgInfo RetAI = getABIReturnInfo(RetTy, *this); switch (RetAI.getKind()) { case ABIArgInfo::ByVal: @@ -997,9 +996,10 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { break; } - for (++begin; begin != end; ++begin) { - ABIArgInfo AI = getABIArgumentInfo(*begin, *this); - const llvm::Type *Ty = ConvertType(*begin); + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); + it != ie; ++it) { + ABIArgInfo AI = getABIArgumentInfo(*it, *this); + const llvm::Type *Ty = ConvertType(*it); switch (AI.getKind()) { case ABIArgInfo::Ignore: @@ -1020,7 +1020,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { break; case ABIArgInfo::Expand: - GetExpandedTypes(*begin, ArgTys); + GetExpandedTypes(*it, ArgTys); break; } } @@ -1028,7 +1028,7 @@ CodeGenTypes::GetFunctionType(const CGFunctionInfo &FI, bool IsVariadic) { return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic); } -void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &Info, +void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI, const Decl *TargetDecl, AttributeListType &PAL) { unsigned FuncAttrs = 0; @@ -1045,8 +1045,7 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &Info, FuncAttrs |= llvm::Attribute::ReadNone; } - ArgTypeIterator begin = Info.argtypes_begin(), end = Info.argtypes_end(); - QualType RetTy = *begin; + QualType RetTy = FI.getReturnType(); unsigned Index = 1; ABIArgInfo RetAI = getABIReturnInfo(RetTy, getTypes()); switch (RetAI.getKind()) { @@ -1078,8 +1077,9 @@ void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &Info, if (RetAttrs) PAL.push_back(llvm::AttributeWithIndex::get(0, RetAttrs)); - for (++begin; begin != end; ++begin) { - QualType ParamType = *begin; + for (CGFunctionInfo::arg_iterator it = FI.arg_begin(), ie = FI.arg_end(); + it != ie; ++it) { + QualType ParamType = *it; unsigned Attributes = 0; ABIArgInfo AI = getABIArgumentInfo(ParamType, getTypes()); diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index f8fb32b15a4e..aaab36ca83ec 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -47,21 +47,19 @@ namespace CodeGen { typedef llvm::SmallVector, 16> FunctionArgList; - // FIXME: This should be a better iterator type so that we can avoid - // construction of the ArgTypes smallvectors. - typedef llvm::SmallVector::const_iterator ArgTypeIterator; - /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. class CGFunctionInfo { llvm::SmallVector ArgTypes; public: + typedef llvm::SmallVector::const_iterator arg_iterator; + CGFunctionInfo(QualType ResTy, const llvm::SmallVector &ArgTys); - ArgTypeIterator argtypes_begin() const; - ArgTypeIterator argtypes_end() const; + arg_iterator arg_begin() const; + arg_iterator arg_end() const; QualType getReturnType() const { return ArgTypes[0]; } }; -- GitLab From f58f0cbfd5cecbbddc70059be27229793a4b5453 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Mon, 2 Feb 2009 23:43:59 +0000 Subject: [PATCH 654/682] Fix another test to not use -mcpu=yonah with 64-bit code. llvm-svn: 63572 --- llvm/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll b/llvm/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll index 61240979ac3b..f793b524e61f 100644 --- a/llvm/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll +++ b/llvm/test/CodeGen/X86/2008-08-25-AsmRegTypeMismatch.ll @@ -1,5 +1,5 @@ -; RUN: llvm-as < %s | llc -mcpu=yonah | grep pxor | count 2 -; RUN: llvm-as < %s | llc -mcpu=yonah | not grep movapd +; RUN: llvm-as < %s | llc -mcpu=core2 | grep pxor | count 2 +; RUN: llvm-as < %s | llc -mcpu=core2 | not grep movapd ; PR2715 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128" -- GitLab From 99231d5c98f49eba72019b1817e0136e689e3986 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Mon, 2 Feb 2009 23:46:21 +0000 Subject: [PATCH 655/682] Formatting fix. llvm-svn: 63573 --- clang/lib/Parse/ParseExpr.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp index 1bec279890d4..c4df632cc8cd 100644 --- a/clang/lib/Parse/ParseExpr.cpp +++ b/clang/lib/Parse/ParseExpr.cpp @@ -1256,8 +1256,7 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { } else { Actions.ActOnBlockError(CaretLoc, CurScope); } - } - else { + } else { // Saw something like: ^expr Diag(Tok, diag::err_expected_expression); return ExprError(); -- GitLab From 72ba6df1a9860b60d0f741c0dcba3aa610375c13 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Mon, 2 Feb 2009 23:46:53 +0000 Subject: [PATCH 656/682] Last DebugLoc propagation for this file. llvm-svn: 63574 --- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 384 ++++++++++-------- 1 file changed, 204 insertions(+), 180 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index ece572a9f013..f88831e83812 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -1117,7 +1117,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Fall Thru case TargetLowering::Legal: { SDValue Ops[] = { DAG.getConstant(0, VT), Tmp1 }; - Result = DAG.getMergeValues(Ops, 2); + Result = DAG.getMergeValues(Ops, 2, dl); break; } } @@ -1151,7 +1151,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Fall Thru case TargetLowering::Legal: { SDValue Ops[] = { DAG.getConstant(0, VT), Tmp2 }; - Result = DAG.getMergeValues(Ops, 2); + Result = DAG.getMergeValues(Ops, 2, dl); break; } } @@ -1283,14 +1283,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { unsigned Line = DSP->getLine(); unsigned Col = DSP->getColumn(); + // A bit self-referential to have DebugLoc on Debug_Loc nodes, but + // it won't hurt anything. if (useDEBUG_LOC) { SDValue Ops[] = { Tmp1, DAG.getConstant(Line, MVT::i32), DAG.getConstant(Col, MVT::i32), DAG.getConstant(SrcFile, MVT::i32) }; - Result = DAG.getNode(ISD::DEBUG_LOC, MVT::Other, Ops, 4); + Result = DAG.getNode(ISD::DEBUG_LOC, dl, MVT::Other, Ops, 4); } else { unsigned ID = DW->RecordSourceLine(Line, Col, SrcFile); - Result = DAG.getLabel(ISD::DBG_LABEL, Tmp1, ID); + Result = DAG.getLabel(ISD::DBG_LABEL, dl, Tmp1, ID); } } else { Result = Tmp1; // chain @@ -1642,7 +1644,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // match the element type of the vector being created. if (Tmp2.getValueType() == Op.getValueType().getVectorElementType()) { - SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, + SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, Tmp1.getValueType(), Tmp2); unsigned NumElts = Tmp1.getValueType().getVectorNumElements(); @@ -1660,10 +1662,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { else ShufOps.push_back(DAG.getConstant(NumElts, ShufMaskEltVT)); } - SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, ShufMaskVT, + SDValue ShufMask = DAG.getNode(ISD::BUILD_VECTOR, dl, ShufMaskVT, &ShufOps[0], ShufOps.size()); - Result = DAG.getNode(ISD::VECTOR_SHUFFLE, Tmp1.getValueType(), + Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, Tmp1.getValueType(), Tmp1, ScVec, ShufMask); Result = LegalizeOp(Result); break; @@ -1728,19 +1730,19 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { for (unsigned i = 0; i != NumElems; ++i) { SDValue Arg = Mask.getOperand(i); if (Arg.getOpcode() == ISD::UNDEF) { - Ops.push_back(DAG.getNode(ISD::UNDEF, EltVT)); + Ops.push_back(DAG.getNode(ISD::UNDEF, dl, EltVT)); } else { assert(isa(Arg) && "Invalid VECTOR_SHUFFLE mask!"); unsigned Idx = cast(Arg)->getZExtValue(); if (Idx < NumElems) - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp1, + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp1, DAG.getConstant(Idx, PtrVT))); else - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, Tmp2, + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp2, DAG.getConstant(Idx - NumElems, PtrVT))); } } - Result = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], Ops.size()); + Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); break; } case TargetLowering::Promote: { @@ -1749,14 +1751,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); // Cast the two input vectors. - Tmp1 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp1); - Tmp2 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp2); + Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1); + Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2); // Convert the shuffle mask to the right # elements. Tmp3 = SDValue(isShuffleLegal(OVT, Node->getOperand(2)), 0); assert(Tmp3.getNode() && "Shuffle not legal?"); - Result = DAG.getNode(ISD::VECTOR_SHUFFLE, NVT, Tmp1, Tmp2, Tmp3); - Result = DAG.getNode(ISD::BIT_CONVERT, OVT, Result); + Result = DAG.getNode(ISD::VECTOR_SHUFFLE, dl, NVT, Tmp1, Tmp2, Tmp3); + Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result); break; } } @@ -1788,11 +1790,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT EltVT = VVT.getVectorElementType(); unsigned NumSubElem = VVT.getVectorNumElements(); for (unsigned j=0; j < NumSubElem; ++j) { - Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, EltVT, SubOp, + Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, SubOp, DAG.getConstant(j, PtrVT))); } } - return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, Node->getValueType(0), + return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0), &Ops[0], Ops.size())); } @@ -1815,7 +1817,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Merge in the last call, to ensure that this call start after the last // call ended. if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) { - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, + Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); } @@ -1914,12 +1917,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { unsigned StackAlign = TLI.getTargetMachine().getFrameInfo()->getStackAlignment(); if (Align > StackAlign) - SP = DAG.getNode(ISD::AND, VT, SP, + SP = DAG.getNode(ISD::AND, dl, VT, SP, DAG.getConstant(-(uint64_t)Align, VT)); - Tmp1 = DAG.getNode(ISD::SUB, VT, SP, Size); // Value + Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value Chain = DAG.getCopyToReg(Chain, SPReg, Tmp1); // Output chain - Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), + Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), DAG.getIntPtrConstant(0, true), SDValue()); Tmp1 = LegalizeOp(Tmp1); @@ -1981,7 +1984,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::BR: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a branch. - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); LastCALLSEQ_END = DAG.getEntryNode(); @@ -1990,7 +1993,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::BRIND: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a branch. - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); LastCALLSEQ_END = DAG.getEntryNode(); @@ -2005,7 +2008,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::BR_JT: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a branch. - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); LastCALLSEQ_END = DAG.getEntryNode(); @@ -2027,28 +2030,29 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT PTy = TLI.getPointerTy(); MachineFunction &MF = DAG.getMachineFunction(); unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize(); - Index= DAG.getNode(ISD::MUL, PTy, Index, DAG.getConstant(EntrySize, PTy)); - SDValue Addr = DAG.getNode(ISD::ADD, PTy, Index, Table); + Index= DAG.getNode(ISD::MUL, dl, PTy, + Index, DAG.getConstant(EntrySize, PTy)); + SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); MVT MemVT = MVT::getIntegerVT(EntrySize * 8); - SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, PTy, Chain, Addr, + SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr, PseudoSourceValue::getJumpTable(), 0, MemVT); Addr = LD; if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) { // For PIC, the sequence is: // BRIND(load(Jumptable + index) + RelocBase) // RelocBase can be JumpTable, GOT or some sort of global base. - Addr = DAG.getNode(ISD::ADD, PTy, Addr, + Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, TLI.getPICJumpTableRelocBase(Table, DAG)); } - Result = DAG.getNode(ISD::BRIND, MVT::Other, LD.getValue(1), Addr); + Result = DAG.getNode(ISD::BRIND, dl, MVT::Other, LD.getValue(1), Addr); } } break; case ISD::BRCOND: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a return. - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); LastCALLSEQ_END = DAG.getEntryNode(); @@ -2065,7 +2069,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { unsigned BitWidth = Tmp2.getValueSizeInBits(); if (!DAG.MaskedValueIsZero(Tmp2, APInt::getHighBitsSet(BitWidth, BitWidth-1))) - Tmp2 = DAG.getZeroExtendInReg(Tmp2, MVT::i1); + Tmp2 = DAG.getZeroExtendInReg(Tmp2, dl, MVT::i1); break; } } @@ -2084,11 +2088,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Expand brcond's setcc into its constituent parts and create a BR_CC // Node. if (Tmp2.getOpcode() == ISD::SETCC) { - Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, Tmp2.getOperand(2), + Result = DAG.getNode(ISD::BR_CC, dl, MVT::Other, + Tmp1, Tmp2.getOperand(2), Tmp2.getOperand(0), Tmp2.getOperand(1), Node->getOperand(2)); } else { - Result = DAG.getNode(ISD::BR_CC, MVT::Other, Tmp1, + Result = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1, DAG.getCondCode(ISD::SETNE), Tmp2, DAG.getConstant(0, Tmp2.getValueType()), Node->getOperand(2)); @@ -2099,7 +2104,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::BR_CC: Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a branch. - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); Tmp2 = Node->getOperand(2); // LHS Tmp3 = Node->getOperand(3); // RHS @@ -2172,7 +2177,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Change base type to a different vector type. MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT); - Tmp1 = DAG.getLoad(NVT, Tmp1, Tmp2, LD->getSrcValue(), + Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getSrcValue(), LD->getSrcValueOffset(), LD->isVolatile(), LD->getAlignment()); Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, VT, Tmp1)); @@ -2214,7 +2219,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { ISD::LoadExtType NewExtType = ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD; - Result = DAG.getExtLoad(NewExtType, Node->getValueType(0), + Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset, NVT, isVolatile, Alignment); @@ -2222,11 +2227,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (ExtType == ISD::SEXTLOAD) // Having the top bits zero doesn't help when sign extending. - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), + Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, + Result.getValueType(), Result, DAG.getValueType(SrcVT)); else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType()) // All the top bits are guaranteed to be zero - inform the optimizers. - Result = DAG.getNode(ISD::AssertZext, Result.getValueType(), Result, + Result = DAG.getNode(ISD::AssertZext, dl, + Result.getValueType(), Result, DAG.getValueType(SrcVT)); Tmp1 = LegalizeOp(Result); @@ -2249,58 +2256,60 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (TLI.isLittleEndian()) { // EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16) // Load the bottom RoundWidth bits. - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, Node->getValueType(0), Tmp1, Tmp2, + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, + Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset, RoundVT, isVolatile, Alignment); // Load the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; - Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2, + Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset + IncrementSize, ExtraVT, isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); // Move the top bits to the right place. - Hi = DAG.getNode(ISD::SHL, Hi.getValueType(), Hi, + Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); // Join the hi and lo parts. - Result = DAG.getNode(ISD::OR, Node->getValueType(0), Lo, Hi); + Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); } else { // Big endian - avoid unaligned loads. // EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8 // Load the top RoundWidth bits. - Hi = DAG.getExtLoad(ExtType, Node->getValueType(0), Tmp1, Tmp2, + Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset, RoundVT, isVolatile, Alignment); // Load the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; - Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(IncrementSize)); - Lo = DAG.getExtLoad(ISD::ZEXTLOAD, Node->getValueType(0), Tmp1, Tmp2, + Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, + Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), SVOffset + IncrementSize, ExtraVT, isVolatile, MinAlign(Alignment, IncrementSize)); // Build a factor node to remember that this load is independent of the // other one. - Ch = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo.getValue(1), + Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), Hi.getValue(1)); // Move the top bits to the right place. - Hi = DAG.getNode(ISD::SHL, Hi.getValueType(), Hi, + Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); // Join the hi and lo parts. - Result = DAG.getNode(ISD::OR, Node->getValueType(0), Lo, Hi); + Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); } Tmp1 = LegalizeOp(Result); @@ -2342,10 +2351,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case TargetLowering::Expand: // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) { - SDValue Load = DAG.getLoad(SrcVT, Tmp1, Tmp2, LD->getSrcValue(), + SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, LD->getSrcValue(), LD->getSrcValueOffset(), LD->isVolatile(), LD->getAlignment()); - Result = DAG.getNode(ISD::FP_EXTEND, Node->getValueType(0), Load); + Result = DAG.getNode(ISD::FP_EXTEND, dl, + Node->getValueType(0), Load); Tmp1 = LegalizeOp(Result); // Relegalize new nodes. Tmp2 = LegalizeOp(Load.getValue(1)); break; @@ -2353,16 +2363,17 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { assert(ExtType != ISD::EXTLOAD &&"EXTLOAD should always be supported!"); // Turn the unsupported load into an EXTLOAD followed by an explicit // zero/sign extend inreg. - Result = DAG.getExtLoad(ISD::EXTLOAD, Node->getValueType(0), + Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0), Tmp1, Tmp2, LD->getSrcValue(), LD->getSrcValueOffset(), SrcVT, LD->isVolatile(), LD->getAlignment()); SDValue ValRes; if (ExtType == ISD::SEXTLOAD) - ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), + ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, + Result.getValueType(), Result, DAG.getValueType(SrcVT)); else - ValRes = DAG.getZeroExtendInReg(Result, SrcVT); + ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT); Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes. break; @@ -2383,13 +2394,13 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case Legal: if (cast(Node->getOperand(1))->getZExtValue()) { // 1 -> Hi - Result = DAG.getNode(ISD::SRL, OpTy, Node->getOperand(0), + Result = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0), DAG.getConstant(OpTy.getSizeInBits()/2, TLI.getShiftAmountTy())); - Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), Result); + Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Result); } else { // 0 -> Lo - Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), + Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Node->getOperand(0)); } break; @@ -2436,7 +2447,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. // Ensure that libcalls are emitted before a return. - Tmp1 = DAG.getNode(ISD::TokenFactor, MVT::Other, Tmp1, LastCALLSEQ_END); + Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); Tmp1 = LegalizeOp(Tmp1); LastCALLSEQ_END = DAG.getEntryNode(); @@ -2458,9 +2469,10 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { std::swap(Lo, Hi); if (Hi.getNode()) - Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi,Tmp3); + Result = DAG.getNode(ISD::RET, dl, MVT::Other, + Tmp1, Lo, Tmp3, Hi,Tmp3); else - Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3); + Result = DAG.getNode(ISD::RET, dl, MVT::Other, Tmp1, Lo, Tmp3); Result = LegalizeOp(Result); } else { SDNode *InVal = Tmp2.getNode(); @@ -2492,7 +2504,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // type should be returned by reference! SDValue Lo, Hi; SplitVectorOp(Tmp2, Lo, Hi); - Result = DAG.getNode(ISD::RET, MVT::Other, Tmp1, Lo, Tmp3, Hi,Tmp3); + Result = DAG.getNode(ISD::RET, dl, MVT::Other, + Tmp1, Lo, Tmp3, Hi,Tmp3); Result = LegalizeOp(Result); } } @@ -2536,7 +2549,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (NewValues.size() == Node->getNumOperands()) Result = DAG.UpdateNodeOperands(Result, &NewValues[0],NewValues.size()); else - Result = DAG.getNode(ISD::RET, MVT::Other, + Result = DAG.getNode(ISD::RET, dl, MVT::Other, &NewValues[0], NewValues.size()); break; } @@ -2575,7 +2588,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Tmp3 = DAG.getConstant(CFP->getValueAPF(). bitcastToAPInt().zextOrTrunc(32), MVT::i32); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); break; } else if (CFP->getValueType(0) == MVT::f64) { @@ -2583,7 +2596,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (getTypeAction(MVT::i64) == Legal) { Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). zextOrTrunc(64), MVT::i64); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); break; } else if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) { @@ -2595,14 +2608,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { SDValue Hi = DAG.getConstant(IntVal.lshr(32).trunc(32), MVT::i32); if (TLI.isBigEndian()) std::swap(Lo, Hi); - Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(), + Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); - Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(4)); - Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, + Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, isVolatile, MinAlign(Alignment, 4U)); - Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); break; } } @@ -2634,9 +2647,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case TargetLowering::Promote: assert(VT.isVector() && "Unknown legal promote case!"); - Tmp3 = DAG.getNode(ISD::BIT_CONVERT, + Tmp3 = DAG.getNode(ISD::BIT_CONVERT, dl, TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, + Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); break; @@ -2647,7 +2660,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (!ST->getMemoryVT().isVector()) { // Truncate the value and store the result. Tmp3 = PromoteOp(ST->getValue()); - Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, ST->getMemoryVT(), isVolatile, Alignment); break; @@ -2673,14 +2686,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (TLI.isTypeLegal(TVT)) { // Turn this into a normal store of the vector type. Tmp3 = LegalizeOp(ST->getValue()); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); Result = LegalizeOp(Result); break; } else if (NumElems == 1) { // Turn this into a normal store of the scalar type. Tmp3 = ScalarizeVectorOp(ST->getValue()); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); // The scalarized value type may not be legal, e.g. it might require // promotion or expansion. Relegalize the scalar store. @@ -2708,7 +2721,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { std::swap(Lo, Hi); } - Lo = DAG.getStore(Tmp1, Lo, Tmp2, ST->getSrcValue(), + Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); if (Hi.getNode() == NULL) { @@ -2717,15 +2730,15 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; } - Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(IncrementSize)); assert(isTypeLegal(Tmp2.getValueType()) && "Pointers must be legal!"); SVOffset += IncrementSize; Alignment = MinAlign(Alignment, IncrementSize); - Hi = DAG.getStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), + Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset, isVolatile, Alignment); - Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); break; } // case Expand } @@ -2745,7 +2758,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Just store the low part. This may become a non-trunc store, so make // sure to use getTruncStore, not UpdateNodeOperands below. ExpandOp(ST->getValue(), Tmp3, Tmp4); - return DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + return DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, MVT::i8, isVolatile, Alignment); } @@ -2757,8 +2770,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // storing an integral number of bytes. For example, promote // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1) MVT NVT = MVT::getIntegerVT(StVT.getStoreSizeInBits()); - Tmp3 = DAG.getZeroExtendInReg(Tmp3, StVT); - Result = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT); + Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, NVT, isVolatile, Alignment); } else if (StWidth & (StWidth - 1)) { // If not storing a power-of-2 number of bits, expand as two stores. @@ -2778,39 +2791,39 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (TLI.isLittleEndian()) { // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16) // Store the bottom RoundWidth bits. - Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, RoundVT, isVolatile, Alignment); // Store the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; - Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(IncrementSize)); - Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3, + Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); - Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), + Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset + IncrementSize, ExtraVT, isVolatile, MinAlign(Alignment, IncrementSize)); } else { // Big endian - avoid unaligned stores. // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X // Store the top RoundWidth bits. - Hi = DAG.getNode(ISD::SRL, Tmp3.getValueType(), Tmp3, + Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); - Hi = DAG.getTruncStore(Tmp1, Hi, Tmp2, ST->getSrcValue(), SVOffset, - RoundVT, isVolatile, Alignment); + Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), + SVOffset, RoundVT, isVolatile, Alignment); // Store the remaining ExtraWidth bits. IncrementSize = RoundWidth / 8; - Tmp2 = DAG.getNode(ISD::ADD, Tmp2.getValueType(), Tmp2, + Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, DAG.getIntPtrConstant(IncrementSize)); - Lo = DAG.getTruncStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), + Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), SVOffset + IncrementSize, ExtraVT, isVolatile, MinAlign(Alignment, IncrementSize)); } // The order of the stores doesn't matter. - Result = DAG.getNode(ISD::TokenFactor, MVT::Other, Lo, Hi); + Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); } else { if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() || Tmp2 != ST->getBasePtr()) @@ -2836,9 +2849,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case Expand: // TRUNCSTORE:i16 i32 -> STORE i16 assert(isTypeLegal(StVT) && "Do not know how to expand this store!"); - Tmp3 = DAG.getNode(ISD::TRUNCATE, StVT, Tmp3); - Result = DAG.getStore(Tmp1, Tmp3, Tmp2, ST->getSrcValue(), SVOffset, - isVolatile, Alignment); + Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3); + Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), + SVOffset, isVolatile, Alignment); break; } } @@ -2873,7 +2886,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { Node->getValueType(0)); Tmp2 = Tmp1.getValue(1); } else { - Tmp1 = DAG.getNode(ISD::UNDEF, Node->getValueType(0)); + Tmp1 = DAG.getNode(ISD::UNDEF, dl, Node->getValueType(0)); Tmp2 = Node->getOperand(0); } break; @@ -2945,7 +2958,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { unsigned BitWidth = Tmp1.getValueSizeInBits(); if (!DAG.MaskedValueIsZero(Tmp1, APInt::getHighBitsSet(BitWidth, BitWidth-1))) - Tmp1 = DAG.getZeroExtendInReg(Tmp1, MVT::i1); + Tmp1 = DAG.getZeroExtendInReg(Tmp1, dl, MVT::i1); break; } } @@ -2964,11 +2977,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { } case TargetLowering::Expand: if (Tmp1.getOpcode() == ISD::SETCC) { - Result = DAG.getSelectCC(Tmp1.getOperand(0), Tmp1.getOperand(1), + Result = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1), Tmp2, Tmp3, cast(Tmp1.getOperand(2))->get()); } else { - Result = DAG.getSelectCC(Tmp1, + Result = DAG.getSelectCC(dl, Tmp1, DAG.getConstant(0, Tmp1.getValueType()), Tmp2, Tmp3, ISD::SETNE); } @@ -2988,14 +3001,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { TruncOp = ISD::FP_ROUND; } // Promote each of the values to the new type. - Tmp2 = DAG.getNode(ExtOp, NVT, Tmp2); - Tmp3 = DAG.getNode(ExtOp, NVT, Tmp3); + Tmp2 = DAG.getNode(ExtOp, dl, NVT, Tmp2); + Tmp3 = DAG.getNode(ExtOp, dl, NVT, Tmp3); // Perform the larger operation, then round down. - Result = DAG.getNode(ISD::SELECT, NVT, Tmp1, Tmp2,Tmp3); + Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp1, Tmp2,Tmp3); if (TruncOp != ISD::FP_ROUND) - Result = DAG.getNode(TruncOp, Node->getValueType(0), Result); + Result = DAG.getNode(TruncOp, dl, Node->getValueType(0), Result); else - Result = DAG.getNode(TruncOp, Node->getValueType(0), Result, + Result = DAG.getNode(TruncOp, dl, Node->getValueType(0), Result, DAG.getIntPtrConstant(0)); break; } @@ -3080,8 +3093,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (NewInTy.isInteger()) assert(0 && "Cannot promote Legal Integer SETCC yet"); else { - Tmp1 = DAG.getNode(ISD::FP_EXTEND, NewInTy, Tmp1); - Tmp2 = DAG.getNode(ISD::FP_EXTEND, NewInTy, Tmp2); + Tmp1 = DAG.getNode(ISD::FP_EXTEND, dl, NewInTy, Tmp1); + Tmp2 = DAG.getNode(ISD::FP_EXTEND, dl, NewInTy, Tmp2); } Tmp1 = LegalizeOp(Tmp1); Tmp2 = LegalizeOp(Tmp2); @@ -3093,7 +3106,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Expand a setcc node into a select_cc of the same condition, lhs, and // rhs that selects between const 1 (true) and const 0 (false). MVT VT = Node->getValueType(0); - Result = DAG.getNode(ISD::SELECT_CC, VT, Tmp1, Tmp2, + Result = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2, DAG.getConstant(1, VT), DAG.getConstant(0, VT), Tmp3); break; @@ -3122,17 +3135,18 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT TmpEltVT = Tmp1.getValueType().getVectorElementType(); SmallVector Ops(NumElems); for (unsigned i = 0; i < NumElems; ++i) { - SDValue In1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT, + SDValue In1 = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, TmpEltVT, Tmp1, DAG.getIntPtrConstant(i)); - Ops[i] = DAG.getNode(ISD::SETCC, TLI.getSetCCResultType(TmpEltVT), In1, - DAG.getNode(ISD::EXTRACT_VECTOR_ELT, TmpEltVT, - Tmp2, DAG.getIntPtrConstant(i)), + Ops[i] = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(TmpEltVT), + In1, DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, + TmpEltVT, Tmp2, + DAG.getIntPtrConstant(i)), CC); - Ops[i] = DAG.getNode(ISD::SELECT, EltVT, Ops[i], DAG.getConstant( + Ops[i] = DAG.getNode(ISD::SELECT, dl, EltVT, Ops[i], DAG.getConstant( APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT), DAG.getConstant(0, EltVT)); } - Result = DAG.getNode(ISD::BUILD_VECTOR, VT, &Ops[0], NumElems); + Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], NumElems); break; } } @@ -3256,31 +3270,36 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { OpToUse = ISD::UMUL_LOHI; } if (OpToUse) { - Result = SDValue(DAG.getNode(OpToUse, VTs, Tmp1, Tmp2).getNode(), 0); + Result = SDValue(DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2).getNode(), + 0); break; } } if (Node->getOpcode() == ISD::MULHS && TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) { - Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, VTs, Tmp1, Tmp2).getNode(), + Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, + VTs, Tmp1, Tmp2).getNode(), 1); break; } if (Node->getOpcode() == ISD::MULHU && TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) { - Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, VTs, Tmp1, Tmp2).getNode(), + Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, + VTs, Tmp1, Tmp2).getNode(), 1); break; } if (Node->getOpcode() == ISD::SDIV && TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { - Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(), + Result = SDValue(DAG.getNode(ISD::SDIVREM, dl, + VTs, Tmp1, Tmp2).getNode(), 0); break; } if (Node->getOpcode() == ISD::UDIV && TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { - Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(), + Result = SDValue(DAG.getNode(ISD::UDIVREM, dl, + VTs, Tmp1, Tmp2).getNode(), 0); break; } @@ -3335,11 +3354,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); assert(OVT.isVector() && "Cannot promote this BinOp!"); // Bit convert each of the values to the new type. - Tmp1 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp1); - Tmp2 = DAG.getNode(ISD::BIT_CONVERT, NVT, Tmp2); - Result = DAG.getNode(Node->getOpcode(), NVT, Tmp1, Tmp2); + Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1); + Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2); + Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); // Bit convert the result back the original type. - Result = DAG.getNode(ISD::BIT_CONVERT, OVT, Result); + Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result); break; } } @@ -3393,14 +3412,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Get the sign bit of the RHS. MVT IVT = Tmp2.getValueType() == MVT::f32 ? MVT::i32 : MVT::i64; - SDValue SignBit = DAG.getNode(ISD::BIT_CONVERT, IVT, Tmp2); - SignBit = DAG.getSetCC(TLI.getSetCCResultType(IVT), + SDValue SignBit = DAG.getNode(ISD::BIT_CONVERT, dl, IVT, Tmp2); + SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(IVT), SignBit, DAG.getConstant(0, IVT), ISD::SETLT); // Get the absolute value of the result. - SDValue AbsVal = DAG.getNode(ISD::FABS, Tmp1.getValueType(), Tmp1); + SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); // Select between the nabs and abs value based on the sign bit of // the input. - Result = DAG.getNode(ISD::SELECT, AbsVal.getValueType(), SignBit, + Result = DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, DAG.getNode(ISD::FNEG, AbsVal.getValueType(), AbsVal), AbsVal); @@ -3412,7 +3431,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT NVT = Node->getValueType(0) == MVT::f32 ? MVT::i32 : MVT::i64; Result = ExpandFCOPYSIGNToBitwiseOps(Node, NVT, DAG, TLI); - Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0), Result); + Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), Result); Result = LegalizeOp(Result); break; } @@ -3483,15 +3502,15 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { assert(0 && "Cannot promote/custom this yet!"); case TargetLowering::Legal: if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) - Result = DAG.getNode(ISD::BUILD_PAIR, PairTy, Tmp1, Tmp2); + Result = DAG.getNode(ISD::BUILD_PAIR, dl, PairTy, Tmp1, Tmp2); break; case TargetLowering::Expand: - Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, PairTy, Tmp1); - Tmp2 = DAG.getNode(ISD::ANY_EXTEND, PairTy, Tmp2); - Tmp2 = DAG.getNode(ISD::SHL, PairTy, Tmp2, + Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Tmp1); + Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Tmp2); + Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2, DAG.getConstant(PairTy.getSizeInBits()/2, TLI.getShiftAmountTy())); - Result = DAG.getNode(ISD::OR, PairTy, Tmp1, Tmp2); + Result = DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2); break; } break; @@ -3524,12 +3543,14 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { SDVTList VTs = DAG.getVTList(VT, VT); if (Node->getOpcode() == ISD::SREM && TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { - Result = SDValue(DAG.getNode(ISD::SDIVREM, VTs, Tmp1, Tmp2).getNode(), 1); + Result = SDValue(DAG.getNode(ISD::SDIVREM, dl, + VTs, Tmp1, Tmp2).getNode(), 1); break; } if (Node->getOpcode() == ISD::UREM && TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { - Result = SDValue(DAG.getNode(ISD::UDIVREM, VTs, Tmp1, Tmp2).getNode(), 1); + Result = SDValue(DAG.getNode(ISD::UDIVREM, dl, + VTs, Tmp1, Tmp2).getNode(), 1); break; } @@ -3537,9 +3558,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { if (TLI.getOperationAction(DivOpc, VT) == TargetLowering::Legal) { // X % Y -> X-X/Y*Y - Result = DAG.getNode(DivOpc, VT, Tmp1, Tmp2); - Result = DAG.getNode(ISD::MUL, VT, Result, Tmp2); - Result = DAG.getNode(ISD::SUB, VT, Tmp1, Result); + Result = DAG.getNode(DivOpc, dl, VT, Tmp1, Tmp2); + Result = DAG.getNode(ISD::MUL, dl, VT, Result, Tmp2); + Result = DAG.getNode(ISD::SUB, dl, VT, Tmp1, Result); } else if (VT.isVector()) { Result = LegalizeOp(UnrollVectorOp(Op)); } else { @@ -3592,16 +3613,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case TargetLowering::Expand: { const Value *V = cast(Node->getOperand(2))->getValue(); - SDValue VAList = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp2, V, 0); + SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0); // Increment the pointer, VAList, to the next vaarg - Tmp3 = DAG.getNode(ISD::ADD, TLI.getPointerTy(), VAList, + Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, DAG.getConstant(TLI.getTargetData()-> getTypePaddedSize(VT.getTypeForMVT()), TLI.getPointerTy())); // Store the incremented VAList to the legalized pointer - Tmp3 = DAG.getStore(VAList.getValue(1), Tmp3, Tmp2, V, 0); + Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0); // Load the actual argument out of the pointer VAList - Result = DAG.getLoad(VT, Tmp3, VAList, NULL, 0); + Result = DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0); Tmp1 = LegalizeOp(Result.getValue(1)); Result = LegalizeOp(Result); break; @@ -3637,8 +3658,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // output, returning the chain. const Value *VD = cast(Node->getOperand(3))->getValue(); const Value *VS = cast(Node->getOperand(4))->getValue(); - Tmp4 = DAG.getLoad(TLI.getPointerTy(), Tmp1, Tmp3, VS, 0); - Result = DAG.getStore(Tmp4.getValue(1), Tmp4, Tmp2, VD, 0); + Tmp4 = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp3, VS, 0); + Result = DAG.getStore(Tmp4.getValue(1), dl, Tmp4, Tmp2, VD, 0); break; } break; @@ -3718,9 +3739,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); - Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1); - Tmp1 = DAG.getNode(ISD::BSWAP, NVT, Tmp1); - Result = DAG.getNode(ISD::SRL, NVT, Tmp1, + Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1); + Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); + Result = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, DAG.getConstant(DiffBits, TLI.getShiftAmountTy())); break; } @@ -3751,24 +3772,24 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); // Zero extend the argument. - Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, NVT, Tmp1); + Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1); // Perform the larger operation, then subtract if needed. - Tmp1 = DAG.getNode(Node->getOpcode(), Node->getValueType(0), Tmp1); + Tmp1 = DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Tmp1); switch (Node->getOpcode()) { case ISD::CTPOP: Result = Tmp1; break; case ISD::CTTZ: //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, - DAG.getConstant(NVT.getSizeInBits(), NVT), + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), + Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT), ISD::SETEQ); - Result = DAG.getNode(ISD::SELECT, NVT, Tmp2, + Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1); break; case ISD::CTLZ: // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) - Result = DAG.getNode(ISD::SUB, NVT, Tmp1, + Result = DAG.getNode(ISD::SUB, dl, NVT, Tmp1, DAG.getConstant(NVT.getSizeInBits() - OVT.getSizeInBits(), NVT)); break; @@ -3816,16 +3837,16 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { case ISD::FNEG: // Expand Y = FNEG(X) -> Y = SUB -0.0, X Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0)); - Result = DAG.getNode(ISD::FSUB, Node->getValueType(0), Tmp2, Tmp1); + Result = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp2, Tmp1); break; case ISD::FABS: { // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). MVT VT = Node->getValueType(0); Tmp2 = DAG.getConstantFP(0.0, VT); - Tmp2 = DAG.getSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), + Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), Tmp1, Tmp2, ISD::SETUGT); - Tmp3 = DAG.getNode(ISD::FNEG, VT, Tmp1); - Result = DAG.getNode(ISD::SELECT, VT, Tmp2, Tmp1, Tmp3); + Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); + Result = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); break; } case ISD::FSQRT: @@ -3947,12 +3968,12 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { MVT TVT = MVT::getVectorVT(EVT, NumElems); if (TLI.isTypeLegal(TVT)) { // Turn this into a bit convert of the vector input. - Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0), + Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), LegalizeOp(Node->getOperand(0))); break; } else if (NumElems == 1) { // Turn this into a bit convert of the scalar input. - Result = DAG.getNode(ISD::BIT_CONVERT, Node->getValueType(0), + Result = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), ScalarizeVectorOp(Node->getOperand(0))); break; } else { @@ -4052,11 +4073,11 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Since the result is legal, we should just be able to truncate the low // part of the source. - Result = DAG.getNode(ISD::TRUNCATE, Node->getValueType(0), Tmp1); + Result = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1); break; case Promote: Result = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::TRUNCATE, Op.getValueType(), Result); + Result = DAG.getNode(ISD::TRUNCATE, dl, Op.getValueType(), Result); break; } break; @@ -4174,7 +4195,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::FP_EXTEND, Op.getValueType(), Tmp1); + Result = DAG.getNode(ISD::FP_EXTEND, dl, Op.getValueType(), Tmp1); break; } break; @@ -4188,7 +4209,8 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { ExpandOp(Node->getOperand(0), Lo, Result); // Round it the rest of the way (e.g. to f32) if needed. if (DstVT!=MVT::f64) - Result = DAG.getNode(ISD::FP_ROUND, DstVT, Result, Op.getOperand(1)); + Result = DAG.getNode(ISD::FP_ROUND, dl, + DstVT, Result, Op.getOperand(1)); break; } // The only other way we can lower this is to turn it into a STORE, @@ -4204,7 +4226,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { break; case Promote: Tmp1 = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::FP_ROUND, Op.getValueType(), Tmp1, + Result = DAG.getNode(ISD::FP_ROUND, dl, Op.getValueType(), Tmp1, Node->getOperand(1)); break; } @@ -4228,18 +4250,18 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { switch (Node->getOpcode()) { case ISD::ANY_EXTEND: Tmp1 = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Tmp1); + Result = DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Tmp1); break; case ISD::ZERO_EXTEND: Result = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result); - Result = DAG.getZeroExtendInReg(Result, + Result = DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Result); + Result = DAG.getZeroExtendInReg(Result, dl, Node->getOperand(0).getValueType()); break; case ISD::SIGN_EXTEND: Result = PromoteOp(Node->getOperand(0)); - Result = DAG.getNode(ISD::ANY_EXTEND, Op.getValueType(), Result); - Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, Result.getValueType(), + Result = DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Result); + Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, Result.getValueType(), Result, DAG.getValueType(Node->getOperand(0).getValueType())); break; @@ -4266,9 +4288,9 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { unsigned BitsDiff = Node->getValueType(0).getSizeInBits() - ExtraVT.getSizeInBits(); SDValue ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy()); - Result = DAG.getNode(ISD::SHL, Node->getValueType(0), + Result = DAG.getNode(ISD::SHL, dl, Node->getValueType(0), Node->getOperand(0), ShiftCst); - Result = DAG.getNode(ISD::SRA, Node->getValueType(0), + Result = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Result, ShiftCst); } else if (Node->getOpcode() == ISD::FP_ROUND_INREG) { // The only way we can lower this is to turn it into a TRUNCSTORE, @@ -4359,7 +4381,7 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { SDValue RHS = LegalizeOp(Node->getOperand(1)); SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ? - ISD::ADD : ISD::SUB, LHS.getValueType(), + ISD::ADD : ISD::SUB, dl, LHS.getValueType(), LHS, RHS); MVT OType = Node->getValueType(1); @@ -4374,21 +4396,22 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { // Sub: // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign) // - SDValue LHSSign = DAG.getSetCC(OType, LHS, Zero, ISD::SETGE); - SDValue RHSSign = DAG.getSetCC(OType, RHS, Zero, ISD::SETGE); - SDValue SignsMatch = DAG.getSetCC(OType, LHSSign, RHSSign, + SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE); + SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE); + SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign, Node->getOpcode() == ISD::SADDO ? ISD::SETEQ : ISD::SETNE); - SDValue SumSign = DAG.getSetCC(OType, Sum, Zero, ISD::SETGE); - SDValue SumSignNE = DAG.getSetCC(OType, LHSSign, SumSign, ISD::SETNE); + SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE); + SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE); - SDValue Cmp = DAG.getNode(ISD::AND, OType, SignsMatch, SumSignNE); + SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE); MVT ValueVTs[] = { LHS.getValueType(), OType }; SDValue Ops[] = { Sum, Cmp }; - Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2), + Result = DAG.getNode(ISD::MERGE_VALUES, dl, + DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); SDNode *RNode = Result.getNode(); DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); @@ -4413,17 +4436,18 @@ SDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { SDValue RHS = LegalizeOp(Node->getOperand(1)); SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ? - ISD::ADD : ISD::SUB, LHS.getValueType(), + ISD::ADD : ISD::SUB, dl, LHS.getValueType(), LHS, RHS); MVT OType = Node->getValueType(1); - SDValue Cmp = DAG.getSetCC(OType, Sum, LHS, + SDValue Cmp = DAG.getSetCC(dl, OType, Sum, LHS, Node->getOpcode () == ISD::UADDO ? ISD::SETULT : ISD::SETUGT); MVT ValueVTs[] = { LHS.getValueType(), OType }; SDValue Ops[] = { Sum, Cmp }; - Result = DAG.getNode(ISD::MERGE_VALUES, DAG.getVTList(&ValueVTs[0], 2), + Result = DAG.getNode(ISD::MERGE_VALUES, dl, + DAG.getVTList(&ValueVTs[0], 2), &Ops[0], 2); SDNode *RNode = Result.getNode(); DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), SDValue(RNode, 0)); -- GitLab From 7403751e16ab476c881ae24b1f58594d16f011d8 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Feb 2009 00:04:43 +0000 Subject: [PATCH 657/682] Change Feature64Bit to not imply FeatureSSE2. All x86-64 hardware has SSE2, however it's possible to disable SSE2, and the subtarget support code thinks that if 64-bit implies SSE2 and SSE2 is disabled then 64-bit should also be disabled. Instead, just mark all the 64-bit subtargets as explicitly supporting SSE2. Also, move the code that makes -march=x86-64 enable 64-bit support by default to only apply when there is no explicit subtarget. If you need to specify a subtarget and you want 64-bit code, you'll need to select a subtarget that supports 64-bit code. llvm-svn: 63575 --- llvm/lib/Target/X86/X86.td | 20 +++++++++++++------- llvm/lib/Target/X86/X86Subtarget.cpp | 19 +++++++++---------- 2 files changed, 22 insertions(+), 17 deletions(-) diff --git a/llvm/lib/Target/X86/X86.td b/llvm/lib/Target/X86/X86.td index 7a2f2570b34c..0e2c98097ed4 100644 --- a/llvm/lib/Target/X86/X86.td +++ b/llvm/lib/Target/X86/X86.td @@ -45,9 +45,11 @@ def Feature3DNow : SubtargetFeature<"3dnow", "X863DNowLevel", "ThreeDNow", def Feature3DNowA : SubtargetFeature<"3dnowa", "X863DNowLevel", "ThreeDNowA", "Enable 3DNow! Athlon instructions", [Feature3DNow]>; +// All x86-64 hardware has SSE2, but we don't mark SSE2 as an implied +// feature, because SSE2 can be disabled (e.g. for compiling OS kernels) +// without disabling 64-bit mode. def Feature64Bit : SubtargetFeature<"64bit", "HasX86_64", "true", - "Support 64-bit instructions", - [FeatureSSE2]>; + "Support 64-bit instructions">; def FeatureSlowBTMem : SubtargetFeature<"slow-bt-mem", "IsBTMemSlow", "true", "Bit testing of memory is slow">; @@ -70,7 +72,7 @@ def : Proc<"pentium2", [FeatureMMX]>; def : Proc<"pentium3", [FeatureSSE1]>; def : Proc<"pentium-m", [FeatureSSE2, FeatureSlowBTMem]>; def : Proc<"pentium4", [FeatureSSE2]>; -def : Proc<"x86-64", [Feature64Bit, FeatureSlowBTMem]>; +def : Proc<"x86-64", [FeatureSSE2, Feature64Bit, FeatureSlowBTMem]>; def : Proc<"yonah", [FeatureSSE3, FeatureSlowBTMem]>; def : Proc<"prescott", [FeatureSSE3, FeatureSlowBTMem]>; def : Proc<"nocona", [FeatureSSE3, Feature64Bit, FeatureSlowBTMem]>; @@ -87,10 +89,14 @@ def : Proc<"athlon-tbird", [FeatureMMX, Feature3DNowA, FeatureSlowBTMem]>; def : Proc<"athlon-4", [FeatureSSE1, Feature3DNowA, FeatureSlowBTMem]>; def : Proc<"athlon-xp", [FeatureSSE1, Feature3DNowA, FeatureSlowBTMem]>; def : Proc<"athlon-mp", [FeatureSSE1, Feature3DNowA, FeatureSlowBTMem]>; -def : Proc<"k8", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>; -def : Proc<"opteron", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>; -def : Proc<"athlon64", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>; -def : Proc<"athlon-fx", [Feature3DNowA, Feature64Bit, FeatureSlowBTMem]>; +def : Proc<"k8", [FeatureSSE2, Feature3DNowA, Feature64Bit, + FeatureSlowBTMem]>; +def : Proc<"opteron", [FeatureSSE2, Feature3DNowA, Feature64Bit, + FeatureSlowBTMem]>; +def : Proc<"athlon64", [FeatureSSE2, Feature3DNowA, Feature64Bit, + FeatureSlowBTMem]>; +def : Proc<"athlon-fx", [FeatureSSE2, Feature3DNowA, Feature64Bit, + FeatureSlowBTMem]>; def : Proc<"winchip-c6", [FeatureMMX]>; def : Proc<"winchip2", [FeatureMMX, Feature3DNow]>; diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index 185f45b4cf1b..5ceafa4c593d 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -327,21 +327,20 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) } else { // Otherwise, use CPUID to auto-detect feature set. AutoDetectSubtargetFeatures(); - if (Is64Bit && X86SSELevel < SSE2) { - // Make sure SSE2 is enabled, it is available on all X86-64 CPUs. - X86SSELevel = SSE2; - } - } - - // If requesting codegen for X86-64, make sure that 64-bit features - // are enabled. - if (Is64Bit) { + // If requesting codegen for X86-64, make sure that 64-bit features + // are enabled. + if (Is64Bit) HasX86_64 = true; + // Make sure SSE2 is enabled; it is available on all X86-64 CPUs. + if (Is64Bit && X86SSELevel < SSE2) + X86SSELevel = SSE2; } - assert(!Is64Bit || HasX86_64); + DOUT << "Subtarget features: SSELevel " << X86SSELevel << ", 3DNowLevel " << X863DNowLevel << ", 64bit " << HasX86_64 << "\n"; + assert((!Is64Bit || HasX86_64) && + "64-bit code requested on a subtarget that doesn't support it!"); // Set the boolean corresponding to the current target triple, or the default // if one cannot be determined, to true. -- GitLab From e0be82956b3d1f8d2cad3954d14921cacb72ff7c Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 3 Feb 2009 00:07:12 +0000 Subject: [PATCH 658/682] Memoize CGFunctionInfo construction. llvm-svn: 63576 --- clang/lib/CodeGen/CGCall.cpp | 13 ++++++++++++- clang/lib/CodeGen/CGCall.h | 16 +++++++++++++++- clang/lib/CodeGen/CodeGenTypes.h | 3 +++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 898c780aaecc..30257d2699e4 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -86,7 +86,18 @@ const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const CGFunctionInfo &CodeGenTypes::getFunctionInfo(QualType ResTy, const llvm::SmallVector &ArgTys) { - return *new CGFunctionInfo(ResTy, ArgTys); + // Lookup or create unique function info. + llvm::FoldingSetNodeID ID; + CGFunctionInfo::Profile(ID, ResTy, ArgTys.begin(), ArgTys.end()); + + void *InsertPos = 0; + CGFunctionInfo *FI = FunctionInfos.FindNodeOrInsertPos(ID, InsertPos); + if (FI) + return *FI; + + FI = new CGFunctionInfo(ResTy, ArgTys); + FunctionInfos.InsertNode(FI, InsertPos); + return *FI; } /***/ diff --git a/clang/lib/CodeGen/CGCall.h b/clang/lib/CodeGen/CGCall.h index aaab36ca83ec..611304900f62 100644 --- a/clang/lib/CodeGen/CGCall.h +++ b/clang/lib/CodeGen/CGCall.h @@ -15,6 +15,7 @@ #ifndef CLANG_CODEGEN_CGCALL_H #define CLANG_CODEGEN_CGCALL_H +#include #include "clang/AST/Type.h" #include "CGValue.h" @@ -49,7 +50,7 @@ namespace CodeGen { /// CGFunctionInfo - Class to encapsulate the information about a /// function definition. - class CGFunctionInfo { + class CGFunctionInfo : public llvm::FoldingSetNode { llvm::SmallVector ArgTypes; public: @@ -62,6 +63,19 @@ namespace CodeGen { arg_iterator arg_end() const; QualType getReturnType() const { return ArgTypes[0]; } + + void Profile(llvm::FoldingSetNodeID &ID) { + Profile(ID, getReturnType(), arg_begin(), arg_end()); + } + template + static void Profile(llvm::FoldingSetNodeID &ID, + QualType ResTy, + Iterator begin, + Iterator end) { + ResTy.Profile(ID); + for (; begin != end; ++begin) + begin->Profile(ID); + } }; } // end namespace CodeGen } // end namespace clang diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h index d41c23d37476..3070c8526098 100644 --- a/clang/lib/CodeGen/CodeGenTypes.h +++ b/clang/lib/CodeGen/CodeGenTypes.h @@ -100,6 +100,9 @@ class CodeGenTypes { /// field no. This info is populated by record organizer. llvm::DenseMap FieldInfo; + /// FunctionInfos - Hold memoized CGFunctionInfo results. + llvm::FoldingSet FunctionInfos; + public: class BitFieldInfo { public: -- GitLab From 76a07f59d4351bb0f26ffb2f0e16b1396774fe73 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Feb 2009 00:08:45 +0000 Subject: [PATCH 659/682] Use the SubclassData field to hold ExtType, isTrunc, and MemIndexedMode information. This eliminates the need for the Flags field in MemSDNode, so this makes LoadSDNode and StoreSDNode smaller. Also, it makes FoldingSetNodeIDs for loads and stores two AddIntegers smaller. llvm-svn: 63577 --- llvm/include/llvm/CodeGen/SelectionDAGNodes.h | 48 ++++++----- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 85 +++++++++---------- 2 files changed, 67 insertions(+), 66 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h index 06e507ba653f..fafc78181853 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAGNodes.h +++ b/llvm/include/llvm/CodeGen/SelectionDAGNodes.h @@ -1596,10 +1596,6 @@ private: //! SVOffset - Memory location offset. Note that base is defined in MemSDNode int SVOffset; - /// Flags - the low bit indicates whether this is a volatile reference; - /// the remainder is a log2 encoding of the alignment in bytes. - unsigned Flags; - public: MemSDNode(unsigned Opc, SDVTList VTs, MVT MemoryVT, const Value *srcValue, int SVOff, @@ -1618,9 +1614,17 @@ public: unsigned alignment, bool isvolatile); /// Returns alignment and volatility of the memory access - unsigned getAlignment() const { return (1u << (Flags >> 1)) >> 1; } - bool isVolatile() const { return Flags & 1; } + unsigned getAlignment() const { return (1u << (SubclassData >> 6)) >> 1; } + bool isVolatile() const { return (SubclassData >> 5) & 1; } + /// getRawSubclassData - Return the SubclassData value, which contains an + /// encoding of the alignment and volatile information, as well as bits + /// used by subclasses. This function should only be used to compute a + /// FoldingSetNodeID value. + unsigned getRawSubclassData() const { + return SubclassData; + } + /// Returns the SrcValue and offset that describes the location of the access const Value *getSrcValue() const { return SrcValue; } int getSrcValueOffset() const { return SVOffset; } @@ -1637,10 +1641,6 @@ public: return getOperand(getOpcode() == ISD::STORE ? 2 : 1); } - /// getRawFlags - Represent the flags as a bunch of bits. - /// - unsigned getRawFlags() const { return Flags; } - // Methods to support isa and dyn_cast static bool classof(const MemSDNode *) { return true; } static bool classof(const SDNode *N) { @@ -2354,9 +2354,10 @@ public: SDVTList VTs, ISD::MemIndexedMode AM, MVT VT, const Value *SV, int SVO, unsigned Align, bool Vol) : MemSDNode(NodeTy, VTs, VT, SV, SVO, Align, Vol) { - SubclassData = AM; - InitOperands(Ops, Operands, numOperands); assert(Align != 0 && "Loads and stores should have non-zero aligment"); + SubclassData |= AM << 2; + assert(getAddressingMode() == AM && "MemIndexedMode encoding error!"); + InitOperands(Ops, Operands, numOperands); assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) && "Only indexed loads and stores have a non-undef offset operand"); } @@ -2364,9 +2365,10 @@ public: unsigned numOperands, SDVTList VTs, ISD::MemIndexedMode AM, MVT VT, const Value *SV, int SVO, unsigned Align, bool Vol) : MemSDNode(NodeTy, dl, VTs, VT, SV, SVO, Align, Vol) { - SubclassData = AM; - InitOperands(Ops, Operands, numOperands); assert(Align != 0 && "Loads and stores should have non-zero aligment"); + SubclassData |= AM << 2; + assert(getAddressingMode() == AM && "MemIndexedMode encoding error!"); + InitOperands(Ops, Operands, numOperands); assert((getOffset().getOpcode() == ISD::UNDEF || isIndexed()) && "Only indexed loads and stores have a non-undef offset operand"); } @@ -2378,7 +2380,7 @@ public: /// getAddressingMode - Return the addressing mode for this load or store: /// unindexed, pre-inc, pre-dec, post-inc, or post-dec. ISD::MemIndexedMode getAddressingMode() const { - return ISD::MemIndexedMode(SubclassData & 7); + return ISD::MemIndexedMode((SubclassData >> 2) & 7); } /// isIndexed - Return true if this is a pre/post inc/dec load/store. @@ -2404,21 +2406,23 @@ protected: const Value *SV, int O=0, unsigned Align=0, bool Vol=false) : LSBaseSDNode(ISD::LOAD, ChainPtrOff, 3, VTs, AM, LVT, SV, O, Align, Vol) { - SubclassData |= (unsigned short)ETy << 3; + SubclassData |= (unsigned short)ETy; + assert(getExtensionType() == ETy && "LoadExtType encoding error!"); } LoadSDNode(SDValue *ChainPtrOff, DebugLoc dl, SDVTList VTs, ISD::MemIndexedMode AM, ISD::LoadExtType ETy, MVT LVT, const Value *SV, int O=0, unsigned Align=0, bool Vol=false) : LSBaseSDNode(ISD::LOAD, dl, ChainPtrOff, 3, VTs, AM, LVT, SV, O, Align, Vol) { - SubclassData |= (unsigned short)ETy << 3; + SubclassData |= (unsigned short)ETy; + assert(getExtensionType() == ETy && "LoadExtType encoding error!"); } public: /// getExtensionType - Return whether this is a plain node, /// or one of the varieties of value-extending loads. ISD::LoadExtType getExtensionType() const { - return ISD::LoadExtType((SubclassData >> 3) & 3); + return ISD::LoadExtType(SubclassData & 3); } const SDValue &getBasePtr() const { return getOperand(1); } @@ -2440,21 +2444,23 @@ protected: const Value *SV, int O=0, unsigned Align=0, bool Vol=false) : LSBaseSDNode(ISD::STORE, ChainValuePtrOff, 4, VTs, AM, SVT, SV, O, Align, Vol) { - SubclassData |= (unsigned short)isTrunc << 3; + SubclassData |= (unsigned short)isTrunc; + assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!"); } StoreSDNode(SDValue *ChainValuePtrOff, DebugLoc dl, SDVTList VTs, ISD::MemIndexedMode AM, bool isTrunc, MVT SVT, const Value *SV, int O=0, unsigned Align=0, bool Vol=false) : LSBaseSDNode(ISD::STORE, dl, ChainValuePtrOff, 4, VTs, AM, SVT, SV, O, Align, Vol) { - SubclassData |= (unsigned short)isTrunc << 3; + SubclassData |= (unsigned short)isTrunc; + assert(isTruncatingStore() == isTrunc && "isTrunc encoding error!"); } public: /// isTruncatingStore - Return true if the op does a truncation before store. /// For integers this is the same as doing a TRUNCATE and storing the result. /// For floats, it is the same as doing an FP_ROUND and storing the result. - bool isTruncatingStore() const { return (SubclassData >> 3) & 1; } + bool isTruncatingStore() const { return SubclassData & 1; } const SDValue &getValue() const { return getOperand(1); } const SDValue &getBasePtr() const { return getOperand(2); } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 32f55439ec64..1d8e3afec27e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -429,18 +429,14 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) { } case ISD::LOAD: { const LoadSDNode *LD = cast(N); - ID.AddInteger(LD->getAddressingMode()); - ID.AddInteger(LD->getExtensionType()); ID.AddInteger(LD->getMemoryVT().getRawBits()); - ID.AddInteger(LD->getRawFlags()); + ID.AddInteger(LD->getRawSubclassData()); break; } case ISD::STORE: { const StoreSDNode *ST = cast(N); - ID.AddInteger(ST->getAddressingMode()); - ID.AddInteger(ST->isTruncatingStore()); ID.AddInteger(ST->getMemoryVT().getRawBits()); - ID.AddInteger(ST->getRawFlags()); + ID.AddInteger(ST->getRawSubclassData()); break; } case ISD::ATOMIC_CMP_SWAP: @@ -456,7 +452,8 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) { case ISD::ATOMIC_LOAD_UMIN: case ISD::ATOMIC_LOAD_UMAX: { const AtomicSDNode *AT = cast(N); - ID.AddInteger(AT->getRawFlags()); + ID.AddInteger(AT->getMemoryVT().getRawBits()); + ID.AddInteger(AT->getRawSubclassData()); break; } } // end switch (N->getOpcode()) @@ -476,11 +473,20 @@ static void AddNodeIDNode(FoldingSetNodeID &ID, const SDNode *N) { } /// encodeMemSDNodeFlags - Generic routine for computing a value for use in -/// the CSE map that carries both alignment and volatility information. +/// the CSE map that carries alignment, volatility, indexing mode, and +/// extension/truncation information. /// static inline unsigned -encodeMemSDNodeFlags(bool isVolatile, unsigned Alignment) { - return isVolatile | ((Log2_32(Alignment) + 1) << 1); +encodeMemSDNodeFlags(int ConvType, ISD::MemIndexedMode AM, + bool isVolatile, unsigned Alignment) { + assert((ConvType & 3) == ConvType && + "ConvType may not require more than 2 bits!"); + assert((AM & 7) == AM && + "AM may not require more than 3 bits!"); + return ConvType | + (AM << 2) | + (isVolatile << 5) | + ((Log2_32(Alignment) + 1) << 6); } //===----------------------------------------------------------------------===// @@ -853,7 +859,6 @@ SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) { } else { NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); } - return getNode(ISD::XOR, DL, VT, Val, NegOne); } @@ -3417,6 +3422,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT, SDVTList VTs = getVTList(VT, MVT::Other); FoldingSetNodeID ID; + ID.AddInteger(MemVT.getRawBits()); SDValue Ops[] = {Chain, Ptr, Cmp, Swp}; AddNodeIDNode(ID, Opcode, VTs, Ops, 4); void* IP = 0; @@ -3445,6 +3451,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDVTList VTs = getVTList(VT, MVT::Other); FoldingSetNodeID ID; + ID.AddInteger(MemVT.getRawBits()); SDValue Ops[] = {Chain, Ptr, Cmp, Swp}; AddNodeIDNode(ID, Opcode, VTs, Ops, 4); void* IP = 0; @@ -3483,6 +3490,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, MVT MemVT, SDVTList VTs = getVTList(VT, MVT::Other); FoldingSetNodeID ID; + ID.AddInteger(MemVT.getRawBits()); SDValue Ops[] = {Chain, Ptr, Val}; AddNodeIDNode(ID, Opcode, VTs, Ops, 3); void* IP = 0; @@ -3521,6 +3529,7 @@ SDValue SelectionDAG::getAtomic(unsigned Opcode, DebugLoc dl, MVT MemVT, SDVTList VTs = getVTList(VT, MVT::Other); FoldingSetNodeID ID; + ID.AddInteger(MemVT.getRawBits()); SDValue Ops[] = {Chain, Ptr, Val}; AddNodeIDNode(ID, Opcode, VTs, Ops, 3); void* IP = 0; @@ -3727,10 +3736,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, ISD::LoadExtType ExtType, SDValue Ops[] = { Chain, Ptr, Offset }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3); - ID.AddInteger(AM); - ID.AddInteger(ExtType); ID.AddInteger(EVT.getRawBits()); - ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment)); + ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, isVolatile, Alignment)); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -3778,10 +3785,8 @@ SelectionDAG::getLoad(ISD::MemIndexedMode AM, DebugLoc dl, SDValue Ops[] = { Chain, Ptr, Offset }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::LOAD, VTs, Ops, 3); - ID.AddInteger(AM); - ID.AddInteger(ExtType); ID.AddInteger(EVT.getRawBits()); - ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment)); + ID.AddInteger(encodeMemSDNodeFlags(ExtType, AM, isVolatile, Alignment)); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -3868,10 +3873,9 @@ SDValue SelectionDAG::getStore(SDValue Chain, SDValue Val, SDValue Ops[] = { Chain, Val, Ptr, Undef }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); - ID.AddInteger(ISD::UNINDEXED); - ID.AddInteger(false); ID.AddInteger(VT.getRawBits()); - ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment)); + ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, + isVolatile, Alignment)); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -3896,10 +3900,9 @@ SDValue SelectionDAG::getStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ops[] = { Chain, Val, Ptr, Undef }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); - ID.AddInteger(ISD::UNINDEXED); - ID.AddInteger(false); ID.AddInteger(VT.getRawBits()); - ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment)); + ID.AddInteger(encodeMemSDNodeFlags(false, ISD::UNINDEXED, + isVolatile, Alignment)); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -3932,10 +3935,9 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, SDValue Val, SDValue Ops[] = { Chain, Val, Ptr, Undef }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); - ID.AddInteger(ISD::UNINDEXED); - ID.AddInteger(1); ID.AddInteger(SVT.getRawBits()); - ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment)); + ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED, + isVolatile, Alignment)); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -3968,10 +3970,9 @@ SDValue SelectionDAG::getTruncStore(SDValue Chain, DebugLoc dl, SDValue Val, SDValue Ops[] = { Chain, Val, Ptr, Undef }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); - ID.AddInteger(ISD::UNINDEXED); - ID.AddInteger(1); ID.AddInteger(SVT.getRawBits()); - ID.AddInteger(encodeMemSDNodeFlags(isVolatile, Alignment)); + ID.AddInteger(encodeMemSDNodeFlags(true, ISD::UNINDEXED, + isVolatile, Alignment)); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -3993,10 +3994,8 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, SDValue Base, SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); - ID.AddInteger(AM); - ID.AddInteger(ST->isTruncatingStore()); ID.AddInteger(ST->getMemoryVT().getRawBits()); - ID.AddInteger(ST->getRawFlags()); + ID.AddInteger(ST->getRawSubclassData()); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -4020,10 +4019,8 @@ SelectionDAG::getIndexedStore(SDValue OrigStore, DebugLoc dl, SDValue Base, SDValue Ops[] = { ST->getChain(), ST->getValue(), Base, Offset }; FoldingSetNodeID ID; AddNodeIDNode(ID, ISD::STORE, VTs, Ops, 4); - ID.AddInteger(AM); - ID.AddInteger(ST->isTruncatingStore()); ID.AddInteger(ST->getMemoryVT().getRawBits()); - ID.AddInteger(ST->getRawFlags()); + ID.AddInteger(ST->getRawSubclassData()); void *IP = 0; if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) return SDValue(E, 0); @@ -5339,9 +5336,8 @@ GlobalAddressSDNode::GlobalAddressSDNode(bool isTarget, const GlobalValue *GA, MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, MVT memvt, const Value *srcValue, int SVO, unsigned alignment, bool vol) - : SDNode(Opc, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), - Flags(encodeMemSDNodeFlags(vol, alignment)) { - + : SDNode(Opc, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) { + SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment); assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); assert(getAlignment() == alignment && "Alignment representation error!"); assert(isVolatile() == vol && "Volatile representation error!"); @@ -5351,8 +5347,8 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, unsigned NumOps, MVT memvt, const Value *srcValue, int SVO, unsigned alignment, bool vol) : SDNode(Opc, VTs, Ops, NumOps), - MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), - Flags(vol | ((Log2_32(alignment) + 1) << 1)) { + MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) { + SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment); assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); assert(getAlignment() == alignment && "Alignment representation error!"); assert(isVolatile() == vol && "Volatile representation error!"); @@ -5361,9 +5357,8 @@ MemSDNode::MemSDNode(unsigned Opc, SDVTList VTs, const SDValue *Ops, MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, MVT memvt, const Value *srcValue, int SVO, unsigned alignment, bool vol) - : SDNode(Opc, dl, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), - Flags(encodeMemSDNodeFlags(vol, alignment)) { - + : SDNode(Opc, dl, VTs), MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) { + SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment); assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); assert(getAlignment() == alignment && "Alignment representation error!"); assert(isVolatile() == vol && "Volatile representation error!"); @@ -5374,8 +5369,8 @@ MemSDNode::MemSDNode(unsigned Opc, DebugLoc dl, SDVTList VTs, unsigned NumOps, MVT memvt, const Value *srcValue, int SVO, unsigned alignment, bool vol) : SDNode(Opc, dl, VTs, Ops, NumOps), - MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO), - Flags(vol | ((Log2_32(alignment) + 1) << 1)) { + MemoryVT(memvt), SrcValue(srcValue), SVOffset(SVO) { + SubclassData = encodeMemSDNodeFlags(0, ISD::UNINDEXED, vol, alignment); assert(isPowerOf2_32(alignment) && "Alignment is not a power of 2!"); assert(getAlignment() == alignment && "Alignment representation error!"); assert(isVolatile() == vol && "Volatile representation error!"); -- GitLab From c88a70d885cd6dbf6e8bcb4e719407662139dfab Mon Sep 17 00:00:00 2001 From: Fariborz Jahanian Date: Tue, 3 Feb 2009 00:09:52 +0000 Subject: [PATCH 660/682] objc2's ir-gen for nonfragile ivar access. llvm-svn: 63578 --- clang/lib/CodeGen/CGExpr.cpp | 13 ++++-- clang/lib/CodeGen/CGObjC.cpp | 11 ++++- clang/lib/CodeGen/CGObjCGNU.cpp | 2 + clang/lib/CodeGen/CGObjCMac.cpp | 65 ++++++++++++++++++++++++----- clang/lib/CodeGen/CGObjCRuntime.h | 1 + clang/lib/CodeGen/CodeGenFunction.h | 7 +++- 6 files changed, 83 insertions(+), 16 deletions(-) diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 2c16c1940b55..4f8bd46b5242 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -1020,7 +1020,8 @@ llvm::Value *CodeGenFunction::EmitIvarOffset(ObjCInterfaceDecl *Interface, Offset); } -LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue, +LValue CodeGenFunction::EmitLValueForIvar(QualType ObjectTy, + llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, unsigned CVRQualifiers) { @@ -1035,6 +1036,7 @@ LValue CodeGenFunction::EmitLValueForIvar(llvm::Value *BaseValue, CVRQualifiers, Index); } llvm::Value *V = CGM.getObjCRuntime().EmitObjCValueForIvar(*this, + ObjectTy, BaseValue, Ivar, Field, CVRQualifiers); LValue LV = LValue::MakeAddr(V, Ivar->getType().getCVRQualifiers()|CVRQualifiers); SetVarDeclObjCAttribute(getContext(), Ivar, Ivar->getType(), LV); @@ -1047,19 +1049,22 @@ LValue CodeGenFunction::EmitObjCIvarRefLValue(const ObjCIvarRefExpr *E) { llvm::Value *BaseValue = 0; const Expr *BaseExpr = E->getBase(); unsigned CVRQualifiers = 0; + QualType ObjectTy; if (E->isArrow()) { BaseValue = EmitScalarExpr(BaseExpr); const PointerType *PTy = cast(getContext().getCanonicalType(BaseExpr->getType())); - CVRQualifiers = PTy->getPointeeType().getCVRQualifiers(); + ObjectTy = PTy->getPointeeType(); + CVRQualifiers = ObjectTy.getCVRQualifiers(); } else { LValue BaseLV = EmitLValue(BaseExpr); // FIXME: this isn't right for bitfields. BaseValue = BaseLV.getAddress(); - CVRQualifiers = BaseExpr->getType().getCVRQualifiers(); + ObjectTy = BaseExpr->getType(); + CVRQualifiers = ObjectTy.getCVRQualifiers(); } - return EmitLValueForIvar(BaseValue, E->getDecl(), + return EmitLValueForIvar(ObjectTy, BaseValue, E->getDecl(), getContext().getFieldDecl(E), CVRQualifiers); } diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp index 9dc45efc6872..3ebee12f0df5 100644 --- a/clang/lib/CodeGen/CGObjC.cpp +++ b/clang/lib/CodeGen/CGObjC.cpp @@ -194,7 +194,8 @@ void CodeGenFunction::GenerateObjCGetter(ObjCImplementationDecl *IMP, } else { FieldDecl *Field = IMP->getClassInterface()->lookupFieldDeclForIvar(getContext(), Ivar); - LValue LV = EmitLValueForIvar(LoadObjCSelf(), Ivar, Field, 0); + LValue LV = EmitLValueForIvar(TypeOfSelfObject(), + LoadObjCSelf(), Ivar, Field, 0); if (hasAggregateLLVMType(Ivar->getType())) { EmitAggregateCopy(ReturnValue, LV.getAddress(), Ivar->getType()); } @@ -294,6 +295,14 @@ llvm::Value *CodeGenFunction::LoadObjCSelf() { return Builder.CreateLoad(LocalDeclMap[OMD->getSelfDecl()], "self"); } +QualType CodeGenFunction::TypeOfSelfObject() { + const ObjCMethodDecl *OMD = cast(CurFuncDecl); + ImplicitParamDecl *selfDecl = OMD->getSelfDecl(); + const PointerType *PTy = + cast(getContext().getCanonicalType(selfDecl->getType())); + return PTy->getPointeeType(); +} + RValue CodeGenFunction::EmitObjCPropertyGet(const Expr *Exp) { // FIXME: Split it into two separate routines. if (const ObjCPropertyRefExpr *E = dyn_cast(Exp)) { diff --git a/clang/lib/CodeGen/CGObjCGNU.cpp b/clang/lib/CodeGen/CGObjCGNU.cpp index 1ce28bf91d40..d3b57b0e9afa 100644 --- a/clang/lib/CodeGen/CGObjCGNU.cpp +++ b/clang/lib/CodeGen/CGObjCGNU.cpp @@ -141,6 +141,7 @@ public: virtual void EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, llvm::Value *src, llvm::Value *dest); virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, @@ -1037,6 +1038,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, } llvm::Value *CGObjCGNU::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp index a577bd03cb26..2b1d9fff0ba6 100644 --- a/clang/lib/CodeGen/CGObjCMac.cpp +++ b/clang/lib/CodeGen/CGObjCMac.cpp @@ -551,6 +551,7 @@ private: llvm::Value *src, llvm::Value *dest); virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, @@ -676,12 +677,11 @@ public: llvm::Value *src, llvm::Value *dest) { return; } virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, - unsigned CVRQualifiers) - { return 0; } - + unsigned CVRQualifiers); }; } // end anonymous namespace @@ -2114,6 +2114,7 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF, /// EmitObjCValueForIvar - Code Gen for ivar reference. /// llvm::Value *CGObjCMac::EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, @@ -3755,15 +3756,16 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.' + Ivar->getNameAsString()); - llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset); + llvm::Constant *Init = llvm::ConstantInt::get(ObjCTypes.LongTy, Offset); llvm::GlobalVariable *IvarOffsetGV = CGM.getModule().getGlobalVariable(ExternalName); if (IvarOffsetGV) { // ivar offset symbol already built due to user code referencing it. IvarOffsetGV->setAlignment( - CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.Int8PtrTy)); + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy)); IvarOffsetGV->setInitializer(Init); + IvarOffsetGV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(IvarOffsetGV); return IvarOffsetGV; } @@ -3776,7 +3778,7 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( ExternalName, &CGM.getModule()); IvarOffsetGV->setAlignment( - CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.Int8PtrTy)); + CGM.getTargetData().getPrefTypeAlignment(ObjCTypes.LongTy)); // @private and @package have hidden visibility. bool globalVisibility = (Ivar->getAccessControl() == ObjCIvarDecl::Public || Ivar->getAccessControl() == ObjCIvarDecl::Protected); @@ -3789,10 +3791,7 @@ llvm::Constant * CGObjCNonFragileABIMac::EmitIvarOffsetVar( IvarOffsetGV->setSection("__DATA, __objc_const"); UsedGlobals.push_back(IvarOffsetGV); - - return llvm::ConstantExpr::getBitCast( - IvarOffsetGV, - llvm::PointerType::getUnqual(ObjCTypes.LongTy)); + return IvarOffsetGV; } /// EmitIvarList - Emit the ivar list for the given @@ -4094,6 +4093,52 @@ CGObjCNonFragileABIMac::GetMethodDescriptionConstant(const ObjCMethodDecl *MD) { Desc[2] = llvm::Constant::getNullValue(ObjCTypes.Int8PtrTy); return llvm::ConstantStruct::get(ObjCTypes.MethodTy, Desc); } + +/// EmitObjCValueForIvar - Code Gen for nonfragile ivar reference. +/// This code gen. amounts to generating code for: +/// @code +/// (type *)((char *)base + _OBJC_IVAR_$_.ivar; +/// @encode +/// +llvm::Value *CGObjCNonFragileABIMac::EmitObjCValueForIvar( + CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, + llvm::Value *BaseValue, + const ObjCIvarDecl *Ivar, + const FieldDecl *Field, + unsigned CVRQualifiers) { + assert(ObjectTy->isObjCInterfaceType() && + "CGObjCNonFragileABIMac::EmitObjCValueForIvar"); + NamedDecl *ID = ObjectTy->getAsObjCInterfaceType()->getDecl(); + // NOTE. This name must match one in EmitIvarOffsetVar. + // FIXME. Consolidate into one naming routine. + std::string ExternalName("\01_OBJC_IVAR_$_" + ID->getNameAsString() + '.' + + Ivar->getNameAsString()); + + llvm::GlobalVariable *IvarOffsetGV = + CGM.getModule().getGlobalVariable(ExternalName); + if (!IvarOffsetGV) + IvarOffsetGV = + new llvm::GlobalVariable(ObjCTypes.LongTy, + false, + llvm::GlobalValue::ExternalLinkage, + 0, + ExternalName, + &CGM.getModule()); + // (char *) BaseValue + llvm::Value *V = CGF.Builder.CreateBitCast(BaseValue, + ObjCTypes.Int8PtrTy); + llvm::Value *Offset = CGF.Builder.CreateLoad(IvarOffsetGV); + // (char*)BaseValue + Offset_symbol + V = CGF.Builder.CreateGEP(V, Offset, "add.ptr"); + // (type *)((char*)BaseValue + Offset_symbol) + const llvm::Type *IvarTy = + CGM.getTypes().ConvertType(Ivar->getType()); + llvm::Type *ptrIvarTy = llvm::PointerType::getUnqual(IvarTy); + V = CGF.Builder.CreateBitCast(V, ptrIvarTy); + return V; +} + /* *** */ CodeGen::CGObjCRuntime * diff --git a/clang/lib/CodeGen/CGObjCRuntime.h b/clang/lib/CodeGen/CGObjCRuntime.h index ded1db2c0b13..ade77af1561b 100644 --- a/clang/lib/CodeGen/CGObjCRuntime.h +++ b/clang/lib/CodeGen/CGObjCRuntime.h @@ -158,6 +158,7 @@ public: llvm::Value *src, llvm::Value *dest) = 0; virtual llvm::Value *EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF, + QualType ObjectTy, llvm::Value *BaseValue, const ObjCIvarDecl *Ivar, const FieldDecl *Field, diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h index 9033a65be26b..75353a7d9836 100644 --- a/clang/lib/CodeGen/CodeGenFunction.h +++ b/clang/lib/CodeGen/CodeGenFunction.h @@ -233,6 +233,10 @@ public: /// LoadObjCSelf - Load the value of self. This function is only /// valid while generating code for an Objective-C method. llvm::Value *LoadObjCSelf(); + + /// TypeOfSelfObject + /// Return type of object that this self represents. + QualType TypeOfSelfObject(); /// isObjCPointerType - Return true if the specificed AST type will map onto /// some Objective-C pointer type. @@ -521,7 +525,8 @@ public: const ObjCIvarDecl *Ivar); LValue EmitLValueForField(llvm::Value* Base, FieldDecl* Field, bool isUnion, unsigned CVRQualifiers); - LValue EmitLValueForIvar(llvm::Value* Base, const ObjCIvarDecl *Ivar, + LValue EmitLValueForIvar(QualType ObjectTy, + llvm::Value* Base, const ObjCIvarDecl *Ivar, const FieldDecl *Field, unsigned CVRQualifiers); -- GitLab From 7948ef5f87f3c0cd4f40d5f96510dfc34e4596c6 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Feb 2009 00:20:22 +0000 Subject: [PATCH 661/682] Add explicit -march=x86 to these tests so that they don't default to -march=x86-64 on 64-bit hosts. llvm-svn: 63579 --- llvm/test/CodeGen/X86/bt.ll | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/CodeGen/X86/bt.ll b/llvm/test/CodeGen/X86/bt.ll index f91130dd69a8..a76242c977ce 100644 --- a/llvm/test/CodeGen/X86/bt.ll +++ b/llvm/test/CodeGen/X86/bt.ll @@ -1,6 +1,6 @@ ; RUN: llvm-as < %s | llc -march=x86 | grep btl | count 28 -; RUN: llvm-as < %s | llc -mcpu=pentium4 | grep btl | not grep esp -; RUN: llvm-as < %s | llc -mcpu=penryn | grep btl | not grep esp +; RUN: llvm-as < %s | llc -march=x86 -mcpu=pentium4 | grep btl | not grep esp +; RUN: llvm-as < %s | llc -march=x86 -mcpu=penryn | grep btl | not grep esp ; PR3253 ; The register+memory form of the BT instruction should be usable on -- GitLab From 423f3bc196a79c0c5ba3c5fa543924194e00cd81 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 00:27:09 +0000 Subject: [PATCH 662/682] This is passing for us. Should it have been reenabled? llvm-svn: 63580 --- llvm/test/FrontendC/2009-01-25-NoSSE.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/llvm/test/FrontendC/2009-01-25-NoSSE.c b/llvm/test/FrontendC/2009-01-25-NoSSE.c index 92612cd4587b..a577c8d31def 100644 --- a/llvm/test/FrontendC/2009-01-25-NoSSE.c +++ b/llvm/test/FrontendC/2009-01-25-NoSSE.c @@ -2,8 +2,7 @@ // PR3402 // This is a test for x86/x86-64, add your target below if it FAILs. // XFAIL: alpha|ia64|arm|powerpc|sparc -// reverted -// XFAIL: * + typedef unsigned long __kernel_size_t; typedef __kernel_size_t size_t; void *memset(void *s, int c, size_t n); -- GitLab From 8761da5f68c6d35434458f52ffe255a9bb5d0c4e Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Tue, 3 Feb 2009 00:34:39 +0000 Subject: [PATCH 663/682] Simplify the way in which we inject the names of tag definitions and elaborated-type-specifier declarations into outer scopes while retaining their proper lexical scope. This way is simpler and more consistent with the way DeclContexts work, and also fixes http://llvm.org/bugs/show_bug.cgi?id=3430 llvm-svn: 63581 --- clang/lib/Sema/SemaDecl.cpp | 33 ++++++++++++++------------------- clang/test/Sema/struct-decl.c | 15 ++++++++++++++- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index d2140b226757..d7c5fa686072 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -839,6 +839,11 @@ Sema::DeclTy *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS, } } else if ((*Mem)->isImplicit()) { // Any implicit members are fine. + } else if (isa(*Mem) && (*Mem)->getDeclContext() != Record) { + // This is a type that showed up in an + // elaborated-type-specifier inside the anonymous struct or + // union, but which actually declares a type outside of the + // anonymous struct or union. It's okay. } else if (RecordDecl *MemRecord = dyn_cast(*Mem)) { if (!MemRecord->isAnonymousStructOrUnion() && MemRecord->getDeclName()) { @@ -2791,7 +2796,6 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, DeclContext *SearchDC = CurContext; DeclContext *DC = CurContext; - DeclContext *LexicalContext = CurContext; Decl *PrevDecl = 0; bool Invalid = false; @@ -2806,6 +2810,7 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, } DC = static_cast(SS.getScopeRep()); + SearchDC = DC; // Look-up name inside 'foo::'. PrevDecl = dyn_cast_or_null( LookupQualifiedName(DC, Name, LookupTagName).getAsDecl()); @@ -2944,9 +2949,8 @@ Sema::DeclTy *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagKind TK, // Find the context where we'll be declaring the tag. // FIXME: We would like to maintain the current DeclContext as the // lexical context, - while (DC->isRecord()) - DC = DC->getParent(); - LexicalContext = DC; + while (SearchDC->isRecord()) + SearchDC = SearchDC->getParent(); // Find the scope where we'll be declaring the tag. while (S->isClassScope() || @@ -2972,7 +2976,7 @@ CreateNewDecl: if (Kind == TagDecl::TK_enum) { // FIXME: Tag decls should be chained to any simultaneous vardecls, e.g.: // enum X { A, B, C } D; D should chain to X. - New = EnumDecl::Create(Context, DC, Loc, Name, + New = EnumDecl::Create(Context, SearchDC, Loc, Name, cast_or_null(PrevDecl)); // If this is an undefined enum, warn. if (TK != TK_Definition) Diag(Loc, diag::ext_forward_ref_enum); @@ -2983,10 +2987,10 @@ CreateNewDecl: // struct X { int A; } D; D should chain to X. if (getLangOptions().CPlusPlus) // FIXME: Look for a way to use RecordDecl for simple structs. - New = CXXRecordDecl::Create(Context, Kind, DC, Loc, Name, + New = CXXRecordDecl::Create(Context, Kind, SearchDC, Loc, Name, cast_or_null(PrevDecl)); else - New = RecordDecl::Create(Context, Kind, DC, Loc, Name, + New = RecordDecl::Create(Context, Kind, SearchDC, Loc, Name, cast_or_null(PrevDecl)); } @@ -3041,7 +3045,7 @@ CreateNewDecl: // Set the lexical context. If the tag has a C++ scope specifier, the // lexical context will be different from the semantic context. - New->setLexicalDeclContext(LexicalContext); + New->setLexicalDeclContext(CurContext); if (TK == TK_Definition) New->startDefinition(); @@ -3049,18 +3053,9 @@ CreateNewDecl: // If this has an identifier, add it to the scope stack. if (Name) { S = getNonFieldDeclScope(S); - - // Add it to the decl chain. - if (LexicalContext != CurContext) { - // FIXME: PushOnScopeChains should not rely on CurContext! - DeclContext *OldContext = CurContext; - CurContext = LexicalContext; - PushOnScopeChains(New, S); - CurContext = OldContext; - } else - PushOnScopeChains(New, S); + PushOnScopeChains(New, S); } else { - LexicalContext->addDecl(New); + CurContext->addDecl(New); } return New; diff --git a/clang/test/Sema/struct-decl.c b/clang/test/Sema/struct-decl.c index 7d7961b16c83..ec006b484f0a 100644 --- a/clang/test/Sema/struct-decl.c +++ b/clang/test/Sema/struct-decl.c @@ -1,5 +1,4 @@ // RUN: clang -fsyntax-only -verify %s - // PR3459 struct bar { char n[1]; @@ -9,3 +8,17 @@ struct foo { char name[(int)&((struct bar *)0)->n]; char name2[(int)&((struct bar *)0)->n - 1]; //expected-error{{fields must have a constant size}} }; + +// PR3430 +struct s { + struct st { + int v; + } *ts; +}; + +struct st; + +int foo() { + struct st *f; + return f->v + f[0].v; +} -- GitLab From b0ad6f9a6cbe044d7747e1dc01982081ff4e435b Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 00:35:11 +0000 Subject: [PATCH 664/682] It fails on Linux. XFAIL that machine. llvm-svn: 63582 --- llvm/test/FrontendC/2009-01-25-NoSSE.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/llvm/test/FrontendC/2009-01-25-NoSSE.c b/llvm/test/FrontendC/2009-01-25-NoSSE.c index a577c8d31def..c1af5c3f94d1 100644 --- a/llvm/test/FrontendC/2009-01-25-NoSSE.c +++ b/llvm/test/FrontendC/2009-01-25-NoSSE.c @@ -1,8 +1,8 @@ // RUN: $llvmgcc -m64 -O1 -march=core2 -mno-sse %s -S -o - | not grep xmm // PR3402 // This is a test for x86/x86-64, add your target below if it FAILs. -// XFAIL: alpha|ia64|arm|powerpc|sparc - +// FIXME: Revert "linux" when fixed. +// XFAIL: alpha|ia64|arm|powerpc|sparc|linux typedef unsigned long __kernel_size_t; typedef __kernel_size_t size_t; void *memset(void *s, int c, size_t n); -- GitLab From f1163e9a4db9ea6c41b6795821eae69de706fd60 Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 3 Feb 2009 00:47:48 +0000 Subject: [PATCH 665/682] Propagation in TargetLowering. Includes passing a DL into SimplifySetCC which gets called elsewhere. llvm-svn: 63583 --- llvm/include/llvm/CodeGen/SelectionDAG.h | 2 +- llvm/include/llvm/Target/TargetLowering.h | 2 +- llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 16 +- llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp | 6 +- .../SelectionDAG/LegalizeIntegerTypes.cpp | 7 +- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 22 +- .../CodeGen/SelectionDAG/TargetLowering.cpp | 194 ++++++++++-------- 7 files changed, 134 insertions(+), 115 deletions(-) diff --git a/llvm/include/llvm/CodeGen/SelectionDAG.h b/llvm/include/llvm/CodeGen/SelectionDAG.h index d6039120f931..5f226e83d5c7 100644 --- a/llvm/include/llvm/CodeGen/SelectionDAG.h +++ b/llvm/include/llvm/CodeGen/SelectionDAG.h @@ -904,7 +904,7 @@ public: /// FoldSetCC - Constant fold a setcc to true or false. SDValue FoldSetCC(MVT VT, SDValue N1, - SDValue N2, ISD::CondCode Cond); + SDValue N2, ISD::CondCode Cond, DebugLoc dl); /// SignBitIsZero - Return true if the sign bit of Op is known to be zero. We /// use this predicate to simplify operations downstream. diff --git a/llvm/include/llvm/Target/TargetLowering.h b/llvm/include/llvm/Target/TargetLowering.h index 5005df3c7997..6639db1e00ed 100644 --- a/llvm/include/llvm/Target/TargetLowering.h +++ b/llvm/include/llvm/Target/TargetLowering.h @@ -789,7 +789,7 @@ public: /// and cc. If it is unable to simplify it, return a null SDValue. SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, bool foldBooleans, - DAGCombinerInfo &DCI) const; + DAGCombinerInfo &DCI, DebugLoc dl) const; /// isGAPlusOffset - Returns true (and the GlobalValue and the offset) if the /// node is a GlobalAddress + offset. diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp index 7d18a864ab76..ebe471083e82 100644 --- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp @@ -207,7 +207,7 @@ namespace { SDValue N3, ISD::CondCode CC, bool NotExtCompare = false); SDValue SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, - bool foldBooleans = true); + DebugLoc DL, bool foldBooleans = true); SDValue SimplifyNodeWithTwoResults(SDNode *N, unsigned LoOp, unsigned HiOp); SDValue CombineConsecutiveLoads(SDNode *N, MVT VT); @@ -2911,7 +2911,7 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) { // Determine if the condition we're dealing with is constant SDValue SCC = SimplifySetCC(TLI.getSetCCResultType(N0.getValueType()), - N0, N1, CC, false); + N0, N1, CC, N->getDebugLoc(), false); if (SCC.getNode()) AddToWorkList(SCC.getNode()); if (ConstantSDNode *SCCC = dyn_cast_or_null(SCC.getNode())) { @@ -2937,7 +2937,8 @@ SDValue DAGCombiner::visitSELECT_CC(SDNode *N) { SDValue DAGCombiner::visitSETCC(SDNode *N) { return SimplifySetCC(N->getValueType(0), N->getOperand(0), N->getOperand(1), - cast(N->getOperand(2))->get()); + cast(N->getOperand(2))->get(), + N->getDebugLoc()); } // ExtendUsesToFormExtLoad - Trying to extend uses of a load to enable this: @@ -4434,7 +4435,8 @@ SDValue DAGCombiner::visitBR_CC(SDNode *N) { // Use SimplifySetCC to simplify SETCC's. SDValue Simp = SimplifySetCC(TLI.getSetCCResultType(CondLHS.getValueType()), - CondLHS, CondRHS, CC->get(), false); + CondLHS, CondRHS, CC->get(), N->getDebugLoc(), + false); if (Simp.getNode()) AddToWorkList(Simp.getNode()); ConstantSDNode *SCCC = dyn_cast_or_null(Simp.getNode()); @@ -5686,7 +5688,7 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, // Determine if the condition we're dealing with is constant SDValue SCC = SimplifySetCC(TLI.getSetCCResultType(N0.getValueType()), - N0, N1, CC, false); + N0, N1, CC, DL, false); if (SCC.getNode()) AddToWorkList(SCC.getNode()); ConstantSDNode *SCCC = dyn_cast_or_null(SCC.getNode()); @@ -5880,10 +5882,10 @@ SDValue DAGCombiner::SimplifySelectCC(DebugLoc DL, SDValue N0, SDValue N1, /// SimplifySetCC - This is a stub for TargetLowering::SimplifySetCC. SDValue DAGCombiner::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, - bool foldBooleans) { + DebugLoc DL, bool foldBooleans) { TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, Level == Unrestricted, false, this); - return TLI.SimplifySetCC(VT, N0, N1, Cond, foldBooleans, DagCombineInfo); + return TLI.SimplifySetCC(VT, N0, N1, Cond, foldBooleans, DagCombineInfo, DL); } /// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp index f88831e83812..b7ace2ed43da 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeDAG.cpp @@ -5315,12 +5315,12 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, // this identity: (B1 ? B2 : B3) --> (B1 & B2)|(!B1&B3) TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL); Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()), - LHSLo, RHSLo, LowCC, false, DagCombineInfo); + LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl); if (!Tmp1.getNode()) Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, LowCC); Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), - LHSHi, RHSHi, CCCode, false, DagCombineInfo); + LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl); if (!Tmp2.getNode()) Tmp2 = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(LHSHi.getValueType()), @@ -5343,7 +5343,7 @@ void SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, } else { Result = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETEQ, false, - DagCombineInfo); + DagCombineInfo, dl); if (!Result.getNode()) Result=DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETEQ); diff --git a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp index f803cb5a64dc..f502a947ce7b 100644 --- a/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/LegalizeIntegerTypes.cpp @@ -2034,12 +2034,12 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, TargetLowering::DAGCombinerInfo DagCombineInfo(DAG, false, true, NULL); SDValue Tmp1, Tmp2; Tmp1 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSLo.getValueType()), - LHSLo, RHSLo, LowCC, false, DagCombineInfo); + LHSLo, RHSLo, LowCC, false, DagCombineInfo, dl); if (!Tmp1.getNode()) Tmp1 = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSLo.getValueType()), LHSLo, RHSLo, LowCC); Tmp2 = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), - LHSHi, RHSHi, CCCode, false, DagCombineInfo); + LHSHi, RHSHi, CCCode, false, DagCombineInfo, dl); if (!Tmp2.getNode()) Tmp2 = DAG.getNode(ISD::SETCC, dl, TLI.getSetCCResultType(LHSHi.getValueType()), @@ -2063,7 +2063,8 @@ void DAGTypeLegalizer::IntegerExpandSetCCOperands(SDValue &NewLHS, } NewLHS = TLI.SimplifySetCC(TLI.getSetCCResultType(LHSHi.getValueType()), - LHSHi, RHSHi, ISD::SETEQ, false, DagCombineInfo); + LHSHi, RHSHi, ISD::SETEQ, false, + DagCombineInfo, dl); if (!NewLHS.getNode()) NewLHS = DAG.getSetCC(dl, TLI.getSetCCResultType(LHSHi.getValueType()), LHSHi, RHSHi, ISD::SETEQ); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 1d8e3afec27e..68dda9949158 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -1334,7 +1334,7 @@ SDValue SelectionDAG::CreateStackTemporary(MVT VT1, MVT VT2) { } SDValue SelectionDAG::FoldSetCC(MVT VT, SDValue N1, - SDValue N2, ISD::CondCode Cond) { + SDValue N2, ISD::CondCode Cond, DebugLoc dl) { // These setcc operations always fold. switch (Cond) { default: break; @@ -1387,29 +1387,29 @@ SDValue SelectionDAG::FoldSetCC(MVT VT, SDValue N1, switch (Cond) { default: break; case ISD::SETEQ: if (R==APFloat::cmpUnordered) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, dl, VT); // fall through case ISD::SETOEQ: return getConstant(R==APFloat::cmpEqual, VT); case ISD::SETNE: if (R==APFloat::cmpUnordered) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, dl, VT); // fall through case ISD::SETONE: return getConstant(R==APFloat::cmpGreaterThan || R==APFloat::cmpLessThan, VT); case ISD::SETLT: if (R==APFloat::cmpUnordered) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, dl, VT); // fall through case ISD::SETOLT: return getConstant(R==APFloat::cmpLessThan, VT); case ISD::SETGT: if (R==APFloat::cmpUnordered) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, dl, VT); // fall through case ISD::SETOGT: return getConstant(R==APFloat::cmpGreaterThan, VT); case ISD::SETLE: if (R==APFloat::cmpUnordered) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, dl, VT); // fall through case ISD::SETOLE: return getConstant(R==APFloat::cmpLessThan || R==APFloat::cmpEqual, VT); case ISD::SETGE: if (R==APFloat::cmpUnordered) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, dl, VT); // fall through case ISD::SETOGE: return getConstant(R==APFloat::cmpGreaterThan || R==APFloat::cmpEqual, VT); @@ -1427,7 +1427,7 @@ SDValue SelectionDAG::FoldSetCC(MVT VT, SDValue N1, } } else { // Ensure that the constant occurs on the RHS. - return getSetCC(VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); + return getSetCC(dl, VT, N2, N1, ISD::getSetCCSwappedOperands(Cond)); } } @@ -2832,12 +2832,12 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, SmallVector Elts(N1.getNode()->op_begin(), N1.getNode()->op_end()); Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end()); Elts.insert(Elts.end(), N3.getNode()->op_begin(), N3.getNode()->op_end()); - return getNode(ISD::BUILD_VECTOR, VT, &Elts[0], Elts.size()); + return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size()); } break; case ISD::SETCC: { // Use FoldSetCC to simplify SETCC's. - SDValue Simp = FoldSetCC(VT, N1, N2, cast(N3)->get()); + SDValue Simp = FoldSetCC(VT, N1, N2, cast(N3)->get(), DL); if (Simp.getNode()) return Simp; break; } @@ -2854,7 +2854,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, case ISD::BRCOND: if (N2C) { if (N2C->getZExtValue()) // Unconditional branch - return getNode(ISD::BR, MVT::Other, N1, N3); + return getNode(ISD::BR, DL, MVT::Other, N1, N3); else return N1; // Never-taken branch } diff --git a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp index 7d524753cd4c..0f7db6e5393e 100644 --- a/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp @@ -760,6 +760,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, assert(Op.getValueSizeInBits() == BitWidth && "Mask size mismatches value type size!"); APInt NewMask = DemandedMask; + DebugLoc dl = Op.getNode()->getDebugLoc(); // Don't know anything. KnownZero = KnownOne = APInt(BitWidth, 0); @@ -778,7 +779,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, } else if (DemandedMask == 0) { // Not demanding any bits from Op. if (Op.getOpcode() != ISD::UNDEF) - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::UNDEF, Op.getValueType())); + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::UNDEF, dl, + Op.getValueType())); return false; } else if (Depth == 6) { // Limit search depth. return false; @@ -905,8 +907,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, if ((KnownOne & KnownOne2) == KnownOne) { MVT VT = Op.getValueType(); SDValue ANDC = TLO.DAG.getConstant(~KnownOne & NewMask, VT); - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, VT, Op.getOperand(0), - ANDC)); + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::AND, dl, VT, + Op.getOperand(0), ANDC)); } } @@ -919,7 +921,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, if (Expanded.isAllOnesValue()) { if (Expanded != C->getAPIntValue()) { MVT VT = Op.getValueType(); - SDValue New = TLO.DAG.getNode(Op.getOpcode(), VT, Op.getOperand(0), + SDValue New = TLO.DAG.getNode(Op.getOpcode(), dl,VT, Op.getOperand(0), TLO.DAG.getConstant(Expanded, VT)); return TLO.CombineTo(Op, New); } @@ -995,7 +997,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, SDValue NewSA = TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType()); MVT VT = Op.getValueType(); - return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT, + return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT, InOp.getOperand(0), NewSA)); } } @@ -1036,7 +1038,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, SDValue NewSA = TLO.DAG.getConstant(Diff, Op.getOperand(1).getValueType()); - return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, VT, + return TLO.CombineTo(Op, TLO.DAG.getNode(Opc, dl, VT, InOp.getOperand(0), NewSA)); } } @@ -1059,7 +1061,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // variable. The low bit of the shift cannot be an input sign bit unless // the shift amount is >= the size of the datatype, which is undefined. if (DemandedMask == 1) - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, Op.getValueType(), + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, Op.getValueType(), Op.getOperand(0), Op.getOperand(1))); if (ConstantSDNode *SA = dyn_cast(Op.getOperand(1))) { @@ -1091,7 +1093,8 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // If the input sign bit is known to be zero, or if none of the top bits // are demanded, turn this into an unsigned shift right. if (KnownZero.intersects(SignBit) || (HighBits & ~NewMask) == HighBits) { - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, VT, Op.getOperand(0), + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, VT, + Op.getOperand(0), Op.getOperand(1))); } else if (KnownOne.intersects(SignBit)) { // New bits are known one. KnownOne |= HighBits; @@ -1132,7 +1135,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // If the input sign bit is known zero, convert this into a zero extension. if (KnownZero.intersects(InSignBit)) return TLO.CombineTo(Op, - TLO.DAG.getZeroExtendInReg(Op.getOperand(0), EVT)); + TLO.DAG.getZeroExtendInReg(Op.getOperand(0),dl,EVT)); if (KnownOne.intersects(InSignBit)) { // Input sign bit known set KnownOne |= NewBits; @@ -1152,7 +1155,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, APInt NewBits = APInt::getHighBitsSet(BitWidth, BitWidth - OperandBitWidth) & NewMask; if (!NewBits.intersects(NewMask)) - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ANY_EXTEND, dl, Op.getValueType(), Op.getOperand(0))); @@ -1174,8 +1177,9 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // If none of the top bits are demanded, convert this into an any_extend. if (NewBits == 0) - return TLO.CombineTo(Op,TLO.DAG.getNode(ISD::ANY_EXTEND,Op.getValueType(), - Op.getOperand(0))); + return TLO.CombineTo(Op,TLO.DAG.getNode(ISD::ANY_EXTEND, dl, + Op.getValueType(), + Op.getOperand(0))); // Since some of the sign extended bits are demanded, we know that the sign // bit is demanded. @@ -1191,7 +1195,7 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, // If the sign bit is known zero, convert this to a zero extend. if (KnownZero.intersects(InSignBit)) - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::ZERO_EXTEND, dl, Op.getValueType(), Op.getOperand(0))); @@ -1247,11 +1251,13 @@ bool TargetLowering::SimplifyDemandedBits(SDValue Op, if (ShAmt->getZExtValue() < BitWidth && !(HighBits & NewMask)) { // None of the shifted in bits are needed. Add a truncate of the // shift input, then shift it. - SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, + SDValue NewTrunc = TLO.DAG.getNode(ISD::TRUNCATE, dl, Op.getValueType(), In.getOperand(0)); - return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL,Op.getValueType(), - NewTrunc, In.getOperand(1))); + return TLO.CombineTo(Op, TLO.DAG.getNode(ISD::SRL, dl, + Op.getValueType(), + NewTrunc, + In.getOperand(1))); } } break; @@ -1361,7 +1367,7 @@ static bool ValueHasAtMostOneBitSet(SDValue Val, const SelectionDAG &DAG) { SDValue TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode Cond, bool foldBooleans, - DAGCombinerInfo &DCI) const { + DAGCombinerInfo &DCI, DebugLoc dl) const { SelectionDAG &DAG = DCI.DAG; // These setcc operations always fold. @@ -1376,7 +1382,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (ConstantSDNode *N1C = dyn_cast(N1.getNode())) { const APInt &C1 = N1C->getAPIntValue(); if (isa(N0.getNode())) { - return DAG.FoldSetCC(VT, N0, N1, Cond); + return DAG.FoldSetCC(VT, N0, N1, Cond, dl); } else { // If the LHS is '(srl (ctlz x), 5)', the RHS is 0/1, and this is an // equality comparison, then we're just comparing whether X itself is @@ -1397,7 +1403,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, Cond = ISD::SETEQ; } SDValue Zero = DAG.getConstant(0, N0.getValueType()); - return DAG.getSetCC(VT, N0.getOperand(0).getOperand(0), + return DAG.getSetCC(dl, VT, N0.getOperand(0).getOperand(0), Zero, Cond); } } @@ -1442,16 +1448,17 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, MVT PtrType = Lod->getOperand(1).getValueType(); SDValue Ptr = Lod->getBasePtr(); if (bestOffset != 0) - Ptr = DAG.getNode(ISD::ADD, PtrType, Lod->getBasePtr(), + Ptr = DAG.getNode(ISD::ADD, dl, PtrType, Lod->getBasePtr(), DAG.getConstant(bestOffset, PtrType)); unsigned NewAlign = MinAlign(Lod->getAlignment(), bestOffset); - SDValue NewLoad = DAG.getLoad(newVT, Lod->getChain(), Ptr, + SDValue NewLoad = DAG.getLoad(newVT, dl, Lod->getChain(), Ptr, Lod->getSrcValue(), Lod->getSrcValueOffset() + bestOffset, false, NewAlign); - return DAG.getSetCC(VT, DAG.getNode(ISD::AND, newVT, NewLoad, + return DAG.getSetCC(dl, VT, + DAG.getNode(ISD::AND, dl, newVT, NewLoad, DAG.getConstant(bestMask, newVT)), - DAG.getConstant(0LL, newVT), Cond); + DAG.getConstant(0LL, newVT), Cond); } } } @@ -1492,7 +1499,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, case ISD::SETUGE: case ISD::SETULT: case ISD::SETULE: - return DAG.getSetCC(VT, N0.getOperand(0), + return DAG.getSetCC(dl, VT, N0.getOperand(0), DAG.getConstant(APInt(C1).trunc(InSize), N0.getOperand(0).getValueType()), Cond); @@ -1520,13 +1527,13 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ZextOp = N0.getOperand(0); } else { APInt Imm = APInt::getLowBitsSet(ExtDstTyBits, ExtSrcTyBits); - ZextOp = DAG.getNode(ISD::AND, Op0Ty, N0.getOperand(0), + ZextOp = DAG.getNode(ISD::AND, dl, Op0Ty, N0.getOperand(0), DAG.getConstant(Imm, Op0Ty)); } if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(ZextOp.getNode()); // Otherwise, make this a use of a zext. - return DAG.getSetCC(VT, ZextOp, + return DAG.getSetCC(dl, VT, ZextOp, DAG.getConstant(C1 & APInt::getLowBitsSet( ExtDstTyBits, ExtSrcTyBits), @@ -1545,7 +1552,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, ISD::CondCode CC = cast(N0.getOperand(2))->get(); CC = ISD::getSetCCInverse(CC, N0.getOperand(0).getValueType().isInteger()); - return DAG.getSetCC(VT, N0.getOperand(0), N0.getOperand(1), CC); + return DAG.getSetCC(dl, VT, N0.getOperand(0), N0.getOperand(1), CC); } if ((N0.getOpcode() == ISD::XOR || @@ -1568,11 +1575,11 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, assert(N0.getOpcode() == ISD::AND && N0.getOperand(0).getOpcode() == ISD::XOR); // ((X^1)&1)^1 -> X & 1 - Val = DAG.getNode(ISD::AND, N0.getValueType(), + Val = DAG.getNode(ISD::AND, dl, N0.getValueType(), N0.getOperand(0).getOperand(0), N0.getOperand(1)); } - return DAG.getSetCC(VT, Val, N1, + return DAG.getSetCC(dl, VT, Val, N1, Cond == ISD::SETEQ ? ISD::SETNE : ISD::SETEQ); } } @@ -1592,15 +1599,17 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (Cond == ISD::SETGE || Cond == ISD::SETUGE) { if (C1 == MinVal) return DAG.getConstant(1, VT); // X >= MIN --> true // X >= C0 --> X > (C0-1) - return DAG.getSetCC(VT, N0, DAG.getConstant(C1-1, N1.getValueType()), - (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT); + return DAG.getSetCC(dl, VT, N0, + DAG.getConstant(C1-1, N1.getValueType()), + (Cond == ISD::SETGE) ? ISD::SETGT : ISD::SETUGT); } if (Cond == ISD::SETLE || Cond == ISD::SETULE) { if (C1 == MaxVal) return DAG.getConstant(1, VT); // X <= MAX --> true // X <= C0 --> X < (C0+1) - return DAG.getSetCC(VT, N0, DAG.getConstant(C1+1, N1.getValueType()), - (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT); + return DAG.getSetCC(dl, VT, N0, + DAG.getConstant(C1+1, N1.getValueType()), + (Cond == ISD::SETLE) ? ISD::SETLT : ISD::SETULT); } if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal) @@ -1614,19 +1623,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // Canonicalize setgt X, Min --> setne X, Min if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MinVal) - return DAG.getSetCC(VT, N0, N1, ISD::SETNE); + return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE); // Canonicalize setlt X, Max --> setne X, Max if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MaxVal) - return DAG.getSetCC(VT, N0, N1, ISD::SETNE); + return DAG.getSetCC(dl, VT, N0, N1, ISD::SETNE); // If we have setult X, 1, turn it into seteq X, 0 if ((Cond == ISD::SETLT || Cond == ISD::SETULT) && C1 == MinVal+1) - return DAG.getSetCC(VT, N0, DAG.getConstant(MinVal, N0.getValueType()), - ISD::SETEQ); + return DAG.getSetCC(dl, VT, N0, + DAG.getConstant(MinVal, N0.getValueType()), + ISD::SETEQ); // If we have setugt X, Max-1, turn it into seteq X, Max else if ((Cond == ISD::SETGT || Cond == ISD::SETUGT) && C1 == MaxVal-1) - return DAG.getSetCC(VT, N0, DAG.getConstant(MaxVal, N0.getValueType()), - ISD::SETEQ); + return DAG.getSetCC(dl, VT, N0, + DAG.getConstant(MaxVal, N0.getValueType()), + ISD::SETEQ); // If we have "setcc X, C0", check to see if we can shrink the immediate // by changing cc. @@ -1634,7 +1645,8 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // SETUGT X, SINTMAX -> SETLT X, 0 if (Cond == ISD::SETUGT && C1 == APInt::getSignedMaxValue(OperandBitSize)) - return DAG.getSetCC(VT, N0, DAG.getConstant(0, N1.getValueType()), + return DAG.getSetCC(dl, VT, N0, + DAG.getConstant(0, N1.getValueType()), ISD::SETLT); // SETULT X, SINTMIN -> SETGT X, -1 @@ -1643,7 +1655,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, SDValue ConstMinusOne = DAG.getConstant(APInt::getAllOnesValue(OperandBitSize), N1.getValueType()); - return DAG.getSetCC(VT, N0, ConstMinusOne, ISD::SETGT); + return DAG.getSetCC(dl, VT, N0, ConstMinusOne, ISD::SETGT); } // Fold bit comparisons when we can. @@ -1656,7 +1668,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (Cond == ISD::SETNE && C1 == 0) {// (X & 8) != 0 --> (X & 8) >> 3 // Perform the xform if the AND RHS is a single bit. if (isPowerOf2_64(AndRHS->getZExtValue())) { - return DAG.getNode(ISD::SRL, VT, N0, + return DAG.getNode(ISD::SRL, dl, VT, N0, DAG.getConstant(Log2_64(AndRHS->getZExtValue()), ShiftTy)); } @@ -1664,7 +1676,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // (X & 8) == 8 --> (X & 8) >> 3 // Perform the xform if C1 is a single bit. if (C1.isPowerOf2()) { - return DAG.getNode(ISD::SRL, VT, N0, + return DAG.getNode(ISD::SRL, dl, VT, N0, DAG.getConstant(C1.logBase2(), ShiftTy)); } } @@ -1672,12 +1684,12 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, } } else if (isa(N0.getNode())) { // Ensure that the constant occurs on the RHS. - return DAG.getSetCC(VT, N1, N0, ISD::getSetCCSwappedOperands(Cond)); + return DAG.getSetCC(dl, VT, N1, N0, ISD::getSetCCSwappedOperands(Cond)); } if (isa(N0.getNode())) { // Constant fold or commute setcc. - SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond); + SDValue O = DAG.FoldSetCC(VT, N0, N1, Cond, dl); if (O.getNode()) return O; } else if (ConstantFPSDNode *CFP = dyn_cast(N1.getNode())) { // If the RHS of an FP comparison is a constant, simplify it away in @@ -1700,7 +1712,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // have SETO(x,x) instead of SETO(x, 0.0) because this avoids having to // materialize 0.0. if (Cond == ISD::SETO || Cond == ISD::SETUO) - return DAG.getSetCC(VT, N0, N0, Cond); + return DAG.getSetCC(dl, VT, N0, N0, Cond); } if (N0 == N1) { @@ -1716,7 +1728,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // if it is not already. ISD::CondCode NewCond = UOF == 0 ? ISD::SETO : ISD::SETUO; if (NewCond != Cond) - return DAG.getSetCC(VT, N0, N1, NewCond); + return DAG.getSetCC(dl, VT, N0, N1, NewCond); } if ((Cond == ISD::SETEQ || Cond == ISD::SETNE) && @@ -1726,15 +1738,17 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // Simplify (X+Y) == (X+Z) --> Y == Z if (N0.getOpcode() == N1.getOpcode()) { if (N0.getOperand(0) == N1.getOperand(0)) - return DAG.getSetCC(VT, N0.getOperand(1), N1.getOperand(1), Cond); + return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(1), Cond); if (N0.getOperand(1) == N1.getOperand(1)) - return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(0), Cond); + return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(0), Cond); if (DAG.isCommutativeBinOp(N0.getOpcode())) { // If X op Y == Y op X, try other combinations. if (N0.getOperand(0) == N1.getOperand(1)) - return DAG.getSetCC(VT, N0.getOperand(1), N1.getOperand(0), Cond); + return DAG.getSetCC(dl, VT, N0.getOperand(1), N1.getOperand(0), + Cond); if (N0.getOperand(1) == N1.getOperand(0)) - return DAG.getSetCC(VT, N0.getOperand(0), N1.getOperand(1), Cond); + return DAG.getSetCC(dl, VT, N0.getOperand(0), N1.getOperand(1), + Cond); } } @@ -1742,7 +1756,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (ConstantSDNode *LHSR = dyn_cast(N0.getOperand(1))) { // Turn (X+C1) == C2 --> X == C2-C1 if (N0.getOpcode() == ISD::ADD && N0.getNode()->hasOneUse()) { - return DAG.getSetCC(VT, N0.getOperand(0), + return DAG.getSetCC(dl, VT, N0.getOperand(0), DAG.getConstant(RHSC->getAPIntValue()- LHSR->getAPIntValue(), N0.getValueType()), Cond); @@ -1754,7 +1768,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // performing the inversion. if (DAG.MaskedValueIsZero(N0.getOperand(0), ~LHSR->getAPIntValue())) return - DAG.getSetCC(VT, N0.getOperand(0), + DAG.getSetCC(dl, VT, N0.getOperand(0), DAG.getConstant(LHSR->getAPIntValue() ^ RHSC->getAPIntValue(), N0.getValueType()), @@ -1765,7 +1779,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (ConstantSDNode *SUBC = dyn_cast(N0.getOperand(0))) { if (N0.getOpcode() == ISD::SUB && N0.getNode()->hasOneUse()) { return - DAG.getSetCC(VT, N0.getOperand(1), + DAG.getSetCC(dl, VT, N0.getOperand(1), DAG.getConstant(SUBC->getAPIntValue() - RHSC->getAPIntValue(), N0.getValueType()), @@ -1776,21 +1790,21 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, // Simplify (X+Z) == X --> Z == 0 if (N0.getOperand(0) == N1) - return DAG.getSetCC(VT, N0.getOperand(1), + return DAG.getSetCC(dl, VT, N0.getOperand(1), DAG.getConstant(0, N0.getValueType()), Cond); if (N0.getOperand(1) == N1) { if (DAG.isCommutativeBinOp(N0.getOpcode())) - return DAG.getSetCC(VT, N0.getOperand(0), + return DAG.getSetCC(dl, VT, N0.getOperand(0), DAG.getConstant(0, N0.getValueType()), Cond); else if (N0.getNode()->hasOneUse()) { assert(N0.getOpcode() == ISD::SUB && "Unexpected operation!"); // (Z-X) == X --> Z == X<<1 - SDValue SH = DAG.getNode(ISD::SHL, N1.getValueType(), + SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), N1, DAG.getConstant(1, getShiftAmountTy())); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(SH.getNode()); - return DAG.getSetCC(VT, N0.getOperand(0), SH, Cond); + return DAG.getSetCC(dl, VT, N0.getOperand(0), SH, Cond); } } } @@ -1799,20 +1813,20 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, N1.getOpcode() == ISD::XOR) { // Simplify X == (X+Z) --> Z == 0 if (N1.getOperand(0) == N0) { - return DAG.getSetCC(VT, N1.getOperand(1), + return DAG.getSetCC(dl, VT, N1.getOperand(1), DAG.getConstant(0, N1.getValueType()), Cond); } else if (N1.getOperand(1) == N0) { if (DAG.isCommutativeBinOp(N1.getOpcode())) { - return DAG.getSetCC(VT, N1.getOperand(0), + return DAG.getSetCC(dl, VT, N1.getOperand(0), DAG.getConstant(0, N1.getValueType()), Cond); } else if (N1.getNode()->hasOneUse()) { assert(N1.getOpcode() == ISD::SUB && "Unexpected operation!"); // X == (Z-X) --> X<<1 == Z - SDValue SH = DAG.getNode(ISD::SHL, N1.getValueType(), N0, + SDValue SH = DAG.getNode(ISD::SHL, dl, N1.getValueType(), N0, DAG.getConstant(1, getShiftAmountTy())); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(SH.getNode()); - return DAG.getSetCC(VT, SH, N1.getOperand(0), Cond); + return DAG.getSetCC(dl, VT, SH, N1.getOperand(0), Cond); } } } @@ -1823,7 +1837,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (ValueHasAtMostOneBitSet(N1, DAG)) { Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true); SDValue Zero = DAG.getConstant(0, N1.getValueType()); - return DAG.getSetCC(VT, N0, Zero, Cond); + return DAG.getSetCC(dl, VT, N0, Zero, Cond); } } if (N1.getOpcode() == ISD::AND) @@ -1831,7 +1845,7 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, if (ValueHasAtMostOneBitSet(N0, DAG)) { Cond = ISD::getSetCCInverse(Cond, /*isInteger=*/true); SDValue Zero = DAG.getConstant(0, N0.getValueType()); - return DAG.getSetCC(VT, N1, Zero, Cond); + return DAG.getSetCC(dl, VT, N1, Zero, Cond); } } } @@ -1842,46 +1856,46 @@ TargetLowering::SimplifySetCC(MVT VT, SDValue N0, SDValue N1, switch (Cond) { default: assert(0 && "Unknown integer setcc!"); case ISD::SETEQ: // X == Y -> ~(X^Y) - Temp = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); - N0 = DAG.getNOT(DebugLoc::getUnknownLoc(), Temp, MVT::i1); + Temp = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1); + N0 = DAG.getNOT(dl, Temp, MVT::i1); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETNE: // X != Y --> (X^Y) - N0 = DAG.getNode(ISD::XOR, MVT::i1, N0, N1); + N0 = DAG.getNode(ISD::XOR, dl, MVT::i1, N0, N1); break; case ISD::SETGT: // X >s Y --> X == 0 & Y == 1 --> ~X & Y case ISD::SETULT: // X X == 0 & Y == 1 --> ~X & Y - Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N0, MVT::i1); + Temp = DAG.getNOT(dl, N0, MVT::i1); N0 = DAG.getNode(ISD::AND, MVT::i1, N1, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETLT: // X X == 1 & Y == 0 --> ~Y & X case ISD::SETUGT: // X >u Y --> X == 1 & Y == 0 --> ~Y & X - Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N1, MVT::i1); - N0 = DAG.getNode(ISD::AND, MVT::i1, N0, Temp); + Temp = DAG.getNOT(dl, N1, MVT::i1); + N0 = DAG.getNode(ISD::AND, dl, MVT::i1, N0, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETULE: // X <=u Y --> X == 0 | Y == 1 --> ~X | Y case ISD::SETGE: // X >=s Y --> X == 0 | Y == 1 --> ~X | Y - Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N0, MVT::i1); - N0 = DAG.getNode(ISD::OR, MVT::i1, N1, Temp); + Temp = DAG.getNOT(dl, N0, MVT::i1); + N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N1, Temp); if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(Temp.getNode()); break; case ISD::SETUGE: // X >=u Y --> X == 1 | Y == 0 --> ~Y | X case ISD::SETLE: // X <=s Y --> X == 1 | Y == 0 --> ~Y | X - Temp = DAG.getNOT(DebugLoc::getUnknownLoc(), N1, MVT::i1); - N0 = DAG.getNode(ISD::OR, MVT::i1, N0, Temp); + Temp = DAG.getNOT(dl, N1, MVT::i1); + N0 = DAG.getNode(ISD::OR, dl, MVT::i1, N0, Temp); break; } if (VT != MVT::i1) { if (!DCI.isCalledByLegalizer()) DCI.AddToWorklist(N0.getNode()); // FIXME: If running after legalize, we probably can't do this. - N0 = DAG.getNode(ISD::ZERO_EXTEND, VT, N0); + N0 = DAG.getNode(ISD::ZERO_EXTEND, dl, VT, N0); } return N0; } @@ -2396,6 +2410,7 @@ static ms magic(const APInt& d) { SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, std::vector* Created) const { MVT VT = N->getValueType(0); + DebugLoc dl= N->getDebugLoc(); // Check to see if we can do this. // FIXME: We should be more aggressive here. @@ -2409,40 +2424,40 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, // FIXME: We should support doing a MUL in a wider type SDValue Q; if (isOperationLegalOrCustom(ISD::MULHS, VT)) - Q = DAG.getNode(ISD::MULHS, VT, N->getOperand(0), + Q = DAG.getNode(ISD::MULHS, dl, VT, N->getOperand(0), DAG.getConstant(magics.m, VT)); else if (isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) - Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, DAG.getVTList(VT, VT), + Q = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, DAG.getVTList(VT, VT), N->getOperand(0), DAG.getConstant(magics.m, VT)).getNode(), 1); else return SDValue(); // No mulhs or equvialent // If d > 0 and m < 0, add the numerator if (d.isStrictlyPositive() && magics.m.isNegative()) { - Q = DAG.getNode(ISD::ADD, VT, Q, N->getOperand(0)); + Q = DAG.getNode(ISD::ADD, dl, VT, Q, N->getOperand(0)); if (Created) Created->push_back(Q.getNode()); } // If d < 0 and m > 0, subtract the numerator. if (d.isNegative() && magics.m.isStrictlyPositive()) { - Q = DAG.getNode(ISD::SUB, VT, Q, N->getOperand(0)); + Q = DAG.getNode(ISD::SUB, dl, VT, Q, N->getOperand(0)); if (Created) Created->push_back(Q.getNode()); } // Shift right algebraic if shift value is nonzero if (magics.s > 0) { - Q = DAG.getNode(ISD::SRA, VT, Q, + Q = DAG.getNode(ISD::SRA, dl, VT, Q, DAG.getConstant(magics.s, getShiftAmountTy())); if (Created) Created->push_back(Q.getNode()); } // Extract the sign bit and add it to the quotient SDValue T = - DAG.getNode(ISD::SRL, VT, Q, DAG.getConstant(VT.getSizeInBits()-1, + DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(VT.getSizeInBits()-1, getShiftAmountTy())); if (Created) Created->push_back(T.getNode()); - return DAG.getNode(ISD::ADD, VT, Q, T); + return DAG.getNode(ISD::ADD, dl, VT, Q, T); } /// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, @@ -2452,6 +2467,7 @@ SDValue TargetLowering::BuildSDIV(SDNode *N, SelectionDAG &DAG, SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, std::vector* Created) const { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); // Check to see if we can do this. // FIXME: We should be more aggressive here. @@ -2467,10 +2483,10 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, // FIXME: We should support doing a MUL in a wider type SDValue Q; if (isOperationLegalOrCustom(ISD::MULHU, VT)) - Q = DAG.getNode(ISD::MULHU, VT, N->getOperand(0), + Q = DAG.getNode(ISD::MULHU, dl, VT, N->getOperand(0), DAG.getConstant(magics.m, VT)); else if (isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) - Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, DAG.getVTList(VT, VT), + Q = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, DAG.getVTList(VT, VT), N->getOperand(0), DAG.getConstant(magics.m, VT)).getNode(), 1); else @@ -2481,20 +2497,20 @@ SDValue TargetLowering::BuildUDIV(SDNode *N, SelectionDAG &DAG, if (magics.a == 0) { assert(magics.s < N1C->getAPIntValue().getBitWidth() && "We shouldn't generate an undefined shift!"); - return DAG.getNode(ISD::SRL, VT, Q, + return DAG.getNode(ISD::SRL, dl, VT, Q, DAG.getConstant(magics.s, getShiftAmountTy())); } else { - SDValue NPQ = DAG.getNode(ISD::SUB, VT, N->getOperand(0), Q); + SDValue NPQ = DAG.getNode(ISD::SUB, dl, VT, N->getOperand(0), Q); if (Created) Created->push_back(NPQ.getNode()); - NPQ = DAG.getNode(ISD::SRL, VT, NPQ, + NPQ = DAG.getNode(ISD::SRL, dl, VT, NPQ, DAG.getConstant(1, getShiftAmountTy())); if (Created) Created->push_back(NPQ.getNode()); - NPQ = DAG.getNode(ISD::ADD, VT, NPQ, Q); + NPQ = DAG.getNode(ISD::ADD, dl, VT, NPQ, Q); if (Created) Created->push_back(NPQ.getNode()); - return DAG.getNode(ISD::SRL, VT, NPQ, + return DAG.getNode(ISD::SRL, dl, VT, NPQ, DAG.getConstant(magics.s-1, getShiftAmountTy())); } } -- GitLab From e3c78361d33bf4986937eb4699169053495e38d2 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 00:55:04 +0000 Subject: [PATCH 666/682] Create DebugLoc information in FastISel. Several temporary methods were created. Specifically, those BuildMIs which use "DebugLoc::getUnknownLoc()". I'll remove them soon. llvm-svn: 63584 --- llvm/include/llvm/CodeGen/FastISel.h | 16 +++-- llvm/include/llvm/CodeGen/MachineFunction.h | 1 + .../llvm/CodeGen/MachineInstrBuilder.h | 59 ++++++++++++++++--- llvm/lib/CodeGen/MachineFunction.cpp | 5 +- llvm/lib/CodeGen/SelectionDAG/FastISel.cpp | 57 ++++++++++-------- .../SelectionDAG/SelectionDAGBuild.cpp | 6 +- llvm/lib/Target/ARM/ARMInstrInfo.cpp | 2 +- llvm/lib/Target/X86/X86InstrInfo.cpp | 11 ++-- 8 files changed, 111 insertions(+), 46 deletions(-) diff --git a/llvm/include/llvm/CodeGen/FastISel.h b/llvm/include/llvm/CodeGen/FastISel.h index 8c048480694a..1c26b3fd763b 100644 --- a/llvm/include/llvm/CodeGen/FastISel.h +++ b/llvm/include/llvm/CodeGen/FastISel.h @@ -16,6 +16,7 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" +#include "llvm/CodeGen/DebugLoc.h" #include "llvm/CodeGen/SelectionDAGNodes.h" namespace llvm { @@ -55,28 +56,33 @@ protected: MachineRegisterInfo &MRI; MachineFrameInfo &MFI; MachineConstantPool &MCP; + DebugLoc DL; const TargetMachine &TM; const TargetData &TD; const TargetInstrInfo &TII; const TargetLowering &TLI; public: - /// startNewBlock - Set the current block, to which generated - /// machine instructions will be appended, and clear the local - /// CSE map. + /// startNewBlock - Set the current block to which generated machine + /// instructions will be appended, and clear the local CSE map. /// void startNewBlock(MachineBasicBlock *mbb) { setCurrentBlock(mbb); LocalValueMap.clear(); } - /// setCurrentBlock - Set the current block, to which generated - /// machine instructions will be appended. + /// setCurrentBlock - Set the current block to which generated machine + /// instructions will be appended. /// void setCurrentBlock(MachineBasicBlock *mbb) { MBB = mbb; } + /// setCurDebugLoc - Set the current debug location information, which is used + /// when creating a machine instruction. + /// + void setCurDebugLoc(DebugLoc dl) { DL = dl; } + /// SelectInstruction - Do "fast" instruction selection for the given /// LLVM IR instruction, and append generated machine instructions to /// the current block. Return true if selection was successful. diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h index 0d5a71d142d7..6abedb50b3c2 100644 --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -286,6 +286,7 @@ public: /// of `new MachineInstr'. /// MachineInstr *CreateMachineInstr(const TargetInstrDesc &TID, + DebugLoc DL, bool NoImp = false); /// CloneMachineInstr - Create a new MachineInstr which is a copy of the diff --git a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h index d097362a5582..54fbe27eec73 100644 --- a/llvm/include/llvm/CodeGen/MachineInstrBuilder.h +++ b/llvm/include/llvm/CodeGen/MachineInstrBuilder.h @@ -100,16 +100,31 @@ public: /// inline MachineInstrBuilder BuildMI(MachineFunction &MF, const TargetInstrDesc &TID) { - return MachineInstrBuilder(MF.CreateMachineInstr(TID)); + return MachineInstrBuilder(MF.CreateMachineInstr(TID, + DebugLoc::getUnknownLoc())); +} +inline MachineInstrBuilder BuildMI(MachineFunction &MF, + DebugLoc DL, + const TargetInstrDesc &TID) { + return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL)); } /// BuildMI - This version of the builder sets up the first operand as a /// destination virtual register. /// -inline MachineInstrBuilder BuildMI(MachineFunction &MF, - const TargetInstrDesc &TID, - unsigned DestReg) { - return MachineInstrBuilder(MF.CreateMachineInstr(TID)).addReg(DestReg, true); +inline MachineInstrBuilder BuildMI(MachineFunction &MF, + const TargetInstrDesc &TID, + unsigned DestReg) { + return MachineInstrBuilder(MF.CreateMachineInstr(TID, + DebugLoc::getUnknownLoc())) + .addReg(DestReg, true); +} +inline MachineInstrBuilder BuildMI(MachineFunction &MF, + DebugLoc DL, + const TargetInstrDesc &TID, + unsigned DestReg) { + return MachineInstrBuilder(MF.CreateMachineInstr(TID, DL)) + .addReg(DestReg, true); } /// BuildMI - This version of the builder inserts the newly-built @@ -120,7 +135,17 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, const TargetInstrDesc &TID, unsigned DestReg) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID); + MachineInstr *MI = + BB.getParent()->CreateMachineInstr(TID, DebugLoc::getUnknownLoc()); + BB.insert(I, MI); + return MachineInstrBuilder(MI).addReg(DestReg, true); +} +inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, + MachineBasicBlock::iterator I, + DebugLoc DL, + const TargetInstrDesc &TID, + unsigned DestReg) { + MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL); BB.insert(I, MI); return MachineInstrBuilder(MI).addReg(DestReg, true); } @@ -132,7 +157,16 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, MachineBasicBlock::iterator I, const TargetInstrDesc &TID) { - MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID); + MachineInstr *MI = + BB.getParent()->CreateMachineInstr(TID, DebugLoc::getUnknownLoc()); + BB.insert(I, MI); + return MachineInstrBuilder(MI); +} +inline MachineInstrBuilder BuildMI(MachineBasicBlock &BB, + MachineBasicBlock::iterator I, + DebugLoc DL, + const TargetInstrDesc &TID) { + MachineInstr *MI = BB.getParent()->CreateMachineInstr(TID, DL); BB.insert(I, MI); return MachineInstrBuilder(MI); } @@ -145,6 +179,11 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, const TargetInstrDesc &TID) { return BuildMI(*BB, BB->end(), TID); } +inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, + DebugLoc DL, + const TargetInstrDesc &TID) { + return BuildMI(*BB, BB->end(), DL, TID); +} /// BuildMI - This version of the builder inserts the newly-built /// instruction at the end of the given MachineBasicBlock, and sets up the first @@ -155,6 +194,12 @@ inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, unsigned DestReg) { return BuildMI(*BB, BB->end(), TID, DestReg); } +inline MachineInstrBuilder BuildMI(MachineBasicBlock *BB, + DebugLoc DL, + const TargetInstrDesc &TID, + unsigned DestReg) { + return BuildMI(*BB, BB->end(), DL, TID, DestReg); +} } // End llvm namespace diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp index b303b1b58c92..434034b888f0 100644 --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -192,9 +192,10 @@ void MachineFunction::RenumberBlocks(MachineBasicBlock *MBB) { /// of `new MachineInstr'. /// MachineInstr * -MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID, bool NoImp) { +MachineFunction::CreateMachineInstr(const TargetInstrDesc &TID, + DebugLoc DL, bool NoImp) { return new (InstructionRecycler.Allocate(Allocator)) - MachineInstr(TID, NoImp); + MachineInstr(TID, DL, NoImp); } /// CloneMachineInstr - Create a new MachineInstr which is a copy of the diff --git a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp index 18cbfe440474..04e97212ddf3 100644 --- a/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/FastISel.cpp @@ -114,7 +114,7 @@ unsigned FastISel::getRegForValue(Value *V) { Reg = LocalValueMap[CE]; } else if (isa(V)) { Reg = createResultReg(TLI.getRegClassFor(VT)); - BuildMI(MBB, TII.get(TargetInstrInfo::IMPLICIT_DEF), Reg); + BuildMI(MBB, DL, TII.get(TargetInstrInfo::IMPLICIT_DEF), Reg); } // If target-independent code couldn't handle the value, give target-specific @@ -324,8 +324,10 @@ bool FastISel::SelectCall(User *I) { unsigned Line = SPI->getLine(); unsigned Col = SPI->getColumn(); unsigned ID = DW->RecordSourceLine(Line, Col, SrcFile); + unsigned Idx = MF.getOrCreateDebugLocID(SrcFile, Line, Col); + setCurDebugLoc(DebugLoc::get(Idx)); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, II).addImm(ID); + BuildMI(MBB, DL, II).addImm(ID); } return true; } @@ -335,7 +337,7 @@ bool FastISel::SelectCall(User *I) { unsigned ID = DW->RecordRegionStart(cast(RSI->getContext())); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, II).addImm(ID); + BuildMI(MBB, DL, II).addImm(ID); } return true; } @@ -345,7 +347,7 @@ bool FastISel::SelectCall(User *I) { unsigned ID = DW->RecordRegionEnd(cast(REI->getContext())); const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, II).addImm(ID); + BuildMI(MBB, DL, II).addImm(ID); } return true; } @@ -353,23 +355,28 @@ bool FastISel::SelectCall(User *I) { if (!DW) return true; DbgFuncStartInst *FSI = cast(I); Value *SP = FSI->getSubprogram(); + if (DW->ValidDebugInfo(SP)) { - // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is - // what (most?) gdb expects. + // llvm.dbg.func.start implicitly defines a dbg_stoppoint which is what + // (most?) gdb expects. DISubprogram Subprogram(cast(SP)); DICompileUnit CompileUnit = Subprogram.getCompileUnit(); unsigned SrcFile = DW->RecordSource(CompileUnit.getDirectory(), CompileUnit.getFilename()); + // Record the source line but does not create a label for the normal // function start. It will be emitted at asm emission time. However, // create a label if this is a beginning of inlined function. - unsigned LabelID = - DW->RecordSourceLine(Subprogram.getLineNumber(), 0, SrcFile); + unsigned Line = Subprogram.getLineNumber(); + unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); + setCurDebugLoc(DebugLoc::get(MF.getOrCreateDebugLocID(SrcFile, Line, 0))); + if (DW->getRecordSourceLineCount() != 1) { const TargetInstrDesc &II = TII.get(TargetInstrInfo::DBG_LABEL); - BuildMI(MBB, II).addImm(LabelID); + BuildMI(MBB, DL, II).addImm(LabelID); } } + return true; } case Intrinsic::dbg_declare: { @@ -393,7 +400,7 @@ bool FastISel::SelectCall(User *I) { // Build the DECLARE instruction. const TargetInstrDesc &II = TII.get(TargetInstrInfo::DECLARE); - BuildMI(MBB, II).addFrameIndex(FI).addGlobalAddress(GV); + BuildMI(MBB, DL, II).addFrameIndex(FI).addGlobalAddress(GV); } return true; } @@ -830,7 +837,7 @@ unsigned FastISel::FastEmitInst_(unsigned MachineInstOpcode, unsigned ResultReg = createResultReg(RC); const TargetInstrDesc &II = TII.get(MachineInstOpcode); - BuildMI(MBB, II, ResultReg); + BuildMI(MBB, DL, II, ResultReg); return ResultReg; } @@ -841,9 +848,9 @@ unsigned FastISel::FastEmitInst_r(unsigned MachineInstOpcode, const TargetInstrDesc &II = TII.get(MachineInstOpcode); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addReg(Op0); + BuildMI(MBB, DL, II, ResultReg).addReg(Op0); else { - BuildMI(MBB, II).addReg(Op0); + BuildMI(MBB, DL, II).addReg(Op0); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) @@ -860,9 +867,9 @@ unsigned FastISel::FastEmitInst_rr(unsigned MachineInstOpcode, const TargetInstrDesc &II = TII.get(MachineInstOpcode); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1); + BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addReg(Op1); else { - BuildMI(MBB, II).addReg(Op0).addReg(Op1); + BuildMI(MBB, DL, II).addReg(Op0).addReg(Op1); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) @@ -878,9 +885,9 @@ unsigned FastISel::FastEmitInst_ri(unsigned MachineInstOpcode, const TargetInstrDesc &II = TII.get(MachineInstOpcode); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addReg(Op0).addImm(Imm); + BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Imm); else { - BuildMI(MBB, II).addReg(Op0).addImm(Imm); + BuildMI(MBB, DL, II).addReg(Op0).addImm(Imm); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) @@ -896,9 +903,9 @@ unsigned FastISel::FastEmitInst_rf(unsigned MachineInstOpcode, const TargetInstrDesc &II = TII.get(MachineInstOpcode); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addReg(Op0).addFPImm(FPImm); + BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addFPImm(FPImm); else { - BuildMI(MBB, II).addReg(Op0).addFPImm(FPImm); + BuildMI(MBB, DL, II).addReg(Op0).addFPImm(FPImm); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) @@ -914,9 +921,9 @@ unsigned FastISel::FastEmitInst_rri(unsigned MachineInstOpcode, const TargetInstrDesc &II = TII.get(MachineInstOpcode); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addReg(Op0).addReg(Op1).addImm(Imm); + BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addReg(Op1).addImm(Imm); else { - BuildMI(MBB, II).addReg(Op0).addReg(Op1).addImm(Imm); + BuildMI(MBB, DL, II).addReg(Op0).addReg(Op1).addImm(Imm); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) @@ -932,9 +939,9 @@ unsigned FastISel::FastEmitInst_i(unsigned MachineInstOpcode, const TargetInstrDesc &II = TII.get(MachineInstOpcode); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addImm(Imm); + BuildMI(MBB, DL, II, ResultReg).addImm(Imm); else { - BuildMI(MBB, II).addImm(Imm); + BuildMI(MBB, DL, II).addImm(Imm); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) @@ -951,9 +958,9 @@ unsigned FastISel::FastEmitInst_extractsubreg(MVT::SimpleValueType RetVT, const TargetInstrDesc &II = TII.get(TargetInstrInfo::EXTRACT_SUBREG); if (II.getNumDefs() >= 1) - BuildMI(MBB, II, ResultReg).addReg(Op0).addImm(Idx); + BuildMI(MBB, DL, II, ResultReg).addReg(Op0).addImm(Idx); else { - BuildMI(MBB, II).addReg(Op0).addImm(Idx); + BuildMI(MBB, DL, II).addReg(Op0).addImm(Idx); bool InsertedCopy = TII.copyRegToReg(*MBB, MBB->end(), ResultReg, II.ImplicitDefs[0], RC, RC); if (!InsertedCopy) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index 9057775a5cdd..dd631af91fdd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -3884,14 +3884,16 @@ SelectionDAGLowering::visitIntrinsicCall(CallInst &I, unsigned Intrinsic) { DICompileUnit CompileUnit = Subprogram.getCompileUnit(); unsigned SrcFile = DW->RecordSource(CompileUnit.getDirectory(), CompileUnit.getFilename()); + // Record the source line but does not create a label for the normal // function start. It will be emitted at asm emission time. However, // create a label if this is a beginning of inlined function. unsigned Line = Subprogram.getLineNumber(); - unsigned LabelID = - DW->RecordSourceLine(Line, 0, SrcFile); + unsigned LabelID = DW->RecordSourceLine(Line, 0, SrcFile); + if (DW->getRecordSourceLineCount() != 1) DAG.setRoot(DAG.getLabel(ISD::DBG_LABEL, getRoot(), LabelID)); + setCurDebugLoc(DebugLoc::get(DAG.getMachineFunction(). getOrCreateDebugLocID(SrcFile, Line, 0))); } diff --git a/llvm/lib/Target/ARM/ARMInstrInfo.cpp b/llvm/lib/Target/ARM/ARMInstrInfo.cpp index 3d1e51231923..c160714b5475 100644 --- a/llvm/lib/Target/ARM/ARMInstrInfo.cpp +++ b/llvm/lib/Target/ARM/ARMInstrInfo.cpp @@ -649,7 +649,7 @@ bool ARMInstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, return false; bool isVarArg = AFI->getVarArgsRegSaveSize() > 0; - MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP)); + MachineInstr *PopMI = MF.CreateMachineInstr(get(ARM::tPOP),MI->getDebugLoc()); MBB.insert(MI, PopMI); for (unsigned i = CSI.size(); i != 0; --i) { unsigned Reg = CSI[i-1].getReg(); diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 188d40208762..21a11e3808b7 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -1938,9 +1938,11 @@ bool X86InstrInfo::restoreCalleeSavedRegisters(MachineBasicBlock &MBB, static MachineInstr *FuseTwoAddrInst(MachineFunction &MF, unsigned Opcode, const SmallVectorImpl &MOs, - MachineInstr *MI, const TargetInstrInfo &TII) { + MachineInstr *MI, + const TargetInstrInfo &TII) { // Create the base instruction with the memory operand as the first part. - MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), true); + MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), + MI->getDebugLoc(), true); MachineInstrBuilder MIB(NewMI); unsigned NumAddrOps = MOs.size(); for (unsigned i = 0; i != NumAddrOps; ++i) @@ -1965,7 +1967,8 @@ static MachineInstr *FuseInst(MachineFunction &MF, unsigned Opcode, unsigned OpNo, const SmallVectorImpl &MOs, MachineInstr *MI, const TargetInstrInfo &TII) { - MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), true); + MachineInstr *NewMI = MF.CreateMachineInstr(TII.get(Opcode), + MI->getDebugLoc(), true); MachineInstrBuilder MIB(NewMI); for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) { @@ -2298,7 +2301,7 @@ bool X86InstrInfo::unfoldMemoryOperand(MachineFunction &MF, MachineInstr *MI, } // Emit the data processing instruction. - MachineInstr *DataMI = MF.CreateMachineInstr(TID, true); + MachineInstr *DataMI = MF.CreateMachineInstr(TID, MI->getDebugLoc(), true); MachineInstrBuilder MIB(DataMI); if (FoldedStore) -- GitLab From 17450acc3b5298a2a72b2742dcb1419d582f2231 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 01:02:39 +0000 Subject: [PATCH 667/682] Propagate debug loc info during SDNode -> machine instr creation. llvm-svn: 63585 --- .../SelectionDAG/ScheduleDAGSDNodesEmit.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp index c6f98bf1e974..06cae7d496e8 100644 --- a/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/ScheduleDAGSDNodesEmit.cpp @@ -219,7 +219,7 @@ unsigned ScheduleDAGSDNodes::getVR(SDValue Op, const TargetRegisterClass *RC = TLI->getRegClassFor(Op.getValueType()); VReg = MRI.createVirtualRegister(RC); } - BuildMI(BB, TII->get(TargetInstrInfo::IMPLICIT_DEF), VReg); + BuildMI(BB, Op.getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF),VReg); return VReg; } @@ -359,7 +359,8 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, unsigned SubIdx = cast(Node->getOperand(1))->getZExtValue(); // Create the extract_subreg machine instruction. - MachineInstr *MI = BuildMI(MF, TII->get(TargetInstrInfo::EXTRACT_SUBREG)); + MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), + TII->get(TargetInstrInfo::EXTRACT_SUBREG)); // Figure out the register class to create for the destreg. const TargetRegisterClass *SRC = TLI->getRegClassFor(Node->getValueType(0)); @@ -401,7 +402,7 @@ void ScheduleDAGSDNodes::EmitSubregNode(SDNode *Node, } // Create the insert_subreg or subreg_to_reg machine instruction. - MachineInstr *MI = BuildMI(MF, TII->get(Opc)); + MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), TII->get(Opc)); MI->addOperand(MachineOperand::CreateReg(VRBase, true)); // If creating a subreg_to_reg, then the first input operand @@ -458,7 +459,7 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, #endif // Create the new machine instruction. - MachineInstr *MI = BuildMI(MF, II); + MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), II); // Add result register values for things that are defined by this // instruction. @@ -479,8 +480,9 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, // specific inserter which may returns a new basic block. BB = TLI->EmitInstrWithCustomInserter(MI, BB); Begin = End = BB->end(); - } else + } else { BB->insert(End, MI); + } // Additional results must be an physical register def. if (HasPhysRegOuts) { @@ -543,7 +545,8 @@ void ScheduleDAGSDNodes::EmitNode(SDNode *Node, bool IsClone, bool IsCloned, --NumOps; // Ignore the flag operand. // Create the inline asm machine instruction. - MachineInstr *MI = BuildMI(MF, TII->get(TargetInstrInfo::INLINEASM)); + MachineInstr *MI = BuildMI(MF, Node->getDebugLoc(), + TII->get(TargetInstrInfo::INLINEASM)); // Add the asm string as an external symbol operand. const char *AsmStr = -- GitLab From 6d6b0d309afc1e8d6a915d101aaeafb69a1658e7 Mon Sep 17 00:00:00 2001 From: Daniel Dunbar Date: Tue, 3 Feb 2009 01:05:53 +0000 Subject: [PATCH 668/682] Move ABIInfo/ABIArgInfo classes into ABIInfo.h llvm-svn: 63586 --- clang/lib/CodeGen/ABIInfo.h | 116 +++++++++++++++++++++++++++++++++++ clang/lib/CodeGen/CGCall.cpp | 106 +------------------------------- 2 files changed, 119 insertions(+), 103 deletions(-) create mode 100644 clang/lib/CodeGen/ABIInfo.h diff --git a/clang/lib/CodeGen/ABIInfo.h b/clang/lib/CodeGen/ABIInfo.h new file mode 100644 index 000000000000..4b33c4e8065d --- /dev/null +++ b/clang/lib/CodeGen/ABIInfo.h @@ -0,0 +1,116 @@ +//===----- ABIInfo.h - ABI information access & encapsulation ---*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef CLANG_CODEGEN_ABIINFO_H +#define CLANG_CODEGEN_ABIINFO_H + +namespace clang { + /* FIXME: All of this stuff should be part of the target interface + somehow. It is currently here because it is not clear how to factor + the targets to support this, since the Targets currently live in a + layer below types n'stuff. + */ + + /// ABIArgInfo - Helper class to encapsulate information about how a + /// specific C type should be passed to or returned from a function. + class ABIArgInfo { + public: + enum Kind { + Default, + StructRet, /// Only valid for return values. The return value + /// should be passed through a pointer to a caller + /// allocated location passed as an implicit first + /// argument to the function. + + Ignore, /// Ignore the argument (treat as void). Useful for + /// void and empty structs. + + Coerce, /// Only valid for aggregate return types, the argument + /// should be accessed by coercion to a provided type. + + ByVal, /// Only valid for aggregate argument types. The + /// structure should be passed "byval" with the + /// specified alignment (0 indicates default + /// alignment). + + Expand, /// Only valid for aggregate argument types. The + /// structure should be expanded into consecutive + /// arguments for its constituent fields. Currently + /// expand is only allowed on structures whose fields + /// are all scalar types or are themselves expandable + /// types. + + KindFirst=Default, KindLast=Expand + }; + + private: + Kind TheKind; + const llvm::Type *TypeData; + unsigned UIntData; + + ABIArgInfo(Kind K, const llvm::Type *TD=0, + unsigned UI=0) : TheKind(K), + TypeData(TD), + UIntData(0) {} + public: + static ABIArgInfo getDefault() { + return ABIArgInfo(Default); + } + static ABIArgInfo getStructRet() { + return ABIArgInfo(StructRet); + } + static ABIArgInfo getIgnore() { + return ABIArgInfo(Ignore); + } + static ABIArgInfo getCoerce(const llvm::Type *T) { + return ABIArgInfo(Coerce, T); + } + static ABIArgInfo getByVal(unsigned Alignment) { + return ABIArgInfo(ByVal, 0, Alignment); + } + static ABIArgInfo getExpand() { + return ABIArgInfo(Expand); + } + + Kind getKind() const { return TheKind; } + bool isDefault() const { return TheKind == Default; } + bool isStructRet() const { return TheKind == StructRet; } + bool isIgnore() const { return TheKind == Ignore; } + bool isCoerce() const { return TheKind == Coerce; } + bool isByVal() const { return TheKind == ByVal; } + bool isExpand() const { return TheKind == Expand; } + + // Coerce accessors + const llvm::Type *getCoerceToType() const { + assert(TheKind == Coerce && "Invalid kind!"); + return TypeData; + } + + // ByVal accessors + unsigned getByValAlignment() const { + assert(TheKind == ByVal && "Invalid kind!"); + return UIntData; + } + }; + + /// ABIInfo - Target specific hooks for defining how a type should be + /// passed or returned from functions. + class ABIInfo { + public: + virtual ~ABIInfo(); + + virtual ABIArgInfo classifyReturnType(QualType RetTy, + ASTContext &Context) const = 0; + + virtual ABIArgInfo classifyArgumentType(QualType Ty, + ASTContext &Context) const = 0; + }; +} // end namespace clang + +#endif diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp index 30257d2699e4..c6e804ea0bbb 100644 --- a/clang/lib/CodeGen/CGCall.cpp +++ b/clang/lib/CodeGen/CGCall.cpp @@ -24,6 +24,9 @@ #include "llvm/Attributes.h" #include "llvm/Support/CommandLine.h" #include "llvm/Target/TargetData.h" + +#include "ABIInfo.h" + using namespace clang; using namespace CodeGen; @@ -118,109 +121,6 @@ CGFunctionInfo::arg_iterator CGFunctionInfo::arg_end() const { /***/ -/// ABIArgInfo - Helper class to encapsulate information about how a -/// specific C type should be passed to or returned from a function. -class ABIArgInfo { -public: - enum Kind { - Default, - StructRet, /// Only valid for return values. The return value - /// should be passed through a pointer to a caller - /// allocated location passed as an implicit first - /// argument to the function. - - Ignore, /// Ignore the argument (treat as void). Useful for - /// void and empty structs. - - Coerce, /// Only valid for aggregate return types, the argument - /// should be accessed by coercion to a provided type. - - ByVal, /// Only valid for aggregate argument types. The - /// structure should be passed "byval" with the - /// specified alignment (0 indicates default - /// alignment). - - Expand, /// Only valid for aggregate argument types. The - /// structure should be expanded into consecutive - /// arguments for its constituent fields. Currently - /// expand is only allowed on structures whose fields - /// are all scalar types or are themselves expandable - /// types. - - KindFirst=Default, KindLast=Expand - }; - -private: - Kind TheKind; - const llvm::Type *TypeData; - unsigned UIntData; - - ABIArgInfo(Kind K, const llvm::Type *TD=0, - unsigned UI=0) : TheKind(K), - TypeData(TD), - UIntData(0) {} -public: - static ABIArgInfo getDefault() { - return ABIArgInfo(Default); - } - static ABIArgInfo getStructRet() { - return ABIArgInfo(StructRet); - } - static ABIArgInfo getIgnore() { - return ABIArgInfo(Ignore); - } - static ABIArgInfo getCoerce(const llvm::Type *T) { - return ABIArgInfo(Coerce, T); - } - static ABIArgInfo getByVal(unsigned Alignment) { - return ABIArgInfo(ByVal, 0, Alignment); - } - static ABIArgInfo getExpand() { - return ABIArgInfo(Expand); - } - - Kind getKind() const { return TheKind; } - bool isDefault() const { return TheKind == Default; } - bool isStructRet() const { return TheKind == StructRet; } - bool isIgnore() const { return TheKind == Ignore; } - bool isCoerce() const { return TheKind == Coerce; } - bool isByVal() const { return TheKind == ByVal; } - bool isExpand() const { return TheKind == Expand; } - - // Coerce accessors - const llvm::Type *getCoerceToType() const { - assert(TheKind == Coerce && "Invalid kind!"); - return TypeData; - } - - // ByVal accessors - unsigned getByValAlignment() const { - assert(TheKind == ByVal && "Invalid kind!"); - return UIntData; - } -}; - -/***/ - -/* FIXME: All of this stuff should be part of the target interface - somehow. It is currently here because it is not clear how to factor - the targets to support this, since the Targets currently live in a - layer below types n'stuff. - */ - -/// ABIInfo - Target specific hooks for defining how a type should be -/// passed or returned from functions. -class clang::ABIInfo { -public: - virtual ~ABIInfo(); - - virtual ABIArgInfo classifyReturnType(QualType RetTy, - ASTContext &Context) const = 0; - - virtual ABIArgInfo classifyArgumentType(QualType Ty, - ASTContext &Context) const = 0; -}; - ABIInfo::~ABIInfo() {} /// isEmptyStruct - Return true iff a structure has no non-empty -- GitLab From a0ce5f060d8e53752c896d3ac97fd4cbf5bfe100 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Feb 2009 01:13:52 +0000 Subject: [PATCH 669/682] this test produces an undefined value, we don't care what it is, but we do want the alloca promoted. llvm-svn: 63587 --- llvm/test/Transforms/ScalarRepl/badarray.ll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/test/Transforms/ScalarRepl/badarray.ll b/llvm/test/Transforms/ScalarRepl/badarray.ll index 56ae04ce9174..acac5a61822f 100644 --- a/llvm/test/Transforms/ScalarRepl/badarray.ll +++ b/llvm/test/Transforms/ScalarRepl/badarray.ll @@ -1,4 +1,4 @@ -; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i32 0} +; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | not grep alloca define i32 @test() { %X = alloca [4 x i32] ; <[4 x i32]*> [#uses=1] -- GitLab From a814d961161e86a0023dfa29ab7814e1de2c85fe Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Feb 2009 01:28:04 +0000 Subject: [PATCH 670/682] Content Cache only needs to be 4-byte aligned. Since it is stored in an std::set, we can't make a strong guarantee about what its alignment will be. Since I don't need the 3rd bit anyway yet, just change the assertion. llvm-svn: 63588 --- clang/include/clang/Basic/SourceManager.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clang/include/clang/Basic/SourceManager.h b/clang/include/clang/Basic/SourceManager.h index a63ef7903728..7dbf0ccf61a0 100644 --- a/clang/include/clang/Basic/SourceManager.h +++ b/clang/include/clang/Basic/SourceManager.h @@ -143,7 +143,7 @@ namespace SrcMgr { FileInfo X; X.IncludeLoc = IL.getRawEncoding(); X.Data = (uintptr_t)Con; - assert((X.Data & 7) == 0 &&"ContentCache pointer insufficiently aligned"); + assert((X.Data & 3) == 0 &&"ContentCache pointer insufficiently aligned"); assert((unsigned)FileCharacter < 4 && "invalid file character"); X.Data |= (unsigned)FileCharacter; return X; @@ -153,7 +153,7 @@ namespace SrcMgr { return SourceLocation::getFromRawEncoding(IncludeLoc); } const ContentCache* getContentCache() const { - return reinterpret_cast(Data & ~7UL); + return reinterpret_cast(Data & ~3UL); } /// getCharacteristic - Return whether this is a system header or not. -- GitLab From fb306c0a10ecdaf6b4f5044b768b2470cd5af76e Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Feb 2009 01:28:32 +0000 Subject: [PATCH 671/682] Move isIdentifiedObject and isNoAliasCall into AliasAnalysis.cpp since they are useful to analyses other than BasicAliasAnalysis.cpp. Include the full comment for isIdentifiedObject in the header file. Thanks to Chris for suggeseting this. llvm-svn: 63589 --- llvm/include/llvm/Analysis/AliasAnalysis.h | 10 ++++++++- llvm/lib/Analysis/AliasAnalysis.cpp | 24 ++++++++++++++++++++++ llvm/lib/Analysis/BasicAliasAnalysis.cpp | 24 ---------------------- 3 files changed, 33 insertions(+), 25 deletions(-) diff --git a/llvm/include/llvm/Analysis/AliasAnalysis.h b/llvm/include/llvm/Analysis/AliasAnalysis.h index 2beb8fb0bf16..1b38baf48c57 100644 --- a/llvm/include/llvm/Analysis/AliasAnalysis.h +++ b/llvm/include/llvm/Analysis/AliasAnalysis.h @@ -345,8 +345,16 @@ public: } }; +/// isNoAliasCall - Return true if this pointer is returned by a noalias +/// function. +bool isNoAliasCall(const Value *V); + /// isIdentifiedObject - Return true if this pointer refers to a distinct and -/// identifiable object. +/// identifiable object. This returns true for: +/// Global Variables and Functions +/// Allocas and Mallocs +/// ByVal and NoAlias Arguments +/// NoAlias returns /// bool isIdentifiedObject(const Value *V); diff --git a/llvm/lib/Analysis/AliasAnalysis.cpp b/llvm/lib/Analysis/AliasAnalysis.cpp index c8c43a69ef74..d5de2fe616ac 100644 --- a/llvm/lib/Analysis/AliasAnalysis.cpp +++ b/llvm/lib/Analysis/AliasAnalysis.cpp @@ -207,6 +207,30 @@ bool AliasAnalysis::canInstructionRangeModify(const Instruction &I1, return false; } +/// isNoAliasCall - Return true if this pointer is returned by a noalias +/// function. +bool llvm::isNoAliasCall(const Value *V) { + if (isa(V) || isa(V)) + return CallSite(const_cast(cast(V))) + .paramHasAttr(0, Attribute::NoAlias); + return false; +} + +/// isIdentifiedObject - Return true if this pointer refers to a distinct and +/// identifiable object. This returns true for: +/// Global Variables and Functions +/// Allocas and Mallocs +/// ByVal and NoAlias Arguments +/// NoAlias returns +/// +bool llvm::isIdentifiedObject(const Value *V) { + if (isa(V) || isa(V) || isNoAliasCall(V)) + return true; + if (const Argument *A = dyn_cast(V)) + return A->hasNoAliasAttr() || A->hasByValAttr(); + return false; +} + // Because of the way .a files work, we must force the BasicAA implementation to // be pulled in if the AliasAnalysis classes are pulled in. Otherwise we run // the risk of AliasAnalysis being used, but the default implementation not diff --git a/llvm/lib/Analysis/BasicAliasAnalysis.cpp b/llvm/lib/Analysis/BasicAliasAnalysis.cpp index 1002868e84cb..ccbe338585df 100644 --- a/llvm/lib/Analysis/BasicAliasAnalysis.cpp +++ b/llvm/lib/Analysis/BasicAliasAnalysis.cpp @@ -64,30 +64,6 @@ static const Value *GetGEPOperands(const Value *V, return V; } -/// isNoAliasCall - Return true if this pointer is returned by a noalias -/// function. -static bool isNoAliasCall(const Value *V) { - if (isa(V) || isa(V)) - return CallSite(const_cast(cast(V))) - .paramHasAttr(0, Attribute::NoAlias); - return false; -} - -/// isIdentifiedObject - Return true if this pointer refers to a distinct and -/// identifiable object. This returns true for: -/// Global Variables and Functions -/// Allocas and Mallocs -/// ByVal and NoAlias Arguments -/// NoAlias returns -/// -bool llvm::isIdentifiedObject(const Value *V) { - if (isa(V) || isa(V) || isNoAliasCall(V)) - return true; - if (const Argument *A = dyn_cast(V)) - return A->hasNoAliasAttr() || A->hasByValAttr(); - return false; -} - /// isKnownNonNull - Return true if we know that the specified value is never /// null. static bool isKnownNonNull(const Value *V) { -- GitLab From 09b65ab288779be19b37f5caaec30a6f2fe023d4 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Feb 2009 01:30:09 +0000 Subject: [PATCH 672/682] rearrange how SRoA handles promotion of allocas to vectors. With the new world order, it can handle cases where the first store into the alloca is an element of the vector, instead of requiring the first analyzed store to have the vector type itself. This allows us to un-xfail test/CodeGen/X86/vec_ins_extract.ll. llvm-svn: 63590 --- .../Scalar/ScalarReplAggregates.cpp | 213 ++++++++++-------- llvm/test/CodeGen/X86/vec_ins_extract.ll | 1 - .../Transforms/ScalarRepl/vector_promote.ll | 10 + 3 files changed, 130 insertions(+), 94 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 012769568d33..5031619b51cb 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -125,8 +125,8 @@ namespace { void RewriteLoadUserOfWholeAlloca(LoadInst *LI, AllocationInst *AI, SmallVector &NewElts); - bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&ResTy, - uint64_t Offset); + bool CanConvertToScalar(Value *V, bool &IsNotTrivial, const Type *&VecTy, + uint64_t Offset, unsigned AllocaSize); void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset); Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, uint64_t Offset); @@ -223,17 +223,38 @@ bool SROA::performScalarRepl(Function &F) { AI->eraseFromParent(); continue; } + + // If this alloca is impossible for us to promote, reject it early. + if (AI->isArrayAllocation() || !AI->getAllocatedType()->isSized()) + continue; + + // Check to see if this allocation is only modified by a memcpy/memmove from + // a constant global. If this is the case, we can change all users to use + // the constant global instead. This is commonly produced by the CFE by + // constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A' + // is only subsequently read. + if (Instruction *TheCopy = isOnlyCopiedFromConstantGlobal(AI)) { + DOUT << "Found alloca equal to global: " << *AI; + DOUT << " memcpy = " << *TheCopy; + Constant *TheSrc = cast(TheCopy->getOperand(2)); + AI->replaceAllUsesWith(ConstantExpr::getBitCast(TheSrc, AI->getType())); + TheCopy->eraseFromParent(); // Don't mutate the global. + AI->eraseFromParent(); + ++NumGlobals; + Changed = true; + continue; + } // Check to see if we can perform the core SROA transformation. We cannot // transform the allocation instruction if it is an array allocation // (allocations OF arrays are ok though), and an allocation of a scalar // value cannot be decomposed at all. - if (!AI->isArrayAllocation() && - (isa(AI->getAllocatedType()) || + uint64_t AllocaSize = TD->getTypePaddedSize(AI->getAllocatedType()); + + if ((isa(AI->getAllocatedType()) || isa(AI->getAllocatedType())) && - AI->getAllocatedType()->isSized() && - // Do not promote any struct whose size is larger than "128" bytes. - TD->getTypePaddedSize(AI->getAllocatedType()) < SRThreshold && + // Do not promote any struct whose size is too big. + AllocaSize < SRThreshold && // Do not promote any struct into more than "32" separate vars. getNumSAElements(AI->getAllocatedType()) < SRThreshold/4) { // Check that all of the users of the allocation are capable of being @@ -251,25 +272,6 @@ bool SROA::performScalarRepl(Function &F) { continue; } } - - // Check to see if this allocation is only modified by a memcpy/memmove from - // a constant global. If this is the case, we can change all users to use - // the constant global instead. This is commonly produced by the CFE by - // constructs like "void foo() { int A[] = {1,2,3,4,5,6,7,8,9...}; }" if 'A' - // is only subsequently read. - if (Instruction *TheCopy = isOnlyCopiedFromConstantGlobal(AI)) { - DOUT << "Found alloca equal to global: " << *AI; - DOUT << " memcpy = " << *TheCopy; - Constant *TheSrc = cast(TheCopy->getOperand(2)); - AI->replaceAllUsesWith(ConstantExpr::getBitCast(TheSrc, AI->getType())); - TheCopy->eraseFromParent(); // Don't mutate the global. - AI->eraseFromParent(); - ++NumGlobals; - Changed = true; - continue; - } - - // If we can turn this aggregate value (potentially with casts) into a // simple scalar value that can be mem2reg'd into a register value. @@ -278,23 +280,32 @@ bool SROA::performScalarRepl(Function &F) { // that we can't just check based on the type: the alloca may be of an i32 // but that has pointer arithmetic to set byte 3 of it or something. bool IsNotTrivial = false; - const Type *ActualTy = 0; - if (CanConvertToScalar(AI, IsNotTrivial, ActualTy, 0)) - if (IsNotTrivial && ActualTy && - TD->getTypeSizeInBits(ActualTy) < SRThreshold*8) { - DOUT << "CONVERT TO SCALAR: " << *AI << " TYPE = " << *ActualTy <<"\n"; - ++NumConverted; + const Type *VectorTy = 0; + if (CanConvertToScalar(AI, IsNotTrivial, VectorTy, + 0, unsigned(AllocaSize)) && IsNotTrivial) { + AllocaInst *NewAI; + if (VectorTy && isa(VectorTy)) { + DOUT << "CONVERT TO VECTOR: " << *AI << " TYPE = " << *VectorTy <<"\n"; - // Create and insert the alloca. - AllocaInst *NewAI = new AllocaInst(ActualTy, 0, AI->getName(), - AI->getParent()->begin()); + // Create and insert the vector alloca. + NewAI = new AllocaInst(VectorTy, 0, "", AI->getParent()->begin()); + ConvertUsesToScalar(AI, NewAI, 0); + } else { + DOUT << "CONVERT TO SCALAR INTEGER: " << *AI << "\n"; + + // Create and insert the integer alloca. + const Type *NewTy = IntegerType::get(AllocaSize*8); + NewAI = new AllocaInst(NewTy, 0, "", AI->getParent()->begin()); ConvertUsesToScalar(AI, NewAI, 0); - AI->eraseFromParent(); - Changed = true; - continue; } + NewAI->takeName(AI); + AI->eraseFromParent(); + ++NumConverted; + Changed = true; + continue; + } - // Otherwise, couldn't process this. + // Otherwise, couldn't process this alloca. } return Changed; @@ -1171,58 +1182,56 @@ void SROA::CanonicalizeAllocaUsers(AllocationInst *AI) { /// 2) A fully general blob of memory, which we turn into some (potentially /// large) integer type with extract and insert operations where the loads /// and stores would mutate the memory. -static void MergeInType(const Type *In, uint64_t Offset, const Type *&Accum, - const TargetData &TD) { - // If this is our first type, just use it. - if ((Accum == 0 && Offset == 0) || In == Type::VoidTy || - // Or if this is a same type, keep it. - (In == Accum && Offset == 0)) { - Accum = In; - return; - } - - // Merging something like i32 into offset 8 means that a "field" is merged in - // before the basic type is. Make sure to consider the offset below. - if (Accum == 0) - Accum = Type::Int8Ty; - - if (const VectorType *VATy = dyn_cast(Accum)) { - if (VATy->getElementType() == In && - Offset % TD.getTypePaddedSize(In) == 0 && - Offset < TD.getTypePaddedSize(VATy)) - return; // Accum is a vector, and we are accessing an element: ok. - if (const VectorType *VInTy = dyn_cast(In)) - if (VInTy->getBitWidth() == VATy->getBitWidth() && Offset == 0) - return; // Two vectors of the same size: keep either one of them. - } - - if (const VectorType *VInTy = dyn_cast(In)) { - // In is a vector, and we are accessing an element: keep V. - if (VInTy->getElementType() == Accum && - Offset % TD.getTypePaddedSize(Accum) == 0 && - Offset < TD.getTypePaddedSize(VInTy)) { - Accum = VInTy; - return; +static void MergeInType(const Type *In, uint64_t Offset, const Type *&VecTy, + unsigned AllocaSize, const TargetData &TD) { + // If this could be contributing to a vector, analyze it. + if (VecTy != Type::VoidTy) { // either null or a vector type. + + // If the In type is a vector that is the same size as the alloca, see if it + // matches the existing VecTy. + if (const VectorType *VInTy = dyn_cast(In)) { + if (VInTy->getBitWidth()/8 == AllocaSize && Offset == 0) { + // If we're storing/loading a vector of the right size, allow it as a + // vector. If this the first vector we see, remember the type so that + // we know the element size. + if (VecTy == 0) + VecTy = VInTy; + return; + } + } else if (In == Type::FloatTy || In == Type::DoubleTy || + (isa(In) && In->getPrimitiveSizeInBits() >= 8 && + isPowerOf2_32(In->getPrimitiveSizeInBits()))) { + // If we're accessing something that could be an element of a vector, see + // if the implied vector agrees with what we already have and if Offset is + // compatible with it. + unsigned EltSize = In->getPrimitiveSizeInBits()/8; + if (Offset % EltSize == 0 && + AllocaSize % EltSize == 0 && + (VecTy == 0 || + cast(VecTy)->getElementType() + ->getPrimitiveSizeInBits()/8 == EltSize)) { + if (VecTy == 0) + VecTy = VectorType::get(In, AllocaSize/EltSize); + return; + } } } - // Otherwise, we have a case that we can't handle with an optimized form. - // Convert the alloca to an integer that is as large as the largest store size - // of the value values. - uint64_t InSize = TD.getTypeStoreSizeInBits(In)+8*Offset; - uint64_t ASize = TD.getTypeStoreSizeInBits(Accum); - if (InSize > ASize) ASize = InSize; - Accum = IntegerType::get(ASize); + // Otherwise, we have a case that we can't handle with an optimized vector + // form. We can still turn this into a large integer. + VecTy = Type::VoidTy; } /// CanConvertToScalar - V is a pointer. If we can convert the pointee and all -/// its accesses to use a to single scalar type, return true, and set ResTy to -/// the new type. Further, if the use is not a completely trivial use that -/// mem2reg could promote, set IsNotTrivial. Offset is the current offset from -/// the base of the alloca being analyzed. +/// its accesses to use a to single vector type, return true, and set VecTy to +/// the new type. If we could convert the alloca into a single promotable +/// integer, return true but set VecTy to VoidTy. Further, if the use is not a +/// completely trivial use that mem2reg could promote, set IsNotTrivial. Offset +/// is the current offset from the base of the alloca being analyzed. /// bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, - const Type *&ResTy, uint64_t Offset) { + const Type *&VecTy, uint64_t Offset, + unsigned AllocaSize) { for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI!=E; ++UI) { Instruction *User = cast(*UI); @@ -1230,19 +1239,19 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, // Don't break volatile loads. if (LI->isVolatile()) return false; - MergeInType(LI->getType(), Offset, ResTy, *TD); + MergeInType(LI->getType(), Offset, VecTy, AllocaSize, *TD); continue; } if (StoreInst *SI = dyn_cast(User)) { // Storing the pointer, not into the value? if (SI->getOperand(0) == V || SI->isVolatile()) return 0; - MergeInType(SI->getOperand(0)->getType(), Offset, ResTy, *TD); + MergeInType(SI->getOperand(0)->getType(), Offset, VecTy, AllocaSize, *TD); continue; } if (BitCastInst *BCI = dyn_cast(User)) { - if (!CanConvertToScalar(BCI, IsNotTrivial, ResTy, Offset)) + if (!CanConvertToScalar(BCI, IsNotTrivial, VecTy, Offset, AllocaSize)) return false; IsNotTrivial = true; continue; @@ -1258,7 +1267,8 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, uint64_t GEPOffset = TD->getIndexedOffset(GEP->getOperand(0)->getType(), &Indices[0], Indices.size()); // See if all uses can be converted. - if (!CanConvertToScalar(GEP, IsNotTrivial, ResTy, Offset+GEPOffset)) + if (!CanConvertToScalar(GEP, IsNotTrivial, VecTy, Offset+GEPOffset, + AllocaSize)) return false; IsNotTrivial = true; continue; @@ -1347,8 +1357,11 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, assert(EltSize*Elt == Offset && "Invalid modulus in validity checking"); } // Return the element extracted out of it. - return new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt), - "tmp", LI); + Value *V = new ExtractElementInst(NV, ConstantInt::get(Type::Int32Ty, Elt), + "tmp", LI); + if (V->getType() != LI->getType()) + V = new BitCastInst(V, LI->getType(), "tmp", LI); + return V; } // Otherwise, this must be a union that was converted to an integer value. @@ -1430,6 +1443,10 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, } else { // Must be an element insertion. unsigned Elt = Offset/TD->getTypePaddedSizeInBits(VTy->getElementType()); + + if (SV->getType() != VTy->getElementType()) + SV = new BitCastInst(SV, VTy->getElementType(), "tmp", SI); + SV = InsertElementInst::Create(Old, SV, ConstantInt::get(Type::Int32Ty, Elt), "tmp", SI); @@ -1452,9 +1469,19 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, else if (isa(SV->getType())) SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), SI); - // Always zero extend the value if needed. - if (SV->getType() != AllocaType) - SV = new ZExtInst(SV, AllocaType, SV->getName(), SI); + // Zero extend or truncate the value if needed. + if (SV->getType() != AllocaType) { + if (SV->getType()->getPrimitiveSizeInBits() < + AllocaType->getPrimitiveSizeInBits()) + SV = new ZExtInst(SV, AllocaType, SV->getName(), SI); + else { + // Truncation may be needed if storing more than the alloca can hold + // (undefined behavior). + SV = new TruncInst(SV, AllocaType, SV->getName(), SI); + SrcWidth = DestWidth; + SrcStoreWidth = DestStoreWidth; + } + } // If this is a big-endian system and the store is narrower than the // full alloca type, we need to do a shift to get the right bits. @@ -1479,7 +1506,7 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, Mask <<= ShAmt; } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) { SV = BinaryOperator::CreateLShr(SV, - ConstantInt::get(SV->getType(),-ShAmt), + ConstantInt::get(SV->getType(), -ShAmt), SV->getName(), SI); Mask = Mask.lshr(-ShAmt); } diff --git a/llvm/test/CodeGen/X86/vec_ins_extract.ll b/llvm/test/CodeGen/X86/vec_ins_extract.ll index 6f6c977db64b..86f13069de29 100644 --- a/llvm/test/CodeGen/X86/vec_ins_extract.ll +++ b/llvm/test/CodeGen/X86/vec_ins_extract.ll @@ -1,6 +1,5 @@ ; RUN: llvm-as < %s | opt -scalarrepl -instcombine | \ ; RUN: llc -march=x86 -mcpu=yonah | not grep sub.*esp -; XFAIL: * ; This checks that various insert/extract idiom work without going to the ; stack. diff --git a/llvm/test/Transforms/ScalarRepl/vector_promote.ll b/llvm/test/Transforms/ScalarRepl/vector_promote.ll index d1d11e229368..a0d331719f06 100644 --- a/llvm/test/Transforms/ScalarRepl/vector_promote.ll +++ b/llvm/test/Transforms/ScalarRepl/vector_promote.ll @@ -52,3 +52,13 @@ entry: store float %tmp.upgrd.6, float* %f ret void } + +define i32 @test5(float %X) { ;; should turn into bitcast. + %X_addr = alloca [4 x float] + %X1 = getelementptr [4 x float]* %X_addr, i32 0, i32 2 + store float %X, float* %X1 + %a = bitcast float* %X1 to i32* + %tmp = load i32* %a + ret i32 %tmp +} + -- GitLab From 9862a64419be9e15a6a5dea28dc4bc8adce7646b Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 01:32:22 +0000 Subject: [PATCH 673/682] Alphabetize includes. llvm-svn: 63591 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h index 397f7b1a249d..47aaf63c9102 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h @@ -20,8 +20,8 @@ #ifndef NDEBUG #include "llvm/ADT/SmallSet.h" #endif -#include "llvm/CodeGen/ValueTypes.h" #include "llvm/CodeGen/SelectionDAGNodes.h" +#include "llvm/CodeGen/ValueTypes.h" #include "llvm/Support/CallSite.h" #include #include -- GitLab From 7aa0c17cff9cbf851b74a5acbf0e4e3a622729ee Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 3 Feb 2009 01:33:26 +0000 Subject: [PATCH 674/682] Delete these two tests. They are specific to x86-64, and there's no reliable way to do this with the current dejagnu infrastructure. If someone can figure out how to fix these tests so that they test what they are intended to test without spuriously failing on any popular platforms, they are invited to reinstate them. llvm-svn: 63592 --- llvm/test/FrontendC/2009-01-25-NoSSE.c | 31 -------------------------- llvm/test/FrontendC/x86-64-red-zone.c | 11 --------- 2 files changed, 42 deletions(-) delete mode 100644 llvm/test/FrontendC/2009-01-25-NoSSE.c delete mode 100644 llvm/test/FrontendC/x86-64-red-zone.c diff --git a/llvm/test/FrontendC/2009-01-25-NoSSE.c b/llvm/test/FrontendC/2009-01-25-NoSSE.c deleted file mode 100644 index c1af5c3f94d1..000000000000 --- a/llvm/test/FrontendC/2009-01-25-NoSSE.c +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: $llvmgcc -m64 -O1 -march=core2 -mno-sse %s -S -o - | not grep xmm -// PR3402 -// This is a test for x86/x86-64, add your target below if it FAILs. -// FIXME: Revert "linux" when fixed. -// XFAIL: alpha|ia64|arm|powerpc|sparc|linux -typedef unsigned long __kernel_size_t; -typedef __kernel_size_t size_t; -void *memset(void *s, int c, size_t n); - -typedef unsigned char cc_t; -typedef unsigned int speed_t; -typedef unsigned int tcflag_t; - -struct ktermios { - tcflag_t c_iflag; - tcflag_t c_oflag; - tcflag_t c_cflag; - tcflag_t c_lflag; - cc_t c_line; - cc_t c_cc[19]; - speed_t c_ispeed; - speed_t c_ospeed; -}; -void bar(struct ktermios*); -void foo() -{ - struct ktermios termios; - memset(&termios, 0, sizeof(termios)); - bar(&termios); -} - diff --git a/llvm/test/FrontendC/x86-64-red-zone.c b/llvm/test/FrontendC/x86-64-red-zone.c deleted file mode 100644 index de9ebbe09b2c..000000000000 --- a/llvm/test/FrontendC/x86-64-red-zone.c +++ /dev/null @@ -1,11 +0,0 @@ -// RUN: $llvmgcc -m64 -fomit-frame-pointer -O2 %s -S -o - > %t -// RUN: not grep subq %t -// RUN: not grep addq %t -// RUN: grep {\\-4(%%rsp)} %t | count 2 -// RUN: $llvmgcc -m64 -fomit-frame-pointer -O2 %s -S -o - -mno-red-zone > %t -// RUN: grep subq %t | count 1 -// RUN: grep addq %t | count 1 -// This is a test for x86-64, add your target below if it FAILs. -// XFAIL: alpha|ia64|arm|powerpc|sparc|i.86 - -long double f0(float f) { return f; } -- GitLab From fa50a23f8a9097e373eb355b4bd39940a1eae893 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 01:33:28 +0000 Subject: [PATCH 675/682] Explicitly pass in the "unknown" debug location. This is probably not correct. We need more infrastructure before we can get the DebugLoc info for these instructions. llvm-svn: 63593 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp | 3 ++- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index dd631af91fdd..a67110ce9b98 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -333,7 +333,8 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf, unsigned NumRegisters = TLI.getNumRegisters(VT); const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); for (unsigned i = 0; i != NumRegisters; ++i) - BuildMI(MBB, TII->get(TargetInstrInfo::PHI), PHIReg+i); + BuildMI(MBB, DebugLoc::getUnknownLoc(), + TII->get(TargetInstrInfo::PHI), PHIReg + i); PHIReg += NumRegisters; } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 3ae70c850dae..e669a58f61a6 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -743,7 +743,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, unsigned LabelID = MMI->addLandingPad(BB); const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL); - BuildMI(BB, II).addImm(LabelID); + BuildMI(BB, DebugLoc::getUnknownLoc(), II).addImm(LabelID); // Mark exception register as live in. unsigned Reg = TLI.getExceptionAddressRegister(); -- GitLab From 143a2c3470bcbe33a713a92c41a9e5eeca919831 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 01:55:42 +0000 Subject: [PATCH 676/682] Use SDL->getCurDebugLoc() instead of unknown loc for landing pads. llvm-svn: 63594 --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index e669a58f61a6..4b166f862d1f 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -743,7 +743,7 @@ void SelectionDAGISel::SelectAllBasicBlocks(Function &Fn, unsigned LabelID = MMI->addLandingPad(BB); const TargetInstrDesc &II = TII.get(TargetInstrInfo::EH_LABEL); - BuildMI(BB, DebugLoc::getUnknownLoc(), II).addImm(LabelID); + BuildMI(BB, SDL->getCurDebugLoc(), II).addImm(LabelID); // Mark exception register as live in. unsigned Reg = TLI.getExceptionAddressRegister(); -- GitLab From db39362c905bc3f14692233d7ede45b4acfb3e9f Mon Sep 17 00:00:00 2001 From: Dale Johannesen Date: Tue, 3 Feb 2009 01:55:44 +0000 Subject: [PATCH 677/682] Fill in some missing DL propagation in getNode()s. llvm-svn: 63595 --- .../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 46 ++++++++++--------- 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp index 68dda9949158..c34211505ac2 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -854,8 +854,7 @@ SDValue SelectionDAG::getNOT(DebugLoc DL, SDValue Val, MVT VT) { SDValue NegOneElt = getConstant(APInt::getAllOnesValue(EltVT.getSizeInBits()), EltVT); std::vector NegOnes(VT.getVectorNumElements(), NegOneElt); - NegOne = getNode(ISD::BUILD_VECTOR, DebugLoc::getUnknownLoc(), VT, - &NegOnes[0], NegOnes.size()); + NegOne = getNode(ISD::BUILD_VECTOR, DL, VT, &NegOnes[0], NegOnes.size()); } else { NegOne = getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT); } @@ -2150,10 +2149,11 @@ bool SelectionDAG::isVerifiedDebugInfoDesc(SDValue Op) const { /// element of the result of the vector shuffle. SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) { MVT VT = N->getValueType(0); + DebugLoc dl = N->getDebugLoc(); SDValue PermMask = N->getOperand(2); SDValue Idx = PermMask.getOperand(i); if (Idx.getOpcode() == ISD::UNDEF) - return getNode(ISD::UNDEF, VT.getVectorElementType()); + return getNode(ISD::UNDEF, dl, VT.getVectorElementType()); unsigned Index = cast(Idx)->getZExtValue(); unsigned NumElems = PermMask.getNumOperands(); SDValue V = (Index < NumElems) ? N->getOperand(0) : N->getOperand(1); @@ -2167,7 +2167,7 @@ SDValue SelectionDAG::getShuffleScalarElt(const SDNode *N, unsigned i) { } if (V.getOpcode() == ISD::SCALAR_TO_VECTOR) return (Index == 0) ? V.getOperand(0) - : getNode(ISD::UNDEF, VT.getVectorElementType()); + : getNode(ISD::UNDEF, dl, VT.getVectorElementType()); if (V.getOpcode() == ISD::BUILD_VECTOR) return V.getOperand(Index); if (V.getOpcode() == ISD::VECTOR_SHUFFLE) @@ -2301,7 +2301,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, Operand.getValueType().isFloatingPoint() && "Invalid FP cast!"); if (Operand.getValueType() == VT) return Operand; // noop conversion. if (Operand.getOpcode() == ISD::UNDEF) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, DL, VT); break; case ISD::SIGN_EXTEND: assert(VT.isInteger() && Operand.getValueType().isInteger() && @@ -2310,7 +2310,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, assert(Operand.getValueType().bitsLT(VT) && "Invalid sext node, dst < src!"); if (OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ZERO_EXTEND) - return getNode(OpOpcode, VT, Operand.getNode()->getOperand(0)); + return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0)); break; case ISD::ZERO_EXTEND: assert(VT.isInteger() && Operand.getValueType().isInteger() && @@ -2319,7 +2319,8 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, assert(Operand.getValueType().bitsLT(VT) && "Invalid zext node, dst < src!"); if (OpOpcode == ISD::ZERO_EXTEND) // (zext (zext x)) -> (zext x) - return getNode(ISD::ZERO_EXTEND, VT, Operand.getNode()->getOperand(0)); + return getNode(ISD::ZERO_EXTEND, DL, VT, + Operand.getNode()->getOperand(0)); break; case ISD::ANY_EXTEND: assert(VT.isInteger() && Operand.getValueType().isInteger() && @@ -2329,7 +2330,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, && "Invalid anyext node, dst < src!"); if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND) // (ext (zext x)) -> (zext x) and (ext (sext x)) -> (sext x) - return getNode(OpOpcode, VT, Operand.getNode()->getOperand(0)); + return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0)); break; case ISD::TRUNCATE: assert(VT.isInteger() && Operand.getValueType().isInteger() && @@ -2338,14 +2339,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, assert(Operand.getValueType().bitsGT(VT) && "Invalid truncate node, src < dst!"); if (OpOpcode == ISD::TRUNCATE) - return getNode(ISD::TRUNCATE, VT, Operand.getNode()->getOperand(0)); + return getNode(ISD::TRUNCATE, DL, VT, Operand.getNode()->getOperand(0)); else if (OpOpcode == ISD::ZERO_EXTEND || OpOpcode == ISD::SIGN_EXTEND || OpOpcode == ISD::ANY_EXTEND) { // If the source is smaller than the dest, we still need an extend. if (Operand.getNode()->getOperand(0).getValueType().bitsLT(VT)) - return getNode(OpOpcode, VT, Operand.getNode()->getOperand(0)); + return getNode(OpOpcode, DL, VT, Operand.getNode()->getOperand(0)); else if (Operand.getNode()->getOperand(0).getValueType().bitsGT(VT)) - return getNode(ISD::TRUNCATE, VT, Operand.getNode()->getOperand(0)); + return getNode(ISD::TRUNCATE, DL, VT, Operand.getNode()->getOperand(0)); else return Operand.getNode()->getOperand(0); } @@ -2356,16 +2357,16 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, && "Cannot BIT_CONVERT between types of different sizes!"); if (VT == Operand.getValueType()) return Operand; // noop conversion. if (OpOpcode == ISD::BIT_CONVERT) // bitconv(bitconv(x)) -> bitconv(x) - return getNode(ISD::BIT_CONVERT, VT, Operand.getOperand(0)); + return getNode(ISD::BIT_CONVERT, DL, VT, Operand.getOperand(0)); if (OpOpcode == ISD::UNDEF) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, DL, VT); break; case ISD::SCALAR_TO_VECTOR: assert(VT.isVector() && !Operand.getValueType().isVector() && VT.getVectorElementType() == Operand.getValueType() && "Illegal SCALAR_TO_VECTOR node!"); if (OpOpcode == ISD::UNDEF) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, DL, VT); // scalar_to_vector(extract_vector_elt V, 0) -> V, top bits are undefined. if (OpOpcode == ISD::EXTRACT_VECTOR_ELT && isa(Operand.getOperand(1)) && @@ -2376,14 +2377,14 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, case ISD::FNEG: // -(X-Y) -> (Y-X) is unsafe because when X==Y, -0.0 != +0.0 if (UnsafeFPMath && OpOpcode == ISD::FSUB) - return getNode(ISD::FSUB, VT, Operand.getNode()->getOperand(1), + return getNode(ISD::FSUB, DL, VT, Operand.getNode()->getOperand(1), Operand.getNode()->getOperand(0)); if (OpOpcode == ISD::FNEG) // --X -> X return Operand.getNode()->getOperand(0); break; case ISD::FABS: if (OpOpcode == ISD::FNEG) // abs(-X) -> abs(X) - return getNode(ISD::FABS, VT, Operand.getNode()->getOperand(0)); + return getNode(ISD::FABS, DL, VT, Operand.getNode()->getOperand(0)); break; } @@ -2473,7 +2474,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, N2.getOpcode() == ISD::BUILD_VECTOR) { SmallVector Elts(N1.getNode()->op_begin(), N1.getNode()->op_end()); Elts.insert(Elts.end(), N2.getNode()->op_begin(), N2.getNode()->op_end()); - return getNode(ISD::BUILD_VECTOR, VT, &Elts[0], Elts.size()); + return getNode(ISD::BUILD_VECTOR, DL, VT, &Elts[0], Elts.size()); } break; case ISD::AND: @@ -2599,7 +2600,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, case ISD::EXTRACT_VECTOR_ELT: // EXTRACT_VECTOR_ELT of an UNDEF is an UNDEF. if (N1.getOpcode() == ISD::UNDEF) - return getNode(ISD::UNDEF, VT); + return getNode(ISD::UNDEF, DL, VT); // EXTRACT_VECTOR_ELT of CONCAT_VECTORS is often formed while lowering is // expanding copies of large vectors from registers. @@ -2608,7 +2609,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, N1.getNumOperands() > 0) { unsigned Factor = N1.getOperand(0).getValueType().getVectorNumElements(); - return getNode(ISD::EXTRACT_VECTOR_ELT, VT, + return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(N2C->getZExtValue() / Factor), getConstant(N2C->getZExtValue() % Factor, N2.getValueType())); @@ -2629,7 +2630,7 @@ SDValue SelectionDAG::getNode(unsigned Opcode, DebugLoc DL, MVT VT, // the original vector. else if (isa(N1.getOperand(2)) && isa(N2)) - return getNode(ISD::EXTRACT_VECTOR_ELT, VT, N1.getOperand(0), N2); + return getNode(ISD::EXTRACT_VECTOR_ELT, DL, VT, N1.getOperand(0), N2); } break; case ISD::EXTRACT_ELEMENT: @@ -2990,7 +2991,8 @@ static SDValue getMemsetStringVal(MVT VT, SelectionDAG &DAG, static SDValue getMemBasePlusOffset(SDValue Base, unsigned Offset, SelectionDAG &DAG) { MVT VT = Base.getValueType(); - return DAG.getNode(ISD::ADD, VT, Base, DAG.getConstant(Offset, VT)); + return DAG.getNode(ISD::ADD, Base.getNode()->getDebugLoc(), + VT, Base, DAG.getConstant(Offset, VT)); } /// isMemSrcFromString - Returns true if memcpy source is a string constant. @@ -4932,7 +4934,7 @@ SDNode *SelectionDAG::getTargetNode(unsigned Opcode, DebugLoc dl, MVT VT1, MVT VT2, MVT VT3, const SDValue *Ops, unsigned NumOps) { const MVT *VTs = getNodeValueTypes(VT1, VT2, VT3); - return getNode(~Opcode, VTs, 3, Ops, NumOps).getNode(); + return getNode(~Opcode, dl, VTs, 3, Ops, NumOps).getNode(); } SDNode *SelectionDAG::getTargetNode(unsigned Opcode, MVT VT1, -- GitLab From 6aa6b1f263e09f16f348bd65cd97ca1e1feba3da Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Feb 2009 02:01:43 +0000 Subject: [PATCH 678/682] Teach ConvertUsesToScalar to handle memset, allowing it to handle crazy cases like: struct f { int A, B, C, D, E, F; }; short test4() { struct f A; A.A = 1; memset(&A.B, 2, 12); return A.C; } llvm-svn: 63596 --- .../Scalar/ScalarReplAggregates.cpp | 76 ++++++++++++++----- .../Transforms/ScalarRepl/memset-aggregate.ll | 18 +++++ 2 files changed, 73 insertions(+), 21 deletions(-) diff --git a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp index 5031619b51cb..83572d65dae3 100644 --- a/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp +++ b/llvm/lib/Transforms/Scalar/ScalarReplAggregates.cpp @@ -130,8 +130,8 @@ namespace { void ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset); Value *ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, uint64_t Offset); - Value *ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, - uint64_t Offset); + Value *ConvertUsesOfStoreToScalar(Value *StoredVal, AllocaInst *NewAI, + uint64_t Offset, Instruction *InsertPt); static Instruction *isOnlyCopiedFromConstantGlobal(AllocationInst *AI); }; } @@ -1274,6 +1274,18 @@ bool SROA::CanConvertToScalar(Value *V, bool &IsNotTrivial, continue; } + // If this is a constant sized memset of a constant value (e.g. 0) we can + // handle it. + if (isa(User) && + // Store of constant value. + isa(User->getOperand(2)) && + // Store with constant size. + isa(User->getOperand(3))) { + VecTy = Type::VoidTy; + IsNotTrivial = true; + continue; + } + // Otherwise, we cannot handle this! return false; } @@ -1301,7 +1313,8 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { if (StoreInst *SI = dyn_cast(User)) { assert(SI->getOperand(0) != Ptr && "Consistency error!"); - new StoreInst(ConvertUsesOfStoreToScalar(SI, NewAI, Offset), NewAI, SI); + new StoreInst(ConvertUsesOfStoreToScalar(SI->getOperand(0), NewAI, + Offset, SI), NewAI, SI); SI->eraseFromParent(); continue; } @@ -1321,6 +1334,29 @@ void SROA::ConvertUsesToScalar(Value *Ptr, AllocaInst *NewAI, uint64_t Offset) { GEP->eraseFromParent(); continue; } + + // If this is a constant sized memset of a constant value (e.g. 0) we can + // transform it into a store of the expanded constant value. + if (MemSetInst *MSI = dyn_cast(User)) { + assert(MSI->getRawDest() == Ptr && "Consistency error!"); + unsigned NumBytes = cast(MSI->getLength())->getZExtValue(); + unsigned Val = cast(MSI->getValue())->getZExtValue(); + + // Compute the value replicated the right number of times. + APInt APVal(NumBytes*8, Val); + + // Splat the value if non-zero. + if (Val) + for (unsigned i = 1; i != NumBytes; ++i) + APVal |= APVal << 8; + + new StoreInst(ConvertUsesOfStoreToScalar(ConstantInt::get(APVal), NewAI, + Offset, MSI), NewAI, MSI); + MSI->eraseFromParent(); + continue; + } + + assert(0 && "Unsupported operation!"); abort(); } @@ -1422,40 +1458,38 @@ Value *SROA::ConvertUsesOfLoadToScalar(LoadInst *LI, AllocaInst *NewAI, /// /// Offset is an offset from the original alloca, in bits that need to be /// shifted to the right. By the end of this, there should be no uses of Ptr. -Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, - uint64_t Offset) { +Value *SROA::ConvertUsesOfStoreToScalar(Value *SV, AllocaInst *NewAI, + uint64_t Offset, Instruction *IP) { // Convert the stored type to the actual type, shift it left to insert // then 'or' into place. - Value *SV = SI->getOperand(0); const Type *AllocaType = NewAI->getType()->getElementType(); - if (SV->getType() == AllocaType && Offset == 0) { + if (SV->getType() == AllocaType && Offset == 0) return SV; - } if (const VectorType *VTy = dyn_cast(AllocaType)) { - Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); + Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", IP); // If the result alloca is a vector type, this is either an element // access or a bitcast to another vector type. if (isa(SV->getType())) { - SV = new BitCastInst(SV, AllocaType, SV->getName(), SI); + SV = new BitCastInst(SV, AllocaType, SV->getName(), IP); } else { // Must be an element insertion. unsigned Elt = Offset/TD->getTypePaddedSizeInBits(VTy->getElementType()); if (SV->getType() != VTy->getElementType()) - SV = new BitCastInst(SV, VTy->getElementType(), "tmp", SI); + SV = new BitCastInst(SV, VTy->getElementType(), "tmp", IP); SV = InsertElementInst::Create(Old, SV, ConstantInt::get(Type::Int32Ty, Elt), - "tmp", SI); + "tmp", IP); } return SV; } - Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", SI); + Value *Old = new LoadInst(NewAI, NewAI->getName()+".in", IP); // If SV is a float, convert it to the appropriate integer type. // If it is a pointer, do the same, and also handle ptr->ptr casts @@ -1465,19 +1499,19 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, unsigned SrcStoreWidth = TD->getTypeStoreSizeInBits(SV->getType()); unsigned DestStoreWidth = TD->getTypeStoreSizeInBits(AllocaType); if (SV->getType()->isFloatingPoint() || isa(SV->getType())) - SV = new BitCastInst(SV, IntegerType::get(SrcWidth), SV->getName(), SI); + SV = new BitCastInst(SV, IntegerType::get(SrcWidth), SV->getName(), IP); else if (isa(SV->getType())) - SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), SI); + SV = new PtrToIntInst(SV, TD->getIntPtrType(), SV->getName(), IP); // Zero extend or truncate the value if needed. if (SV->getType() != AllocaType) { if (SV->getType()->getPrimitiveSizeInBits() < AllocaType->getPrimitiveSizeInBits()) - SV = new ZExtInst(SV, AllocaType, SV->getName(), SI); + SV = new ZExtInst(SV, AllocaType, SV->getName(), IP); else { // Truncation may be needed if storing more than the alloca can hold // (undefined behavior). - SV = new TruncInst(SV, AllocaType, SV->getName(), SI); + SV = new TruncInst(SV, AllocaType, SV->getName(), IP); SrcWidth = DestWidth; SrcStoreWidth = DestStoreWidth; } @@ -1502,12 +1536,12 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, if (ShAmt > 0 && (unsigned)ShAmt < DestWidth) { SV = BinaryOperator::CreateShl(SV, ConstantInt::get(SV->getType(), ShAmt), - SV->getName(), SI); + SV->getName(), IP); Mask <<= ShAmt; } else if (ShAmt < 0 && (unsigned)-ShAmt < DestWidth) { SV = BinaryOperator::CreateLShr(SV, ConstantInt::get(SV->getType(), -ShAmt), - SV->getName(), SI); + SV->getName(), IP); Mask = Mask.lshr(-ShAmt); } @@ -1516,8 +1550,8 @@ Value *SROA::ConvertUsesOfStoreToScalar(StoreInst *SI, AllocaInst *NewAI, if (SrcWidth != DestWidth) { assert(DestWidth > SrcWidth); Old = BinaryOperator::CreateAnd(Old, ConstantInt::get(~Mask), - Old->getName()+".mask", SI); - SV = BinaryOperator::CreateOr(Old, SV, SV->getName()+".ins", SI); + Old->getName()+".mask", IP); + SV = BinaryOperator::CreateOr(Old, SV, SV->getName()+".ins", IP); } return SV; } diff --git a/llvm/test/Transforms/ScalarRepl/memset-aggregate.ll b/llvm/test/Transforms/ScalarRepl/memset-aggregate.ll index 4febda5b9a79..b7b33521bbce 100644 --- a/llvm/test/Transforms/ScalarRepl/memset-aggregate.ll +++ b/llvm/test/Transforms/ScalarRepl/memset-aggregate.ll @@ -1,6 +1,7 @@ ; PR1226 ; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | grep {ret i32 16843009} ; RUN: llvm-as < %s | opt -scalarrepl | llvm-dis | not grep alloca +; RUN: llvm-as < %s | opt -scalarrepl -instcombine | llvm-dis | grep {ret i16 514} target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64" target triple = "i686-apple-darwin8" @@ -46,3 +47,20 @@ entry: %tmp7 = load i32* %tmp6 ; [#uses=1] ret i32 %tmp7 } + + + %struct.f = type { i32, i32, i32, i32, i32, i32 } + +define i16 @test4() nounwind { +entry: + %A = alloca %struct.f, align 8 ; <%struct.f*> [#uses=3] + %0 = getelementptr %struct.f* %A, i32 0, i32 0 ; [#uses=1] + store i32 1, i32* %0, align 8 + %1 = getelementptr %struct.f* %A, i32 0, i32 1 ; [#uses=1] + %2 = bitcast i32* %1 to i8* ; [#uses=1] + call void @llvm.memset.i32(i8* %2, i8 2, i32 12, i32 4) + %3 = getelementptr %struct.f* %A, i32 0, i32 2 ; [#uses=1] + %4 = load i32* %3, align 8 ; [#uses=1] + %retval12 = trunc i32 %4 to i16 ; [#uses=1] + ret i16 %retval12 +} -- GitLab From fa4e35aca7dba138e9df5f6939238a91f2036486 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 3 Feb 2009 02:11:28 +0000 Subject: [PATCH 679/682] fix a bitcode reader bug where it can't handle extractelement correctly: the index of the value being extracted is always an i32. This fixes PR3465 llvm-svn: 63597 --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 3 +-- llvm/test/Bitcode/extractelement.ll | 8 ++++++++ 2 files changed, 9 insertions(+), 2 deletions(-) create mode 100644 llvm/test/Bitcode/extractelement.ll diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 87700284c483..adffe8292027 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -915,8 +915,7 @@ bool BitcodeReader::ParseConstants() { dyn_cast_or_null(getTypeByID(Record[0])); if (OpTy == 0) return Error("Invalid CE_EXTRACTELT record"); Constant *Op0 = ValueList.getConstantFwdRef(Record[1], OpTy); - Constant *Op1 = ValueList.getConstantFwdRef(Record[2], - OpTy->getElementType()); + Constant *Op1 = ValueList.getConstantFwdRef(Record[2], Type::Int32Ty); V = ConstantExpr::getExtractElement(Op0, Op1); break; } diff --git a/llvm/test/Bitcode/extractelement.ll b/llvm/test/Bitcode/extractelement.ll new file mode 100644 index 000000000000..04cb131f6e7f --- /dev/null +++ b/llvm/test/Bitcode/extractelement.ll @@ -0,0 +1,8 @@ +; RUN: llvm-as < %s | opt -constprop | llvm-dis +; PR3465 + +define double @test() { + %tmp24 = extractelement <2 x double> bitcast (<1 x i128> < i128 85070591730234615870450834276742070272 > to <2 x double>), i32 0 + ret double %tmp24 +} + -- GitLab From 135227a060a14062555c32ace1e2a158d153ecb9 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 02:20:52 +0000 Subject: [PATCH 680/682] Pass in something sensible for the debug location information when creating the initial PHI nodes of the machine function. llvm-svn: 63598 --- .../SelectionDAG/SelectionDAGBuild.cpp | 53 +++++++++++++++++-- .../CodeGen/SelectionDAG/SelectionDAGBuild.h | 3 +- .../CodeGen/SelectionDAG/SelectionDAGISel.cpp | 2 +- 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp index a67110ce9b98..87d6d2fa5c7a 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.cpp @@ -271,6 +271,7 @@ FunctionLoweringInfo::FunctionLoweringInfo(TargetLowering &tli) } void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf, + SelectionDAG &DAG, bool EnableFastISel) { Fn = &fn; MF = &mf; @@ -320,8 +321,53 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf, // Create Machine PHI nodes for LLVM PHI nodes, lowering them as // appropriate. PHINode *PN; - for (BasicBlock::iterator I = BB->begin();(PN = dyn_cast(I)); ++I){ - if (PN->use_empty()) continue; + DebugLoc DL; + for (BasicBlock::iterator + I = BB->begin(), E = BB->end(); I != E; ++I) { + if (CallInst *CI = dyn_cast(I)) { + if (Function *F = CI->getCalledFunction()) { + switch (F->getIntrinsicID()) { + default: break; + case Intrinsic::dbg_stoppoint: { + DwarfWriter *DW = DAG.getDwarfWriter(); + DbgStopPointInst *SPI = cast(I); + + if (DW && DW->ValidDebugInfo(SPI->getContext())) { + DICompileUnit CU(cast(SPI->getContext())); + unsigned SrcFile = DW->RecordSource(CU.getDirectory(), + CU.getFilename()); + unsigned idx = MF->getOrCreateDebugLocID(SrcFile, + SPI->getLine(), + SPI->getColumn()); + DL = DebugLoc::get(idx); + } + + break; + } + case Intrinsic::dbg_func_start: { + DwarfWriter *DW = DAG.getDwarfWriter(); + if (DW) { + DbgFuncStartInst *FSI = cast(I); + Value *SP = FSI->getSubprogram(); + + if (DW->ValidDebugInfo(SP)) { + DISubprogram Subprogram(cast(SP)); + DICompileUnit CU(Subprogram.getCompileUnit()); + unsigned SrcFile = DW->RecordSource(CU.getDirectory(), + CU.getFilename()); + unsigned Line = Subprogram.getLineNumber(); + DL = DebugLoc::get(MF->getOrCreateDebugLocID(SrcFile, Line, 0)); + } + } + + break; + } + } + } + } + + PN = dyn_cast(I); + if (!PN || PN->use_empty()) continue; unsigned PHIReg = ValueMap[PN]; assert(PHIReg && "PHI node does not have an assigned virtual register!"); @@ -333,8 +379,7 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf, unsigned NumRegisters = TLI.getNumRegisters(VT); const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); for (unsigned i = 0; i != NumRegisters; ++i) - BuildMI(MBB, DebugLoc::getUnknownLoc(), - TII->get(TargetInstrInfo::PHI), PHIReg + i); + BuildMI(MBB, DL, TII->get(TargetInstrInfo::PHI), PHIReg + i); PHIReg += NumRegisters; } } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h index 47aaf63c9102..487c796321fd 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuild.h @@ -95,7 +95,8 @@ public: /// set - Initialize this FunctionLoweringInfo with the given Function /// and its associated MachineFunction. /// - void set(Function &Fn, MachineFunction &MF, bool EnableFastISel); + void set(Function &Fn, MachineFunction &MF, SelectionDAG &DAG, + bool EnableFastISel); /// MBBMap - A mapping from LLVM basic blocks to their machine code entry. DenseMap MBBMap; diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp index 4b166f862d1f..9c53fc9362c0 100644 --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp @@ -313,7 +313,7 @@ bool SelectionDAGISel::runOnFunction(Function &Fn) { RegInfo = &MF->getRegInfo(); DOUT << "\n\n\n=== " << Fn.getName() << "\n"; - FuncInfo->set(Fn, *MF, EnableFastISel); + FuncInfo->set(Fn, *MF, *CurDAG, EnableFastISel); MachineModuleInfo *MMI = getAnalysisIfAvailable(); DwarfWriter *DW = getAnalysisIfAvailable(); CurDAG->init(*MF, MMI, DW); -- GitLab From 67cd395d4575ebf48bdf4fa4eda6eec7c2358cf3 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Tue, 3 Feb 2009 02:29:34 +0000 Subject: [PATCH 681/682] Explicitly pass in debug location information to BuildMI. llvm-svn: 63599 --- llvm/lib/CodeGen/GCStrategy.cpp | 3 ++- llvm/lib/CodeGen/PHIElimination.cpp | 2 +- llvm/lib/CodeGen/TargetInstrInfoImpl.cpp | 2 +- llvm/lib/CodeGen/VirtRegMap.cpp | 3 ++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/llvm/lib/CodeGen/GCStrategy.cpp b/llvm/lib/CodeGen/GCStrategy.cpp index 96b81226bd9f..b851c074c218 100644 --- a/llvm/lib/CodeGen/GCStrategy.cpp +++ b/llvm/lib/CodeGen/GCStrategy.cpp @@ -329,7 +329,8 @@ void MachineCodeAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { unsigned MachineCodeAnalysis::InsertLabel(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { unsigned Label = MMI->NextLabelID(); - BuildMI(MBB, MI, TII->get(TargetInstrInfo::GC_LABEL)).addImm(Label); + BuildMI(MBB, MI, MI->getDebugLoc(), + TII->get(TargetInstrInfo::GC_LABEL)).addImm(Label); return Label; } diff --git a/llvm/lib/CodeGen/PHIElimination.cpp b/llvm/lib/CodeGen/PHIElimination.cpp index 147ccab3a1e4..b32db2e062fa 100644 --- a/llvm/lib/CodeGen/PHIElimination.cpp +++ b/llvm/lib/CodeGen/PHIElimination.cpp @@ -166,7 +166,7 @@ void PNE::LowerAtomicPHINode(MachineBasicBlock &MBB, if (isSourceDefinedByImplicitDef(MPhi, MRI)) // If all sources of a PHI node are implicit_def, just emit an // implicit_def instead of a copy. - BuildMI(MBB, AfterPHIsIt, + BuildMI(MBB, AfterPHIsIt, MPhi->getDebugLoc(), TII->get(TargetInstrInfo::IMPLICIT_DEF), DestReg); else { IncomingReg = MF.getRegInfo().createVirtualRegister(RC); diff --git a/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp b/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp index c28b045b2ec5..a213400dcbdf 100644 --- a/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp +++ b/llvm/lib/CodeGen/TargetInstrInfoImpl.cpp @@ -44,7 +44,7 @@ MachineInstr *TargetInstrInfoImpl::commuteInstruction(MachineInstr *MI, unsigned Reg0 = ChangeReg0 ? Reg2 : MI->getOperand(0).getReg(); bool Reg0IsDead = MI->getOperand(0).isDead(); MachineFunction &MF = *MI->getParent()->getParent(); - return BuildMI(MF, MI->getDesc()) + return BuildMI(MF, MI->getDebugLoc(), MI->getDesc()) .addReg(Reg0, true, false, false, Reg0IsDead) .addReg(Reg2, false, false, Reg2IsKill) .addReg(Reg1, false, false, Reg1IsKill); diff --git a/llvm/lib/CodeGen/VirtRegMap.cpp b/llvm/lib/CodeGen/VirtRegMap.cpp index b35fc2c653a2..9cb580b9f0ab 100644 --- a/llvm/lib/CodeGen/VirtRegMap.cpp +++ b/llvm/lib/CodeGen/VirtRegMap.cpp @@ -1360,7 +1360,8 @@ void LocalSpiller::RewriteMBB(MachineBasicBlock &MBB, VirtRegMap &VRM) { unsigned RReg = SubIdx ? TRI->getSubReg(Phys, SubIdx) : Phys; MI.getOperand(i).setReg(RReg); if (VRM.isImplicitlyDefined(VirtReg)) - BuildMI(MBB, &MI, TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg); + BuildMI(MBB, &MI, MI.getDebugLoc(), + TII->get(TargetInstrInfo::IMPLICIT_DEF), RReg); continue; } -- GitLab From 12a130bd06ac94c20e1cf60c2ed9592c056c5e04 Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Tue, 3 Feb 2009 04:34:40 +0000 Subject: [PATCH 682/682] Update the callgraph when replacing InvokeInst with CallInst when inlining. llvm-svn: 63600 --- llvm/lib/Transforms/Utils/InlineFunction.cpp | 11 +++++-- .../Inline/2009-02-02-InvokeUpdateCG.ll | 32 +++++++++++++++++++ 2 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 llvm/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll diff --git a/llvm/lib/Transforms/Utils/InlineFunction.cpp b/llvm/lib/Transforms/Utils/InlineFunction.cpp index cee224aae524..eb136b503497 100644 --- a/llvm/lib/Transforms/Utils/InlineFunction.cpp +++ b/llvm/lib/Transforms/Utils/InlineFunction.cpp @@ -37,11 +37,12 @@ bool llvm::InlineFunction(InvokeInst *II, CallGraph *CG, const TargetData *TD) { /// in the body of the inlined function into invokes and turn unwind /// instructions into branches to the invoke unwind dest. /// -/// II is the invoke instruction begin inlined. FirstNewBlock is the first +/// II is the invoke instruction being inlined. FirstNewBlock is the first /// block of the inlined code (the last block is the end of the function), /// and InlineCodeInfo is information about the code that got inlined. static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, - ClonedCodeInfo &InlinedCodeInfo) { + ClonedCodeInfo &InlinedCodeInfo, + CallGraph *CG) { BasicBlock *InvokeDest = II->getUnwindDest(); std::vector InvokeDestPHIValues; @@ -93,6 +94,10 @@ static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock, // Make sure that anything using the call now uses the invoke! CI->replaceAllUsesWith(II); + // Update the callgraph. + if (CG) + (*CG)[Caller]->replaceCallSite(CI, II); + // Delete the unconditional branch inserted by splitBasicBlock BB->getInstList().pop_back(); Split->getInstList().pop_front(); // Delete the original call @@ -433,7 +438,7 @@ bool llvm::InlineFunction(CallSite CS, CallGraph *CG, const TargetData *TD) { // any inlined 'unwind' instructions into branches to the invoke exception // destination, and call instructions into invoke instructions. if (InvokeInst *II = dyn_cast(TheCall)) - HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo); + HandleInlinedInvoke(II, FirstNewBlock, InlinedFunctionInfo, CG); // If we cloned in _exactly one_ basic block, and if that block ends in a // return instruction, we splice the body of the inlined callee directly into diff --git a/llvm/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll b/llvm/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll new file mode 100644 index 000000000000..38d759656f26 --- /dev/null +++ b/llvm/test/Transforms/Inline/2009-02-02-InvokeUpdateCG.ll @@ -0,0 +1,32 @@ +; RUN: llvm-as < %s | opt -inline -prune-eh +; PR3367 + +define void @f2() { + invoke void @f6() + to label %ok1 unwind label %lpad1 + +ok1: + ret void + +lpad1: + invoke void @f4() + to label %ok2 unwind label %lpad2 + +ok2: + call void @f8() + unreachable + +lpad2: + unreachable +} + +declare void @f3() + +define void @f4() { + call void @f3() + ret void +} + +declare void @f6() nounwind + +declare void @f8() -- GitLab