* [PATCH] Better OBJ_TYPE_REF folding
@ 2011-04-18 12:26 Richard Guenther
0 siblings, 0 replies; only message in thread
From: Richard Guenther @ 2011-04-18 12:26 UTC (permalink / raw)
To: gcc-patches
We can fold OBJ_TYPE_REFs to direct calls if the callee is known. Even
easier now that we keep fntypes separately.
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.
Richard.
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.
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h (revision 172640)
--- gcc/gimple.h (working copy)
*************** gimple_call_set_fndecl (gimple gs, tree
*** 2065,2070 ****
--- 2065,2088 ----
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
*************** gimple_call_set_fndecl (gimple gs, tree
*** 2073,2093 ****
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;
}
--- 2091,2097 ----
static inline tree
gimple_call_fndecl (const_gimple gs)
{
! return gimple_call_addr_fndecl (gimple_call_fn (gs));
}
Index: gcc/gimple-fold.c
===================================================================
*** gcc/gimple-fold.c (revision 172640)
--- gcc/gimple-fold.c (working copy)
*************** bool
*** 1450,1460 ****
gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
{
gimple stmt = gsi_stmt (*gsi);
!
! tree callee = gimple_call_fndecl (stmt);
/* Check for builtins that CCP can handle using information not
available in the generic fold routines. */
if (!inplace && callee && DECL_BUILT_IN (callee))
{
tree result = gimple_fold_builtin (stmt);
--- 1450,1460 ----
gimple_fold_call (gimple_stmt_iterator *gsi, bool inplace)
{
gimple stmt = gsi_stmt (*gsi);
! 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);
*************** gimple_fold_call (gimple_stmt_iterator *
*** 1466,1471 ****
--- 1466,1481 ----
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;
}
Index: gcc/tree-ssa-ccp.c
===================================================================
*** gcc/tree-ssa-ccp.c (revision 172640)
--- gcc/tree-ssa-ccp.c (working copy)
*************** ccp_fold_stmt (gimple_stmt_iterator *gsi
*** 1702,1708 ****
tree lhs = gimple_call_lhs (stmt);
tree val;
tree argt;
- tree callee;
bool changed = false;
unsigned i;
--- 1702,1707 ----
*************** ccp_fold_stmt (gimple_stmt_iterator *gsi
*** 1743,1759 ****
}
}
- 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;
}
--- 1742,1747 ----
Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c (revision 172640)
--- gcc/tree-ssa-pre.c (working copy)
*************** eliminate (void)
*** 4380,4392 ****
}
/* Visit indirect calls and turn them into direct calls if
possible. */
! if (is_gimple_call (stmt)
! && TREE_CODE (gimple_call_fn (stmt)) == SSA_NAME)
{
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
&& useless_type_conversion_p (TREE_TYPE (orig_fn),
TREE_TYPE (fn)))
{
--- 4380,4397 ----
}
/* Visit indirect calls and turn them into direct calls if
possible. */
! if (is_gimple_call (stmt))
{
tree orig_fn = gimple_call_fn (stmt);
! 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)))
{
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2011-04-18 11:57 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-18 12:26 [PATCH] Better OBJ_TYPE_REF folding Richard Guenther
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).