[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