diff options
author | Andrey Belevantsev <abel@ispras.ru> | 2012-08-09 18:08:31 +0400 |
---|---|---|
committer | Andrey Belevantsev <abel@gcc.gnu.org> | 2012-08-09 18:08:31 +0400 |
commit | 0c02ab396ed1385ee0fc14c534fcfe36dbe11675 (patch) | |
tree | a145593be9727c2b55c552211e1c27d86799eb93 /gcc/sel-sched.c | |
parent | 82ad0aaf6e6d671b8dab3fd9ae3b496f1c70aea7 (diff) | |
download | gcc-0c02ab396ed1385ee0fc14c534fcfe36dbe11675.zip gcc-0c02ab396ed1385ee0fc14c534fcfe36dbe11675.tar.gz gcc-0c02ab396ed1385ee0fc14c534fcfe36dbe11675.tar.bz2 |
re PR rtl-optimization/53701 (ICE on ia64 (when building Allegro 4.4) in sel-sched)
PR rtl-optimization/53701
* sel-sched.c (vinsn_vec_has_expr_p): Clarify function comment.
Process not only expr's vinsns but all old vinsns from expr's
history of changes.
(update_and_record_unavailable_insns): Clarify comment.
* gcc.dg/pr53701.c: New test.
From-SVN: r190253
Diffstat (limited to 'gcc/sel-sched.c')
-rw-r--r-- | gcc/sel-sched.c | 52 |
1 files changed, 32 insertions, 20 deletions
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c index 3099b92..f0c6eaf 100644 --- a/gcc/sel-sched.c +++ b/gcc/sel-sched.c @@ -3564,29 +3564,41 @@ process_use_exprs (av_set_t *av_ptr) return NULL; } -/* Lookup EXPR in VINSN_VEC and return TRUE if found. */ +/* Lookup EXPR in VINSN_VEC and return TRUE if found. Also check patterns from + EXPR's history of changes. */ static bool vinsn_vec_has_expr_p (vinsn_vec_t vinsn_vec, expr_t expr) { - vinsn_t vinsn; + vinsn_t vinsn, expr_vinsn; int n; + unsigned i; - FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) - if (VINSN_SEPARABLE_P (vinsn)) - { - if (vinsn_equal_p (vinsn, EXPR_VINSN (expr))) - return true; - } - else - { - /* For non-separable instructions, the blocking insn can have - another pattern due to substitution, and we can't choose - different register as in the above case. Check all registers - being written instead. */ - if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), - VINSN_REG_SETS (EXPR_VINSN (expr)))) - return true; - } + /* Start with checking expr itself and then proceed with all the old forms + of expr taken from its history vector. */ + for (i = 0, expr_vinsn = EXPR_VINSN (expr); + expr_vinsn; + expr_vinsn = (i < VEC_length (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr)) + ? VEC_index (expr_history_def, + EXPR_HISTORY_OF_CHANGES (expr), + i++)->old_expr_vinsn + : NULL)) + FOR_EACH_VEC_ELT (vinsn_t, vinsn_vec, n, vinsn) + if (VINSN_SEPARABLE_P (vinsn)) + { + if (vinsn_equal_p (vinsn, expr_vinsn)) + return true; + } + else + { + /* For non-separable instructions, the blocking insn can have + another pattern due to substitution, and we can't choose + different register as in the above case. Check all registers + being written instead. */ + if (bitmap_intersect_p (VINSN_REG_SETS (vinsn), + VINSN_REG_SETS (expr_vinsn))) + return true; + } return false; } @@ -5694,8 +5706,8 @@ update_and_record_unavailable_insns (basic_block book_block) || EXPR_TARGET_AVAILABLE (new_expr) != EXPR_TARGET_AVAILABLE (cur_expr)) /* Unfortunately, the below code could be also fired up on - separable insns. - FIXME: add an example of how this could happen. */ + separable insns, e.g. when moving insns through the new + speculation check as in PR 53701. */ vinsn_vec_add (&vec_bookkeeping_blocked_vinsns, cur_expr); } |