[Bug libstdc++/80811] New: out-of-line string members less efficient than they could be
msebor at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu May 18 04:48:00 GMT 2017
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80811
Bug ID: 80811
Summary: out-of-line string members less efficient than they
could be
Product: gcc
Version: 7.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: libstdc++
Assignee: unassigned at gcc dot gnu.org
Reporter: msebor at gcc dot gnu.org
Target Milestone: ---
Consider the following contrived example and the optimized dump of the two
functions. The first overload of cmp is optimized into a no-op, while the
second, equivalent overload contains a pair of identical calls to
string::compare along with a dutiful comparison of their return values. The
difference is likely thanks to the first overload of string::compare being
defined inline and GCC being able to determine that it has no side-effects,
while the second overload of string::compare being defined out-of-line and GCC
apparently not being able to make the same determination. But when the second
overload is decorated with attribute pure, GCC is able to optimize both
functions the same way. I would expect it to be possible to make GCC recognize
this and perform the optimization regardless, but until it does, it seems that
there may be an opportunity to help GCC optimize many libstdc++ functions by
making use of this attribute (and perhaps others as well).
$ cat t.C && g++ -O2 -S -Wall -Wextra -fdump-tree-optimized=/dev/stdout t.ii
#include <string>
void cmp (const std::string &str, const char *s)
{
int c1 = str.compare (s);
int c2 = str.compare (s);
if (c1 != c2)
__builtin_abort ();
}
void cmp (const std::string &s1, const std::string &s2)
{
int c1 = s1.compare (s2;
int c2 = s2.compare (s1);
if (c1 != c2)
__builtin_abort ();
}
;; Function void cmp(const string&, const string&)
(_Z3cmpRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES6_,
funcdef_no=1005, decl_uid=24124, cgraph_uid=293, symbol_order=295)
void cmp(const string&, const string&) (const struct string & s1, const struct
string & s2)
{
<bb 2> [100.00%]:
return;
}
;; Function void cmp(const string&, const char*)
(_Z3cmpRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPKc,
funcdef_no=1006, decl_uid=24130, cgraph_uid=294, symbol_order=296)
void cmp(const string&, const char*) (const struct string & str, const char *
s)
{
int c2;
int c1;
<bb 2> [100.00%]:
c1_5 = std::__cxx11::basic_string<char>::compare (str_2(D), s_3(D));
c2_7 = std::__cxx11::basic_string<char>::compare (str_2(D), s_3(D));
if (c1_5 != c2_7)
goto <bb 3>; [0.04%]
else
goto <bb 4>; [99.96%]
<bb 3> [0.04%]:
__builtin_abort ();
<bb 4> [99.96%]:
return;
}
More information about the Gcc-bugs
mailing list