optimization/10185: [3.3/3.4 regression] Wrong code with 3-int-structs & optimization
Jan Hubicka
jh@suse.cz
Mon Mar 24 19:09:00 GMT 2003
> The regression appeared with this patch:
>
> Sun Jul 21 00:54:54 CEST 2002 Jan Hubicka <jh@suse.cz>
>
> * gcse.c: Include cselib.h
> (constptop_register): Break out from ...
> (cprop_insn): ... here; kill basic_block argument.
> (do_local_cprop, local_cprop_pass): New functions.
> (one_cprop_pass): Call local_cprop_pass.
>
> My testing used the submitter's test case with -O2 on
> i686-pc-linux-gnu.
As described in the audit, the bug is really latent problem in BIV
discovery code. This patch fixes the reason why gcse now manifest it.
I am now using cselib to discover noop moves and remove them more
aggresivly than delete_trivially_dead_insns can. 15 such noops are
found in combine.c compilation and resulting insn chain is reduced by 7
instructions, so this arrise in real programs too.
Bootstrapped/regtested x86-64. OK?
Mon Mar 24 19:00:35 CET 2003 Jan Hubicka <jh@suse.cz>
* gcse.c (local_cprop_pass): Do not copy propagate noop sets;
attempt to turn set into noop.
* cselib.c (cselib_set_noop_p): New function.
* cselib.h (cselib_set_noop_p): Declare.
Index: gcse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcse.c,v
retrieving revision 1.239
diff -c -3 -p -r1.239 gcse.c
*** gcse.c 8 Mar 2003 09:47:28 -0000 1.239
--- gcse.c 24 Mar 2003 18:12:32 -0000
*************** local_cprop_pass (alter_jumps)
*** 4437,4442 ****
--- 4437,4443 ----
if (INSN_P (insn))
{
rtx note = find_reg_note (insn, REG_LIBCALL, NULL_RTX);
+ rtx set;
if (note)
{
*************** local_cprop_pass (alter_jumps)
*** 4448,4453 ****
--- 4449,4499 ----
if (note)
libcall_sp++;
note = find_reg_equal_equiv_note (insn);
+
+ if (noop_move_p (insn)
+ && !find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ {
+ delete_insn (insn);
+ continue;
+ }
+
+ set = single_set (insn);
+
+ /* Don't do copy propagation on noop moves as it only
+ results in these being in the insn chain longer */
+ if (set && set_noop_p (set))
+ continue;
+ /* Attempt to turn (set A B) where A B are known to be equivalent
+ into (set A A) or (set B B) so the instruction is removed later.
+ */
+ if (set && cselib_set_noop_p (set)
+ && (!SMALL_REGISTER_CLASSES
+ || ((!REG_P (SET_DEST (set))
+ || REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
+ && (GET_CODE (SET_DEST (set)) != SUBREG
+ || (REGNO (SUBREG_REG (SET_DEST (set)))
+ >= FIRST_PSEUDO_REGISTER)))))
+ {
+ bool converted = false;
+
+ if (validate_change (insn, &SET_DEST (set),
+ copy_rtx (SET_SRC (set)), 0))
+ converted = true;
+ else if (validate_change (insn, &SET_SRC (set),
+ copy_rtx (SET_DEST (set)), 0))
+ converted = true;
+ if (converted)
+ {
+ if (gcse_file)
+ fprintf (gcse_file,
+ "LOCAL COPY-PROP: Set in insn %d turned into noop",
+ INSN_UID (insn));
+ if (noop_move_p (insn)
+ && !find_reg_note (insn, REG_LIBCALL, NULL_RTX))
+ delete_insn (insn);
+ continue;
+ }
+ }
do
{
reg_use_count = 0;
Index: cselib.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.c,v
retrieving revision 1.26
diff -c -3 -p -r1.26 cselib.c
*** cselib.c 14 Mar 2003 20:15:11 -0000 1.26
--- cselib.c 24 Mar 2003 18:12:33 -0000
*************** rtx_equal_for_cselib_p (x, y)
*** 541,546 ****
--- 541,570 ----
return 1;
}
+ /* Return nonzero if the destination of SET equals the source
+ and there are no side effects. Use cselib infromation to recognize
+ nontrivial cases. */
+
+ bool
+ cselib_set_noop_p (set)
+ rtx set;
+ {
+ rtx src = SET_SRC (set);
+ rtx dst = SET_DEST (set);
+
+ if (GET_CODE (dst) == STRICT_LOW_PART)
+ dst = XEXP (dst, 0);
+ if ((GET_CODE (dst) == SIGN_EXTRACT
+ || GET_CODE (dst) == ZERO_EXTRACT)
+ && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx)
+ dst = XEXP (dst, 0);
+
+ if (rtx_equal_for_cselib_p (src, dst))
+ return !side_effects_p (src) && !side_effects_p (dst);
+
+ return false;
+ }
+
/* We need to pass down the mode of constants through the hash table
functions. For that purpose, wrap them in a CONST of the appropriate
mode. */
Index: cselib.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cselib.h,v
retrieving revision 1.7
diff -c -3 -p -r1.7 cselib.h
*** cselib.h 11 Mar 2003 21:52:41 -0000 1.7
--- cselib.h 24 Mar 2003 18:12:33 -0000
*************** extern void cselib_update_varray_sizes P
*** 67,72 ****
--- 67,73 ----
extern void cselib_init PARAMS ((void));
extern void cselib_finish PARAMS ((void));
extern void cselib_process_insn PARAMS ((rtx));
+ extern bool cselib_set_noop_p PARAMS ((rtx));
extern int rtx_equal_for_cselib_p PARAMS ((rtx, rtx));
extern int references_value_p PARAMS ((rtx, int));
extern rtx cselib_subst_to_values PARAMS ((rtx));
More information about the Gcc-bugs
mailing list