Ian Lance Taylor wrote:
Kenneth Zadeck <[EMAIL PROTECTED]> writes:

For complete accuracy, there are probably going to be some target
specific registers which need to be handled, unfortunately.  For
example, on MIPS, with -mabicalls (which is the default on GNU/Linux),
$25 is live on function entry.  It holds the address of the function,
and is used to initialize $28, which is PIC_OFFSET_TABLE_REGNUM.  I
don't think there is any target independent way of getting at that
fact.


Is the right thing to do to define a target hook for this that
defaults to doing nothing and we only define it in those places where
necessary or should I add a few other macros to the ports as necessary
and just check to see if they are defined?  I have noticed that there
are several macros that are only used on a single port.

I think the best approach would be a target hook.  I guess you could
pass it the function decl and have it set bits in a bitmap or a
HARD_REG_SET.  You might even want to do the whole thing in a target
hook, in which case the code you wrote would become the default
version of the hook (and would probably be called by non-default
versions).  I don't have a strong feeling as to which approach would
be best.

Ian
Being the glutton for punishment, lets try this again.

I have one question about EH_USES on the ia-64 (the only place it is used). The function
that implements this starts out with

int
ia64_eh_uses (int regno)
{
 if (! reload_completed)
   return 0;

This means that before register allocation, all of the uses of these registers are hidden.

However, in the definition of REG_ALLOC_ORDER contains all of the register that are defined in ia64_eh_uses after reload. It is at the end of the order and there are a large number of registers but it seems to me that if someone were to write a program that needed a large boatload of registers, the register allocator might be tempted to use these registers (unless there are no instruction patterns that use these registers) and then the instruction exception unwinder would not work.

Is this a latent bug?

Asside from the concern from above and plumbing the target hook, how does this look?

/* 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;

 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   {
     if (FUNCTION_ARG_REGNO_P (i))
#ifdef INCOMING_REGNO
   bitmap_set_bit (df->entry_block_defs, INCOMING_REGNO (i));
#else
   bitmap_set_bit (df->entry_block_defs, i);
#endif
   }
/* Once the prologue has been generated, all of these registers
    should just show up in the first regular block.  */
 if (HAVE_prologue && epilogue_completed)
   {
     /* Defs for the callee saved registers are inserted so that the
    pushes have some defining location.  */
     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   if ((call_used_regs[i] == 0) && (regs_ever_live[i]))
     bitmap_set_bit (df->entry_block_defs, i);
   }
 else
   {
     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);

#ifdef EH_USES
     /* The ia-64, the only machine that uses this, does not define these
    until after reload.  */
     for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
   if (EH_USES (i))
     {
       bitmap_set_bit (df->entry_block_defs, i);
     }
#endif
#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
#ifdef PIC_OFFSET_TABLE_REGNUM
     /* 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);
#endif
   }

 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