aboutsummaryrefslogtreecommitdiff
path: root/gcc/gcse.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2002-07-21 00:56:05 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2002-07-20 22:56:05 +0000
commitae860ff78713f48ecb4556b705212378aae6ec2e (patch)
tree2e02554dc60e8ae63b81cc75fcbd9109e1ebb1e4 /gcc/gcse.c
parent0da65b89f1c0930d104b273a9218fb63226f4cad (diff)
downloadgcc-ae860ff78713f48ecb4556b705212378aae6ec2e.zip
gcc-ae860ff78713f48ecb4556b705212378aae6ec2e.tar.gz
gcc-ae860ff78713f48ecb4556b705212378aae6ec2e.tar.bz2
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
Diffstat (limited to 'gcc/gcse.c')
-rw-r--r--gcc/gcse.c186
1 files changed, 140 insertions, 46 deletions
diff --git a/gcc/gcse.c b/gcc/gcse.c
index bb36211..d46f81b 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 = &reg_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)