<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi Matthijs,<div><br></div><div><div><blockquote type="cite"><div><font class="Apple-style-span" color="#000000"><br></font></div></blockquote><blockquote type="cite"><div><blockquote type="cite"><blockquote type="cite">Specifically, I would  like instcombining to be able to use this info to<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">remove useless  bitcasts. Also, this information is useful for clang to<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">know when inserting an  implicit cast makes sense and when it would be an<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">error.<br></blockquote></blockquote><blockquote type="cite">Clang should just reject implicit casts in *any* case when the addr  <br></blockquote><blockquote type="cite">spaces differ IMO.  In any case, clang has it's own parameterization  <br></blockquote><blockquote type="cite">of the target which is richer than TargetData already, so if it really  <br></blockquote><blockquote type="cite">wanted to allow implicit casts between address space subsets, it could  <br></blockquote><blockquote type="cite">do so based on its own info.<br></blockquote>I think that adding this info to Clang's targetinfo code would indeed make<br>sense, though perhaps disallowing implicit casts entirely is also acceptable<br>(provided that you can still do explicit casts).<br><br></div></blockquote><div><br></div><div>Like most other type qualifier, explicit casts are allowed.  However, if some one uses it in a context which is illegal, the result is undefined (e.g.,., cast a pointer from one space to another one address and then uses it where the address spaces don't overlap).  The C99 extension  indicates that a cast of a pointer to one address space to another is valid only if the object that pointer points to exists in both address spaces (otherwise, the result is undefined). I think we all agree that the default behavior in clang should reject implicit casts between address spaces unless clang has some additional information to know better.</div><div><br></div><blockquote type="cite"><div>However, what I find more important (this discussion is greatly helping me in<br>finding out what exactly it is that I find important :-p) is that instcombine<br>(or some other pass, for all I care) can remove bitcasts that are not strictly<br>needed.<br><br>I will focus on address spaces that are nested, since that is the most<br>interesting and general case. Say we have address spaces SubA, SubB and Super, and<br>SubA and SubB are subsets of Super (but disjoint to each other).<br><br>When is bitcast between address spaces really needed? I can see two main<br>reasons.<br> 1) A function gets passed pointers into both SubA and SubB (which then need<br>    to be bitcasted to pointer-into-Super).<br> 2) A pointer variable is assigned pointers into both SubA and SubB. In LLVM<br>    this would probably mean a phi node that joins pointers into different<br><span class="Apple-tab-span" style="white-space:pre">       </span><span class="Apple-tab-span" style="white-space:pre">    </span>address spaces (which is not possible, hence a bitcast is needed and the<br><span class="Apple-tab-span" style="white-space:pre">  </span><span class="Apple-tab-span" style="white-space:pre">    </span>phi node would be of type pointer-into-super).<br><br>However, after some transformations (mainly code duplication AFAICS), the<br>above situations might get removed, making the bitcasts redundant. The patch I<br>attached a few posts back implements this by removing the bitcast when<br>possible. This does mean that any users of the bitcast now have one of their<br>operands changed (the address space gets changed).<br><br>Take for example a load instruction, that directly uses a bitcasted pointer.<br><br>When removing the bitcast, the load instruction can be replaced by a new one<br>that takes a pointer into another (smaller) address space. The result of the<br>load instruction will still be the same value, but a bitcast was removed (and<br>the load instruction was possibly improved as well).<br><br>Let's look at two use cases I can see for nested address spaces.<br><br> 1) Different address spaces translate to different accessing instructions at<br>    code generation time. Instructions that access smaller address spaces<br><span class="Apple-tab-span" style="white-space:pre">   </span><span class="Apple-tab-span" style="white-space:pre">    </span>(SubA, SubB) can execute faster than instructions that access the Super<br><span class="Apple-tab-span" style="white-space:pre">   </span><span class="Apple-tab-span" style="white-space:pre">    </span>address space. Because of this, removing unneeded bitcasts to Super (and<br><span class="Apple-tab-span" style="white-space:pre">  </span><span class="Apple-tab-span" style="white-space:pre">    </span>then replacing, for example, load instructions with their SubA or SubB<br><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span>variants) can result in faster code. This is currently not our use case,<br><span class="Apple-tab-span" style="white-space:pre">  </span><span class="Apple-tab-span" style="white-space:pre">    </span>but depending on where our hardware design goes might become so.<br> </div></blockquote><br><blockquote type="cite"><div>2) Having the Super address space as an address space that is usable in the<br><span class="Apple-tab-span" style="white-space:pre">        </span><span class="Apple-tab-span" style="white-space:pre">    </span>input C code, but should be optimized away before it hits the backend.<br><span class="Apple-tab-span" style="white-space:pre">    </span><span class="Apple-tab-span" style="white-space:pre">    </span>Removing those redundant bitcasts allows us to prevent a lot of code<br><span class="Apple-tab-span" style="white-space:pre">      </span><span class="Apple-tab-span" style="white-space:pre">    </span>duplication or ugly macro use in our C code, while still ending up with<br><span class="Apple-tab-span" style="white-space:pre">   </span><span class="Apple-tab-span" style="white-space:pre">    </span>code our backend can compile. This is our current use case.<br><br>For both these use cases, it would be needed to remove redundant bitcasts. To<br>be able to do that, the transformation passes (or at least the one the will do<br>this) needs to know the relations between the different address spaces.<br><br></div></blockquote><div><br></div><div>I would imagine that such a cleanup phase will probably need to track what objects a pointer can point to in some region of code so it can either remove redundant casts or add a cast to refine the information of what a pointer can point to.</div><br><blockquote type="cite"><div>At the very least, redundant bitcasts should be removed. It hacked up a patch<br>to make instcombine do this, but that only makes sense if removing those<br>bitcasts allows instcombine to do further optimizations, which again allows<br>bitcasts to be removed. I have the feeling that propagating address spaces<br>might be quite orthogonal to the other transformations instcombine does, so a<br>seperate pass for just this might be better.<br><br>I think the main question here is, are there any other transformations that<br>would need (or benefit from) information on address space relations? If not,<br>then it might be sufficient to pass an "AddressSpacesDescriptor" to just that<br>one pass.</div></blockquote><div> </div><div>Alias analysis could use the information to help determine if two pointer aliases.  As you indicated, a cleanup phases could use the information.  I don't think most other phases care as what they want to know is what address space a pointer points to and not the relationship about the address spaces.  </div><div><br></div><div><br></div><blockquote type="cite"><div>If there are other transformations, it would be useful to have one central<br>place to store this information (like TargetData now).<br><br>I've only just realized that this is an essential question, so I haven't given<br>it too much thought yet.<br><br><br>In either case, we should wonder in what way this information is given to the<br>tools (opt/llc). If we make it dependent on the target architecture, this only<br>becomes an issue once we support an architecture where this is relevant.<br>Alternatively, we could have some way of specifying the relations on the<br>commandline (either directly or by choosing between a number of models). Which<br>of these is chosen (if any) would not be too relevant for us, since we have<br>our own compiler driver which can pass anything to the (instcombine or other)<br>pass in a hardcoded fashion.<br></div></blockquote><div><br></div><div>IMO, I would think that address space relationship is based on the target architecture so it seems most natural to associate with the target.  </div><div><br></div><div>Regards,</div><div>  -- Mon Ping</div></div></div></body></html>