Commit f20ca725 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/46076 (constant propagation and compile-time math no…

re PR tree-optimization/46076 (constant propagation and compile-time math no longer happening versus 4.4 and 4.5)

2011-04-12  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/46076
	* gimple.h (struct gimple_statement_call): Add fntype field.
	(gimple_call_fntype): Adjust.
	(gimple_call_set_fntype): New function.
	* gimple.c (gimple_build_call_1): Set the call function type.
	* gimplify.c (gimplify_call_expr): Preserve the function
	type the frontend used for the call.
	(gimplify_modify_expr): Likewise.
	* lto-streamer-in.c (input_gimple_stmt): Input the call stmts
	function type.
	* lto-streamer-out.c (output_gimple_stmt): Output the call stmts
	function type.
	* tree-ssa.c (useless_type_conversion_p): Function pointer
	conversions are useless.

	* gcc.dg/tree-ssa/pr46076.c: Un-XFAIL.

From-SVN: r172310
parent 78a869ec
2011-04-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46076
* gimple.h (struct gimple_statement_call): Add fntype field.
(gimple_call_fntype): Adjust.
(gimple_call_set_fntype): New function.
* gimple.c (gimple_build_call_1): Set the call function type.
* gimplify.c (gimplify_call_expr): Preserve the function
type the frontend used for the call.
(gimplify_modify_expr): Likewise.
* lto-streamer-in.c (input_gimple_stmt): Input the call stmts
function type.
* lto-streamer-out.c (output_gimple_stmt): Output the call stmts
function type.
* tree-ssa.c (useless_type_conversion_p): Function pointer
conversions are useless.
2011-04-12 Martin Jambor <mjambor@suse.cz>
* cgraph.h (cgraph_node): Remove function declaration.
......
......@@ -231,6 +231,7 @@ gimple_build_call_1 (tree fn, unsigned nargs)
if (TREE_CODE (fn) == FUNCTION_DECL)
fn = build_fold_addr_expr (fn);
gimple_set_op (s, 1, fn);
gimple_call_set_fntype (s, TREE_TYPE (TREE_TYPE (fn)));
gimple_call_reset_alias_info (s);
return s;
}
......
......@@ -405,7 +405,10 @@ struct GTY(()) gimple_statement_call
struct pt_solution call_used;
struct pt_solution call_clobbered;
/* [ WORD 13 ]
/* [ WORD 13 ] */
tree fntype;
/* [ WORD 14 ]
Operand vector. NOTE! This must always be the last field
of this structure. In particular, this means that this
structure cannot be embedded inside another one. */
......@@ -2001,22 +2004,33 @@ gimple_call_set_lhs (gimple gs, tree lhs)
}
/* Return the tree node representing the function called by call
statement GS. */
/* Return the function type of the function called by GS. */
static inline tree
gimple_call_fn (const_gimple gs)
gimple_call_fntype (const_gimple gs)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
return gimple_op (gs, 1);
return gs->gimple_call.fntype;
}
/* Return the function type of the function called by GS. */
/* Set the type of the function called by GS to FNTYPE. */
static inline void
gimple_call_set_fntype (gimple gs, tree fntype)
{
GIMPLE_CHECK (gs, GIMPLE_CALL);
gs->gimple_call.fntype = fntype;
}
/* Return the tree node representing the function called by call
statement GS. */
static inline tree
gimple_call_fntype (const_gimple gs)
gimple_call_fn (const_gimple gs)
{
return TREE_TYPE (TREE_TYPE (gimple_call_fn (gs)));
GIMPLE_CHECK (gs, GIMPLE_CALL);
return gimple_op (gs, 1);
}
/* Return a pointer to the tree node representing the function called by call
......
......@@ -2290,7 +2290,7 @@ gimplify_arg (tree *arg_p, gimple_seq *pre_p, location_t call_location)
static enum gimplify_status
gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
{
tree fndecl, parms, p;
tree fndecl, parms, p, fnptrtype;
enum gimplify_status ret;
int i, nargs;
gimple call;
......@@ -2349,6 +2349,9 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
}
}
/* Remember the original function pointer type. */
fnptrtype = TREE_TYPE (CALL_EXPR_FN (*expr_p));
/* There is a sequence point before the call, so any side effects in
the calling expression must occur before the actual call. Force
gimplify_expr to use an internal post queue. */
......@@ -2436,7 +2439,7 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
/* Verify the function result. */
if (want_value && fndecl
&& VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fndecl))))
&& VOID_TYPE_P (TREE_TYPE (TREE_TYPE (fnptrtype))))
{
error_at (loc, "using result of function returning %<void%>");
ret = GS_ERROR;
......@@ -2488,11 +2491,16 @@ gimplify_call_expr (tree *expr_p, gimple_seq *pre_p, bool want_value)
have to do is replicate it as a GIMPLE_CALL tuple. */
gimple_stmt_iterator gsi;
call = gimple_build_call_from_tree (*expr_p);
gimple_call_set_fntype (call, TREE_TYPE (fnptrtype));
gimplify_seq_add_stmt (pre_p, call);
gsi = gsi_last (*pre_p);
fold_stmt (&gsi);
*expr_p = NULL_TREE;
}
else
/* Remember the original function type. */
CALL_EXPR_FN (*expr_p) = build1 (NOP_EXPR, fnptrtype,
CALL_EXPR_FN (*expr_p));
return ret;
}
......@@ -4607,7 +4615,11 @@ gimplify_modify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p,
{
/* Since the RHS is a CALL_EXPR, we need to create a GIMPLE_CALL
instead of a GIMPLE_ASSIGN. */
tree fnptrtype = TREE_TYPE (CALL_EXPR_FN (*from_p));
CALL_EXPR_FN (*from_p) = TREE_OPERAND (CALL_EXPR_FN (*from_p), 0);
STRIP_USELESS_TYPE_CONVERSION (CALL_EXPR_FN (*from_p));
assign = gimple_build_call_from_tree (*from_p);
gimple_call_set_fntype (assign, TREE_TYPE (fnptrtype));
if (!gimple_call_noreturn_p (assign))
gimple_call_set_lhs (assign, *to_p);
}
......
......@@ -1062,6 +1062,8 @@ input_gimple_stmt (struct lto_input_block *ib, struct data_in *data_in,
op = TREE_OPERAND (op, 0);
}
}
if (is_gimple_call (stmt))
gimple_call_set_fntype (stmt, lto_input_tree (ib, data_in));
break;
case GIMPLE_NOP:
......
......@@ -1759,6 +1759,8 @@ output_gimple_stmt (struct output_block *ob, gimple stmt)
}
lto_output_tree_ref (ob, op);
}
if (is_gimple_call (stmt))
lto_output_tree_ref (ob, gimple_call_fntype (stmt));
break;
case GIMPLE_NOP:
......
2011-04-12 Richard Guenther <rguenther@suse.de>
PR tree-optimization/46076
* gcc.dg/tree-ssa/pr46076.c: Un-XFAIL.
2011-04-12 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
PR testsuite/21164
......
/* { dg-do link } */
/* { dg-options "-O2" } */
extern void link_error (void) { /* XFAIL */ }
extern void link_error (void);
typedef unsigned char(*Calculable)(void);
......
......@@ -1239,17 +1239,8 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
&& TYPE_RESTRICT (outer_type))
return false;
/* If the outer type is (void *) or a pointer to an incomplete
record type or a pointer to an unprototyped function,
then the conversion is not necessary. */
if (VOID_TYPE_P (TREE_TYPE (outer_type))
|| ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
&& (TREE_CODE (TREE_TYPE (outer_type))
== TREE_CODE (TREE_TYPE (inner_type)))
&& !prototype_p (TREE_TYPE (outer_type))
&& useless_type_conversion_p (TREE_TYPE (TREE_TYPE (outer_type)),
TREE_TYPE (TREE_TYPE (inner_type)))))
/* If the outer type is (void *), the conversion is not necessary. */
if (VOID_TYPE_P (TREE_TYPE (outer_type)))
return true;
}
......@@ -1305,8 +1296,8 @@ useless_type_conversion_p (tree outer_type, tree inner_type)
/* Do not lose casts to function pointer types. */
if ((TREE_CODE (TREE_TYPE (outer_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (outer_type)) == METHOD_TYPE)
&& !useless_type_conversion_p (TREE_TYPE (outer_type),
TREE_TYPE (inner_type)))
&& !(TREE_CODE (TREE_TYPE (inner_type)) == FUNCTION_TYPE
|| TREE_CODE (TREE_TYPE (inner_type)) == METHOD_TYPE))
return false;
/* We do not care for const qualification of the pointed-to types
......
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