diff options
author | abel <abel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-09 14:08:31 +0000 |
---|---|---|
committer | abel <abel@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-08-09 14:08:31 +0000 |
commit | 846800d706faeaeda5ee66ff9a7e479886a89d7e (patch) | |
tree | a145593be9727c2b55c552211e1c27d86799eb93 /gcc/sel-sched.c | |
parent | 3efd0ea8801334260442a4a0fe60c392bf955cd8 (diff) | |
download | gcc-846800d706faeaeda5ee66ff9a7e479886a89d7e.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@190253 138bc75d-0d04-0410-961f-82ee72b054a4
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 3099b92627a..f0c6eafb6f3 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); } |