OSDN Git Service

[pf3gnuchains/gcc-fork.git] / gcc / reorg.c
index 007d92e..a26f9d2 100644 (file)
@@ -61,6 +61,10 @@ Boston, MA 02111-1307, USA.  */
    we can hoist insns from the fall-through path for forward branches or
    steal insns from the target of backward branches.
 
+   The TMS320C3x and C4x have three branch delay slots.  When the three
+   slots are filled, the branch penalty is zero.  Most insns can fill the
+   delay slots except jump insns.
+
    Three techniques for filling delay slots have been implemented so far:
 
    (1) `fill_simple_delay_slots' is the simplest, most efficient way
@@ -131,12 +135,6 @@ Boston, MA 02111-1307, USA.  */
 #include "obstack.h"
 #include "insn-attr.h"
 
-/* Import list of registers used as spill regs from reload.  */
-extern HARD_REG_SET used_spill_regs;
-
-/* Import highest label used in function at end of reload.  */
-extern int max_label_num_after_reload;
-
 
 #ifdef DELAY_SLOTS
 
@@ -1693,6 +1691,7 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
   int must_annul = *pannul_p;
   int i;
   int used_annul = 0;
+  struct resources cc_set;
 
   /* We can't do anything if there are more delay slots in SEQ than we
      can handle, or if we don't know that it will be a taken branch.
@@ -1702,7 +1701,23 @@ steal_delay_list_from_target (insn, condition, seq, delay_list,
      Also, exit if the branch has more than one set, since then it is computing
      other results that can't be ignored, e.g. the HPPA mov&branch instruction.
      ??? It may be possible to move other sets into INSN in addition to
-     moving the instructions in the delay slots.  */
+     moving the instructions in the delay slots.
+
+     We can not steal the delay list if one of the instructions in the
+     current delay_list modifies the condition codes and the jump in the 
+     sequence is a conditional jump. We can not do this because we can
+     not change the direction of the jump because the condition codes
+     will effect the direction of the jump in the sequence. */
+
+  CLEAR_RESOURCE (&cc_set);
+  for (temp = delay_list; temp; temp = XEXP (temp, 1))
+    {
+      rtx trial = XEXP (temp, 0);
+
+      mark_set_resources (trial, &cc_set, 0, 1);
+      if (insn_references_resource_p (XVECEXP (seq , 0, 0), &cc_set, 0))
+        return delay_list;
+    }
 
   if (XVECLEN (seq, 0) - 1 > slots_remaining
       || ! condition_dominates_p (condition, XVECEXP (seq, 0, 0))
@@ -2584,14 +2599,6 @@ find_dead_or_set_registers (target, res, jump_target, jump_count, set, needed)
          AND_COMPL_HARD_REG_SET (res->regs, pending_dead_regs);
          CLEAR_HARD_REG_SET (pending_dead_regs);
 
-         if (CODE_LABEL_NUMBER (insn) < max_label_num_after_reload)
-           {
-             /* All spill registers are dead at a label, so kill all of the
-                ones that aren't needed also.  */
-             COPY_HARD_REG_SET (scratch, used_spill_regs);
-             AND_COMPL_HARD_REG_SET (scratch, needed.regs);
-             AND_COMPL_HARD_REG_SET (res->regs, scratch);
-           }
          continue;
 
        case BARRIER:
@@ -3452,7 +3459,8 @@ fill_simple_delay_slots (non_jumps_p)
       SET_HARD_REG_BIT (needed.regs, HARD_FRAME_POINTER_REGNUM);
 #endif
 #ifdef EXIT_IGNORE_STACK
-      if (! EXIT_IGNORE_STACK)
+      if (! EXIT_IGNORE_STACK
+         || current_function_sp_is_unchanging)
 #endif
        SET_HARD_REG_BIT (needed.regs, STACK_POINTER_REGNUM);
     }
@@ -3729,8 +3737,6 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
 
                  delay_list = add_to_delay_list (temp, delay_list);
 
-                 mark_set_resources (trial, &opposite_needed, 0, 1);
-
                  if (slots_to_fill == ++(*pslots_filled))
                    {
                      /* Even though we have filled all the slots, we
@@ -3808,9 +3814,7 @@ fill_slots_from_thread (insn, condition, thread, opposite_thread, likely,
     {
       /* If this is the `true' thread, we will want to follow the jump,
         so we can only do this if we have taken everything up to here.  */
-      if (thread_if_true && trial == new_thread
-         && ! insn_references_resource_p (XVECEXP (PATTERN (trial), 0, 0),
-                                          &opposite_needed, 0))
+      if (thread_if_true && trial == new_thread)
        delay_list
          = steal_delay_list_from_target (insn, condition, PATTERN (trial),
                                          delay_list, &set, &needed,
@@ -4160,7 +4164,7 @@ relax_delay_slots (first)
          && (other = prev_active_insn (insn)) != 0
          && (condjump_p (other) || condjump_in_parallel_p (other))
          && no_labels_between_p (other, insn)
-         && 0 < mostly_true_jump (other,
+         && 0 > mostly_true_jump (other,
                                   get_branch_condition (other,
                                                         JUMP_LABEL (other))))
        {
@@ -4602,7 +4606,8 @@ dbr_schedule (first, file)
       SET_HARD_REG_BIT (end_of_function_needs.regs, HARD_FRAME_POINTER_REGNUM);
 #endif
 #ifdef EXIT_IGNORE_STACK
-      if (! EXIT_IGNORE_STACK)
+      if (! EXIT_IGNORE_STACK
+         || current_function_sp_is_unchanging)
 #endif
        SET_HARD_REG_BIT (end_of_function_needs.regs, STACK_POINTER_REGNUM);
     }