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:
parent
870ef0cee0
commit
3b45a007ef
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
34
gcc/gimple.h
34
gcc/gimple.h
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)))
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue