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