cfg merge part 19 - gcse tweek
Jan Hubicka
jh@suse.cz
Mon May 27 05:07:00 GMT 2002
Hi,
this is small patch from cfg-branch. It's purpose is to make gcse to drop
REG_EQUAL note when it GCSEes out the real computation so the local passes
won't lose track of what is going on.
It helps to avoid negative results of my next GCSE patch to switch it
into code hoisting functions (that patch needs liveness that is still
discussed), but anyway this has small positive effect.
Bootstrapped/regtested i386.
Honza
Mon May 27 13:53:16 CEST 2002 Jan Hubicka <jh@suse.cz>
* gcse.c (gcse_emit_move_after): New.
(pre_delete, hoist_store): Use it.
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/gcse.c,v
retrieving revision 1.190
diff -c -3 -p -r1.190 gcse.c
*** gcse.c 23 May 2002 19:23:40 -0000 1.190
--- gcse.c 27 May 2002 11:52:54 -0000
*************** static void store_motion PARAMS ((void)
*** 700,705 ****
--- 700,706 ----
static void free_insn_expr_list_list PARAMS ((rtx *));
static void clear_modify_mem_tables PARAMS ((void));
static void free_modify_mem_tables PARAMS ((void));
+ static rtx gcse_emit_move_after PARAMS ((rtx, rtx, rtx));
/* Entry point for global common subexpression elimination.
F is the first instruction in the function. */
*************** pre_insert_copies ()
*** 4948,4953 ****
--- 4949,4981 ----
}
}
+ /* Emit move from SRC to DEST noting the equivalence with expression computed
+ in INSN. */
+ static rtx
+ gcse_emit_move_after (src, dest, insn)
+ rtx src, dest, insn;
+ {
+ rtx new;
+ rtx set = single_set (insn);
+ rtx note;
+ rtx eqv;
+
+ /* This should never fail since we're creating a reg->reg copy
+ we've verified to be valid. */
+
+ new = emit_insn_after (gen_rtx_SET (VOIDmode, dest, src), insn);
+
+ /* Note the equivalence for local CSE pass. */
+ if ((note = find_reg_equal_equiv_note (insn)))
+ eqv = XEXP (note, 0);
+ else
+ eqv = SET_SRC (set);
+
+ set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (src));
+
+ return new;
+ }
+
/* Delete redundant computations.
Deletion is done by changing the insn to copy the `reaching_reg' of
the expression into the result of the SET. It is left to later passes
*************** pre_delete ()
*** 4991,5011 ****
expr->reaching_reg
= gen_reg_rtx (GET_MODE (SET_DEST (set)));
! /* In theory this should never fail since we're creating
! a reg->reg copy.
!
! However, on the x86 some of the movXX patterns actually
! contain clobbers of scratch regs. This may cause the
! insn created by validate_change to not match any pattern
! and thus cause validate_change to fail. */
! if (validate_change (insn, &SET_SRC (set),
! expr->reaching_reg, 0))
! {
! occr->deleted_p = 1;
! SET_BIT (pre_redundant_insns, INSN_CUID (insn));
! changed = 1;
! gcse_subst_count++;
! }
if (gcse_file)
{
--- 5019,5030 ----
expr->reaching_reg
= gen_reg_rtx (GET_MODE (SET_DEST (set)));
! gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
! delete_insn (insn);
! occr->deleted_p = 1;
! SET_BIT (pre_redundant_insns, INSN_CUID (insn));
! changed = 1;
! gcse_subst_count++;
if (gcse_file)
{
*************** hoist_code ()
*** 5827,5849 ****
expr->reaching_reg
= gen_reg_rtx (GET_MODE (SET_DEST (set)));
! /* In theory this should never fail since we're creating
! a reg->reg copy.
!
! However, on the x86 some of the movXX patterns
! actually contain clobbers of scratch regs. This may
! cause the insn created by validate_change to not
! match any pattern and thus cause validate_change to
! fail. */
! if (validate_change (insn, &SET_SRC (set),
! expr->reaching_reg, 0))
{
! occr->deleted_p = 1;
! if (!insn_inserted_p)
! {
! insert_insn_end_bb (index_map[i], bb, 0);
! insn_inserted_p = 1;
! }
}
}
}
--- 5846,5858 ----
expr->reaching_reg
= gen_reg_rtx (GET_MODE (SET_DEST (set)));
! gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
! delete_insn (insn);
! occr->deleted_p = 1;
! if (!insn_inserted_p)
{
! insert_insn_end_bb (index_map[i], bb, 0);
! insn_inserted_p = 1;
}
}
}
More information about the Gcc-patches
mailing list