This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: peephole2: dead regs not marked as dead


Paolo Bonzini schrieb:
> On 10/27/2010 04:30 PM, Georg Lay wrote:
>> The first time it occurs in "exit block uses" is in pro/epilogue:
>>
>> peep2.c.193r.split2:;;  exit block uses          2 [d2] 26 [SP] 27 [a11]
>> peep2.c.195r.pro_and_epilogue:;;  exit block uses        2 [d2] 15
>> [d15] 26 [SP]
>> 27 [a11]
>> peep2.c.196r.dse2:;;  exit block uses    2 [d2] 15 [d15] 26 [SP] 27 [a11]
>> peep2.c.196r.dse2:;;  exit block uses    2 [d2] 15 [d15] 26 [SP] 27 [a11]
> 
> Oh, that helps a lot: this is what df_get_exit_block_use_set says:
> 
>   if (HAVE_epilogue && epilogue_completed)
>     {
>       /* Mark all call-saved registers that we actually used.  */
>       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
>         if (df_regs_ever_live_p (i) && !LOCAL_REGNO (i)
>             && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
>           bitmap_set_bit (exit_block_uses, i);
>     }
> 
> These uses are needed to ensure that, if restores of call-saved
> registers are explicitly in the RTL for the epilogue, they are not
> considered dead.  However, they make d15 live.

Yeah! That's it. Totally happy :-)

I implemented Hook LOCAL_REGNO and it works as expected. The machine actually
has no register windows resp. only a "trivial window" with IN_REGNO==OUT_REGNO
for all passed REGs. However, with a proper definition of LOCAL_REGNO I see the
dead-notes and the code is as expected.

I hope LOCAL_REGNO has no undesired side effects. Even the stack pointer (reg 26
[SP] above) is an element of LOCAL_REGNO, which means that if a function needs a
frame, e.g. alloca, there is no need to explicitly restore SP before returning.

> It looks like you need to represent the definition of call-saved
> registers explicitly in the RTL for the epilogue.  These definitions
> will make d15 dead as you expect, and you need them even if they will
> not output any assembly.

Emitting a bunch of CLOBBERs in epilogue/sibcall_epilogue works also, at least
for the small example above. But using LOCAL_REGNO seems more natural to me and
that does not clutter RTL.

> In this sense, this is a backend bug: you are not making the RTL stream
> accurate, and it's biting you.  I acknowledge it's quite tricky; from
> what I understood it happens because of a peculiarity of your
> architecture with respect to callee-save registers (d15 is automatically
> save/restored, or something like that).

Yes. From gcc's point of view it's a hermaphrodite caller-saves and
callee-restores machine where all saves/restores are handled by the hardware and
no code is needed. CALLs save the call-saved regs and invalidate(sic!) them.
When the callee-code starts the content of call-saved regs is undefined (except
SP). So these regs cannot be used to pass params. The RETURN implicitly restores
these registers, the values coming out of the blue (not from the stack). This
introduces overhead in runtime because all call-saved regs get saved/restored no
matter if they are actually used or not. However, code density is good (at least
for prologues and epilogues).

I already had to fix IRA and remove the following part of
ira-color.c::assign_hard_reg() because it makes assumptions that do not hold for
the machine:

      if (! allocated_hardreg_p[hard_regno]
	  && ira_hard_reg_not_in_set_p (hard_regno, mode, call_used_reg_set))
	/* We need to save/restore the hard register in
	   epilogue/prologue.  Therefore we increase the cost.  */
	{
	  /* ??? If only part is call clobbered.  */
	  rclass = REGNO_REG_CLASS (hard_regno);
	  add_cost = (ira_memory_move_cost[mode][rclass][0]
		      + ira_memory_move_cost[mode][rclass][1] - 1);
	  cost += add_cost;
	  full_cost += add_cost;
	}

Thanks a lot for pointing me to the right place!

Georg


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]