Commit 50aac998 by Michael Matz Committed by Michael Matz

df.h (enum df_ref_flags.DF_REF_STRIPPED): New.

        * df.h (enum df_ref_flags.DF_REF_STRIPPED): New.
        (DF_FOR_REGALLOC): New.
        * df.c (df_ref_record): Set DF_REF_STRIPPED.
        (read_modify_subreg_p): Simplify.
        (df_def_record_1, df_uses_record): Set DF_REF_MODE_CHANGE more often.
        Use DF_FOR_REGALLOC.
        * ra.h (struct web): New member subreg_stripped.
        (invalid_mode_change_regs): Declare.
        * ra.c (invalid_mode_change_regs): New.
        (init_ra): Initialize it.
        * ra-build.c (init_one_web_common, remember_web_was_spilled): Use it.
        Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
        (reinit_one_web, parts_to_web_1): Deal with subreg_stripped.
        * ra-colorize.c (colorize_one_web): Use invalid_mode_change_regs.
        Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.

From-SVN: r63952
parent aa6e8ed3
2003-03-07 Michael Matz <matz@suse.de>
* df.h (enum df_ref_flags.DF_REF_STRIPPED): New.
(DF_FOR_REGALLOC): New.
* df.c (df_ref_record): Set DF_REF_STRIPPED.
(read_modify_subreg_p): Simplify.
(df_def_record_1, df_uses_record): Set DF_REF_MODE_CHANGE more often.
Use DF_FOR_REGALLOC.
* ra.h (struct web): New member subreg_stripped.
(invalid_mode_change_regs): Declare.
* ra.c (invalid_mode_change_regs): New.
(init_ra): Initialize it.
* ra-build.c (init_one_web_common, remember_web_was_spilled): Use it.
Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
(reinit_one_web, parts_to_web_1): Deal with subreg_stripped.
* ra-colorize.c (colorize_one_web): Use invalid_mode_change_regs.
Use CANNOT_CHANGE_MODE_CLASS as ifdef guard.
2003-03-07 Richard Earnshaw <rearnsha@arm.com> 2003-03-07 Richard Earnshaw <rearnsha@arm.com>
* arm.md (addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, negsf2) * arm.md (addsf3, adddf3, subsf3, subdf3, mulsf3, muldf3, negsf2)
......
...@@ -849,6 +849,7 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags) ...@@ -849,6 +849,7 @@ df_ref_record (df, reg, loc, insn, ref_type, ref_flags)
{ {
loc = &SUBREG_REG (reg); loc = &SUBREG_REG (reg);
reg = *loc; reg = *loc;
ref_flags |= DF_REF_STRIPPED;
} }
regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg); regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
...@@ -893,13 +894,8 @@ read_modify_subreg_p (x) ...@@ -893,13 +894,8 @@ read_modify_subreg_p (x)
return false; return false;
isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))); isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
osize = GET_MODE_SIZE (GET_MODE (x)); osize = GET_MODE_SIZE (GET_MODE (x));
if (isize <= osize) /* Paradoxical subreg writes don't leave a trace of the old content. */
return true; return (isize > osize && isize > UNITS_PER_WORD);
if (isize <= UNITS_PER_WORD)
return false;
if (osize > UNITS_PER_WORD)
return false;
return true;
} }
...@@ -927,9 +923,7 @@ df_def_record_1 (df, x, bb, insn) ...@@ -927,9 +923,7 @@ df_def_record_1 (df, x, bb, insn)
} }
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (dst) == SUBREG if (GET_CODE (dst) == SUBREG)
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
GET_MODE (dst)))
flags |= DF_REF_MODE_CHANGE; flags |= DF_REF_MODE_CHANGE;
#endif #endif
...@@ -938,7 +932,8 @@ df_def_record_1 (df, x, bb, insn) ...@@ -938,7 +932,8 @@ df_def_record_1 (df, x, bb, insn)
while (GET_CODE (dst) == STRICT_LOW_PART while (GET_CODE (dst) == STRICT_LOW_PART
|| GET_CODE (dst) == ZERO_EXTRACT || GET_CODE (dst) == ZERO_EXTRACT
|| GET_CODE (dst) == SIGN_EXTRACT || GET_CODE (dst) == SIGN_EXTRACT
|| read_modify_subreg_p (dst)) || ((df->flags & DF_FOR_REGALLOC) == 0
&& read_modify_subreg_p (dst)))
{ {
/* Strict low part always contains SUBREG, but we do not want to make /* Strict low part always contains SUBREG, but we do not want to make
it appear outside, as whole register is always considered. */ it appear outside, as whole register is always considered. */
...@@ -948,9 +943,7 @@ df_def_record_1 (df, x, bb, insn) ...@@ -948,9 +943,7 @@ df_def_record_1 (df, x, bb, insn)
dst = *loc; dst = *loc;
} }
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CLASS_CANNOT_CHANGE_MODE
if (GET_CODE (dst) == SUBREG if (GET_CODE (dst) == SUBREG)
&& CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (SUBREG_REG (dst)),
GET_MODE (dst)))
flags |= DF_REF_MODE_CHANGE; flags |= DF_REF_MODE_CHANGE;
#endif #endif
loc = &XEXP (dst, 0); loc = &XEXP (dst, 0);
...@@ -1050,9 +1043,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) ...@@ -1050,9 +1043,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
return; return;
} }
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CLASS_CANNOT_CHANGE_MODE
if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (x), flags |= DF_REF_MODE_CHANGE;
GET_MODE (SUBREG_REG (x))))
flags |= DF_REF_MODE_CHANGE;
#endif #endif
/* ... Fall through ... */ /* ... Fall through ... */
...@@ -1072,13 +1063,12 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) ...@@ -1072,13 +1063,12 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
{ {
enum df_ref_flags use_flags; enum df_ref_flags use_flags;
case SUBREG: case SUBREG:
if (read_modify_subreg_p (dst)) if ((df->flags & DF_FOR_REGALLOC) == 0
&& read_modify_subreg_p (dst))
{ {
use_flags = DF_REF_READ_WRITE; use_flags = DF_REF_READ_WRITE;
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CLASS_CANNOT_CHANGE_MODE
if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst), use_flags |= DF_REF_MODE_CHANGE;
GET_MODE (SUBREG_REG (dst))))
use_flags |= DF_REF_MODE_CHANGE;
#endif #endif
df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb, df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
insn, use_flags); insn, use_flags);
...@@ -1102,9 +1092,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags) ...@@ -1102,9 +1092,7 @@ df_uses_record (df, loc, ref_type, bb, insn, flags)
abort (); abort ();
use_flags = DF_REF_READ_WRITE; use_flags = DF_REF_READ_WRITE;
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CLASS_CANNOT_CHANGE_MODE
if (CLASS_CANNOT_CHANGE_MODE_P (GET_MODE (dst), use_flags |= DF_REF_MODE_CHANGE;
GET_MODE (SUBREG_REG (dst))))
use_flags |= DF_REF_MODE_CHANGE;
#endif #endif
df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb, df_uses_record (df, &SUBREG_REG (dst), DF_REF_REG_USE, bb,
insn, use_flags); insn, use_flags);
......
...@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -31,6 +31,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#define DF_ALL 255 #define DF_ALL 255
#define DF_HARD_REGS 1024 /* Mark hard registers. */ #define DF_HARD_REGS 1024 /* Mark hard registers. */
#define DF_EQUIV_NOTES 2048 /* Mark uses present in EQUIV/EQUAL notes. */ #define DF_EQUIV_NOTES 2048 /* Mark uses present in EQUIV/EQUAL notes. */
#define DF_FOR_REGALLOC 4096 /* If called for the register allocator. */
enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD, enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
DF_REF_REG_MEM_STORE}; DF_REF_REG_MEM_STORE};
...@@ -52,13 +53,17 @@ enum df_ref_flags ...@@ -52,13 +53,17 @@ enum df_ref_flags
DF_REF_READ_WRITE = 1, DF_REF_READ_WRITE = 1,
/* This flag is set on register references inside a subreg on /* This flag is set on register references inside a subreg on
machines which have CLASS_CANNOT_CHANGE_MODE and where the mode machines which have CANNOT_CHANGE_MODE_CLASS.
change of that subreg expression is invalid for this class.
Note, that this flag can also be set on df_refs representing Note, that this flag can also be set on df_refs representing
the REG itself (i.e., one might not see the subreg anyore). the REG itself (i.e., one might not see the subreg anyore).
Also note, that this flag is set also for hardreg refs, i.e., Also note, that this flag is set also for hardreg refs, i.e.,
you must check yourself if it's a pseudo. */ you must check yourself if it's a pseudo. */
DF_REF_MODE_CHANGE = 2 DF_REF_MODE_CHANGE = 2,
/* This flag is set, if we stripped the subreg from the reference.
In this case we must make conservative guesses, at what the
outer mode was. */
DF_REF_STRIPPED = 4
}; };
......
...@@ -1305,10 +1305,9 @@ init_one_web_common (web, reg) ...@@ -1305,10 +1305,9 @@ init_one_web_common (web, reg)
AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors); AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors);
prune_hardregs_for_mode (&web->usable_regs, prune_hardregs_for_mode (&web->usable_regs,
PSEUDO_REGNO_MODE (web->regno)); PSEUDO_REGNO_MODE (web->regno));
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed) if (web->mode_changed)
AND_COMPL_HARD_REG_SET (web->usable_regs, reg_class_contents[ AND_COMPL_HARD_REG_SET (web->usable_regs, invalid_mode_change_regs);
(int) CLASS_CANNOT_CHANGE_MODE]);
#endif #endif
web->num_freedom = hard_regs_count (web->usable_regs); web->num_freedom = hard_regs_count (web->usable_regs);
web->num_freedom -= web->add_hardregs; web->num_freedom -= web->add_hardregs;
...@@ -1351,6 +1350,7 @@ reinit_one_web (web, reg) ...@@ -1351,6 +1350,7 @@ reinit_one_web (web, reg)
web->artificial = 0; web->artificial = 0;
web->live_over_abnormal = 0; web->live_over_abnormal = 0;
web->mode_changed = 0; web->mode_changed = 0;
web->subreg_stripped = 0;
web->move_related = 0; web->move_related = 0;
web->in_load = 0; web->in_load = 0;
web->target_of_spilled_move = 0; web->target_of_spilled_move = 0;
...@@ -1912,6 +1912,9 @@ parts_to_webs_1 (df, copy_webs, all_refs) ...@@ -1912,6 +1912,9 @@ parts_to_webs_1 (df, copy_webs, all_refs)
if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0 if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0
&& web->regno >= FIRST_PSEUDO_REGISTER) && web->regno >= FIRST_PSEUDO_REGISTER)
web->mode_changed = 1; web->mode_changed = 1;
if ((DF_REF_FLAGS (ref) & DF_REF_STRIPPED) != 0
&& web->regno >= FIRST_PSEUDO_REGISTER)
web->subreg_stripped = 1;
if (i >= def_id if (i >= def_id
&& TEST_BIT (live_over_abnormal, ref_id)) && TEST_BIT (live_over_abnormal, ref_id))
web->live_over_abnormal = 1; web->live_over_abnormal = 1;
...@@ -1961,6 +1964,9 @@ parts_to_webs_1 (df, copy_webs, all_refs) ...@@ -1961,6 +1964,9 @@ parts_to_webs_1 (df, copy_webs, all_refs)
if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0 if ((DF_REF_FLAGS (ref) & DF_REF_MODE_CHANGE) != 0
&& web->regno >= FIRST_PSEUDO_REGISTER) && web->regno >= FIRST_PSEUDO_REGISTER)
web->mode_changed = 1; web->mode_changed = 1;
if ((DF_REF_FLAGS (ref) & DF_REF_STRIPPED) != 0
&& web->regno >= FIRST_PSEUDO_REGISTER)
web->subreg_stripped = 1;
/* Setup def2web, or use2web, and increment num_defs or num_uses. */ /* Setup def2web, or use2web, and increment num_defs or num_uses. */
if (i < def_id) if (i < def_id)
...@@ -2364,10 +2370,9 @@ remember_web_was_spilled (web) ...@@ -2364,10 +2370,9 @@ remember_web_was_spilled (web)
reg_class_contents[(int) GENERAL_REGS]); reg_class_contents[(int) GENERAL_REGS]);
AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors); AND_COMPL_HARD_REG_SET (web->usable_regs, never_use_colors);
prune_hardregs_for_mode (&web->usable_regs, PSEUDO_REGNO_MODE (web->regno)); prune_hardregs_for_mode (&web->usable_regs, PSEUDO_REGNO_MODE (web->regno));
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed) if (web->mode_changed)
AND_COMPL_HARD_REG_SET (web->usable_regs, reg_class_contents[ AND_COMPL_HARD_REG_SET (web->usable_regs, invalid_mode_change_regs);
(int) CLASS_CANNOT_CHANGE_MODE]);
#endif #endif
web->num_freedom = hard_regs_count (web->usable_regs); web->num_freedom = hard_regs_count (web->usable_regs);
if (!web->num_freedom) if (!web->num_freedom)
......
...@@ -1370,10 +1370,9 @@ colorize_one_web (web, hard) ...@@ -1370,10 +1370,9 @@ colorize_one_web (web, hard)
else else
COPY_HARD_REG_SET (colors, COPY_HARD_REG_SET (colors,
usable_regs[reg_preferred_class (web->regno)]); usable_regs[reg_preferred_class (web->regno)]);
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed) if (web->mode_changed)
AND_COMPL_HARD_REG_SET (colors, reg_class_contents[ AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
(int) CLASS_CANNOT_CHANGE_MODE]);
#endif #endif
COPY_HARD_REG_SET (call_clobbered, colors); COPY_HARD_REG_SET (call_clobbered, colors);
AND_HARD_REG_SET (call_clobbered, call_used_reg_set); AND_HARD_REG_SET (call_clobbered, call_used_reg_set);
...@@ -1404,10 +1403,9 @@ colorize_one_web (web, hard) ...@@ -1404,10 +1403,9 @@ colorize_one_web (web, hard)
else else
IOR_HARD_REG_SET (colors, usable_regs IOR_HARD_REG_SET (colors, usable_regs
[reg_alternate_class (web->regno)]); [reg_alternate_class (web->regno)]);
#ifdef CLASS_CANNOT_CHANGE_MODE #ifdef CANNOT_CHANGE_MODE_CLASS
if (web->mode_changed) if (web->mode_changed)
AND_COMPL_HARD_REG_SET (colors, reg_class_contents[ AND_COMPL_HARD_REG_SET (colors, invalid_mode_change_regs);
(int) CLASS_CANNOT_CHANGE_MODE]);
#endif #endif
COPY_HARD_REG_SET (call_clobbered, colors); COPY_HARD_REG_SET (call_clobbered, colors);
AND_HARD_REG_SET (call_clobbered, call_used_reg_set); AND_HARD_REG_SET (call_clobbered, call_used_reg_set);
......
...@@ -148,6 +148,7 @@ HARD_REG_SET never_use_colors; ...@@ -148,6 +148,7 @@ HARD_REG_SET never_use_colors;
HARD_REG_SET usable_regs[N_REG_CLASSES]; HARD_REG_SET usable_regs[N_REG_CLASSES];
unsigned int num_free_regs[N_REG_CLASSES]; unsigned int num_free_regs[N_REG_CLASSES];
HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES]; HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
HARD_REG_SET invalid_mode_change_regs;
unsigned char byte2bitcount[256]; unsigned char byte2bitcount[256];
unsigned int debug_new_regalloc = -1; unsigned int debug_new_regalloc = -1;
...@@ -555,6 +556,23 @@ init_ra () ...@@ -555,6 +556,23 @@ init_ra ()
COPY_HARD_REG_SET (hardregs_for_mode[i], rs); COPY_HARD_REG_SET (hardregs_for_mode[i], rs);
} }
CLEAR_HARD_REG_SET (invalid_mode_change_regs);
#ifdef CANNOT_CHANGE_MODE_CLASS
if (0)
for (i = 0; i < NUM_MACHINE_MODES; i++)
{
enum machine_mode from = (enum machine_mode) i;
enum machine_mode to;
for (to = VOIDmode; to < MAX_MACHINE_MODE; ++to)
{
int r;
for (r = 0; r < FIRST_PSEUDO_REGISTER; r++)
if (REG_CANNOT_CHANGE_MODE_P (from, to, r))
SET_HARD_REG_BIT (invalid_mode_change_regs, r);
}
}
#endif
for (an_unusable_color = 0; an_unusable_color < FIRST_PSEUDO_REGISTER; for (an_unusable_color = 0; an_unusable_color < FIRST_PSEUDO_REGISTER;
an_unusable_color++) an_unusable_color++)
if (TEST_HARD_REG_BIT (never_use_colors, an_unusable_color)) if (TEST_HARD_REG_BIT (never_use_colors, an_unusable_color))
...@@ -755,7 +773,7 @@ reg_alloc () ...@@ -755,7 +773,7 @@ reg_alloc ()
chains per insn, and per regno. In later passes only update chains per insn, and per regno. In later passes only update
that info from the new and modified insns. */ that info from the new and modified insns. */
df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1, df_analyse (df, (ra_pass == 1) ? 0 : (bitmap) -1,
DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN); DF_HARD_REGS | DF_RD_CHAIN | DF_RU_CHAIN | DF_FOR_REGALLOC);
if ((debug_new_regalloc & DUMP_DF) != 0) if ((debug_new_regalloc & DUMP_DF) != 0)
{ {
......
...@@ -168,6 +168,11 @@ struct web ...@@ -168,6 +168,11 @@ struct web
was illegal for hardregs in CLASS_CANNOT_CHANGE_MODE. */ was illegal for hardregs in CLASS_CANNOT_CHANGE_MODE. */
unsigned int mode_changed:1; unsigned int mode_changed:1;
/* Nonzero if some references of this web, where in subreg context,
but the actual subreg is already stripped (i.e. we don't know the
outer mode of the actual reference). */
unsigned int subreg_stripped:1;
/* Nonzero, when this web stems from the last pass of the allocator, /* Nonzero, when this web stems from the last pass of the allocator,
and all info is still valid (i.e. it wasn't spilled). */ and all info is still valid (i.e. it wasn't spilled). */
unsigned int old_web:1; unsigned int old_web:1;
...@@ -497,6 +502,8 @@ extern unsigned int num_free_regs[N_REG_CLASSES]; ...@@ -497,6 +502,8 @@ extern unsigned int num_free_regs[N_REG_CLASSES];
represent the possible resources which could be taken away be a value represent the possible resources which could be taken away be a value
in mode M. */ in mode M. */
extern HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES]; extern HARD_REG_SET hardregs_for_mode[NUM_MACHINE_MODES];
/* The set of hardregs, for which _any_ mode change is invalid. */
extern HARD_REG_SET invalid_mode_change_regs;
/* For 0 <= I <= 255, the number of bits set in I. Used to calculate /* For 0 <= I <= 255, the number of bits set in I. Used to calculate
the number of set bits in a HARD_REG_SET. */ the number of set bits in a HARD_REG_SET. */
extern unsigned char byte2bitcount[256]; extern unsigned char byte2bitcount[256];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment