[committed] d: Refactor use of built-in memcmp/memcpy/memset into helper functions.

Message ID 20200730160651.2516448-1-ibuclaw@gdcproject.org
State New
Headers show
Series
  • [committed] d: Refactor use of built-in memcmp/memcpy/memset into helper functions.
Related show

Commit Message

Bill Schmidt via Gcc-patches July 30, 2020, 4:06 p.m.
Hi,

This patch adds three codegen helper functions for generating calls to
memcmp, memcpy and memset.  All parts of the front-end have been updated
to call them instead of doing it themselves.

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

Regards
Iain

---
gcc/d/ChangeLog:

	* d-codegen.cc (build_memcmp_call): New function.
	(build_memcpy_call): New function.
	(build_memset_call): New function.
	(build_float_identity): Call build_memcmp_call.
	(lower_struct_comparison): Likewise.
	(build_struct_comparison): Likewise.
	* d-tree.h (build_memcmp_call): Declare.
	(build_memcpy_call): Declare.
	(build_memset_call): Declare.
	* expr.cc (ExprVisitor::visit (EqualExp *)): Call build_memcmp_call.
	(ExprVisitor::visit (AssignExp *)): Call build_memset_call.
	(ExprVisitor::visit (ArrayLiteralExp *)): Call build_memcpy_call.
	(ExprVisitor::visit (StructLiteralExp *)): Call build_memset_call.
---
 gcc/d/d-codegen.cc | 62 ++++++++++++++++++++++++++++++++--------------
 gcc/d/d-tree.h     |  3 +++
 gcc/d/expr.cc      | 44 +++++++-------------------------
 3 files changed, 56 insertions(+), 53 deletions(-)

-- 
2.25.1

Patch

diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index cea47315d0e..a38aa6c55e0 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -794,6 +794,41 @@  d_mark_read (tree exp)
   return exp;
 }
 
+/* Build a call to memcmp(), compares the first NUM bytes of PTR1 with PTR2.  */
+
+tree
+build_memcmp_call (tree ptr1, tree ptr2, tree num)
+{
+  return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,
+			  ptr1, ptr2, num);
+}
+
+/* Build a call to memcpy(), copies the first NUM bytes of SRC into DST.  */
+
+tree
+build_memcpy_call (tree dst, tree src, tree num)
+{
+  return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCPY), 3,
+			  dst, src, num);
+}
+
+/* Build a call to memset(), fills the first NUM bytes of PTR with zeros.
+   If NUM is NULL, then we expect PTR to be object that requires filling.  */
+
+tree
+build_memset_call (tree ptr, tree num)
+{
+  if (num == NULL_TREE)
+    {
+      gcc_assert (TREE_CODE (ptr) != ADDR_EXPR);
+      num = TYPE_SIZE_UNIT (TREE_TYPE (ptr));
+      ptr = build_address (ptr);
+    }
+
+  return build_call_expr (builtin_decl_explicit (BUILT_IN_MEMSET), 3,
+			  ptr, integer_zero_node, num);
+}
+
 /* Return TRUE if the struct SD is suitable for comparison using memcmp.
    This is because we don't guarantee that padding is zero-initialized for
    a stack variable, so we can't use memcmp to compare struct values.  */
@@ -846,11 +881,9 @@  identity_compare_p (StructDeclaration *sd)
 tree
 build_float_identity (tree_code code, tree t1, tree t2)
 {
-  tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
   tree size = size_int (TYPE_PRECISION (TREE_TYPE (t1)) / BITS_PER_UNIT);
-
-  tree result = build_call_expr (tmemcmp, 3, build_address (t1),
-				 build_address (t2), size);
+  tree result = build_memcmp_call (build_address (t1),
+				   build_address (t2), size);
   return build_boolop (code, result, integer_zero_node);
 }
 
@@ -879,10 +912,8 @@  lower_struct_comparison (tree_code code, StructDeclaration *sd,
   /* Let back-end take care of union comparisons.  */
   if (sd->isUnionDeclaration ())
     {
-      tmemcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP), 3,
-				 build_address (t1), build_address (t2),
-				 size_int (sd->structsize));
-
+      tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
+				   size_int (sd->structsize));
       return build_boolop (code, tmemcmp, integer_zero_node);
     }
 
@@ -943,11 +974,9 @@  lower_struct_comparison (tree_code code, StructDeclaration *sd,
 	  else
 	    {
 	      /* Simple memcmp between types.  */
-	      tcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP),
-				      3, build_address (t1ref),
-				      build_address (t2ref),
-				      TYPE_SIZE_UNIT (stype));
-
+	      tcmp = build_memcmp_call (build_address (t1ref),
+					build_address (t2ref),
+					TYPE_SIZE_UNIT (stype));
 	      tcmp = build_boolop (code, tcmp, integer_zero_node);
 	    }
 	}
@@ -995,11 +1024,8 @@  build_struct_comparison (tree_code code, StructDeclaration *sd,
   else
     {
       /* Do bit compare of structs.  */
-      tree size = size_int (sd->structsize);
-      tree tmemcmp = build_call_expr (builtin_decl_explicit (BUILT_IN_MEMCMP),
-				      3, build_address (t1),
-				      build_address (t2), size);
-
+      tree tmemcmp = build_memcmp_call (build_address (t1), build_address (t2),
+					size_int (sd->structsize));
       result = build_boolop (code, tmemcmp, integer_zero_node);
     }
 
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index d92418a55c9..48c8ef09dd1 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -530,6 +530,9 @@  extern tree build_address (tree);
 extern tree d_mark_addressable (tree);
 extern tree d_mark_used (tree);
 extern tree d_mark_read (tree);
+extern tree build_memcmp_call (tree, tree, tree);
+extern tree build_memcpy_call (tree, tree, tree);
+extern tree build_memset_call (tree, tree = NULL_TREE);
 extern bool identity_compare_p (StructDeclaration *);
 extern tree build_float_identity (tree_code, tree, tree);
 extern tree build_struct_comparison (tree_code, StructDeclaration *,
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index ac9a2820112..58d4943ef2b 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -378,9 +378,8 @@  public:
 		|| identity_compare_p (t1elem->isTypeStruct ()->sym))
 	      {
 		tree size = size_mult_expr (t1len, size_int (t1elem->size ()));
-		tree tmemcmp = builtin_decl_explicit (BUILT_IN_MEMCMP);
 
-		result = build_call_expr (tmemcmp, 3, t1ptr, t2ptr, size);
+		result = build_memcmp_call (t1ptr, t2ptr, size);
 		result = build_boolop (code, result, integer_zero_node);
 	      }
 	    else
@@ -948,12 +947,9 @@  public:
 
 	    if (integer_zerop (t2))
 	      {
-		tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
 		tree size = size_mult_expr (d_array_length (t1),
 					    size_int (etype->size ()));
-
-		result = build_call_expr (tmemset, 3, d_array_ptr (t1),
-					  integer_zero_node, size);
+		result = build_memset_call (d_array_ptr (t1), size);
 	      }
 	    else
 	      result = build_array_set (d_array_ptr (t1),
@@ -970,12 +966,10 @@  public:
 	      {
 		tree t1 = d_save_expr (d_array_convert (e->e1));
 		tree t2 = d_array_convert (e->e2);
-		tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
 		tree size = size_mult_expr (d_array_length (t1),
 					    size_int (etype->size ()));
-
-		tree result = build_call_expr (tmemcpy, 3, d_array_ptr (t1),
-					       d_array_ptr (t2), size);
+		tree result = build_memcpy_call (d_array_ptr (t1),
+						 d_array_ptr (t2), size);
 		this->result_ = compound_expr (result, t1);
 	      }
 	    else if ((postblit || destructor) && e->op != TOKblit)
@@ -1042,9 +1036,7 @@  public:
 	  {
 	    /* Use memset to fill struct.  */
 	    gcc_assert (e->op == TOKblit);
-	    tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
-	    tree result = build_call_expr (tmemset, 3, build_address (t1),
-					   t2, size_int (sd->structsize));
+	    tree result = build_memset_call (t1);
 
 	    /* Maybe set-up hidden pointer to outer scope context.  */
 	    if (sd->isNested ())
@@ -1065,12 +1057,7 @@  public:
 
 	    /* Fill any alignment holes in the struct using memset.  */
 	    if (e->op == TOKconstruct && !identity_compare_p (sd))
-	      {
-		tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
-		init = build_call_expr (tmemset, 3, build_address (t1),
-					integer_zero_node,
-					size_int (sd->structsize));
-	      }
+	      init = build_memset_call (t1);
 
 	    tree result = build_assign (modifycode, t1, t2);
 	    this->result_ = compound_expr (init, result);
@@ -1087,15 +1074,7 @@  public:
 	  {
 	    /* Use memset to fill the array.  */
 	    gcc_assert (e->op == TOKblit);
-
-	    tree t1 = build_expr (e->e1);
-	    tree t2 = convert_for_assignment (build_expr (e->e2),
-					      e->e2->type, e->e1->type);
-	    tree size = size_int (e->e1->type->size ());
-
-	    tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
-	    this->result_ = build_call_expr (tmemset, 3, build_address (t1),
-					     t2, size);
+	    this->result_ = build_memset_call (build_expr (e->e1));
 	    return;
 	  }
 
@@ -2753,12 +2732,10 @@  public:
 	mem = d_save_expr (mem);
 
 	/* Now copy the constructor into memory.  */
-	tree tmemcpy = builtin_decl_explicit (BUILT_IN_MEMCPY);
 	tree size = size_mult_expr (size_int (e->elements->length),
 				    size_int (tb->nextOf ()->size ()));
 
-	tree result = build_call_expr (tmemcpy, 3, mem,
-				       build_address (ctor), size);
+	tree result = build_memcpy_call (mem, build_address (ctor), size);
 
 	/* Return the array pointed to by MEM.  */
 	result = compound_expr (result, mem);
@@ -2935,10 +2912,7 @@  public:
       {
 	/* For unions, use memset to fill holes in the object.  */
 	tree var = build_local_temp (TREE_TYPE (ctor));
-	tree tmemset = builtin_decl_explicit (BUILT_IN_MEMSET);
-	tree init = build_call_expr (tmemset, 3, build_address (var),
-				     size_zero_node,
-				     size_int (e->sd->structsize));
+	tree init = build_memset_call (var);
 
 	init = compound_expr (init, saved_elems);
 	init = compound_expr (init, modify_expr (var, ctor));