[PATCH] Teach libc++ to use __builtin_operator_new/__builtin_operator_delete when available

Richard Smith richard at metafoo.co.uk
Wed Jun 4 09:42:04 PDT 2014


On 4 Jun 2014 08:02, "Marshall Clow" <mclow.lists at gmail.com> wrote:
>
>
> On Jun 3, 2014, at 3:14 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> > Hi!
> >
> > This patch causes libc++ to use Clang's new __builtin_operator_new and
__builtin_operator_delete builtins when possible. These builtins allow
optimizations that the standard builtins do not: in particular, if we can
remove all uses of an allocation, this permits removing the allocation
itself too.
> >
> > In particular, this allows code using std::vector and its kin to be
optimized away to nothing. Previously it would get optimized to the point
where only the allocation and deallocation remained.
> >
> > This change has been applied to most calls to ::operator new and
::operator delete in libc++; I believe such optimizations are permitted by
the specification of all affected library components.
> >
> > The exceptions are:
> >  * get_temporary_buffer wants to call nothrow new, and we don't support
that with the builtins (that would require teaching Clang about
std::nothrow_t)
> >  * __refstring is not affected; this doesn't seem particularly
worthwhile since the only purpose for it is ABI interoperability with GCC
> >
> > One other caveat: the patch adds an include of <new> to <valarray>.
<new> is extremely light, so I doubt this is a problem, but I thought it
was worth calling out.
>
> The code here looks quite straightforward.
> I don’t see any problems - but I do have questions.
>
> How does __builtin_operator_new/__builtin_operator_delete work if a user
provides their own
> global operator new/delete ?
>
> For example, given code like this:
>
> $ cat junk1.cpp
>
> int main () {
>         // something that eventually calls __builtin_operator_new
> }
>
> $ cat junk2.cpp
> #include <new>
>
> char buffer[10240];
> size_t offset = 0;
>
> void * operator new(size_t sz) throw(std::bad_alloc) {
>         void *p = &buffer[offset];
>         offset += sz;
>         return p;
> }
> void operator delete(void *) {}
>
> does the user’s operator new get called?

Yes, if the allocation isn't optimised out. (The builtins behave just like
the allocation / deallocation in a new-expression or delete-expression.)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20140604/8140f834/attachment.html>


More information about the cfe-commits mailing list