aboutsummaryrefslogtreecommitdiff
path: root/gcc/d
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/d')
-rw-r--r--gcc/d/ChangeLog17
-rw-r--r--gcc/d/d-codegen.cc41
-rw-r--r--gcc/d/d-tree.h1
-rw-r--r--gcc/d/expr.cc53
-rw-r--r--gcc/d/toir.cc5
5 files changed, 47 insertions, 70 deletions
diff --git a/gcc/d/ChangeLog b/gcc/d/ChangeLog
index f816c70..b6815d3 100644
--- a/gcc/d/ChangeLog
+++ b/gcc/d/ChangeLog
@@ -1,3 +1,20 @@
+2025-04-29 Iain Buclaw <ibuclaw@gdcproject.org>
+
+ PR d/103044
+ * d-tree.h (build_clear_padding_call): New prototype.
+ * d-codegen.cc (build_clear_padding_call): New function.
+ (build_memset_call): Remove generated call to __builtin_memcpy.
+ (build_address): Replace generated call to __builtin_memset with
+ __builtin_clear_padding.
+ (build_array_from_exprs): Likewise.
+ * expr.cc (ExprVisitor::visit (AssignExp *)): Remove generated call to
+ __builtin_memset.
+ (ExprVisitor::visit (ArrayLiteralExp *)): Likewise. Insert call to
+ __builtin_clear_padding after copying array into GC memory.
+ (ExprVisitor::visit (StructLiteralExp *)): Remove generated call to
+ __builtin_memset.
+ * toir.cc (IRVisitor::visit (ReturnStatement *)): Likewise.
+
2025-04-17 Iain Buclaw <ibuclaw@gdcproject.org>
* dmd/MERGE: Merge upstream dmd 956e73d64e.
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index 1a7575a..e35f75a 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -717,10 +717,11 @@ build_address (tree exp)
if (AGGREGATE_TYPE_P (TREE_TYPE (exp))
&& !aggregate_value_p (TREE_TYPE (exp), exp))
{
- tree tmp = build_local_temp (TREE_TYPE (exp));
- init = compound_expr (init, build_memset_call (tmp));
- init = compound_expr (init, modify_expr (tmp, exp));
- exp = tmp;
+ tree target = force_target_expr (exp);
+ tree ptr = build_address (TARGET_EXPR_SLOT (target));
+ init = compound_expr (init, target);
+ init = compound_expr (init, build_clear_padding_call (ptr));
+ exp = TARGET_EXPR_SLOT (target);
}
else
exp = force_target_expr (exp);
@@ -891,17 +892,13 @@ build_memset_call (tree ptr, tree num)
}
/* Use a zero constant to fill the destination if setting the entire object.
- For CONSTRUCTORs, the memcpy() is lowered to a ref-all pointer assignment,
- which can then be merged with other stores to the object. */
+ For CONSTRUCTORs, also set CONSTRUCTOR_ZERO_PADDING_BITS. */
tree valtype = TREE_TYPE (TREE_TYPE (ptr));
if (tree_int_cst_equal (TYPE_SIZE_UNIT (valtype), num))
{
tree cst = build_zero_cst (valtype);
if (TREE_CODE (cst) == CONSTRUCTOR)
- {
- CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1;
- return build_memcpy_call (ptr, build_address (cst), num);
- }
+ CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1;
return modify_expr (build_deref (ptr), cst);
}
@@ -910,6 +907,18 @@ build_memset_call (tree ptr, tree num)
ptr, integer_zero_node, num);
}
+/* Build a call to built-in clear_padding(), clears padding bits inside of the
+ object representation of object pointed by PTR. */
+
+tree
+build_clear_padding_call (tree ptr)
+{
+ gcc_assert (POINTER_TYPE_P (TREE_TYPE (ptr)));
+
+ return build_call_expr (builtin_decl_explicit (BUILT_IN_CLEAR_PADDING), 1,
+ ptr);
+}
+
/* 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. */
@@ -1893,15 +1902,13 @@ build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
/* Create a new temporary to store the array. */
tree var = build_local_temp (satype);
- /* Fill any alignment holes with zeroes. */
- TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
- tree init = NULL;
- if (ts && (!identity_compare_p (ts->sym) || ts->sym->isUnionDeclaration ()))
- init = build_memset_call (var);
-
/* Initialize the temporary. */
tree assign = modify_expr (var, build_padded_constructor (satype, elms));
- return compound_expr (compound_expr (init, assign), var);
+
+ /* Fill any alignment holes with zeroes. */
+ tree clear_padding = build_clear_padding_call (build_address (var));
+
+ return compound_expr (compound_expr (assign, clear_padding), var);
}
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index ebbbe71..9d576e2 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -568,6 +568,7 @@ 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 tree build_clear_padding_call (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 1c1ecf2..268a176 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -1026,7 +1026,6 @@ public:
if (tb1->ty == TY::Tstruct)
{
tree t1 = build_expr (e->e1);
- tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
StructDeclaration *sd = tb1->isTypeStruct ()->sym;
/* Look for struct = 0. */
@@ -1051,25 +1050,8 @@ public:
else
{
/* Simple struct literal assignment. */
- tree init = NULL_TREE;
-
- /* Fill any alignment holes in the struct using memset. */
- if ((e->op == EXP::construct
- || (e->e2->op == EXP::structLiteral && e->op == EXP::blit))
- && (sd->isUnionDeclaration () || !identity_compare_p (sd)))
- {
- t1 = stabilize_reference (t1);
- init = build_memset_call (t1);
- }
-
- /* Elide generating assignment if init is all zeroes. */
- if (init != NULL_TREE && initializer_zerop (t2))
- this->result_ = compound_expr (init, t1);
- else
- {
- tree result = build_assign (modifycode, t1, t2);
- this->result_ = compound_expr (init, result);
- }
+ tree t2 = convert_for_assignment (e->e2, e->e1->type, true);
+ this->result_ = build_assign (modifycode, t1, t2);
}
return;
@@ -2685,22 +2667,6 @@ public:
if (constant_p && initializer_constant_valid_p (ctor, TREE_TYPE (ctor)))
TREE_STATIC (ctor) = 1;
- /* Use memset to fill any alignment holes in the array. */
- if (!this->constp_ && !this->literalp_)
- {
- TypeStruct *ts = etype->baseElemOf ()->isTypeStruct ();
-
- if (ts != NULL && (!identity_compare_p (ts->sym)
- || ts->sym->isUnionDeclaration ()))
- {
- tree var = build_local_temp (TREE_TYPE (ctor));
- tree init = build_memset_call (var);
- /* Evaluate memset() first, then any saved elements. */
- saved_elems = compound_expr (init, saved_elems);
- ctor = compound_expr (modify_expr (var, ctor), var);
- }
- }
-
this->result_ = compound_expr (saved_elems, d_convert (type, ctor));
}
else if (e->onstack)
@@ -2726,6 +2692,9 @@ public:
tree result = build_memcpy_call (mem, build_address (ctor), size);
+ /* Fill any alignment holes in the array. */
+ result = compound_expr (result, build_clear_padding_call (mem));
+
/* Return the array pointed to by MEM. */
result = compound_expr (result, mem);
@@ -2899,18 +2868,6 @@ public:
tree var = build_deref (e->sym);
ctor = compound_expr (modify_expr (var, ctor), var);
}
- else if (!this->literalp_)
- {
- /* Use memset to fill any alignment holes in the object. */
- if (!identity_compare_p (e->sd) || e->sd->isUnionDeclaration ())
- {
- tree var = build_local_temp (TREE_TYPE (ctor));
- tree init = build_memset_call (var);
- /* Evaluate memset() first, then any saved element constructors. */
- saved_elems = compound_expr (init, saved_elems);
- ctor = compound_expr (modify_expr (var, ctor), var);
- }
- }
this->result_ = compound_expr (saved_elems, ctor);
}
diff --git a/gcc/d/toir.cc b/gcc/d/toir.cc
index 427a662..b70db7a 100644
--- a/gcc/d/toir.cc
+++ b/gcc/d/toir.cc
@@ -1058,13 +1058,8 @@ public:
if (sle != NULL)
{
- StructDeclaration *sd = type->baseElemOf ()->isTypeStruct ()->sym;
sle->sym = build_address (this->func_->shidden);
using_rvo_p = true;
-
- /* Fill any alignment holes in the return slot using memset. */
- if (!identity_compare_p (sd) || sd->isUnionDeclaration ())
- add_stmt (build_memset_call (this->func_->shidden));
}
if (using_rvo_p == true)