Boost logo

Boost :

Subject: Re: [boost] [optional] generates unnessesary code for trivial types
From: Domagoj Saric (domagoj.saric_at_[hidden])
Date: 2012-01-27 11:32:50


On 25.1.2012. 18:28, Hite, Christopher wrote:
> When decompiling my code I noticed a bunch of unnessesary code caused by boost::optional.

Hi, I've recently created an improved internal version of boost::optional to
help workaround two issues:
  - suboptimal codegen
  - concurrent access.

You can now find this version under
https://svn.boost.org/svn/boost/sandbox/optional. So far the following has been
done:

a) the lifetime management bool was changed into a properly typed pointer (this
    actually takes the same amount of space while it provides a no-op get_ptr()
    member function as well as easier debugging as the contents of optional can
    now clearly be seen through the pointer, as opposed to gibberish in an opaque
    storage array)
b) added another conditional constructor that accepts an in-place factory
c) uses the safe bool idiom implementation from Boost.Range (which generates
    better code on pre MSVC10 compilers)
d) skips redundant/dead stores of marking itself as uninitialised [including but
    limited to, in its destructor (if it has one)]
e) streamlined internal assign paths to help the compiler avoid unnecessary
    branching
f) added direct_create() and direct_destroy() member functions that allow the
    user to bypass the internal lifetime management (they only assert correct
    usage) in situations where the user's own external logic already implicitly
    knows the state of the optional
g) optional now declares and defines a destructor only if the contained type has
    a non-trivial destructor (this prevents the compiler from detecting false EH
    states and thus generating bogus EH code)
h) optional marks itself as uninitialised _before_ calling the contained
    object's destructor (this makes it a little more robust in race conditions;
    it is of course not a complete solution for such scenarios, those require
    external "help" and/or (m)-reference counting to be implemented)
i) extracted the "placeholder" functionality into a standalone class (basically
    what would be left of optional<> if the lifetime management "bool" member and
    logic was removed) so that it can be reused (e.g. for singleton like classes,
    or when more complex custom lifetime management is required)
j) added compiler specific "aids" to workaround situations when the compiler is
    unable to detect that placement new will never return a nullptr (and then
    generates bogus branching) - IOW "optional<int> optional_number( 3 );" no
    longer generates a branch before storing "3" (yes "LOL":)
k) the lifetime management pointer is now stored after the actual contained
    object (this helps in avoiding more complex/offset addressing when accessing
    optionals through pointers w/o checking whether they are initialised)
l) removed support for antediluvian compilers (MSVC6, BCB5)

todo:

m) lifetime management policy: bool, pointer, reference count (+ a more generic
abstraction/interop with smart_ptr)...

n) zero size overhead for optional references (requires (m))

o) avoid branching in assignment and copy construction of optionals that hold
    PODs smaller than N * sizeof( void * ) where N is some small number

  - temporarily renamed to optional2 to avoid collision with the original
    optional
  - passes all optional unit tests (after being renamed back to optional) with
    MSVC10 SP1 and Apple Clang 3.0 (from Xcode 4.2.1)

Hope it helps ;)

ps. AFAICT the only real obstacle in having really nice codegen with
boost::optional<a_fundamental_type> is lack of proper ABI/compiler support for
passing and returning small structs in registers...

-- 
"What Huxley teaches is that in the age of advanced technology, spiritual
devastation is more likely to come from an enemy with a smiling face than
from one whose countenance exudes suspicion and hate."
Neil Postman

Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk