public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [c++-delayed-folding] Introduce convert_to_complex_nofold
@ 2015-11-02 15:26 Marek Polacek
  2015-11-02 18:00 ` Jason Merrill
  0 siblings, 1 reply; 2+ messages in thread
From: Marek Polacek @ 2015-11-02 15:26 UTC (permalink / raw)
  To: GCC Patches, Jason Merrill

The following introduces convert_to_complex_nofold, similarly to what
I've done with convert_to_pointer.  Nothing too surprising in the patch,
I suppose.

Now, what remains to do is to also introduce convert_to_real.  Then we
should be done with convert.c as convert_to_vector doesn't fold and
convert_to_fixed isn't used in the C++ FE at all.  More tomorrow.

Bootstrapped/regtested on x86_64-linux, ok for branch?

diff --git gcc/convert.c gcc/convert.c
index ab3eb20..ec6ff37 100644
--- gcc/convert.c
+++ gcc/convert.c
@@ -40,6 +40,9 @@ along with GCC; see the file COPYING3.  If not see
 #define maybe_fold_build1_loc(FOLD_P, LOC, CODE, TYPE, EXPR) \
   ((FOLD_P) ? fold_build1_loc (LOC, CODE, TYPE, EXPR)	     \
    : build1_loc (LOC, CODE, TYPE, EXPR))
+#define maybe_fold_build2_loc(FOLD_P, LOC, CODE, TYPE, EXPR1, EXPR2) \
+  ((FOLD_P) ? fold_build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2)	     \
+   : build2_loc (LOC, CODE, TYPE, EXPR1, EXPR2))
 
 /* Convert EXPR to some pointer or reference type TYPE.
    EXPR must be pointer, reference, integer, enumeral, or literal zero;
@@ -968,11 +971,13 @@ convert_to_integer_nofold (tree type, tree expr)
   return convert_to_integer_1 (type, expr, CONSTANT_CLASS_P (expr));
 }
 
-/* Convert EXPR to the complex type TYPE in the usual ways.  */
+/* Convert EXPR to the complex type TYPE in the usual ways.  If FOLD_P is
+   true, try to fold the expression.  */
 
-tree
-convert_to_complex (tree type, tree expr)
+static tree
+convert_to_complex_1 (tree type, tree expr, bool fold_p)
 {
+  location_t loc = EXPR_LOCATION (expr);
   tree subtype = TREE_TYPE (type);
 
   switch (TREE_CODE (TREE_TYPE (expr)))
@@ -993,43 +998,63 @@ convert_to_complex (tree type, tree expr)
 	  return expr;
 	else if (TREE_CODE (expr) == COMPOUND_EXPR)
 	  {
-	    tree t = convert_to_complex (type, TREE_OPERAND (expr, 1));
+	    tree t = convert_to_complex_1 (type, TREE_OPERAND (expr, 1),
+					   fold_p);
 	    if (t == TREE_OPERAND (expr, 1))
 	      return expr;
 	    return build2_loc (EXPR_LOCATION (expr), COMPOUND_EXPR,
 			       TREE_TYPE (t), TREE_OPERAND (expr, 0), t);
-	  }    
+	  }
 	else if (TREE_CODE (expr) == COMPLEX_EXPR)
-	  return fold_build2 (COMPLEX_EXPR, type,
-			      convert (subtype, TREE_OPERAND (expr, 0)),
-			      convert (subtype, TREE_OPERAND (expr, 1)));
+	  return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
+					convert (subtype,
+						 TREE_OPERAND (expr, 0)),
+					convert (subtype,
+						 TREE_OPERAND (expr, 1)));
 	else
 	  {
 	    expr = save_expr (expr);
-	    return
-	      fold_build2 (COMPLEX_EXPR, type,
-			   convert (subtype,
-				    fold_build1 (REALPART_EXPR,
-						 TREE_TYPE (TREE_TYPE (expr)),
-						 expr)),
-			   convert (subtype,
-				    fold_build1 (IMAGPART_EXPR,
-						 TREE_TYPE (TREE_TYPE (expr)),
-						 expr)));
+	    tree realp = maybe_fold_build1_loc (fold_p, loc, REALPART_EXPR,
+						TREE_TYPE (TREE_TYPE (expr)),
+						expr);
+	    tree imagp = maybe_fold_build1_loc (fold_p, loc, IMAGPART_EXPR,
+						TREE_TYPE (TREE_TYPE (expr)),
+						expr);
+	    return maybe_fold_build2_loc (fold_p, loc, COMPLEX_EXPR, type,
+					  convert (subtype, realp),
+					  convert (subtype, imagp));
 	  }
       }
 
     case POINTER_TYPE:
     case REFERENCE_TYPE:
       error ("pointer value used where a complex was expected");
-      return convert_to_complex (type, integer_zero_node);
+      return convert_to_complex_1 (type, integer_zero_node, fold_p);
 
     default:
       error ("aggregate value used where a complex was expected");
-      return convert_to_complex (type, integer_zero_node);
+      return convert_to_complex_1 (type, integer_zero_node, fold_p);
     }
 }
 
+/* A wrapper around convert_to_complex_1 that always folds the
+   expression.  */
+
+tree
+convert_to_complex (tree type, tree expr)
+{
+  return convert_to_complex_1 (type, expr, true);
+}
+
+/* A wrapper around convert_to_complex_1 that only folds the
+   expression if it is CONSTANT_CLASS_P.  */
+
+tree
+convert_to_complex_nofold (tree type, tree expr)
+{
+  return convert_to_complex_1 (type, expr, CONSTANT_CLASS_P (expr));
+}
+
 /* Convert EXPR to the vector type TYPE in the usual ways.  */
 
 tree
diff --git gcc/convert.h gcc/convert.h
index 24fa6bf..6cb439e 100644
--- gcc/convert.h
+++ gcc/convert.h
@@ -27,6 +27,7 @@ extern tree convert_to_pointer_nofold (tree, tree);
 extern tree convert_to_real (tree, tree);
 extern tree convert_to_fixed (tree, tree);
 extern tree convert_to_complex (tree, tree);
+extern tree convert_to_complex_nofold (tree, tree);
 extern tree convert_to_vector (tree, tree);
 
 #endif /* GCC_CONVERT_H */
diff --git gcc/cp/cvt.c gcc/cp/cvt.c
index 04f6b81..1368f15 100644
--- gcc/cp/cvt.c
+++ gcc/cp/cvt.c
@@ -710,7 +710,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
       /* For complex data types, we need to perform componentwise
 	 conversion.  */
       else if (TREE_CODE (type) == COMPLEX_TYPE)
-	return convert_to_complex (type, e);
+	return convert_to_complex_nofold (type, e);
       else if (VECTOR_TYPE_P (type))
 	return convert_to_vector (type, e);
       else if (TREE_CODE (e) == TARGET_EXPR)
@@ -848,7 +848,7 @@ ocp_convert (tree type, tree expr, int convtype, int flags,
       if (code == REAL_TYPE)
 	return convert_to_real (type, e);
       else if (code == COMPLEX_TYPE)
-	return convert_to_complex (type, e);
+	return convert_to_complex_nofold (type, e);
     }
 
   /* New C++ semantics:  since assignment is now based on

	Marek

^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: [c++-delayed-folding] Introduce convert_to_complex_nofold
  2015-11-02 15:26 [c++-delayed-folding] Introduce convert_to_complex_nofold Marek Polacek
@ 2015-11-02 18:00 ` Jason Merrill
  0 siblings, 0 replies; 2+ messages in thread
From: Jason Merrill @ 2015-11-02 18:00 UTC (permalink / raw)
  To: Marek Polacek, GCC Patches

OK, thanks.

Jason

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2015-11-02 18:00 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-11-02 15:26 [c++-delayed-folding] Introduce convert_to_complex_nofold Marek Polacek
2015-11-02 18:00 ` Jason Merrill

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).