[cfe-dev] [RFC] Attribute that can be used to instruct clang to pass and return non-trivial structs directly

Reid Kleckner via cfe-dev cfe-dev at lists.llvm.org
Tue Nov 14 09:42:32 PST 2017


Yes, this idea has been kicking around for a long time. We should
definitely have an attribute for this.

We talked for a long time about the idea that this attribute marks a type
as not having address identity, kind of like unnamed_addr works for
globals. However, I think some identity-related name would probably be
confusing to users. Most people don't understand the vagaries of why
std::unique_ptr<T*> isn't passed the same as T*, and they want a fix that
says something like "pass_in_registers" or
"shut_up_compiler_do_what_I_want", even though pass_in_registers is kind of
meaningless when you're out of or never had any parameter registers.

Anyway, trivial_abi sounds fine. At least, as someone who has worked in
clang call lowering, I understand what it means.

On Mon, Nov 13, 2017 at 5:37 PM, Akira Hatanaka via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

> I'd like to propose an attribute that can be used to instruct clang to
> pass and return non-trivial C++ structs directly when it's possible to do
> so. Any feedback would be greatly appreciated.
>
> ### Motivation for the attribute
> We have a user who wants to adopt smart pointers to manage lifetime of
> objects. The current code looks like this:
>
> struct Object {
>   ...
>   void release();
> };
>
> Object *getObject();
>
> void test() {
>   Object *t = getObject();
>   ...
>   // Users have to call 'release' manually.
>   t->release();
> }
>
> The smart pointer the user plans to use is a thin C++ template wrapper
> whose only data member is the raw pointer that points to the object being
> managed:
>
> template<class T>
> struct SmartPtr {
>   T *ptr;
>   SmartPtr(T *p);
>   SmartPtr(const SmartPtr &);
>   ~SmartPtr() {
>     ptr->release();
>   }
> };
>
> SmartPtr<Object> getObject();
>
> void test() {
>   SmartPtr<Object> t = getObject();
>   ...
>   // The object 't' points to is automatically released when ~SmartPtr is
> called.
> }
>
> The problem with the code above is that, since SmartPtr is considered to
> be non-trivial for the purpose of calls according to the C++ ABI, function
> getObject now returns its return value indirectly via an implicit pointer
> parameter passed to the function even though the struct has the same
> in-memory representation as a raw pointer. This breaks ABI compatibility
> for users who use getObject in their code but cannot rewrite their code to
> use the new API.
>
> ### The proposed attribute
> The attribute (tentatively named "trivial_abi") will be used to annotate
> C++ structs and instruct clang to pass and return the struct indirectly
> when it's possible to do so. This means that the presence of a non-trivial
> destructor or copy constructor will not force the struct to be passed or
> returned indirectly, but it doesn't guarantee the struct will always be
> passed or returned directly (the struct have to be passed indirectly if its
> size is too large or there is another data member that is non-trivial, for
> example).
>
> Besides avoiding ABI breakage, the attribute can potentially improve
> performance since the extra load instruction to get the value of the
> pointer isn't needed when the struct is passed or returned directly.
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20171114/3c69b2d5/attachment.html>


More information about the cfe-dev mailing list