gcc-4.5: Sync from OE

Remove unneeded patches. This should bring all the changes from OE
uptodate. Now we are left with syncing the changes from oe-core
then we will ready to push it into oe-core.

Signed-off-by: Khem Raj <raj.khem@gmail.com>
Signed-off-by: Koen Kooi <koen@dominion.thruhere.net>
This commit is contained in:
Khem Raj 2011-03-12 05:31:52 -08:00 committed by Koen Kooi
parent 6d9070a43a
commit 154d33a214
39 changed files with 9656 additions and 4413 deletions

View File

@ -12,9 +12,9 @@ LIC_FILES_CHKSUM = "file://COPYING;md5=59530bdf33659b29e73d4adb9f9f6552 \
file://COPYING.RUNTIME;md5=fe60d87048567d4fe8c8a0ed2448bcc8"
SRCREV = "168622"
SRCREV = "170880"
PV = "4.5"
INC_PR = "r31"
INC_PR = "r32"
# BINV should be incremented after updating to a revision
# after a minor gcc release (e.g. 4.5.1 or 4.5.2) has been made
@ -29,13 +29,14 @@ PR_append = "+svnr${SRCPV}"
SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
file://gcc-4.3.1-ARCH_FLAGS_FOR_TARGET.patch \
file://100-uclibc-conf.patch \
file://gcc-uclibc-locale-ctype_touplow_t.patch \
file://gcc-uclibc-locale-ctype_touplow_t.patch \
file://cache-amnesia.patch \
file://gcc-flags-for-build.patch \
file://libstdc++-emit-__cxa_end_cleanup-in-text.patch \
file://arm-bswapsi2.patch \
file://Makefile.in.patch \
file://gcc-armv4-pass-fix-v4bx-to-ld.patch \
file://sh4-multilib.patch \
file://arm-lib1funcs.as-fix-mismatch-between-conditions-of-an-IT-block.patch \
file://linaro/gcc-4.5-linaro-r99297.patch \
file://linaro/gcc-4.5-linaro-r99298.patch \
file://linaro/gcc-4.5-linaro-r99299.patch \
@ -156,55 +157,63 @@ SRC_URI = "svn://gcc.gnu.org/svn/gcc/branches;module=${BRANCH} \
file://linaro/gcc-4.5-linaro-r99442.patch \
file://linaro/gcc-4.5-linaro-r99443.patch \
file://linaro/gcc-4.5-linaro-r99444.patch \
file://linaro/gcc-4.5-linaro-r99448.patch \
file://linaro/gcc-4.5-linaro-r99449.patch \
file://linaro/gcc-4.5-linaro-r99450.patch \
file://linaro/gcc-4.5-linaro-r99451.patch \
file://linaro/gcc-4.5-linaro-r99452.patch \
file://linaro/gcc-4.5-linaro-r99453.patch \
file://linaro/gcc-4.5-linaro-r99454.patch \
file://linaro/gcc-4.5-linaro-r99455.patch \
file://linaro/gcc-4.5-linaro-r99449.patch \
file://linaro/gcc-4.5-linaro-r99450.patch \
file://linaro/gcc-4.5-linaro-r99451.patch \
file://linaro/gcc-4.5-linaro-r99452.patch \
file://linaro/gcc-4.5-linaro-r99453.patch \
file://linaro/gcc-4.5-linaro-r99454.patch \
file://linaro/gcc-4.5-linaro-r99455.patch \
file://linaro/gcc-4.5-linaro-r99464.patch \
file://linaro/gcc-4.5-linaro-r99465.patch \
file://linaro/gcc-4.5-linaro-r99466.patch \
file://linaro/gcc-4.5-linaro-r99468.patch \
file://linaro/gcc-4.5-linaro-r99473.patch \
file://linaro/gcc-4.5-linaro-r99474.patch \
file://linaro/gcc-4.5-linaro-r99475.patch \
file://linaro/gcc-4.5-linaro-r99478.patch \
file://linaro/gcc-4.5-linaro-r99479.patch \
file://linaro/gcc-4.5-linaro-r99480.patch \
file://linaro/gcc-4.5-linaro-r99481.patch \
file://linaro/gcc-4.5-linaro-r99482.patch \
file://linaro/gcc-4.5-linaro-r99483.patch \
file://more-epilogues.patch \
file://gcc-scalar-widening-pr45847.patch \
file://gcc-arm-volatile-bitfield-fix.patch \
file://gcc-arm-volatile-bitfield-fix.patch \
\
file://optional_libstdc.patch \
file://64bithack.patch \
file://optional_libstdc.patch \
file://64bithack.patch \
file://GPLUSPLUS_INCLUDE_DIR_with_sysroot.patch \
"
SRC_URI_append_sh3 = " file://sh3-installfix-fixheaders.patch;patch=1 "
"
# Language Overrides
FORTRAN = ""
JAVA = ""
rename_srcdir (){
mv ${WORKDIR}/${BRANCH} ${WORKDIR}/gcc-${PV}
}
do_unpack_append() {
bb.build.exec_func('rename_srcdir', d)
}
S = "${WORKDIR}/${BRANCH}"
#EXTRA_OECONF_BASE = " --enable-cheaders=c_std \
# --enable-libssp \
# --disable-bootstrap \
# --disable-libgomp \
# --disable-libmudflap"
EXTRA_OECONF_BASE = " --enable-lto \
--enable-libssp \
--disable-bootstrap \
--disable-libgomp \
--disable-libmudflap \
--enable-cheaders=c_global "
EXTRA_OECONF_BASE = "--enable-lto \
--enable-libssp \
--disable-bootstrap \
--disable-libgomp \
--disable-libmudflap \
--enable-cheaders=c_global "
EXTRA_OECONF_INITIAL = "--disable-libmudflap \
--disable-libgomp \
--disable-libssp \
--enable-decimal-float=no"
--disable-libgomp \
--disable-libssp \
--enable-decimal-float=no"
EXTRA_OECONF_INTERMEDIATE = "--disable-libmudflap \
--disable-libgomp \
--disable-libssp"
--disable-libgomp \
--disable-libssp"
EXTRA_OECONF_append_libc-uclibc = " --disable-decimal-float "
EXTRA_OECONF_append_mips64 = " --with-arch-64=mips64 --with-tune-64=mips64"
EXTRA_OECONF_append_mips64el = " --with-arch-64=mips64 --with-tune-64=mips64"

View File

@ -1,15 +0,0 @@
Corrects sub machine arch corectly
Index: gcc-4.5.0/gcc/config.gcc
===================================================================
--- gcc-4.5.0.orig/gcc/config.gcc 2010-06-25 10:17:43.809880847 -0700
+++ gcc-4.5.0/gcc/config.gcc 2010-06-25 10:38:09.689882136 -0700
@@ -2171,7 +2171,7 @@
;;
sh-*-elf* | sh[12346l]*-*-elf* | \
sh-*-symbianelf* | sh[12346l]*-*-symbianelf* | \
- sh-*-linux* | sh[2346lbe]*-*-linux* | \
+ sh*-*-linux* | sh[2346lbe]*-*-linux* | \
sh-*-netbsdelf* | shl*-*-netbsdelf* | sh5-*-netbsd* | sh5l*-*-netbsd* | \
sh64-*-netbsd* | sh64l*-*-netbsd*)
tmake_file="${tmake_file} sh/t-sh sh/t-elf"

File diff suppressed because it is too large Load Diff

View File

@ -1,233 +0,0 @@
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/c++locale_internal.h 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/c++locale_internal.h 2008-08-16 01:33:23.000000000 -0700
@@ -60,4 +60,49 @@
extern "C" __typeof(wctype_l) __wctype_l;
#endif
+# define __nl_langinfo_l nl_langinfo_l
+# define __strcoll_l strcoll_l
+# define __strftime_l strftime_l
+# define __strtod_l strtod_l
+# define __strtof_l strtof_l
+# define __strtold_l strtold_l
+# define __strxfrm_l strxfrm_l
+# define __newlocale newlocale
+# define __freelocale freelocale
+# define __duplocale duplocale
+# define __uselocale uselocale
+
+# ifdef _GLIBCXX_USE_WCHAR_T
+# define __iswctype_l iswctype_l
+# define __towlower_l towlower_l
+# define __towupper_l towupper_l
+# define __wcscoll_l wcscoll_l
+# define __wcsftime_l wcsftime_l
+# define __wcsxfrm_l wcsxfrm_l
+# define __wctype_l wctype_l
+# endif
+
+#else
+# define __nl_langinfo_l(N, L) nl_langinfo((N))
+# define __strcoll_l(S1, S2, L) strcoll((S1), (S2))
+# define __strtod_l(S, E, L) strtod((S), (E))
+# define __strtof_l(S, E, L) strtof((S), (E))
+# define __strtold_l(S, E, L) strtold((S), (E))
+# define __strxfrm_l(S1, S2, N, L) strxfrm((S1), (S2), (N))
+# warning should dummy __newlocale check for C|POSIX ?
+# define __newlocale(a, b, c) NULL
+# define __freelocale(a) ((void)0)
+# define __duplocale(a) __c_locale()
+//# define __uselocale ?
+//
+# ifdef _GLIBCXX_USE_WCHAR_T
+# define __iswctype_l(C, M, L) iswctype((C), (M))
+# define __towlower_l(C, L) towlower((C))
+# define __towupper_l(C, L) towupper((C))
+# define __wcscoll_l(S1, S2, L) wcscoll((S1), (S2))
+//# define __wcsftime_l(S, M, F, T, L) wcsftime((S), (M), (F), (T))
+# define __wcsxfrm_l(S1, S2, N, L) wcsxfrm((S1), (S2), (N))
+# define __wctype_l(S, L) wctype((S))
+# endif
+
#endif // GLIBC 2.3 and later
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/c_locale.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/c_locale.cc 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/c_locale.cc 2008-08-16 01:33:00.000000000 -0700
@@ -39,20 +39,6 @@
#include <langinfo.h>
#include <bits/c++locale_internal.h>
-#ifndef __UCLIBC_HAS_XLOCALE__
-#define __strtol_l(S, E, B, L) strtol((S), (E), (B))
-#define __strtoul_l(S, E, B, L) strtoul((S), (E), (B))
-#define __strtoll_l(S, E, B, L) strtoll((S), (E), (B))
-#define __strtoull_l(S, E, B, L) strtoull((S), (E), (B))
-#define __strtof_l(S, E, L) strtof((S), (E))
-#define __strtod_l(S, E, L) strtod((S), (E))
-#define __strtold_l(S, E, L) strtold((S), (E))
-#warning should dummy __newlocale check for C|POSIX ?
-#define __newlocale(a, b, c) NULL
-#define __freelocale(a) ((void)0)
-#define __duplocale(a) __c_locale()
-#endif
-
namespace std
{
template<>
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/collate_members.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/collate_members.cc 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/collate_members.cc 2008-08-16 01:30:31.000000000 -0700
@@ -36,13 +36,6 @@
#include <locale>
#include <bits/c++locale_internal.h>
-#ifndef __UCLIBC_HAS_XLOCALE__
-#define __strcoll_l(S1, S2, L) strcoll((S1), (S2))
-#define __strxfrm_l(S1, S2, N, L) strxfrm((S1), (S2), (N))
-#define __wcscoll_l(S1, S2, L) wcscoll((S1), (S2))
-#define __wcsxfrm_l(S1, S2, N, L) wcsxfrm((S1), (S2), (N))
-#endif
-
namespace std
{
// These are basically extensions to char_traits, and perhaps should
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/monetary_members.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/monetary_members.cc 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/monetary_members.cc 2008-08-16 01:30:31.000000000 -0700
@@ -43,10 +43,6 @@
#warning tailor for stub locale support
#endif
-#ifndef __UCLIBC_HAS_XLOCALE__
-#define __nl_langinfo_l(N, L) nl_langinfo((N))
-#endif
-
namespace std
{
// Construct and return valid pattern consisting of some combination of:
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/numeric_members.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/numeric_members.cc 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/numeric_members.cc 2008-08-16 01:30:31.000000000 -0700
@@ -41,9 +41,6 @@
#ifdef __UCLIBC_MJN3_ONLY__
#warning tailor for stub locale support
#endif
-#ifndef __UCLIBC_HAS_XLOCALE__
-#define __nl_langinfo_l(N, L) nl_langinfo((N))
-#endif
namespace std
{
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/time_members.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/time_members.cc 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/time_members.cc 2008-08-16 01:30:31.000000000 -0700
@@ -40,9 +40,6 @@
#ifdef __UCLIBC_MJN3_ONLY__
#warning tailor for stub locale support
#endif
-#ifndef __UCLIBC_HAS_XLOCALE__
-#define __nl_langinfo_l(N, L) nl_langinfo((N))
-#endif
namespace std
{
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/ctype_members.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/ctype_members.cc 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/ctype_members.cc 2008-08-16 01:30:31.000000000 -0700
@@ -38,13 +38,6 @@
#undef _LIBC
#include <bits/c++locale_internal.h>
-#ifndef __UCLIBC_HAS_XLOCALE__
-#define __wctype_l(S, L) wctype((S))
-#define __towupper_l(C, L) towupper((C))
-#define __towlower_l(C, L) towlower((C))
-#define __iswctype_l(C, M, L) iswctype((C), (M))
-#endif
-
namespace std
{
// NB: The other ctype<char> specializations are in src/locale.cc and
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/messages_members.cc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/messages_members.cc 2008-08-16 01:27:18.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/messages_members.cc 2008-08-16 01:30:31.000000000 -0700
@@ -39,13 +39,10 @@
#ifdef __UCLIBC_MJN3_ONLY__
#warning fix gettext stuff
#endif
-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
-extern "C" char *__dcgettext(const char *domainname,
- const char *msgid, int category);
#undef gettext
-#define gettext(msgid) __dcgettext(NULL, msgid, LC_MESSAGES)
+#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
+#define gettext(msgid) dcgettext(NULL, msgid, LC_MESSAGES)
#else
-#undef gettext
#define gettext(msgid) (msgid)
#endif
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/messages_members.h
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/messages_members.h 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/messages_members.h 2008-08-16 01:31:43.000000000 -0700
@@ -36,15 +36,11 @@
#ifdef __UCLIBC_MJN3_ONLY__
#warning fix prototypes for *textdomain funcs
#endif
-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
-extern "C" char *__textdomain(const char *domainname);
-extern "C" char *__bindtextdomain(const char *domainname,
- const char *dirname);
-#else
-#undef __textdomain
-#undef __bindtextdomain
-#define __textdomain(D) ((void)0)
-#define __bindtextdomain(D,P) ((void)0)
+#ifndef __UCLIBC_HAS_GETTEXT_AWARENESS__
+#undef textdomain
+#undef bindtextdomain
+#define textdomain(D) ((void)0)
+#define bindtextdomain(D,P) ((void)0)
#endif
// Non-virtual member functions.
@@ -70,7 +66,7 @@
messages<_CharT>::open(const basic_string<char>& __s, const locale& __loc,
const char* __dir) const
{
- __bindtextdomain(__s.c_str(), __dir);
+ bindtextdomain(__s.c_str(), __dir);
return this->do_open(__s, __loc);
}
@@ -90,7 +86,7 @@
{
// No error checking is done, assume the catalog exists and can
// be used.
- __textdomain(__s.c_str());
+ textdomain(__s.c_str());
return 0;
}
Index: gcc-4.3.1/libstdc++-v3/config/locale/uclibc/c_locale.h
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/config/locale/uclibc/c_locale.h 2008-08-16 01:29:20.000000000 -0700
+++ gcc-4.3.1/libstdc++-v3/config/locale/uclibc/c_locale.h 2008-08-16 01:30:31.000000000 -0700
@@ -68,6 +68,7 @@
{
extern "C" __typeof(uselocale) __uselocale;
}
+#define __uselocale uselocale
#endif
namespace std

View File

@ -1,48 +0,0 @@
--- gcc/libstdc++-v3/config/locale/uclibc/monetary_members.cc.uclibc200_wchar~ 2006-03-10 15:32:37 +0100
+++ gcc/libstdc++-v3/config/locale/uclibc/monetary_members.cc 2006-03-10 15:37:27 +0100
@@ -401,7 +401,7 @@
# ifdef __UCLIBC_HAS_XLOCALE__
_M_data->_M_decimal_point = __cloc->decimal_point_wc;
_M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
-# else
+# elif defined __UCLIBC_HAS_LOCALE__
_M_data->_M_decimal_point = __global_locale->decimal_point_wc;
_M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
# endif
@@ -556,7 +556,7 @@
# ifdef __UCLIBC_HAS_XLOCALE__
_M_data->_M_decimal_point = __cloc->decimal_point_wc;
_M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
-# else
+# elif defined __UCLIBC_HAS_LOCALE__
_M_data->_M_decimal_point = __global_locale->decimal_point_wc;
_M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
# endif
--- gcc/libstdc++-v3/config/locale/uclibc/numeric_members.cc.uclibc200_wchar~ 2006-03-10 15:32:37 +0100
+++ gcc/libstdc++-v3/config/locale/uclibc/numeric_members.cc 2006-03-10 15:37:27 +0100
@@ -127,12 +127,25 @@
{
// Named locale.
// NB: In the GNU model wchar_t is always 32 bit wide.
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning fix this... should be numeric
+#endif
+#ifdef __UCLIBC__
+# ifdef __UCLIBC_HAS_XLOCALE__
+ _M_data->_M_decimal_point = __cloc->decimal_point_wc;
+ _M_data->_M_thousands_sep = __cloc->thousands_sep_wc;
+# elif defined __UCLIBC_HAS_LOCALE__
+ _M_data->_M_decimal_point = __global_locale->decimal_point_wc;
+ _M_data->_M_thousands_sep = __global_locale->thousands_sep_wc;
+# endif
+#else
union { char *__s; wchar_t __w; } __u;
__u.__s = __nl_langinfo_l(_NL_NUMERIC_DECIMAL_POINT_WC, __cloc);
_M_data->_M_decimal_point = __u.__w;
__u.__s = __nl_langinfo_l(_NL_NUMERIC_THOUSANDS_SEP_WC, __cloc);
_M_data->_M_thousands_sep = __u.__w;
+#endif
if (_M_data->_M_thousands_sep == L'\0')
_M_data->_M_grouping = "";

View File

@ -1,519 +0,0 @@
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/c_locale.cc
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/c_locale.cc 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/c_locale.cc 2008-09-17 22:35:29.000000000 -0700
@@ -39,23 +39,20 @@
#include <langinfo.h>
#include <bits/c++locale_internal.h>
-namespace std
-{
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
template<>
void
__convert_to_v(const char* __s, float& __v, ios_base::iostate& __err,
const __c_locale& __cloc)
{
- if (!(__err & ios_base::failbit))
- {
- char* __sanity;
- errno = 0;
- float __f = __strtof_l(__s, &__sanity, __cloc);
- if (__sanity != __s && errno != ERANGE)
- __v = __f;
- else
- __err |= ios_base::failbit;
- }
+ char* __sanity;
+ errno = 0;
+ float __f = __strtof_l(__s, &__sanity, __cloc);
+ if (__sanity != __s && errno != ERANGE)
+ __v = __f;
+ else
+ __err |= ios_base::failbit;
}
template<>
@@ -63,16 +60,13 @@
__convert_to_v(const char* __s, double& __v, ios_base::iostate& __err,
const __c_locale& __cloc)
{
- if (!(__err & ios_base::failbit))
- {
- char* __sanity;
- errno = 0;
- double __d = __strtod_l(__s, &__sanity, __cloc);
- if (__sanity != __s && errno != ERANGE)
- __v = __d;
- else
- __err |= ios_base::failbit;
- }
+ char* __sanity;
+ errno = 0;
+ double __d = __strtod_l(__s, &__sanity, __cloc);
+ if (__sanity != __s && errno != ERANGE)
+ __v = __d;
+ else
+ __err |= ios_base::failbit;
}
template<>
@@ -80,16 +74,13 @@
__convert_to_v(const char* __s, long double& __v, ios_base::iostate& __err,
const __c_locale& __cloc)
{
- if (!(__err & ios_base::failbit))
- {
- char* __sanity;
- errno = 0;
- long double __ld = __strtold_l(__s, &__sanity, __cloc);
- if (__sanity != __s && errno != ERANGE)
- __v = __ld;
- else
- __err |= ios_base::failbit;
- }
+ char* __sanity;
+ errno = 0;
+ long double __ld = __strtold_l(__s, &__sanity, __cloc);
+ if (__sanity != __s && errno != ERANGE)
+ __v = __ld;
+ else
+ __err |= ios_base::failbit;
}
void
@@ -110,17 +101,18 @@
void
locale::facet::_S_destroy_c_locale(__c_locale& __cloc)
{
- if (_S_get_c_locale() != __cloc)
+ if (__cloc && _S_get_c_locale() != __cloc)
__freelocale(__cloc);
}
__c_locale
locale::facet::_S_clone_c_locale(__c_locale& __cloc)
{ return __duplocale(__cloc); }
-} // namespace std
-namespace __gnu_cxx
-{
+_GLIBCXX_END_NAMESPACE
+
+_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
+
const char* const category_names[6 + _GLIBCXX_NUM_CATEGORIES] =
{
"LC_CTYPE",
@@ -138,9 +130,11 @@
"LC_IDENTIFICATION"
#endif
};
-}
-namespace std
-{
+_GLIBCXX_END_NAMESPACE
+
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
const char* const* const locale::_S_categories = __gnu_cxx::category_names;
-} // namespace std
+
+_GLIBCXX_END_NAMESPACE
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/ctype_members.cc
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/ctype_members.cc 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/ctype_members.cc 2008-09-17 23:09:49.000000000 -0700
@@ -33,16 +33,20 @@
// Written by Benjamin Kosnik <bkoz@redhat.com>
+#include <features.h>
+#ifdef __UCLIBC_HAS_LOCALE__
#define _LIBC
#include <locale>
#undef _LIBC
+#else
+#include <locale>
+#endif
#include <bits/c++locale_internal.h>
-namespace std
-{
+_GLIBCXX_BEGIN_NAMESPACE(std)
+
// NB: The other ctype<char> specializations are in src/locale.cc and
// various /config/os/* files.
- template<>
ctype_byname<char>::ctype_byname(const char* __s, size_t __refs)
: ctype<char>(0, false, __refs)
{
@@ -57,6 +61,8 @@
#endif
}
}
+ ctype_byname<char>::~ctype_byname()
+ { }
#ifdef _GLIBCXX_USE_WCHAR_T
ctype<wchar_t>::__wmask_type
@@ -138,17 +144,33 @@
ctype<wchar_t>::
do_is(mask __m, wchar_t __c) const
{
- // Highest bitmask in ctype_base == 10, but extra in "C"
- // library for blank.
+ // The case of __m == ctype_base::space is particularly important,
+ // due to its use in many istream functions. Therefore we deal with
+ // it first, exploiting the knowledge that on GNU systems _M_bit[5]
+ // is the mask corresponding to ctype_base::space. NB: an encoding
+ // change would not affect correctness!
+
bool __ret = false;
- const size_t __bitmasksize = 11;
- for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
- if (__m & _M_bit[__bitcur]
- && __iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
- {
- __ret = true;
- break;
- }
+ if (__m == _M_bit[5])
+ __ret = __iswctype_l(__c, _M_wmask[5], _M_c_locale_ctype);
+ else
+ {
+ // Highest bitmask in ctype_base == 10, but extra in "C"
+ // library for blank.
+ const size_t __bitmasksize = 11;
+ for (size_t __bitcur = 0; __bitcur <= __bitmasksize; ++__bitcur)
+ if (__m & _M_bit[__bitcur])
+ {
+ if (__iswctype_l(__c, _M_wmask[__bitcur], _M_c_locale_ctype))
+ {
+ __ret = true;
+ break;
+ }
+ else if (__m == _M_bit[__bitcur])
+ break;
+ }
+ }
+
return __ret;
}
@@ -290,4 +312,5 @@
#endif
}
#endif // _GLIBCXX_USE_WCHAR_T
-}
+
+_GLIBCXX_END_NAMESPACE
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/messages_members.h
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/messages_members.h 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/messages_members.h 2008-09-17 23:13:34.000000000 -0700
@@ -53,12 +53,16 @@
template<typename _CharT>
messages<_CharT>::messages(__c_locale __cloc, const char* __s,
size_t __refs)
- : facet(__refs), _M_c_locale_messages(_S_clone_c_locale(__cloc)),
- _M_name_messages(__s)
+ : facet(__refs), _M_c_locale_messages(NULL),
+ _M_name_messages(NULL)
{
- char* __tmp = new char[std::strlen(__s) + 1];
- std::strcpy(__tmp, __s);
+ const size_t __len = std::strlen(__s) + 1;
+ char* __tmp = new char[__len];
+ std::memcpy(__tmp, __s, __len);
_M_name_messages = __tmp;
+
+ // Last to avoid leaking memory if new throws.
+ _M_c_locale_messages = _S_clone_c_locale(__cloc);
}
template<typename _CharT>
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/monetary_members.cc
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/monetary_members.cc 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/monetary_members.cc 2008-09-17 22:35:29.000000000 -0700
@@ -33,9 +33,14 @@
// Written by Benjamin Kosnik <bkoz@redhat.com>
+#include <features.h>
+#ifdef __UCLIBC_HAS_LOCALE__
#define _LIBC
#include <locale>
#undef _LIBC
+#else
+#include <locale>
+#endif
#include <bits/c++locale_internal.h>
#ifdef __UCLIBC_MJN3_ONLY__
@@ -206,7 +211,7 @@
}
break;
default:
- ;
+ __ret = pattern();
}
return __ret;
}
@@ -390,7 +395,9 @@
__c_locale __old = __uselocale(__cloc);
#else
// Switch to named locale so that mbsrtowcs will work.
- char* __old = strdup(setlocale(LC_ALL, NULL));
+ char* __old = setlocale(LC_ALL, NULL);
+ const size_t __llen = strlen(__old) + 1;
+ char* __sav = new char[__llen];
setlocale(LC_ALL, __name);
#endif
@@ -477,8 +484,8 @@
#ifdef __UCLIBC_HAS_XLOCALE__
__uselocale(__old);
#else
- setlocale(LC_ALL, __old);
- free(__old);
+ setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
__throw_exception_again;
}
@@ -498,8 +505,8 @@
#ifdef __UCLIBC_HAS_XLOCALE__
__uselocale(__old);
#else
- setlocale(LC_ALL, __old);
- free(__old);
+ setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
}
}
@@ -545,8 +552,11 @@
__c_locale __old = __uselocale(__cloc);
#else
// Switch to named locale so that mbsrtowcs will work.
- char* __old = strdup(setlocale(LC_ALL, NULL));
- setlocale(LC_ALL, __name);
+ char* __old = setlocale(LC_ALL, NULL);
+ const size_t __llen = strlen(__old) + 1;
+ char* __sav = new char[__llen];
+ memcpy(__sav, __old, __llen);
+ setlocale(LC_ALL, __name);
#endif
#ifdef __UCLIBC_MJN3_ONLY__
@@ -633,8 +643,8 @@
#ifdef __UCLIBC_HAS_XLOCALE__
__uselocale(__old);
#else
- setlocale(LC_ALL, __old);
- free(__old);
+ setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
__throw_exception_again;
}
@@ -653,8 +663,8 @@
#ifdef __UCLIBC_HAS_XLOCALE__
__uselocale(__old);
#else
- setlocale(LC_ALL, __old);
- free(__old);
+ setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
}
}
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/numeric_members.cc
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/numeric_members.cc 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/numeric_members.cc 2008-09-17 22:35:29.000000000 -0700
@@ -33,9 +33,14 @@
// Written by Benjamin Kosnik <bkoz@redhat.com>
+#include <features.h>
+#ifdef __UCLIBC_HAS_LOCALE__
#define _LIBC
#include <locale>
#undef _LIBC
+#else
+#include <locale>
+#endif
#include <bits/c++locale_internal.h>
#ifdef __UCLIBC_MJN3_ONLY__
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/time_members.h
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/time_members.h 2008-09-17 22:35:27.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/time_members.h 2008-09-17 23:13:34.000000000 -0700
@@ -50,12 +50,21 @@
__timepunct<_CharT>::__timepunct(__c_locale __cloc, const char* __s,
size_t __refs)
: facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
- _M_name_timepunct(__s)
+ _M_name_timepunct(NULL)
{
- char* __tmp = new char[std::strlen(__s) + 1];
- std::strcpy(__tmp, __s);
+ const size_t __len = std::strlen(__s) + 1;
+ char* __tmp = new char[__len];
+ std::memcpy(__tmp, __s, __len);
_M_name_timepunct = __tmp;
- _M_initialize_timepunct(__cloc);
+
+ try
+ { _M_initialize_timepunct(__cloc); }
+ catch(...)
+ {
+ delete [] _M_name_timepunct;
+ __throw_exception_again;
+ }
+
}
template<typename _CharT>
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/c_locale.h
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/c_locale.h 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/c_locale.h 2008-09-17 22:35:29.000000000 -0700
@@ -39,21 +39,23 @@
#pragma GCC system_header
#include <cstring> // get std::strlen
-#include <cstdio> // get std::snprintf or std::sprintf
+#include <cstdio> // get std::vsnprintf or std::vsprintf
#include <clocale>
#include <langinfo.h> // For codecvt
#ifdef __UCLIBC_MJN3_ONLY__
#warning fix this
#endif
-#ifdef __UCLIBC_HAS_LOCALE__
+#ifdef _GLIBCXX_USE_ICONV
#include <iconv.h> // For codecvt using iconv, iconv_t
#endif
-#ifdef __UCLIBC_HAS_GETTEXT_AWARENESS__
-#include <libintl.h> // For messages
+#ifdef HAVE_LIBINTL_H
+#include <libintl.h> // For messages
#endif
+#include <cstdarg>
#ifdef __UCLIBC_MJN3_ONLY__
#warning what is _GLIBCXX_C_LOCALE_GNU for
+// psm: used in os/gnu-linux/ctype_noninline.h
#endif
#define _GLIBCXX_C_LOCALE_GNU 1
@@ -78,23 +80,25 @@
#else
typedef int* __c_locale;
#endif
-
- // Convert numeric value of type _Tv to string and return length of
- // string. If snprintf is available use it, otherwise fall back to
- // the unsafe sprintf which, in general, can be dangerous and should
+ // Convert numeric value of type double to string and return length of
+ // string. If vsnprintf is available use it, otherwise fall back to
+ // the unsafe vsprintf which, in general, can be dangerous and should
// be avoided.
- template<typename _Tv>
- int
- __convert_from_v(char* __out,
- const int __size __attribute__ ((__unused__)),
- const char* __fmt,
-#ifdef __UCLIBC_HAS_XCLOCALE__
- _Tv __v, const __c_locale& __cloc, int __prec)
+ inline int
+ __convert_from_v(const __c_locale&
+#ifndef __UCLIBC_HAS_XCLOCALE__
+ __cloc __attribute__ ((__unused__))
+#endif
+ ,
+ char* __out,
+ const int __size,
+ const char* __fmt, ...)
{
+ va_list __args;
+#ifdef __UCLIBC_HAS_XCLOCALE__
+
__c_locale __old = __gnu_cxx::__uselocale(__cloc);
#else
- _Tv __v, const __c_locale&, int __prec)
- {
# ifdef __UCLIBC_HAS_LOCALE__
char* __old = std::setlocale(LC_ALL, NULL);
char* __sav = new char[std::strlen(__old) + 1];
@@ -103,7 +107,9 @@
# endif
#endif
- const int __ret = std::snprintf(__out, __size, __fmt, __prec, __v);
+ va_start(__args, __fmt);
+ const int __ret = std::vsnprintf(__out, __size, __fmt, __args);
+ va_end(__args);
#ifdef __UCLIBC_HAS_XCLOCALE__
__gnu_cxx::__uselocale(__old);
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/time_members.cc
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/time_members.cc 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/time_members.cc 2008-09-17 22:35:29.000000000 -0700
@@ -53,11 +53,14 @@
const size_t __len = __strftime_l(__s, __maxlen, __format, __tm,
_M_c_locale_timepunct);
#else
- char* __old = strdup(setlocale(LC_ALL, NULL));
+ char* __old = setlocale(LC_ALL, NULL);
+ const size_t __llen = strlen(__old) + 1;
+ char* __sav = new char[__llen];
+ memcpy(__sav, __old, __llen);
setlocale(LC_ALL, _M_name_timepunct);
const size_t __len = strftime(__s, __maxlen, __format, __tm);
- setlocale(LC_ALL, __old);
- free(__old);
+ setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
// Make sure __s is null terminated.
if (__len == 0)
@@ -207,11 +210,14 @@
const size_t __len = __wcsftime_l(__s, __maxlen, __format, __tm,
_M_c_locale_timepunct);
#else
- char* __old = strdup(setlocale(LC_ALL, NULL));
+ char* __old = setlocale(LC_ALL, NULL);
+ const size_t __llen = strlen(__old) + 1;
+ char* __sav = new char[__llen];
+ memcpy(__sav, __old, __llen);
setlocale(LC_ALL, _M_name_timepunct);
const size_t __len = wcsftime(__s, __maxlen, __format, __tm);
- setlocale(LC_ALL, __old);
- free(__old);
+ setlocale(LC_ALL, __sav);
+ delete [] __sav;
#endif
// Make sure __s is null terminated.
if (__len == 0)
Index: gcc-4.3.2/libstdc++-v3/config/locale/uclibc/c++locale_internal.h
===================================================================
--- gcc-4.3.2.orig/libstdc++-v3/config/locale/uclibc/c++locale_internal.h 2008-09-17 22:35:28.000000000 -0700
+++ gcc-4.3.2/libstdc++-v3/config/locale/uclibc/c++locale_internal.h 2008-09-17 22:35:29.000000000 -0700
@@ -31,6 +31,9 @@
#include <bits/c++config.h>
#include <clocale>
+#include <cstdlib>
+#include <cstring>
+#include <cstddef>
#ifdef __UCLIBC_MJN3_ONLY__
#warning clean this up

View File

@ -1,13 +0,0 @@
Index: gcc-4.5.0/boehm-gc/include/gc.h
===================================================================
--- gcc-4.5.0.orig/boehm-gc/include/gc.h 2007-04-23 14:10:09.000000000 -0700
+++ gcc-4.5.0/boehm-gc/include/gc.h 2010-06-25 10:49:12.768883509 -0700
@@ -503,7 +503,7 @@
#if defined(__linux__) || defined(__GLIBC__)
# include <features.h>
# if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1 || __GLIBC__ > 2) \
- && !defined(__ia64__)
+ && !defined(__ia64__) && !defined(__UCLIBC__)
# ifndef GC_HAVE_BUILTIN_BACKTRACE
# define GC_HAVE_BUILTIN_BACKTRACE
# endif

View File

@ -1,13 +0,0 @@
Index: gcc-4.5.0/libstdc++-v3/include/c_std/cstdio
===================================================================
--- gcc-4.5.0.orig/libstdc++-v3/include/c_std/cstdio 2010-02-04 10:20:34.000000000 -0800
+++ gcc-4.5.0/libstdc++-v3/include/c_std/cstdio 2010-06-25 10:51:12.712631679 -0700
@@ -139,7 +139,7 @@
_GLIBCXX_END_NAMESPACE
-#if _GLIBCXX_USE_C99
+#if _GLIBCXX_USE_C99 || defined(__UCLIBC__)
#undef snprintf
#undef vfscanf

View File

@ -1,14 +0,0 @@
Index: gcc-4.5.0/libstdc++-v3/configure
===================================================================
--- gcc-4.5.0.orig/libstdc++-v3/configure 2010-06-25 10:48:37.488384191 -0700
+++ gcc-4.5.0/libstdc++-v3/configure 2010-06-25 10:51:23.804380413 -0700
@@ -18262,6 +18262,9 @@
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <complex.h>
+#ifdef __UCLIBC__
+#error ugly hack to make sure configure test fails here for cross until uClibc supports the complex funcs
+#endif
int
main ()
{

View File

@ -1,28 +0,0 @@
Index: gcc-4.5.0/libstdc++-v3/include/ext/rope
===================================================================
--- gcc-4.5.0.orig/libstdc++-v3/include/ext/rope 2009-04-09 08:00:19.000000000 -0700
+++ gcc-4.5.0/libstdc++-v3/include/ext/rope 2010-06-25 10:51:33.613383077 -0700
@@ -54,6 +54,9 @@
#include <bits/gthr.h>
#include <tr1/functional>
+/* cope w/ index defined as macro, SuSv3 proposal */
+#undef index
+
# ifdef __GC
# define __GC_CONST const
# else
Index: gcc-4.5.0/libstdc++-v3/include/ext/ropeimpl.h
===================================================================
--- gcc-4.5.0.orig/libstdc++-v3/include/ext/ropeimpl.h 2009-04-09 08:00:19.000000000 -0700
+++ gcc-4.5.0/libstdc++-v3/include/ext/ropeimpl.h 2010-06-25 10:51:33.621381669 -0700
@@ -49,6 +49,9 @@
#include <ext/memory> // For uninitialized_copy_n
#include <ext/numeric> // For power
+/* cope w/ index defined as macro, SuSv3 proposal */
+#undef index
+
_GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx)
using std::size_t;

View File

@ -1,49 +0,0 @@
Index: gcc-4.5.0/libmudflap/mf-hooks2.c
===================================================================
--- gcc-4.5.0.orig/libmudflap/mf-hooks2.c 2009-04-09 08:00:19.000000000 -0700
+++ gcc-4.5.0/libmudflap/mf-hooks2.c 2010-06-25 10:52:13.937636901 -0700
@@ -421,7 +421,7 @@
{
TRACE ("%s\n", __PRETTY_FUNCTION__);
MF_VALIDATE_EXTENT(s, n, __MF_CHECK_WRITE, "bzero region");
- bzero (s, n);
+ memset (s, 0, n);
}
@@ -431,7 +431,7 @@
TRACE ("%s\n", __PRETTY_FUNCTION__);
MF_VALIDATE_EXTENT(src, n, __MF_CHECK_READ, "bcopy src");
MF_VALIDATE_EXTENT(dest, n, __MF_CHECK_WRITE, "bcopy dest");
- bcopy (src, dest, n);
+ memmove (dest, src, n);
}
@@ -441,7 +441,7 @@
TRACE ("%s\n", __PRETTY_FUNCTION__);
MF_VALIDATE_EXTENT(s1, n, __MF_CHECK_READ, "bcmp 1st arg");
MF_VALIDATE_EXTENT(s2, n, __MF_CHECK_READ, "bcmp 2nd arg");
- return bcmp (s1, s2, n);
+ return n == 0 ? 0 : memcmp (s1, s2, n);
}
@@ -450,7 +450,7 @@
size_t n = strlen (s);
TRACE ("%s\n", __PRETTY_FUNCTION__);
MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "index region");
- return index (s, c);
+ return strchr (s, c);
}
@@ -459,7 +459,7 @@
size_t n = strlen (s);
TRACE ("%s\n", __PRETTY_FUNCTION__);
MF_VALIDATE_EXTENT(s, CLAMPADD(n, 1), __MF_CHECK_READ, "rindex region");
- return rindex (s, c);
+ return strrchr (s, c);
}
/* XXX: stpcpy, memccpy */

View File

@ -1,38 +0,0 @@
Index: gcc-4.5.0/libstdc++-v3/config/locale/uclibc/messages_members.h
===================================================================
--- gcc-4.5.0.orig/libstdc++-v3/config/locale/uclibc/messages_members.h 2010-06-25 10:49:07.024632961 -0700
+++ gcc-4.5.0/libstdc++-v3/config/locale/uclibc/messages_members.h 2010-06-25 10:52:33.980632645 -0700
@@ -32,7 +32,8 @@
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
-
+namespace std
+{
#ifdef __UCLIBC_MJN3_ONLY__
#warning fix prototypes for *textdomain funcs
#endif
@@ -116,3 +117,4 @@
this->_S_create_c_locale(this->_M_c_locale_messages, __s);
}
}
+}
Index: gcc-4.5.0/libstdc++-v3/config/locale/uclibc/time_members.h
===================================================================
--- gcc-4.5.0.orig/libstdc++-v3/config/locale/uclibc/time_members.h 2010-06-25 10:49:07.024632961 -0700
+++ gcc-4.5.0/libstdc++-v3/config/locale/uclibc/time_members.h 2010-06-25 10:52:33.980632645 -0700
@@ -33,7 +33,8 @@
//
// Written by Benjamin Kosnik <bkoz@redhat.com>
-
+namespace std
+{
template<typename _CharT>
__timepunct<_CharT>::__timepunct(size_t __refs)
: facet(__refs), _M_data(NULL), _M_c_locale_timepunct(NULL),
@@ -75,3 +76,4 @@
delete _M_data;
_S_destroy_c_locale(_M_c_locale_timepunct);
}
+}

View File

@ -1,19 +0,0 @@
This patch fixes a bug into ostream::operator<<(double) due to the wrong size
passed into the __convert_from_v method. The wrong size is then passed to
std::snprintf function, that, on uClibc, doens't handle sized 0 buffer.
Signed-off-by: Carmelo Amoroso <carmelo.amoroso@st.com>
Index: gcc-4.3.1/libstdc++-v3/include/bits/locale_facets.tcc
===================================================================
--- gcc-4.3.1.orig/libstdc++-v3/include/bits/locale_facets.tcc 2007-11-26 17:59:41.000000000 -0800
+++ gcc-4.3.1/libstdc++-v3/include/bits/locale_facets.tcc 2008-08-16 02:14:48.000000000 -0700
@@ -1004,7 +1004,7 @@
const int __cs_size = __fixed ? __max_exp + __prec + 4
: __max_digits * 2 + __prec;
char* __cs = static_cast<char*>(__builtin_alloca(__cs_size));
- __len = std::__convert_from_v(_S_get_c_locale(), __cs, 0, __fbuf,
+ __len = std::__convert_from_v(_S_get_c_locale(), __cs, __cs_size, __fbuf,
__prec, __v);
#endif

View File

@ -1,13 +0,0 @@
Index: gcc-4.5/gcc/config/arm/arm.md
===================================================================
--- gcc-4.5.orig/gcc/config/arm/arm.md 2010-06-17 09:13:07.000000000 -0700
+++ gcc-4.5/gcc/config/arm/arm.md 2010-06-22 08:08:45.397212002 -0700
@@ -11267,7 +11267,7 @@
(define_expand "bswapsi2"
[(set (match_operand:SI 0 "s_register_operand" "=r")
(bswap:SI (match_operand:SI 1 "s_register_operand" "r")))]
-"TARGET_EITHER"
+"TARGET_EITHER && (arm_arch6 && !optimize_size)"
"
if (!arm_arch6)
{

View File

@ -0,0 +1,18 @@
Fix for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43999
http://patchwork.ozlabs.org/patch/72260/ is the patch that made into
upstream gcc
diff --git a/gcc/config/arm/lib1funcs.asm b/gcc/config/arm/lib1funcs.asm
index 085e690..2e76c01 100644
--- a/gcc/config/arm/lib1funcs.asm
+++ b/gcc/config/arm/lib1funcs.asm
@@ -641,7 +641,7 @@ pc .req r15
subhs \dividend, \dividend, \divisor, lsr #3
orrhs \result, \result, \curbit, lsr #3
cmp \dividend, #0 @ Early termination?
- do_it hs, t
+ do_it ne, t
movnes \curbit, \curbit, lsr #4 @ No, any more bits to do?
movne \divisor, \divisor, lsr #4
bne 1b

View File

@ -1,24 +0,0 @@
# Dimitry Andric <dimitry@andric.com>, 2004-05-01
#
# * Removed the extra -lfloat option from LIBGCC_SPEC, since it isn't needed
# anymore. (The required functions are now in libgcc.)
#
# Fixes errors like
# arm-softfloat-linux-gnu/3.4.0/../../../../arm-softfloat-linux-gnu/bin/ld: cannot find -lfloat
# collect2: ld returned 1 exit status
# make[2]: *** [arm-softfloat-linux-gnu/gcc-3.4.0-glibc-2.3.2/build-glibc/iconvdata/ISO8859-1.so] Error 1
# when building glibc-2.3.3 with gcc-3.4.0 for arm-softfloat
Index: gcc-4.5.0/gcc/config/arm/linux-elf.h
===================================================================
--- gcc-4.5.0.orig/gcc/config/arm/linux-elf.h 2010-06-25 11:04:49.572437901 -0700
+++ gcc-4.5.0/gcc/config/arm/linux-elf.h 2010-06-25 11:06:12.273162283 -0700
@@ -60,7 +60,7 @@
%{shared:-lc} \
%{!shared:%{profile:-lc_p}%{!profile:-lc}}"
-#define LIBGCC_SPEC "%{msoft-float:-lfloat} %{mfloat-abi=soft*:-lfloat} -lgcc"
+#define LIBGCC_SPEC "-lgcc"
#define GLIBC_DYNAMIC_LINKER "/lib/ld-linux.so.2"

View File

@ -1,16 +0,0 @@
Index: gcc-4.5.0/gcc/config/arm/t-linux
===================================================================
--- gcc-4.5.0.orig/gcc/config/arm/t-linux 2009-04-21 12:03:23.000000000 -0700
+++ gcc-4.5.0/gcc/config/arm/t-linux 2010-06-25 11:11:06.836381365 -0700
@@ -23,7 +23,10 @@
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx _clzsi2 _clzdi2 \
- _arm_addsubdf3 _arm_addsubsf3
+ _negdf2 _addsubdf3 _muldivdf3 _cmpdf2 _unorddf2 _fixdfsi _fixunsdfsi \
+ _truncdfsf2 _negsf2 _addsubsf3 _muldivsf3 _cmpsf2 _unordsf2 \
+ _fixsfsi _fixunssfsi _floatdidf _floatdisf _floatundisf _floatundidf
+# _arm_addsubdf3 _arm_addsubsf3
# MULTILIB_OPTIONS = mhard-float/msoft-float
# MULTILIB_DIRNAMES = hard-float soft-float

View File

@ -1,114 +0,0 @@
Before committing, I noticed that PR/32161 was marked as a dup of PR/32009, but my previous patch did not fix it.
This alternative patch is better because it lets you just use CFLAGS_FOR_TARGET to set the compilation flags for libgcc. Since bootstrapped target libraries are never compiled with the native compiler, it makes little sense to use different flags for stage1 and later stages. And it also makes little sense to use a different variable than CFLAGS_FOR_TARGET.
Other changes I had to do include:
- moving the creation of default CFLAGS_FOR_TARGET from Makefile.am to configure.ac, because otherwise the BOOT_CFLAGS are substituted into CFLAGS_FOR_TARGET (which is "-O2 -g $(CFLAGS)") via $(CFLAGS). It is also cleaner this way though.
- passing the right CFLAGS to configure scripts as exported environment variables
I also stopped passing LIBCFLAGS to configure scripts since they are unused in the whole src tree. And I updated the documentation as H-P reminded me to do.
Bootstrapped/regtested i686-pc-linux-gnu, will commit to 4.4 shortly. Ok for 4.3?
Paolo
2008-02-19 Paolo Bonzini <bonzini@gnu.org>
PR bootstrap/32009
PR bootstrap/32161
* configure.ac (CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET): Compute here.
* configure: Regenerate.
* Makefile.def: Define stage_libcflags for all bootstrap stages.
* Makefile.tpl (BOOT_LIBCFLAGS, STAGE2_LIBCFLAGS, STAGE3_LIBCFLAGS,
STAGE4_LIBCFLAGS): New.
(CFLAGS_FOR_TARGET, CXXFLAGS_FOR_TARGET): Subst from autoconf, without
$(SYSROOT_CFLAGS_FOR_TARGET) and $(DEBUG_PREFIX_CFLAGS_FOR_TARGET).
(BASE_TARGET_EXPORTS): Append them here to C{,XX}FLAGS.
(EXTRA_TARGET_FLAGS): Append them here to {LIB,}C{,XX}FLAGS.
(configure-stage[+id+]-[+prefix+][+module+]): Pass stage_libcflags
for target modules. Don't export LIBCFLAGS.
(all-stage[+id+]-[+prefix+][+module+]): Pass stage_libcflags; pass
$(BASE_FLAGS_TO_PASS) where [+args+] was passed, and [+args+] after
the overridden CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET.
(invocations of `all'): Replace $(TARGET_FLAGS_TO_PASS) with
$(EXTRA_TARGET_FLAGS), $(FLAGS_TO_PASS) with $(EXTRA_HOST_FLAGS).
* Makefile.in: Regenerate.
config:
2008-02-19 Paolo Bonzini <bonzini@gnu.org>
PR bootstrap/32009
* mh-ppc-darwin (BOOT_CFLAGS): Reenable.
gcc:
2008-02-19 Paolo Bonzini <bonzini@gnu.org>
PR bootstrap/32009
* doc/install.texi: Correct references to CFLAGS, replacing them
with BOOT_CFLAGS. Document flags used during bootstrap for
target libraries.
---
Makefile.def | 25
Makefile.in | 1845 ++++++++++++++++++++++++++++++-------------------
Makefile.tpl | 91 +-
config/mh-ppc-darwin | 3
configure | 36
configure.ac | 32
gcc/Makefile.in | 2
gcc/configure | 6
gcc/configure.ac | 3
gcc/doc/install.texi | 56 -
libiberty/Makefile.in | 162 ++--
libiberty/configure | 46 -
libiberty/configure.ac | 43 -
13 files changed, 1454 insertions(+), 896 deletions(-)
Index: gcc-4.5.0/configure
===================================================================
--- gcc-4.5.0.orig/configure 2010-06-25 14:51:59.409382073 -0700
+++ gcc-4.5.0/configure 2010-06-25 14:52:35.157132702 -0700
@@ -7130,6 +7130,38 @@
fi
+# During gcc bootstrap, if we use some random cc for stage1 then CFLAGS
+# might be empty or "-g". We don't require a C++ compiler, so CXXFLAGS
+# might also be empty (or "-g", if a non-GCC C++ compiler is in the path).
+# We want to ensure that TARGET libraries (which we know are built with
+# gcc) are built with "-O2 -g", so include those options when setting
+# CFLAGS_FOR_TARGET and CXXFLAGS_FOR_TARGET.
+if test "x$CFLAGS_FOR_TARGET" = x; then
+ CFLAGS_FOR_TARGET=$CFLAGS
+ case " $CFLAGS " in
+ *" -O2 "*) ;;
+ *) CFLAGS_FOR_TARGET="-O2 $CFLAGS" ;;
+ esac
+ case " $CFLAGS " in
+ *" -g "* | *" -g3 "*) ;;
+ *) CFLAGS_FOR_TARGET="-g $CFLAGS" ;;
+ esac
+fi
+
+
+if test "x$CXXFLAGS_FOR_TARGET" = x; then
+ CXXFLAGS_FOR_TARGET=$CXXFLAGS
+ case " $CXXFLAGS " in
+ *" -O2 "*) ;;
+ *) CXXFLAGS_FOR_TARGET="-O2 $CXXFLAGS" ;;
+ esac
+ case " $CXXFLAGS " in
+ *" -g "* | *" -g3 "*) ;;
+ *) CXXFLAGS_FOR_TARGET="-g $CXXFLAGS" ;;
+ esac
+fi
+
+
# Handle --with-headers=XXX. If the value is not "yes", the contents of
# the named directory are copied to $(tooldir)/sys-include.
if test x"${with_headers}" != x && test x"${with_headers}" != xno ; then

View File

@ -1,25 +0,0 @@
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35964
Index: gcc-4.3.0/gcc/regrename.c
===================================================================
--- gcc-4.3.0.orig/gcc/regrename.c 2008-05-28 08:31:15.000000000 -0700
+++ gcc-4.3.0/gcc/regrename.c 2008-05-28 08:34:00.000000000 -0700
@@ -782,6 +782,10 @@
|| (predicated && recog_data.operand_type[i] == OP_OUT))
recog_data.operand_type[i] = OP_INOUT;
}
+ /* Unshare dup_loc RTL */
+ for (i = 0; i < recog_data.n_dups; i++)
+ *recog_data.dup_loc[i] = copy_rtx(*recog_data.dup_loc[i]);
+
/* Step 1: Close chains for which we have overlapping reads. */
for (i = 0; i < n_ops; i++)
@@ -813,7 +817,7 @@
OP_IN, 0);
for (i = 0; i < recog_data.n_dups; i++)
- *recog_data.dup_loc[i] = copy_rtx (old_dups[i]);
+ *recog_data.dup_loc[i] = old_dups[i];
for (i = 0; i < n_ops; i++)
*recog_data.operand_loc[i] = old_operands[i];
if (recog_data.n_dups)

View File

@ -1,130 +0,0 @@
2010-10-15 Chung-Lin Tang <cltang@codesourcery.com>
Backport from mainline:
2010-10-15 Chung-Lin Tang <cltang@codesourcery.com>
gcc/
* ifcvt.c (find_active_insn_before): New function.
(find_active_insn_after): New function.
(cond_exec_process_if_block): Use new functions to replace
prev_active_insn() and next_active_insn().
gcc/testsuite/
* gcc.dg/20101010-1.c: New testcase.
=== modified file 'gcc/ifcvt.c'
Index: gcc-4.5/gcc/ifcvt.c
===================================================================
--- gcc-4.5.orig/gcc/ifcvt.c
+++ gcc-4.5/gcc/ifcvt.c
@@ -88,6 +88,8 @@ static int count_bb_insns (const_basic_b
static bool cheap_bb_rtx_cost_p (const_basic_block, int);
static rtx first_active_insn (basic_block);
static rtx last_active_insn (basic_block, int);
+static rtx find_active_insn_before (basic_block, rtx);
+static rtx find_active_insn_after (basic_block, rtx);
static basic_block block_fallthru (basic_block);
static int cond_exec_process_insns (ce_if_block_t *, rtx, rtx, rtx, rtx, int);
static rtx cond_exec_get_condition (rtx);
@@ -230,6 +232,48 @@ last_active_insn (basic_block bb, int sk
return insn;
}
+/* Return the active insn before INSN inside basic block CURR_BB. */
+
+static rtx
+find_active_insn_before (basic_block curr_bb, rtx insn)
+{
+ if (!insn || insn == BB_HEAD (curr_bb))
+ return NULL_RTX;
+
+ while ((insn = PREV_INSN (insn)) != NULL_RTX)
+ {
+ if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
+ break;
+
+ /* No other active insn all the way to the start of the basic block. */
+ if (insn == BB_HEAD (curr_bb))
+ return NULL_RTX;
+ }
+
+ return insn;
+}
+
+/* Return the active insn after INSN inside basic block CURR_BB. */
+
+static rtx
+find_active_insn_after (basic_block curr_bb, rtx insn)
+{
+ if (!insn || insn == BB_END (curr_bb))
+ return NULL_RTX;
+
+ while ((insn = NEXT_INSN (insn)) != NULL_RTX)
+ {
+ if (NONJUMP_INSN_P (insn) || JUMP_P (insn) || CALL_P (insn))
+ break;
+
+ /* No other active insn all the way to the end of the basic block. */
+ if (insn == BB_END (curr_bb))
+ return NULL_RTX;
+ }
+
+ return insn;
+}
+
/* Return the basic block reached by falling though the basic block BB. */
static basic_block
@@ -448,9 +492,9 @@ cond_exec_process_if_block (ce_if_block_
if (n_matching > 0)
{
if (then_end)
- then_end = prev_active_insn (then_first_tail);
+ then_end = find_active_insn_before (then_bb, then_first_tail);
if (else_end)
- else_end = prev_active_insn (else_first_tail);
+ else_end = find_active_insn_before (else_bb, else_first_tail);
n_insns -= 2 * n_matching;
}
@@ -488,9 +532,9 @@ cond_exec_process_if_block (ce_if_block_
if (n_matching > 0)
{
if (then_start)
- then_start = next_active_insn (then_last_head);
+ then_start = find_active_insn_after (then_bb, then_last_head);
if (else_start)
- else_start = next_active_insn (else_last_head);
+ else_start = find_active_insn_after (else_bb, else_last_head);
n_insns -= 2 * n_matching;
}
}
@@ -646,7 +690,7 @@ cond_exec_process_if_block (ce_if_block_
{
rtx from = then_first_tail;
if (!INSN_P (from))
- from = next_active_insn (from);
+ from = find_active_insn_after (then_bb, from);
delete_insn_chain (from, BB_END (then_bb), false);
}
if (else_last_head)
Index: gcc-4.5/gcc/testsuite/gcc.dg/20101010-1.c
===================================================================
--- /dev/null
+++ gcc-4.5/gcc/testsuite/gcc.dg/20101010-1.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fno-crossjumping" } */
+
+int foo (void)
+{
+ int len;
+ if (bar1 (&len))
+ {
+ char devpath [len];
+ if (bar2 (devpath) == len)
+ return len;
+ }
+ return -1;
+}

View File

@ -1,27 +0,0 @@
Source: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=45805
Index: gcc-4.5/gcc/config/arm/neon.md
===================================================================
--- gcc-4.5.orig/gcc/config/arm/neon.md 2010-09-28 12:04:38.000000000 -0700
+++ gcc-4.5/gcc/config/arm/neon.md 2010-09-28 12:07:28.026227000 -0700
@@ -5682,9 +5682,9 @@
;; Vectorize for non-neon-quad case
(define_insn "neon_unpack<US>_<mode>"
[(set (match_operand:<V_widen> 0 "register_operand" "=w")
- (SE:<V_widen> (match_operand:VDI 1 "register_operand" "")))]
+ (SE:<V_widen> (match_operand:VDI 1 "register_operand" "w")))]
"TARGET_NEON"
- "vmovl.<US><V_sz_elem> %q0, %1"
+ "vmovl.<US><V_sz_elem> %q0, %P1"
[(set_attr "neon_type" "neon_shift_1")]
)
@@ -5721,7 +5721,7 @@
(SE:<V_widen>
(match_operand:VDI 2 "register_operand" "w"))))]
"TARGET_NEON"
- "vmull.<US><V_sz_elem> %q0, %1, %2"
+ "vmull.<US><V_sz_elem> %q0, %P1, %P2"
[(set_attr "neon_type" "neon_shift_1")]
)

View File

@ -1,3 +1,11 @@
2010-07-26 Julian Brown <julian@codesourcery.com>
Merge from Sourcery G++ 4.4:
Jie Zhang <jie@codesourcery.com>
Issue #7122
gcc/
* config/arm/arm.c (arm_rtx_costs_1): Adjust cost for
CONST_VECTOR.
(arm_size_rtx_costs): Likewise.
@ -25,18 +33,6 @@
* gcc.target/arm/neon-vdup-18.c: New test case.
* gcc.target/arm/neon-vdup-19.c: New test case.
2010-07-26 Julian Brown <julian@codesourcery.com>
Merge from Sourcery G++ 4.4:
Jie Zhang <jie@codesourcery.com>
Issue #7122
gcc/
* config/arm/vfp.md (movdf_vfp): Add load double 0.0 case.
(thumb2_movdf_vfp): Likewise. Require that one of the operands be a
register.
=== modified file 'gcc/config/arm/arm.c'
--- old/gcc/config/arm/arm.c 2010-08-13 10:55:28 +0000

View File

@ -1,3 +1,7 @@
2010-07-26 Julian Brown <julian@codesourcery.com>
Merge from Sourcery G++ 4.4:
2010-04-07 Thomas Schwinge <thomas@codesourcery.com>
Daniel Jacobowitz <dan@codesourcery.com>
@ -13,13 +17,6 @@
* config/arm/arm.h (DWARF2_UNWIND_INFO): Remove definition.
* config/arm/bpabi.h (DWARF2_UNWIND_INFO): Define to zero.
2010-07-26 Julian Brown <julian@codesourcery.com>
Merge from Sourcery G++ 4.4:
Jie Zhang <jie@codesourcery.com>
Issue #7122
=== modified file 'gcc/config/arm/arm.h'
--- old/gcc/config/arm/arm.h 2010-08-13 10:30:35 +0000

View File

@ -1,147 +0,0 @@
2010-12-13 Chung-Lin Tang <cltang@codesourcery.com>
Backport from mainline:
2010-12-10 Jakub Jelinek <jakub@redhat.com>
PR rtl-optimization/46865
* rtl.c (rtx_equal_p_cb, rtx_equal_p): For last operand of
ASM_OPERANDS and ASM_INPUT if integers are different,
call locator_eq.
* jump.c (rtx_renumbered_equal_p): Likewise.
gcc/testsuite/
* gcc.target/i386/pr46865-1.c: New test.
* gcc.target/i386/pr46865-2.c: New test.
=== modified file 'gcc/jump.c'
--- old/gcc/jump.c 2009-11-25 10:55:54 +0000
+++ new/gcc/jump.c 2010-12-13 10:05:52 +0000
@@ -1728,7 +1728,13 @@
case 'i':
if (XINT (x, i) != XINT (y, i))
- return 0;
+ {
+ if (((code == ASM_OPERANDS && i == 6)
+ || (code == ASM_INPUT && i == 1))
+ && locator_eq (XINT (x, i), XINT (y, i)))
+ break;
+ return 0;
+ }
break;
case 't':
=== modified file 'gcc/rtl.c'
--- old/gcc/rtl.c 2009-11-25 10:55:54 +0000
+++ new/gcc/rtl.c 2010-12-13 10:05:52 +0000
@@ -429,7 +429,15 @@
case 'n':
case 'i':
if (XINT (x, i) != XINT (y, i))
- return 0;
+ {
+#ifndef GENERATOR_FILE
+ if (((code == ASM_OPERANDS && i == 6)
+ || (code == ASM_INPUT && i == 1))
+ && locator_eq (XINT (x, i), XINT (y, i)))
+ break;
+#endif
+ return 0;
+ }
break;
case 'V':
@@ -549,7 +557,15 @@
case 'n':
case 'i':
if (XINT (x, i) != XINT (y, i))
- return 0;
+ {
+#ifndef GENERATOR_FILE
+ if (((code == ASM_OPERANDS && i == 6)
+ || (code == ASM_INPUT && i == 1))
+ && locator_eq (XINT (x, i), XINT (y, i)))
+ break;
+#endif
+ return 0;
+ }
break;
case 'V':
=== added file 'gcc/testsuite/gcc.target/i386/pr46865-1.c'
--- old/gcc/testsuite/gcc.target/i386/pr46865-1.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/i386/pr46865-1.c 2010-12-13 10:05:52 +0000
@@ -0,0 +1,31 @@
+/* PR rtl-optimization/46865 */
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+extern unsigned long f;
+
+#define m1(f) \
+ if (f & 1) \
+ asm volatile ("nop /* asmnop */\n"); \
+ else \
+ asm volatile ("nop /* asmnop */\n");
+
+#define m2(f) \
+ if (f & 1) \
+ asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); \
+ else \
+ asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx");
+
+void
+foo (void)
+{
+ m1 (f);
+}
+
+void
+bar (void)
+{
+ m2 (f);
+}
+
+/* { dg-final { scan-assembler-times "asmnop" 2 } } */
=== added file 'gcc/testsuite/gcc.target/i386/pr46865-2.c'
--- old/gcc/testsuite/gcc.target/i386/pr46865-2.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/i386/pr46865-2.c 2010-12-13 10:05:52 +0000
@@ -0,0 +1,32 @@
+/* PR rtl-optimization/46865 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -save-temps" } */
+
+extern unsigned long f;
+
+#define m1(f) \
+ if (f & 1) \
+ asm volatile ("nop /* asmnop */\n"); \
+ else \
+ asm volatile ("nop /* asmnop */\n");
+
+#define m2(f) \
+ if (f & 1) \
+ asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx"); \
+ else \
+ asm volatile ("nop /* asmnop */\n" : : "i" (6) : "cx");
+
+void
+foo (void)
+{
+ m1 (f);
+}
+
+void
+bar (void)
+{
+ m2 (f);
+}
+
+/* { dg-final { scan-assembler-times "asmnop" 2 } } */
+/* { dg-final { cleanup-saved-temps } } */

View File

@ -0,0 +1,157 @@
LP: #681138
Backport from mainline:
gcc/
* config/arm/sync.md (sync_clobber, sync_t2_reqd): New code attribute.
(arm_sync_old_<sync_optab>si, arm_sync_old_<sync_optab><mode>): Use
the sync_clobber and sync_t2_reqd code attributes.
* config/arm/arm.c (arm_output_sync_loop): Reverse the operation if
the t2 argument is NULL.
=== modified file 'gcc/config/arm/arm.c'
Index: gcc-4_5-branch/gcc/config/arm/arm.c
===================================================================
--- gcc-4_5-branch.orig/gcc/config/arm/arm.c
+++ gcc-4_5-branch/gcc/config/arm/arm.c
@@ -23098,10 +23098,46 @@ arm_output_sync_loop (emit_f emit,
break;
}
- arm_output_strex (emit, mode, "", t2, t1, memory);
- operands[0] = t2;
- arm_output_asm_insn (emit, 0, operands, "teq\t%%0, #0");
- arm_output_asm_insn (emit, 0, operands, "bne\t%sLSYT%%=", LOCAL_LABEL_PREFIX);
+ if (t2)
+ {
+ arm_output_strex (emit, mode, "", t2, t1, memory);
+ operands[0] = t2;
+ arm_output_asm_insn (emit, 0, operands, "teq\t%%0, #0");
+ arm_output_asm_insn (emit, 0, operands, "bne\t%sLSYT%%=",
+ LOCAL_LABEL_PREFIX);
+ }
+ else
+ {
+ /* Use old_value for the return value because for some operations
+ the old_value can easily be restored. This saves one register. */
+ arm_output_strex (emit, mode, "", old_value, t1, memory);
+ operands[0] = old_value;
+ arm_output_asm_insn (emit, 0, operands, "teq\t%%0, #0");
+ arm_output_asm_insn (emit, 0, operands, "bne\t%sLSYT%%=",
+ LOCAL_LABEL_PREFIX);
+
+ switch (sync_op)
+ {
+ case SYNC_OP_ADD:
+ arm_output_op3 (emit, "sub", old_value, t1, new_value);
+ break;
+
+ case SYNC_OP_SUB:
+ arm_output_op3 (emit, "add", old_value, t1, new_value);
+ break;
+
+ case SYNC_OP_XOR:
+ arm_output_op3 (emit, "eor", old_value, t1, new_value);
+ break;
+
+ case SYNC_OP_NONE:
+ arm_output_op2 (emit, "mov", old_value, required_value);
+ break;
+
+ default:
+ gcc_unreachable ();
+ }
+ }
arm_process_output_memory_barrier (emit, NULL);
arm_output_asm_insn (emit, 1, operands, "%sLSYB%%=:", LOCAL_LABEL_PREFIX);
Index: gcc-4_5-branch/gcc/config/arm/sync.md
===================================================================
--- gcc-4_5-branch.orig/gcc/config/arm/sync.md
+++ gcc-4_5-branch/gcc/config/arm/sync.md
@@ -103,6 +103,18 @@
(plus "add")
(minus "sub")])
+(define_code_attr sync_clobber [(ior "=&r")
+ (and "=&r")
+ (xor "X")
+ (plus "X")
+ (minus "X")])
+
+(define_code_attr sync_t2_reqd [(ior "4")
+ (and "4")
+ (xor "*")
+ (plus "*")
+ (minus "*")])
+
(define_expand "sync_<sync_optab>si"
[(match_operand:SI 0 "memory_operand")
(match_operand:SI 1 "s_register_operand")
@@ -286,7 +298,6 @@
VUNSPEC_SYNC_COMPARE_AND_SWAP))
(set (match_dup 1) (unspec_volatile:SI [(match_dup 2)]
VUNSPEC_SYNC_COMPARE_AND_SWAP))
- (clobber:SI (match_scratch:SI 4 "=&r"))
(set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]
VUNSPEC_SYNC_COMPARE_AND_SWAP))
]
@@ -299,7 +310,6 @@
(set_attr "sync_required_value" "2")
(set_attr "sync_new_value" "3")
(set_attr "sync_t1" "0")
- (set_attr "sync_t2" "4")
(set_attr "conds" "clob")
(set_attr "predicable" "no")])
@@ -313,7 +323,6 @@
VUNSPEC_SYNC_COMPARE_AND_SWAP)))
(set (match_dup 1) (unspec_volatile:NARROW [(match_dup 2)]
VUNSPEC_SYNC_COMPARE_AND_SWAP))
- (clobber:SI (match_scratch:SI 4 "=&r"))
(set (reg:CC CC_REGNUM) (unspec_volatile:CC [(match_dup 1)]
VUNSPEC_SYNC_COMPARE_AND_SWAP))
]
@@ -326,7 +335,6 @@
(set_attr "sync_required_value" "2")
(set_attr "sync_new_value" "3")
(set_attr "sync_t1" "0")
- (set_attr "sync_t2" "4")
(set_attr "conds" "clob")
(set_attr "predicable" "no")])
@@ -487,7 +495,7 @@
VUNSPEC_SYNC_OLD_OP))
(clobber (reg:CC CC_REGNUM))
(clobber (match_scratch:SI 3 "=&r"))
- (clobber (match_scratch:SI 4 "=&r"))]
+ (clobber (match_scratch:SI 4 "<sync_clobber>"))]
"TARGET_HAVE_LDREX && TARGET_HAVE_MEMORY_BARRIER"
{
return arm_output_sync_insn (insn, operands);
@@ -496,7 +504,7 @@
(set_attr "sync_memory" "1")
(set_attr "sync_new_value" "2")
(set_attr "sync_t1" "3")
- (set_attr "sync_t2" "4")
+ (set_attr "sync_t2" "<sync_t2_reqd>")
(set_attr "sync_op" "<sync_optab>")
(set_attr "conds" "clob")
(set_attr "predicable" "no")])
@@ -540,7 +548,7 @@
VUNSPEC_SYNC_OLD_OP))
(clobber (reg:CC CC_REGNUM))
(clobber (match_scratch:SI 3 "=&r"))
- (clobber (match_scratch:SI 4 "=&r"))]
+ (clobber (match_scratch:SI 4 "<sync_clobber>"))]
"TARGET_HAVE_LDREXBHD && TARGET_HAVE_MEMORY_BARRIER"
{
return arm_output_sync_insn (insn, operands);
@@ -549,7 +557,7 @@
(set_attr "sync_memory" "1")
(set_attr "sync_new_value" "2")
(set_attr "sync_t1" "3")
- (set_attr "sync_t2" "4")
+ (set_attr "sync_t2" "<sync_t2_reqd>")
(set_attr "sync_op" "<sync_optab>")
(set_attr "conds" "clob")
(set_attr "predicable" "no")])

View File

@ -0,0 +1,94 @@
2011-01-18 Ulrich Weigand <uweigand@de.ibm.com>
LP: #685352
Backport from mainline:
2011-01-18 Jakub Jelinek <jakub@redhat.com>
gcc/
PR rtl-optimization/47299
* expr.c (expand_expr_real_2) <case WIDEN_MULT_EXPR>: Don't use
subtarget. Use normal multiplication if both operands are
constants.
* expmed.c (expand_widening_mult): Don't try to optimize constant
multiplication if op0 has VOIDmode. Convert op1 constant to mode
before using it.
gcc/testsuite/
PR rtl-optimization/47299
* gcc.c-torture/execute/pr47299.c: New test.
=== modified file 'gcc/expmed.c'
Index: gcc-4_5-branch/gcc/expmed.c
===================================================================
--- gcc-4_5-branch.orig/gcc/expmed.c
+++ gcc-4_5-branch/gcc/expmed.c
@@ -3355,12 +3355,17 @@ expand_widening_mult (enum machine_mode
int unsignedp, optab this_optab)
{
bool speed = optimize_insn_for_speed_p ();
+ rtx cop1;
if (CONST_INT_P (op1)
- && (INTVAL (op1) >= 0
+ && GET_MODE (op0) != VOIDmode
+ && (cop1 = convert_modes (mode, GET_MODE (op0), op1,
+ this_optab == umul_widen_optab))
+ && CONST_INT_P (cop1)
+ && (INTVAL (cop1) >= 0
|| GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT))
{
- HOST_WIDE_INT coeff = INTVAL (op1);
+ HOST_WIDE_INT coeff = INTVAL (cop1);
int max_cost;
enum mult_variant variant;
struct algorithm algorithm;
Index: gcc-4_5-branch/gcc/expr.c
===================================================================
--- gcc-4_5-branch.orig/gcc/expr.c
+++ gcc-4_5-branch/gcc/expr.c
@@ -7624,10 +7624,10 @@ expand_expr_real_2 (sepops ops, rtx targ
if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)
{
if (TYPE_UNSIGNED (TREE_TYPE (treeop0)))
- expand_operands (treeop0, treeop1, subtarget, &op0, &op1,
+ expand_operands (treeop0, treeop1, NULL_RTX, &op0, &op1,
EXPAND_NORMAL);
else
- expand_operands (treeop0, treeop1, subtarget, &op1, &op0,
+ expand_operands (treeop0, treeop1, NULL_RTX, &op1, &op0,
EXPAND_NORMAL);
goto binop3;
}
@@ -7645,7 +7645,8 @@ expand_expr_real_2 (sepops ops, rtx targ
optab other_optab = zextend_p ? smul_widen_optab : umul_widen_optab;
this_optab = zextend_p ? umul_widen_optab : smul_widen_optab;
- if (mode == GET_MODE_2XWIDER_MODE (innermode))
+ if (mode == GET_MODE_2XWIDER_MODE (innermode)
+ && TREE_CODE (treeop0) != INTEGER_CST)
{
if (optab_handler (this_optab, mode)->insn_code != CODE_FOR_nothing)
{
Index: gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c
===================================================================
--- /dev/null
+++ gcc-4_5-branch/gcc/testsuite/gcc.c-torture/execute/pr47299.c
@@ -0,0 +1,17 @@
+/* PR rtl-optimization/47299 */
+
+extern void abort (void);
+
+__attribute__ ((noinline, noclone)) unsigned short
+foo (unsigned char x)
+{
+ return x * 255;
+}
+
+int
+main ()
+{
+ if (foo (0x40) != 0x3fc0)
+ abort ();
+ return 0;
+}

View File

@ -0,0 +1,38 @@
2011-01-19 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
Backport from FSF mainline
2011-01-18 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/cortex-a9.md (cortex-a9-neon.md): Actually
include.
(cortex_a9_dp): Handle neon types correctly.
=== modified file 'gcc/config/arm/cortex-a9.md'
Index: gcc-4_5-branch/gcc/config/arm/cortex-a9.md
===================================================================
--- gcc-4_5-branch.orig/gcc/config/arm/cortex-a9.md
+++ gcc-4_5-branch/gcc/config/arm/cortex-a9.md
@@ -79,10 +79,11 @@ cortex_a9_p1_e2 + cortex_a9_p0_e1 + cort
;; which can go down E2 without any problem.
(define_insn_reservation "cortex_a9_dp" 2
(and (eq_attr "tune" "cortexa9")
- (ior (eq_attr "type" "alu")
- (ior (and (eq_attr "type" "alu_shift_reg, alu_shift")
- (eq_attr "insn" "mov"))
- (eq_attr "neon_type" "none"))))
+ (ior (and (eq_attr "type" "alu")
+ (eq_attr "neon_type" "none"))
+ (and (and (eq_attr "type" "alu_shift_reg, alu_shift")
+ (eq_attr "insn" "mov"))
+ (eq_attr "neon_type" "none"))))
"cortex_a9_p0_default|cortex_a9_p1_default")
;; An instruction using the shifter will go down E1.
@@ -263,3 +264,6 @@ cortex_a9_store3_4, cortex_a9_store1_2,
(and (eq_attr "tune" "cortexa9")
(eq_attr "type" "fdivd"))
"ca9fp_ds1 + ca9_issue_vfp_neon, nothing*24")
+
+;; Include Neon pipeline description
+(include "cortex-a9-neon.md")

View File

@ -0,0 +1,811 @@
2010-12-13 Tom de Vries <tom@codesourcery.com>
gcc/
* tree-if-switch-conversion.c: New pass.
* tree-pass.h (pass_if_to_switch): Declare.
* common.opt (ftree-if-to-switch-conversion): New switch.
* opts.c (decode_options): Set flag_tree_if_to_switch_conversion at -O2
and higher.
* passes.c (init_optimization_passes): Use new pass.
* params.def (PARAM_IF_TO_SWITCH_THRESHOLD): New param.
* doc/invoke.texi (-ftree-if-to-switch-conversion)
(if-to-switch-threshold): New item.
* doc/invoke.texi (Optimization Options, option -O2): Add
-ftree-if-to-switch-conversion.
* Makefile.in (OBJS-common): Add tree-if-switch-conversion.o.
* Makefile.in (tree-if-switch-conversion.o): New rule.
=== modified file 'gcc/Makefile.in'
Index: gcc-4_5-branch/gcc/Makefile.in
===================================================================
--- gcc-4_5-branch.orig/gcc/Makefile.in
+++ gcc-4_5-branch/gcc/Makefile.in
@@ -1354,6 +1354,7 @@ OBJS-common = \
tree-profile.o \
tree-scalar-evolution.o \
tree-sra.o \
+ tree-if-switch-conversion.o \
tree-switch-conversion.o \
tree-ssa-address.o \
tree-ssa-alias.o \
@@ -3013,6 +3014,11 @@ tree-sra.o : tree-sra.c $(CONFIG_H) $(SY
$(TM_H) $(TREE_H) $(GIMPLE_H) $(CGRAPH_H) $(TREE_FLOW_H) $(IPA_PROP_H) \
$(DIAGNOSTIC_H) statistics.h $(TREE_DUMP_H) $(TIMEVAR_H) $(PARAMS_H) \
$(TARGET_H) $(FLAGS_H) $(EXPR_H) $(TREE_INLINE_H)
+tree-if-switch-conversion.o : tree-if-switch-conversion.c $(CONFIG_H) \
+ $(SYSTEM_H) $(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) \
+ $(TREE_INLINE_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
+ $(GIMPLE_H) $(TREE_PASS_H) $(FLAGS_H) $(EXPR_H) $(BASIC_BLOCK_H) output.h \
+ $(GGC_H) $(OBSTACK_H) $(PARAMS_H) $(CPPLIB_H) $(PARAMS_H)
tree-switch-conversion.o : tree-switch-conversion.c $(CONFIG_H) $(SYSTEM_H) \
$(TREE_H) $(TM_P_H) $(TREE_FLOW_H) $(DIAGNOSTIC_H) $(TREE_INLINE_H) \
$(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) $(GIMPLE_H) \
Index: gcc-4_5-branch/gcc/common.opt
===================================================================
--- gcc-4_5-branch.orig/gcc/common.opt
+++ gcc-4_5-branch/gcc/common.opt
@@ -1285,6 +1285,10 @@ ftree-switch-conversion
Common Report Var(flag_tree_switch_conversion) Optimization
Perform conversions of switch initializations.
+ftree-if-to-switch-conversion
+Common Report Var(flag_tree_if_to_switch_conversion) Optimization
+Perform conversions of chains of ifs into switches.
+
ftree-dce
Common Report Var(flag_tree_dce) Optimization
Enable SSA dead code elimination optimization on trees
Index: gcc-4_5-branch/gcc/doc/invoke.texi
===================================================================
--- gcc-4_5-branch.orig/gcc/doc/invoke.texi
+++ gcc-4_5-branch/gcc/doc/invoke.texi
@@ -382,7 +382,8 @@ Objective-C and Objective-C++ Dialects}.
-fstrict-aliasing -fstrict-overflow -fthread-jumps -ftracer @gol
-ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copy-prop @gol
-ftree-copyrename -ftree-dce @gol
--ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre -ftree-loop-im @gol
+-ftree-dominator-opts -ftree-dse -ftree-forwprop -ftree-fre @gol
+-ftree-if-to-switch-conversion -ftree-loop-im @gol
-ftree-phiprop -ftree-loop-distribution @gol
-ftree-loop-ivcanon -ftree-loop-linear -ftree-loop-optimize @gol
-ftree-parallelize-loops=@var{n} -ftree-pre -ftree-pta -ftree-reassoc @gol
@@ -5798,6 +5799,7 @@ also turns on the following optimization
-fsched-interblock -fsched-spec @gol
-fschedule-insns -fschedule-insns2 @gol
-fstrict-aliasing -fstrict-overflow @gol
+-ftree-if-to-switch-conversion @gol
-ftree-switch-conversion @gol
-ftree-pre @gol
-ftree-vrp}
@@ -6634,6 +6636,10 @@ Perform conversion of simple initializat
initializations from a scalar array. This flag is enabled by default
at @option{-O2} and higher.
+@item -ftree-if-to-switch-conversion
+Perform conversion of chains of ifs into switches. This flag is enabled by
+default at @option{-O2} and higher.
+
@item -ftree-dce
@opindex ftree-dce
Perform dead code elimination (DCE) on trees. This flag is enabled by
@@ -8577,6 +8583,12 @@ loop in the loop nest by a given number
length can be changed using the @option{loop-block-tile-size}
parameter. The default value is 51 iterations.
+@item if-to-switch-threshold
+If-chain to switch conversion, enabled by
+@option{-ftree-if-to-switch-conversion} convert chains of ifs of sufficient
+length into switches. The parameter @option{if-to-switch-threshold} can be
+used to set the minimal required length. The default value is 3.
+
@end table
@end table
Index: gcc-4_5-branch/gcc/opts.c
===================================================================
--- gcc-4_5-branch.orig/gcc/opts.c
+++ gcc-4_5-branch/gcc/opts.c
@@ -905,6 +905,7 @@ decode_options (unsigned int argc, const
flag_tree_builtin_call_dce = opt2;
flag_tree_pre = opt2;
flag_tree_switch_conversion = opt2;
+ flag_tree_if_to_switch_conversion = opt2;
flag_ipa_cp = opt2;
flag_ipa_sra = opt2;
flag_ee = opt2;
Index: gcc-4_5-branch/gcc/params.def
===================================================================
--- gcc-4_5-branch.orig/gcc/params.def
+++ gcc-4_5-branch/gcc/params.def
@@ -826,6 +826,11 @@ DEFPARAM (PARAM_IPA_SRA_PTR_GROWTH_FACTO
"a pointer to an aggregate with",
2, 0, 0)
+DEFPARAM (PARAM_IF_TO_SWITCH_THRESHOLD,
+ "if-to-switch-threshold",
+ "Threshold for converting an if-chain into a switch",
+ 3, 0, 0)
+
/*
Local variables:
mode:c
Index: gcc-4_5-branch/gcc/passes.c
===================================================================
--- gcc-4_5-branch.orig/gcc/passes.c
+++ gcc-4_5-branch/gcc/passes.c
@@ -788,6 +788,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_cd_dce);
NEXT_PASS (pass_early_ipa_sra);
NEXT_PASS (pass_tail_recursion);
+ NEXT_PASS (pass_if_to_switch);
NEXT_PASS (pass_convert_switch);
NEXT_PASS (pass_cleanup_eh);
NEXT_PASS (pass_profile);
@@ -844,6 +845,7 @@ init_optimization_passes (void)
NEXT_PASS (pass_phiprop);
NEXT_PASS (pass_fre);
NEXT_PASS (pass_copy_prop);
+ NEXT_PASS (pass_if_to_switch);
NEXT_PASS (pass_merge_phi);
NEXT_PASS (pass_vrp);
NEXT_PASS (pass_dce);
Index: gcc-4_5-branch/gcc/tree-if-switch-conversion.c
===================================================================
--- /dev/null
+++ gcc-4_5-branch/gcc/tree-if-switch-conversion.c
@@ -0,0 +1,643 @@
+/* Convert a chain of ifs into a switch.
+ Copyright (C) 2010 Free Software Foundation, Inc.
+ Contributed by Tom de Vries <tom@codesourcery.com>
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation; either version 3, or (at your option) any
+later version.
+
+GCC is distributed in the hope that it will be useful, but WITHOUT
+ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not, write to the Free
+Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA. */
+
+
+/* The following pass converts a chain of ifs into a switch.
+
+ The if-chain has the following properties:
+ - all bbs end in a GIMPLE_COND.
+ - all but the first bb are empty, apart from the GIMPLE_COND.
+ - the GIMPLE_CONDs compare the same variable against integer constants.
+ - the true gotos all target the same bb.
+ - the false gotos target the next in the if-chain.
+
+ F.i., consider the following if-chain:
+ ...
+ <bb 4>:
+ ...
+ if (D.1993_3 == 32)
+ goto <bb 3>;
+ else
+ goto <bb 5>;
+
+ <bb 5>:
+ if (D.1993_3 == 13)
+ goto <bb 3>;
+ else
+ goto <bb 6>;
+
+ <bb 6>:
+ if (D.1993_3 == 10)
+ goto <bb 3>;
+ else
+ goto <bb 7>;
+
+ <bb 7>:
+ if (D.1993_3 == 9)
+ goto <bb 3>;
+ else
+ goto <bb 8>;
+ ...
+
+ The pass will report this if-chain like this:
+ ...
+ var: D.1993_3
+ first: <bb 4>
+ true: <bb 3>
+ last: <bb 7>
+ constants: 9 10 13 32
+ ...
+
+ and then convert the if-chain into a switch:
+ ...
+ <bb 4>:
+ ...
+ switch (D.1993_3) <default: <L8>,
+ case 9: <L7>,
+ case 10: <L7>,
+ case 13: <L7>,
+ case 32: <L7>>
+ ...
+
+ The conversion does not happen if the chain is too short. The threshold is
+ determined by the parameter PARAM_IF_TO_SWITCH_THRESHOLD.
+
+ The pass will try to construct a chain for each bb, unless the bb it is
+ already contained in a chain. This ensures that all chains will be found,
+ and that no chain will be constructed twice. The pass constructs and
+ converts the chains one-by-one, rather than first calculating all the chains
+ and then doing the conversions.
+
+ The pass could detect range-checks in analyze_bb as well, and handle them.
+ Simple ones, like 'c <= 5', and more complex ones, like
+ '(unsigned char) c + 247 <= 1', which is generated by the C front-end from
+ code like '(c == 9 || c == 10)' or '(9 <= c && c <= 10)'. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+
+#include "params.h"
+#include "flags.h"
+#include "tree.h"
+#include "basic-block.h"
+#include "tree-flow.h"
+#include "tree-flow-inline.h"
+#include "tree-ssa-operands.h"
+#include "diagnostic.h"
+#include "tree-pass.h"
+#include "tree-dump.h"
+#include "timevar.h"
+
+/* Information we've collected about a single bb. */
+
+struct ifsc_info
+{
+ /* The variable of the bb's ending GIMPLE_COND, NULL_TREE if not present. */
+ tree var;
+ /* The cond_code of the bb's ending GIMPLE_COND. */
+ enum tree_code cond_code;
+ /* The constant of the bb's ending GIMPLE_COND. */
+ tree constant;
+ /* Successor edge of the bb if its GIMPLE_COND is true. */
+ edge true_edge;
+ /* Successor edge of the bb if its GIMPLE_COND is false. */
+ edge false_edge;
+ /* Set if the bb has valid ifsc_info. */
+ bool valid;
+ /* Set if the bb is part of a chain. */
+ bool chained;
+};
+
+/* Macros to access the fields of struct ifsc_info. */
+
+#define BB_IFSC_VAR(bb) (((struct ifsc_info *)bb->aux)->var)
+#define BB_IFSC_COND_CODE(bb) (((struct ifsc_info *)bb->aux)->cond_code)
+#define BB_IFSC_CONSTANT(bb) (((struct ifsc_info *)bb->aux)->constant)
+#define BB_IFSC_TRUE_EDGE(bb) (((struct ifsc_info *)bb->aux)->true_edge)
+#define BB_IFSC_FALSE_EDGE(bb) (((struct ifsc_info *)bb->aux)->false_edge)
+#define BB_IFSC_VALID(bb) (((struct ifsc_info *)bb->aux)->valid)
+#define BB_IFSC_CHAINED(bb) (((struct ifsc_info *)bb->aux)->chained)
+
+/* Data-type describing an if-chain. */
+
+struct if_chain
+{
+ /* First bb in the chain. */
+ basic_block first;
+ /* Last bb in the chain. */
+ basic_block last;
+ /* Variable that GIMPLE_CONDs of all bbs in chain compare against. */
+ tree var;
+ /* bb that all GIMPLE_CONDs jump to if comparison succeeds. */
+ basic_block true_dest;
+ /* Constants that GIMPLE_CONDs of all bbs in chain compare var against. */
+ VEC (tree, heap) *constants;
+ /* Same as previous, but sorted and with duplicates removed. */
+ VEC (tree, heap) *unique_constants;
+};
+
+/* Utility macro. */
+
+#define SWAP(T, X, Y) do { T tmp = (X); (X) = (Y); (Y) = tmp; } while (0)
+
+/* Helper function for sort_constants. */
+
+static int
+compare_constants (const void *p1, const void *p2)
+{
+ const_tree const c1 = *(const_tree const*)p1;
+ const_tree const c2 = *(const_tree const*)p2;
+
+ return tree_int_cst_compare (c1, c2);
+}
+
+/* Sort constants in constants and copy to unique_constants, while skipping
+ duplicates. */
+
+static void
+sort_constants (VEC (tree,heap) *constants, VEC (tree,heap) **unique_constants)
+{
+ size_t len = VEC_length (tree, constants);
+ unsigned int ix;
+ tree prev = NULL_TREE, constant;
+
+ /* Sort constants. */
+ qsort (VEC_address (tree, constants), len, sizeof (tree),
+ compare_constants);
+
+ /* Copy to unique_constants, while skipping duplicates. */
+ for (ix = 0; VEC_iterate (tree, constants, ix, constant); ix++)
+ {
+ if (prev != NULL_TREE && tree_int_cst_compare (prev, constant) == 0)
+ continue;
+ prev = constant;
+
+ VEC_safe_push (tree, heap, *unique_constants, constant);
+ }
+}
+
+/* Get true_edge and false_edge of a bb ending in a conditional jump. */
+
+static void
+get_edges (basic_block bb, edge *true_edge, edge *false_edge)
+{
+ edge e0, e1;
+ int e0_true;
+ int n = EDGE_COUNT (bb->succs);
+ gcc_assert (n == 2);
+
+ e0 = EDGE_SUCC (bb, 0);
+ e1 = EDGE_SUCC (bb, 1);
+
+ e0_true = e0->flags & EDGE_TRUE_VALUE;
+
+ *true_edge = e0_true ? e0 : e1;
+ *false_edge = e0_true ? e1 : e0;
+
+ gcc_assert ((*true_edge)->flags & EDGE_TRUE_VALUE);
+ gcc_assert ((*false_edge)->flags & EDGE_FALSE_VALUE);
+
+ gcc_assert (((*true_edge)->flags & EDGE_FALLTHRU) == 0);
+ gcc_assert (((*false_edge)->flags & EDGE_FALLTHRU) == 0);
+}
+
+/* Analyze bb and store results in ifsc_info struct. */
+
+static void
+analyze_bb (basic_block bb)
+{
+ gimple stmt = last_stmt (bb);
+ tree lhs, rhs, var, constant;
+ edge true_edge, false_edge;
+ enum tree_code cond_code;
+
+ /* Don't redo analysis. */
+ if (BB_IFSC_VALID (bb))
+ return;
+ BB_IFSC_VALID (bb) = true;
+
+
+ /* bb needs to end in GIMPLE_COND. */
+ if (!stmt || gimple_code (stmt) != GIMPLE_COND)
+ return;
+
+ /* bb needs to end in EQ_EXPR or NE_EXPR. */
+ cond_code = gimple_cond_code (stmt);
+ if (cond_code != EQ_EXPR && cond_code != NE_EXPR)
+ return;
+
+ lhs = gimple_cond_lhs (stmt);
+ rhs = gimple_cond_rhs (stmt);
+
+ /* GIMPLE_COND needs to compare variable to constant. */
+ if ((TREE_CONSTANT (lhs) == 0)
+ == (TREE_CONSTANT (rhs) == 0))
+ return;
+
+ var = TREE_CONSTANT (lhs) ? rhs : lhs;
+ constant = TREE_CONSTANT (lhs)? lhs : rhs;
+
+ /* Switches cannot handle non-integral types. */
+ if (!INTEGRAL_TYPE_P(TREE_TYPE (var)))
+ return;
+
+ get_edges (bb, &true_edge, &false_edge);
+
+ if (cond_code == NE_EXPR)
+ SWAP (edge, true_edge, false_edge);
+
+ /* TODO: loosen this constraint. In principle it's ok if true_edge->dest has
+ phis, as long as for each phi all the edges coming from the chain have the
+ same value. */
+ if (!gimple_seq_empty_p (phi_nodes (true_edge->dest)))
+ return;
+
+ /* Store analysis in ifsc_info struct. */
+ BB_IFSC_VAR (bb) = var;
+ BB_IFSC_COND_CODE (bb) = cond_code;
+ BB_IFSC_CONSTANT (bb) = constant;
+ BB_IFSC_TRUE_EDGE (bb) = true_edge;
+ BB_IFSC_FALSE_EDGE (bb) = false_edge;
+}
+
+/* Grow if-chain forward. */
+
+static void
+grow_if_chain_forward (struct if_chain *chain)
+{
+ basic_block next_bb;
+
+ while (1)
+ {
+ next_bb = BB_IFSC_FALSE_EDGE (chain->last)->dest;
+
+ /* next_bb is already part of another chain. */
+ if (BB_IFSC_CHAINED (next_bb))
+ break;
+
+ /* next_bb needs to be dominated by the last bb. */
+ if (!single_pred_p (next_bb))
+ break;
+
+ analyze_bb (next_bb);
+
+ /* Does next_bb fit in chain? */
+ if (BB_IFSC_VAR (next_bb) != chain->var
+ || BB_IFSC_TRUE_EDGE (next_bb)->dest != chain->true_dest)
+ break;
+
+ /* We can only add empty bbs at the end of the chain. */
+ if (first_stmt (next_bb) != last_stmt (next_bb))
+ break;
+
+ /* Add next_bb at end of chain. */
+ VEC_safe_push (tree, heap, chain->constants, BB_IFSC_CONSTANT (next_bb));
+ BB_IFSC_CHAINED (next_bb) = true;
+ chain->last = next_bb;
+ }
+}
+
+/* Grow if-chain backward. */
+
+static void
+grow_if_chain_backward (struct if_chain *chain)
+{
+ basic_block prev_bb;
+
+ while (1)
+ {
+ /* First bb is not empty, cannot grow backwards. */
+ if (first_stmt (chain->first) != last_stmt (chain->first))
+ break;
+
+ /* First bb has no single predecessor, cannot grow backwards. */
+ if (!single_pred_p (chain->first))
+ break;
+
+ prev_bb = single_pred (chain->first);
+
+ /* prev_bb is already part of another chain. */
+ if (BB_IFSC_CHAINED (prev_bb))
+ break;
+
+ analyze_bb (prev_bb);
+
+ /* Does prev_bb fit in chain? */
+ if (BB_IFSC_VAR (prev_bb) != chain->var
+ || BB_IFSC_TRUE_EDGE (prev_bb)->dest != chain->true_dest)
+ break;
+
+ /* Add prev_bb at beginning of chain. */
+ VEC_safe_push (tree, heap, chain->constants, BB_IFSC_CONSTANT (prev_bb));
+ BB_IFSC_CHAINED (prev_bb) = true;
+ chain->first = prev_bb;
+ }
+}
+
+/* Grow if-chain containing bb. */
+
+static void
+grow_if_chain (basic_block bb, struct if_chain *chain)
+{
+ /* Initialize chain to empty. */
+ VEC_truncate (tree, chain->constants, 0);
+ VEC_truncate (tree, chain->unique_constants, 0);
+
+ /* bb is already part of another chain. */
+ if (BB_IFSC_CHAINED (bb))
+ return;
+
+ analyze_bb (bb);
+
+ /* bb is not fit to be part of a chain. */
+ if (BB_IFSC_VAR (bb) == NULL_TREE)
+ return;
+
+ /* Set bb as initial part of the chain. */
+ VEC_safe_push (tree, heap, chain->constants, BB_IFSC_CONSTANT (bb));
+ chain->first = chain->last = bb;
+ chain->var = BB_IFSC_VAR (bb);
+ chain->true_dest = BB_IFSC_TRUE_EDGE (bb)->dest;
+
+ /* bb is part of a chain now. */
+ BB_IFSC_CHAINED (bb) = true;
+
+ /* Grow chain to its maximum size. */
+ grow_if_chain_forward (chain);
+ grow_if_chain_backward (chain);
+
+ /* Sort constants and skip duplicates. */
+ sort_constants (chain->constants, &chain->unique_constants);
+}
+
+static void
+dump_tree_vector (VEC (tree, heap) *vec)
+{
+ unsigned int ix;
+ tree constant;
+
+ for (ix = 0; VEC_iterate (tree, vec, ix, constant); ix++)
+ {
+ if (ix != 0)
+ fprintf (dump_file, " ");
+ print_generic_expr (dump_file, constant, 0);
+ }
+ fprintf (dump_file, "\n");
+}
+
+/* Dump if-chain to dump_file. */
+
+static void
+dump_if_chain (struct if_chain *chain)
+{
+ if (!dump_file)
+ return;
+
+ fprintf (dump_file, "var: ");
+ print_generic_expr (dump_file, chain->var, 0);
+ fprintf (dump_file, "\n");
+ fprintf (dump_file, "first: <bb %d>\n", chain->first->index);
+ fprintf (dump_file, "true: <bb %d>\n", chain->true_dest->index);
+ fprintf (dump_file, "last: <bb %d>\n",chain->last->index);
+
+ fprintf (dump_file, "constants: ");
+ dump_tree_vector (chain->constants);
+
+ if (VEC_length (tree, chain->unique_constants)
+ != VEC_length (tree, chain->constants))
+ {
+ fprintf (dump_file, "unique_constants: ");
+ dump_tree_vector (chain->unique_constants);
+ }
+}
+
+/* Remove redundant bbs and edges. */
+
+static void
+remove_redundant_bbs_and_edges (struct if_chain *chain, int *false_prob)
+{
+ basic_block bb, next;
+ edge true_edge, false_edge;
+
+ for (bb = chain->first;; bb = next)
+ {
+ true_edge = BB_IFSC_TRUE_EDGE (bb);
+ false_edge = BB_IFSC_FALSE_EDGE (bb);
+
+ /* Determine next, before we delete false_edge. */
+ next = false_edge->dest;
+
+ /* Accumulate probability. */
+ *false_prob = (*false_prob * false_edge->probability) / REG_BR_PROB_BASE;
+
+ /* Don't remove the new true_edge. */
+ if (bb != chain->first)
+ remove_edge (true_edge);
+
+ /* Don't remove the new false_edge. */
+ if (bb != chain->last)
+ remove_edge (false_edge);
+
+ /* Don't remove the first bb. */
+ if (bb != chain->first)
+ delete_basic_block (bb);
+
+ /* Stop after last. */
+ if (bb == chain->last)
+ break;
+ }
+}
+
+/* Update control flow graph. */
+
+static void
+update_cfg (struct if_chain *chain)
+{
+ edge true_edge, false_edge;
+ int false_prob;
+ int flags_mask = ~(EDGE_FALLTHRU|EDGE_TRUE_VALUE|EDGE_FALSE_VALUE);
+
+ /* We keep these 2 edges, and remove the rest. We need this specific
+ false_edge, because a phi in chain->last->dest might reference (the index
+ of) this edge. For true_edge, we could pick any of them. */
+ true_edge = BB_IFSC_TRUE_EDGE (chain->first);
+ false_edge = BB_IFSC_FALSE_EDGE (chain->last);
+
+ /* Update true edge. */
+ true_edge->flags &= flags_mask;
+
+ /* Update false edge. */
+ redirect_edge_pred (false_edge, chain->first);
+ false_edge->flags &= flags_mask;
+
+ false_prob = REG_BR_PROB_BASE;
+ remove_redundant_bbs_and_edges (chain, &false_prob);
+
+ /* Repair probabilities. */
+ true_edge->probability = REG_BR_PROB_BASE - false_prob;
+ false_edge->probability = false_prob;
+
+ /* Force recalculation of dominance info. */
+ free_dominance_info (CDI_DOMINATORS);
+ free_dominance_info (CDI_POST_DOMINATORS);
+}
+
+/* Create switch statement. Borrows from gimplify_switch_expr. */
+
+static void
+convert_if_chain_to_switch (struct if_chain *chain)
+{
+ tree label_decl_true, label_decl_false;
+ gimple label_true, label_false, gimple_switch;
+ gimple_stmt_iterator gsi;
+ tree default_case, other_case, constant;
+ unsigned int ix;
+ VEC (tree, heap) *labels;
+
+ labels = VEC_alloc (tree, heap, 8);
+
+ /* Create and insert true jump label. */
+ label_decl_true = create_artificial_label (UNKNOWN_LOCATION);
+ label_true = gimple_build_label (label_decl_true);
+ gsi = gsi_start_bb (chain->true_dest);
+ gsi_insert_before (&gsi, label_true, GSI_SAME_STMT);
+
+ /* Create and insert false jump label. */
+ label_decl_false = create_artificial_label (UNKNOWN_LOCATION);
+ label_false = gimple_build_label (label_decl_false);
+ gsi = gsi_start_bb (BB_IFSC_FALSE_EDGE (chain->last)->dest);
+ gsi_insert_before (&gsi, label_false, GSI_SAME_STMT);
+
+ /* Create default case label. */
+ default_case = build3 (CASE_LABEL_EXPR, void_type_node,
+ NULL_TREE, NULL_TREE,
+ label_decl_false);
+
+ /* Create case labels. */
+ for (ix = 0; VEC_iterate (tree, chain->unique_constants, ix, constant); ix++)
+ {
+ /* TODO: use ranges, as in gimplify_switch_expr. */
+ other_case = build3 (CASE_LABEL_EXPR, void_type_node,
+ constant, NULL_TREE,
+ label_decl_true);
+ VEC_safe_push (tree, heap, labels, other_case);
+ }
+
+ /* Create and insert switch. */
+ gimple_switch = gimple_build_switch_vec (chain->var, default_case, labels);
+ gsi = gsi_for_stmt (last_stmt (chain->first));
+ gsi_insert_before (&gsi, gimple_switch, GSI_SAME_STMT);
+
+ /* Remove now obsolete if. */
+ gsi_remove (&gsi, true);
+
+ VEC_free (tree, heap, labels);
+}
+
+/* Allocation and initialization. */
+
+static void
+init_pass (struct if_chain *chain)
+{
+ alloc_aux_for_blocks (sizeof (struct ifsc_info));
+
+ chain->constants = VEC_alloc (tree, heap, 8);
+ chain->unique_constants = VEC_alloc (tree, heap, 8);
+}
+
+/* Deallocation. */
+
+static void
+finish_pass (struct if_chain *chain)
+{
+ free_aux_for_blocks ();
+
+ VEC_free (tree, heap, chain->constants);
+ VEC_free (tree, heap, chain->unique_constants);
+}
+
+/* Find if-chains and convert them to switches. */
+
+static unsigned int
+do_if_to_switch (void)
+{
+ basic_block bb;
+ struct if_chain chain;
+ unsigned int convert_threshold = PARAM_VALUE (PARAM_IF_TO_SWITCH_THRESHOLD);
+
+ init_pass (&chain);
+
+ for (bb = cfun->cfg->x_entry_block_ptr->next_bb;
+ bb != cfun->cfg->x_exit_block_ptr;)
+ {
+ grow_if_chain (bb, &chain);
+
+ do
+ bb = bb->next_bb;
+ while (BB_IFSC_CHAINED (bb));
+
+ /* Determine if the chain is long enough. */
+ if (VEC_length (tree, chain.unique_constants) < convert_threshold)
+ continue;
+
+ dump_if_chain (&chain);
+
+ convert_if_chain_to_switch (&chain);
+
+ update_cfg (&chain);
+ }
+
+ finish_pass (&chain);
+
+ return 0;
+}
+
+/* The pass gate. */
+
+static bool
+if_to_switch_gate (void)
+{
+ return flag_tree_if_to_switch_conversion;
+}
+
+/* The pass definition. */
+
+struct gimple_opt_pass pass_if_to_switch =
+{
+ {
+ GIMPLE_PASS,
+ "iftoswitch", /* name */
+ if_to_switch_gate, /* gate */
+ do_if_to_switch, /* execute */
+ NULL, /* sub */
+ NULL, /* next */
+ 0, /* static_pass_number */
+ TV_TREE_SWITCH_CONVERSION, /* tv_id */
+ PROP_cfg | PROP_ssa, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_update_ssa | TODO_dump_func
+ | TODO_ggc_collect | TODO_verify_ssa /* todo_flags_finish */
+ }
+};
Index: gcc-4_5-branch/gcc/tree-pass.h
===================================================================
--- gcc-4_5-branch.orig/gcc/tree-pass.h
+++ gcc-4_5-branch/gcc/tree-pass.h
@@ -560,6 +560,7 @@ extern struct gimple_opt_pass pass_inlin
extern struct gimple_opt_pass pass_all_early_optimizations;
extern struct gimple_opt_pass pass_update_address_taken;
extern struct gimple_opt_pass pass_convert_switch;
+extern struct gimple_opt_pass pass_if_to_switch;
/* The root of the compilation pass tree, once constructed. */
extern struct opt_pass *all_passes, *all_small_ipa_passes, *all_lowering_passes,

View File

@ -0,0 +1,409 @@
2010-02-04 Tom de Vries <tom@codesourcery.com>
gcc/
stmt.c (set_jump_prob): Fix assert condition.
2010-01-27 Tom de Vries <tom@codesourcery.com>
gcc/
stmt.c (rtx_seq_cost): Use insn_rtx_cost instead of rtx_cost.
2010-01-26 Tom de Vries <tom@codesourcery.com>
gcc/
* stmt.c (struct case_bit_test): Add rev_hi and rev_lo field.
* stmt.c (emit_case_bit_test_jump): New function.
* stmt.c (rtx_seq_cost): New function.
* stmt.c (choose_case_bit_test_expand_method): New function.
* stmt.c (set_bit): New function.
* stmt.c (emit_case_bit_test): Adjust comment.
* stmt.c (emit_case_bit_test): Set and update rev_hi and rev_lo fields.
* stmt.c (emit_case_bit_test): Use set_bit.
* stmt.c (emit_case_bit_test): Use choose_case_bit_test_expand_method.
* stmt.c (emit_case_bit_test): Use emit_case_bit_test_jump.
* testsuite/gcc.dg/switch-bittest.c: New test.
2010-01-25 Tom de Vries <tom@codesourcery.com>
gcc/
* stmt.c (emit_case_bit_tests): Change prototype.
* stmt.c (struct case_bit_test): Add prob field.
* stmt.c (get_label_prob): New function.
* stmt.c (set_jump_prob): New function.
* stmt.c (emit_case_bit_tests): Use get_label_prob.
* stmt.c (emit_case_bit_tests): Set prob field.
* stmt.c (emit_case_bit_tests): Use set_jump_prob.
* stmt.c (expand_case): Add new args to emit_case_bit_tests invocation.
* testsuite/gcc.dg/switch-prob.c: Add test.
=== modified file 'gcc/stmt.c'
Index: gcc-4_5-branch/gcc/stmt.c
===================================================================
--- gcc-4_5-branch.orig/gcc/stmt.c
+++ gcc-4_5-branch/gcc/stmt.c
@@ -117,7 +117,8 @@ static void expand_value_return (rtx);
static int estimate_case_costs (case_node_ptr);
static bool lshift_cheap_p (void);
static int case_bit_test_cmp (const void *, const void *);
-static void emit_case_bit_tests (tree, tree, tree, tree, case_node_ptr, rtx);
+static void emit_case_bit_tests (tree, tree, tree, tree, case_node_ptr, tree,
+ rtx, basic_block);
static void balance_case_nodes (case_node_ptr *, case_node_ptr);
static int node_has_low_bound (case_node_ptr, tree);
static int node_has_high_bound (case_node_ptr, tree);
@@ -2107,8 +2108,11 @@ struct case_bit_test
{
HOST_WIDE_INT hi;
HOST_WIDE_INT lo;
+ HOST_WIDE_INT rev_hi;
+ HOST_WIDE_INT rev_lo;
rtx label;
int bits;
+ int prob;
};
/* Determine whether "1 << x" is relatively cheap in word_mode. */
@@ -2148,10 +2152,193 @@ case_bit_test_cmp (const void *p1, const
return CODE_LABEL_NUMBER (d2->label) - CODE_LABEL_NUMBER (d1->label);
}
+/* Emit a bit test and a conditional jump. */
+
+static void
+emit_case_bit_test_jump (unsigned int count, rtx index, rtx label,
+ unsigned int method, HOST_WIDE_INT hi,
+ HOST_WIDE_INT lo, HOST_WIDE_INT rev_hi,
+ HOST_WIDE_INT rev_lo)
+{
+ rtx expr;
+
+ if (method == 1)
+ {
+ /* (1 << index). */
+ if (count == 0)
+ index = expand_binop (word_mode, ashl_optab, const1_rtx,
+ index, NULL_RTX, 1, OPTAB_WIDEN);
+ /* CST. */
+ expr = immed_double_const (lo, hi, word_mode);
+ /* ((1 << index) & CST). */
+ expr = expand_binop (word_mode, and_optab, index, expr,
+ NULL_RTX, 1, OPTAB_WIDEN);
+ /* if (((1 << index) & CST)). */
+ emit_cmp_and_jump_insns (expr, const0_rtx, NE, NULL_RTX,
+ word_mode, 1, label);
+ }
+ else if (method == 2)
+ {
+ /* (bit_reverse (CST)) */
+ expr = immed_double_const (rev_lo, rev_hi, word_mode);
+ /* ((bit_reverse (CST)) << index) */
+ expr = expand_binop (word_mode, ashl_optab, expr,
+ index, NULL_RTX, 1, OPTAB_WIDEN);
+ /* if (((bit_reverse (CST)) << index) < 0). */
+ emit_cmp_and_jump_insns (expr, const0_rtx, LT, NULL_RTX,
+ word_mode, 0, label);
+ }
+ else
+ gcc_unreachable ();
+}
+
+/* Return the cost of rtx sequence SEQ. The sequence is supposed to contain one
+ jump, which has no effect in the cost. */
+
+static unsigned int
+rtx_seq_cost (rtx seq)
+{
+ rtx one;
+ unsigned int nr_branches = 0;
+ unsigned int sum = 0, cost;
+
+ for (one = seq; one != NULL_RTX; one = NEXT_INSN (one))
+ if (JUMP_P (one))
+ nr_branches++;
+ else
+ {
+ cost = insn_rtx_cost (PATTERN (one), optimize_insn_for_speed_p ());
+ if (dump_file)
+ {
+ print_rtl_single (dump_file, one);
+ fprintf (dump_file, "cost: %u\n", cost);
+ }
+ sum += cost;
+ }
+
+ gcc_assert (nr_branches == 1);
+
+ if (dump_file)
+ fprintf (dump_file, "total cost: %u\n", sum);
+ return sum;
+}
+
+/* Generate the rtx sequences for 2 bit test expansion methods, measure the cost
+ and choose the cheapest. */
+
+static unsigned int
+choose_case_bit_test_expand_method (rtx label)
+{
+ rtx seq, index;
+ unsigned int cost[2];
+ static bool method_known = false;
+ static unsigned int method;
+
+ /* If already known, return the method. */
+ if (method_known)
+ return method;
+
+ index = gen_rtx_REG (word_mode, 10000);
+
+ for (method = 1; method <= 2; ++method)
+ {
+ start_sequence ();
+ emit_case_bit_test_jump (0, index, label, method, 0, 0x0f0f0f0f, 0,
+ 0x0f0f0f0f);
+ seq = get_insns ();
+ end_sequence ();
+ cost[method - 1] = rtx_seq_cost (seq);
+ }
+
+ /* Determine method based on heuristic. */
+ method = ((cost[1] < cost[0]) ? 1 : 0) + 1;
+
+ /* Save and return method. */
+ method_known = true;
+ return method;
+}
+
+/* Get the edge probability of the edge from SRC to LABEL_DECL. */
+
+static int
+get_label_prob (basic_block src, tree label_decl)
+{
+ basic_block dest;
+ int prob = 0, nr_prob = 0;
+ unsigned int i;
+ edge e;
+
+ if (label_decl == NULL_TREE)
+ return 0;
+
+ dest = VEC_index (basic_block, label_to_block_map,
+ LABEL_DECL_UID (label_decl));
+
+ for (i = 0; i < EDGE_COUNT (src->succs); ++i)
+ {
+ e = EDGE_SUCC (src, i);
+
+ if (e->dest != dest)
+ continue;
+
+ prob += e->probability;
+ nr_prob++;
+ }
+
+ gcc_assert (nr_prob == 1);
+
+ return prob;
+}
+
+/* Add probability note with scaled PROB to JUMP and update INV_SCALE. This
+ function is intended to be used with a series of conditional jumps to L[i]
+ where the probabilities p[i] to get to L[i] are known, and the jump
+ probabilities j[i] need to be computed.
+
+ The algorithm to calculate the probabilities is
+
+ scale = REG_BR_PROB_BASE;
+ for (i = 0; i < n; ++i)
+ {
+ j[i] = p[i] * scale / REG_BR_PROB_BASE;
+ f[i] = REG_BR_PROB_BASE - j[i];
+ scale = scale / (f[i] / REG_BR_PROB_BASE);
+ }
+
+ The implementation uses inv_scale (REG_BR_PROB_BASE / scale) instead of
+ scale, because scale tends to grow bigger than REG_BR_PROB_BASE. */
+
+static void
+set_jump_prob (rtx jump, int prob, int *inv_scale)
+{
+ /* j[i] = p[i] * scale / REG_BR_PROB_BASE. */
+ int jump_prob = prob * REG_BR_PROB_BASE / *inv_scale;
+ /* f[i] = REG_BR_PROB_BASE - j[i]. */
+ int fallthrough_prob = REG_BR_PROB_BASE - jump_prob;
+
+ gcc_assert (jump_prob <= REG_BR_PROB_BASE);
+ add_reg_note (jump, REG_BR_PROB, GEN_INT (jump_prob));
+
+ /* scale = scale / (f[i] / REG_BR_PROB_BASE). */
+ *inv_scale = *inv_scale * fallthrough_prob / REG_BR_PROB_BASE;
+}
+
+/* Set bit in hwi hi/lo pair. */
+
+static void
+set_bit (HOST_WIDE_INT *hi, HOST_WIDE_INT *lo, unsigned int j)
+{
+ if (j >= HOST_BITS_PER_WIDE_INT)
+ *hi |= (HOST_WIDE_INT) 1 << (j - HOST_BITS_PER_INT);
+ else
+ *lo |= (HOST_WIDE_INT) 1 << j;
+}
+
/* Expand a switch statement by a short sequence of bit-wise
comparisons. "switch(x)" is effectively converted into
- "if ((1 << (x-MINVAL)) & CST)" where CST and MINVAL are
- integer constants.
+ "if ((1 << (x-MINVAL)) & CST)" or
+ "if (((bit_reverse (CST)) << (x-MINVAL)) < 0)", where CST
+ and MINVAL are integer constants.
INDEX_EXPR is the value being switched on, which is of
type INDEX_TYPE. MINVAL is the lowest case value of in
@@ -2165,14 +2352,17 @@ case_bit_test_cmp (const void *p1, const
static void
emit_case_bit_tests (tree index_type, tree index_expr, tree minval,
- tree range, case_node_ptr nodes, rtx default_label)
+ tree range, case_node_ptr nodes, tree default_label_decl,
+ rtx default_label, basic_block bb)
{
struct case_bit_test test[MAX_CASE_BIT_TESTS];
enum machine_mode mode;
rtx expr, index, label;
unsigned int i,j,lo,hi;
struct case_node *n;
- unsigned int count;
+ unsigned int count, method;
+ int inv_scale = REG_BR_PROB_BASE;
+ int default_prob = get_label_prob (bb, default_label_decl);
count = 0;
for (n = nodes; n; n = n->right)
@@ -2187,8 +2377,11 @@ emit_case_bit_tests (tree index_type, tr
gcc_assert (count < MAX_CASE_BIT_TESTS);
test[i].hi = 0;
test[i].lo = 0;
+ test[i].rev_hi = 0;
+ test[i].rev_lo = 0;
test[i].label = label;
test[i].bits = 1;
+ test[i].prob = get_label_prob (bb, n->code_label);
count++;
}
else
@@ -2199,10 +2392,11 @@ emit_case_bit_tests (tree index_type, tr
hi = tree_low_cst (fold_build2 (MINUS_EXPR, index_type,
n->high, minval), 1);
for (j = lo; j <= hi; j++)
- if (j >= HOST_BITS_PER_WIDE_INT)
- test[i].hi |= (HOST_WIDE_INT) 1 << (j - HOST_BITS_PER_INT);
- else
- test[i].lo |= (HOST_WIDE_INT) 1 << j;
+ {
+ set_bit (&test[i].hi, &test[i].lo, j);
+ set_bit (&test[i].rev_hi, &test[i].rev_lo,
+ GET_MODE_BITSIZE (word_mode) - j - 1);
+ }
}
qsort (test, count, sizeof(*test), case_bit_test_cmp);
@@ -2216,20 +2410,20 @@ emit_case_bit_tests (tree index_type, tr
mode = TYPE_MODE (index_type);
expr = expand_normal (range);
if (default_label)
- emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
- default_label);
+ {
+ emit_cmp_and_jump_insns (index, expr, GTU, NULL_RTX, mode, 1,
+ default_label);
+ set_jump_prob (get_last_insn (), default_prob / 2, &inv_scale);
+ }
index = convert_to_mode (word_mode, index, 0);
- index = expand_binop (word_mode, ashl_optab, const1_rtx,
- index, NULL_RTX, 1, OPTAB_WIDEN);
+ method = choose_case_bit_test_expand_method (test[0].label);
for (i = 0; i < count; i++)
{
- expr = immed_double_const (test[i].lo, test[i].hi, word_mode);
- expr = expand_binop (word_mode, and_optab, index, expr,
- NULL_RTX, 1, OPTAB_WIDEN);
- emit_cmp_and_jump_insns (expr, const0_rtx, NE, NULL_RTX,
- word_mode, 1, test[i].label);
+ emit_case_bit_test_jump (i, index, test[i].label, method, test[i].hi,
+ test[i].lo, test[i].rev_hi, test[i].rev_lo);
+ set_jump_prob (get_last_insn (), test[i].prob, &inv_scale);
}
if (default_label)
@@ -2400,7 +2594,8 @@ expand_case (gimple stmt)
range = maxval;
}
emit_case_bit_tests (index_type, index_expr, minval, range,
- case_list, default_label);
+ case_list, default_label_decl, default_label,
+ gimple_bb (stmt));
}
/* If range of values is much bigger than number of values,
Index: gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-bittest.c
===================================================================
--- /dev/null
+++ gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-bittest.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-expand" } */
+
+const char *
+f (const char *p)
+{
+ while (1)
+ {
+ switch (*p)
+ {
+ case 9:
+ case 10:
+ case 13:
+ case 32:
+ break;
+ default:
+ return p;
+ }
+ }
+}
+
+/* { dg-final { scan-rtl-dump-times "jump_insn" 4 "expand" { target mips*-*-* } } } */
+/* { dg-final { scan-rtl-dump-times "REG_BR_PROB" 2 "expand" { target mips*-*-* } } } */
+/* { dg-final { scan-rtl-dump-times "lt " 1 "expand" { target mips*-*-* } } } */
+/* { dg-final { cleanup-rtl-dump "expand" } } */
Index: gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-prob.c
===================================================================
--- /dev/null
+++ gcc-4_5-branch/gcc/testsuite/gcc.dg/switch-prob.c
@@ -0,0 +1,25 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-rtl-expand" } */
+
+const char *
+f (const char *p)
+{
+ while (1)
+ {
+ switch (*p)
+ {
+ case 9:
+ case 10:
+ case 13:
+ case 32:
+ break;
+ default:
+ return p;
+ }
+ }
+}
+
+/* { dg-final { scan-rtl-dump-times "jump_insn" 4 "expand" { target mips*-*-* } } } */
+/* { dg-final { scan-rtl-dump-times "REG_BR_PROB" 2 "expand" { target mips*-*-* } } } */
+/* { dg-final { scan-rtl-dump-times "heuristics" 0 "expand" { target mips*-*-* } } } */
+/* { dg-final { cleanup-rtl-dump "expand" } } */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,74 @@
2011-01-11 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/t-arm: Fix up last commit.
2011-01-11 Ramana Radhakrishnan <ramana.radhakrishnan@arm.com>
* config/arm/t-arm: Update MD_INCLUDES to include
all the files correctly.
* config/arm/arm.md: Update comments.
=== modified file 'gcc/config/arm/arm.md'
--- old/gcc/config/arm/arm.md 2011-02-22 11:38:56 +0000
+++ new/gcc/config/arm/arm.md 2011-03-01 14:32:39 +0000
@@ -11246,6 +11246,7 @@
"
)
+;; Make sure that the includes are reflected in MD_INCLUDES.
;; Load the load/store multiple patterns
(include "ldmstm.md")
;; Load the FPA co-processor patterns
=== modified file 'gcc/config/arm/t-arm'
--- old/gcc/config/arm/t-arm 2010-08-16 09:41:58 +0000
+++ new/gcc/config/arm/t-arm 2011-01-11 21:01:30 +0000
@@ -18,20 +18,33 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-MD_INCLUDES= $(srcdir)/config/arm/arm-tune.md \
- $(srcdir)/config/arm/predicates.md \
- $(srcdir)/config/arm/arm-generic.md \
- $(srcdir)/config/arm/arm1020e.md \
- $(srcdir)/config/arm/arm1026ejs.md \
- $(srcdir)/config/arm/arm1136jfs.md \
- $(srcdir)/config/arm/arm926ejs.md \
- $(srcdir)/config/arm/cirrus.md \
- $(srcdir)/config/arm/fpa.md \
- $(srcdir)/config/arm/vec-common.md \
- $(srcdir)/config/arm/iwmmxt.md \
- $(srcdir)/config/arm/vfp.md \
- $(srcdir)/config/arm/neon.md \
- $(srcdir)/config/arm/thumb2.md
+MD_INCLUDES= $(srcdir)/config/arm/arm-tune.md \
+ $(srcdir)/config/arm/predicates.md \
+ $(srcdir)/config/arm/arm-generic.md \
+ $(srcdir)/config/arm/arm1020e.md \
+ $(srcdir)/config/arm/arm1026ejs.md \
+ $(srcdir)/config/arm/arm1136jfs.md \
+ $(srcdir)/config/arm/arm926ejs.md \
+ $(srcdir)/config/arm/cirrus.md \
+ $(srcdir)/config/arm/fpa.md \
+ $(srcdir)/config/arm/vec-common.md \
+ $(srcdir)/config/arm/iwmmxt.md \
+ $(srcdir)/config/arm/vfp.md \
+ $(srcdir)/config/arm/cortex-a5.md \
+ $(srcdir)/config/arm/cortex-a8.md \
+ $(srcdir)/config/arm/cortex-a9.md \
+ $(srcdir)/config/arm/cortex-a9-neon.md \
+ $(srcdir)/config/arm/cortex-r4.md \
+ $(srcdir)/config/arm/cortex-r4f.md \
+ $(srcdir)/config/arm/cortex-m4.md \
+ $(srcdir)/config/arm/cortex-m4-fpu.md \
+ $(srcdir)/config/arm/vfp11.md \
+ $(srcdir)/config/arm/ldmstm.md \
+ $(srcdir)/config/arm/thumb2.md \
+ $(srcdir)/config/arm/neon.md \
+ $(srcdir)/config/arm/sync.md \
+ $(srcdir)/config/arm/cortex-a8-neon.md \
+ $(srcdir)/config/arm/constraints.md
LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _thumb1_case_sqi _thumb1_case_uqi _thumb1_case_shi \

View File

@ -0,0 +1,101 @@
2011-02-24 Chung-Lin Tang <cltang@codesourcery.com>
Backport from FSF mainline:
2010-08-10 Bernd Schmidt <bernds@codesourcery.com>
PR bootstrap/45177
* config/arm/arm.c (multiple_operation_profitable_p): Move xscale
test here from arm_gen_load_multiple_1.
(arm_gen_load_multiple_1, arm_gen_store_multiple_1): Use
multiple_operation_profitable_p.
=== modified file 'gcc/config/arm/arm.c'
--- old/gcc/config/arm/arm.c 2011-02-22 11:38:56 +0000
+++ new/gcc/config/arm/arm.c 2011-02-24 17:30:32 +0000
@@ -9728,6 +9728,36 @@
if (nops == 2 && arm_ld_sched && add_offset != 0)
return false;
+ /* XScale has load-store double instructions, but they have stricter
+ alignment requirements than load-store multiple, so we cannot
+ use them.
+
+ For XScale ldm requires 2 + NREGS cycles to complete and blocks
+ the pipeline until completion.
+
+ NREGS CYCLES
+ 1 3
+ 2 4
+ 3 5
+ 4 6
+
+ An ldr instruction takes 1-3 cycles, but does not block the
+ pipeline.
+
+ NREGS CYCLES
+ 1 1-3
+ 2 2-6
+ 3 3-9
+ 4 4-12
+
+ Best case ldr will always win. However, the more ldr instructions
+ we issue, the less likely we are to be able to schedule them well.
+ Using ldr instructions also increases code size.
+
+ As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
+ for counts of 3 or 4 regs. */
+ if (nops <= 2 && arm_tune_xscale && !optimize_size)
+ return false;
return true;
}
@@ -10086,35 +10116,7 @@
int i = 0, j;
rtx result;
- /* XScale has load-store double instructions, but they have stricter
- alignment requirements than load-store multiple, so we cannot
- use them.
-
- For XScale ldm requires 2 + NREGS cycles to complete and blocks
- the pipeline until completion.
-
- NREGS CYCLES
- 1 3
- 2 4
- 3 5
- 4 6
-
- An ldr instruction takes 1-3 cycles, but does not block the
- pipeline.
-
- NREGS CYCLES
- 1 1-3
- 2 2-6
- 3 3-9
- 4 4-12
-
- Best case ldr will always win. However, the more ldr instructions
- we issue, the less likely we are to be able to schedule them well.
- Using ldr instructions also increases code size.
-
- As a compromise, we use ldr for counts of 1 or 2 regs, and ldm
- for counts of 3 or 4 regs. */
- if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size))
+ if (low_irq_latency || !multiple_operation_profitable_p (false, count, 0))
{
rtx seq;
@@ -10166,9 +10168,7 @@
if (GET_CODE (basereg) == PLUS)
basereg = XEXP (basereg, 0);
- /* See arm_gen_load_multiple_1 for discussion of
- the pros/cons of ldm/stm usage for XScale. */
- if (low_irq_latency || (arm_tune_xscale && count <= 2 && ! optimize_size))
+ if (low_irq_latency || !multiple_operation_profitable_p (false, count, 0))
{
rtx seq;

View File

@ -0,0 +1,64 @@
2011-02-02 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
PR target/47551
* config/arm/arm.c (coproc_secondary_reload_class): Handle
structure modes. Don't check neon_vector_mem_operand for
vector or structure modes.
gcc/testsuite/
PR target/47551
* gcc.target/arm/neon-modes-2.c: New test.
=== modified file 'gcc/config/arm/arm.c'
--- old/gcc/config/arm/arm.c 2011-02-24 17:30:32 +0000
+++ new/gcc/config/arm/arm.c 2011-03-02 11:29:06 +0000
@@ -9303,11 +9303,14 @@
return GENERAL_REGS;
}
+ /* The neon move patterns handle all legitimate vector and struct
+ addresses. */
if (TARGET_NEON
+ && MEM_P (x)
&& (GET_MODE_CLASS (mode) == MODE_VECTOR_INT
- || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT)
- && neon_vector_mem_operand (x, 0))
- return NO_REGS;
+ || GET_MODE_CLASS (mode) == MODE_VECTOR_FLOAT
+ || VALID_NEON_STRUCT_MODE (mode)))
+ return NO_REGS;
if (arm_coproc_mem_operand (x, wb) || s_register_operand (x, mode))
return NO_REGS;
=== added file 'gcc/testsuite/gcc.target/arm/neon-modes-2.c'
--- old/gcc/testsuite/gcc.target/arm/neon-modes-2.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/arm/neon-modes-2.c 2011-02-02 13:48:10 +0000
@@ -0,0 +1,24 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O1" } */
+/* { dg-add-options arm_neon } */
+
+#include "arm_neon.h"
+
+#define SETUP(A) x##A = vld3_u32 (ptr + A * 0x20)
+#define MODIFY(A) x##A = vld3_lane_u32 (ptr + A * 0x20 + 0x10, x##A, 1)
+#define STORE(A) vst3_u32 (ptr + A * 0x20, x##A)
+
+#define MANY(A) A (0), A (1), A (2), A (3), A (4), A (5)
+
+void
+bar (uint32_t *ptr, int y)
+{
+ uint32x2x3_t MANY (SETUP);
+ int *x = __builtin_alloca (y);
+ int z[0x1000];
+ foo (x, z);
+ MANY (MODIFY);
+ foo (x, z);
+ MANY (STORE);
+}

View File

@ -0,0 +1,40 @@
2011-02-02 Richard Sandiford <richard.sandiford@linaro.org>
gcc/testsuite/
PR target/47553
* gcc.target/arm/neon-vld-1.c: New test.
gcc/
PR target/47553
* config/arm/predicates.md (neon_lane_number): Accept 0..15.
=== modified file 'gcc/config/arm/predicates.md'
--- old/gcc/config/arm/predicates.md 2011-02-08 12:07:29 +0000
+++ new/gcc/config/arm/predicates.md 2011-03-02 12:28:41 +0000
@@ -607,7 +607,7 @@
;; TODO: We could check lane numbers more precisely based on the mode.
(define_predicate "neon_lane_number"
(and (match_code "const_int")
- (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 7")))
+ (match_test "INTVAL (op) >= 0 && INTVAL (op) <= 15")))
;; Predicates for named expanders that overlap multiple ISAs.
(define_predicate "cmpdi_operand"
=== added file 'gcc/testsuite/gcc.target/arm/neon-vld-1.c'
--- old/gcc/testsuite/gcc.target/arm/neon-vld-1.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.target/arm/neon-vld-1.c 2011-02-02 13:57:54 +0000
@@ -0,0 +1,13 @@
+/* { dg-do compile } */
+/* { dg-require-effective-target arm_neon_ok } */
+/* { dg-options "-O1" } */
+/* { dg-add-options arm_neon } */
+
+#include <arm_neon.h>
+
+uint8x16_t
+foo (uint8_t *a, uint8x16_t b)
+{
+ vst1q_lane_u8 (a, b, 14);
+ return vld1q_lane_u8 (a + 0x100, b, 15);
+}

View File

@ -0,0 +1,84 @@
2011-02-02 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
Backport from mainline:
2011-01-23 Bernd Schmidt <bernds@codesourcery.com>
Richard Sandiford <rdsandiford@googlemail.com>
PR rtl-optimization/47166
* reload1.c (emit_reload_insns): Disable the spill_reg_store
mechanism for PRE_MODIFY and POST_MODIFY.
(inc_for_reload): For PRE_MODIFY, return the insn that sets the
reloadreg.
gcc/testsuite/
* gcc.c-torture/execute/postmod-1.c: New test.
=== added file 'gcc/testsuite/gcc.c-torture/execute/postmod-1.c'
--- old/gcc/testsuite/gcc.c-torture/execute/postmod-1.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.c-torture/execute/postmod-1.c 2011-02-02 14:23:10 +0000
@@ -0,0 +1,62 @@
+#define DECLARE_ARRAY(A) array##A[0x10]
+#define DECLARE_COUNTER(A) counter##A = 0
+#define DECLARE_POINTER(A) *pointer##A = array##A + x
+/* Create a loop that allows post-modification of pointerA, followed by
+ a use of the post-modified address. */
+#define BEFORE(A) counter##A += *pointer##A, pointer##A += 3
+#define AFTER(A) counter##A += pointer##A[x]
+
+/* Set up the arrays so that one iteration of the loop sets the counter
+ to 3.0f. */
+#define INIT_ARRAY(A) array##A[1] = 1.0f, array##A[5] = 2.0f
+
+/* Check that the loop worked correctly for all values. */
+#define CHECK_ARRAY(A) exit_code |= (counter##A != 3.0f)
+
+/* Having 6 copies triggered the bug for ARM and Thumb. */
+#define MANY(A) A (0), A (1), A (2), A (3), A (4), A (5)
+
+/* Each addendA should be allocated a register. */
+#define INIT_VOLATILE(A) addend##A = vol
+#define ADD_VOLATILE(A) vol += addend##A
+
+/* Having 5 copies triggered the bug for ARM and Thumb. */
+#define MANY2(A) A (0), A (1), A (2), A (3), A (4)
+
+float MANY (DECLARE_ARRAY);
+float MANY (DECLARE_COUNTER);
+
+volatile int stop = 1;
+volatile int vol;
+
+void __attribute__((noinline))
+foo (int x)
+{
+ float MANY (DECLARE_POINTER);
+ int i;
+
+ do
+ {
+ MANY (BEFORE);
+ MANY (AFTER);
+ /* Create an inner loop that should ensure the code above
+ has registers free for reload inheritance. */
+ {
+ int MANY2 (INIT_VOLATILE);
+ for (i = 0; i < 10; i++)
+ MANY2 (ADD_VOLATILE);
+ }
+ }
+ while (!stop);
+}
+
+int
+main (void)
+{
+ int exit_code = 0;
+
+ MANY (INIT_ARRAY);
+ foo (1);
+ MANY (CHECK_ARRAY);
+ return exit_code;
+}

View File

@ -0,0 +1,63 @@
2011-02-11 Richard Sandiford <richard.sandiford@linaro.org>
gcc/
* cse.c (count_reg_usage): Check side_effects_p. Remove the
separate check for volatile asms.
gcc/testsuite/
* gcc.dg/torture/volatile-pic-1.c: New test.
=== modified file 'gcc/cse.c'
--- old/gcc/cse.c 2010-11-26 12:03:32 +0000
+++ new/gcc/cse.c 2011-02-11 09:27:19 +0000
@@ -6634,9 +6634,10 @@
case CALL_INSN:
case INSN:
case JUMP_INSN:
- /* We expect dest to be NULL_RTX here. If the insn may trap, mark
- this fact by setting DEST to pc_rtx. */
- if (insn_could_throw_p (x))
+ /* We expect dest to be NULL_RTX here. If the insn may trap,
+ or if it cannot be deleted due to side-effects, mark this fact
+ by setting DEST to pc_rtx. */
+ if (insn_could_throw_p (x) || side_effects_p (PATTERN (x)))
dest = pc_rtx;
if (code == CALL_INSN)
count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
@@ -6676,10 +6677,6 @@
return;
case ASM_OPERANDS:
- /* If the asm is volatile, then this insn cannot be deleted,
- and so the inputs *must* be live. */
- if (MEM_VOLATILE_P (x))
- dest = NULL_RTX;
/* Iterate over just the inputs, not the constraints as well. */
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
=== added file 'gcc/testsuite/gcc.dg/torture/volatile-pic-1.c'
--- old/gcc/testsuite/gcc.dg/torture/volatile-pic-1.c 1970-01-01 00:00:00 +0000
+++ new/gcc/testsuite/gcc.dg/torture/volatile-pic-1.c 2011-02-11 09:27:19 +0000
@@ -0,0 +1,20 @@
+/* { dg-do run } */
+/* { dg-require-visibility "" } */
+/* { dg-require-effective-target fpic } */
+/* { dg-options "-fPIC" } */
+
+volatile int x __attribute__((visibility("hidden")));
+
+void __attribute__((noinline)) bar (void)
+{
+#if defined (__arm__)
+ asm volatile ("mov r3,%0" :: "r" (0xdeadbeef) : "r3");
+#endif
+ (void) x;
+}
+
+int main (void)
+{
+ bar ();
+ return 0;
+}

View File

@ -0,0 +1,83 @@
Index: a/gcc/cfgcleanup.c
===================================================================
--- a/gcc/cfgcleanup.c (revision 315947)
+++ b/gcc/cfgcleanup.c (working copy)
@@ -1179,13 +1179,19 @@ flow_find_head_matching_sequence (basic_
while (true)
{
-
- /* Ignore notes. */
+ /* Ignore notes, except NOTE_INSN_EPILOGUE_BEG. */
while (!NONDEBUG_INSN_P (i1) && i1 != BB_END (bb1))
- i1 = NEXT_INSN (i1);
-
+ {
+ if (NOTE_P (i1) && NOTE_KIND (i1) == NOTE_INSN_EPILOGUE_BEG)
+ break;
+ i1 = NEXT_INSN (i1);
+ }
while (!NONDEBUG_INSN_P (i2) && i2 != BB_END (bb2))
- i2 = NEXT_INSN (i2);
+ {
+ if (NOTE_P (i2) && NOTE_KIND (i2) == NOTE_INSN_EPILOGUE_BEG)
+ break;
+ i2 = NEXT_INSN (i2);
+ }
if (NOTE_P (i1) || NOTE_P (i2)
|| JUMP_P (i1) || JUMP_P (i2))
Index: a/gcc/cfglayout.c
===================================================================
--- a/gcc/cfglayout.c (revision 315947)
+++ b/gcc/cfglayout.c (working copy)
@@ -1295,6 +1295,16 @@ cfg_layout_initialize (unsigned int flag
bb->flags |= BB_NON_LOCAL_GOTO_TARGET;
}
+ FOR_EACH_BB (bb)
+ {
+ rtx insn;
+ FOR_BB_INSNS (bb, insn)
+ if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
+ {
+ bb->flags |= BB_EPILOGUE_BEGIN;
+ break;
+ }
+ }
cleanup_cfg (CLEANUP_CFGLAYOUT | flags);
}
Index: a/gcc/basic-block.h
===================================================================
--- a/gcc/basic-block.h (revision 315947)
+++ b/gcc/basic-block.h (working copy)
@@ -332,7 +332,11 @@ enum bb_flags
/* Set on blocks that cannot be threaded through.
Only used in cfgcleanup.c. */
- BB_NONTHREADABLE_BLOCK = 1 << 11
+ BB_NONTHREADABLE_BLOCK = 1 << 11,
+
+ /* Set on blocks that have a NOTE_INSN_EPILOGUE_BEGIN.
+ Only used in cfglayout mode. */
+ BB_EPILOGUE_BEGIN = 1 << 12
};
/* Dummy flag for convenience in the hot/cold partitioning code. */
Index: a/gcc/cfgrtl.c
===================================================================
--- a/gcc/cfgrtl.c (revision 315947)
+++ b/gcc/cfgrtl.c (working copy)
@@ -2707,7 +2707,10 @@ cfg_layout_can_merge_blocks_p (basic_blo
not allow us to redirect an edge by replacing a table jump. */
&& (!JUMP_P (BB_END (a))
|| ((!optimize || reload_completed)
- ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a)))));
+ ? simplejump_p (BB_END (a)) : onlyjump_p (BB_END (a))))
+ /* Don't separate a NOTE_INSN_EPILOGUE_BEG from its returnjump. */
+ && (!(b->flags & BB_EPILOGUE_BEGIN)
+ || returnjump_p (BB_END (b))));
}
/* Merge block A and B. The blocks must be mergeable. */

View File

@ -1,33 +0,0 @@
# by default c++ include directories are not relative to "--sysroot"
# which brings one trouble when using the toolchain in an environment
# where the build directory generating that toolchain doesn't exist,
# e.g. in sstate, machine specific sysroot and relocatable SDK
# toolchain. This patch now enables c++ include paths under sysroot.
# This way it's enough as long as "--sysroot" is correctly enabled
# in the new environment.
#
# Signed-off-by Kevin Tian <kevin.tian@intel.com>, 2010-12-30
diff --git a/gcc/cppdefault.c b/gcc/cppdefault.c
index 5024f48..9b47d1c 100644
--- a/gcc/cppdefault.c
+++ b/gcc/cppdefault.c
@@ -48,15 +48,15 @@ const struct default_include cpp_include_defaults[]
= {
#ifdef GPLUSPLUS_INCLUDE_DIR
/* Pick up GNU C++ generic include files. */
- { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 0, 0 },
+ { GPLUSPLUS_INCLUDE_DIR, "G++", 1, 1, 1, 0 },
#endif
#ifdef GPLUSPLUS_TOOL_INCLUDE_DIR
/* Pick up GNU C++ target-dependent include files. */
- { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 0, 1 },
+ { GPLUSPLUS_TOOL_INCLUDE_DIR, "G++", 1, 1, 1, 1 },
#endif
#ifdef GPLUSPLUS_BACKWARD_INCLUDE_DIR
/* Pick up GNU C++ backward and deprecated include files. */
- { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 0, 0 },
+ { GPLUSPLUS_BACKWARD_INCLUDE_DIR, "G++", 1, 1, 1, 0 },
#endif
#ifdef LOCAL_INCLUDE_DIR
/* /usr/local/include comes before the fixincluded header files. */