From: Jan Hubicka Date: Sat, 20 Jul 2002 22:56:05 +0000 (+0200) Subject: gcse.c: Include cselib.h X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=ae860ff78713f48ecb4556b705212378aae6ec2e;p=gcc.git gcse.c: Include cselib.h * gcse.c: Include cselib.h (constptop_register): Break out from ... (cprop_insn): ... here; kill basic_block argument. (do_local_cprop, local_cprop_pass): New functions. (one_cprop_pass): Call local_cprop_pass. From-SVN: r55615 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 833b857e7c1..42cf042b6dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +Sun Jul 21 00:54:54 CEST 2002 Jan Hubicka + + * gcse.c: Include cselib.h + (constptop_register): Break out from ... + (cprop_insn): ... here; kill basic_block argument. + (do_local_cprop, local_cprop_pass): New functions. + (one_cprop_pass): Call local_cprop_pass. + 2002-07-20 Roger Sayle * simplify-rtx.c (simplify_relational_operation): Optimize diff --git a/gcc/gcse.c b/gcc/gcse.c index bb362118b21..d46f81bc800 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -162,6 +162,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "except.h" #include "ggc.h" #include "params.h" +#include "cselib.h" #include "obstack.h" #define obstack_chunk_alloc gmalloc @@ -613,9 +614,10 @@ static int cprop_jump PARAMS ((basic_block, rtx, rtx, rtx, rtx)); static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *)); static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int)); static void canon_list_insert PARAMS ((rtx, rtx, void *)); -static int cprop_insn PARAMS ((basic_block, rtx, int)); +static int cprop_insn PARAMS ((rtx, int)); static int cprop PARAMS ((int)); static int one_cprop_pass PARAMS ((int, int)); +static bool constprop_register PARAMS ((rtx, rtx, rtx, int)); static struct expr *find_bypass_set PARAMS ((int, int)); static int bypass_block PARAMS ((basic_block, rtx, rtx)); static int bypass_conditional_jumps PARAMS ((void)); @@ -701,6 +703,8 @@ static void free_insn_expr_list_list PARAMS ((rtx *)); static void clear_modify_mem_tables PARAMS ((void)); static void free_modify_mem_tables PARAMS ((void)); static rtx gcse_emit_move_after PARAMS ((rtx, rtx, rtx)); +static bool do_local_cprop PARAMS ((rtx, rtx, int)); +static void local_cprop_pass PARAMS ((int)); /* Entry point for global common subexpression elimination. F is the first instruction in the function. */ @@ -4152,12 +4156,48 @@ cprop_jump (bb, setcc, jump, from, src) return 1; } +static bool +constprop_register (insn, from, to, alter_jumps) + rtx insn; + rtx from; + rtx to; + int alter_jumps; +{ + rtx sset; + + /* Check for reg or cc0 setting instructions followed by + conditional branch instructions first. */ + if (alter_jumps + && (sset = single_set (insn)) != NULL + && any_condjump_p (NEXT_INSN (insn)) && onlyjump_p (NEXT_INSN (insn))) + { + rtx dest = SET_DEST (sset); + if ((REG_P (dest) || CC0_P (dest)) + && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), from, to)) + return 1; + } + + /* Handle normal insns next. */ + if (GET_CODE (insn) == INSN + && try_replace_reg (from, to, insn)) + return 1; + + /* Try to propagate a CONST_INT into a conditional jump. + We're pretty specific about what we will handle in this + code, we can extend this as necessary over time. + + Right now the insn in question must look like + (set (pc) (if_then_else ...)) */ + else if (alter_jumps && any_condjump_p (insn) && onlyjump_p (insn)) + return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to); + return 0; +} + /* Perform constant and copy propagation on INSN. The result is non-zero if a change was made. */ static int -cprop_insn (bb, insn, alter_jumps) - basic_block bb; +cprop_insn (insn, alter_jumps) rtx insn; int alter_jumps; { @@ -4210,56 +4250,18 @@ cprop_insn (bb, insn, alter_jumps) /* Constant propagation. */ if (CONSTANT_P (src)) { - rtx sset; - - /* Check for reg or cc0 setting instructions followed by - conditional branch instructions first. */ - if (alter_jumps - && (sset = single_set (insn)) != NULL - && any_condjump_p (NEXT_INSN (insn)) - && onlyjump_p (NEXT_INSN (insn))) - { - rtx dest = SET_DEST (sset); - if ((REG_P (dest) || CC0_P (dest)) - && cprop_jump (bb, insn, NEXT_INSN (insn), - reg_used->reg_rtx, src)) - { - changed = 1; - break; - } - } - - /* Handle normal insns next. */ - if (GET_CODE (insn) == INSN - && try_replace_reg (reg_used->reg_rtx, src, insn)) + if (constprop_register (insn, reg_used->reg_rtx, src, alter_jumps)) { changed = 1; const_prop_count++; if (gcse_file != NULL) { - fprintf (gcse_file, "CONST-PROP: Replacing reg %d in ", - regno); - fprintf (gcse_file, "insn %d with constant ", - INSN_UID (insn)); + fprintf (gcse_file, "GLOBAL CONST-PROP: Replacing reg %d in ", regno); + fprintf (gcse_file, "insn %d with constant ", INSN_UID (insn)); print_rtl (gcse_file, src); fprintf (gcse_file, "\n"); } - - /* The original insn setting reg_used may or may not now be - deletable. We leave the deletion to flow. */ } - - /* Try to propagate a CONST_INT into a conditional jump. - We're pretty specific about what we will handle in this - code, we can extend this as necessary over time. - - Right now the insn in question must look like - (set (pc) (if_then_else ...)) */ - else if (alter_jumps - && any_condjump_p (insn) - && onlyjump_p (insn)) - changed |= cprop_jump (bb, NULL, insn, reg_used->reg_rtx, src); - } else if (GET_CODE (src) == REG && REGNO (src) >= FIRST_PSEUDO_REGISTER @@ -4271,7 +4273,7 @@ cprop_insn (bb, insn, alter_jumps) copy_prop_count++; if (gcse_file != NULL) { - fprintf (gcse_file, "COPY-PROP: Replacing reg %d in insn %d", + fprintf (gcse_file, "GLOBAL COPY-PROP: Replacing reg %d in insn %d", regno, INSN_UID (insn)); fprintf (gcse_file, " with reg %d\n", REGNO (src)); } @@ -4288,6 +4290,96 @@ cprop_insn (bb, insn, alter_jumps) return changed; } +static bool +do_local_cprop (x, insn, alter_jumps) + rtx x; + rtx insn; + int alter_jumps; +{ + rtx newreg = NULL, newcnst = NULL; + + /* Rule out USE instructions and ASM statements as we don't want to change the hard + registers mentioned. */ + if (GET_CODE (x) == REG + && (REGNO (x) >= FIRST_PSEUDO_REGISTER + || (GET_CODE (PATTERN (insn)) != USE && asm_noperands (PATTERN (insn)) < 0))) + { + cselib_val *val = cselib_lookup (x, GET_MODE (x), 0); + struct elt_loc_list *l; + + if (!val) + return false; + for (l = val->locs; l; l = l->next) + { + rtx this_rtx = l->loc; + if (CONSTANT_P (this_rtx)) + newcnst = this_rtx; + if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER) + newreg = this_rtx; + } + if (newcnst && constprop_register (insn, x, newcnst, alter_jumps)) + { + if (gcse_file != NULL) + { + fprintf (gcse_file, "LOCAL CONST-PROP: Replacing reg %d in ", + REGNO (x)); + fprintf (gcse_file, "insn %d with constant ", + INSN_UID (insn)); + print_rtl (gcse_file, newcnst); + fprintf (gcse_file, "\n"); + } + const_prop_count++; + return true; + } + else if (newreg && newreg != x && try_replace_reg (x, newreg, insn)) + { + if (gcse_file != NULL) + { + fprintf (gcse_file, + "LOCAL COPY-PROP: Replacing reg %d in insn %d", + REGNO (x), INSN_UID (insn)); + fprintf (gcse_file, " with reg %d\n", REGNO (newreg)); + } + copy_prop_count++; + return true; + } + } + return false; +} + +static void +local_cprop_pass (alter_jumps) + int alter_jumps; +{ + rtx insn; + struct reg_use *reg_used; + + cselib_init (); + for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) + { + if (INSN_P (insn)) + { + rtx note = find_reg_equal_equiv_note (insn); + + do + { + reg_use_count = 0; + note_uses (&PATTERN (insn), find_used_regs, NULL); + if (note) + find_used_regs (&XEXP (note, 0), NULL); + + for (reg_used = ®_use_table[0]; reg_use_count > 0; + reg_used++, reg_use_count--) + if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps)) + break; + } + while (reg_use_count); + } + cselib_process_insn (insn); + } + cselib_finish (); +} + /* Forward propagate copies. This includes copies and constants. Return non-zero if a change was made. */ @@ -4319,7 +4411,7 @@ cprop (alter_jumps) insn = NEXT_INSN (insn)) if (INSN_P (insn)) { - changed |= cprop_insn (bb, insn, 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. Don't @@ -4349,6 +4441,8 @@ one_cprop_pass (pass, alter_jumps) const_prop_count = 0; copy_prop_count = 0; + local_cprop_pass (alter_jumps); + alloc_set_hash_table (max_cuid); compute_set_hash_table (); if (gcse_file)