From ab0edbcb371cce5f82136f20ad45155c003d4982 Mon Sep 17 00:00:00 2001 From: Iain Buclaw Date: Fri, 17 Jul 2020 17:20:02 +0200 Subject: [PATCH] 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. --- gcc/d/d-codegen.cc | 62 ++++++++++++++++++++++++++++++++++++++---------------- gcc/d/d-tree.h | 3 +++ gcc/d/expr.cc | 44 ++++++++------------------------------ 3 files changed, 56 insertions(+), 53 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); } diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h index d92418a..48c8ef0 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 ac9a282..58d4943 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)); -- 2.7.4