diff options
author | Bernd Schmidt <bernds@cygnus.co.uk> | 1999-08-25 03:30:45 +0000 |
---|---|---|
committer | Jeff Law <law@gcc.gnu.org> | 1999-08-24 21:30:45 -0600 |
commit | abd535b681d7bba79c3f8bc85451822fe7e4f8d0 (patch) | |
tree | 8b7837f542b26655996939408963aac7b9617fee | |
parent | b6c8689d9b5bf1e163efaca313dd491c8dca50e0 (diff) | |
download | gcc-abd535b681d7bba79c3f8bc85451822fe7e4f8d0.zip gcc-abd535b681d7bba79c3f8bc85451822fe7e4f8d0.tar.gz gcc-abd535b681d7bba79c3f8bc85451822fe7e4f8d0.tar.bz2 |
gcse.c (cprop_jump): New function, broken out of cprop_insn.
* gcse.c (cprop_jump): New function, broken out of cprop_insn.
(cprop_cc0_jump): New function.
(cprop_insn): Break out new function cprop_jump and use it.
Also use cprop_cc0_jump for machines with CC0.
(cprop): Don't crash if cprop_insn turned the insn into a NOTE.
From-SVN: r28834
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/gcse.c | 207 |
2 files changed, 137 insertions, 76 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7649747..cb72d95 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -110,6 +110,12 @@ Tue Aug 24 09:32:07 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> Tue Aug 24 12:35:20 1999 Bernd Schmidt <bernds@cygnus.co.uk> + * gcse.c (cprop_jump): New function, broken out of cprop_insn. + (cprop_cc0_jump): New function. + (cprop_insn): Break out new function cprop_jump and use it. + Also use cprop_cc0_jump for machines with CC0. + (cprop): Don't crash if cprop_insn turned the insn into a NOTE. + * tree.h (current_function_calls_setjmp, current_function_calls_longjmp): Delete declarations. * dsp16xx.c: Include "function.h". @@ -310,6 +310,10 @@ static char can_copy_p[(int) NUM_MACHINE_MODES]; /* Non-zero if can_copy_p has been initialized. */ static int can_copy_init_p; +struct reg_use { + rtx reg_rtx; +}; + /* Hash table of expressions. */ struct expr @@ -572,6 +576,8 @@ static void compute_cprop_data PROTO ((void)); static void find_used_regs PROTO ((rtx)); static int try_replace_reg PROTO ((rtx, rtx, rtx)); static struct expr *find_avail_set PROTO ((int, rtx)); +static int cprop_jump PROTO((rtx, rtx, struct reg_use *, rtx)); +static int cprop_cc0_jump PROTO((rtx, struct reg_use *, rtx)); static int cprop_insn PROTO ((rtx, int)); static int cprop PROTO ((int)); static int one_cprop_pass PROTO ((int, int)); @@ -3532,10 +3538,6 @@ compute_cprop_data () /* Copy/constant propagation. */ -struct reg_use { - rtx reg_rtx; -}; - /* Maximum number of register uses in an insn that we handle. */ #define MAX_USES 8 @@ -3666,6 +3668,114 @@ find_avail_set (regno, insn) return set; } +/* Subroutine of cprop_insn that tries to propagate constants into + JUMP_INSNS. INSN must be a conditional jump; COPY is a copy of it + that we can use for substitutions. + REG_USED is the use we will try to replace, SRC is the constant we + will try to substitute for it. + Returns nonzero if a change was made. */ +static int +cprop_jump (insn, copy, reg_used, src) + rtx insn, copy; + struct reg_use *reg_used; + rtx src; +{ + rtx set = PATTERN (copy); + rtx temp; + + /* Replace the register with the appropriate constant. */ + replace_rtx (SET_SRC (set), reg_used->reg_rtx, src); + + temp = simplify_ternary_operation (GET_CODE (SET_SRC (set)), + GET_MODE (SET_SRC (set)), + GET_MODE (XEXP (SET_SRC (set), 0)), + XEXP (SET_SRC (set), 0), + XEXP (SET_SRC (set), 1), + XEXP (SET_SRC (set), 2)); + + /* If no simplification can be made, then try the next + register. */ + if (temp == 0) + return 0; + + SET_SRC (set) = temp; + + /* That may have changed the structure of TEMP, so + force it to be rerecognized if it has not turned + into a nop or unconditional jump. */ + + INSN_CODE (copy) = -1; + if ((SET_DEST (set) == pc_rtx + && (SET_SRC (set) == pc_rtx + || GET_CODE (SET_SRC (set)) == LABEL_REF)) + || recog (PATTERN (copy), copy, NULL) >= 0) + { + /* This has either become an unconditional jump + or a nop-jump. We'd like to delete nop jumps + here, but doing so confuses gcse. So we just + make the replacement and let later passes + sort things out. */ + PATTERN (insn) = set; + INSN_CODE (insn) = -1; + + /* One less use of the label this insn used to jump to + if we turned this into a NOP jump. */ + if (SET_SRC (set) == pc_rtx && JUMP_LABEL (insn) != 0) + --LABEL_NUSES (JUMP_LABEL (insn)); + + /* If this has turned into an unconditional jump, + then put a barrier after it so that the unreachable + code will be deleted. */ + if (GET_CODE (SET_SRC (set)) == LABEL_REF) + emit_barrier_after (insn); + + run_jump_opt_after_gcse = 1; + + const_prop_count++; + if (gcse_file != NULL) + { + int regno = REGNO (reg_used->reg_rtx); + fprintf (gcse_file, "CONST-PROP: Replacing reg %d in insn %d with constant ", + regno, INSN_UID (insn)); + print_rtl (gcse_file, src); + fprintf (gcse_file, "\n"); + } + return 1; + } + return 0; +} + +#ifdef HAVE_cc0 +/* Subroutine of cprop_insn that tries to propagate constants into + JUMP_INSNS for machines that have CC0. INSN is a single set that + stores into CC0; the insn following it is a conditional jump. + REG_USED is the use we will try to replace, SRC is the constant we + will try to substitute for it. + Returns nonzero if a change was made. */ +static int +cprop_cc0_jump (insn, reg_used, src) + rtx insn; + struct reg_use *reg_used; + rtx src; +{ + rtx jump = NEXT_INSN (insn); + rtx copy = copy_rtx (jump); + rtx set = PATTERN (copy); + + /* We need to copy the source of the cc0 setter, as cprop_jump is going to + substitute into it. */ + replace_rtx (SET_SRC (set), cc0_rtx, copy_rtx (SET_SRC (PATTERN (insn)))); + if (! cprop_jump (jump, copy, reg_used, src)) + return 0; + + /* If we succeeded, delete the cc0 setter. */ + PUT_CODE (insn, NOTE); + NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED; + NOTE_SOURCE_FILE (insn) = 0; + return 1; + } +#endif + /* Perform constant and copy propagation on INSN. The result is non-zero if a change was made. */ @@ -3743,80 +3853,23 @@ cprop_insn (insn, alter_jumps) code, we can extend this as necessary over time. Right now the insn in question must look like - - (set (pc) (if_then_else ...)) - - Note this does not currently handle machines which use cc0. */ + (set (pc) (if_then_else ...)) */ else if (alter_jumps && GET_CODE (insn) == JUMP_INSN && condjump_p (insn) && ! simplejump_p (insn)) - { - /* We want a copy of the JUMP_INSN so we can modify it - in-place as needed without effecting the original. */ - rtx copy = copy_rtx (insn); - rtx set = PATTERN (copy); - rtx temp; - - /* Replace the register with the appropriate constant. */ - replace_rtx (SET_SRC (set), reg_used->reg_rtx, src); - - temp = simplify_ternary_operation (GET_CODE (SET_SRC (set)), - GET_MODE (SET_SRC (set)), - GET_MODE (XEXP (SET_SRC (set), 0)), - XEXP (SET_SRC (set), 0), - XEXP (SET_SRC (set), 1), - XEXP (SET_SRC (set), 2)); - - /* If no simplification can be made, then try the next - register. */ - if (temp) - SET_SRC (set) = temp; - else - continue; - - /* That may have changed the structure of TEMP, so - force it to be rerecognized if it has not turned - into a nop or unconditional jump. */ - - INSN_CODE (copy) = -1; - if ((SET_DEST (set) == pc_rtx - && (SET_SRC (set) == pc_rtx - || GET_CODE (SET_SRC (set)) == LABEL_REF)) - || recog (PATTERN (copy), copy, NULL) >= 0) - { - /* This has either become an unconditional jump - or a nop-jump. We'd like to delete nop jumps - here, but doing so confuses gcse. So we just - make the replacement and let later passes - sort things out. */ - PATTERN (insn) = set; - INSN_CODE (insn) = -1; - - /* One less use of the label this insn used to jump to - if we turned this into a NOP jump. */ - if (SET_SRC (set) == pc_rtx && JUMP_LABEL (insn) != 0) - --LABEL_NUSES (JUMP_LABEL (insn)); - - /* If this has turned into an unconditional jump, - then put a barrier after it so that the unreachable - code will be deleted. */ - if (GET_CODE (SET_SRC (set)) == LABEL_REF) - emit_barrier_after (insn); - - run_jump_opt_after_gcse = 1; - - changed = 1; - const_prop_count++; - if (gcse_file != NULL) - { - fprintf (gcse_file, "CONST-PROP: Replacing reg %d in insn %d with constant ", - regno, INSN_UID (insn)); - print_rtl (gcse_file, src); - fprintf (gcse_file, "\n"); - } - } - } + changed |= cprop_jump (insn, copy_rtx (insn), reg_used, src); +#ifdef HAVE_cc0 + /* Similar code for machines that use a pair of CC0 setter and + conditional jump insn. */ + else if (alter_jumps + && GET_CODE (PATTERN (insn)) == SET + && SET_DEST (PATTERN (insn)) == cc0_rtx + && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN + && condjump_p (NEXT_INSN (insn)) + && ! simplejump_p (NEXT_INSN (insn))) + changed |= cprop_cc0_jump (insn, reg_used, src); +#endif } else if (GET_CODE (src) == REG && REGNO (src) >= FIRST_PSEUDO_REGISTER @@ -3879,8 +3932,10 @@ cprop (alter_jumps) changed |= cprop_insn (insn, alter_jumps); /* Keep track of everything modified by this insn. */ - /* ??? Need to be careful w.r.t. mods done to INSN. */ - mark_oprs_set (insn); + /* ??? Need to be careful w.r.t. mods done to INSN. Don't + call mark_oprs_set if we turned the insn into a NOTE. */ + if (GET_CODE (insn) != NOTE) + mark_oprs_set (insn); } } } |