aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/d-codegen.cc
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2020-07-17 17:20:02 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2020-07-30 18:01:33 +0200
commitab0edbcb371cce5f82136f20ad45155c003d4982 (patch)
tree2601487ec66c374c0560c25a47ce266cbbd7bc2b /gcc/d/d-codegen.cc
parentdc60d67674dd809fd5d57390e1360436351ae7ae (diff)
downloadgcc-ab0edbcb371cce5f82136f20ad45155c003d4982.zip
gcc-ab0edbcb371cce5f82136f20ad45155c003d4982.tar.gz
gcc-ab0edbcb371cce5f82136f20ad45155c003d4982.tar.bz2
d: Refactor use of built-in memcmp/memcpy/memset into helper functions.
Generating calls to memset, memcpy, and memcmp is frequent enough that it becomes beneficial to put them into their own routine. All parts of the front-end have been updated to call the new helper functions instead of doing it themselves. 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.
Diffstat (limited to 'gcc/d/d-codegen.cc')
-rw-r--r--gcc/d/d-codegen.cc62
1 files changed, 44 insertions, 18 deletions
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index cea4731..a38aa6c 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);
}