pragma attribute syntax

Artur Skawina art.08.09 at gmail.com
Wed Jun 6 08:03:25 PDT 2012


On 06/06/12 12:14, Iain Buclaw wrote:
> On 5 June 2012 00:24, Artur Skawina <art.08.09 at gmail.com> wrote:
>> On 06/04/12 23:49, Iain Buclaw wrote:
>>> On 4 June 2012 21:53, Artur Skawina <art.08.09 at gmail.com> wrote:
>>>> On 06/04/12 21:48, Iain Buclaw wrote:
>>>>> On 4 June 2012 19:49, Artur Skawina <art.08.09 at gmail.com> wrote:
>>>>>> Would it be possible to allow give the gcc attribute as a string?
>>>>>> So that it would be possible to express 'pragma(attribute, align(8))' etc
>>>>>>
>>>>>> Because right now you can not do this:
>>>>>>
>>>>>>   pragma(attribute, pure)
>>>>>>   pragma(attribute, const)
>>>>
>>>>> You can use underscores as alternate syntax:
>>>>>
>>>>> pragma(attribute, __pure__)
>>>>> pragma(attribute, __const__)
>>>>>
>>>>
>>>> Works, thank you.
>>>>
>>>> And it even does the right thing - makes the compiler correctly optimize
>>>> away calls to pure functions that take const ref/pointer args, which D's
>>>> "pure" does not handle yet.
>>
>> I should probably add that, unlike the D "pure" attribute, GCC will assume
>> that you know what you're doing, so it's possible to wrongly tag a function
>> as pure using this pragma.
>>
>>> To get the equivalent of "pure", you need to mark the function as pure
>>> nothrow in D.  There is no equivalent of "const" yet, but we can
>>> discuss ways to go about defining that. :)
>>
>> No, "pure nothrow" is unfortunately not enough; the only case where it works
>> as one might expect if the function takes any pointer/ref arguments, is when
>> these args are immutable.
>>
>> D's pure functions that do not have pointer/ref inputs should map pretty
>> well do GCC "const", but from the little testing I did today, it seems
>> this already works reasonably well, so the "const" attribute may not be
>> needed, the compiler manages to eliminate redundant calls already.
>>
> 
> With help of the hints passed to the backend, it should be able to
> determine that functions  a) with no side effects and b) who's return
> value is ignored - should safely discarded.

It should also improve CSE, hoisting out loop invariants etc.

>> The problematic case is something like this:
>>
>>   struct S {
>>      int a,b;
>>      int[64] c;
>>      pragma(attribute, noinline, __pure__) bool f() const pure nothrow {
>>         return a||b;
>>      }
>>   }
>>
>> Without the pragma the compiler will call f() twice when evaluating
>>
>>   S s; auto r = s.f()+s.f(); /*...use r...*/
>>
>> I'm told this is by design, which, if true, would prevent a lot of
>> valid optimizations.
>>
>> The (long) story: http://d.puremagic.com/issues/show_bug.cgi?id=8185
>>
> 
> I've just added a change which should give it a better mapping from
> keyword to gcc attribute equivalents.
> 
> D keyword -> D frontend representation (depends on function contents
> however) -> gcc matched attribute
> 
> pure                -> PUREweak   -> no vops
> pure const       -> PUREconst   -> const
> pure nothrow    -> PUREstrong  -> pure
> 
> 
> This means that any pure functions should be guaranteed to be
> evaluated once in the use case s.f()+s.f(); - will have a play around
> with it though to check for safety / correctness.

Hmm, is there a way to see the purity level determined by the frontend,
w/o doing any compiler modifications?


>> The "noinline", BTW, is for some reason required in both the D-pure
>> and GCC-pure cases for the optimization to work.
> 
> This is an optimisation I pulled from ISO C++ into gdc - that all
> member functions defined within the body of a class (and in D, this
> includes structs too) are to be marked inline.

I know. What I'm saying is that omitting the "noinline" attribute causes
the "pure" function, like s.f() above, to be called twice. Add the
"noinline" back, with no other changes - and it gets called only once.
This happens both for "strongly pure" D functions and gcc-pure-tagged
functions. It seems that either the optimizer (CSE?) gets confused by
the inlining or it treats the case when the function body is available
differently.

> However, this does not currently work with members outside the current
> module we are compiling for.  So the next step is to get cross-module
> inlining working.

That would be great, then i could stop writing code like
  int f(INLINE=this)(...) {...}
:)

artur 


More information about the D.gnu mailing list