Delay slot scheduling bug in gcc 2.8 & egcs 1.0.1

Ken Rose rose@acm.org
Thu Feb 12 17:47:00 GMT 1998


There is a bug in both gcc-2.8.0 and egcs-1.0.1 in the delay slot
scheduling code.
In fill_simple_delay_slots(), it first tries to fill slots from the code

before the branch, and if it is an unconditional branch, it then tries
to fill any
remaining slots from the branch target.  The problem is that when it
goes
to look at the target, it forgets about any insns that it has already
picked up.  Ultimately this results in a SEQUENCE that is shorter than
is represented
to emit_delay_sequence(), which crashes.

My solution is to add another parameter to fill_slots_from_thread() and
pass
the current list of delay insns (possibly NULL) in, so that it can be
extended
and eventually passed to emit_delay_sequence().

Changelog entry:

Thu Feb 12 17:30:00 1998  Ken Rose (rose@acm.org)

        * reorg.c (fill_simple_delay_slots,fill_slots_from_thread
        fill_eager_delay_slots): Added delay_list parameter to
        fill_slots_from_thread().

Patch:


*** reorg.c.old Thu Feb 12 11:39:06 1998
--- reorg.c     Thu Feb 12 11:49:06 1998
*************** static rtx next_insn_no_annul   PROTO((rtx
*** 266,272 ****
  static void mark_target_live_regs PROTO((rtx, struct resources *));
  static void fill_simple_delay_slots PROTO((rtx, int));
  static rtx fill_slots_from_thread PROTO((rtx, rtx, rtx, rtx, int, int,

!                                        int, int, int, int *));
  static void fill_eager_delay_slots PROTO((rtx));
  static void relax_delay_slots PROTO((rtx));
  static void make_return_insns PROTO((rtx));
--- 266,272 ----
  static void mark_target_live_regs PROTO((rtx, struct resources *));
  static void fill_simple_delay_slots PROTO((rtx, int));
  static rtx fill_slots_from_thread PROTO((rtx, rtx, rtx, rtx, int, int,

!                                        int, int, int, int *, rtx));
  static void fill_eager_delay_slots PROTO((rtx));
  static void relax_delay_slots PROTO((rtx));
  static void make_return_insns PROTO((rtx));
*************** fill_simple_delay_slots (first, non_jump
*** 3322,3328 ****
                                    NULL, 1, 1,
                                    own_thread_p (JUMP_LABEL (insn),
                                                  JUMP_LABEL (insn), 0),

!                                   0, slots_to_fill, &slots_filled);

        if (delay_list)
        unfilled_slots_base[i]
--- 3322,3328 ----
                                    NULL, 1, 1,
                                    own_thread_p (JUMP_LABEL (insn),
                                                  JUMP_LABEL (insn), 0),

!                                   0, slots_to_fill, &slots_filled,
delay_list);

        if (delay_list)
        unfilled_slots_base[i]
*************** fill_simple_delay_slots (first, non_jump
*** 3452,3458 ****
  static rtx
  fill_slots_from_thread (insn, condition, thread, opposite_thread,
likely,
                        thread_if_true, own_thread, own_opposite_thread,

!                       slots_to_fill, pslots_filled)
       rtx insn;
       rtx condition;
       rtx thread, opposite_thread;
--- 3452,3458 ----
  static rtx
  fill_slots_from_thread (insn, condition, thread, opposite_thread,
likely,
                        thread_if_true, own_thread, own_opposite_thread,

!                       slots_to_fill, pslots_filled, delay_list)
       rtx insn;
       rtx condition;
       rtx thread, opposite_thread;
*************** fill_slots_from_thread (insn, condition,
*** 3460,3468 ****
       int thread_if_true;
       int own_thread, own_opposite_thread;
       int slots_to_fill, *pslots_filled;
  {
    rtx new_thread;
-   rtx delay_list = 0;
    struct resources opposite_needed, set, needed;
    rtx trial;
    int lose = 0;
--- 3460,3468 ----
       int thread_if_true;
       int own_thread, own_opposite_thread;
       int slots_to_fill, *pslots_filled;
+      rtx delay_list;
  {
    rtx new_thread;
    struct resources opposite_needed, set, needed;
    rtx trial;
    int lose = 0;
*************** fill_eager_delay_slots (first)
*** 3905,3911 ****
            = fill_slots_from_thread (insn, condition, insn_at_target,
                                      fallthrough_insn, prediction == 2,
1,
                                      own_target, own_fallthrough,
!                                     slots_to_fill, &slots_filled);

          if (delay_list == 0 && own_fallthrough)
            {
--- 3905,3911 ----
            = fill_slots_from_thread (insn, condition, insn_at_target,
                                      fallthrough_insn, prediction == 2,
1,
                                      own_target, own_fallthrough,
!                                     slots_to_fill, &slots_filled,
delay_list);

          if (delay_list == 0 && own_fallthrough)
            {
*************** fill_eager_delay_slots (first)
*** 3920,3926 ****
                = fill_slots_from_thread (insn, condition,
fallthrough_insn,
                                          insn_at_target, 0, 0,
                                          own_fallthrough, own_target,
!                                         slots_to_fill, &slots_filled);

            }
        }
        else
--- 3920,3926 ----
                = fill_slots_from_thread (insn, condition,
fallthrough_insn,
                                          insn_at_target, 0, 0,
                                          own_fallthrough, own_target,
!                                         slots_to_fill, &slots_filled,
delay_list);
            }
        }
        else
*************** fill_eager_delay_slots (first)
*** 3930,3943 ****
              = fill_slots_from_thread (insn, condition,
fallthrough_insn,
                                        insn_at_target, 0, 0,
                                        own_fallthrough, own_target,
!                                       slots_to_fill, &slots_filled);

          if (delay_list == 0)
            delay_list
              = fill_slots_from_thread (insn, condition, insn_at_target,

                                        next_active_insn (insn), 0, 1,
                                        own_target, own_fallthrough,
!                                       slots_to_fill, &slots_filled);
        }

        if (delay_list)
--- 3930,3943 ----
              = fill_slots_from_thread (insn, condition,
fallthrough_insn,
                                        insn_at_target, 0, 0,
                                        own_fallthrough, own_target,
!                                       slots_to_fill, &slots_filled,
delay_list);

          if (delay_list == 0)
            delay_list
              = fill_slots_from_thread (insn, condition, insn_at_target,

                                        next_active_insn (insn), 0, 1,
                                        own_target, own_fallthrough,
!                                       slots_to_fill, &slots_filled,
delay_list);
        }

        if (delay_list)





More information about the Gcc-bugs mailing list