summaryrefslogtreecommitdiff
blob: 525262c43f41276379907cddb4b3752d24aec4b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
2002-04-22  Jan Hubicka  <jh@suse.cz>
	
	* loop.c (gen_load_of_final_value): New.
	(loop_givs_rescan, strength_reduce, check_dbra_loop): Use it.
	
--- gcc-3.1-20020515/gcc/loop.c.loop-load-final-value	2002-05-17 00:15:52.000000000 +0200
+++ gcc-3.1-20020515/gcc/loop.c	2002-05-17 00:32:20.000000000 +0200
@@ -354,6 +354,7 @@ static rtx loop_insn_sink_or_swim PARAMS
 static void loop_dump_aux PARAMS ((const struct loop *, FILE *, int));
 static void loop_delete_insns PARAMS ((rtx, rtx));
 static HOST_WIDE_INT remove_constant_addition PARAMS ((rtx *));
+static rtx gen_load_of_final_value PARAMS ((rtx, rtx));
 void debug_ivs PARAMS ((const struct loop *));
 void debug_iv_class PARAMS ((const struct iv_class *));
 void debug_biv PARAMS ((const struct induction *));
@@ -4797,7 +4798,8 @@ loop_givs_rescan (loop, bl, reg_map)
 			       v->mult_val, v->add_val, v->dest_reg);
       else if (v->final_value)
 	loop_insn_sink_or_swim (loop,
-				gen_move_insn (v->dest_reg, v->final_value));
+				gen_load_of_final_value (v->dest_reg,
+							 v->final_value));
 
       if (loop_dump_stream)
 	{
@@ -5154,8 +5156,9 @@ strength_reduce (loop, flags)
 	     value, so we don't need another one.  We can't calculate the
 	     proper final value for such a biv here anyways.  */
 	  if (bl->final_value && ! bl->reversed)
-	      loop_insn_sink_or_swim (loop, gen_move_insn
-				      (bl->biv->dest_reg, bl->final_value));
+	      loop_insn_sink_or_swim (loop,
+				      gen_load_of_final_value (bl->biv->dest_reg,
+							       bl->final_value));
 
 	  if (loop_dump_stream)
 	    fprintf (loop_dump_stream, "Reg %d: biv eliminated\n",
@@ -5164,8 +5167,8 @@ strength_reduce (loop, flags)
       /* See above note wrt final_value.  But since we couldn't eliminate
 	 the biv, we must set the value after the loop instead of before.  */
       else if (bl->final_value && ! bl->reversed)
-	loop_insn_sink (loop, gen_move_insn (bl->biv->dest_reg,
-					     bl->final_value));
+	loop_insn_sink (loop, gen_load_of_final_value (bl->biv->dest_reg,
+						       bl->final_value));
     }
 
   /* Go through all the instructions in the loop, making all the
@@ -8360,7 +8363,7 @@ check_dbra_loop (loop, insn_count)
 	      if ((REGNO_LAST_UID (bl->regno) != INSN_UID (first_compare))
 		  || ! bl->init_insn
 		  || REGNO_FIRST_UID (bl->regno) != INSN_UID (bl->init_insn))
-		loop_insn_sink (loop, gen_move_insn (reg, final_value));
+		loop_insn_sink (loop, gen_load_of_final_value (reg, final_value));
 
 	      /* Delete compare/branch at end of loop.  */
 	      delete_related_insns (PREV_INSN (loop_end));
@@ -10355,6 +10358,21 @@ loop_insn_sink (loop, pattern)
   return loop_insn_emit_before (loop, 0, loop->sink, pattern);
 }
 
+/* bl->final_value can be eighter general_operand or PLUS of general_operand
+   and constant.  Emit sequence of intructions to load it into REG  */
+static rtx
+gen_load_of_final_value (reg, final_value)
+     rtx reg, final_value;
+{
+  rtx seq;
+  start_sequence ();
+  final_value = force_operand (final_value, reg);
+  if (final_value != reg)
+    emit_move_insn (reg, final_value);
+  seq = gen_sequence ();
+  end_sequence ();
+  return seq;
+}
 
 /* If the loop has multiple exits, emit insn for PATTERN before the
    loop to ensure that it will always be executed no matter how the