------- Comment #5 from vmakarov at redhat dot com  2008-12-19 23:30 -------
Eric, thanks for analysis.  It saved a lot of my time.

The problem was in wrong final live ranges of a379r452 therefore the conflicts
was not recognized and the pseudos were coalesced.  One pseudo is a temporary
pseudo used for breaking register shuffle cycle (it is actually a rare case) on
a CFG edge (loop exit).  And another pseudo is destination of removed store
insn on the loop exit.  In normal case it should not conflict with the
temporary pseudo because the temporary lives only on the edge and another
pseudo lives only after the edge destination.  But it should conflict with the
temporary in this case because we removed the store and another pseudo lives
through all loop.  The suspicious code looks like 

  EXECUTE_IF_SET_IN_BITMAP (live_through, FIRST_PSEUDO_REGISTER, regno, bi)
    {
      a = node->regno_allocno_map[regno];
      if (ALLOCNO_MEM_OPTIMIZED_DEST (a) == NULL)
        {
          ALLOCNO_LIVE_RANGES (a)
            = ira_create_allocno_live_range (a, start, ira_max_point - 1,
                                             ALLOCNO_LIVE_RANGES (a));
          if (internal_flag_ira_verbose > 2 && ira_dump_file != NULL)
            fprintf
              (ira_dump_file,
               "    Adding range [%d..%d] to live through allocno a%dr%d\n",
               start, ira_max_point - 1, ALLOCNO_NUM (a),
               REGNO (ALLOCNO_REG (a)));
        }

I'll send a patch solving the problem after its testing.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38495

Reply via email to