<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><br><div><div>On Apr 9, 2014, at 2:06 AM, Jeremy Lakeman <<a href="mailto:Jeremy.Lakeman@gmail.com">Jeremy.Lakeman@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div dir="ltr">On Mon, Apr 7, 2014 at 5:37 PM, Andrew Trick <span dir="ltr"><<a href="mailto:atrick@apple.com" target="_blank">atrick@apple.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5"><br>
</div></div>I agree with Filip that implementing null checks as trapping loads is essentially a minor code-size optimization that is typically not worthwhile. However, my point is that this decision should not be made at IR level.<br>

<br>
It could make sense to have a null check intrinsic that encapsulates and+cmp+br+invoke. I just don't like the idea of it subsuming the load/store. I think that will complicate both null check optimization and load/store optimization.<br>

<br>
Whether the null check can be profitably implemented as a trapping load/store is specific to the target platform. This decision should be independent of optimization in the presence of null checks and independent of optimization of the null checks themselves. It is purely a codegen issue.<br>

<br>
Imagine someone else porting your frontend to a new platform. They should not be required to implement trapping loads/stores to achieve a working system. And either way, they should benefit from the same platform independent optimization.<br>
</blockquote><div><br></div><div>Integer type legalisation, vector math... There's plenty of existing language features you don't have to implement, just run passes to simplify the IR first. <br>I'm also thinking particularly of how ecmascripten and pnacl are implemented.<br>
</div></div><br></div><div class="gmail_extra">If the IR changes (and I'm not taking a position on that issue), we just need a pass to transform the IR for back ends that don't wish to implement it.<br></div></div>
</blockquote></div><br><div>Good point. Let me put it this way, I don’t want trapping loads/stores to be an IR feature, but I think someone should be able to add them as a codegen feature. Every runtime needs to be able to handle explicit null checks. Only in a rare platform-specific case would someone want to also support implicit null checks via trapping loads/stores.</div><div><br></div><div>Actually, the most important thing to keep in mind here is that we don’t want to add new instructions to the LLVM language unless there is a very widespread, compelling need, and we want optimization passes to be explicitly aware of them by default. That’s where intrinsics come in.</div><div><br></div><div>Now, the question is, what should a null check intrinsic look like? We could introduce two:</div><div>(1) llvm.nullcheck that just encapsulates the check+trap</div><div>(2) llvm.load/store.nullchecked does check+load/store+trap.</div><div><br></div><div>At the IR optimization level, I think it’s potentially useful to have llvm.nullcheck. Although I think it should be lowered to canonical IR instructions and control flow early in the optimization pipeline.</div><div><br></div><div>I can see how a llvm.load/store.nullchecked could facilitate machine code generation. A frontend would be free to generate this intrinsic directly, but I think it would inhibit optimization. I better option would be for a codegen pass to fold loads/stores into null checks after the null checks have been optimized. Although even that has it’s drawbacks, as AliasAnalysis would need to be taught about the intrinsic. In terms of the best phase ordering, this optimization belongs in the instruction scheduler, but that’s not really practical.</div><div><br></div><div>-Andy</div></body></html>