regmove.c (discover_flags_reg, [...]): Delete.

2009-02-25  Paolo Bonzini  <bonzini@gnu.org>

	* regmove.c (discover_flags_reg, flags_set_1, mark_flags_life_zones,
	flags_set_1_rtx, flags_set_1_set): Delete.
	(regmove_optimize): Do not call mark_flags_life_zones.

From-SVN: r144425
This commit is contained in:
Paolo Bonzini 2009-02-25 14:08:14 +00:00 committed by Paolo Bonzini
parent 6d2538f5f9
commit c8a05f7c57
2 changed files with 6 additions and 173 deletions

View File

@ -1,3 +1,9 @@
2009-02-25 Paolo Bonzini <bonzini@gnu.org>
* regmove.c (discover_flags_reg, flags_set_1, mark_flags_life_zones,
flags_set_1_rtx, flags_set_1_set): Delete.
(regmove_optimize): Do not call mark_flags_life_zones.
2009-02-24 Julian Brown <julian@codesourcery.com>
PR target/35965

View File

@ -58,10 +58,6 @@ struct match {
int early_clobber[MAX_RECOG_OPERANDS];
};
static rtx discover_flags_reg (void);
static void mark_flags_life_zones (rtx);
static void flags_set_1 (rtx, const_rtx, void *);
static int find_matches (rtx, struct match *);
static int regclass_compatible_p (int, int);
static int fixup_match_2 (rtx, rtx, rtx, rtx);
@ -79,171 +75,6 @@ regclass_compatible_p (int class0, int class1)
}
/* Determine if the pattern generated by add_optab has a clobber,
such as might be issued for a flags hard register. To make the
code elsewhere simpler, we handle cc0 in this same framework.
Return the register if one was discovered. Return NULL_RTX if
if no flags were found. Return pc_rtx if we got confused. */
static rtx
discover_flags_reg (void)
{
rtx tmp;
tmp = gen_rtx_REG (word_mode, 10000);
tmp = gen_add3_insn (tmp, tmp, const2_rtx);
/* If we get something that isn't a simple set, or a
[(set ..) (clobber ..)], this whole function will go wrong. */
if (GET_CODE (tmp) == SET)
return NULL_RTX;
else if (GET_CODE (tmp) == PARALLEL)
{
int found;
if (XVECLEN (tmp, 0) != 2)
return pc_rtx;
tmp = XVECEXP (tmp, 0, 1);
if (GET_CODE (tmp) != CLOBBER)
return pc_rtx;
tmp = XEXP (tmp, 0);
/* Don't do anything foolish if the md wanted to clobber a
scratch or something. We only care about hard regs.
Moreover we don't like the notion of subregs of hard regs. */
if (GET_CODE (tmp) == SUBREG
&& REG_P (SUBREG_REG (tmp))
&& REGNO (SUBREG_REG (tmp)) < FIRST_PSEUDO_REGISTER)
return pc_rtx;
found = (REG_P (tmp) && REGNO (tmp) < FIRST_PSEUDO_REGISTER);
return (found ? tmp : NULL_RTX);
}
return pc_rtx;
}
/* It is a tedious task identifying when the flags register is live and
when it is safe to optimize. Since we process the instruction stream
multiple times, locate and record these live zones by marking the
mode of the instructions --
QImode is used on the instruction at which the flags becomes live.
HImode is used within the range (exclusive) that the flags are
live. Thus the user of the flags is not marked.
All other instructions are cleared to VOIDmode. */
/* Used to communicate with flags_set_1. */
static rtx flags_set_1_rtx;
static int flags_set_1_set;
static void
mark_flags_life_zones (rtx flags)
{
int flags_regno;
int flags_nregs;
basic_block block;
#ifdef HAVE_cc0
/* If we found a flags register on a cc0 host, bail. */
if (flags == NULL_RTX)
flags = cc0_rtx;
else if (flags != cc0_rtx)
flags = pc_rtx;
#endif
/* Simple cases first: if no flags, clear all modes. If confusing,
mark the entire function as being in a flags shadow. */
if (flags == NULL_RTX || flags == pc_rtx)
{
enum machine_mode mode = (flags ? HImode : VOIDmode);
rtx insn;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
PUT_MODE (insn, mode);
return;
}
#ifdef HAVE_cc0
flags_regno = -1;
flags_nregs = 1;
#else
flags_regno = REGNO (flags);
flags_nregs = hard_regno_nregs[flags_regno][GET_MODE (flags)];
#endif
flags_set_1_rtx = flags;
/* Process each basic block. */
FOR_EACH_BB_REVERSE (block)
{
rtx insn, end;
int live;
insn = BB_HEAD (block);
end = BB_END (block);
/* Look out for the (unlikely) case of flags being live across
basic block boundaries. */
live = 0;
#ifndef HAVE_cc0
{
int i;
for (i = 0; i < flags_nregs; ++i)
live |= REGNO_REG_SET_P (df_get_live_in (block), flags_regno + i);
}
#endif
while (1)
{
/* Process liveness in reverse order of importance --
alive, death, birth. This lets more important info
overwrite the mode of lesser info. */
if (INSN_P (insn))
{
#ifdef HAVE_cc0
/* In the cc0 case, death is not marked in reg notes,
but is instead the mere use of cc0 when it is alive. */
if (live && reg_mentioned_p (cc0_rtx, PATTERN (insn)))
live = 0;
#else
/* In the hard reg case, we watch death notes. */
if (live && find_regno_note (insn, REG_DEAD, flags_regno))
live = 0;
#endif
PUT_MODE (insn, (live ? HImode : VOIDmode));
/* In either case, birth is denoted simply by its presence
as the destination of a set. */
flags_set_1_set = 0;
note_stores (PATTERN (insn), flags_set_1, NULL);
if (flags_set_1_set)
{
live = 1;
PUT_MODE (insn, QImode);
}
}
else
PUT_MODE (insn, (live ? HImode : VOIDmode));
if (insn == end)
break;
insn = NEXT_INSN (insn);
}
}
}
/* A subroutine of mark_flags_life_zones, called through note_stores. */
static void
flags_set_1 (rtx x, const_rtx pat, void *data ATTRIBUTE_UNUSED)
{
if (GET_CODE (pat) == SET
&& reg_overlap_mentioned_p (x, flags_set_1_rtx))
flags_set_1_set = 1;
}
#ifdef AUTO_INC_DEC
/* Find the place in the rtx X where REG is used as a memory address.
@ -1077,10 +908,6 @@ regmove_optimize (rtx f, int nregs)
regstat_init_n_sets_and_refs ();
regstat_compute_ri ();
/* Find out where a potential flags register is live, and so that we
can suppress some optimizations in those zones. */
mark_flags_life_zones (discover_flags_reg ());
regno_src_regno = XNEWVEC (int, nregs);
for (i = nregs; --i >= 0; )
regno_src_regno[i] = -1;