diff options
author | cvs2svn <cvs2svn@FreeBSD.org> | 2000-03-27 03:00:06 +0000 |
---|---|---|
committer | cvs2svn <cvs2svn@FreeBSD.org> | 2000-03-27 03:00:06 +0000 |
commit | 3e26bdf09c5e0a4e9b015a5f02b9c948454010e1 (patch) | |
tree | 36f3f9a09138cd7071d3de64269ad734e9d9c50b /contrib/gcc/cse.c | |
parent | 536abd52d2bd3b3830d8ac369f03865f32e4d496 (diff) |
Diffstat (limited to 'contrib/gcc/cse.c')
-rw-r--r-- | contrib/gcc/cse.c | 71 |
1 files changed, 48 insertions, 23 deletions
diff --git a/contrib/gcc/cse.c b/contrib/gcc/cse.c index e315610b3e288..45613edc3ac92 100644 --- a/contrib/gcc/cse.c +++ b/contrib/gcc/cse.c @@ -1,5 +1,5 @@ /* Common subexpression elimination for GNU compiler. - Copyright (C) 1987, 88, 89, 92-99, 2000 Free Software Foundation, Inc. + Copyright (C) 1987, 88, 89, 92-7, 1998, 1999 Free Software Foundation, Inc. This file is part of GNU CC. @@ -42,14 +42,12 @@ Boston, MA 02111-1307, USA. */ expressions encountered with the cheapest equivalent expression. It is too complicated to keep track of the different possibilities - when control paths merge in this code; so, at each label, we forget all - that is known and start fresh. This can be described as processing each - extended basic block separately. We have a separate pass to perform - global CSE. - - Note CSE can turn a conditional or computed jump into a nop or - an unconditional jump. When this occurs we arrange to run the jump - optimizer after CSE to delete the unreachable code. + when control paths merge; so, at each label, we forget all that is + known and start fresh. This can be described as processing each + basic block separately. Note, however, that these are not quite + the same as the basic blocks found by a later pass and used for + data flow analysis and register packing. We do not need to start fresh + after a conditional jump instruction if there is no label there. We use two data structures to record the equivalent expressions: a hash table for most expressions, and several vectors together @@ -5863,15 +5861,7 @@ fold_rtx (x, insn) hence not save anything) or be incorrect. */ if (const_arg1 != 0 && GET_CODE (const_arg1) == CONST_INT && INTVAL (const_arg1) < 0 - /* This used to test - - - INTVAL (const_arg1) >= 0 - - But The Sun V5.0 compilers mis-compiled that test. So - instead we test for the problematic value in a more direct - manner and hope the Sun compilers get it correct. */ - && INTVAL (const_arg1) != - ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1)) + && - INTVAL (const_arg1) >= 0 && GET_CODE (folded_arg1) == REG) { rtx new_const = GEN_INT (- INTVAL (const_arg1)); @@ -7470,6 +7460,7 @@ cse_insn (insn, libcall_insn) rtx new = emit_jump_insn_before (gen_jump (XEXP (src, 0)), insn); JUMP_LABEL (new) = XEXP (src, 0); LABEL_NUSES (XEXP (src, 0))++; + delete_insn (insn); insn = new; } else @@ -7480,11 +7471,42 @@ cse_insn (insn, libcall_insn) Until the right place is found, might as well do this here. */ INSN_CODE (insn) = -1; - /* Now emit a BARRIER after the unconditional jump. Do not bother - deleting any unreachable code, let jump/flow do that. */ - if (NEXT_INSN (insn) != 0 - && GET_CODE (NEXT_INSN (insn)) != BARRIER) - emit_barrier_after (insn); + /* Now that we've converted this jump to an unconditional jump, + there is dead code after it. Delete the dead code until we + reach a BARRIER, the end of the function, or a label. Do + not delete NOTEs except for NOTE_INSN_DELETED since later + phases assume these notes are retained. */ + + p = insn; + + while (NEXT_INSN (p) != 0 + && GET_CODE (NEXT_INSN (p)) != BARRIER + && GET_CODE (NEXT_INSN (p)) != CODE_LABEL) + { + /* Note, we must update P with the return value from + delete_insn, otherwise we could get an infinite loop + if NEXT_INSN (p) had INSN_DELETED_P set. */ + if (GET_CODE (NEXT_INSN (p)) != NOTE + || NOTE_LINE_NUMBER (NEXT_INSN (p)) == NOTE_INSN_DELETED) + p = PREV_INSN (delete_insn (NEXT_INSN (p))); + else + p = NEXT_INSN (p); + } + + /* If we don't have a BARRIER immediately after INSN, put one there. + Much code assumes that there are no NOTEs between a JUMP_INSN and + BARRIER. */ + + if (NEXT_INSN (insn) == 0 + || GET_CODE (NEXT_INSN (insn)) != BARRIER) + emit_barrier_before (NEXT_INSN (insn)); + + /* We might have two BARRIERs separated by notes. Delete the second + one if so. */ + + if (p != insn && NEXT_INSN (p) != 0 + && GET_CODE (NEXT_INSN (p)) == BARRIER) + delete_insn (NEXT_INSN (p)); cse_jumps_altered = 1; sets[i].rtl = 0; @@ -8977,6 +8999,9 @@ cse_basic_block (from, to, next_branch, around_loop) insn = NEXT_INSN (to); + if (LABEL_NUSES (to) == 0) + insn = delete_insn (to); + /* If TO was the last insn in the function, we are done. */ if (insn == 0) return 0; |