This is an archive of the discontinued LLVM Phabricator instance.

[Builtins] Overload __builtin_operator_new/delete to allow forwarding to usual allocation/deallocation functions.
ClosedPublic

Authored by EricWF on Feb 7 2018, 2:48 PM.

Details

Summary

Libc++'s default allocator uses __builtin_operator_new and __builtin_operator_delete in order to allow the calls to new/delete to be ellided. However, libc++ now needs to support over-aligned types in the default allocator. In order to support this without disabling the existing optimization Clang needs to support calling the aligned new overloads from the builtins.

See llvm.org/PR22634 for more information about the libc++ bug.

This patch changes __builtin_operator_new/__builtin_operator_delete to call any usual operator new/operator delete function. It does this by performing overload resolution with the arguments passed to the builtin to determine which allocation function to call. If the selected function is not a usual allocation function a diagnostic is issued.

One open issue is if the align_val_t overloads should be considered "usual" when LangOpts::AlignedAllocation is disabled.

In order to allow libc++ to detect this new behavior the value for __has_builtin(__builtin_operator_new) has been updated to 201802.

Diff Detail

Event Timeline

EricWF created this revision.Feb 7 2018, 2:48 PM
rsmith added inline comments.Feb 7 2018, 3:13 PM
lib/CodeGen/CGExprCXX.cpp
1309–1344

Can we leave this code alone and set the builtin expression's type to exactly match the type of the chosen function? I really don't want to be special-casing aligned allocation here. (This change should also cover sized delete and any future extensions to builtin operator new/delete.)

lib/Lex/PPMacroExpansion.cpp
1242–1243

Hmm, I'd prefer something that just indicates that we have generalized __builtin_operator_new/delete support, so that you can use it for sized delete too.

lib/Sema/SemaChecking.cpp
2918–2962

Here's how I think this should work:

  • perform overload resolution for an operator new or operator delete with the given arguments
  • if the selected function is not a usual allocation / deallocation function, issue an error
  • set the type of the callee expression to the type of the selected function and convert the parameters as if you were going to call the selected function (so that codegen can find the correct callee again)
EricWF marked an inline comment as done.Feb 7 2018, 6:29 PM
EricWF added inline comments.
lib/CodeGen/CGExprCXX.cpp
1309–1344

That doesn't seem possible as you describe it. Both overloads of the builtin operator share the same FunctionDecl, and we can't change the type of that decl to match the selected operator for a particular call.

I think checking the argument types is the best way to proceed. However, I'll change the types of the call expression to exactly match the types of the selected operator new/delete, which will at least clean this up some.

EricWF added inline comments.Feb 7 2018, 6:49 PM
lib/CodeGen/CGExprCXX.cpp
1309–1344

Nevermind... I see what you meant. I can set the Callee type and not the type of the CalleeDecl.

EricWF updated this revision to Diff 133365.Feb 7 2018, 8:30 PM

@rsmith Is this the direction you were thinking?

I haven't updated the tests yet, but I wanted to make the other changes visible earlier.

EricWF updated this revision to Diff 133517.Feb 8 2018, 3:31 PM
EricWF retitled this revision from [Builtins] Overload __builtin_operator_new/delete to accept an optional alignment parameter. to [Builtins] Overload __builtin_operator_new/delete to allow forwarding to usual allocation/deallocation functions..
EricWF edited the summary of this revision. (Show Details)
  • Complete implementation suggested by @rsmith. The builtins now perform overload resolution to allow calling arbitrary usual allocation/deallocation functions.
  • Complete tests.
rsmith accepted this revision.Mar 19 2018, 2:58 PM

Thanks, this looks great.

lib/Sema/SemaExprCXX.cpp
3458 ↗(On Diff #134989)

It would be nice to assert that the callee you're setting the type of is an ImplicitCastExpr doing a BuiltinFnToFnPtr cast (just so that it's obvious that this is the only type we need to update and that it's freshly-created).

This revision is now accepted and ready to land.Mar 19 2018, 2:58 PM
EricWF updated this revision to Diff 139347.Mar 21 2018, 12:21 PM
EricWF marked an inline comment as done.
  • Merge with upstream.
  • Add requested assertion.
lib/Sema/SemaExprCXX.cpp
3458 ↗(On Diff #134989)

Ack. Done.

This revision was automatically updated to reflect the committed changes.
This revision was automatically updated to reflect the committed changes.