This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] PR31848
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Richard Guenther <rguenther at suse dot de>, Vladimir Makarov <vmakarov at redhat dot com>, Richard Earnshaw <Richard dot Earnshaw at buzzard dot freeserve dot co dot uk>
- Date: Fri, 11 May 2007 00:40:49 +0200
- Subject: [PATCH] PR31848
Hi,
The attached patch should fix PR31848. This is a bug very similar to
the one in the old RTL loop optimizer that was discussed on this list
earlier this week: We managed to move an invariant insn with a REG_EQUAL
note that was only conditionally valid.
In addition to fixing this PR, I took the opportunity to move the jump
bypassing pass after loop2. This has been on my wish list for quite
some time now. In the existing pass schedule we basically run CPROP
twice after PRE: We have CPROP2 in gcse_main, and the jump bypassing
pass, which is CPROP on steroids.
The patch enables jump bypassing at the end of GCSE, which we previously
would not do because this confused the old RTL loop optimizer, which is
gone (whee!).
At the same time, we're badly missing a constant/copy propagation pass
after the new RTL loop optimizers. So I just moved the loop bypassing
pass (which is CPROP on steroids) down.
I've bootstrapped and tested this patch on ia64-linux. The compiler is
2% faster (!) with this patch, and the code we produce at -O2 is smaller
and faster.
I've CC:'ed a few people because I need some help. Can one of you folks
run a SPEC benchmark with this patch, please? I'm interested in compile
times and in SPEC score differences. Thanks in advance! ;-)
Gr.
Steven
* gcse.c (gcse_main): Do jump bypassing in CPROP2.
* passes.c (init_optimization_passes): Move pass_jump_bypass
after loop2.
PR rtl-optimization/31848
* loop-invariant.c (move_invariant_reg): If we move an insn
with a REG_EQUAL note, and that insn is not always executed,
remove the REG_EQUAL note.
Index: gcse.c
===================================================================
--- gcse.c (revision 124576)
+++ gcse.c (working copy)
@@ -789,7 +789,7 @@ gcse_main (rtx f ATTRIBUTE_UNUSED)
alloc_gcse_mem ();
/* This time, go ahead and allow cprop to alter jumps. */
timevar_push (TV_CPROP2);
- one_cprop_pass (pass + 1, true, false);
+ one_cprop_pass (pass + 1, true, true);
timevar_pop (TV_CPROP2);
free_gcse_mem ();
Index: passes.c
===================================================================
--- passes.c (revision 124576)
+++ passes.c (working copy)
@@ -664,7 +664,6 @@ init_optimization_passes (void)
NEXT_PASS (pass_cse);
NEXT_PASS (pass_rtl_fwprop);
NEXT_PASS (pass_gcse);
- NEXT_PASS (pass_jump_bypass);
NEXT_PASS (pass_rtl_ifcvt);
NEXT_PASS (pass_tracer);
/* Perform loop optimizations. It might be better to do them a bit
@@ -682,6 +681,7 @@ init_optimization_passes (void)
*p = NULL;
}
NEXT_PASS (pass_web);
+ NEXT_PASS (pass_jump_bypass);
NEXT_PASS (pass_cse2);
NEXT_PASS (pass_rtl_fwprop_addr);
NEXT_PASS (pass_outof_cfg_layout_mode);
Index: loop-invariant.c
===================================================================
--- loop-invariant.c (revision 124576)
+++ loop-invariant.c (working copy)
@@ -1156,9 +1156,21 @@ move_invariant_reg (struct loop *loop, u
to let emit_move_insn produce a valid instruction stream. */
if (REG_P (dest) && !HARD_REGISTER_P (dest))
{
+ rtx note;
+
emit_insn_after (gen_move_insn (dest, reg), inv->insn);
SET_DEST (set) = reg;
reorder_insns (inv->insn, inv->insn, BB_END (preheader));
+
+ /* If there is a REG_EQUAL note on the insn we just moved, and
+ insn is in a basic block that is not always executed, the note
+ may no longer be valid after we move the insn.
+ Note that uses in REG_EQUAL notes are taken into account in
+ the computation of invariants. Hence it is safe to retain the
+ note even if the note contains register references. */
+ if (! inv->always_executed
+ && (note = find_reg_note (inv->insn, REG_EQUAL, NULL_RTX)))
+ remove_note (inv->insn, note);
}
else
{