aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99339.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99339.patch')
-rw-r--r--meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99339.patch236
1 files changed, 236 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99339.patch b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99339.patch
new file mode 100644
index 0000000000..f4a8e80ab7
--- /dev/null
+++ b/meta-oe/recipes-devtools/gcc/gcc-4.5/linaro/gcc-4.5-linaro-r99339.patch
@@ -0,0 +1,236 @@
+ Backport from FSF mainline:
+
+ gcc/
+ * gengtype-lex.l: Add HARD_REG_SET.
+ * expr.c (expand_expr_real_1): Record writes to hard registers.
+ * function.h (rtl_data): Add asm_clobbers.
+ * ira.c (compute_regs_asm_clobbered): Use crtl->asm_clobbers.
+ (ira_setup_eliminable_regset): Remove regs_asm_clobbered.
+ Use crtl->asm_clobbers.
+
+ gcc/testsuite/
+ * gcc.target/arm/frame-pointer-1.c: New test.
+ * gcc.target/i386/pr9771-1.c: Move code out of main to allow frame
+ pointer elimination.
+
+2010-07-26 Julian Brown <julian@codesourcery.com>
+
+ Merge from Sourcery G++ 4.4:
+
+ 2009-06-23 Kazu Hirata <kazu@codesourcery.com>
+
+=== modified file 'gcc/expr.c'
+--- old/gcc/expr.c 2010-05-31 14:45:06 +0000
++++ new/gcc/expr.c 2010-08-12 13:51:16 +0000
+@@ -8458,6 +8458,19 @@
+ expand_decl_rtl:
+ gcc_assert (decl_rtl);
+ decl_rtl = copy_rtx (decl_rtl);
++ /* Record writes to register variables. */
++ if (modifier == EXPAND_WRITE && REG_P (decl_rtl)
++ && REGNO (decl_rtl) < FIRST_PSEUDO_REGISTER)
++ {
++ int i = REGNO (decl_rtl);
++ int nregs = hard_regno_nregs[i][GET_MODE (decl_rtl)];
++ while (nregs)
++ {
++ SET_HARD_REG_BIT (crtl->asm_clobbers, i);
++ i++;
++ nregs--;
++ }
++ }
+
+ /* Ensure variable marked as used even if it doesn't go through
+ a parser. If it hasn't be used yet, write out an external
+
+=== modified file 'gcc/function.h'
+--- old/gcc/function.h 2009-11-25 10:55:54 +0000
++++ new/gcc/function.h 2010-08-12 13:51:16 +0000
+@@ -25,6 +25,7 @@
+ #include "tree.h"
+ #include "hashtab.h"
+ #include "vecprim.h"
++#include "hard-reg-set.h"
+
+ /* Stack of pending (incomplete) sequences saved by `start_sequence'.
+ Each element describes one pending sequence.
+@@ -433,6 +434,12 @@
+ TREE_NOTHROW (current_function_decl) it is set even for overwritable
+ function where currently compiled version of it is nothrow. */
+ bool nothrow;
++
++ /* Like regs_ever_live, but 1 if a reg is set or clobbered from an
++ asm. Unlike regs_ever_live, elements of this array corresponding
++ to eliminable regs (like the frame pointer) are set if an asm
++ sets them. */
++ HARD_REG_SET asm_clobbers;
+ };
+
+ #define return_label (crtl->x_return_label)
+
+=== modified file 'gcc/gengtype-lex.l'
+--- old/gcc/gengtype-lex.l 2009-11-21 10:24:25 +0000
++++ new/gcc/gengtype-lex.l 2010-08-12 13:51:16 +0000
+@@ -49,7 +49,7 @@
+ ID [[:alpha:]_][[:alnum:]_]*
+ WS [[:space:]]+
+ HWS [ \t\r\v\f]*
+-IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t
++IWORD short|long|(un)?signed|char|int|HOST_WIDE_INT|HOST_WIDEST_INT|bool|size_t|BOOL_BITFIELD|CPPCHAR_SIGNED_T|ino_t|dev_t|HARD_REG_SET
+ ITYPE {IWORD}({WS}{IWORD})*
+ EOID [^[:alnum:]_]
+
+
+=== modified file 'gcc/ira.c'
+--- old/gcc/ira.c 2010-03-31 01:44:10 +0000
++++ new/gcc/ira.c 2010-08-12 13:51:16 +0000
+@@ -1385,14 +1385,12 @@
+ return for_each_rtx (&insn, insn_contains_asm_1, NULL);
+ }
+
+-/* Set up regs_asm_clobbered. */
++/* Add register clobbers from asm statements. */
+ static void
+-compute_regs_asm_clobbered (char *regs_asm_clobbered)
++compute_regs_asm_clobbered (void)
+ {
+ basic_block bb;
+
+- memset (regs_asm_clobbered, 0, sizeof (char) * FIRST_PSEUDO_REGISTER);
+-
+ FOR_EACH_BB (bb)
+ {
+ rtx insn;
+@@ -1413,7 +1411,7 @@
+ + hard_regno_nregs[dregno][mode] - 1;
+
+ for (i = dregno; i <= end; ++i)
+- regs_asm_clobbered[i] = 1;
++ SET_HARD_REG_BIT(crtl->asm_clobbers, i);
+ }
+ }
+ }
+@@ -1425,12 +1423,6 @@
+ void
+ ira_setup_eliminable_regset (void)
+ {
+- /* Like regs_ever_live, but 1 if a reg is set or clobbered from an
+- asm. Unlike regs_ever_live, elements of this array corresponding
+- to eliminable regs (like the frame pointer) are set if an asm
+- sets them. */
+- char *regs_asm_clobbered
+- = (char *) alloca (FIRST_PSEUDO_REGISTER * sizeof (char));
+ #ifdef ELIMINABLE_REGS
+ int i;
+ static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
+@@ -1454,7 +1446,8 @@
+ COPY_HARD_REG_SET (ira_no_alloc_regs, no_unit_alloc_regs);
+ CLEAR_HARD_REG_SET (eliminable_regset);
+
+- compute_regs_asm_clobbered (regs_asm_clobbered);
++ compute_regs_asm_clobbered ();
++
+ /* Build the regset of all eliminable registers and show we can't
+ use those that we already know won't be eliminated. */
+ #ifdef ELIMINABLE_REGS
+@@ -1464,7 +1457,7 @@
+ = (! targetm.can_eliminate (eliminables[i].from, eliminables[i].to)
+ || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp));
+
+- if (! regs_asm_clobbered[eliminables[i].from])
++ if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, eliminables[i].from))
+ {
+ SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from);
+
+@@ -1478,7 +1471,7 @@
+ df_set_regs_ever_live (eliminables[i].from, true);
+ }
+ #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
+- if (! regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM])
++ if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
+ {
+ SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM);
+ if (need_fp)
+@@ -1492,7 +1485,7 @@
+ #endif
+
+ #else
+- if (! regs_asm_clobbered[FRAME_POINTER_REGNUM])
++ if (!TEST_HARD_REG_BIT (crtl->asm_clobbers, HARD_FRAME_POINTER_REGNUM))
+ {
+ SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM);
+ if (need_fp)
+
+=== added file 'gcc/testsuite/gcc.target/arm/frame-pointer-1.c'
+--- old/gcc/testsuite/gcc.target/arm/frame-pointer-1.c 1970-01-01 00:00:00 +0000
++++ new/gcc/testsuite/gcc.target/arm/frame-pointer-1.c 2010-08-12 13:51:16 +0000
+@@ -0,0 +1,42 @@
++/* Check local register variables using a register conventionally
++ used as the frame pointer aren't clobbered under high register pressure. */
++/* { dg-do run } */
++/* { dg-options "-Os -mthumb -fomit-frame-pointer" } */
++
++#include <stdlib.h>
++
++int global=5;
++
++void __attribute__((noinline)) foo(int p1, int p2, int p3, int p4)
++{
++ if (global != 5 || p1 != 1 || p2 != 2 || p3 != 3 || p4 != 4)
++ abort();
++}
++
++int __attribute__((noinline)) test(int a, int b, int c, int d)
++{
++ register unsigned long r __asm__("r7") = 0xdeadbeef;
++ int e;
++
++ /* ABCD are live after the call which should be enough
++ to cause r7 to be used if it weren't for the register variable. */
++ foo(a,b,c,d);
++
++ e = 0;
++ __asm__ __volatile__ ("mov %0, %2"
++ : "=r" (e)
++ : "0" (e), "r" (r));
++
++ global = a+b+c+d;
++
++ return e;
++}
++
++int main()
++{
++ if (test(1, 2, 3, 4) != 0xdeadbeef)
++ abort();
++ if (global != 10)
++ abort();
++ return 0;
++}
+
+=== modified file 'gcc/testsuite/gcc.target/i386/pr9771-1.c'
+--- old/gcc/testsuite/gcc.target/i386/pr9771-1.c 2007-08-22 08:59:14 +0000
++++ new/gcc/testsuite/gcc.target/i386/pr9771-1.c 2010-08-12 13:51:16 +0000
+@@ -28,7 +28,10 @@
+ *adr = save;
+ }
+
+-int main()
++/* This must not be inlined becuase main() requires the frame pointer
++ for stack alignment. */
++void test(void) __attribute__((noinline));
++void test(void)
+ {
+ B = &x;
+
+@@ -42,3 +45,9 @@
+ exit(0);
+ }
+
++int main()
++{
++ test();
++ return 0;
++
++}
+