Commit 34ee7f82 by Roger Sayle Committed by Roger Sayle

re PR rtl-optimization/8423 (CSE1 not propagating __builtin_constant_p enough)


	PR optimization/8423
	* cse.c (fold_rtx): Only eliminate a CONSTANT_P_RTX to 1 when
	its argument is constant, or 0 if !flag_gcse.
	* simplify-rtx.c (simplify_rtx): Convert CONSTANT_P_RTX to 1
	if it's argument is constant.
	* gcse.c (want_to_gcse_p): Ignore CONSTANT_P_RTX nodes.
	(hash_scan_set): Don't record CONSTANT_P_RTX expressions.
	(do_local_cprop): Don't propagate CONSTANT_P_RTX constants.
	* builtins.c (purge_builtin_constant_p): New function to force
	instantiation of any remaining CONSTANT_P_RTX nodes.
	* rtl.h (purge_builtin_constant_p): Prototype here.
	* toplev.c (rest_of_compilation): Invoke purge_builtin_constant_p
	pass after GCSE and before loop.
	(flag_gcse): No longer static.
	* flags.h (flag_gcse): Prototype here.

From-SVN: r61642
parent 94edc4ab
2003-01-22 Roger Sayle <roger@eyesopen.com>
PR optimization/8423
* cse.c (fold_rtx): Only eliminate a CONSTANT_P_RTX to 1 when
its argument is constant, or 0 if !flag_gcse.
* simplify-rtx.c (simplify_rtx): Convert CONSTANT_P_RTX to 1
if it's argument is constant.
* gcse.c (want_to_gcse_p): Ignore CONSTANT_P_RTX nodes.
(hash_scan_set): Don't record CONSTANT_P_RTX expressions.
(do_local_cprop): Don't propagate CONSTANT_P_RTX constants.
* builtins.c (purge_builtin_constant_p): New function to force
instantiation of any remaining CONSTANT_P_RTX nodes.
* rtl.h (purge_builtin_constant_p): Prototype here.
* toplev.c (rest_of_compilation): Invoke purge_builtin_constant_p
pass after GCSE and before loop.
(flag_gcse): No longer static.
* flags.h (flag_gcse): Prototype here.
2003-01-22 Ulrich Weigand <uweigand@de.ibm.com> 2003-01-22 Ulrich Weigand <uweigand@de.ibm.com>
* config/s390/s390.h (HARD_REGNO_MODE_OK): Fix warning regression * config/s390/s390.h (HARD_REGNO_MODE_OK): Fix warning regression
......
...@@ -1461,8 +1461,8 @@ expand_builtin_constant_p (exp) ...@@ -1461,8 +1461,8 @@ expand_builtin_constant_p (exp)
arglist = TREE_VALUE (arglist); arglist = TREE_VALUE (arglist);
/* We have taken care of the easy cases during constant folding. This /* We have taken care of the easy cases during constant folding. This
case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE get a case is not obvious, so emit (constant_p_rtx (ARGLIST)) and let CSE
chance to see if it can deduce whether ARGLIST is constant. */ get a chance to see if it can deduce whether ARGLIST is constant. */
tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0); tmp = expand_expr (arglist, NULL_RTX, VOIDmode, 0);
tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp); tmp = gen_rtx_CONSTANT_P_RTX (value_mode, tmp);
...@@ -4496,3 +4496,32 @@ default_expand_builtin (exp, target, subtarget, mode, ignore) ...@@ -4496,3 +4496,32 @@ default_expand_builtin (exp, target, subtarget, mode, ignore)
{ {
return NULL_RTX; return NULL_RTX;
} }
/* Instantiate all remaining CONSTANT_P_RTX nodes. */
void
purge_builtin_constant_p ()
{
rtx insn, done, set;
rtx arg, new, note;
basic_block bb;
FOR_EACH_BB (bb)
{
done = NEXT_INSN (bb->end);
for (insn = bb->head; insn != done; insn = NEXT_INSN (insn))
if (INSN_P (insn)
&& (set = single_set (insn)) != NULL_RTX
&& GET_CODE (SET_SRC (set)) == CONSTANT_P_RTX)
{
arg = XEXP (SET_SRC (set), 0);
new = CONSTANT_P (arg) ? const1_rtx : const0_rtx;
validate_change (insn, &SET_SRC (set), new, 0);
/* Remove the REG_EQUAL note from the insn. */
if ((note = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
remove_note (insn, note);
}
}
}
/* Common subexpression elimination for GNU compiler. /* Common subexpression elimination for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998
1999, 2000, 2001, 2002 Free Software Foundation, Inc. 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -4332,9 +4332,14 @@ fold_rtx (x, insn) ...@@ -4332,9 +4332,14 @@ fold_rtx (x, insn)
break; break;
case 'x': case 'x':
/* Always eliminate CONSTANT_P_RTX at this stage. */ /* Eliminate CONSTANT_P_RTX if its constant. */
if (code == CONSTANT_P_RTX) if (code == CONSTANT_P_RTX)
return (const_arg0 ? const1_rtx : const0_rtx); {
if (const_arg0)
return const1_rtx;
if (!flag_gcse)
return const0_rtx;
}
break; break;
} }
......
...@@ -633,6 +633,10 @@ extern enum graph_dump_types graph_dump_format; ...@@ -633,6 +633,10 @@ extern enum graph_dump_types graph_dump_format;
extern int flag_no_ident; extern int flag_no_ident;
/* Nonzero means perform global CSE. */
extern int flag_gcse;
/* Nonzero if we want to perform enhanced load motion during gcse. */ /* Nonzero if we want to perform enhanced load motion during gcse. */
extern int flag_gcse_lm; extern int flag_gcse_lm;
......
...@@ -1305,6 +1305,7 @@ want_to_gcse_p (x) ...@@ -1305,6 +1305,7 @@ want_to_gcse_p (x)
case CONST_DOUBLE: case CONST_DOUBLE:
case CONST_VECTOR: case CONST_VECTOR:
case CALL: case CALL:
case CONSTANT_P_RTX:
return 0; return 0;
default: default:
...@@ -2216,7 +2217,8 @@ hash_scan_set (pat, insn, table) ...@@ -2216,7 +2217,8 @@ hash_scan_set (pat, insn, table)
&& REGNO (src) >= FIRST_PSEUDO_REGISTER && REGNO (src) >= FIRST_PSEUDO_REGISTER
&& can_copy_p [GET_MODE (dest)] && can_copy_p [GET_MODE (dest)]
&& REGNO (src) != regno) && REGNO (src) != regno)
|| CONSTANT_P (src)) || (CONSTANT_P (src)
&& GET_CODE (src) != CONSTANT_P_RTX))
/* A copy is not available if its src or dest is subsequently /* A copy is not available if its src or dest is subsequently
modified. Here we want to search from INSN+1 on, but modified. Here we want to search from INSN+1 on, but
oprs_available_p searches from INSN on. */ oprs_available_p searches from INSN on. */
...@@ -4277,7 +4279,8 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp) ...@@ -4277,7 +4279,8 @@ do_local_cprop (x, insn, alter_jumps, libcall_sp)
if (l->in_libcall) if (l->in_libcall)
continue; continue;
if (CONSTANT_P (this_rtx)) if (CONSTANT_P (this_rtx)
&& GET_CODE (this_rtx) != CONSTANT_P_RTX)
newcnst = this_rtx; newcnst = this_rtx;
if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER
/* Don't copy propagate if it has attached REG_EQUIV note. /* Don't copy propagate if it has attached REG_EQUIV note.
......
...@@ -1346,6 +1346,7 @@ extern int ceil_log2 PARAMS ((unsigned HOST_WIDE_INT)); ...@@ -1346,6 +1346,7 @@ extern int ceil_log2 PARAMS ((unsigned HOST_WIDE_INT));
/* In builtins.c */ /* In builtins.c */
extern rtx expand_builtin_expect_jump PARAMS ((tree, rtx, rtx)); extern rtx expand_builtin_expect_jump PARAMS ((tree, rtx, rtx));
extern void purge_builtin_constant_p PARAMS ((void));
/* In explow.c */ /* In explow.c */
extern void set_stack_check_libfunc PARAMS ((rtx)); extern void set_stack_check_libfunc PARAMS ((rtx));
......
/* RTL simplification functions for GNU compiler. /* RTL simplification functions for GNU compiler.
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
1999, 2000, 2001, 2002 Free Software Foundation, Inc. 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
This file is part of GCC. This file is part of GCC.
...@@ -2729,11 +2729,15 @@ simplify_rtx (x) ...@@ -2729,11 +2729,15 @@ simplify_rtx (x)
: GET_MODE (XEXP (x, 1))), : GET_MODE (XEXP (x, 1))),
XEXP (x, 0), XEXP (x, 1)); XEXP (x, 0), XEXP (x, 1));
case 'x': case 'x':
/* The only case we try to handle is a SUBREG. */
if (code == SUBREG) if (code == SUBREG)
return simplify_gen_subreg (mode, SUBREG_REG (x), return simplify_gen_subreg (mode, SUBREG_REG (x),
GET_MODE (SUBREG_REG (x)), GET_MODE (SUBREG_REG (x)),
SUBREG_BYTE (x)); SUBREG_BYTE (x));
if (code == CONSTANT_P_RTX)
{
if (CONSTANT_P (XEXP (x,0)))
return const1_rtx;
}
return NULL; return NULL;
default: default:
return NULL; return NULL;
......
...@@ -621,10 +621,6 @@ int flag_volatile_static; ...@@ -621,10 +621,6 @@ int flag_volatile_static;
int flag_syntax_only = 0; int flag_syntax_only = 0;
/* Nonzero means perform global cse. */
static int flag_gcse;
/* Nonzero means perform loop optimizer. */ /* Nonzero means perform loop optimizer. */
static int flag_loop_optimize; static int flag_loop_optimize;
...@@ -646,6 +642,10 @@ static int flag_if_conversion2; ...@@ -646,6 +642,10 @@ static int flag_if_conversion2;
static int flag_delete_null_pointer_checks; static int flag_delete_null_pointer_checks;
/* Nonzero means perform global CSE. */
int flag_gcse = 0;
/* Nonzero means to do the enhanced load motion during gcse, which trys /* Nonzero means to do the enhanced load motion during gcse, which trys
to hoist loads by not killing them when a store to the same location to hoist loads by not killing them when a store to the same location
is seen. */ is seen. */
...@@ -2921,6 +2921,9 @@ rest_of_compilation (decl) ...@@ -2921,6 +2921,9 @@ rest_of_compilation (decl)
#endif #endif
} }
/* Instantiate any remaining CONSTANT_P_RTX nodes. */
purge_builtin_constant_p ();
/* Move constant computations out of loops. */ /* Move constant computations out of loops. */
if (optimize > 0 && flag_loop_optimize) if (optimize > 0 && flag_loop_optimize)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment