summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'sys-devel/gcc/files/3.2.1/gcc31-loop-load-final-value.patch')
-rw-r--r--sys-devel/gcc/files/3.2.1/gcc31-loop-load-final-value.patch79
1 files changed, 79 insertions, 0 deletions
diff --git a/sys-devel/gcc/files/3.2.1/gcc31-loop-load-final-value.patch b/sys-devel/gcc/files/3.2.1/gcc31-loop-load-final-value.patch
new file mode 100644
index 0000000..525262c
--- /dev/null
+++ b/sys-devel/gcc/files/3.2.1/gcc31-loop-load-final-value.patch
@@ -0,0 +1,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