pragma attribute syntax

Iain Buclaw ibuclaw at
Wed Jun 6 09:02:30 PDT 2012

On 6 June 2012 16:03, Artur Skawina <art.08.09 at> wrote:
> On 06/06/12 12:14, Iain Buclaw wrote:
>> On 5 June 2012 00:24, Artur Skawina <art.08.09 at> wrote:
>>> On 06/04/12 23:49, Iain Buclaw wrote:
>>>> On 4 June 2012 21:53, Artur Skawina <art.08.09 at> wrote:
>>>>> On 06/04/12 21:48, Iain Buclaw wrote:
>>>>>> On 4 June 2012 19:49, Artur Skawina <art.08.09 at> 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:
>> 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?

Unfortunately not.  I can tell you that the modification would be to - adding a fprintf(stderr) with
the purity value - hint, it's an enum.

>>> 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.

Could you provide some examples?

I can only think of this occurring for functions that have arbituary
side effects.  ie: if you insert debug printf statements into pure

Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';

More information about the D.gnu mailing list