question about registers that are set on entry to a function.

Kenneth Zadeck zadeck@naturalbridge.com
Thu Jan 5 19:18:00 GMT 2006


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






More information about the Gcc mailing list