patch regrename.c enable-checking fix

Graham Stott grahams@redhat.com
Tue Nov 14 11:37:00 GMT 2000


All

Running make check on an --enable-checking=rtl,tree,misc build results in a lot of failures at -O3 with
the following diagnostic.

/egcs/build/gcc/xgcc -B/apple/bradley/grahams/egcs/build/gcc/ -w -O3 -fomit-frame-pointer -c -o
/egcs/build/gcc/testsuite/20000120-2.o /egcs/gcc/gcc/testsuite/gcc.c-torture/compile/20000120-2.c
/egcs/gcc/gcc/testsuite/gcc.c-torture/compile/20000120-2.c: In function `odd':
/egcs/gcc/gcc/testsuite/gcc.c-torture/compile/20000120-2.c:19: RTL check: expected code `reg', have `cc0'
/egcs/gcc/gcc/testsuite/gcc.c-torture/compile/20000120-2.c:19: Internal compiler error in scan_rtx_reg,
at regrename.c:310
   Please submit a full bug report.
   See <URL: http://www.gnu.org/software/gcc/bugs.html > for instructions.

The problem is this code fragment from regrename.c

  for (p = &open_chains; *p;)
    {
      struct du_chain *this = *p;
      int regno = REGNO (*this->loc);
      int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
      int exact_match = (regno == this_regno && nregs == this_nregs);

The chains may be terminated with a cc0_rtx which the above code fragment does not handle.

The patch just skips to the next chain on encountering a cc0_rtx. It looks bigger than it really is
because of the extra indentation of the existing code blocks. (i.e. the essence of the patch is just
changing the above code fragment to)

  for (p = &open_chains; *p;)
    {
      struct du_chain *this = *p;

      if (*this->loc == cc0_rtx)
        p = &this->next_chain;
      else
        {
          int regno = REGNO (*this->loc);
          int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
          int exact_match = (regno == this_regno && nregs == this_nregs);

           ...
        }

Ok to commit?

Graham

ChangeLog
	*(regrename.c): Skip to the next chain on encountering a terminated chain.

--------------------------------------------------------------------------------------------------
Index: regrename.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/regrename.c,v
retrieving revision 1.15
diff -c -p -r1.15 regrename.c
*** regrename.c 2000/11/10 10:44:42     1.15
--- regrename.c 2000/11/14 19:33:34
*************** scan_rtx_reg (insn, loc, class, action,
*** 307,368 ****
    for (p = &open_chains; *p;)
      {
        struct du_chain *this = *p;
-       int regno = REGNO (*this->loc);
-       int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
-       int exact_match = (regno == this_regno && nregs == this_nregs);

!       if (regno + nregs <= this_regno
!         || this_regno + this_nregs <= regno)
        p = &this->next_chain;
!       else if (action == mark_read)
!       {
!         if (! exact_match)
!           abort ();
!         if (class == NO_REGS)
!           abort ();
!
!         this = (struct du_chain *)
!           obstack_alloc (&rename_obstack, sizeof (struct du_chain));
!         this->next_use = *p;
!         this->next_chain = (*p)->next_chain;
!         this->loc = loc;
!         this->insn = insn;
!         this->class = class;
!         this->need_caller_save_reg = 0;
!         *p = this;
!         return;
!       }
!       else if (action != terminate_overlapping_read || ! exact_match)
!       {
!         struct du_chain *next = this->next_chain;
!
!         /* Whether the terminated chain can be used for renaming
!            depends on the action and this being an exact match.
!            In either case, we remove this element from open_chains.  */

!         if ((action == terminate_dead || action == terminate_write)
!             && exact_match)
            {
!             this->next_chain = closed_chains;
!             closed_chains = this;
!             if (rtl_dump_file)
!               fprintf (rtl_dump_file,
!                        "Closing chain %s at insn %d (%s)\n",
!                        reg_names[REGNO (*this->loc)], INSN_UID (insn),
!                        scan_actions_name[(int) action]);
            }
!         else
            {
!             if (rtl_dump_file)
!               fprintf (rtl_dump_file,
!                        "Discarding chain %s at insn %d (%s)\n",
!                        reg_names[REGNO (*this->loc)], INSN_UID (insn),
!                        scan_actions_name[(int) action]);
            }
!         *p = next;
        }
-       else
-       p = &this->next_chain;
      }
  }

--- 307,381 ----
    for (p = &open_chains; *p;)
      {
        struct du_chain *this = *p;

!       /* Check if the chain has been terminated if it has then skip to
!        the next chain.
!
!        This can happen when we've already appended the location to
!        the chain in Step 3, but are trying to hide in-out operands
!        from terminate_write in Step 5.  */
!
!       if (*this->loc == cc0_rtx)
        p = &this->next_chain;
!       else
!         {
!         int regno = REGNO (*this->loc);
!         int nregs = HARD_REGNO_NREGS (regno, GET_MODE (*this->loc));
!         int exact_match = (regno == this_regno && nregs == this_nregs);

!         if (regno + nregs <= this_regno
!             || this_regno + this_nregs <= regno)
!           p = &this->next_chain;
!         else if (action == mark_read)
            {
!             if (! exact_match)
!               abort ();
!             if (class == NO_REGS)
!               abort ();
!
!             this = (struct du_chain *)
!               obstack_alloc (&rename_obstack, sizeof (struct du_chain));
!             this->next_use = *p;
!             this->next_chain = (*p)->next_chain;
!             this->loc = loc;
!             this->insn = insn;
!             this->class = class;
!             this->need_caller_save_reg = 0;
!             *p = this;
!             return;
            }
!         else if (action != terminate_overlapping_read || ! exact_match)
            {
!             struct du_chain *next = this->next_chain;
!
!             /* Whether the terminated chain can be used for renaming
!                depends on the action and this being an exact match.
!                In either case, we remove this element from open_chains.  */
!
!             if ((action == terminate_dead || action == terminate_write)
!                 && exact_match)
!               {
!                 this->next_chain = closed_chains;
!                 closed_chains = this;
!                 if (rtl_dump_file)
!                   fprintf (rtl_dump_file,
!                            "Closing chain %s at insn %d (%s)\n",
!                            reg_names[REGNO (*this->loc)], INSN_UID (insn),
!                            scan_actions_name[(int) action]);
!               }
!             else
!               {
!                 if (rtl_dump_file)
!                   fprintf (rtl_dump_file,
!                            "Discarding chain %s at insn %d (%s)\n",
!                            reg_names[REGNO (*this->loc)], INSN_UID (insn),
!                            scan_actions_name[(int) action]);
!               }
!             *p = next;
            }
!         else
!           p = &this->next_chain;
        }
      }
  }

--------------------------------------------------------------------------------------------------


More information about the Gcc-patches mailing list