public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).