aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2025-04-09 14:49:14 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2025-04-09 14:49:14 +0200
commit3e3b665cc77791f2e088aeee124d8a9fb7f6eb41 (patch)
treee6d42f3c47aa4a897e5c4232564b94a8d3b123ea
parent24d1832e0d6edce4f6f717135fcec65d6939e199 (diff)
downloadgcc-3e3b665cc77791f2e088aeee124d8a9fb7f6eb41.zip
gcc-3e3b665cc77791f2e088aeee124d8a9fb7f6eb41.tar.gz
gcc-3e3b665cc77791f2e088aeee124d8a9fb7f6eb41.tar.bz2
d: Use CONSTRUCTOR_ZERO_PADDING_BITS in the D FE [PR117832]
Adds a new wrapper function for `build_constructor', and calls it instead to ensure that all CONSTRUCTOR nodes explicitly created by the front-end have CONSTRUCTOR_ZERO_PADDING_BITS set. Some places may not be necessary as it's guaranteed for there to be no padding in the type, such as D dynamic arrays. Other places this gets turned into a double-memset when optimizations are turned off, as the front-end already generates a memset call to zero out all padding on initializing a variable. The optimizer sees through this so will correctly clear all bits once, so this can be improved later as-needed. PR d/117832 gcc/d/ChangeLog: * d-tree.h (build_padded_constructor): New prototype. * d-codegen.cc (build_padded_constructor): New function. (d_array_value): Call it. (build_memset_call): Likewise. (build_struct_literal): Likewise. (underlying_complex_expr): Likewise. (build_array_from_val): Likewise. (build_array_from_exprs): Likewise. (d_build_call): Likewise. (get_frame_for_symbol): Likewise. * d-convert.cc (convert_for_rvalue): Likewise. (convert_for_assignment): Likewise. * decl.cc (class DeclVisitor): Likewise. * expr.cc (class ExprVisitor): Likewise. * modules.cc (layout_moduleinfo): Likewise. * typeinfo.cc (class TypeInfoVisitor): Likewise.
-rw-r--r--gcc/d/d-codegen.cc32
-rw-r--r--gcc/d/d-convert.cc4
-rw-r--r--gcc/d/d-tree.h1
-rw-r--r--gcc/d/decl.cc2
-rw-r--r--gcc/d/expr.cc22
-rw-r--r--gcc/d/modules.cc4
-rw-r--r--gcc/d/typeinfo.cc8
7 files changed, 45 insertions, 28 deletions
diff --git a/gcc/d/d-codegen.cc b/gcc/d/d-codegen.cc
index ad71486..1a7575a 100644
--- a/gcc/d/d-codegen.cc
+++ b/gcc/d/d-codegen.cc
@@ -317,7 +317,7 @@ d_array_value (tree type, tree len, tree data)
CONSTRUCTOR_APPEND_ELT (ce, len_field, len);
CONSTRUCTOR_APPEND_ELT (ce, ptr_field, data);
- return build_constructor (type, ce);
+ return build_padded_constructor (type, ce);
}
/* Returns value representing the array length of expression EXP.
@@ -898,7 +898,10 @@ build_memset_call (tree ptr, tree num)
{
tree cst = build_zero_cst (valtype);
if (TREE_CODE (cst) == CONSTRUCTOR)
- return build_memcpy_call (ptr, build_address (cst), num);
+ {
+ CONSTRUCTOR_ZERO_PADDING_BITS (cst) = 1;
+ return build_memcpy_call (ptr, build_address (cst), num);
+ }
return modify_expr (build_deref (ptr), cst);
}
@@ -1205,7 +1208,7 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
{
/* If the initializer was empty, use default zero initialization. */
if (vec_safe_is_empty (init))
- return build_constructor (type, NULL);
+ return build_padded_constructor (type, NULL);
/* Struct literals can be seen for special enums representing `_Complex',
make sure to reinterpret the literal as the correct type. */
@@ -1306,7 +1309,7 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
/* Ensure that we have consumed all values. */
gcc_assert (vec_safe_is_empty (init) || ANON_AGGR_TYPE_P (type));
- tree ctor = build_constructor (type, ve);
+ tree ctor = build_padded_constructor (type, ve);
if (constant_p)
TREE_CONSTANT (ctor) = 1;
@@ -1314,6 +1317,17 @@ build_struct_literal (tree type, vec <constructor_elt, va_gc> *init)
return ctor;
}
+/* Return a new zero padded CONSTRUCTOR node whose type is TYPE and values are
+ in the vec pointed to by VALS. */
+
+tree
+build_padded_constructor (tree type, vec<constructor_elt, va_gc> *vals)
+{
+ tree ctor = build_constructor (type, vals);
+ CONSTRUCTOR_ZERO_PADDING_BITS (ctor) = 1;
+ return ctor;
+}
+
/* Given the TYPE of an anonymous field inside T, return the
FIELD_DECL for the field. If not found return NULL_TREE.
Because anonymous types can nest, we must also search all
@@ -1647,7 +1661,7 @@ underlying_complex_expr (tree type, tree expr)
real_part (expr));
CONSTRUCTOR_APPEND_ELT (ve, TREE_CHAIN (TYPE_FIELDS (type)),
imaginary_part (expr));
- return build_constructor (type, ve);
+ return build_padded_constructor (type, ve);
}
/* Replace type in the reinterpret cast with a cast to the record type. */
@@ -1852,7 +1866,7 @@ build_array_from_val (Type *type, tree val)
for (size_t i = 0; i < dims; i++)
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), val);
- return build_constructor (build_ctype (type), elms);
+ return build_padded_constructor (build_ctype (type), elms);
}
/* Build a static array of type TYPE from an array of EXPS.
@@ -1886,7 +1900,7 @@ build_array_from_exprs (Type *type, Expressions *exps, bool const_p)
init = build_memset_call (var);
/* Initialize the temporary. */
- tree assign = modify_expr (var, build_constructor (satype, elms));
+ tree assign = modify_expr (var, build_padded_constructor (satype, elms));
return compound_expr (compound_expr (init, assign), var);
}
@@ -2301,7 +2315,7 @@ d_build_call (TypeFunction *tf, tree callable, tree object,
if (empty_aggregate_p (TREE_TYPE (targ)) && !TREE_ADDRESSABLE (targ)
&& TREE_CODE (targ) != CONSTRUCTOR)
{
- tree t = build_constructor (TREE_TYPE (targ), NULL);
+ tree t = build_padded_constructor (TREE_TYPE (targ), NULL);
targ = build2 (COMPOUND_EXPR, TREE_TYPE (t), targ, t);
}
@@ -2613,7 +2627,7 @@ get_frame_for_symbol (Dsymbol *sym)
framefields = DECL_CHAIN (framefields);
}
- frame_ref = build_address (build_constructor (type, ve));
+ frame_ref = build_address (build_padded_constructor (type, ve));
}
}
diff --git a/gcc/d/d-convert.cc b/gcc/d/d-convert.cc
index 4b19584..c5b0d65 100644
--- a/gcc/d/d-convert.cc
+++ b/gcc/d/d-convert.cc
@@ -688,7 +688,7 @@ convert_for_rvalue (tree expr, Type *etype, Type *totype)
CONSTRUCTOR_APPEND_ELT (elms, index, value);
}
- return build_constructor (build_ctype (totype), elms);
+ return build_padded_constructor (build_ctype (totype), elms);
}
}
@@ -788,7 +788,7 @@ convert_for_assignment (Expression *expr, Type *totype, bool literalp)
TypeSArray *sa_type = tbtype->isTypeSArray ();
uinteger_t count = sa_type->dim->toUInteger ();
- tree ctor = build_constructor (build_ctype (totype), NULL);
+ tree ctor = build_padded_constructor (build_ctype (totype), NULL);
if (count)
{
vec <constructor_elt, va_gc> *ce = NULL;
diff --git a/gcc/d/d-tree.h b/gcc/d/d-tree.h
index 42d01e4..ebbbe71 100644
--- a/gcc/d/d-tree.h
+++ b/gcc/d/d-tree.h
@@ -575,6 +575,7 @@ extern tree build_struct_comparison (tree_code, StructDeclaration *,
extern tree build_array_struct_comparison (tree_code, StructDeclaration *,
tree, tree, tree);
extern tree build_struct_literal (tree, vec <constructor_elt, va_gc> *);
+extern tree build_padded_constructor (tree, vec <constructor_elt, va_gc> *);
extern tree component_ref (tree, tree);
extern tree build_assign (tree_code, tree, tree);
extern tree modify_expr (tree, tree);
diff --git a/gcc/d/decl.cc b/gcc/d/decl.cc
index 250d148..136f78b 100644
--- a/gcc/d/decl.cc
+++ b/gcc/d/decl.cc
@@ -651,7 +651,7 @@ public:
}
DECL_INITIAL (vtblsym->csym)
- = build_constructor (TREE_TYPE (vtblsym->csym), elms);
+ = build_padded_constructor (TREE_TYPE (vtblsym->csym), elms);
d_finish_decl (vtblsym->csym);
d->semanticRun (PASS::obj);
diff --git a/gcc/d/expr.cc b/gcc/d/expr.cc
index 46e6514..1c1ecf2 100644
--- a/gcc/d/expr.cc
+++ b/gcc/d/expr.cc
@@ -2457,7 +2457,7 @@ public:
CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
result = build_nop (build_ctype (e->type),
- build_constructor (aatype, ce));
+ build_padded_constructor (aatype, ce));
}
else
gcc_unreachable ();
@@ -2530,7 +2530,7 @@ public:
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
}
- tree ctor = build_constructor (type, elms);
+ tree ctor = build_padded_constructor (type, elms);
TREE_CONSTANT (ctor) = 1;
this->result_ = ctor;
return;
@@ -2612,8 +2612,10 @@ public:
this->result_ = d_array_value (build_ctype (e->type),
size_int (0), null_pointer_node);
else
- this->result_ = build_constructor (make_array_type (tb->nextOf (), 0),
- NULL);
+ {
+ tree arrtype = make_array_type (tb->nextOf (), 0);
+ this->result_ = build_padded_constructor (arrtype, NULL);
+ }
return;
}
@@ -2654,7 +2656,7 @@ public:
/* Now return the constructor as the correct type. For static arrays there
is nothing else to do. For dynamic arrays, return a two field struct.
For pointers, return the address. */
- tree ctor = build_constructor (satype, elms);
+ tree ctor = build_padded_constructor (satype, elms);
tree type = build_ctype (e->type);
/* Nothing else to do for static arrays. */
@@ -2755,7 +2757,7 @@ public:
TypeAArray *ta = tb->isTypeAArray ();
if (e->keys->length == 0)
{
- this->result_ = build_constructor (build_ctype (ta), NULL);
+ this->result_ = build_padded_constructor (build_ctype (ta), NULL);
return;
}
@@ -2787,7 +2789,7 @@ public:
CONSTRUCTOR_APPEND_ELT (ce, TYPE_FIELDS (aatype), mem);
tree result = build_nop (build_ctype (e->type),
- build_constructor (aatype, ce));
+ build_padded_constructor (aatype, ce));
this->result_ = compound_expr (init, result);
}
@@ -2798,7 +2800,7 @@ public:
/* Handle empty struct literals. */
if (e->elements == NULL || e->sd->fields.length == 0)
{
- this->result_ = build_constructor (build_ctype (e->type), NULL);
+ this->result_ = build_padded_constructor (build_ctype (e->type), NULL);
return;
}
@@ -2849,7 +2851,7 @@ public:
elem = d_save_expr (elem);
if (initializer_zerop (elem))
- value = build_constructor (build_ctype (ftype), NULL);
+ value = build_padded_constructor (build_ctype (ftype), NULL);
else
value = build_array_from_val (ftype, elem);
}
@@ -2948,7 +2950,7 @@ public:
if (constant_p)
this->result_ = build_vector_from_ctor (type, elms);
else
- this->result_ = build_constructor (type, elms);
+ this->result_ = build_padded_constructor (type, elms);
}
else if (e->e1->type->toBasetype ()->ty == TY::Tsarray)
{
diff --git a/gcc/d/modules.cc b/gcc/d/modules.cc
index 471ac43..813d94b 100644
--- a/gcc/d/modules.cc
+++ b/gcc/d/modules.cc
@@ -667,7 +667,7 @@ layout_moduleinfo (Module *decl)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aimports_dim));
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
- build_constructor (satype, elms));
+ build_padded_constructor (satype, elms));
}
if (flags & MIlocalClasses)
@@ -684,7 +684,7 @@ layout_moduleinfo (Module *decl)
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE, size_int (aclasses.length));
CONSTRUCTOR_APPEND_ELT (minit, NULL_TREE,
- build_constructor (satype, elms));
+ build_padded_constructor (satype, elms));
}
if (flags & MIname)
diff --git a/gcc/d/typeinfo.cc b/gcc/d/typeinfo.cc
index e81b2f0..4c3e9e4 100644
--- a/gcc/d/typeinfo.cc
+++ b/gcc/d/typeinfo.cc
@@ -489,14 +489,14 @@ class TypeInfoVisitor : public Visitor
CONSTRUCTOR_APPEND_ELT (v, size_int (3), size_int (b->offset));
/* Add to the array of interfaces. */
- value = build_constructor (vtbl_interface_type_node, v);
+ value = build_padded_constructor (vtbl_interface_type_node, v);
CONSTRUCTOR_APPEND_ELT (elms, size_int (i), value);
}
tree domain = size_int (cd->vtblInterfaces->length - 1);
tree arrtype = build_array_type (vtbl_interface_type_node,
build_index_type (domain));
- return build_constructor (arrtype, elms);
+ return build_padded_constructor (arrtype, elms);
}
/* Write out the interfacing vtable[] of base class BCD that will be accessed
@@ -542,7 +542,7 @@ class TypeInfoVisitor : public Visitor
tree vtbldomain = build_index_type (size_int (id->vtbl.length - 1));
tree vtbltype = build_array_type (vtable_entry_type, vtbldomain);
- tree value = build_constructor (vtbltype, elms);
+ tree value = build_padded_constructor (vtbltype, elms);
this->layout_field (value);
}
@@ -1160,7 +1160,7 @@ public:
CONSTRUCTOR_APPEND_ELT (elms, size_int (i),
build_typeinfo (d->loc, arg->type));
}
- tree ctor = build_constructor (build_ctype (satype), elms);
+ tree ctor = build_padded_constructor (build_ctype (satype), elms);
tree decl = this->internal_reference (ctor);
tree length = size_int (ti->arguments->length);