https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114729

--- Comment #13 from Vineet Gupta <vineetg at gcc dot gnu.org> ---
So after many months on and off on the issue, I think I understand what's going
on.

There are 3 insns involved in the issue which sched1 current generates in
following order:

insn 46(1)      srliw   a0,a5,16
insn 55(3)      srli    a1,a5,32
insn 54(2)      sh      a0,%lo(_Z1sv+2)(a3)

We want them in order 1,2,3 to avoid allocating a1, which ends up getting
spilled.

When insn 54 is ready, we see this

;;        GR_REGS:28(1)  FP_REGS:1(-31)
;;              dependencies resolved: insn 54
;;              tick updated: insn 54 into ready
;;      +------------------------------------------------------
;;      | Pressure costs for ready queue
;;      |  pressure points GR_REGS:[28->28 at 0:94] FP_REGS:[1->1 at 0:94]
                                    ^^^^^^^

insn 54 is clearly a sink insn and it is going to reduce register pressure, no
matter what. But it seems in the complex maze of pressure calculations this
crucial bit is getting lost and model_excess_cost concludes pressure stays at
28 (from 28).

schedule_block
  ready_sort_real
    model_set_excess_costs (first = ready_lastpos (ready) which is insn 54)
       model_excess_cost(insn 54)

model_excess_cost (insn=0x7ffff75c8fc0, print_p=true) at
../../gcc-scratch/gcc/haifa-sched.cc:2428
2428    {
(gdb)
2433      calculate_reg_deaths (insn, insn_death);
(gdb)
2436      cost = 0;
(gdb) 
2446          delta = insn_reg_pressure[pci].set_increase - insn_death[cl];
(gdb) 
(gdb) p delta
$5 = -1
2447          this_cost = model_excess_group_cost (&model_before_pressure,
point, pci, delta = -1)               
(gdb) 
2449          cost += this_cost;
(gdb) p this_cost
$12 = 0

model_excess_group_costs -> model_spill_cost do takes delta -1 into account but
there's a bunch of MAX values (all of which I don't quite understand) which
ends up computing this_cost to 0 which is inaccurate for this insn.

As a hack to understand this, I initialize the cost above to NOT 0, but the
first delta which causes the -1 to get factored into cost returned by
model_excess_cost.

@@ -2444,6 +2444,8 @@ model_excess_cost (rtx_insn *insn, bool print_p)
     {
       cl = ira_pressure_classes[pci];
       delta = insn_reg_pressure[pci].set_increase - insn_death[cl];
+      if (pci == 0)
+        cost = delta;
       this_cost = model_excess_group_cost (&model_before_pressure,
                                           point, pci, delta);

This causes the test to NOT spill. This doesn't feel like a production ready
fix but seems like progress.

Reply via email to