mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-26 23:51:20 +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>
|
2002-07-20 Roger Sayle <roger@eyesopen.com>
|
||||||
|
|
||||||
* simplify-rtx.c (simplify_relational_operation): Optimize
|
* 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 "except.h"
|
||||||
#include "ggc.h"
|
#include "ggc.h"
|
||||||
#include "params.h"
|
#include "params.h"
|
||||||
|
#include "cselib.h"
|
||||||
|
|
||||||
#include "obstack.h"
|
#include "obstack.h"
|
||||||
#define obstack_chunk_alloc gmalloc
|
#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 void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
|
||||||
static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
|
static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
|
||||||
static void canon_list_insert PARAMS ((rtx, rtx, void *));
|
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 cprop PARAMS ((int));
|
||||||
static int one_cprop_pass PARAMS ((int, 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 struct expr *find_bypass_set PARAMS ((int, int));
|
||||||
static int bypass_block PARAMS ((basic_block, rtx, rtx));
|
static int bypass_block PARAMS ((basic_block, rtx, rtx));
|
||||||
static int bypass_conditional_jumps PARAMS ((void));
|
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 clear_modify_mem_tables PARAMS ((void));
|
||||||
static void free_modify_mem_tables PARAMS ((void));
|
static void free_modify_mem_tables PARAMS ((void));
|
||||||
static rtx gcse_emit_move_after PARAMS ((rtx, rtx, rtx));
|
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.
|
/* Entry point for global common subexpression elimination.
|
||||||
F is the first instruction in the function. */
|
F is the first instruction in the function. */
|
||||||
@ -4152,12 +4156,48 @@ cprop_jump (bb, setcc, jump, from, src)
|
|||||||
return 1;
|
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.
|
/* Perform constant and copy propagation on INSN.
|
||||||
The result is non-zero if a change was made. */
|
The result is non-zero if a change was made. */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
cprop_insn (bb, insn, alter_jumps)
|
cprop_insn (insn, alter_jumps)
|
||||||
basic_block bb;
|
|
||||||
rtx insn;
|
rtx insn;
|
||||||
int alter_jumps;
|
int alter_jumps;
|
||||||
{
|
{
|
||||||
@ -4210,56 +4250,18 @@ cprop_insn (bb, insn, alter_jumps)
|
|||||||
/* Constant propagation. */
|
/* Constant propagation. */
|
||||||
if (CONSTANT_P (src))
|
if (CONSTANT_P (src))
|
||||||
{
|
{
|
||||||
rtx sset;
|
if (constprop_register (insn, reg_used->reg_rtx, src, alter_jumps))
|
||||||
|
|
||||||
/* 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))
|
|
||||||
{
|
{
|
||||||
changed = 1;
|
changed = 1;
|
||||||
const_prop_count++;
|
const_prop_count++;
|
||||||
if (gcse_file != NULL)
|
if (gcse_file != NULL)
|
||||||
{
|
{
|
||||||
fprintf (gcse_file, "CONST-PROP: Replacing reg %d in ",
|
fprintf (gcse_file, "GLOBAL CONST-PROP: Replacing reg %d in ", regno);
|
||||||
regno);
|
fprintf (gcse_file, "insn %d with constant ", INSN_UID (insn));
|
||||||
fprintf (gcse_file, "insn %d with constant ",
|
|
||||||
INSN_UID (insn));
|
|
||||||
print_rtl (gcse_file, src);
|
print_rtl (gcse_file, src);
|
||||||
fprintf (gcse_file, "\n");
|
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
|
else if (GET_CODE (src) == REG
|
||||||
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
|
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
|
||||||
@ -4271,7 +4273,7 @@ cprop_insn (bb, insn, alter_jumps)
|
|||||||
copy_prop_count++;
|
copy_prop_count++;
|
||||||
if (gcse_file != NULL)
|
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));
|
regno, INSN_UID (insn));
|
||||||
fprintf (gcse_file, " with reg %d\n", REGNO (src));
|
fprintf (gcse_file, " with reg %d\n", REGNO (src));
|
||||||
}
|
}
|
||||||
@ -4288,6 +4290,96 @@ cprop_insn (bb, insn, alter_jumps)
|
|||||||
return changed;
|
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
|
/* Forward propagate copies. This includes copies and constants. Return
|
||||||
non-zero if a change was made. */
|
non-zero if a change was made. */
|
||||||
|
|
||||||
@ -4319,7 +4411,7 @@ cprop (alter_jumps)
|
|||||||
insn = NEXT_INSN (insn))
|
insn = NEXT_INSN (insn))
|
||||||
if (INSN_P (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. */
|
/* Keep track of everything modified by this insn. */
|
||||||
/* ??? Need to be careful w.r.t. mods done to INSN. Don't
|
/* ??? 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;
|
const_prop_count = 0;
|
||||||
copy_prop_count = 0;
|
copy_prop_count = 0;
|
||||||
|
|
||||||
|
local_cprop_pass (alter_jumps);
|
||||||
|
|
||||||
alloc_set_hash_table (max_cuid);
|
alloc_set_hash_table (max_cuid);
|
||||||
compute_set_hash_table ();
|
compute_set_hash_table ();
|
||||||
if (gcse_file)
|
if (gcse_file)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user