summaryrefslogtreecommitdiff
path: root/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch
diff options
context:
space:
mode:
authorKhem Raj <raj.khem@gmail.com>2011-06-12 20:56:57 -0700
committerRichard Purdie <richard.purdie@linuxfoundation.org>2011-06-14 14:37:31 +0100
commit3968f33b6542cf20cf63cf49bfbc033bd2486295 (patch)
tree2bdb5e2f692a3bd3ecadbf2b4c7dc9f54485c737 /meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch
parent022ca1d1357caafdfe23aa9ab82f90ba89b6942b (diff)
downloadopenembedded-core-3968f33b6542cf20cf63cf49bfbc033bd2486295.tar.gz
openembedded-core-3968f33b6542cf20cf63cf49bfbc033bd2486295.tar.bz2
openembedded-core-3968f33b6542cf20cf63cf49bfbc033bd2486295.tar.xz
openembedded-core-3968f33b6542cf20cf63cf49bfbc033bd2486295.zip
gcc-4.6.0: Bring in patches from FSF 4.6 branch
This brings in new patches from 4.6 release branch updates the comment section of existing branch to not contain patch numbers. Tested build on qemu for arm ppc mips x86 and x86_64 Signed-off-by: Khem Raj <raj.khem@gmail.com>
Diffstat (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch')
-rw-r--r--meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch200
1 files changed, 200 insertions, 0 deletions
diff --git a/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch
new file mode 100644
index 000000000..80f89fd41
--- /dev/null
+++ b/meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch
@@ -0,0 +1,200 @@
+From a6f15e84e042ffb95afa499d2bd2d6b2758f85f9 Mon Sep 17 00:00:00 2001
+From: jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4>
+Date: Thu, 26 May 2011 10:20:34 +0000
+Subject: [PATCH] PR tree-optimization/49161
+ * tree-vrp.c (struct case_info): New type.
+ (compare_case_labels): Sort case_info structs instead of
+ trees, and not primarily by CASE_LABEL uids but by
+ label_for_block indexes.
+ (find_switch_asserts): Put case labels into struct case_info
+ array instead of TREE_VEC, adjust sorting, compare label_for_block
+ values instead of CASE_LABELs.
+
+ * gcc.c-torture/execute/pr49161.c: New test.
+
+
+git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/gcc-4_6-branch@174272 138bc75d-0d04-0410-961f-82ee72b054a4
+
+index 2c4fdd4..b5d9fd3 100644
+new file mode 100644
+index 0000000..cc822da
+--- /dev/null
++++ b/gcc/testsuite/gcc.c-torture/execute/pr49161.c
+@@ -0,0 +1,46 @@
++/* PR tree-optimization/49161 */
++
++extern void abort (void);
++
++int c;
++
++__attribute__((noinline, noclone)) void
++bar (int x)
++{
++ if (x != c++)
++ abort ();
++}
++
++__attribute__((noinline, noclone)) void
++foo (int x)
++{
++ switch (x)
++ {
++ case 3: goto l1;
++ case 4: goto l2;
++ case 6: goto l3;
++ default: return;
++ }
++l1:
++ goto l4;
++l2:
++ goto l4;
++l3:
++ bar (-1);
++l4:
++ bar (0);
++ if (x != 4)
++ bar (1);
++ if (x != 3)
++ bar (-1);
++ bar (2);
++}
++
++int
++main ()
++{
++ foo (3);
++ if (c != 3)
++ abort ();
++ return 0;
++}
+diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
+index 7bff5fa..6914a08 100644
+--- a/gcc/tree-vrp.c
++++ b/gcc/tree-vrp.c
+@@ -4672,28 +4672,35 @@ find_conditional_asserts (basic_block bb, gimple last)
+ return need_assert;
+ }
+
+-/* Compare two case labels sorting first by the destination label uid
++struct case_info
++{
++ tree expr;
++ basic_block bb;
++};
++
++/* Compare two case labels sorting first by the destination bb index
+ and then by the case value. */
+
+ static int
+ compare_case_labels (const void *p1, const void *p2)
+ {
+- const_tree const case1 = *(const_tree const*)p1;
+- const_tree const case2 = *(const_tree const*)p2;
+- unsigned int uid1 = DECL_UID (CASE_LABEL (case1));
+- unsigned int uid2 = DECL_UID (CASE_LABEL (case2));
++ const struct case_info *ci1 = (const struct case_info *) p1;
++ const struct case_info *ci2 = (const struct case_info *) p2;
++ int idx1 = ci1->bb->index;
++ int idx2 = ci2->bb->index;
+
+- if (uid1 < uid2)
++ if (idx1 < idx2)
+ return -1;
+- else if (uid1 == uid2)
++ else if (idx1 == idx2)
+ {
+ /* Make sure the default label is first in a group. */
+- if (!CASE_LOW (case1))
++ if (!CASE_LOW (ci1->expr))
+ return -1;
+- else if (!CASE_LOW (case2))
++ else if (!CASE_LOW (ci2->expr))
+ return 1;
+ else
+- return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
++ return tree_int_cst_compare (CASE_LOW (ci1->expr),
++ CASE_LOW (ci2->expr));
+ }
+ else
+ return 1;
+@@ -4714,8 +4721,8 @@ find_switch_asserts (basic_block bb, gimple last)
+ gimple_stmt_iterator bsi;
+ tree op;
+ edge e;
+- tree vec2;
+- size_t n = gimple_switch_num_labels(last);
++ struct case_info *ci;
++ size_t n = gimple_switch_num_labels (last);
+ #if GCC_VERSION >= 4000
+ unsigned int idx;
+ #else
+@@ -4730,36 +4737,38 @@ find_switch_asserts (basic_block bb, gimple last)
+ return false;
+
+ /* Build a vector of case labels sorted by destination label. */
+- vec2 = make_tree_vec (n);
++ ci = XNEWVEC (struct case_info, n);
+ for (idx = 0; idx < n; ++idx)
+- TREE_VEC_ELT (vec2, idx) = gimple_switch_label (last, idx);
+- qsort (&TREE_VEC_ELT (vec2, 0), n, sizeof (tree), compare_case_labels);
++ {
++ ci[idx].expr = gimple_switch_label (last, idx);
++ ci[idx].bb = label_to_block (CASE_LABEL (ci[idx].expr));
++ }
++ qsort (ci, n, sizeof (struct case_info), compare_case_labels);
+
+ for (idx = 0; idx < n; ++idx)
+ {
+ tree min, max;
+- tree cl = TREE_VEC_ELT (vec2, idx);
++ tree cl = ci[idx].expr;
++ basic_block cbb = ci[idx].bb;
+
+ min = CASE_LOW (cl);
+ max = CASE_HIGH (cl);
+
+ /* If there are multiple case labels with the same destination
+ we need to combine them to a single value range for the edge. */
+- if (idx + 1 < n
+- && CASE_LABEL (cl) == CASE_LABEL (TREE_VEC_ELT (vec2, idx + 1)))
++ if (idx + 1 < n && cbb == ci[idx + 1].bb)
+ {
+ /* Skip labels until the last of the group. */
+ do {
+ ++idx;
+- } while (idx < n
+- && CASE_LABEL (cl) == CASE_LABEL (TREE_VEC_ELT (vec2, idx)));
++ } while (idx < n && cbb == ci[idx].bb);
+ --idx;
+
+ /* Pick up the maximum of the case label range. */
+- if (CASE_HIGH (TREE_VEC_ELT (vec2, idx)))
+- max = CASE_HIGH (TREE_VEC_ELT (vec2, idx));
++ if (CASE_HIGH (ci[idx].expr))
++ max = CASE_HIGH (ci[idx].expr);
+ else
+- max = CASE_LOW (TREE_VEC_ELT (vec2, idx));
++ max = CASE_LOW (ci[idx].expr);
+ }
+
+ /* Nothing to do if the range includes the default label until we
+@@ -4768,7 +4777,7 @@ find_switch_asserts (basic_block bb, gimple last)
+ continue;
+
+ /* Find the edge to register the assert expr on. */
+- e = find_edge (bb, label_to_block (CASE_LABEL (cl)));
++ e = find_edge (bb, cbb);
+
+ /* Register the necessary assertions for the operand in the
+ SWITCH_EXPR. */
+@@ -4786,6 +4795,7 @@ find_switch_asserts (basic_block bb, gimple last)
+ }
+ }
+
++ XDELETEVEC (ci);
+ return need_assert;
+ }
+
+--
+1.7.0.4
+