pragma attribute syntax

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


On 6 June 2012 16:03, Artur Skawina <art.08.09 at gmail.com> wrote:
> 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?
>
>

Unfortunately not.  I can tell you that the modification would be to
d-decls.cc:(FuncDeclaration::toSymbol) - 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
functions.


-- 
Iain Buclaw

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


More information about the D.gnu mailing list