Extend store merging to STRING_CST
authorEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 3 Jul 2020 16:10:25 +0000 (18:10 +0200)
committerEric Botcazou <ebotcazou@gcc.gnu.org>
Fri, 3 Jul 2020 16:31:04 +0000 (18:31 +0200)
commite362a897655e3b92949b65a2b53e00fb3ab8ded0
tree4a6123efd03f9969c0a3124c6add9061e421a983
parentb9a15a8325ba89b926e3c437b7961829a6b2fa2b
Extend store merging to STRING_CST

The GIMPLE store merging pass doesn't merge STRING_CSTs in the general
case, although they are accepted by native_encode_expr; the reason is
that the pass only works with integral modes, i.e. with chunks whose
size is a power of two.

There are two possible ways of extending it to handle STRING_CSTs:
1) lift the condition of integral modes and treat STRING_CSTs as
other _CST nodes but with arbitrary size; 2) implement a specific
and separate handling for STRING_CSTs.

The attached patch implements 2) for the following reasons: on the
one hand, even in Ada where character strings are first-class citizens,
cases where merging STRING_CSTs with other *_CST nodes would be possible
are quite rare in practice; on the other hand, string concatenations
happen more naturally and frequently thanks to the "&" operator, giving
rise to merging opportunities.

gcc/ChangeLog:
* gimple-fold.c (gimple_fold_builtin_memory_op): Fold calls that
were initially created for the assignment of a variable-sized
object and whose source is now a string constant.
* gimple-ssa-store-merging.c (struct merged_store_group): Document
STRING_CST for rhs_code field.
Add string_concatenation boolean field.
(merged_store_group::merged_store_group): Initialize it as well as
bit_insertion here.
(merged_store_group::do_merge): Set it upon seeing a STRING_CST.
Also set bit_insertion here upon seeing a BIT_INSERT_EXPR.
(merged_store_group::apply_stores): Clear it for small regions.
Do not create a power-of-2-sized buffer if it is still true.
And do not set bit_insertion here again.
(encode_tree_to_bitpos): Deal with BLKmode for the expression.
(merged_store_group::can_be_merged_into): Deal with STRING_CST.
(imm_store_chain_info::coalesce_immediate_stores): Set bit_insertion
to true after changing MEM_REF stores into BIT_INSERT_EXPR stores.
(count_multiple_uses): Return 0 for STRING_CST.
(split_group): Do not split the group for a string concatenation.
(imm_store_chain_info::output_merged_store): Constify and rename
some local variables.  Build an array type as destination type
for a string concatenation, as well as a zero mask, and call
build_string to build the source.
(lhs_valid_for_store_merging_p): Return true for VIEW_CONVERT_EXPR.
(pass_store_merging::process_store): Accept STRING_CST on the RHS.
* gimple.h (gimple_call_alloca_for_var_p): New accessor function.
* gimplify.c (gimplify_modify_expr_to_memcpy): Set alloca_for_var.
* tree.h (CALL_ALLOCA_FOR_VAR_P): Document it for BUILT_IN_MEMCPY.

gcc/testsuite/ChangeLog:
* gnat.dg/opt87.adb: New test.
* gnat.dg/opt87_pkg.ads: New helper.
* gnat.dg/opt87_pkg.adb: Likewise.
gcc/gimple-fold.c
gcc/gimple-ssa-store-merging.c
gcc/gimple.h
gcc/gimplify.c
gcc/testsuite/gnat.dg/opt87.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt87_pkg.adb [new file with mode: 0644]
gcc/testsuite/gnat.dg/opt87_pkg.ads [new file with mode: 0644]
gcc/tree.h