mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-25 19:44:46 +08:00
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:
parent
0da65b89f1
commit
ae860ff787
@ -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
|
||||
|
186
gcc/gcse.c
186
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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user