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
This commit is contained in:
Jan Hubicka 2002-07-21 00:56:05 +02:00 committed by Jan Hubicka
parent 0da65b89f1
commit ae860ff787
2 changed files with 148 additions and 46 deletions

View File

@ -1,3 +1,11 @@
Sun Jul 21 00:54:54 CEST 2002 Jan Hubicka <jh@suse.cz>
* 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 <roger@eyesopen.com>
* simplify-rtx.c (simplify_relational_operation): Optimize

View File

@ -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)