<div dir="ltr"><br><div class="gmail_extra">+cc Artem, who added the LinkOnlyNeeded flag.</div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 20, 2016 at 9:18 AM, Mehdi Amini 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 style="word-wrap:break-word">Hi Neil,<div><br><div><span class=""><blockquote type="cite"><div>On Apr 20, 2016, at 5:20 AM, Neil Henning via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:</div><br><div>
  

    
  
  <div text="#000000" bgcolor="#FFFFFF">
    TL;DR - when linking from a lazily loaded module and using
    Linker::LinkOnlyNeeded, bodies of used functions aren't being copied
    during linking.<br>
    <br>
    Previously on one of our products, we would lazily load our runtime
    module (around 9000 functions), and link some user module into this
    (which is in all practical use cases much smaller).</div></div></blockquote><div><br></div></span><div>It sounds reverse to what I would intuitively do (i.e. load the runtime into my module).</div><span class=""><br><blockquote type="cite"><div><div text="#000000" bgcolor="#FFFFFF"> Then, post
    linking, we have a pass that runs over the module and rips out all
    the un-materialized functions that weren't being used in the
    original user module.<br>
    <br>
    I only just noticed that LinkModules has a flags parameter that can
    take a LinkOnlyNeeded flag, which made me wonder if I could reverse
    the link order (EG. link from the lazily loaded runtime module into
    the user module), set the LinkOnlyNeeded flag, and hey presto, we
    wouldn't need to have a cleanup pass that ran afterwards ripping out
    functions that weren't used.<br>
    <br>
    So I tried it, and it failed. Basically any function that was still
    to be materialized wasn't getting its body copied over during
    linking.<br>
    <br>
    The only line of code that differs when you set LinkOnlyNeeded is in
    LinkModules.cpp -> ModuleLinker::linkIfNeeded:<br>
    <br>
    <pre>if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration()))
    return false;
</pre>
    <br>
    The isDeclaration() for functions has a call to isMaterializable().<br>
    <br>
    Things I've tried:<br>
    <ul>
      <li>If I don't pass LinkOnlyNeeded but still link from the lazily
        loaded runtime module into the user module, it works (albeit it
        is orders of magnitude slower like we'd expect).</li>
      <li>If I don't lazily load the runtime module, it works (but
        again, much slower).</li>
      <li>I tried doing the linking and then materializing the newly
        linked module, but the runtime functions were still missing
        their bodies (which implies the information was lost during
        linking).<br>
      </li>
      <li>If I hack the LinkModules.cpp code such that it checks if the
        DGV could be materialized, and if so materialize it, before
        checking for a declaration again, it works:</li>
    </ul>
    <pre>if (shouldLinkOnlyNeeded() && !(DGV && DGV->isDeclaration())) {
    if (DGV && DGV->isMaterializable())
        DGV->materialize();

    if (!(DGV && DGV->isDeclaration()))
        return false;
}
</pre></div></div></blockquote><div><br></div></span><div>DGV is the GlobalValue in the *destination* Module, it is not clear to me how materializing has an effect on the *source* Module.</div><div>I am probably missing something here...</div></div></div></div></blockquote><div><br></div><div>I think the difference here is that the destination module is being lazy loaded, whereas I typically see the source modules being lazily loaded. So it sounds like the issue is that DGV has not *yet* been materialized in the dest module, and therefore DGV->isDeclaration() is returning false, leading the linkIfNeeded to return false, despite the fact that if we did materialize DGV it would be a declaration and would decide to link in SGV.</div><div><br></div><div>Not sure that this usage mode of lazy loading has been tested before. As Mehdi says, Rafael may have more insight.</div><div><br></div><div>Teresa</div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word"><div><div><span class=""><br><blockquote type="cite"><div><div text="#000000" bgcolor="#FFFFFF"><p>Even with the extra cost of the hack above - this has resulted in
      a 2x speedup in our total link time.<br>
    </p><p>So really here I am wondering - is this expected behaviour? A
      bug? And if so how best to go about fixing the issue would be some
      grand advice from people more in the know!<br></p></div></div></blockquote></span><div>The linker was written before Module was lazy loaded I think. Many pieces in LLVM assume things their working on are materialized.</div><div>On a side note (a bit off-topic), I wonder if `isDeclaration()` should return false for materializable function?</div><div><br></div><div>CC Rafael, who knows this code better.</div><span class="HOEnZb"><font color="#888888"><div><br></div><div>-- </div><div>Mehdi</div><div><br></div><div><br></div></font></span></div></div></div><br>_______________________________________________<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/mailman/listinfo/llvm-dev</a><br>
<br></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature"><span style="font-family:Times;font-size:medium"><table cellspacing="0" cellpadding="0"><tbody><tr style="color:rgb(85,85,85);font-family:sans-serif;font-size:small"><td nowrap style="border-top-style:solid;border-top-color:rgb(213,15,37);border-top-width:2px">Teresa Johnson |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(51,105,232);border-top-width:2px"> Software Engineer |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(0,153,57);border-top-width:2px"> <a href="mailto:tejohnson@google.com" target="_blank">tejohnson@google.com</a> |</td><td nowrap style="border-top-style:solid;border-top-color:rgb(238,178,17);border-top-width:2px"> 408-460-2413</td></tr></tbody></table></span></div>
</div></div>