[committed] d: Move private functions out of ExprVisitor into local statics

Iain Buclaw ibuclaw@gdcproject.org
Thu Jul 30 16:06:35 GMT 2020


Hi,

This patch breaks out all private functions from ExprVisitor into free
standing static functions.  None of them need access to the context
pointer of the visitor class.

Bootstrapped and regression tested on x86_64-linux-gnu, and committed to
mainline.

Regards
Iain

---
gcc/d/ChangeLog:

	* expr.cc (needs_postblit): Move out of ExprVisitor as a static
	function.  Update all callers.
	(needs_dtor): Likewise.
	(lvalue_p): Likewise.
	(binary_op): Likewise.
	(binop_assignment): Likewise.
---
 gcc/d/expr.cc | 313 +++++++++++++++++++++++++-------------------------
 1 file changed, 159 insertions(+), 154 deletions(-)

diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 7a209fbe733..ac9a2820112 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -43,181 +43,186 @@ along with GCC; see the file COPYING3.  If not see
 #include "d-tree.h"
 
 
-/* Implements the visitor interface to build the GCC trees of all Expression
-   AST classes emitted from the D Front-end.
-   All visit methods accept one parameter E, which holds the frontend AST
-   of the expression to compile.  They also don't return any value, instead
-   generated code is cached in RESULT_ and returned from the caller.  */
+/* Determine if type T is a struct that has a postblit.  */
 
-class ExprVisitor : public Visitor
+static bool
+needs_postblit (Type *t)
 {
-  using Visitor::visit;
-
-  tree result_;
-  bool constp_;
+  t = t->baseElemOf ();
 
-  /* Determine if type is a struct that has a postblit.  */
-
-  bool needs_postblit (Type *t)
-  {
-    t = t->baseElemOf ();
-
-    if (TypeStruct *ts = t->isTypeStruct ())
-      {
-	if (ts->sym->postblit)
-	  return true;
-      }
+  if (TypeStruct *ts = t->isTypeStruct ())
+    {
+      if (ts->sym->postblit)
+	return true;
+    }
 
-    return false;
-  }
+  return false;
+}
 
-  /* Determine if type is a struct that has a destructor.  */
+/* Determine if type T is a struct that has a destructor.  */
 
-  bool needs_dtor (Type *t)
-  {
-    t = t->baseElemOf ();
+static bool
+needs_dtor (Type *t)
+{
+  t = t->baseElemOf ();
 
-    if (TypeStruct *ts = t->isTypeStruct ())
-      {
-	if (ts->sym->dtor)
-	  return true;
-      }
+  if (TypeStruct *ts = t->isTypeStruct ())
+    {
+      if (ts->sym->dtor)
+	return true;
+    }
 
-    return false;
-  }
+  return false;
+}
 
-  /* Determine if expression is suitable lvalue.  */
+/* Determine if expression E is a suitable lvalue.  */
 
-  bool lvalue_p (Expression *e)
-  {
-    SliceExp *se = e->isSliceExp ();
-    if (se != NULL && se->e1->isLvalue ())
-      return true;
+static bool
+lvalue_p (Expression *e)
+{
+  SliceExp *se = e->isSliceExp ();
+  if (se != NULL && se->e1->isLvalue ())
+    return true;
 
-    CastExp *ce = e->isCastExp ();
-    if (ce != NULL && ce->e1->isLvalue ())
-      return true;
+  CastExp *ce = e->isCastExp ();
+  if (ce != NULL && ce->e1->isLvalue ())
+    return true;
 
-    return (e->op != TOKslice && e->isLvalue ());
-  }
-
-  /* Build an expression of code CODE, data type TYPE, and operands ARG0 and
-     ARG1.  Perform relevant conversions needed for correct code operations.  */
+  return (e->op != TOKslice && e->isLvalue ());
+}
 
-  tree binary_op (tree_code code, tree type, tree arg0, tree arg1)
-  {
-    tree t0 = TREE_TYPE (arg0);
-    tree t1 = TREE_TYPE (arg1);
-    tree ret = NULL_TREE;
+/* Build an expression of code CODE, data type TYPE, and operands ARG0 and
+   ARG1.  Perform relevant conversions needed for correct code operations.  */
 
-    bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
+static tree
+binary_op (tree_code code, tree type, tree arg0, tree arg1)
+{
+  tree t0 = TREE_TYPE (arg0);
+  tree t1 = TREE_TYPE (arg1);
+  tree ret = NULL_TREE;
 
-    /* Deal with float mod expressions immediately.  */
-    if (code == FLOAT_MOD_EXPR)
-      return build_float_modulus (type, arg0, arg1);
+  bool unsignedp = TYPE_UNSIGNED (t0) || TYPE_UNSIGNED (t1);
 
-    if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
-      return build_nop (type, build_offset_op (code, arg0, arg1));
+  /* Deal with float mod expressions immediately.  */
+  if (code == FLOAT_MOD_EXPR)
+    return build_float_modulus (type, arg0, arg1);
 
-    if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
-      return build_nop (type, build_offset_op (code, arg1, arg0));
+  if (POINTER_TYPE_P (t0) && INTEGRAL_TYPE_P (t1))
+    return build_nop (type, build_offset_op (code, arg0, arg1));
 
-    if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
-      {
-	gcc_assert (code == MINUS_EXPR);
-	tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
+  if (INTEGRAL_TYPE_P (t0) && POINTER_TYPE_P (t1))
+    return build_nop (type, build_offset_op (code, arg1, arg0));
 
-	/* POINTER_DIFF_EXPR requires a signed integer type of the same size as
-	   pointers.  If some platform cannot provide that, or has a larger
-	   ptrdiff_type to support differences larger than half the address
-	   space, cast the pointers to some larger integer type and do the
-	   computations in that type.  */
-	if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
-	  ret = fold_build2 (MINUS_EXPR, ptrtype,
-			     d_convert (ptrtype, arg0),
-			     d_convert (ptrtype, arg1));
-	else
-	  ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
-      }
-    else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
-      {
-	tree inttype = (unsignedp)
-	  ? d_unsigned_type (type) : d_signed_type (type);
-	ret = fold_build2 (code, inttype, arg0, arg1);
-      }
-    else
-      {
-	/* If the operation needs excess precision.  */
-	tree eptype = excess_precision_type (type);
-	if (eptype != NULL_TREE)
-	  {
-	    arg0 = d_convert (eptype, arg0);
-	    arg1 = d_convert (eptype, arg1);
-	  }
-	else
-	  {
-	    /* Front-end does not do this conversion and GCC does not
-	       always do it right.  */
-	    if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
-	      arg1 = d_convert (t0, arg1);
-	    else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
-	      arg0 = d_convert (t1, arg0);
+  if (POINTER_TYPE_P (t0) && POINTER_TYPE_P (t1))
+    {
+      gcc_assert (code == MINUS_EXPR);
+      tree ptrtype = lang_hooks.types.type_for_mode (ptr_mode, 0);
+
+      /* POINTER_DIFF_EXPR requires a signed integer type of the same size as
+	 pointers.  If some platform cannot provide that, or has a larger
+	 ptrdiff_type to support differences larger than half the address
+	 space, cast the pointers to some larger integer type and do the
+	 computations in that type.  */
+      if (TYPE_PRECISION (ptrtype) > TYPE_PRECISION (t0))
+	ret = fold_build2 (MINUS_EXPR, ptrtype,
+			   d_convert (ptrtype, arg0),
+			   d_convert (ptrtype, arg1));
+      else
+	ret = fold_build2 (POINTER_DIFF_EXPR, ptrtype, arg0, arg1);
+    }
+  else if (INTEGRAL_TYPE_P (type) && (TYPE_UNSIGNED (type) != unsignedp))
+    {
+      tree inttype = (unsignedp)
+	? d_unsigned_type (type) : d_signed_type (type);
+      ret = fold_build2 (code, inttype, arg0, arg1);
+    }
+  else
+    {
+      /* If the operation needs excess precision.  */
+      tree eptype = excess_precision_type (type);
+      if (eptype != NULL_TREE)
+	{
+	  arg0 = d_convert (eptype, arg0);
+	  arg1 = d_convert (eptype, arg1);
+	}
+      else
+	{
+	  /* Front-end does not do this conversion and GCC does not
+	     always do it right.  */
+	  if (COMPLEX_FLOAT_TYPE_P (t0) && !COMPLEX_FLOAT_TYPE_P (t1))
+	    arg1 = d_convert (t0, arg1);
+	  else if (COMPLEX_FLOAT_TYPE_P (t1) && !COMPLEX_FLOAT_TYPE_P (t0))
+	    arg0 = d_convert (t1, arg0);
+
+	  eptype = type;
+	}
+
+      ret = fold_build2 (code, eptype, arg0, arg1);
+    }
 
-	    eptype = type;
-	  }
+  return d_convert (type, ret);
+}
 
-	ret = fold_build2 (code, eptype, arg0, arg1);
-      }
+/* Build a binary expression of code CODE, assigning the result into E1.  */
 
-    return d_convert (type, ret);
-  }
+static tree
+binop_assignment (tree_code code, Expression *e1, Expression *e2)
+{
+  /* Skip casts for lhs assignment.  */
+  Expression *e1b = e1;
+  while (e1b->op == TOKcast)
+    {
+      CastExp *ce = e1b->isCastExp ();
+      gcc_assert (same_type_p (ce->type, ce->to));
+      e1b = ce->e1;
+    }
 
-  /* Build a binary expression of code CODE, assigning the result into E1.  */
+  /* Stabilize LHS for assignment.  */
+  tree lhs = build_expr (e1b);
+  tree lexpr = stabilize_expr (&lhs);
 
-  tree binop_assignment (tree_code code, Expression *e1, Expression *e2)
-  {
-    /* Skip casts for lhs assignment.  */
-    Expression *e1b = e1;
-    while (e1b->op == TOKcast)
-      {
-	CastExp *ce = e1b->isCastExp ();
-	gcc_assert (same_type_p (ce->type, ce->to));
-	e1b = ce->e1;
-      }
+  /* The LHS expression could be an assignment, to which its operation gets
+     lost during gimplification.  */
+  if (TREE_CODE (lhs) == MODIFY_EXPR)
+    {
+      /* If LHS has side effects, call stabilize_reference on it, so it can
+	 be evaluated multiple times.  */
+      if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
+	lhs = build_assign (MODIFY_EXPR,
+			    stabilize_reference (TREE_OPERAND (lhs, 0)),
+			    TREE_OPERAND (lhs, 1));
+
+      lexpr = compound_expr (lexpr, lhs);
+      lhs = TREE_OPERAND (lhs, 0);
+    }
 
-    /* Stabilize LHS for assignment.  */
-    tree lhs = build_expr (e1b);
-    tree lexpr = stabilize_expr (&lhs);
+  lhs = stabilize_reference (lhs);
 
-    /* The LHS expression could be an assignment, to which its operation gets
-       lost during gimplification.  */
-    if (TREE_CODE (lhs) == MODIFY_EXPR)
-      {
-	/* If LHS has side effects, call stabilize_reference on it, so it can
-	   be evaluated multiple times.  */
-	if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0)))
-	  lhs = build_assign (MODIFY_EXPR,
-			      stabilize_reference (TREE_OPERAND (lhs, 0)),
-			      TREE_OPERAND (lhs, 1));
+  /* Save RHS, to ensure that the expression is evaluated before LHS.  */
+  tree rhs = build_expr (e2);
+  tree rexpr = d_save_expr (rhs);
 
-	lexpr = compound_expr (lexpr, lhs);
-	lhs = TREE_OPERAND (lhs, 0);
-      }
+  rhs = binary_op (code, build_ctype (e1->type),
+		   convert_expr (lhs, e1b->type, e1->type), rexpr);
+  if (TREE_SIDE_EFFECTS (rhs))
+    rhs = compound_expr (rexpr, rhs);
 
-    lhs = stabilize_reference (lhs);
+  tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
+  return compound_expr (lexpr, expr);
+}
 
-    /* Save RHS, to ensure that the expression is evaluated before LHS.  */
-    tree rhs = build_expr (e2);
-    tree rexpr = d_save_expr (rhs);
+/* Implements the visitor interface to build the GCC trees of all Expression
+   AST classes emitted from the D Front-end.
+   All visit methods accept one parameter E, which holds the frontend AST
+   of the expression to compile.  They also don't return any value, instead
+   generated code is cached in RESULT_ and returned from the caller.  */
 
-    rhs = this->binary_op (code, build_ctype (e1->type),
-			   convert_expr (lhs, e1b->type, e1->type), rexpr);
-    if (TREE_SIDE_EFFECTS (rhs))
-      rhs = compound_expr (rexpr, rhs);
+class ExprVisitor : public Visitor
+{
+  using Visitor::visit;
 
-    tree expr = modify_expr (lhs, convert_expr (rhs, e1->type, e1b->type));
-    return compound_expr (lexpr, expr);
-  }
+  tree result_;
+  bool constp_;
 
 public:
   ExprVisitor (bool constp)
@@ -653,8 +658,8 @@ public:
 	gcc_unreachable ();
       }
 
-    this->result_ = this->binary_op (code, build_ctype (e->type),
-				     build_expr (e->e1), build_expr (e->e2));
+    this->result_ = binary_op (code, build_ctype (e->type),
+			       build_expr (e->e1), build_expr (e->e2));
   }
 
 
@@ -807,7 +812,7 @@ public:
 	gcc_unreachable ();
       }
 
-    tree exp = this->binop_assignment (code, e1b, e->e2);
+    tree exp = binop_assignment (code, e1b, e->e2);
     this->result_ = convert_expr (exp, e1b->type, e->type);
   }
 
@@ -915,8 +920,8 @@ public:
 	Type *etype = stype->nextOf ()->toBasetype ();
 
 	/* Determine if we need to run postblit or dtor.  */
-	bool postblit = this->needs_postblit (etype) && this->lvalue_p (e->e2);
-	bool destructor = this->needs_dtor (etype);
+	bool postblit = needs_postblit (etype) && lvalue_p (e->e2);
+	bool destructor = needs_dtor (etype);
 
 	if (e->memset & blockAssign)
 	  {
@@ -1098,15 +1103,15 @@ public:
 	gcc_assert (e->e2->type->toBasetype ()->ty == Tsarray);
 
 	/* Determine if we need to run postblit.  */
-	bool postblit = this->needs_postblit (etype);
-	bool destructor = this->needs_dtor (etype);
-	bool lvalue_p = this->lvalue_p (e->e2);
+	bool postblit = needs_postblit (etype);
+	bool destructor = needs_dtor (etype);
+	bool lvalue = lvalue_p (e->e2);
 
 	/* Even if the elements in rhs are all rvalues and don't have
 	   to call postblits, this assignment should call dtors on old
 	   assigned elements.  */
 	if ((!postblit && !destructor)
-	    || (e->op == TOKconstruct && !lvalue_p && postblit)
+	    || (e->op == TOKconstruct && !lvalue && postblit)
 	    || (e->op == TOKblit || e->e1->type->size () == 0))
 	  {
 	    tree t1 = build_expr (e->e1);
@@ -1132,7 +1137,7 @@ public:
 	  {
 	    /* Generate: _d_arrayassign_l()
 		     or: _d_arrayassign_r()  */
-	    libcall_fn libcall = (lvalue_p)
+	    libcall_fn libcall = (lvalue)
 	      ? LIBCALL_ARRAYASSIGN_L : LIBCALL_ARRAYASSIGN_R;
 	    tree elembuf = build_local_temp (build_ctype (etype));
 
-- 
2.25.1



More information about the Gcc-patches mailing list