This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Blackfin: Workaround fixes


This is a patch to fix a number of bugs in the speculation/sync
workarounds. We could miscount the number of NOPs in certain cases
where multiple consecutive instructions required them. The number of
NOPs needed for loads vs. syncs was swapped. Also, there's no need to
add NOPs after CALL insns.
Furthermore, the only the first pass properly accounted for parallel instructions; in our local 4.1 tree we were using a different RTL representation of these, and the >=4.3 code was not fully converted previously.


Committed, rev 140230.


Bernd -- This footer brought to you by insane German lawmakers. Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368 Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif


Index: ChangeLog
===================================================================
--- ChangeLog	(revision 140229)
+++ ChangeLog	(working copy)
@@ -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.
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 140228)
+++ config/bfin/bfin.c	(working copy)
@@ -4799,6 +4799,7 @@ workaround_speculation (void)
   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;
@@ -4808,6 +4809,7 @@ workaround_speculation (void)
   for (insn = get_insns (); insn; insn = next)
     {
       rtx pat;
+      int delay_needed = 0;
 
       next = find_next_insn_start (insn);
       
@@ -4826,6 +4828,7 @@ workaround_speculation (void)
 	      && ! cbranch_predicted_taken_p (insn))
 	    {
 	      last_condjump = insn;
+	      delay_added = 0;
 	      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);
-	  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))
-		delay_needed = 3;
+		delay_needed = 4;
 	    }
 	  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.  */
-  if (! ENABLE_WA_SPECULATIVE_SYNCS)
-    return;
-
   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 next_tgt;
+
 	  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;
 
+	      next_tgt = find_next_insn_start (target);
+
 	      if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
 		continue;
 
@@ -4904,12 +4918,18 @@ workaround_speculation (void)
 
 	      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++;
 
-		  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)
Index: config/bfin/bfin.md
===================================================================
--- config/bfin/bfin.md	(revision 140228)
+++ config/bfin/bfin.md	(working copy)
@@ -2588,7 +2588,7 @@ (define_insn "cbranch_with_nops"
   return "";
 }
   [(set_attr "type" "brcc")
-   (set_attr "length" "6")])
+   (set_attr "length" "8")])
 
 ;; setcc insns.  */
 (define_expand "seq"

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]