From 3968f33b6542cf20cf63cf49bfbc033bd2486295 Mon Sep 17 00:00:00 2001 From: Khem Raj Date: Sun, 12 Jun 2011 20:56:57 -0700 Subject: 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 --- .../0349-PR-tree-optimization-49161.patch | 200 +++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch (limited to 'meta/recipes-devtools/gcc/gcc-4.6.0/gcc-4_6-branch-backports/0349-PR-tree-optimization-49161.patch') 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 +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 + -- cgit v1.2.3