diff options
author | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2020-07-03 18:10:25 +0200 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2020-07-03 18:31:04 +0200 |
commit | e362a897655e3b92949b65a2b53e00fb3ab8ded0 (patch) | |
tree | 4a6123efd03f9969c0a3124c6add9061e421a983 /gcc/tree.h | |
parent | b9a15a8325ba89b926e3c437b7961829a6b2fa2b (diff) | |
download | gcc-e362a897655e3b92949b65a2b53e00fb3ab8ded0.zip gcc-e362a897655e3b92949b65a2b53e00fb3ab8ded0.tar.gz gcc-e362a897655e3b92949b65a2b53e00fb3ab8ded0.tar.bz2 |
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.
Diffstat (limited to 'gcc/tree.h')
-rw-r--r-- | gcc/tree.h | 4 |
1 files changed, 3 insertions, 1 deletions
@@ -925,7 +925,9 @@ extern void omp_clause_range_check_failed (const_tree, const char *, int, #define CALL_FROM_THUNK_P(NODE) (CALL_EXPR_CHECK (NODE)->base.protected_flag) /* In a CALL_EXPR, if the function being called is BUILT_IN_ALLOCA, means that - it has been built for the declaration of a variable-sized object. */ + it has been built for the declaration of a variable-sized object and, if the + function being called is BUILT_IN_MEMCPY, means that it has been built for + the assignment of a variable-sized object. */ #define CALL_ALLOCA_FOR_VAR_P(NODE) \ (CALL_EXPR_CHECK (NODE)->base.protected_flag) |