* Any way to locally apply no-strict-alias?
@ 2008-10-09 12:40 John Fine
2008-10-09 12:48 ` Andrew Haley
0 siblings, 1 reply; 9+ messages in thread
From: John Fine @ 2008-10-09 12:40 UTC (permalink / raw)
To: gcc-help
I have a very large module, which contains a few places where a pointer
is cast based on a templated data type.
Typically a pointer is created using a templated type, then copied as a
void*, then used as the templated type. In one of those places, the
optimizer removes the copy step, which is correct behavior for the
optimizer under strict aliasing, but of course incorrect for the program.
Because of the way the templating fits in, it would be very hard to
either make a correct union for the pointer, or do the copy using the
correct type.
Creating, copying and using the pointer are coded in different sub
projects in code templated on different things, but all of which might
be brought together by inlining (so the optimizer can do this damage).
If I compile the whole module with no-strict-alias it runs correctly,
but the generated code is 3% bigger and I think runs significantly
slower (I can only approximate how fast the broken code runs).
It would be great to have some attribute one could define on a pointer
to say that pointer violates strict aliasing. The pointers described
above are actually used through another layer of pointer, which is
declared as a void**. In concept the code looks like:
Datatype* a;
void** x = malloc ...
(Datatype*&)(x[n]) = a;
void** y = malloc ...
y[n] = x[n];
Datatype* b;
b = (Datatype*&)(y[n]);
So if there were a way to put an attribute on x and y to say they
violate strict aliasing, that would be a perfect solution.
Alternately, if violation of strict aliasing could be applied to inline
function definitions, that might be reasonable (hopefully just applying
to the operations inside that function, not to the whole function into
which it gets inlined).
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 12:40 Any way to locally apply no-strict-alias? John Fine
@ 2008-10-09 12:48 ` Andrew Haley
2008-10-09 14:09 ` John Fine
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2008-10-09 12:48 UTC (permalink / raw)
To: John Fine; +Cc: gcc-help
John Fine wrote:
> I have a very large module, which contains a few places where a pointer
> is cast based on a templated data type.
>
> Typically a pointer is created using a templated type, then copied as a
> void*, then used as the templated type. In one of those places, the
> optimizer removes the copy step, which is correct behavior for the
> optimizer under strict aliasing, but of course incorrect for the program.
I don't really get this.
You are allowed to take a pointer, copy it as a void *, and copy it
back to the same type and dereference it. If the compiler removes
the copy step, then the compiler is broken. If your code accesses
the object via an incompatible type, then your code is broken.
Confused,
Andrew.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 12:48 ` Andrew Haley
@ 2008-10-09 14:09 ` John Fine
2008-10-09 16:58 ` Andrew Haley
0 siblings, 1 reply; 9+ messages in thread
From: John Fine @ 2008-10-09 14:09 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
Andrew Haley wrote:
> You are allowed to take a pointer, copy it as a void *, and copy it
> back to the same type and dereference it. If the compiler removes
> the copy step, then the compiler is broken. If your code accesses
> the object via an incompatible type, then your code is broken.
>
>
I think the difference between that and what I'm doing is the extra
level of indirection.
I write a Datatype* indirectly through a Datatype**. Then I read a
void* indirectly through a void** that happens to be the same pointer as
that Datatype**.
Next I do the reverse (write through void** to read through Datatype**).
You're saying I can copy a Datatype* to a void* then back to a Datatype*
and use it. That wouldn't be a violation of strict aliasing, because it
never dereferences two different type pointers to the same address.
I know my code is "broken". I didn't write it and I have no practical
way to rewrite it. I'm looking for a local work around to the problem.
I've looked at the generated assembler code and the copy step is
optimized out when compiled without -fno-strict-alias and isn't
optimized out when compiled with -fno-strict-alias.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 14:09 ` John Fine
@ 2008-10-09 16:58 ` Andrew Haley
2008-10-09 17:30 ` John Fine
0 siblings, 1 reply; 9+ messages in thread
From: Andrew Haley @ 2008-10-09 16:58 UTC (permalink / raw)
To: John Fine; +Cc: gcc-help
John Fine wrote:
> Andrew Haley wrote:
>> You are allowed to take a pointer, copy it as a void *, and copy it
>> back to the same type and dereference it. If the compiler removes
>> the copy step, then the compiler is broken. If your code accesses
>> the object via an incompatible type, then your code is broken.
>
> I think the difference between that and what I'm doing is the extra
> level of indirection.
>
> I write a Datatype* indirectly through a Datatype**. Then I read a
> void* indirectly through a void** that happens to be the same pointer as
> that Datatype**.
> Next I do the reverse (write through void** to read through Datatype**).
By my reckoning this should still work. Writing through the void**
will be fine. Casting &(void*) to Datatype** is the bit that won't
work. But you don't need to do that...
> You're saying I can copy a Datatype* to a void* then back to a Datatype*
> and use it. That wouldn't be a violation of strict aliasing, because it
> never dereferences two different type pointers to the same address.
OK, I now understand.
> I know my code is "broken". I didn't write it and I have no practical
> way to rewrite it. I'm looking for a local work around to the problem.
>
> I've looked at the generated assembler code and the copy step is
> optimized out when compiled without -fno-strict-alias and isn't
> optimized out when compiled with -fno-strict-alias.
OK, but you still haven't said what "the copy step" is.
We obviously don't want to start having a no-strict-alias attribute for
pointers. I think it's pointless because it would only apply to new
code, and the whole point of no-strict-alias is to make old code work.
Andrew.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 16:58 ` Andrew Haley
@ 2008-10-09 17:30 ` John Fine
2008-10-09 17:39 ` Andrew Haley
0 siblings, 1 reply; 9+ messages in thread
From: John Fine @ 2008-10-09 17:30 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
Andrew Haley wrote:
>
> We obviously don't want to start having a no-strict-alias attribute for
> pointers. I think it's pointless because it would only apply to new
> code, and the whole point of no-strict-alias is to make old code work.
>
>
>
I sure disagree with that.
How about making old code repairable.
It would be a monster task to rewrite old code to not need the problem
casts. It is a much more reasonable task to find all the pointers that
are used with problem casts. If you could just tack some attribute onto
the declaration of each such pointer, you could take a giant application
you don't even understand and repair it for this issue in under a day.
I think I've tricked the compiler into generating working code. I don't
think my correction is correct (I think I just confused the optimizer).
But I don't know enough about the exact rules of aliasing to be sure.
I made a union of void* and int*. And my basic pointer now points to
that union instead of being void**.
Then I never use the int* member of the union. What used to directly
use the void** now uses the void* member of the union. What used to use
the Datatye** cast of the void** now uses a Datatype** cast of the
address of the void* member of the union. That still means I'm casting
a void** to a Datatype**, but it seems to have changed the compiler's
understanding of it.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 17:30 ` John Fine
@ 2008-10-09 17:39 ` Andrew Haley
2008-10-09 18:13 ` John Fine
2008-10-09 19:34 ` John Breitenbach
0 siblings, 2 replies; 9+ messages in thread
From: Andrew Haley @ 2008-10-09 17:39 UTC (permalink / raw)
To: John Fine; +Cc: gcc-help
John Fine wrote:
> Andrew Haley wrote:
>>
>> We obviously don't want to start having a no-strict-alias attribute for
>> pointers. I think it's pointless because it would only apply to new
>> code, and the whole point of no-strict-alias is to make old code work.
>
> I sure disagree with that.
>
> How about making old code repairable.
>
> It would be a monster task to rewrite old code to not need the problem
> casts.
The hard part IME is finding the bad casts. Once you've done that it's
not so awfully hard to convert pointer casts to use unions instead.
Adding a no-strict-alias attribute solves the easy part, leaving the
hard part.
> It is a much more reasonable task to find all the pointers that
> are used with problem casts. If you could just tack some attribute onto
> the declaration of each such pointer, you could take a giant application
> you don't even understand and repair it for this issue in under a day.
>
> I think I've tricked the compiler into generating working code. I don't
> think my correction is correct (I think I just confused the optimizer).
> But I don't know enough about the exact rules of aliasing to be sure.
>
> I made a union of void* and int*. And my basic pointer now points to
> that union instead of being void**.
> Then I never use the int* member of the union. What used to directly
> use the void** now uses the void* member of the union. What used to use
> the Datatye** cast of the void** now uses a Datatype** cast of the
> address of the void* member of the union. That still means I'm casting
> a void** to a Datatype**, but it seems to have changed the compiler's
> understanding of it.
Why not make it a union of Datatype* and void* ?
Then you wouldn't need to cast at all.
Andrew.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 17:39 ` Andrew Haley
@ 2008-10-09 18:13 ` John Fine
2008-10-09 19:34 ` John Breitenbach
1 sibling, 0 replies; 9+ messages in thread
From: John Fine @ 2008-10-09 18:13 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
Andrew Haley wrote:
> Why not make it a union of Datatype* and void* ?
> Then you wouldn't need to cast at all.
>
>
Datatype is a template argument that is known at the time the casts are
instantiated but can't be known nor even used as a template argument at
the time the pointer (that was void** and now is my_union*) is
instantiated, nor at the point that the copying is done.
1) Allocate (using malloc for some stupid reason) a my_union[] at a
point where Datatype can't be known.
2) Fill that array with nulls
3) In code where Datatype is a template argument, pass various
Datatype*& from within that array to several routines which overwrite
some of those nulls.
4) Steps 1 and 2 for a different my_union[] (again can't know Datatype)
5) In other code that can't know Datatype, copy some void*'s from the
first array to the second. The optimizer discarded this code before my
change.
6) In code where Datatype is a template argument, pass Datatype*const&
from within the second array to several routines which use those
Datatype*'s.
Under strict aliasing, the void*'s copied in step 5 are never used, and
everything that touches the second array across its entire lifetime is
inlined into one place, so the compiler knows those void*'s are never used.
The Datatype*'s that exist at the same address as those void*'s are used.
Datatype is never int. The union tells the compiler that an int* exists
at the same address as the void*. Even though the compiler inlines
enough code to see the int* is never used, somehow this defeats the
optimization.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 17:39 ` Andrew Haley
2008-10-09 18:13 ` John Fine
@ 2008-10-09 19:34 ` John Breitenbach
2008-10-09 20:06 ` John Fine
1 sibling, 1 reply; 9+ messages in thread
From: John Breitenbach @ 2008-10-09 19:34 UTC (permalink / raw)
To: Andrew Haley; +Cc: gcc-help
Have you considered __attribute__ ((__may_alias__)) on the variable
declaration? I've used this on a structure
declaration which, coincidently, may alias another structure ... solved
my problem when upgrading from gcc 2.95 to 3.4.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Any way to locally apply no-strict-alias?
2008-10-09 19:34 ` John Breitenbach
@ 2008-10-09 20:06 ` John Fine
0 siblings, 0 replies; 9+ messages in thread
From: John Fine @ 2008-10-09 20:06 UTC (permalink / raw)
To: John Breitenbach; +Cc: Andrew Haley, gcc-help
John Breitenbach wrote:
> Have you considered __attribute__ ((__may_alias__)) on the variable
> declaration? I've used this on a structure
> declaration which, coincidently, may alias another structure ...
> solved my problem when upgrading from gcc 2.95 to 3.4.
>
Thanks. I looked through all the variable attributes and function
attributes (both C and C++) in the 4.1.2 documentation. I didn't
notice (until the google search of __may_alias__ I just did) that there
are also type attributes (section 5.32 of the documentation).
I'll need to experiment a bit to see if that makes a cleaner solution to
the problem and to see what the correct syntax would be.
If I understand the documentation, I could
typedef void* __attribute__((__may_alias__)) alias_ptr;
Then, after alias_ptr* x = malloc ..., I can mix accesses to
(Datatype*&)(x[n]) and x[n] without breaking aliasing rules?
after void** x = malloc ..., I can't mix accesses to (Datatype*&)(x[n])
and x[n], because the thing pointed to by a void** (unlike the thing
pointed to by a void*) is subject to the aliasing rules.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-10-09 20:06 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2008-10-09 12:40 Any way to locally apply no-strict-alias? John Fine
2008-10-09 12:48 ` Andrew Haley
2008-10-09 14:09 ` John Fine
2008-10-09 16:58 ` Andrew Haley
2008-10-09 17:30 ` John Fine
2008-10-09 17:39 ` Andrew Haley
2008-10-09 18:13 ` John Fine
2008-10-09 19:34 ` John Breitenbach
2008-10-09 20:06 ` John Fine
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).