This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] fix pr30907, worse code produced when an address is forward propagated
- From: Paolo Bonzini <paolo dot bonzini at lu dot unisi dot ch>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 22 Feb 2007 11:47:56 +0100
- Subject: [PATCH] fix pr30907, worse code produced when an address is forward propagated
fwprop has a mechanism to propagate addresses only after loop
optimization passes. This is because invariant addresses can be hoisted
out of the loop, and in this case it would not be beneficial to put them
back in the loop. It was not needed in CSE because it did not cross
basic block boundaries, while the forward propagation is more global in
nature.
This mechanism is currently enabled only if loop unrolling is done.
However, PR30907 has a testcase where, on dataflow branch, the mechanism
is needed also when loops are not unrolled.
Now, why is this needed only on dataflow branch? It turns out that the
reason is that the df bug detailed in
http://gcc.gnu.org/ml/gcc-patches/2007-02/msg01797.html (and related to
PR30841), on mainline, is preventing fwprop from doing the pessimizing
transformation. Since this bug is fixed on dataflow branch, as of now
the transformation is done only on the branch.
Hence, I propose this patch for mainline rather than for dataflow branch.
Bootstrapped/regtested i686-pc-linux-gnu, ok for mainline?
Paolo
2007-02-22 Paolo Bonzini <bonzini@gnu.org>
PR rtl-optimization/30907
* fwprop.c (forward_propagate_into): Never propagate inside a loop.
(fwprop_init): Always call loop_optimizer_initialize.
(fwprop_done): Always call loop_optimizer_finalize.
(fwprop): We always have loop info now.
(gate_fwprop_addr): Remove.
(pass_fwprop_addr): Use gate_fwprop as gate.
Index: gcc-test-df/peak-gcc-src/gcc/fwprop.c
===================================================================
--- gcc-test-df/peak-gcc-src/gcc/fwprop.c (revision 122189)
+++ gcc-test-df/peak-gcc-src/gcc/fwprop.c (working copy)
@@ -886,10 +887,8 @@ forward_propagate_into (struct df_ref *u
if (DF_REF_IS_ARTIFICIAL (def))
return;
- /* Do not propagate loop invariant definitions inside the loop if
- we are going to unroll. */
- if (current_loops
- && DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father)
+ /* Do not propagate loop invariant definitions inside the loop. */
+ if (DF_REF_BB (def)->loop_father != DF_REF_BB (use)->loop_father)
return;
/* Check if the use is still present in the insn! */
@@ -924,8 +923,7 @@ fwprop_init (void)
loops and be careful about them. But we have to call flow_loops_find
before df_analyze, because flow_loops_find may introduce new jump
insns (sadly) if we are not working in cfglayout mode. */
- if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops))
- loop_optimizer_init (0);
+ loop_optimizer_init (0);
/* Now set up the dataflow problem (we only want use-def chains) and
put the dataflow solver to work. */
@@ -939,8 +937,7 @@ fwprop_init (void)
static void
fwprop_done (void)
{
- if (flag_rerun_cse_after_loop && (flag_unroll_loops || flag_peel_loops))
- loop_optimizer_finalize ();
+ loop_optimizer_finalize ();
free_dominance_info (CDI_DOMINATORS);
cleanup_cfg (0);
@@ -979,8 +976,7 @@ fwprop (void)
{
struct df_ref *use = DF_USES_GET (i);
if (use)
- if (!current_loops
- || DF_REF_TYPE (use) == DF_REF_REG_USE
+ if (DF_REF_TYPE (use) == DF_REF_REG_USE
|| DF_REF_BB (use)->loop_father == NULL)
forward_propagate_into (use);
}
@@ -1007,13 +1003,6 @@ struct tree_opt_pass pass_rtl_fwprop =
0 /* letter */
};
-static bool
-gate_fwprop_addr (void)
-{
- return optimize > 0 && flag_forward_propagate && flag_rerun_cse_after_loop
- && (flag_unroll_loops || flag_peel_loops);
-}
-
static unsigned int
fwprop_addr (void)
{
@@ -1041,7 +1030,7 @@ fwprop_addr (void)
struct tree_opt_pass pass_rtl_fwprop_addr =
{
"fwprop2", /* name */
- gate_fwprop_addr, /* gate */
+ gate_fwprop, /* gate */
fwprop_addr, /* execute */
NULL, /* sub */
NULL, /* next */