This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PR rtl-optimization/55604]: fix ICE in remove_some_program_points_and_update_live_ranges


On Wed, Dec 5, 2012 at 7:47 PM, Vladimir Makarov wrote:
> On 12-12-05 1:13 PM, Aldy Hernandez wrote:
>>
>> This is a division by zero ICE.
>>
>> In the testcase in the PR, both `n' and `lra_live_max_point' are zero. I
>> have opted to inhibit the dump when lra_live_max_point is zero, but I can
>> just as easily avoiding printing the percentage in this case.
>>
> Interesting.  I never thought that is possible.
>
>> Let me know what you prefer.
>>
>> OK for trunk?
>
> Yes, it is ok if you add the testcase for GCC testsuite.

Eh, are you sure?

This means we enter remove_some_program_points_and_update_live_ranges
with lra_live_max_point==0 (it's updated _after_ compression so at the
point of the dump it's using the value on entry, _before_
compression). So we're doing things like:

  born = sbitmap_alloc (lra_live_max_point); // => sbitmap_alloc (0);
  dead = sbitmap_alloc (lra_live_max_point); // idem
  bitmap_clear (born); // clear a bitmap that doesn't really exit
  bitmap_clear (dead); // idem.
  max_regno = max_reg_num ();
  for (i = FIRST_PSEUDO_REGISTER; i < (unsigned) max_regno; i++)
    {  // walk all registers on looking for live ranges -- but there
can't be any
      for (r = lra_reg_info[i].live_ranges; r != NULL; r = r->next)
        {
          lra_assert (r->start <= r->finish);
          bitmap_set_bit (born, r->start);
          bitmap_set_bit (dead, r->finish);
        }
    }

etc.


That makes no sense...

The function that triggers this, has this RTL after IRA:

    1: NOTE_INSN_DELETED
    3: NOTE_INSN_BASIC_BLOCK 2
    2: NOTE_INSN_FUNCTION_BEG
    5: {r60:DI=frame:DI-0x10;clobber flags:CC;}
      REG_UNUSED flags:CC
      REG_EQUIV frame:DI-0x10
    6: dx:DI=r60:DI
      REG_DEAD r60:DI
      REG_EQUAL frame:DI-0x10
    7: si:SI=0x5
    8: di:DI=`*.LC0'
    9: ax:QI=0
   10: ax:SI=call [`printf'] argc:0
      REG_DEAD di:DI
      REG_DEAD si:SI
      REG_DEAD dx:DI
      REG_UNUSED ax:SI
   15: ax:SI=0
   18: use ax:SI

Note how there are no pseudos at all in the function. So why run LRA
on it at all?

How about the fix proposed below?

Ciao!
Steven


Index: lra-lives.c
===================================================================
--- lra-lives.c (revision 194226)
+++ lra-lives.c (working copy)
@@ -915,6 +915,7 @@ lra_create_live_ranges (bool all_p)
   basic_block bb;
   int i, hard_regno, max_regno = max_reg_num ();
   int curr_point;
+  bool have_referenced_pseudos = false;

   timevar_push (TV_LRA_CREATE_LIVE_RANGES);

@@ -947,10 +948,24 @@ lra_create_live_ranges (bool all_p)
       lra_reg_info[i].call_p = false;
 #endif
       if (i >= FIRST_PSEUDO_REGISTER
-         && lra_reg_info[i].nrefs != 0 && (hard_regno = reg_renumber[i]) >= 0)
-       lra_hard_reg_usage[hard_regno] += lra_reg_info[i].freq;
+         && lra_reg_info[i].nrefs != 0)
+       {
+         if ((hard_regno = reg_renumber[i]) >= 0)
+           lra_hard_reg_usage[hard_regno] += lra_reg_info[i].freq;
+         have_referenced_pseudos = true;
+       }
     }
   lra_free_copies ();
+
+  /* Under some circumstances, we can have functions without pseudo
+     registers.  For such functions, lra_live_max_point will be 0,
+     see e.g. PR55604, and there's nothing more to do for us here.  */
+  if (! have_referenced_pseudos)
+    {
+      timevar_pop (TV_LRA_CREATE_LIVE_RANGES);
+      return;
+    }
+
   pseudos_live = sparseset_alloc (max_regno);
   pseudos_live_through_calls = sparseset_alloc (max_regno);
   pseudos_live_through_setjumps = sparseset_alloc (max_regno);
@@ -973,6 +988,7 @@ lra_create_live_ranges (bool all_p)
     }
   free (post_order_rev_cfg);
   lra_live_max_point = curr_point;
+  gcc_checking_assert (lra_live_max_point > 0);
   if (lra_dump_file != NULL)
     print_live_ranges (lra_dump_file);
   /* Clean up. */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]