]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR middle-end/35545 (tracer pass is run too late)
authorJan Hubicka <hubicka@ucw.cz>
Tue, 17 Dec 2013 23:43:22 +0000 (00:43 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Tue, 17 Dec 2013 23:43:22 +0000 (23:43 +0000)
PR middle-end/35535
* gimple-fold.c (fold_gimple_assign): Attempt to devirtualize
OBJ_TYPE_REF.
(gimple_fold_stmt_to_constant_1): Bypass OBJ_TYPE_REF wrappers.

From-SVN: r206074

gcc/ChangeLog
gcc/gimple-fold.c

index 6ce6a601181f38c3d97de5727cefb2f3158977da..2441b102b87b81b838779d52f9306e2d5c4a5ecc 100644 (file)
@@ -1,3 +1,10 @@
+2013-12-17  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR middle-end/35535
+       * gimple-fold.c (fold_gimple_assign): Attempt to devirtualize
+       OBJ_TYPE_REF.
+       (gimple_fold_stmt_to_constant_1): Bypass OBJ_TYPE_REF wrappers.
+
 2013-12-17  Jan Hubicka  <hubicka@ucw.cz>
 
        PR middle-end/35535
index 767c869a476eb9b76cb3fbbbec25ec3491a01788..3b6fc571c404677dace598eb288156124beb17fe 100644 (file)
@@ -374,6 +374,30 @@ fold_gimple_assign (gimple_stmt_iterator *si)
        if (REFERENCE_CLASS_P (rhs))
          return maybe_fold_reference (rhs, false);
 
+       else if (TREE_CODE (rhs) == OBJ_TYPE_REF)
+         {
+           tree val = OBJ_TYPE_REF_EXPR (rhs);
+           if (is_gimple_min_invariant (val))
+             return val;
+           else if (flag_devirtualize && virtual_method_call_p (val))
+             {
+               bool final;
+               vec <cgraph_node *>targets
+                 = possible_polymorphic_call_targets (val, &final);
+               if (final && targets.length () <= 1)
+                 {
+                   tree fndecl;
+                   if (targets.length () == 1)
+                     fndecl = targets[0]->decl;
+                   else
+                     fndecl = builtin_decl_implicit (BUILT_IN_UNREACHABLE);
+                   val = fold_convert (TREE_TYPE (val), fndecl);
+                   STRIP_USELESS_TYPE_CONVERSION (val);
+                   return val;
+                 }
+             }
+
+         }
        else if (TREE_CODE (rhs) == ADDR_EXPR)
          {
            tree ref = TREE_OPERAND (rhs, 0);
@@ -2525,6 +2549,13 @@ gimple_fold_stmt_to_constant_1 (gimple stmt, tree (*valueize) (tree))
 
                  return build_vector (TREE_TYPE (rhs), vec);
                }
+             if (subcode == OBJ_TYPE_REF)
+               {
+                 tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
+                 /* If callee is constant, we can fold away the wrapper.  */
+                 if (is_gimple_min_invariant (val))
+                   return val;
+               }
 
               if (kind == tcc_reference)
                {