This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: local alloc / global alloc / reload problem
- To: john at feith dot com (John Wehle)
- Subject: Re: local alloc / global alloc / reload problem
- From: Jeffrey A Law <law at cygnus dot com>
- Date: Mon, 13 Jul 1998 00:06:02 -0600
- cc: egcs at cygnus dot com, egcs-patches at cygnus dot com
- Reply-To: law at cygnus dot com
In message <199807130430.AAA17950@jwlab.FEITH.COM>you write:
> It appears that i386 performance regression resulting from the June 11
> regmove change is due to regmove turning:
>
> (insn 29 27 31 (set (reg:SI 28)
> (xor:SI (reg/v:SI 21)
> (const_int 1))) -1 (nil)
> (nil))
>
> (insn 31 29 33 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)))
> (reg:SI 28)) -1 (insn_list 29 (nil))
> (expr_list:REG_DEAD (reg:SI 28)
> (nil)))
>
> into:
>
> (insn 280 27 29 (set (reg:SI 28)
> (reg/v:SI 21)) 54 {movsi+2} (nil)
> (nil))
>
> (insn 29 280 31 (set (reg:SI 28)
> (xor:SI (reg:SI 28)
> (const_int 1))) 189 {xorsi3} (nil)
> (nil))
>
> (insn 31 29 33 (set (mem:SI (pre_dec:SI (reg:SI 7 %esp)))
> (reg:SI 28)) 50 {movsi-2} (insn_list 29 (nil))
> (expr_list:REG_DEAD (reg:SI 28)
> (nil)))
>
> Local register allocation allocates hard register 0 for reg 28.
> This is noticed by:
>
> for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
> if (REG_N_REFS (i) != 0 && reg_renumber[i] < 0 && REG_LIVE_LENGTH (i) !
> = -1
> && (! current_function_has_nonlocal_label
|| REG_N_CALLS_CROSSED (i) == 0))
> {
> [ ... ]
> }
> else
> reg_allocno[i] = -1;
>
> in global_alloc so reg_allocno[28] is set to -1. Global register
> allocation is performed and reload is called. Hard register 0 is
> spilled and retry_global_alloc is called for reg 28. As a result
> of reg_allocno equaling -1 retry_global_alloc doesn't do anything
> and reg 28 ends up on the stack even though a hard register may of
> been available.
>
> The enclosed patch is intended ONLY as food for thought ... it does
> NOT survive a bootstrap. Hopefully someone more knowledgeable about
> these issues will chime in.
Current the compiler does not support re-allocation of regs which are
allocated by local-alloc, but are kicked out due to the actions of either
global register allocation or reload.
It doesn't seem like a particularly difficult problem to solve, but then
again I've never tried or even looked deeply into why we've got this
restriction.
So what happened before the regmove change in terms of global alloc
and reload? ie, what hard reg was pseudo 28 assigned to? Presumably
that hard reg did not end up being used as a spill.
jeff