[Bug ipa/86590] Codegen is poor when passing std::string by value with _GLIBCXX_EXTERN_TEMPLATE undefined
rguenth at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Fri Jul 20 08:36:00 GMT 2018
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86590
--- Comment #7 from Richard Biener <rguenth at gcc dot gnu.org> ---
I see differences in EH as well (comparing .original dumps of gnu++14 vs.
gnu++17):
@@ -126,7 +126,7 @@
;; enabled by -tree-original
-<<< Unknown tree: eh_spec_block
+<<< Unknown tree: must_not_throw_expr
<<cleanup_point return <retval> = __builtin_constant_p (__c) == 0 ||
(unsigned int) __c > 127 ? __btowc_alias (__c) : (wint_t) __c>>
>>>;
__builtin_unreachable ();
and
-;; Function static void
std::char_traits<char>::assign(std::char_traits<char>::char_type&, const
char_type&) (null)
+;; Function static constexpr void
std::char_traits<char>::assign(std::char_traits<char>::char_type&, const
char_type&) (null)
But the biggest difference seems to be the introduction of
;; Function constexpr bool std::__constant_string_p(const _CharT*) [with _CharT
= char] (null)
;; enabled by -tree-original
while (1)
{
if (__builtin_constant_p ((char) *__s) == 0 || *__s == 0) goto <D.10182>;
<<cleanup_point <<< Unknown tree: expr_stmt
(void) __s++ >>>>>;
}
<D.10182>:;
return <retval> = __builtin_constant_p ((char) *__s) != 0;
which inlined survices as
<bb 2> [local count: 1073741826]:
MEM[(struct &)&a] ={v} {CLOBBER};
_59 = &a.D.22134._M_local_buf;
MEM[(struct &)&a] ={v} {CLOBBER};
MEM[(struct _Alloc_hider *)&a]._M_p = _59;
<bb 3> [local count: 10037315480]:
# __s_63 = PHI <"Hello world"(2), __s_66(5)>
_64 = *__s_63;
_65 = __builtin_constant_p (_64);
if (_65 == 0)
goto <bb 6>; [5.50%]
else
goto <bb 4>; [94.50%]
which we are not able to simplify and which confuses us in optimizing.
Only the first DOM pass forcefully drops that to false. This seems to be
a quite stupid loop structure btw resulting from
std::char_traits<char>::length (const char_type * __s)
{
bool retval.1;
size_t D.33082;
retval.1 = std::__constant_string_p<char> (__s);
if (retval.1 != 0) goto <D.33080>; else goto <D.33081>;
<D.33080>:
D.33082 = __gnu_cxx::char_traits<char>::length (__s);
return D.33082;
<D.33081>:
D.33082 = __builtin_strlen (__s);
return D.33082;
}
and
std::__constant_string_p<char> (const char * __s)
{
bool D.33088;
<bb 2> :
_1 = *__s;
_2 = __builtin_constant_p (_1);
if (_2 == 0)
goto <bb 5>; [INV]
else
goto <bb 3>; [INV]
<bb 3> :
_3 = *__s;
if (_3 == 0)
goto <bb 5>; [INV]
else
goto <bb 4>; [INV]
<bb 4> :
__s = __s + 1;
goto <bb 2>; [INV]
<bb 5> :
_4 = *__s;
_5 = __builtin_constant_p (_4);
D.33088 = _5 != 0;
return D.33088;
}
/**
* @brief Determine whether the characters of a NULL-terminated
* string are known at compile time.
* @param __s The string.
*
* Assumes that _CharT is a built-in character type.
*/
template<typename _CharT>
static _GLIBCXX_ALWAYS_INLINE constexpr bool
__constant_string_p(const _CharT* __s)
{
while (__builtin_constant_p(*__s) && *__s)
__s++;
return __builtin_constant_p(*__s);
}
WTF?
More information about the Gcc-bugs
mailing list