------- Comment #3 from abel at gcc dot gnu dot org  2009-05-26 12:19 -------
I have further looked at seqno handling, and it seems that we can't rip it off
without changing the region walking logic pretty much.  Seqnos are computed in
such a way that they mark the stage (the number of iteration of scheduling
loop) on which a parallel group of insns has been scheduled.  That is, if all
insns scheduled within the first iteration on fences will get #1, all insns
scheduled within the second iteration will get #2, this will be pretty much
equivalent.

Walking from higher to lower seqnos is prohibited, but not only to mark the
dynamic back-edge, but to forbid moving insns from "earlier" scheduling
iterations to "later" ones.  E.g., when pipelining, we can move insns from
stage #2 to #0 (yet unscheduled code), possibly through insns from stage #1,
but we cannot move insns from stage #1 to #0 through insns belonging to stage
#2.  

This logic is modeled by existing seqnos, so we cannot rip seqnos off without
changing the logic.  We can simplify it very slightly by making seqnos to be
plain iteration numbers like described above, but that would not allow removing
any code as I hoped.  We can also change this logic so that any movements from
scheduled to unscheduled code is possible for pipelining, but that would
require much more work and some tuning (I would probably try that later, but
not for this bug).

Thus, I would fix just the bug for now.  The fix is quite simple.  In the
situations like in the testcase, no positive seqnos around the bookkeeping insn
means that the fences will not be able to get to it.  This normally happens
during pipelining, though quite rare, so we have a code for this that would
pick up unscheduled bookkeeping and schedule it afterwards.  This logic will
deal with the test case, too.  We just need to assign pretty much arbitrary
positive seqno in this case.

So the following patch fixes the test case (it passes all SPECs) and bootstraps
on ia64 with sel-sched enabled at -O2, testing is in progress.  I will post it
to gcc-patches if the testing will look fine.


Index: gcc/sel-sched.c
===================================================================
*** gcc/sel-sched.c     (revision 147558)
--- gcc/sel-sched.c     (working copy)
*************** find_seqno_for_bookkeeping (insn_t place
*** 4524,4534 ****
    if (INSN_P (next)
        && JUMP_P (next)
        && BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert))
!     seqno = INSN_SEQNO (next);
    else if (INSN_SEQNO (join_point) > 0)
      seqno = INSN_SEQNO (join_point);
    else
!     seqno = get_seqno_by_preds (place_to_insert);

    gcc_assert (seqno > 0);
    return seqno;
--- 4524,4550 ----
    if (INSN_P (next)
        && JUMP_P (next)
        && BLOCK_FOR_INSN (next) == BLOCK_FOR_INSN (place_to_insert))
!     {
!       gcc_assert (INSN_SCHED_TIMES (next) == 0);
!       seqno = INSN_SEQNO (next);
!     }
    else if (INSN_SEQNO (join_point) > 0)
      seqno = INSN_SEQNO (join_point);
    else
!     {
!       seqno = get_seqno_by_preds (place_to_insert);
!
!       /* Sometimes the fences can move in such a way that there will be
!          no instructions with positive seqno around this bookkeeping.
!          This means that there will be no way to get to it by a regular
!          fence movement.  Never mind because we pick up such pieces for
!          rescheduling anyways, so any positive value will do for now.  */
!       if (seqno < 0)
!         {
!           gcc_assert (pipelining_p);
!           seqno = 42;
!         }
!     }

    gcc_assert (seqno > 0);
    return seqno;
Index: gcc/sel-sched-ir.c
===================================================================
*** gcc/sel-sched-ir.c  (revision 147558)
--- gcc/sel-sched-ir.c  (working copy)
*************** get_seqno_of_a_pred (insn_t insn)
*** 3730,3736 ****
    return seqno;
  }

! /*  Find the proper seqno for inserting at INSN.  */
  int
  get_seqno_by_preds (rtx insn)
  {
--- 3730,3737 ----
    return seqno;
  }

! /*  Find the proper seqno for inserting at INSN.  Returns -1 if no
predecessors
!     with positive seqno exist.  */
  int
  get_seqno_by_preds (rtx insn)
  {
*************** get_seqno_by_preds (rtx insn)
*** 3749,3755 ****
    for (i = 0, seqno = -1; i < n; i++)
      seqno = MAX (seqno, INSN_SEQNO (preds[i]));

-   gcc_assert (seqno > 0);
    return seqno;
  }

--- 3750,3755 ----


-- 


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

Reply via email to