OSDN Git Service

* config/bfin/bfin.c (workaround_speculation): Correct algorithm to
authorbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Sep 2008 13:28:34 +0000 (13:28 +0000)
committerbernds <bernds@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 10 Sep 2008 13:28:34 +0000 (13:28 +0000)
not lose track of the number of NOPs needed.  Number of NOPs needed
for sync vs. loads workaround was switched; corrected.  Run second
pass for all workarounds.  No NOPs needed after call insns.  Change
second pass to use find_next_insn_start and find_load helpers in order
to properly detect parallel insns.
* config/bfin/bfin.md (cbranch_with_nops): Increase length.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140230 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/bfin/bfin.c
gcc/config/bfin/bfin.md

index e6ede43..4d68e22 100644 (file)
@@ -1,3 +1,13 @@
+2008-09-10  Bernd Schmidt  <bernd.schmidt@analog.com>
+
+       * config/bfin/bfin.c (workaround_speculation): Correct algorithm to
+       not lose track of the number of NOPs needed.  Number of NOPs needed
+       for sync vs. loads workaround was switched; corrected.  Run second
+       pass for all workarounds.  No NOPs needed after call insns.  Change
+       second pass to use find_next_insn_start and find_load helpers in order
+       to properly detect parallel insns.
+       * config/bfin/bfin.md (cbranch_with_nops): Increase length.
+
 2008-09-10  Jan Hubicka  <jh@suse.cz>
 
        * value-prof.c (gimple_ic): Fix tuplification bug.
 2008-09-10  Jan Hubicka  <jh@suse.cz>
 
        * value-prof.c (gimple_ic): Fix tuplification bug.
index 7ff1379..9af7fab 100644 (file)
@@ -4799,6 +4799,7 @@ workaround_speculation (void)
   rtx insn, next;
   rtx last_condjump = NULL_RTX;
   int cycles_since_jump = INT_MAX;
   rtx insn, next;
   rtx last_condjump = NULL_RTX;
   int cycles_since_jump = INT_MAX;
+  int delay_added = 0;
 
   if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS)
     return;
 
   if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS)
     return;
@@ -4808,6 +4809,7 @@ workaround_speculation (void)
   for (insn = get_insns (); insn; insn = next)
     {
       rtx pat;
   for (insn = get_insns (); insn; insn = next)
     {
       rtx pat;
+      int delay_needed = 0;
 
       next = find_next_insn_start (insn);
       
 
       next = find_next_insn_start (insn);
       
@@ -4826,6 +4828,7 @@ workaround_speculation (void)
              && ! cbranch_predicted_taken_p (insn))
            {
              last_condjump = insn;
              && ! cbranch_predicted_taken_p (insn))
            {
              last_condjump = insn;
+             delay_added = 0;
              cycles_since_jump = 0;
            }
          else
              cycles_since_jump = 0;
            }
          else
@@ -4835,49 +4838,56 @@ workaround_speculation (void)
        {
          rtx load_insn = find_load (insn);
          enum attr_type type = type_for_anomaly (insn);
        {
          rtx load_insn = find_load (insn);
          enum attr_type type = type_for_anomaly (insn);
-         int delay_needed = 0;
+
          if (cycles_since_jump < INT_MAX)
            cycles_since_jump++;
 
          if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
            {
              if (trapping_loads_p (load_insn))
          if (cycles_since_jump < INT_MAX)
            cycles_since_jump++;
 
          if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
            {
              if (trapping_loads_p (load_insn))
-               delay_needed = 3;
+               delay_needed = 4;
            }
          else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
            }
          else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
-           delay_needed = 4;
+           delay_needed = 3;
+       }
 
 
-         if (delay_needed > cycles_since_jump)
-           {
-             rtx pat;
-             int num_clobbers;
-             rtx *op = recog_data.operand;
+      if (delay_needed > cycles_since_jump
+         && (delay_needed - cycles_since_jump) > delay_added)
+       {
+         rtx pat1;
+         int num_clobbers;
+         rtx *op = recog_data.operand;
 
 
-             delay_needed -= cycles_since_jump;
+         delay_needed -= cycles_since_jump;
 
 
-             extract_insn (last_condjump);
-             if (optimize_size)
-               {
-                 pat = gen_cbranch_predicted_taken (op[0], op[1], op[2],
-                                                    op[3]);
-                 cycles_since_jump = INT_MAX;
-               }
-             else
-               /* Do not adjust cycles_since_jump in this case, so that
-                  we'll increase the number of NOPs for a subsequent insn
-                  if necessary.  */
-               pat = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
-                                            GEN_INT (delay_needed));
-             PATTERN (last_condjump) = pat;
-             INSN_CODE (last_condjump) = recog (pat, insn, &num_clobbers);
+         extract_insn (last_condjump);
+         if (optimize_size)
+           {
+             pat1 = gen_cbranch_predicted_taken (op[0], op[1], op[2],
+                                                op[3]);
+             cycles_since_jump = INT_MAX;
+           }
+         else
+           {
+             /* Do not adjust cycles_since_jump in this case, so that
+                we'll increase the number of NOPs for a subsequent insn
+                if necessary.  */
+             pat1 = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
+                                           GEN_INT (delay_needed));
+             delay_added = delay_needed;
            }
            }
+         PATTERN (last_condjump) = pat1;
+         INSN_CODE (last_condjump) = recog (pat1, insn, &num_clobbers);
+       }
+      if (CALL_P (insn))
+       {
+         cycles_since_jump = INT_MAX;
+         delay_added = 0;
        }
     }
        }
     }
+
   /* Second pass: for predicted-true branches, see if anything at the
      branch destination needs extra nops.  */
   /* Second pass: for predicted-true branches, see if anything at the
      branch destination needs extra nops.  */
-  if (! ENABLE_WA_SPECULATIVE_SYNCS)
-    return;
-
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
       int cycles_since_jump;
   for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
     {
       int cycles_since_jump;
@@ -4888,11 +4898,15 @@ workaround_speculation (void)
        {
          rtx target = JUMP_LABEL (insn);
          rtx label = target;
        {
          rtx target = JUMP_LABEL (insn);
          rtx label = target;
+         rtx next_tgt;
+
          cycles_since_jump = 0;
          cycles_since_jump = 0;
-         for (; target && cycles_since_jump < 3; target = NEXT_INSN (target))
+         for (; target && cycles_since_jump < 3; target = next_tgt)
            {
              rtx pat;
 
            {
              rtx pat;
 
+             next_tgt = find_next_insn_start (target);
+
              if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
                continue;
 
              if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
                continue;
 
@@ -4904,12 +4918,18 @@ workaround_speculation (void)
 
              if (INSN_P (target))
                {
 
              if (INSN_P (target))
                {
+                 rtx load_insn = find_load (target);
                  enum attr_type type = type_for_anomaly (target);
                  int delay_needed = 0;
                  if (cycles_since_jump < INT_MAX)
                    cycles_since_jump++;
 
                  enum attr_type type = type_for_anomaly (target);
                  int delay_needed = 0;
                  if (cycles_since_jump < INT_MAX)
                    cycles_since_jump++;
 
-                 if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
+                 if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
+                   {
+                     if (trapping_loads_p (load_insn))
+                       delay_needed = 2;
+                   }
+                 else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
                    delay_needed = 2;
 
                  if (delay_needed > cycles_since_jump)
                    delay_needed = 2;
 
                  if (delay_needed > cycles_since_jump)
index 1388266..bd2d208 100644 (file)
   return "";
 }
   [(set_attr "type" "brcc")
   return "";
 }
   [(set_attr "type" "brcc")
-   (set_attr "length" "6")])
+   (set_attr "length" "8")])
 
 ;; setcc insns.  */
 (define_expand "seq"
 
 ;; setcc insns.  */
 (define_expand "seq"