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);
   }
}




Reply via email to