public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
From: Richard Sandiford <richard.sandiford@arm.com>
To: Georg-Johann Lay <gjl@gcc.gnu.org>
Cc: gcc@gcc.gnu.org
Subject: Re: Code bloat due to silly IRA cost model?
Date: Wed, 11 Dec 2019 17:55:00 -0000	[thread overview]
Message-ID: <mpteexa21d5.fsf@arm.com> (raw)
In-Reply-To: <5DEFFCD4.4080903@gcc.gnu.org> (Georg-Johann Lay's message of	"Tue, 10 Dec 2019 21:15:16 +0100")

Georg-Johann Lay <gjl@gcc.gnu.org> writes:
> Hi, doesn't actually anybody know know to make memory more expensive 
> than registers when it comes to allocating registers?
>
> Whatever I am trying for TARGET_MEMORY_MOVE_COST and 
> TARGET_REGISTER_MOVE_COST, ira-costs.c always makes registers more 
> expensive than mem and therefore allocates values to stack slots instead 
> of keeping them in registers.
>
> Test case (for avr) is as simple as it gets:
>
> float func (float);
>
> float call (float f)
> {
>      return func (f);
> }
>
> What am I missing?
>
> Johann
>
>
> Georg-Johann Lay schrieb:
>> Hi,
>> 
>> I am trying to track down a code bloat issue and am stuck because I do 
>> not understand IRA's cost model.
>> 
>> The test case is as simple as it gets:
>> 
>> float func (float);
>> 
>> float call (float f)
>> {
>>     return func (f);
>> }
>> 
>> IRA dump shows the following insns:
>> 
>> 
>> (insn 14 4 2 2 (set (reg:SF 44)
>>         (reg:SF 22 r22 [ f ])) "bloat.c":4:1 85 {*movsf}
>>      (expr_list:REG_DEAD (reg:SF 22 r22 [ f ])
>>         (nil)))
>> (insn 2 14 3 2 (set (reg/v:SF 43 [ f ])
>>         (reg:SF 44)) "bloat.c":4:1 85 {*movsf}
>>      (expr_list:REG_DEAD (reg:SF 44)
>>         (nil)))
>> (note 3 2 6 2 NOTE_INSN_FUNCTION_BEG)
>> (insn 6 3 7 2 (set (reg:SF 22 r22)
>>         (reg/v:SF 43 [ f ])) "bloat.c":5:12 85 {*movsf}
>>      (expr_list:REG_DEAD (reg/v:SF 43 [ f ])
>>         (nil)))
>> (call_insn/j 7 6 8 2 (parallel [
>> 
>> #14 sets pseudo 44 from arg register R22.
>> #2 moves it to pseudo 43
>> #6 moves it to R22 as it prepares for call_insn #7.
>> 
>> There are 2 allocnos and cost:
>> 
>> Pass 0 for finding pseudo/allocno costs
>> 
>>     a1 (r44,l0) best NO_REGS, allocno NO_REGS
>>     a0 (r43,l0) best NO_REGS, allocno NO_REGS
>> 
>>   a0(r43,l0) costs: ADDW_REGS:32000 SIMPLE_LD_REGS:32000 LD_REGS:32000 
>> NO_LD_REGS:32000 GENERAL_REGS:32000 MEM:9000
>>   a1(r44,l0) costs: ADDW_REGS:32000 SIMPLE_LD_REGS:32000 LD_REGS:32000 
>> NO_LD_REGS:32000 GENERAL_REGS:32000 MEM:9000
>> 
>> which is quite odd because MEM is way more expensive here than any REG.
>> 
>> Okay, so let's boost the MEM cost (TARGET_MEMORY_MOVE_COST) by a factor 
>> of 100:
>> 
>>     a1 (r44,l0) best NO_REGS, allocno NO_REGS
>>     a0 (r43,l0) best NO_REGS, allocno NO_REGS
>> 
>>   a0(r43,l0) costs: ADDW_REGS:3200000 SIMPLE_LD_REGS:3200000 
>> LD_REGS:3200000 NO_LD_REGS:3200000 GENERAL_REGS:3200000 MEM:801000
>>   a1(r44,l0) costs: ADDW_REGS:3200000 SIMPLE_LD_REGS:3200000 
>> LD_REGS:3200000 NO_LD_REGS:3200000 GENERAL_REGS:3200000 MEM:801000
>> 
>> What??? The REG costs are 100 times higher, and stille higher that the 
>> MEM costs.  What the heck is going on?
>> 
>> Setting TARGET_REGISTER_MOVE_COST and also TARGET_MEMORY_MOVE_COST to 0 
>> yiels:
>> 
>>   a0(r43,l0) costs: ADDW_REGS:0 SIMPLE_LD_REGS:0 LD_REGS:0 NO_LD_REGS:0 
>> GENERAL_REGS:0 MEM:0
>>   a1(r44,l0) costs: ADDW_REGS:0 SIMPLE_LD_REGS:0 LD_REGS:0 NO_LD_REGS:0 
>> GENERAL_REGS:0 MEM:0
>> 
>> as expected, i.e. there is no other hidden source of costs considered by 
>> IRA.  And even TARGET_REGISTER_MOVE_COST = 0  and 
>> TARGET_MEMORY_MOVE_COST = original gives:
>> 
>>   a0(r43,l0) costs: ADDW_REGS:32000 SIMPLE_LD_REGS:32000 LD_REGS:32000 
>> NO_LD_REGS:32000 GENERAL_REGS:32000 MEM:9000
>>   a1(r44,l0) costs: ADDW_REGS:32000 SIMPLE_LD_REGS:32000 LD_REGS:32000 
>> NO_LD_REGS:32000 GENERAL_REGS:32000 MEM:9000
>> 
>> How the heck do I tell ira-costs that registers are way cheaper than MEM?

I think this is coming from:

  /* FIXME: Ideally, the following test is not needed.
        However, it turned out that it can reduce the number
        of spill fails.  AVR and it's poor endowment with
        address registers is extreme stress test for reload.  */

  if (GET_MODE_SIZE (mode) >= 4
      && regno >= REG_X)
    return false;

in avr_hard_regno_mode_ok.  This forbids SFmode in r26+ and means that
moves between pointer registers and general registers have the highest
possible cost (65535) to prevent them for being used for SFmode.  So:

   ira_register_move_cost[SFmode][POINTER_REGS][GENERAL_REGS] = 65535;

The costs for union classes are the maximum (worst-case) cost of
for each subclass, so this means that:

   ira_register_move_cost[SFmode][GENERAL_REGS][GENERAL_REGS] = 65535;

as well.

Removing the code above fixes it.  If you don't want to do that, an
alternative might be to add a class for r0-r25 (but I've not tested that).

Thanks,
Richard

>> 
>> Johann
>> 
>> 
>> p.s.
>> 
>> test case compiled with
>> 
>> $ avr-gcc bloat.c -S -Os -dp -da -fsplit-wide-types-early -v
>> 
>> Target: avr
>> Configured with: ../../gcc.gnu.org/trunk/configure --target=avr 
>> --prefix=/local/gnu/install/gcc-10 --disable-shared --disable-nls 
>> --with-dwarf2 --enable-target-optspace=yes --with-gnu-as --with-gnu-ld 
>> --enable-checking=release --enable-languages=c,c++ --disable-gcov
>> Thread model: single
>> Supported LTO compression algorithms: zlib
>> gcc version 10.0.0 20191021 (experimental) (GCC)

  reply	other threads:[~2019-12-11 17:55 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-10-25 11:07 Georg-Johann Lay
2019-12-10 20:16 ` Georg-Johann Lay
2019-12-11 17:55   ` Richard Sandiford [this message]
2019-12-13 11:58     ` Georg-Johann Lay
2019-12-13 12:46       ` Richard Sandiford
2019-12-13 16:04         ` Segher Boessenkool
2019-12-13 16:22           ` Richard Sandiford
2019-12-13 18:59             ` Segher Boessenkool
2019-12-13 22:31               ` Richard Sandiford
2019-12-18 15:29                 ` Segher Boessenkool
2019-12-18 15:43                   ` Richard Sandiford
2020-01-09  9:52         ` Georg-Johann Lay
2019-12-16 13:52     ` Georg-Johann Lay
2019-12-16 14:12       ` Richard Sandiford

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=mpteexa21d5.fsf@arm.com \
    --to=richard.sandiford@arm.com \
    --cc=gcc@gcc.gnu.org \
    --cc=gjl@gcc.gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).