<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jun 30, 2017 at 1:02 AM, Chandler Carruth via llvm-dev <span dir="ltr"><<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I have hit a fairly isolated practical issue deploying the new PM, but it does point to a latent theoretical issues as well. I see various ways to address it, but want feedback from others before moving forward.<div><br></div><div>The issue is that we can introduce out-of-thin-air calls to known library functions (`SimplifyLibCalls`, etc). These can be introduced in function passes (`InstCombine` in particular) and that seems highly desirable.</div><div><br></div><div>These all look like one of these cases:</div><div>1a) Introducing a new call to an LLVM intrinsic</div><div>1b) Replacing an existing call with a call to an LLVM intrinsic</div><div>2a) Introducing a new call to a declared library function (but not defined)</div><div>2b) Replacing an existing call with a call to a declared library function</div><div>3a) Introducing a new call to a defined library function</div><div>3b) Replacing an existing call with a call to a defined library function</div><div><br></div><div>Both #1 and #2 are easy to handle in reality. Intrinsics and declared functions don't impact the PM's call graph because there is no need to order the walk over them. But #3 is a real issue.</div><div><br></div><div>The only case I have found that actually hits #3 at all hits #3b when building FORTIFY code with the new pass manager because after inlining we do a lot of (really nice) optimizations on library calls to remove unnecessary FORTIFY checks. But this is in *theory* a problem when LTO-ing with libc. More likely it could be a problem when LTO-ing with a vector math library.</div><div><br></div><div>So what do we do?</div><div><br></div><div>My initial idea: find all *defined* library functions in the module, and every time we create a ref edge to one of them, synthesize a ref edge to all of them. This should completely solve #3b above. But it doesn't really address #3a at all.</div><div><br></div><div>Is that OK? It would be very convenient to say that if we want to introduce truly novel and new calls to library functions, we should have an LLVM intrinsic to model those routines.</div></div></blockquote><div><br></div><div>That seems reasonable, though it would in theory block inlining of, say, memset_pattern if we have a definition available when LTO'ing but that seems acceptable (and we already live with similar restrictions with other memory intrinsics anyway and I don't hear anyone complaining).</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>But we actually have an example (I think) of #3a, introducing a call to a library function out of the blue: memset_pattern. =/</div><div><br></div><div>The only way I see to reasonably handle #3a is to have *every* function implicitly contain a reference edge to every defined library function in the module. This is, needless to say, amazingly wasteful. Hence my email. How important is this?</div></div></blockquote><div><br></div><div>This seems like the simplest and most natural solution overall. Can you get some numbers on how wasteful it actually is? (and for the alternative approach)</div><div><br></div><div>Even if it ends up not being that wasteful and worth doing just for simplicity's sake, I do like the idea of "out-of-thin-air calls must be intrinsics".</div><div><br></div><div>-- Sean Silva</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><br></div><div>If we need to correctly handle this, I think I would probably implement this by actually changing the *iteration* of reference edges in the graph to just implicitly walk the list of defined library functions so that we didn't burn any space on this. But it will make iteration of reference edges slower and add a reasonable amount of complexity. So I'd like to hear some other opinions before going down either of these roads.</div><div><br></div><div><br></div><div>Thanks,</div><div>-Chandler</div></div>
<br>______________________________<wbr>_________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/<wbr>mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br></div></div>