On 07/04/2017 06:02 PM, Geza Herman wrote:
Hi,

I've included a small program at the end of my email.

Here's what happens: in callInitA(), an Object put onto the stack (which
has a const member variable, initialized to 0). Then somefunction called
(which is intentionally not defined). Then ~Object() is called, which
has an "if", which has a not-immediately-obvious, but always false
condition. Compiling with -03, everything gets inlined.

My question is about the inlined ~Object(). As m_initType is always 0,
why does not optimize the destructor GCC away? GCC inserts code that
checks the value of m_initType.

Is it because such construct is rare in practice? Or is it hard to do an
optimization like that?

I've checked other compilers (clang, icc, msvc), none of them optimized
this.

(I've tried gcc 5.1, 6.1, 7.1)

I agree this would be a useful optimization.  I recently raised
bug 80794 with this same observation/request.  There are some
concerns with it (Jonathan gave a partial example(*)) but I don't
think they necessarily rule it out for the reasons discussed in
the bug (my comments 2 and 5).  It would be helpful if you added
your observations/interest there.

In general, GCC doesn't implement these kinds of optimizations
(based on the const qualifier) because its optimizer doesn't have
a way to distinguish between a const reference (or pointer) to
a non-const object that can be safely modified by casting
the constness away and a reference to const-ualified object
that cannot.  With this limitation overcome it should be possible
to implement this and other interesting optimizations that exploit
the const qualifier (another opportunity is discussed in bug 81009).
To avoid breaking existing (though I suspect rare) programs that
play tricks like those in the examples GCC might need to expose
its internal annotation to users to decorate functions/ and either
opt in to the optimization or opt out of it.  The annotation could
take the form of  a new attribute similar to that already provided
by some compilers.  For instance some make it possible to annotate
function arguments as "in" or "out" in addition to const.  Another
possibility is to make use of restrict in C++).

Martin

[*] While the example (copied below) is valid, accessing the object
after someFunction() has returned via a reference or pointer to it
is not.

  void somefunction(const Object& object);
  {
    void* p = &object;
    object.~Object();
    new(p) Object();
  }

In simple cases like the one above, decorating the reference with
the __restrict keyword would invalidate the code and make the
optimization safe.

  void somefunction(const Object& __restrict object);

Reply via email to