diff options
author | Jan Hubicka <hubicka@ucw.cz> | 2025-03-30 23:49:49 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@ucw.cz> | 2025-03-30 23:51:19 +0200 |
commit | 9c5505a35d9d71705464f9254f55407192d31ec3 (patch) | |
tree | 28d09286bfcec94536d72aee660fa3eb670cfc11 /gcc | |
parent | 37f35ebc7c50afdc9aeb4774b7d0ca7e7f32bbf1 (diff) | |
download | gcc-9c5505a35d9d71705464f9254f55407192d31ec3.zip gcc-9c5505a35d9d71705464f9254f55407192d31ec3.tar.gz gcc-9c5505a35d9d71705464f9254f55407192d31ec3.tar.bz2 |
Optimize string constructor
this patch improves code generation on string constructors. We currently have
_M_construct which takes as a parameter two iterators (begin/end pointers to
other string) and produces new string. This patch adds special case of
constructor where instead of begining/end pointers we readily know the string
size and also special case when we know that source is 0 terminated. This
happens commonly when producing stirng copies. Moreover currently ipa-prop is
not able to propagate information that beg-end is known constant (copied string
size) which makes it impossible for inliner to spot the common case where
string size is known to be shorter than 15 bytes and fits in local buffer.
Finally I made new constructor inline. Because it is explicitely instantiated
without C++20 constexpr we do not produce implicit instantiation (as required
by standard) which prevents inlining, ipa-modref and any other IPA analysis to
happen. I think we need to make many of the other functions inline, since
optimization accross string manipulation is quite important. There is PR94960
to track this issue.
Bootstrapped/regtested x86_64-linux, OK?
libstdc++-v3/ChangeLog:
PR tree-optimization/103827
PR tree-optimization/80331
PR tree-optimization/87502
* config/abi/pre/gnu.ver: Add version for _M_construct<bool>
* include/bits/basic_string.h: (basic_string::_M_construct<bool>): Declare.
(basic_string constructors): Use it.
* include/bits/basic_string.tcc: (basic_string::_M_construct<bool>): New template.
* src/c++11/string-inst.cc: Instantated S::_M_construct<bool>.
gcc/testsuite/ChangeLog:
* g++.dg/tree-ssa/pr80331.C: New test.
* g++.dg/tree-ssa/pr87502.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr80331.C | 8 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/tree-ssa/pr87502.C | 15 |
2 files changed, 23 insertions, 0 deletions
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr80331.C b/gcc/testsuite/g++.dg/tree-ssa/pr80331.C new file mode 100644 index 0000000..8503450 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr80331.C @@ -0,0 +1,8 @@ +// { dg-do compile } +// { dg-additional-options "-O2 -fdump-tree-optimized" } +#include<string> +int sain() { + const std::string remove_me("remove_me"); + return 0; +} +// { dg-final { scan-tree-dump-not "remove_me" "optimized" } } diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr87502.C b/gcc/testsuite/g++.dg/tree-ssa/pr87502.C new file mode 100644 index 0000000..ad3e9d2 --- /dev/null +++ b/gcc/testsuite/g++.dg/tree-ssa/pr87502.C @@ -0,0 +1,15 @@ +// { dg-do compile } +// { dg-additional-options "-O2 -fdump-tree-optimized" } +#include <string> + + +__attribute__ ((pure)) +extern int foo (const std::string &); + +int +bar () +{ + return foo ("abc") + foo (std::string("abc")); +} +// We used to add terminating zero explicitely instead of using fact +// that memcpy source is already 0 terminated. |