regmove.c (STACK_GROWS_DOWNWARD): Don't boolean-ize.

* regmove.c (STACK_GROWS_DOWNWARD): Don't boolean-ize.
	(regmove_bb_head): Remove.
	(copy_src_to_dest): Don't update regmove_bb_head and BB_HEAD.
	(regmove_optimize): Don't do unnecessary CFG fixes for non-existing
	problems with fixup_match_1.
	Don't initialize/free regmove_bb_head.

	(reg_is_remote_constant_p): If an insn is in the same basic block
	but not before INSN, consider it remote, too.

From-SVN: r123522
This commit is contained in:
Steven Bosscher 2007-04-05 16:52:26 +00:00
parent f9ca0dee6d
commit a78f3e715c
2 changed files with 34 additions and 78 deletions

View File

@ -1,3 +1,15 @@
2007-04-05 Steven Bosscher <steven@gcc.gnu.org>
* regmove.c (STACK_GROWS_DOWNWARD): Don't boolean-ize.
(regmove_bb_head): Remove.
(copy_src_to_dest): Don't update regmove_bb_head and BB_HEAD.
(regmove_optimize): Don't do unnecessary CFG fixes for non-existing
problems with fixup_match_1.
Don't initialize/free regmove_bb_head.
(reg_is_remote_constant_p): If an insn is in the same basic block
but not before INSN, consider it remote, too.
2007-04-05 Anatoly Sokolov <aesok@post.ru> 2007-04-05 Anatoly Sokolov <aesok@post.ru>
PR target/25448 PR target/25448

View File

@ -47,20 +47,11 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "tree-pass.h" #include "tree-pass.h"
/* Turn STACK_GROWS_DOWNWARD into a boolean. */
#ifdef STACK_GROWS_DOWNWARD
#undef STACK_GROWS_DOWNWARD
#define STACK_GROWS_DOWNWARD 1
#else
#define STACK_GROWS_DOWNWARD 0
#endif
static int perhaps_ends_bb_p (rtx); static int perhaps_ends_bb_p (rtx);
static int optimize_reg_copy_1 (rtx, rtx, rtx); static int optimize_reg_copy_1 (rtx, rtx, rtx);
static void optimize_reg_copy_2 (rtx, rtx, rtx); static void optimize_reg_copy_2 (rtx, rtx, rtx);
static void optimize_reg_copy_3 (rtx, rtx, rtx); static void optimize_reg_copy_3 (rtx, rtx, rtx);
static void copy_src_to_dest (rtx, rtx, rtx, int); static void copy_src_to_dest (rtx, rtx, rtx);
static int *regmove_bb_head;
struct match { struct match {
int with[MAX_RECOG_OPERANDS]; int with[MAX_RECOG_OPERANDS];
@ -737,7 +728,7 @@ optimize_reg_copy_3 (rtx insn, rtx dest, rtx src)
instead moving the value to dest directly before the operation. */ instead moving the value to dest directly before the operation. */
static void static void
copy_src_to_dest (rtx insn, rtx src, rtx dest, int old_max_uid) copy_src_to_dest (rtx insn, rtx src, rtx dest)
{ {
rtx seq; rtx seq;
rtx link; rtx link;
@ -806,18 +797,8 @@ copy_src_to_dest (rtx insn, rtx src, rtx dest, int old_max_uid)
*p_move_notes = NULL_RTX; *p_move_notes = NULL_RTX;
*p_insn_notes = NULL_RTX; *p_insn_notes = NULL_RTX;
/* Is the insn the head of a basic block? If so extend it. */
insn_uid = INSN_UID (insn); insn_uid = INSN_UID (insn);
move_uid = INSN_UID (move_insn); move_uid = INSN_UID (move_insn);
if (insn_uid < old_max_uid)
{
bb = regmove_bb_head[insn_uid];
if (bb >= 0)
{
BB_HEAD (BASIC_BLOCK (bb)) = move_insn;
regmove_bb_head[insn_uid] = -1;
}
}
/* Update the various register tables. */ /* Update the various register tables. */
dest_regno = REGNO (dest); dest_regno = REGNO (dest);
@ -854,8 +835,7 @@ static unsigned int max_reg_computed;
may increase register pressure and make reload harder. If REG is may increase register pressure and make reload harder. If REG is
set in the same basic block as INSN, we don't worry about it, set in the same basic block as INSN, we don't worry about it,
because we'll probably need a register anyhow (??? but what if REG because we'll probably need a register anyhow (??? but what if REG
is used in a different basic block as well as this one?). FIRST is is used in a different basic block as well as this one?). */
the first insn in the function. */
static bool static bool
reg_is_remote_constant_p (rtx reg, rtx insn) reg_is_remote_constant_p (rtx reg, rtx insn)
@ -870,44 +850,27 @@ reg_is_remote_constant_p (rtx reg, rtx insn)
reg_set_in_bb = xcalloc (max, sizeof (*reg_set_in_bb)); reg_set_in_bb = xcalloc (max, sizeof (*reg_set_in_bb));
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
for (p = BB_HEAD (bb); p != NEXT_INSN (BB_END (bb)); FOR_BB_INSNS (bb, p)
p = NEXT_INSN (p)) {
{ rtx s;
rtx s;
if (!INSN_P (p)) if (!INSN_P (p))
continue; continue;
s = single_set (p); s = single_set (p);
/* This is the instruction which sets REG. If there is a /* This is the instruction which sets REG. If there is a
REG_EQUAL note, then REG is equivalent to a constant. */ REG_EQUAL note, then REG is equivalent to a constant. */
if (s != 0 if (s != 0
&& REG_P (SET_DEST (s)) && REG_P (SET_DEST (s))
&& REG_N_SETS (REGNO (SET_DEST (s))) == 1 && REG_N_SETS (REGNO (SET_DEST (s))) == 1
&& find_reg_note (p, REG_EQUAL, NULL_RTX)) && find_reg_note (p, REG_EQUAL, NULL_RTX))
reg_set_in_bb[REGNO (SET_DEST (s))] = bb; reg_set_in_bb[REGNO (SET_DEST (s))] = bb;
} }
} }
gcc_assert (REGNO (reg) < max_reg_computed); gcc_assert (REGNO (reg) < max_reg_computed);
if (reg_set_in_bb[REGNO (reg)] == NULL) if (reg_set_in_bb[REGNO (reg)] == NULL)
return false; return false;
if (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn)) return (reg_set_in_bb[REGNO (reg)] != BLOCK_FOR_INSN (insn));
return true;
/* Look for the set. */
for (p = BB_HEAD (BLOCK_FOR_INSN (insn)); p != insn; p = NEXT_INSN (p))
{
rtx s;
if (!INSN_P (p))
continue;
s = single_set (p);
if (s != 0
&& REG_P (SET_DEST (s)) && REGNO (SET_DEST (s)) == REGNO (reg))
{
/* The register is set in the same basic block. */
return false;
}
}
return true;
} }
/* INSN is adding a CONST_INT to a REG. We search backwards looking for /* INSN is adding a CONST_INT to a REG. We search backwards looking for
@ -1053,7 +1016,6 @@ fixup_match_2 (rtx insn, rtx dst, rtx src, rtx offset)
static void static void
regmove_optimize (rtx f, int nregs) regmove_optimize (rtx f, int nregs)
{ {
int old_max_uid = get_max_uid ();
rtx insn; rtx insn;
struct match match; struct match match;
int pass; int pass;
@ -1071,12 +1033,8 @@ regmove_optimize (rtx f, int nregs)
mark_flags_life_zones (discover_flags_reg ()); mark_flags_life_zones (discover_flags_reg ());
regno_src_regno = XNEWVEC (int, nregs); regno_src_regno = XNEWVEC (int, nregs);
for (i = nregs; --i >= 0; ) regno_src_regno[i] = -1; for (i = nregs; --i >= 0; )
regno_src_regno[i] = -1;
regmove_bb_head = XNEWVEC (int, old_max_uid + 1);
for (i = old_max_uid; i >= 0; i--) regmove_bb_head[i] = -1;
FOR_EACH_BB (bb)
regmove_bb_head[INSN_UID (BB_HEAD (bb))] = bb->index;
/* A forward/backward pass. Replace output operands with input operands. */ /* A forward/backward pass. Replace output operands with input operands. */
@ -1500,28 +1458,14 @@ regmove_optimize (rtx f, int nregs)
/* If we weren't able to replace any of the alternatives, try an /* If we weren't able to replace any of the alternatives, try an
alternative approach of copying the source to the destination. */ alternative approach of copying the source to the destination. */
if (!success && copy_src != NULL_RTX) if (!success && copy_src != NULL_RTX)
copy_src_to_dest (insn, copy_src, copy_dst, old_max_uid); copy_src_to_dest (insn, copy_src, copy_dst);
} }
} }
/* In fixup_match_1, some insns may have been inserted after basic block
ends. Fix that here. */
FOR_EACH_BB (bb)
{
rtx end = BB_END (bb);
rtx new = end;
rtx next = NEXT_INSN (new);
while (next != 0 && INSN_UID (next) >= old_max_uid
&& (bb->next_bb == EXIT_BLOCK_PTR || BB_HEAD (bb->next_bb) != next))
new = next, next = NEXT_INSN (new);
BB_END (bb) = new;
}
done: done:
/* Clean up. */ /* Clean up. */
free (regno_src_regno); free (regno_src_regno);
free (regmove_bb_head);
if (reg_set_in_bb) if (reg_set_in_bb)
{ {
free (reg_set_in_bb); free (reg_set_in_bb);