diff options
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/sel-sched-ir.c | 20 | ||||
-rw-r--r-- | gcc/sel-sched-ir.h | 5 | ||||
-rw-r--r-- | gcc/sel-sched.c | 5 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 3 | ||||
-rw-r--r-- | gcc/testsuite/gcc.target/ia64/20071210-2.c | 68 |
6 files changed, 96 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ecf5300315a..b7e96d18e05 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 168b01f64d4..d3f35627815 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 4bf21b21263..3d219e1568a 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 e524d02516f..b1a33beb7d0 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 79a06791382..14086b8381c 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 00000000000..96a20a73f87 --- /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; +} |