[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-03-02 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

--- Comment #13 from CVS Commits  ---
The master branch has been updated by Patrick Palka :

https://gcc.gnu.org/g:5425159d176a7a92afc932cbb22d8822667099c4

commit r13-6422-g5425159d176a7a92afc932cbb22d8822667099c4
Author: Patrick Palka 
Date:   Thu Mar 2 14:04:50 2023 -0500

c++: more mce_false folding from cp_fully_fold_init [PR108243]

We should also fold the overall initializer passed to cp_fully_fold_init
with mce_false, which allows folding of the copy-initialization of
'a1' in the below testcase (the initializer here is an AGGR_INIT_EXPR).

Unfortunately this doesn't help with direct- or default-initialization
because we don't call cp_fully_fold_init in that case, and even if we
did the initializer in that case is expressed as a bare CALL_EXPR
instead of an AGGR_INIT_EXPR, which cp_fully_fold_init can't really
fold.

PR c++/108243
PR c++/97553

gcc/cp/ChangeLog:

* cp-gimplify.cc (cp_fully_fold): Add an internal overload that
additionally takes and propagate an mce_value parameter, and
define the existing public overload in terms of it.
(cp_fully_fold_init): Pass mce_false to cp_fully_fold.

gcc/testsuite/ChangeLog:

* g++.dg/opt/is_constant_evaluated3.C: New test.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-03-02 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

--- Comment #12 from CVS Commits  ---
The master branch has been updated by Patrick Palka :

https://gcc.gnu.org/g:cbaa1d9c218d9c0b5e34e510a462ff4e299a0f3f

commit r13-6421-gcbaa1d9c218d9c0b5e34e510a462ff4e299a0f3f
Author: Patrick Palka 
Date:   Thu Mar 2 14:03:21 2023 -0500

c++: constant non-copy-init is manifestly constant [PR108243]

According to [basic.start.static]/2 and [expr.const]/2, a variable
with static storage duration initialized with a constant initializer
has constant initialization, and such an initializer is manifestly
constant-evaluated.

For copy initialization, we're already getting this right because in
that case check_initializer would consistently call store_init_value,
which for TREE_STATIC variables calls fold_non_dependent_init with
m_c_e=true.

But for direct (or default) initialization, check_initializer doesn't
always call store_init_value.  We instead however always call
maybe_constant_init from expand_default_init[1], albeit with m_c_e=false
which means we don't get the "manifestly constant-evaluated" part right
for non-copy-init.

This patch fixes this by setting m_c_e=true in maybe_constant_init for
static storage duration variables, mainly for benefit of the call
to maybe_constant_init from expand_default_init.

[1]: this maybe_constant_init call isn't reached in the copy-init
case because there init is a CONSTRUCTOR rather than a TREE_LIST,
and so we exit early from expand_default_init, returning an INIT_EXPR.
This INIT_EXPR is ultimately what causes us to consistently hit the
store_init_value code path from check_initializer in the copy-init case.

PR c++/108243

gcc/cp/ChangeLog:

* constexpr.cc (maybe_constant_init_1): Override
manifestly_const_eval to true if is_static.

gcc/testsuite/ChangeLog:

* g++.dg/cpp2a/is-constant-evaluated14.C: New test.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-02-21 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

--- Comment #11 from Patrick Palka  ---
The pending patch
https://gcc.gnu.org/pipermail/gcc-patches/2023-February/612365.html will fix
that.  With that patch we'll statically initialize

  static const string_view foo("bar");

as we already do for

  static const string_view foo = {"bar"};

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-02-21 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Richard Biener  changed:

   What|Removed |Added

   Priority|P3  |P2

--- Comment #10 from Richard Biener  ---
I'm not sure if this is supposed to be fixed yet.  For the comment#2 testcase
I now get

   [local count: 1073741824]:
  _1 = __atomic_load_1 (&_ZGVZ4mainE3foo, 2);
  if (_1 == 0)
goto ; [33.00%]
  else
goto ; [67.00%]

   [local count: 956811341]:
  goto ; [100.00%]

   [local count: 354334800]:
  _2 = __cxa_guard_acquire (&_ZGVZ4mainE3foo);
  if (_2 != 0)
goto ; [33.00%]
  else
goto ; [67.00%]

   [local count: 116930483]:
  MEM[(struct string_view *)] ={v} {CLOBBER};
  MEM[(struct string_view *)].str = "bar";
  MEM[(struct string_view *)].len = 3;
  __cxa_guard_release (&_ZGVZ4mainE3foo);

   [local count: 1073741824]:
  _9 = foo.len;
  _8 = (int) _9;
  return _8;

so we fail to CSE foo.len because __cxa_guard_release possibly clobbers it
(it's global memory).

Note the clobbering is necessary to prevent code motion across the
lock primitives.

Note that __cxa_guard_release also prevents removing the .str initialization
since only the .len member is ever inspected.  As noted static initialization
would improve this quite a bit.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-02-20 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

--- Comment #9 from Patrick Palka  ---
(In reply to Jiang An from comment #8)
> This seems a bug, not merely missing of optimization. The string_view object
> should always be statically initialized, because it has static storage
> duration and its initializer is a constant iniitializer.

Good point.  It looks like we're inconsistent about static initialization here
--  we do it for suitable copy initialization but not for suitable direct
initialization:

static std::string_view foo1 = {"bar"}; // static initialization
static std::string_view foo2("bar");// dynamic initialization

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-02-20 Thread de34 at live dot cn via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Jiang An  changed:

   What|Removed |Added

 CC||de34 at live dot cn

--- Comment #8 from Jiang An  ---
This seems a bug, not merely missing of optimization. The string_view object
should always be statically initialized, because it has static storage duration
and its initializer is a constant iniitializer.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-02-17 Thread cvs-commit at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

--- Comment #7 from CVS Commits  ---
The master branch has been updated by Patrick Palka :

https://gcc.gnu.org/g:5fea1be820508e1fbc610d1a54b61c1add33c36f

commit r13-6120-g5fea1be820508e1fbc610d1a54b61c1add33c36f
Author: Patrick Palka 
Date:   Fri Feb 17 15:18:10 2023 -0500

c++: speculative constexpr and is_constant_evaluated [PR108243]

This PR illustrates that __builtin_is_constant_evaluated currently acts
as an optimization barrier for our speculative constexpr evaluation,
since we don't want to prematurely fold the builtin to false before the
expression in question undergoes manifestly constant evaluation if
appropriate (in which case the builtin must instead be folded to true).

This patch fixes this by permitting __builtin_is_constant_evaluated to
get folded as false at appropiate points, namely during cp_fold_function
and cp_fully_fold_init where we know we're done with manifestly constant
evaluation.  The function cp_fold gets a flags parameter that controls
whether we pass mce_false or mce_unknown to maybe_constant_value when
folding a CALL_EXPR.

PR c++/108243
PR c++/97553

gcc/cp/ChangeLog:

* cp-gimplify.cc (enum fold_flags): Define.
(fold_flags_t): Declare.
(cp_fold_data::genericize): Replace this data member with ...
(cp_fold_data::fold_flags): ... this.
(cp_fold_r): Adjust use of cp_fold_data and calls to cp_fold.
(cp_fold_function): Likewise.
(cp_fold_maybe_rvalue): Add an internal overload that
additionally takes and propagates a fold_flags_t parameter, and
define the existing public overload in terms of it.
(cp_fold_rvalue): Likewise.
(cp_fully_fold_init): Adjust use of cp_fold_data.
(fold_cache): Replace with ...
(fold_caches): ... this 2-element array of caches.
(get_fold_cache): Define.
(clear_fold_cache): Adjust.
(cp_fold): Add fold_flags_t parameter.  Use get_fold_cache.
Pass flags to calls to cp_fold, cp_fold_rvalue and
cp_fold_maybe_rvalue.
: If ff_mce_false is set, fold
__builtin_is_constant_evaluated to false and pass mce_false to
maybe_constant_value.

gcc/testsuite/ChangeLog:

* g++.dg/opt/is_constant_evaluated1.C: New test.
* g++.dg/opt/is_constant_evaluated2.C: New test.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-01-27 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Patrick Palka  changed:

   What|Removed |Added

   Assignee|unassigned at gcc dot gnu.org  |ppalka at gcc dot 
gnu.org
 Status|NEW |ASSIGNED

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-01-09 Thread rguenth at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Richard Biener  changed:

   What|Removed |Added

   Target Milestone|--- |10.5

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-01-04 Thread jakub at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Jakub Jelinek  changed:

   What|Removed |Added

 CC||jakub at gcc dot gnu.org

--- Comment #6 from Jakub Jelinek  ---
We could have some FE constant expression evaluation mode in which we'd
guarantee that if the initializer/expression was manifestly constant evaluated,
it has been constant expression evaluated with manifestly_const_eval=true
already and do that as a last resort folding of initializers or perhaps
expressions in cp_fold_function or so.
But as you wrote, we can't do that by default for !manifestly_const_eval
evaluation, because we often do that before we evaluate those with
manifestly_const_eval=true.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-01-04 Thread ppalka at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Patrick Palka  changed:

   What|Removed |Added

   See Also||https://gcc.gnu.org/bugzill
   ||a/show_bug.cgi?id=97553
 CC||ppalka at gcc dot gnu.org

--- Comment #5 from Patrick Palka  ---
IIUC __builtin_is_constant_evaluated() currently acts as an optimization
barrier for the frontend's speculative folding since we don't want to
prematurely fold is_constant_evaluated() to false if the expression in question
would later be manifestly constant evaluated (in which case
is_constant_evaluated() must be folded to true).  PR97553 is caused by the same
issue I think.

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-01-04 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

--- Comment #4 from Jonathan Wakely  ---
GCC can't even optimize it properly for C++20 when using if-consteval:

  static constexpr unsigned long length(const char* s)
  {
#ifndef FIX
if consteval {
  unsigned long n = 0;
  while (*s++)
++n;
  return n;
}
#endif
return __builtin_strlen(s);
  }

[Bug c++/108243] [10/11/12/13 Regression] Missed optimization for static const std::string_view(const char*)

2023-01-04 Thread redi at gcc dot gnu.org via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108243

Jonathan Wakely  changed:

   What|Removed |Added

Summary|Missed optimization for |[10/11/12/13 Regression]
   |static const|Missed optimization for
   |std::string_view(const  |static const
   |char*)  |std::string_view(const
   ||char*)

--- Comment #3 from Jonathan Wakely  ---
And if the variable is like this it does optimize it:

  static constexpr string_view foo("bar");

Because then we take the constant evaluation path and calculate the length by
hand.

The problem seems to be that GCC considers the
__builtin_is_constant_evaluated() branch to be reachable for non-constexpr and
so doesn't inline as aggressively. If we have:

struct traits
{
  static constexpr unsigned long length(const char* s)
  {
#ifndef FIX
if (__builtin_is_constant_evaluated())
{
  unsigned long n = 0;
  while (*s++)
++n;
  return n;
}
#endif
return __builtin_strlen(s);
  }
};

struct string_view
{
  constexpr
  string_view(const char* s) : str(s), len(traits::length(s)) { }

  unsigned long size() const { return len; }

  const char* str;
  unsigned long len;
};

int main()
{
  static const string_view foo("bar");
  return foo.size();
}

Then with -DFIX we optimize correctly, but without -DFIX we don't. That block
of code should make no difference to inlining decisions, because at runtime it
is always dead code.