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.
This commit is contained in:
parent
24d1832e0d
commit
3e3b665cc7
7 changed files with 45 additions and 28 deletions
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue