df.h (DF_SUBREGS, [...]): New.
2005-05-26 Paolo Bonzini <bonzini@gnu.org> * df.h (DF_SUBREGS, df_local_def_available_p, df_insn_modified_p): New. * df.c (DF_SUBREGS, df_local_def_available_p, df_insn_modified_p): New. From-SVN: r100197
This commit is contained in:
parent
383898f765
commit
57a95bc48d
@ -1,3 +1,8 @@
|
||||
2005-05-26 Paolo Bonzini <bonzini@gnu.org>
|
||||
|
||||
* df.h (DF_SUBREGS, df_local_def_available_p, df_insn_modified_p): New.
|
||||
* df.c (DF_SUBREGS, df_local_def_available_p, df_insn_modified_p): New.
|
||||
|
||||
2005-05-26 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR target/21716
|
||||
|
61
gcc/df.c
61
gcc/df.c
@ -820,7 +820,8 @@ df_ref_record (struct df *df, rtx reg, rtx *loc, rtx insn,
|
||||
reg. As written in the docu those should have the form
|
||||
(subreg:SI (reg:M A) N), with size(SImode) > size(Mmode).
|
||||
XXX Is that true? We could also use the global word_mode variable. */
|
||||
if (GET_CODE (reg) == SUBREG
|
||||
if ((df->flags & DF_SUBREGS) == 0
|
||||
&& GET_CODE (reg) == SUBREG
|
||||
&& (GET_MODE_SIZE (GET_MODE (reg)) < GET_MODE_SIZE (word_mode)
|
||||
|| GET_MODE_SIZE (GET_MODE (reg))
|
||||
>= GET_MODE_SIZE (GET_MODE (SUBREG_REG (reg)))))
|
||||
@ -2675,6 +2676,20 @@ df_insn_modify (struct df *df, basic_block bb, rtx insn)
|
||||
will just get ignored. */
|
||||
}
|
||||
|
||||
/* Check if INSN was marked as changed. Of course the correctness of
|
||||
the information depends on whether the instruction was really modified
|
||||
at the time df_insn_modify was called. */
|
||||
bool
|
||||
df_insn_modified_p (struct df *df, rtx insn)
|
||||
{
|
||||
unsigned int uid;
|
||||
|
||||
uid = INSN_UID (insn);
|
||||
return (df->insns_modified
|
||||
&& uid < df->insn_size
|
||||
&& bitmap_bit_p (df->insns_modified, uid));
|
||||
}
|
||||
|
||||
typedef struct replace_args
|
||||
{
|
||||
rtx match;
|
||||
@ -3237,6 +3252,48 @@ df_bb_regs_lives_compare (struct df *df, basic_block bb, rtx reg1, rtx reg2)
|
||||
}
|
||||
|
||||
|
||||
/* Return true if the definition DEF, which is in the same basic
|
||||
block as USE, is available at USE. So DEF may as well be
|
||||
dead, in which case using it will extend its live range. */
|
||||
bool
|
||||
df_local_def_available_p (struct df *df, struct ref *def, struct ref *use)
|
||||
{
|
||||
struct df_link *link;
|
||||
int def_luid = DF_INSN_LUID (df, DF_REF_INSN (def));
|
||||
int in_bb = 0;
|
||||
unsigned int regno = REGNO (def->reg);
|
||||
basic_block bb;
|
||||
|
||||
/* The regs must be local to BB. */
|
||||
gcc_assert (DF_REF_BB (def) == DF_REF_BB (use));
|
||||
bb = DF_REF_BB (def);
|
||||
|
||||
/* This assumes that the reg-def list is ordered such that for any
|
||||
BB, the first def is found first. However, since the BBs are not
|
||||
ordered, the first def in the chain is not necessarily the first
|
||||
def in the function. */
|
||||
for (link = df->regs[regno].defs; link; link = link->next)
|
||||
{
|
||||
struct ref *this_def = link->ref;
|
||||
if (DF_REF_BB (this_def) == bb)
|
||||
{
|
||||
int this_luid = DF_INSN_LUID (df, DF_REF_INSN (this_def));
|
||||
/* Do nothing with defs coming before DEF. */
|
||||
if (this_luid > def_luid)
|
||||
return this_luid > DF_INSN_LUID (df, DF_REF_INSN (use));
|
||||
|
||||
in_bb = 1;
|
||||
}
|
||||
else if (in_bb)
|
||||
/* DEF was the last in its basic block. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* DEF was the last in the function. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Return last use of REGNO within BB. */
|
||||
struct ref *
|
||||
df_bb_regno_last_use_find (struct df *df, basic_block bb, unsigned int regno)
|
||||
@ -3304,7 +3361,7 @@ df_bb_regno_last_def_find (struct df *df, basic_block bb, unsigned int regno)
|
||||
return last_def;
|
||||
}
|
||||
|
||||
/* Return first use of REGNO inside INSN within BB. */
|
||||
/* Return last use of REGNO inside INSN within BB. */
|
||||
static struct ref *
|
||||
df_bb_insn_regno_last_use_find (struct df *df,
|
||||
basic_block bb ATTRIBUTE_UNUSED, rtx insn,
|
||||
|
11
gcc/df.h
11
gcc/df.h
@ -38,6 +38,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
||||
#define DF_ALL 255
|
||||
#define DF_HARD_REGS 1024 /* Mark hard registers. */
|
||||
#define DF_EQUIV_NOTES 2048 /* Mark uses present in EQUIV/EQUAL notes. */
|
||||
#define DF_SUBREGS 4096 /* Return subregs rather than the inner reg. */
|
||||
|
||||
enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE, DF_REF_REG_MEM_LOAD,
|
||||
DF_REF_REG_MEM_STORE};
|
||||
@ -207,11 +208,9 @@ struct df_map
|
||||
((DF)->regs[REGNUM].uses ? (DF)->regs[REGNUM].uses->ref : 0)
|
||||
|
||||
#define DF_REGNO_FIRST_BB(DF, REGNUM) \
|
||||
(DF_REGNO_FIRST_DEF (DF, REGNUM) \
|
||||
? DF_REF_BB (DF_REGNO_FIRST_DEF (DF, REGNUM)) : 0)
|
||||
((DF)->regs[REGNUM].defs ? DF_REF_BB ((DF)->regs[REGNUM].defs->ref) : 0)
|
||||
#define DF_REGNO_LAST_BB(DF, REGNUM) \
|
||||
(DF_REGNO_LAST_USE (DF, REGNUM) \
|
||||
? DF_REF_BB (DF_REGNO_LAST_USE (DF, REGNUM)) : 0)
|
||||
((DF)->regs[REGNUM].uses ? DF_REF_BB ((DF)->regs[REGNUM].uses->ref) : 0)
|
||||
|
||||
|
||||
/* Macros to access the elements within the insn_info structure table. */
|
||||
@ -235,6 +234,8 @@ extern void df_dump (struct df *, int, FILE *);
|
||||
|
||||
/* Functions to modify insns. */
|
||||
|
||||
extern bool df_insn_modified_p (struct df *, rtx);
|
||||
|
||||
extern void df_insn_modify (struct df *, basic_block, rtx);
|
||||
|
||||
extern rtx df_insn_delete (struct df *, basic_block, rtx);
|
||||
@ -280,6 +281,8 @@ extern int df_bb_reg_live_end_p (struct df *, basic_block, rtx);
|
||||
|
||||
extern int df_bb_regs_lives_compare (struct df *, basic_block, rtx, rtx);
|
||||
|
||||
extern bool df_local_def_available_p (struct df *, struct ref *, struct ref *);
|
||||
|
||||
extern rtx df_bb_single_def_use_insn_find (struct df *, basic_block, rtx,
|
||||
rtx);
|
||||
extern struct ref *df_bb_regno_last_use_find (struct df *, basic_block, unsigned int);
|
||||
|
Loading…
Reference in New Issue
Block a user