public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug c++/115639] New: Large variations in compilation times involving static_assert
@ 2024-06-25 11:13 pkeir at outlook dot com
2024-06-26 17:53 ` [Bug c++/115639] " mpolacek at gcc dot gnu.org
2024-06-26 20:07 ` mpolacek at gcc dot gnu.org
0 siblings, 2 replies; 3+ messages in thread
From: pkeir at outlook dot com @ 2024-06-25 11:13 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115639
Bug ID: 115639
Summary: Large variations in compilation times involving
static_assert
Product: gcc
Version: 15.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c++
Assignee: unassigned at gcc dot gnu.org
Reporter: pkeir at outlook dot com
Target Milestone: ---
I often want to be sure that an expression is evaluated at compile time, while
also checking that it produces the expected value. With a `constexpr` function
called `big_calc`, expected to return zero, I might either use:
static_assert(0==big_calc()); // (1)
...or:
constexpr int ret = big_calc(); // (2)
static_assert(0==ret);
Surprisingly, the first of these (1) takes around 76% longer than the second
(2) to compile.
constexpr int big_calc()
{
long i = 1, count = 0, n = (1<<22);
for (; i < n; i++)
count = count + i;
bool b = count == (i * (i - 1)) / 2;
return 0;
}
This is true even when `big_calc` involves more calculations. I am using Ubuntu
24.04 with an Intel i9-13900K, and g++ (GCC) 15.0.0 20240623 (experimental).
With `n` of `big_calc` set at `(1<<22)` (as above) average compilation times
are 6.5 secs. for approach (1); and 3.7 secs. for approach (2).
With `n` of `big_calc` set at `(1<<24)` average compilation times are 28.3
secs. for approach (1); and 16.2 secs. for approach (2).
time /opt/gcc-latest/bin/g++ -std=c++20
performance-bug-double-constant-eval.cpp -fconstexpr-ops-limit=$((2**31-1))
-fconstexpr-loop-limit=$((2**31-1))
Other approaches to invoke `big_calc` (e.g. SFINAE/Concepts class/function
templates) are also slow; and have the performance profile of method (1).
Perhaps the constant expression is being evaluated twice.
It does look odd that the `big_calc` function returns zero. This was reduced
from a larger problem. Curiously, if `big_calc` instead returns a boolean (i.e.
`b`), and the `0==` part of each constant expression is removed, the issue
disappears.
This is reminiscent of a recently resolved Clang issue
(https://github.com/llvm/llvm-project/issues/92924), though with 2 notable
differences: firstly, with GCC the problem only arises when the `big_calc`
function is actually invoked; and secondly, the `-Wno-invalid-constexpr` flag
makes no difference to the performance with GCC.
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bug c++/115639] Large variations in compilation times involving static_assert
2024-06-25 11:13 [Bug c++/115639] New: Large variations in compilation times involving static_assert pkeir at outlook dot com
@ 2024-06-26 17:53 ` mpolacek at gcc dot gnu.org
2024-06-26 20:07 ` mpolacek at gcc dot gnu.org
1 sibling, 0 replies; 3+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2024-06-26 17:53 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115639
Marek Polacek <mpolacek at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Last reconfirmed| |2024-06-26
CC| |mpolacek at gcc dot gnu.org
Status|UNCONFIRMED |NEW
Ever confirmed|0 |1
--- Comment #1 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
Reproduced:
$ time ./cc1plus -quiet 115639.C -fconstexpr-ops-limit=$((2**31-1))
-fconstexpr-loop-limit=$((2**31-1))
real 0m46.072s
user 0m45.541s
sys 0m0.273s
vs.
$ time ./cc1plus -quiet 115639.C -fconstexpr-ops-limit=$((2**31-1))
-fconstexpr-loop-limit=$((2**31-1))
real 0m25.545s
user 0m25.125s
sys 0m0.285s
^ permalink raw reply [flat|nested] 3+ messages in thread
* [Bug c++/115639] Large variations in compilation times involving static_assert
2024-06-25 11:13 [Bug c++/115639] New: Large variations in compilation times involving static_assert pkeir at outlook dot com
2024-06-26 17:53 ` [Bug c++/115639] " mpolacek at gcc dot gnu.org
@ 2024-06-26 20:07 ` mpolacek at gcc dot gnu.org
1 sibling, 0 replies; 3+ messages in thread
From: mpolacek at gcc dot gnu.org @ 2024-06-26 20:07 UTC (permalink / raw)
To: gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=115639
--- Comment #2 from Marek Polacek <mpolacek at gcc dot gnu.org> ---
With
static_assert(0==big_calc()); // (1)
we evaluate the big_calc call twice. Once, while parsing the static_assert:
#0 cxx_eval_call_expression (ctx=0x7fffffffc3e0, t=<call_expr 0x7fffea3c5b40>,
lval=vc_prvalue,
non_constant_p=0x7fffffffc50f, overflow_p=0x7fffffffc50e) at
/home/mpolacek/src/gcc/gcc/cp/constexpr.cc:2801
#1 0x0000000000e45583 in cxx_eval_constant_expression (ctx=0x7fffffffc3e0,
t=<call_expr 0x7fffea3c5b40>,
lval=vc_prvalue, non_constant_p=0x7fffffffc50f, overflow_p=0x7fffffffc50e,
jump_target=0x0)
at /home/mpolacek/src/gcc/gcc/cp/constexpr.cc:7554
#2 0x0000000000e4b6b8 in cxx_eval_outermost_constant_expr (t=<call_expr
0x7fffea3c5b40>, allow_non_constant=true,
strict=true, manifestly_const_eval=mce_value::mce_unknown,
constexpr_dtor=false, object=<tree 0x0>)
at /home/mpolacek/src/gcc/gcc/cp/constexpr.cc:8852
#3 0x0000000000e4c8ee in maybe_constant_value (t=<call_expr 0x7fffea3c5b40>,
decl=<tree 0x0>,
manifestly_const_eval=mce_value::mce_unknown) at
/home/mpolacek/src/gcc/gcc/cp/constexpr.cc:9161
#4 0x0000000000e95c58 in cp_fully_fold (x=<call_expr 0x7fffea3c5b40>,
manifestly_const_eval=mce_value::mce_unknown)
at /home/mpolacek/src/gcc/gcc/cp/cp-gimplify.cc:2852
#5 0x0000000000e95dc7 in cp_fully_fold (x=<call_expr 0x7fffea3c5b40>)
at /home/mpolacek/src/gcc/gcc/cp/cp-gimplify.cc:2871
#6 0x000000000122ee78 in cp_build_binary_op (location=..., code=EQ_EXPR,
orig_op0=<non_lvalue_expr 0x7fffea3cd540>,
orig_op1=<call_expr 0x7fffea3c5b40>, complain=3) at
/home/mpolacek/src/gcc/gcc/cp/typeck.cc:6669
#7 0x0000000000dc774e in build_new_op (loc=..., code=EQ_EXPR, flags=1,
arg1=<non_lvalue_expr 0x7fffea3cd540>,
arg2=<call_expr 0x7fffea3c5b40>, arg3=<tree 0x0>, lookups=<tree 0x0>,
overload=0x7fffffffcc30, complain=3)
at /home/mpolacek/src/gcc/gcc/cp/call.cc:7516
and the second time while in finish_static_assert:
#0 cxx_eval_call_expression (ctx=0x7fffffffce20, t=<call_expr 0x7fffea3c5b40>,
lval=vc_prvalue,
non_constant_p=0x7fffffffcf4f, overflow_p=0x7fffffffcf4e) at
/home/mpolacek/src/gcc/gcc/cp/constexpr.cc:2801
#1 0x0000000000e45583 in cxx_eval_constant_expression (ctx=0x7fffffffce20,
t=<call_expr 0x7fffea3c5b40>,
lval=vc_prvalue, non_constant_p=0x7fffffffcf4f, overflow_p=0x7fffffffcf4e,
jump_target=0x0)
at /home/mpolacek/src/gcc/gcc/cp/constexpr.cc:7554
#2 0x0000000000e35b6b in cxx_eval_binary_expression (ctx=0x7fffffffce20,
t=<eq_expr 0x7fffea3cc5a0>, lval=vc_prvalue,
non_constant_p=0x7fffffffcf4f, overflow_p=0x7fffffffcf4e) at
/home/mpolacek/src/gcc/gcc/cp/constexpr.cc:3820
#3 0x0000000000e46f1f in cxx_eval_constant_expression (ctx=0x7fffffffce20,
t=<eq_expr 0x7fffea3cc5a0>, lval=vc_prvalue,
non_constant_p=0x7fffffffcf4f, overflow_p=0x7fffffffcf4e, jump_target=0x0)
at /home/mpolacek/src/gcc/gcc/cp/constexpr.cc:7966
#4 0x0000000000e4b6b8 in cxx_eval_outermost_constant_expr (t=<eq_expr
0x7fffea3cc5a0>, allow_non_constant=true,
strict=true, manifestly_const_eval=mce_value::mce_true,
constexpr_dtor=false, object=<tree 0x0>)
at /home/mpolacek/src/gcc/gcc/cp/constexpr.cc:8852
#5 0x0000000000e4c7c2 in maybe_constant_value (t=<eq_expr 0x7fffea3cc5a0>,
decl=<tree 0x0>,
manifestly_const_eval=mce_value::mce_true) at
/home/mpolacek/src/gcc/gcc/cp/constexpr.cc:9140
#6 0x0000000000e4ce02 in fold_non_dependent_expr (t=<eq_expr 0x7fffea3cc5a0>,
complain=3, manifestly_const_eval=true,
object=<tree 0x0>) at /home/mpolacek/src/gcc/gcc/cp/constexpr.cc:9280
#7 0x00000000011dd851 in finish_static_assert (condition=<eq_expr
0x7fffea3cc5a0>, message=<string_cst 0x7fffcde811f8>,
location=2147483661, member_p=false, show_expr_p=false) at
/home/mpolacek/src/gcc/gcc/cp/semantics.cc:11887
The second time around, we're not finding the call in constexpr_call_table.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-06-26 20:07 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-06-25 11:13 [Bug c++/115639] New: Large variations in compilation times involving static_assert pkeir at outlook dot com
2024-06-26 17:53 ` [Bug c++/115639] " mpolacek at gcc dot gnu.org
2024-06-26 20:07 ` mpolacek at gcc dot gnu.org
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).