gimple.h (gimple_call_addr_fndecl): New function.

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

	* gimple.h (gimple_call_addr_fndecl): New function.
	(gimple_call_fndecl): Use it.
	* gimple-fold.c (gimple_fold_call): Fold away OBJ_TYPE_REFs
	for direct calls.
	* tree-ssa-ccp.c (ccp_fold_stmt): Remove OBJ_TYPE_REF folding.
	* tree-ssa-pre.c (eliminate): Also simplify indirect OBJ_TYPE_REFs.

From-SVN: r172644
This commit is contained in:
Richard Guenther 2011-04-18 11:59:34 +00:00 committed by Richard Biener
parent 870ef0cee0
commit 3b45a007ef
5 changed files with 50 additions and 34 deletions

View File

@ -1,3 +1,12 @@
2011-04-18 Richard Guenther <rguenther@suse.de>
* gimple.h (gimple_call_addr_fndecl): New function.
(gimple_call_fndecl): Use it.
* gimple-fold.c (gimple_fold_call): Fold away OBJ_TYPE_REFs
for direct calls.
* tree-ssa-ccp.c (ccp_fold_stmt): Remove OBJ_TYPE_REF folding.
* tree-ssa-pre.c (eliminate): Also simplify indirect OBJ_TYPE_REFs.
2011-04-18 Richard Guenther <rguenther@suse.de>
PR middle-end/48650

View File

@ -1450,11 +1450,11 @@ bool
gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
{
gimple stmt = gsi_stmt (*gsi);
tree callee = gimple_call_fndecl (stmt);
tree callee;
/* Check for builtins that CCP can handle using information not
available in the generic fold routines. */
callee = gimple_call_fndecl (stmt);
if (!inplace && callee && DECL_BUILT_IN (callee))
{
tree result = gimple_fold_builtin (stmt);
@ -1466,6 +1466,16 @@ gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
return true;
}
}
/* Check for virtual calls that became direct calls. */
callee = gimple_call_fn (stmt);
if (TREE_CODE (callee) == OBJ_TYPE_REF
&& gimple_call_addr_fndecl (OBJ_TYPE_REF_EXPR (callee)) != NULL_TREE)
{
gimple_call_set_fn (stmt, OBJ_TYPE_REF_EXPR (callee));
return true;
}
return false;
}

View File

@ -2065,6 +2065,24 @@ gimple_call_set_fndecl (gimple gs, tree decl)
gimple_set_op (gs, 1, build_fold_addr_expr_loc (gimple_location (gs), decl));
}
/* Given a valid GIMPLE_CALL function address return the FUNCTION_DECL
associated with the callee if known. Otherwise return NULL_TREE. */
static inline tree
gimple_call_addr_fndecl (const_tree fn)
{
if (TREE_CODE (fn) == ADDR_EXPR)
{
tree fndecl = TREE_OPERAND (fn, 0);
if (TREE_CODE (fndecl) == MEM_REF
&& TREE_CODE (TREE_OPERAND (fndecl, 0)) == ADDR_EXPR
&& integer_zerop (TREE_OPERAND (fndecl, 1)))
fndecl = TREE_OPERAND (TREE_OPERAND (fndecl, 0), 0);
if (TREE_CODE (fndecl) == FUNCTION_DECL)
return fndecl;
}
return NULL_TREE;
}
/* If a given GIMPLE_CALL's callee is a FUNCTION_DECL, return it.
Otherwise return NULL. This function is analogous to
@ -2073,21 +2091,7 @@ gimple_call_set_fndecl (gimple gs, tree decl)
static inline tree
gimple_call_fndecl (const_gimple gs)
{
tree addr = gimple_call_fn (gs);
if (TREE_CODE (addr) == ADDR_EXPR)
{
tree fndecl = TREE_OPERAND (addr, 0);
if (TREE_CODE (fndecl) == MEM_REF)
{
if (TREE_CODE (TREE_OPERAND (fndecl, 0)) == ADDR_EXPR
&& integer_zerop (TREE_OPERAND (fndecl, 1)))
return TREE_OPERAND (TREE_OPERAND (fndecl, 0), 0);
else
return NULL_TREE;
}
return TREE_OPERAND (addr, 0);
}
return NULL_TREE;
return gimple_call_addr_fndecl (gimple_call_fn (gs));
}

View File

@ -1702,7 +1702,6 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
tree lhs = gimple_call_lhs (stmt);
tree val;
tree argt;
tree callee;
bool changed = false;
unsigned i;
@ -1743,17 +1742,6 @@ ccp_fold_stmt (gimple_stmt_iterator *gsi)
}
}
callee = gimple_call_fn (stmt);
if (TREE_CODE (callee) == OBJ_TYPE_REF
&& TREE_CODE (OBJ_TYPE_REF_EXPR (callee)) == SSA_NAME)
{
tree expr = OBJ_TYPE_REF_EXPR (callee);
OBJ_TYPE_REF_EXPR (callee) = valueize_op (expr);
if (gimple_fold_call (gsi, false))
changed = true;
OBJ_TYPE_REF_EXPR (callee) = expr;
}
return changed;
}

View File

@ -4380,13 +4380,18 @@ eliminate (void)
}
/* Visit indirect calls and turn them into direct calls if
possible. */
if (is_gimple_call (stmt)
&& TREE_CODE (gimple_call_fn (stmt)) == SSA_NAME)
if (is_gimple_call (stmt))
{
tree orig_fn = gimple_call_fn (stmt);
tree fn = VN_INFO (orig_fn)->valnum;
if (TREE_CODE (fn) == ADDR_EXPR
&& TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL
tree fn;
if (TREE_CODE (orig_fn) == SSA_NAME)
fn = VN_INFO (orig_fn)->valnum;
else if (TREE_CODE (orig_fn) == OBJ_TYPE_REF
&& TREE_CODE (OBJ_TYPE_REF_EXPR (orig_fn)) == SSA_NAME)
fn = VN_INFO (OBJ_TYPE_REF_EXPR (orig_fn))->valnum;
else
continue;
if (gimple_call_addr_fndecl (fn) != NULL_TREE
&& useless_type_conversion_p (TREE_TYPE (orig_fn),
TREE_TYPE (fn)))
{