Martin Sebor <mse...@gmail.com> writes: > On 11/13/2017 04:36 PM, Richard Sandiford wrote: >> Jeff Law <l...@redhat.com> writes: >>> On 11/09/2017 04:06 AM, Richard Sandiford wrote: >>> >>>>> Let me say at the outset that I struggle to comprehend that a few >>>>> instructions is even a consideration when not optimizing, especially >>>>> in light of the bug the macro caused that would have been prevented >>>>> by using a function instead. But... >>>> >>>> Many people still build at -O0 though. One of the things I was asked >>>> for was the time it takes to build stage 2 with an -O0 stage 1 >>>> (where stage 1 would usually be built by the host compiler). >>> I suspect folks are concerned about this because it potentially affects >>> their daily development cycle times. So they're looking to see if the >>> introduction of the poly types has a significant impact. It's a >>> legitimate question, particularly for the introduction of low level >>> infrastructure that potentially gets hit a lot. >>> >>> Richard, what were the results of that test (if it's elsewhere in the >>> thread I'll eventually find it... >> >> On an x86_64 box I got: >> >> real: +7% >> user: +8.6% >> >> for building stage2 with an -O0 -g stage1. For aarch64 with the >> NUM_POLY_INT_COEFFS==2 change it was: >> >> real: +17% >> user: +20% >> >> That's obviously not ideal, but C++11 would get rid of some of the >> inefficiencies, once we can switch to that. > > For the purposes of this discussion, what would the numbers look > like if the macro were replaced with the inline function as I > suggested? > > What impact on the numbers would having the default ctor actually > initialize the object have? (As opposed to leaving it uninitialized.)
I was objecting to that for semantic reasons[*], not performance when built with -O0. I realise you don't agree, but I don't think either of us is going to convince the other here. > I don't want to make a bigger deal out of this macro than it > already is. Unlike the wide int constructors, it's > an implementation detail that, when correct, almost no-one will > have to worry about. The main reason for my strenuous objections > is not the macro itself but the philosophy that performance, > especially at -O0, should be an overriding consideration. Code > should be safe first and foremost. Otherwise, the few cycles we > might save by writing unsafe but fast code will be wasted in > debugging sessions. But the macro was originally added to improve release builds, not -O0 builds. It replaced plain assignments of the form: r.coeffs[0] = ...; Using an inline function instead of a macro is no better than the original call to operator=(); see the mem_ref_offset figures I gave earlier. Thanks, Richard [*] Which were: 1) Not all types used with poly_int have a single meaningful initial value (wide_int). 2) It prevents useful static warnings about uninitialised variables. The fact that we don't warn in every case doesn't defeat this IMO. 3) Using C++11 "= default" is a good compromise, but making poly_ints always initialised by default now would make it too dangerous to switch to "= default" in future. 4) Conditionally using "= default" when being built with C++11 compilers and something else when being built with C++03 compilers would be too dangerous, since we don't want the semantics of the class to depend on host compiler. 5) AFAIK, the only case that would be handled differently by the current "() {}" constructor and "= default" is the use of "T ()" to construct a zeroed T. IMO, "T (0)" is better than "T ()" anyway because (a) it makes it obvious that you're initialising it to the numerical value 0, rather than simply zeroed memory contents, and (b) it will give a compile error if T doesn't have a single zero representation (as for wide_int). Those are all independent of whatever the -O0 performance regression would be from unconditional initialisation.