<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On 7 November 2013 18:05, Johannes Pfau <span dir="ltr"><<a href="mailto:nospam@example.com" target="_blank">nospam@example.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Am Thu, 7 Nov 2013 16:14:59 +0000<br>
schrieb Iain Buclaw <<a href="mailto:ibuclaw@ubuntu.com">ibuclaw@ubuntu.com</a>>:<br>
<div class="im"><br>
> On 3 November 2013 10:20, Johannes Pfau <<a href="mailto:nospam@example.com">nospam@example.com</a>> wrote:<br>
><br>
</div><div><div class="h5">> > Am Sun, 3 Nov 2013 02:10:20 +0000<br>
> > schrieb Iain Buclaw <<a href="mailto:ibuclaw@ubuntu.com">ibuclaw@ubuntu.com</a>>:<br>
> ><br>
> > > last time I<br>
> > > checked, returning 0 disables aliasing rules from taking effect.<br>
> ><br>
> > That should work. Alias set 0 is a special alias set which conflicts<br>
> > with everything. I'll check if it works as expected.<br>
> ><br>
><br>
><br>
</div></div><div class="im">> This is taken from hunks in the 2.064 merge I'm testing:<br>
><br>
> Pastebin link here:  <a href="http://pastebin.com/jxQQL68N" target="_blank">http://pastebin.com/jxQQL68N</a><br>
><br>
<br>
</div>Some probably stupid questions about this patch:<br>
<div class="im"><br>
// If the type is a dynamic array, use the alias set of the basetype.<br>
<br>
</div>What exactly does happen in that case? The Tarray type is the<br>
two-field type consisting of length and ptr, right? Currently<br>
TypeDArray->toCtype constructs a two_field_type with size_t and<br>
typeof(Element)*. So according to the C aliasing rules, the TypeDArray<br>
alias set does already conflict with size_t and Element*. It does not<br>
conflict with Element. But I don't know why it should conflict with<br>
Element if we're talking about the slice type here. It would<br>
allow code like this to work: "char[] a; char* b = (cast(char*)&a)" but<br>
I don't see why this should work, it's illegal anyway?<br>
<br></blockquote><div><br></div><div>That would be seen as two distinct alias sets that would break strict aliasing in that example.<br></div><div><br></div><div>Though, will have to implement -Wstrict-aliasing in the front-end to get any feel for what could potentially be utterly wrong.  But the idea is that for dynamic arrays, telling gcc to not rely on structural equality to determine whether or not two dynamic arrays are part of the same alias set.<br>
<br>eg:<br>byte[] a, long[] b = *(cast (long[]*)&a) should be seen as being different alias sets, and so *will* be about breaking strict aliasing.<br><br>In contrast, string[] a, char[] b = *cast(string[]*)&a) should be seen as being part of the same alias set, and so the compiler must know that the two types (which are distinct structures to the backend) could potentially be referencing the same slice of memory, as to not cause any problems.<br>
<br></div><div>For people trying to work around the cast system for dynamic arrays, IMO they should be punished for it, and told to do it in the correct way that invokes _d_arraycopy, or do their unsafe work through unions.<br>
</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
Also, AFAICS it does not help with the problem in std.algorithm:<br>
char[] a;<br>
//cast(ubyte[])a generates:<br>
*cast(ubyte[]*)&a;<br>
<br>
Do you think this cast should be illegal in D?<br>
I think if we want to support strict aliasing for the code above we'll<br>
have to do what gcc does for pointers:<br>
<a href="http://code.metager.de/source/xref/gnu/gcc/gcc/alias.c#819" target="_blank">http://code.metager.de/source/xref/gnu/gcc/gcc/alias.c#819</a><br>
Put all array slices - regardless of element type - into the same alias<br>
set and make size_t and void* subsets of this alias set.<br>
<div class="im"><br>
<br>
// Permit type-punning when accessing a union<br>
<br>
</div>Isn't that already guaranteed by GCC? See:<br>
<a href="http://code.metager.de/source/xref/gnu/gcc/gcc/alias.c#982" target="_blank">http://code.metager.de/source/xref/gnu/gcc/gcc/alias.c#982</a><br>
Unions have all their member types added as subsets. So as long as the<br>
reference is through the union GCC knows the union type and it'll<br>
conflict with all member types.<br>
<br></blockquote><div><br></div><div>There is no harm enforcing it in the front-end as well, even if it is just there to speed up the process of returning what the backend will no doubt return too.  There's also the (extremely) unlikely event that the guarantee by GCC might be removed in a later version.<br>
</div><div> <br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<br>
But even if we make those changes to aliasing rules, we'll have to fix<br>
many places in phobos. For example:<br>
<a href="https://github.com/D-Programming-Language/phobos/blob/master/std/math.d#L1965" target="_blank">https://github.com/D-Programming-Language/phobos/blob/master/std/math.d#L1965</a><br>
real value;<br>
ushort* vu = cast(ushort*)&value;<br>
AFAICS this will always be invalid with strict aliasing.<br>
<br></blockquote><div><br></div><div>Yep, as it should be.  std.math is a danger point for type punning between pointers and reals, ensuring that type-punning/casting does not get DCE'd, etc...  This needs to be fixed.<br>
<br><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
<a href="https://github.com/D-Programming-Language/phobos/blob/master/std/uuid.d#L468" target="_blank">https://github.com/D-Programming-Language/phobos/blob/master/std/uuid.d#L468</a><br>
casts ubyte[16]* to size_t* also illegal, AFAICS.<br>
<br>
Are there any statistics about the performance improvements with strict<br>
aliasing? I'm not really sold on the idea of strict aliasing, right now<br>
it looks to me as if it's mainly a way to introduce subtle, hard to<br>
debug and often latent bugs (As whether you really see a problem<br>
depends on optimization)<br>
<br>
<a href="http://stackoverflow.com/questions/1225741/performance-impact-of-fno-strict-aliasing" target="_blank">http://stackoverflow.com/questions/1225741/performance-impact-of-fno-strict-aliasing</a><br>
</blockquote></div><br></div><div class="gmail_extra">Not that I'm aware of (other than Ada boasting it's use).  But I'd like to push the opinion of - although it isn't in the spec, D should be strict aliasing.  And people should be aware of the problems breaking strict aliasing (see: <a href="http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html">http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html</a> )<br>
<br>But first... plan of attack:<br><br>- We first disable strict aliasing entirely (lang_hook.get_alias_set => 0)<br>- Implement -Wstrict-aliasing<br>- Start turning on strict aliasing for types guaranteed not to be referencing the same memory location as other types (eg: TypeBasic, TypeDelegate, TypeSArray, TypeVector).<br>
</div><div class="gmail_extra">- Identify gdc problems with implicit code generation that could break strict aliasing (these are our bugs).<br></div><div class="gmail_extra">- Identify frontend/library problems that could break strict aliasing (these are the dmd/phobos developer's bugs).<br>
</div><div class="gmail_extra">- Turn on strict aliasing for the remaining types.  For those that cause problems, we can define a TYPE_LANG_FLAG macro to allow us to tell the backend if the type can alias any other types.<br>
</div><div class="gmail_extra"><br><br></div><div class="gmail_extra">I still stand by what I say on aliasing rules of D:<br></div><div class="gmail_extra">- Permit type-punning when accessing through a union<br></div><div class="gmail_extra">
- Dynamic arrays of the same basetype (regardless of qualifiers) may alias each other/occupy the same slice of memory.<br><br></div><div class="gmail_extra">Other possible considerations:<br><br></div><div class="gmail_extra">
- Most D code pretty much assumes that any object may be accessed via a void[] or void*.<br><br clear="all"></div><div class="gmail_extra">- C standard allows aliasing between signed and unsigned variants.  It is therefore likely not unreasonable to do the same for convenience.<br>
<br></div><div class="gmail_extra">- Infact, for the consideration of std.math.  It we could go one step further and simply build up an alias set list based on the type size over type distinction.  In this model double/long/byte[8]/short[4]/int[2] would all be considered as types that could be referencing each other.<br>
</div><div class="gmail_extra"><br>-- <br>Iain Buclaw<br><br>*(p < e ? p++ : p) = (c & 0x0f) + '0';
</div></div>