Optimize assignment to volatile aggregate variable
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 15 Jun 2020 17:56:00 +0000 (19:56 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Mon, 15 Jun 2020 17:58:31 +0000 (19:58 +0200)
commitc7bac01ab41f019a66bc07fc704752f436707eb8
tree6262e09a4b849ae56d10e87e20c65fd6f8099681
parentfb149ebdfee8995ed091f17cd64355ff54e9fb30
Optimize assignment to volatile aggregate variable

gimplify_modify_expr_rhs has an optimization whereby the assignment to
an aggregate variable from a read-only object with a DECL_INITIAL is
optimized into the direct assignment of the DECL_INITIAL, provided that
no temporary is created in the process.

The optimization is blocked if the read-only object is volatile, which
is OK as per the semantics of volatile, but also if the target variable
is volatile, on the grounds that the modified assignment might end up
being done on a per field basis, which is also OK.  But this latter
restriction is enforced a priori and there are cases where the modified
assignment would be OK, for example if there is only one field or the
DECL_INITIAL is equivalent to the empty CONSTRUCTOR, i.e. all zeros.

So, in the latter case, the patch changes gimplify_modify_expr_rhs to ask
gimplify_init_constructor whether the assignment would be done as a block,
which is easy because gimplify_init_constructor knows that it must create
a temporary if the LHS is volatile and this would not be the case, so it's
just a matter of completing the NOTIFY_TEMP_CREATION mechanism.

gcc/ChangeLog
* gimplify.c (gimplify_init_constructor) <AGGREGATE_TYPE>: Declare
new ENSURE_SINGLE_ACCESS constant and move variables down.  If it is
true and all elements are zero, then always clear.  Return GS_ERROR
if a temporary would be created for it and NOTIFY_TEMP_CREATION set.
(gimplify_modify_expr_rhs) <VAR_DECL>: If the target is volatile but
the type is aggregate non-addressable, ask gimplify_init_constructor
whether it can generate a single access to the target.

gcc/testsuite/ChangeLog
* gnat.dg/aggr30.ads, gnat.dg/aggr30.adb: New test.
gcc/gimplify.c
gcc/testsuite/gnat.dg/aggr30.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/aggr30.ads [new file with mode: 0644]