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

Aaron Ballman via cfe-dev cfe-dev at lists.llvm.org
Tue Nov 14 09:56:25 PST 2017


+1 to the idea. I think trivial_abi is a reasonable name for the
attribute as well.

~Aaron

On Tue, Nov 14, 2017 at 12:42 PM, Reid Kleckner via cfe-dev
<cfe-dev at lists.llvm.org> wrote:
> 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
>>
>
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
>



More information about the cfe-dev mailing list