This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PR middle-end/35535 part II


Hi,
this patch contines on tract of making us to handle OBJ_TYPE_REF in expressions
more gracefully.  The change in gimple_fold_stmt_to_constant_1 makes
it to skip the wrapper, so valuelize functions of passes never see it,
and in addition OBJ_TYPE_REF is stripped once argument becomes constant.

In gimple-fold we also ask type devirtualization machinery for call target the
same way as we do for call statements.  I think this is rather important, since
still we resolve good part of devirtualization only after inlining.  Often we
however manage to produce a speculative edge and we really do not want to keep
the speculation in code after we found real target.

Bootstrapped/regtested x86_64-linux, OK?

Honza

	* gimple-fold.c (fold_gimple_assign): Attempt to devirtualize
	OBJ_TYPE_REF.
	(gimple_fold_stmt_to_constant_1): Bypass OBJ_TYPE_REF wrappers.
Index: gimple-fold.c
===================================================================
--- gimple-fold.c	(revision 206042)
+++ gimple-fold.c	(working copy)
@@ -374,6 +375,30 @@ fold_gimple_assign (gimple_stmt_iterator
 	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 +2550,13 @@ gimple_fold_stmt_to_constant_1 (gimple s
 
 		  return build_vector (TREE_TYPE (rhs), vec);
 		}
+	      if (subcode == OBJ_TYPE_REF)
+		{
+		  tree val = (*valueize) (OBJ_TYPE_REF_EXPR (rhs));
+		  /* If calle is constant, we can fold away the wrapper.  */
+		  if (is_gimple_min_invariant (val))
+		    return val;
+		}
 
               if (kind == tcc_reference)
 		{


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]