Code bloat due to silly IRA cost model?

Georg-Johann Lay gjl@gcc.gnu.org
Tue Dec 10 20:16:00 GMT 2019


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?
> 
> 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)




More information about the Gcc mailing list