Ian and Honza,
Here is a first draft of the a function to find the set of registers
that are (will) be defined on entry to function. I generated this from
our conversation on chat and by looking around.
This function is necessary in the new version of df because, unlike
flow, we do both forwards and backward propagation to get better
information. Thus there is no code in flow to give me a hint about
this. Furthermore, the other places that do forwards analysis like
make_accurate_live analysis punt on the hard registers and just assume
that they are all live on entry to the function.
1) Do you believe that this code could be correct?
2) Most of the paragraphs are protected by either reload_completed or
epilogue_completed (which has a comment at the its point of declaration
that it is true for both the prologue and epilogue). Is it true that
after these epochs, that there will really be code in the first basic
block that will def these registers? I.e. are any of them implicitly
set before the function is called so I will not find a def?
3) Am I missing any classes of registers?
Any one else who has any opinions (or secret, undocumented knowledge of
ports) is encouraged to answer back also.
Thanks,
Kenny
/* Record the (conservative) set of hard registers that are defined on
entry to the function. */
static void
df_record_entry_block_defs (struct dataflow * dflow)
{
unsigned int i;
bitmap_iterator bi;
rtx r;
struct df * df = dflow->df;
bitmap_clear (df->entry_block_defs);
if (! (df->flags & DF_HARD_REGS))
return;
/* Once the prologue has been generated, all of these registers
should just show up in the first regular block. */
if (HAVE_prologue && epilogue_completed)
{
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
if (FUNCTION_ARG_REGNO_P (i))
bitmap_set_bit (df->entry_block_defs, i);
}
#ifdef EH_USES
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
if (EH_USES (i))
{
bitmap_set_bit (df->entry_block_defs, i);
}
#endif
if (REG_P (INCOMING_RETURN_ADDR_RTX))
bitmap_set_bit (df->entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));
/* If STATIC_CHAIN_INCOMING_REGNUM == STATIC_CHAIN_REGNUM
only STATIC_CHAIN_REGNUM is defined. If they are different,
we only care about the STATIC_CHAIN_INCOMING_REGNUM. */
#ifdef STATIC_CHAIN_INCOMING_REGNUM
bitmap_set_bit (df->entry_block_defs, STATIC_CHAIN_INCOMING_REGNUM);
#else
#ifdef STATIC_CHAIN_REGNUM
bitmap_set_bit (df->entry_block_defs, STATIC_CHAIN_REGNUM);
#endif
#endif
r = TARGET_STRUCT_VALUE_RTX (current_function_decl, true)
if (r && REG_P (r))
bitmap_set_bit (df->entry_block_defs, REGNO (r));
}
/* These registers are live everywhere. */
if (! reload_completed)
{
/* Any reference to any pseudo before reload is a potential
reference of the frame pointer. */
bitmap_set_bit (df->entry_block_defs, FRAME_POINTER_REGNUM);
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
/* Pseudos with argument area equivalences may require
reloading via the argument pointer. */
if (fixed_regs[ARG_POINTER_REGNUM])
bitmap_set_bit (df->entry_block_defs, ARG_POINTER_REGNUM);
#endif
/* Any constant, or pseudo with constant equivalences, may
require reloading from memory using the pic register. */
if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
&& fixed_regs[PIC_OFFSET_TABLE_REGNUM])
bitmap_set_bit (df->entry_block_defs, PIC_OFFSET_TABLE_REGNUM);
}
EXECUTE_IF_SET_IN_BITMAP (df->entry_block_defs, 0, i, bi)
{
rtx def = df_reg_def_gen (true, i);
df_ref_create_structure (dflow, regno_reg_rtx[i],
&XEXP (def, 0), ENTRY_BLOCK_PTR, NULL,
DF_REF_REG_DEF, DF_REF_ARTIFICIAL);
}
}