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: Generate hardware loops even if last insn is problematic


The hardware loop feature on the Blackfin only works if the last insn in a loop is not a jump, a call, or one of certain other instructions. Rather than disable generation of hardware loops in such cases, it's better to just add a NOP to the loop; it'll still be faster.

This patch cleans up the code dealing with this problem; we'll now generate the extra NOP in more cases. Also, we test not only CALL_P but also check for instructions of TYPE_CALL; there'll be a later patch that introduces more of these.

Committed as 146952.


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 146948)
+++ ChangeLog	(working copy)
@@ -1,3 +1,10 @@
+2009-04-29  Bernd Schmidt  <bernd.schmidt@analog.com>
+	
+	* config/bfin/bfin.c (bfin_optimize_loop): Unify handling of
+	problematic last insns.  Test for TYPE_CALL rather than CALL_P.
+	Remove special case testing for last insn of inner loops. Don't fail if
+	the loop ends with a jump, emit an extra nop instead.
+
 2009-04-29  Richard Guenther  <rguenther@suse.de>
 
 	PR tree-optimization/39941
Index: config/bfin/bfin.c
===================================================================
--- config/bfin/bfin.c	(revision 146929)
+++ config/bfin/bfin.c	(working copy)
@@ -3792,7 +3792,7 @@ bfin_optimize_loop (loop_info loop)
 {
   basic_block bb;
   loop_info inner;
-  rtx insn, init_insn, last_insn, nop_insn;
+  rtx insn, init_insn, last_insn;
   rtx loop_init, start_label, end_label;
   rtx reg_lc0, reg_lc1, reg_lt0, reg_lt1, reg_lb0, reg_lb1;
   rtx iter_reg;
@@ -4003,42 +4003,34 @@ bfin_optimize_loop (loop_info loop)
       goto bad_loop;
     }
 
-  if (JUMP_P (last_insn))
+  if (JUMP_P (last_insn) && !any_condjump_p (last_insn))
     {
-      loop_info inner = (loop_info) bb->aux;
-      if (inner
-	  && inner->outer == loop
-	  && inner->loop_end == last_insn
-	  && inner->depth == 1)
-	/* This jump_insn is the exact loop_end of an inner loop
-	   and to be optimized away. So use the inner's last_insn.  */
-	last_insn = inner->last_insn;
-      else
+      if (dump_file)
+	fprintf (dump_file, ";; loop %d has bad last instruction\n",
+		 loop->loop_no);
+      goto bad_loop;
+    }
+  /* In all other cases, try to replace a bad last insn with a nop.  */
+  else if (JUMP_P (last_insn)
+	   || CALL_P (last_insn)
+	   || get_attr_type (last_insn) == TYPE_SYNC
+	   || get_attr_type (last_insn) == TYPE_CALL
+	   || get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI
+	   || recog_memoized (last_insn) == CODE_FOR_return_internal
+	   || GET_CODE (PATTERN (last_insn)) == ASM_INPUT
+	   || asm_noperands (PATTERN (last_insn)) >= 0)
+    {
+      if (loop->length + 2 > MAX_LOOP_LENGTH)
 	{
 	  if (dump_file)
-	    fprintf (dump_file, ";; loop %d has bad last instruction\n",
-		     loop->loop_no);
+	    fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
 	  goto bad_loop;
 	}
-    }
-  else if (CALL_P (last_insn)
-	   || (GET_CODE (PATTERN (last_insn)) != SEQUENCE
-	       && get_attr_type (last_insn) == TYPE_SYNC)
-	   || recog_memoized (last_insn) == CODE_FOR_return_internal)
-    {
       if (dump_file)
-	fprintf (dump_file, ";; loop %d has bad last instruction\n",
+	fprintf (dump_file, ";; loop %d has bad last insn; replace with nop\n",
 		 loop->loop_no);
-      goto bad_loop;
-    }
 
-  if (GET_CODE (PATTERN (last_insn)) == ASM_INPUT
-      || asm_noperands (PATTERN (last_insn)) >= 0
-      || (GET_CODE (PATTERN (last_insn)) != SEQUENCE
-	  && get_attr_seq_insns (last_insn) == SEQ_INSNS_MULTI))
-    {
-      nop_insn = emit_insn_after (gen_nop (), last_insn);
-      last_insn = nop_insn;
+      last_insn = emit_insn_after (gen_forced_nop (), last_insn);
     }
 
   loop->last_insn = last_insn;
@@ -4169,7 +4161,7 @@ bfin_optimize_loop (loop_info loop)
 	    redirect_edge_succ (e, new_bb);
 	}
     }
-  
+
   delete_insn (loop->loop_end);
   /* Insert the loop end label before the last instruction of the loop.  */
   emit_label_before (loop->end_label, loop->last_insn);

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