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)