diff options
author | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2002-05-09 20:02:13 +0000 |
commit | c8f5fc7032940ad6633f932ac40cade82ec4d0cc (patch) | |
tree | 29a0f0a6c79a69ecc64f612947a0fe5904311713 /contrib/gcc/recog.c | |
parent | c9ab9ae440a8066b2c2b85b157b1fdadcf09916a (diff) | |
download | FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.zip FreeBSD-src-c8f5fc7032940ad6633f932ac40cade82ec4d0cc.tar.gz |
Gcc 3.1.0 pre-release from the FSF anoncvs repo on 9-May-2002 15:57:15 EDT.
Diffstat (limited to 'contrib/gcc/recog.c')
-rw-r--r-- | contrib/gcc/recog.c | 111 |
1 files changed, 98 insertions, 13 deletions
diff --git a/contrib/gcc/recog.c b/contrib/gcc/recog.c index ec0ec88..d74e399 100644 --- a/contrib/gcc/recog.c +++ b/contrib/gcc/recog.c @@ -753,6 +753,7 @@ find_single_use_1 (dest, loc) case LABEL_REF: case SYMBOL_REF: case CONST_DOUBLE: + case CONST_VECTOR: case CLOBBER: return 0; @@ -1967,7 +1968,9 @@ offsettable_address_p (strictp, mode, y) of the specified mode. We assume that if Y and Y+c are valid addresses then so is Y+d for all 0<d<c. adjust_address will go inside a LO_SUM here, so we do so as well. */ - if (GET_CODE (y) == LO_SUM) + if (GET_CODE (y) == LO_SUM + && mode != BLKmode + && mode_sz <= GET_MODE_ALIGNMENT (mode) / BITS_PER_UNIT) z = gen_rtx_LO_SUM (GET_MODE (y), XEXP (y, 0), plus_constant (XEXP (y, 1), mode_sz - 1)); else @@ -3018,8 +3021,10 @@ peephole2_optimize (dump_file) int i, b; #ifdef HAVE_conditional_execution sbitmap blocks; - int changed; + bool changed; #endif + bool do_cleanup_cfg = false; + bool do_rebuild_jump_labels = false; /* Initialize the regsets we're going to use. */ for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i) @@ -3029,7 +3034,7 @@ peephole2_optimize (dump_file) #ifdef HAVE_conditional_execution blocks = sbitmap_alloc (n_basic_blocks); sbitmap_zero (blocks); - changed = 0; + changed = false; #else count_or_remove_death_notes (NULL, 1); #endif @@ -3062,8 +3067,9 @@ peephole2_optimize (dump_file) prev = PREV_INSN (insn); if (INSN_P (insn)) { - rtx try; + rtx try, before_try, x; int match_len; + rtx note; /* Record this insn. */ if (--peep2_current < 0) @@ -3115,7 +3121,6 @@ peephole2_optimize (dump_file) note = XEXP (note, 1)) switch (REG_NOTE_KIND (note)) { - case REG_EH_REGION: case REG_NORETURN: case REG_SETJMP: case REG_ALWAYS_RETURN: @@ -3145,10 +3150,66 @@ peephole2_optimize (dump_file) if (i >= MAX_INSNS_PER_PEEP2 + 1) i -= MAX_INSNS_PER_PEEP2 + 1; + note = find_reg_note (peep2_insn_data[i].insn, + REG_EH_REGION, NULL_RTX); + /* Replace the old sequence with the new. */ try = emit_insn_after (try, peep2_insn_data[i].insn); + before_try = PREV_INSN (insn); delete_insn_chain (insn, peep2_insn_data[i].insn); + /* Re-insert the EH_REGION notes. */ + if (note) + { + edge eh_edge; + + for (eh_edge = bb->succ; eh_edge + ; eh_edge = eh_edge->succ_next) + if (eh_edge->flags & EDGE_EH) + break; + + for (x = try ; x != before_try ; x = PREV_INSN (x)) + if (GET_CODE (x) == CALL_INSN + || (flag_non_call_exceptions + && may_trap_p (PATTERN (x)) + && !find_reg_note (x, REG_EH_REGION, NULL))) + { + REG_NOTES (x) + = gen_rtx_EXPR_LIST (REG_EH_REGION, + XEXP (note, 0), + REG_NOTES (x)); + + if (x != bb->end && eh_edge) + { + edge nfte, nehe; + int flags; + + nfte = split_block (bb, x); + flags = EDGE_EH | EDGE_ABNORMAL; + if (GET_CODE (x) == CALL_INSN) + flags |= EDGE_ABNORMAL_CALL; + nehe = make_edge (nfte->src, eh_edge->dest, + flags); + + nehe->probability = eh_edge->probability; + nfte->probability + = REG_BR_PROB_BASE - nehe->probability; + + do_cleanup_cfg |= purge_dead_edges (nfte->dest); +#ifdef HAVE_conditional_execution + SET_BIT (blocks, nfte->dest->index); + changed = true; +#endif + bb = nfte->src; + eh_edge = nehe; + } + } + + /* Converting possibly trapping insn to non-trapping is + possible. Zap dummy outgoing edges. */ + do_cleanup_cfg |= purge_dead_edges (bb); + } + #ifdef HAVE_conditional_execution /* With conditional execution, we cannot back up the live information so easily, since the conditional @@ -3156,7 +3217,7 @@ peephole2_optimize (dump_file) So record that we've made a modification to this block and update life information at the end. */ SET_BIT (blocks, b); - changed = 1; + changed = true; for (i = 0; i < MAX_INSNS_PER_PEEP2 + 1; ++i) peep2_insn_data[i].insn = NULL_RTX; @@ -3169,25 +3230,35 @@ peephole2_optimize (dump_file) COPY_REG_SET (live, peep2_insn_data[i].live_before); /* Update life information for the new sequence. */ + x = try; do { - if (INSN_P (try)) + if (INSN_P (x)) { if (--i < 0) i = MAX_INSNS_PER_PEEP2; - peep2_insn_data[i].insn = try; - propagate_one_insn (pbi, try); + peep2_insn_data[i].insn = x; + propagate_one_insn (pbi, x); COPY_REG_SET (peep2_insn_data[i].live_before, live); } - try = PREV_INSN (try); + x = PREV_INSN (x); } - while (try != prev); + while (x != prev); /* ??? Should verify that LIVE now matches what we had before the new sequence. */ peep2_current = i; #endif + + /* If we generated a jump instruction, it won't have + JUMP_LABEL set. Recompute after we're done. */ + for (x = try; x != before_try; x = PREV_INSN (x)) + if (GET_CODE (x) == JUMP_INSN) + { + do_rebuild_jump_labels = true; + break; + } } } @@ -3202,9 +3273,23 @@ peephole2_optimize (dump_file) FREE_REG_SET (peep2_insn_data[i].live_before); FREE_REG_SET (live); + if (do_rebuild_jump_labels) + rebuild_jump_labels (get_insns ()); + + /* If we eliminated EH edges, we may be able to merge blocks. Further, + we've changed global life since exception handlers are no longer + reachable. */ + if (do_cleanup_cfg) + { + cleanup_cfg (0); + update_life_info (0, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES); + } #ifdef HAVE_conditional_execution - count_or_remove_death_notes (blocks, 1); - update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES); + else + { + count_or_remove_death_notes (blocks, 1); + update_life_info (blocks, UPDATE_LIFE_LOCAL, PROP_DEATH_NOTES); + } sbitmap_free (blocks); #endif } |