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