summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorabel <abel@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-08 13:55:57 +0000
committerabel <abel@138bc75d-0d04-0410-961f-82ee72b054a4>2010-12-08 13:55:57 +0000
commit1a5dbaab5d6f1df044bc9c3005e7350247ea0a7a (patch)
tree9de16294b5bf2aded7c916f41b6b50f5f2bb4670 /gcc
parentb8f647b62880cce2b8858fd334ab95f5b2ab9e59 (diff)
downloadgcc-1a5dbaab5d6f1df044bc9c3005e7350247ea0a7a.tar.gz
PR target/43603
* haifa-sched.c (sched_create_recovery_edges): Update dominator info. * sel-sched-ir.c (maybe_tidy_empty_bb): Update dominator info after deleting an empty block. (tidy_control_flow): Also verify dominators. (sel_remove_bb): Update dominator info after removing a block. (sel_redirect_edge_and_branch_force): Assert that no unreachable blocks will be created. Update dominator info. (sel_redirect_edge_and_branch): Update dominator info when basic blocks do not become unreachable. (sel_remove_loop_preheader): Update dominator info. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167588 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog15
-rw-r--r--gcc/haifa-sched.c2
-rw-r--r--gcc/sel-sched-ir.c55
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/opt/pr46640.C44
-rw-r--r--gcc/testsuite/gcc.target/ia64/pr43603.c39
6 files changed, 155 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 495fe62f1f4..4c5932d9e30 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,18 @@
+2010-12-07 Andrey Belevantsev <abel@ispras.ru>
+
+ PR target/43603
+ * haifa-sched.c (sched_create_recovery_edges): Update
+ dominator info.
+ * sel-sched-ir.c (maybe_tidy_empty_bb): Update dominator info
+ after deleting an empty block.
+ (tidy_control_flow): Also verify dominators.
+ (sel_remove_bb): Update dominator info after removing a block.
+ (sel_redirect_edge_and_branch_force): Assert that no unreachable
+ blocks will be created. Update dominator info.
+ (sel_redirect_edge_and_branch): Update dominator info when
+ basic blocks do not become unreachable.
+ (sel_remove_loop_preheader): Update dominator info.
+
2010-12-07 Richard Guenther <rguenther@suse.de>
* tree-vect-data-refs.c (vect_create_addr_base_for_vector_ref):
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index a22baf93097..bd3b84c5c23 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -4467,6 +4467,8 @@ sched_create_recovery_edges (basic_block first_bb, basic_block rec,
edge_flags = 0;
make_single_succ_edge (rec, second_bb, edge_flags);
+ if (dom_info_available_p (CDI_DOMINATORS))
+ set_immediate_dominator (CDI_DOMINATORS, rec, first_bb);
}
/* This function creates recovery code for INSN. If MUTATE_P is nonzero,
diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c
index 26968828d19..e1c68764184 100644
--- a/gcc/sel-sched-ir.c
+++ b/gcc/sel-sched-ir.c
@@ -3571,6 +3571,7 @@ static bool
maybe_tidy_empty_bb (basic_block bb)
{
basic_block succ_bb, pred_bb;
+ VEC (basic_block, heap) *dom_bbs;
edge e;
edge_iterator ei;
bool rescan_p;
@@ -3606,6 +3607,7 @@ maybe_tidy_empty_bb (basic_block bb)
succ_bb = single_succ (bb);
rescan_p = true;
pred_bb = NULL;
+ dom_bbs = NULL;
/* Redirect all non-fallthru edges to the next bb. */
while (rescan_p)
@@ -3619,7 +3621,14 @@ maybe_tidy_empty_bb (basic_block bb)
if (!(e->flags & EDGE_FALLTHRU))
{
/* We can not invalidate computed topological order by moving
- the edge destination block (E->SUCC) along a fallthru edge. */
+ the edge destination block (E->SUCC) along a fallthru edge.
+
+ We will update dominators here only when we'll get
+ an unreachable block when redirecting, otherwise
+ sel_redirect_edge_and_branch will take care of it. */
+ if (e->dest != bb
+ && single_pred_p (e->dest))
+ VEC_safe_push (basic_block, heap, dom_bbs, e->dest);
sel_redirect_edge_and_branch (e, succ_bb);
rescan_p = true;
break;
@@ -3656,6 +3665,13 @@ maybe_tidy_empty_bb (basic_block bb)
remove_empty_bb (bb, true);
}
+ if (!VEC_empty (basic_block, dom_bbs))
+ {
+ VEC_safe_push (basic_block, heap, dom_bbs, succ_bb);
+ iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, false);
+ VEC_free (basic_block, heap, dom_bbs);
+ }
+
return true;
}
@@ -3740,6 +3756,7 @@ tidy_control_flow (basic_block xbb, bool full_tidying)
#ifdef ENABLE_CHECKING
verify_backedges ();
+ verify_dominators (CDI_DOMINATORS);
#endif
return changed;
@@ -5075,7 +5092,12 @@ sel_remove_bb (basic_block bb, bool remove_from_cfg_p)
bitmap_clear_bit (blocks_to_reschedule, idx);
if (remove_from_cfg_p)
- delete_and_free_basic_block (bb);
+ {
+ basic_block succ = single_succ (bb);
+ delete_and_free_basic_block (bb);
+ set_immediate_dominator (CDI_DOMINATORS, succ,
+ recompute_dominator (CDI_DOMINATORS, succ));
+ }
rgn_setup_region (CONTAINING_RGN (idx));
}
@@ -5410,12 +5432,15 @@ sel_merge_blocks (basic_block a, basic_block b)
void
sel_redirect_edge_and_branch_force (edge e, basic_block to)
{
- basic_block jump_bb, src;
+ basic_block jump_bb, src, orig_dest = e->dest;
int prev_max_uid;
rtx jump;
- gcc_assert (!sel_bb_empty_p (e->src));
-
+ /* This function is now used only for bookkeeping code creation, where
+ we'll never get the single pred of orig_dest block and thus will not
+ hit unreachable blocks when updating dominator info. */
+ gcc_assert (!sel_bb_empty_p (e->src)
+ && !single_pred_p (orig_dest));
src = e->src;
prev_max_uid = get_max_uid ();
jump_bb = redirect_edge_and_branch_force (e, to);
@@ -5432,6 +5457,10 @@ sel_redirect_edge_and_branch_force (edge e, basic_block to)
jump = find_new_jump (src, jump_bb, prev_max_uid);
if (jump)
sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
+ set_immediate_dominator (CDI_DOMINATORS, to,
+ recompute_dominator (CDI_DOMINATORS, to));
+ set_immediate_dominator (CDI_DOMINATORS, orig_dest,
+ recompute_dominator (CDI_DOMINATORS, orig_dest));
}
/* A wrapper for redirect_edge_and_branch. Return TRUE if blocks connected by
@@ -5440,11 +5469,12 @@ bool
sel_redirect_edge_and_branch (edge e, basic_block to)
{
bool latch_edge_p;
- basic_block src;
+ basic_block src, orig_dest = e->dest;
int prev_max_uid;
rtx jump;
edge redirected;
bool recompute_toporder_p = false;
+ bool maybe_unreachable = single_pred_p (orig_dest);
latch_edge_p = (pipelining_p
&& current_loop_nest
@@ -5475,6 +5505,15 @@ sel_redirect_edge_and_branch (edge e, basic_block to)
if (jump)
sel_init_new_insn (jump, INSN_INIT_TODO_LUID | INSN_INIT_TODO_SIMPLEJUMP);
+ /* Only update dominator info when we don't have unreachable blocks.
+ Otherwise we'll update in maybe_tidy_empty_bb. */
+ if (!maybe_unreachable)
+ {
+ set_immediate_dominator (CDI_DOMINATORS, to,
+ recompute_dominator (CDI_DOMINATORS, to));
+ set_immediate_dominator (CDI_DOMINATORS, orig_dest,
+ recompute_dominator (CDI_DOMINATORS, orig_dest));
+ }
return recompute_toporder_p;
}
@@ -6201,6 +6240,10 @@ sel_remove_loop_preheader (void)
if (BB_END (prev_bb) == bb_note (prev_bb))
free_data_sets (prev_bb);
}
+
+ set_immediate_dominator (CDI_DOMINATORS, next_bb,
+ recompute_dominator (CDI_DOMINATORS,
+ next_bb));
}
}
VEC_free (basic_block, heap, preheader_blocks);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index c2016451054..8743d366b79 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2010-12-07 Andrey Belevantsev <abel@ispras.ru>
+
+ PR target/43603
+ * gcc.target/ia64/pr43603.c: New.
+ * gcc/testsuite/g++.dg/opt/pr46640.C: New.
+
2010-12-07 Tobias Burnus <burnus@net-b.de>
PR fortran/44352
diff --git a/gcc/testsuite/g++.dg/opt/pr46640.C b/gcc/testsuite/g++.dg/opt/pr46640.C
new file mode 100644
index 00000000000..0892c9ac861
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pr46640.C
@@ -0,0 +1,44 @@
+// { dg-do compile { target x86_64-*-* } }
+// { dg-options "-fschedule-insns2 -fsel-sched-pipelining -fselective-scheduling2 -fno-exceptions -O" }
+
+struct QBasicAtomicInt
+{
+ int i, j;
+ bool deref ()
+ {
+ asm volatile ("":"=m" (i), "=qm" (j));
+ }
+};
+
+struct Data
+{
+ QBasicAtomicInt ref;
+ void *data;
+};
+
+struct QByteArray
+{
+ Data * d;
+ ~QByteArray ()
+ {
+ d->ref.deref ();
+ }
+};
+
+int indexOf (unsigned);
+int stat (void *, int *);
+QByteArray encodeName ();
+
+bool makeDir (unsigned len)
+{
+ unsigned i = 0;
+ while (len)
+ {
+ int st;
+ int pos = indexOf (i);
+ QByteArray baseEncoded = encodeName ();
+ if (stat (baseEncoded.d->data, &st) && stat (baseEncoded.d, &st))
+ return false;
+ i = pos;
+ }
+}
diff --git a/gcc/testsuite/gcc.target/ia64/pr43603.c b/gcc/testsuite/gcc.target/ia64/pr43603.c
new file mode 100644
index 00000000000..ad3a5b114bc
--- /dev/null
+++ b/gcc/testsuite/gcc.target/ia64/pr43603.c
@@ -0,0 +1,39 @@
+/* { dg-do compile } */
+/* { dg-options "-O3" } */
+
+int
+foo( long * np, int * dp, int qn)
+{
+ int i;
+ int n0;
+ int d0;
+ int a;
+ int b;
+ int c;
+ int d;
+
+ a = 1;
+ b = 0;
+ c = 1;
+ d = 1;
+
+ d0 = dp[0];
+
+ for (i = qn; i >= 0; i--) {
+ if (bar((c == 0)) && (np[1] == d0)) {
+ car(np - 3, dp, 3);
+ } else {
+ __asm__ ("xma.hu %0 = %2, %3, f0\n\txma.l %1 = %2, %3, f0" : "=&f" ((a)),
+"=f" (b) : "f" ((c)), "f" ((d)));
+ n0 = np[0];
+ if (n0 < d0)
+ c = 1;
+ else
+ c = 0;
+
+ }
+ *--np = a;
+ }
+
+ return 0;
+}