gimple.h (gimple_call_addr_fndecl): New function.
authorRichard Guenther <rguenther@suse.de>
Mon, 18 Apr 2011 11:59:34 +0000 (11:59 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Mon, 18 Apr 2011 11:59:34 +0000 (11:59 +0000)
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

gcc/ChangeLog
gcc/gimple-fold.c
gcc/gimple.h
gcc/tree-ssa-ccp.c
gcc/tree-ssa-pre.c

index e2c4a019d077134fcc724a747e06cb3c2d01cc1a..49c04815325a0218635bdd0884cbfef9ec14c1c2 100644 (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
index f629fd565a171a580636c522426a36f683d8bb63..9047f670e7d292dd1735b5708d9e95213903dbe4 100644 (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;
 }
 
index 788ffe6d487726d9ba316fd6621d519b37b8d126..3146b70cb125bd7062ee35953f7111229eff397d 100644 (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));
 }
 
 
index 4775a2a567f5cf41eff7b88ff5499b3de3f23f18..3aa2773ad8f0d65320caa4285a8ecd3ac7363a76 100644 (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;
       }
 
index e59a598348b580bb91e2648230bacc18c16fd9ed..df2a13867d1f5da397cd02f87631b70c1d7a6b68 100644 (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)))
                {