aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Monakov <amonakov@ispras.ru>2009-04-28 14:01:52 +0400
committerAlexander Monakov <amonakov@gcc.gnu.org>2009-04-28 14:01:52 +0400
commitf2c45f08668a1e898d965d02914957d03ffb091f (patch)
tree49f2c287d751ab49352e33fce6814bbe9a083ce9
parent7a00d767b7c149202d3a8d0600e7384940eec14d (diff)
downloadgcc-f2c45f08668a1e898d965d02914957d03ffb091f.zip
gcc-f2c45f08668a1e898d965d02914957d03ffb091f.tar.gz
gcc-f2c45f08668a1e898d965d02914957d03ffb091f.tar.bz2
20071210-2.c: New testcase.
gcc/testsuite/Changelog: 2009-04-28 Alexander Monakov <amonakov@ispras.ru> * gcc.target/ia64/20071210-2.c: New testcase. gcc/Changelog: 2009-04-28 Alexander Monakov <amonakov@ispras.ru> * sel-sched-ir.c (maybe_tidy_empty_bb): Do not attempt to delete a block if there are complex incoming edges. (sel_merge_blocks): Remove useless assert. (sel_redirect_edge_and_branch): Check that edge was redirected. * sel-sched-ir.h (_eligible_successor_edge_p): Remove assert. (sel_find_rgns): Delete declaration. * sel-sched.c (purge_empty_blocks): Attempt to remove first block of the region when it is not a preheader. From-SVN: r146882
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/sel-sched-ir.c20
-rw-r--r--gcc/sel-sched-ir.h5
-rw-r--r--gcc/sel-sched.c5
-rw-r--r--gcc/testsuite/ChangeLog3
-rw-r--r--gcc/testsuite/gcc.target/ia64/20071210-2.c68
6 files changed, 96 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ecf5300..b7e96d1 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2009-04-28 Alexander Monakov <amonakov@ispras.ru>
+ * sel-sched-ir.c (maybe_tidy_empty_bb): Do not attempt to delete a
+ block if there are complex incoming edges.
+ (sel_merge_blocks): Remove useless assert.
+ (sel_redirect_edge_and_branch): Check that edge was redirected.
+ * sel-sched-ir.h (_eligible_successor_edge_p): Remove assert.
+ (sel_find_rgns): Delete declaration.
+ * sel-sched.c (purge_empty_blocks): Attempt to remove first block of
+ the region when it is not a preheader.
+
2009-04-28 Uros Bizjak <ubizjak@gmail.com>
PR c/39323
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 168b01f..d3f3562 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -3481,6 +3481,8 @@ bool
maybe_tidy_empty_bb (basic_block bb)
{
basic_block succ_bb, pred_bb;
+ edge e;
+ edge_iterator ei;
bool rescan_p;
/* Keep empty bb only if this block immediately precedes EXIT and
@@ -3492,6 +3494,11 @@ maybe_tidy_empty_bb (basic_block bb)
|| !(single_pred_edge (bb)->flags & EDGE_FALLTHRU))))
return false;
+ /* Do not attempt to redirect complex edges. */
+ FOR_EACH_EDGE (e, ei, bb->preds)
+ if (e->flags & EDGE_COMPLEX)
+ return false;
+
free_data_sets (bb);
/* Do not delete BB if it has more than one successor.
@@ -3510,9 +3517,6 @@ maybe_tidy_empty_bb (basic_block bb)
/* Redirect all non-fallthru edges to the next bb. */
while (rescan_p)
{
- edge e;
- edge_iterator ei;
-
rescan_p = false;
FOR_EACH_EDGE (e, ei, bb->preds)
@@ -5244,8 +5248,6 @@ sel_create_recovery_block (insn_t orig_insn)
void
sel_merge_blocks (basic_block a, basic_block b)
{
- gcc_assert (can_merge_blocks_p (a, b));
-
sel_remove_empty_bb (b, true, false);
merge_blocks (a, b);
@@ -5290,6 +5292,7 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
basic_block src;
int prev_max_uid;
rtx jump;
+ edge redirected;
latch_edge_p = (pipelining_p
&& current_loop_nest
@@ -5297,9 +5300,10 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
src = e->src;
prev_max_uid = get_max_uid ();
-
- redirect_edge_and_branch (e, to);
- gcc_assert (last_added_blocks == NULL);
+
+ redirected = redirect_edge_and_branch (e, to);
+
+ gcc_assert (redirected && last_added_blocks == NULL);
/* When we've redirected a latch edge, update the header. */
if (latch_edge_p)
diff --git a/gcc/sel-sched-ir.h b/gcc/sel-sched-ir.h
index 4bf21b2..3d219e1 100644
--- a/gcc/sel-sched-ir.h
+++ b/gcc/sel-sched-ir.h
@@ -1358,10 +1358,6 @@ _eligible_successor_edge_p (edge e1, succ_iterator *ip)
e2 = EDGE_SUCC (bb, 0);
bb = e2->dest;
-
- /* This couldn't happen inside a region. */
- gcc_assert (! in_current_region_p (bb)
- || (flags & SUCCS_OUT));
}
/* Save the second edge for later checks. */
@@ -1584,7 +1580,6 @@ extern void sel_redirect_edge_and_branch_force (edge, basic_block);
extern void sel_init_pipelining (void);
extern void sel_finish_pipelining (void);
extern void sel_sched_region (int);
-extern void sel_find_rgns (void);
extern loop_p get_loop_nest_for_rgn (unsigned int);
extern bool considered_for_pipelining_p (struct loop *);
extern void make_region_from_loop_preheader (VEC(basic_block, heap) **);
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index e524d02..b1a33be 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -6483,9 +6483,10 @@ setup_current_loop_nest (int rgn)
static void
purge_empty_blocks (void)
{
- int i ;
+ /* Do not attempt to delete preheader. */
+ int i = sel_is_loop_preheader_p (BASIC_BLOCK (BB_TO_BLOCK (0))) ? 1 : 0;
- for (i = 1; i < current_nr_blocks; )
+ while (i < current_nr_blocks)
{
basic_block b = BASIC_BLOCK (BB_TO_BLOCK (i));
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 79a0679..14086b8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,6 @@
+2009-04-28 Alexander Monakov <amonakov@ispras.ru>
+ * gcc.target/ia64/20071210-2.c: New testcase.
+
2009-04-28 Uros Bizjak <ubizjak@gmail.com>
PR c/39323
diff --git a/gcc/testsuite/gcc.target/ia64/20071210-2.c b/gcc/testsuite/gcc.target/ia64/20071210-2.c
new file mode 100644
index 0000000..96a20a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/20071210-2.c
@@ -0,0 +1,68 @@
+/* { dg-do compile } */
+/* { dg-options "-Os -fselective-scheduling2" } */
+
+extern void abort (void);
+
+struct S
+{
+ int n1, n2, n3, n4;
+};
+
+__attribute__((noinline)) struct S
+foo (int x, int y, int z)
+{
+ if (x != 10 || y != 9 || z != 8)
+ abort ();
+ struct S s = { 1, 2, 3, 4 };
+ return s;
+}
+
+__attribute__((noinline)) void **
+bar (void **u, int *v)
+{
+ void **w = u;
+ int *s = v, x, y, z;
+ void **p, **q;
+ static void *l[] = { &&lab1, &&lab1, &&lab2, &&lab3, &&lab4 };
+
+ if (!u)
+ return l;
+
+ q = *w++;
+ goto *q;
+lab2:
+ p = q;
+ q = *w++;
+ x = s[2];
+ y = s[1];
+ z = s[0];
+ s -= 1;
+ struct S r = foo (x, y, z);
+ s[3] = r.n1;
+ s[2] = r.n2;
+ s[1] = r.n3;
+ s[0] = r.n4;
+ goto *q;
+lab3:
+ p = q;
+ q = *w++;
+ s += 1;
+ s[0] = 23;
+lab1:
+ goto *q;
+lab4:
+ return 0;
+}
+
+int
+main (void)
+{
+ void **u = bar ((void **) 0, (int *) 0);
+ void *t[] = { u[2], u[4] };
+ int s[] = { 7, 8, 9, 10, 11, 12 };
+ if (bar (t, &s[1]) != (void **) 0
+ || s[0] != 4 || s[1] != 3 || s[2] != 2 || s[3] != 1
+ || s[4] != 11 || s[5] != 12)
+ abort ();
+ return 0;
+}