<div dir="ltr">Ah! Okay then, so you are saying something substantive that I think I disagree with, but that could be because there are relevant issues I don't understand.<div><br></div><div>My reasoning is, I've already got a pointer to the function I want the generated code to call, so I just supply that pointer, it looks ugly on a microscopic scale because there are a couple of lines of casts to shepherd it through the type system, but on an even slightly larger scale it's as simple and elegant as it gets: I supply a 64-bit machine word that gets compiled into the object code, there are no extra layers of machinery to go wrong, no nonlocal effects to understand, no having to wonder about whether anything depends on symbol information that might vary between debug and release builds or between the vendor compiler and clang or between Windows and Linux; if it works once, it will work the same way every time. As a bonus, it will compile slightly faster.</div><div><br></div><div>Keeping things symbolic - you're saying the advantage is the intermediate code is easier to debug because a dump will say 'call print' instead of 'call function at 123456'? I can see that being a real advantage but as of right now it doesn't jump out at me as necessarily outweighing the advantages of the direct pointer method.</div><div><br></div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 29, 2016 at 4:37 AM, Philip Reames <span dir="ltr"><<a href="mailto:listmail@philipreames.com" target="_blank">listmail@philipreames.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="auto"><div>I think our use cases are actually quite similar.  Part of generating the in memory executable code is resolving all the symbolic symbols and relocations.  The details of this are mostly hidden from you by the MCJIT interface, but it's this step I was referring to as "link time".  </div><div><br></div><div>The way to think of MCJIT: generate object file, incrementally link, run dynamic loader, but do it all in memory without round tripping through disk or explicit files.  </div><span class="HOEnZb"><font color="#888888"><div><br></div><div>Philip<br><br><br></div></font></span><div><div class="h5"><div><br>On Mar 28, 2016, at 7:25 PM, Russell Wallace <<a href="mailto:russell.wallace@gmail.com" target="_blank">russell.wallace@gmail.com</a>> wrote:<br><br></div><blockquote type="cite"><div><div dir="ltr">Right, but when you say link time, the JIT compiler I'm writing works the way openJDK or v8 do, it reads a script, JIT compiles it into memory and runs the code in memory without ever writing anything to disk (an option for ahead of time compilation may come later, but that will be a while down the road), so we might be doing different things?</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Mar 29, 2016 at 2:59 AM, Philip Reames <span dir="ltr"><<a href="mailto:listmail@philipreames.com" target="_blank">listmail@philipreames.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
  
    
  
  <div text="#000000" bgcolor="#FFFFFF">
    The option we use is to have a custom memory manager, override the
    getPointerToNamedFunction function, and provide the pointer to the
    external function at link time.  The inttoptr scheme works fairly
    well, but it does make for some pretty ugly and sometimes hard to
    analyze IR.  I recommend leaving everything symbolic until link time
    if you can.<br>
    <br>
    Philip<div><div><br>
    <br>
    <div>On 03/28/2016 06:33 PM, Russell Wallace
      via llvm-dev wrote:<br>
    </div>
    </div></div><blockquote type="cite"><div><div>
      <div dir="ltr">That seems to work, thanks! The specific code I
        ended up with to call int64_t print(int64_t) looks like:
        <div><br>
        </div>
        <div>
          <div>        auto f = builder.CreateIntToPtr(</div>
          <div>            ConstantInt::get(builder.getInt64Ty(),
            uintptr_t(print)),</div>
          <div>            PointerType::getUnqual(FunctionType::get(</div>
          <div>                builder.getInt64Ty(),
            {builder.getInt64Ty()}, false)));</div>
          <div>        return builder.CreateCall(f, args);</div>
        </div>
        <div><br>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Mon, Mar 28, 2016 at 1:40 PM,
          Caldarale, Charles R <span dir="ltr"><<a href="mailto:Chuck.Caldarale@unisys.com" target="_blank"></a><a href="mailto:Chuck.Caldarale@unisys.com" target="_blank">Chuck.Caldarale@unisys.com</a>></span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">> From:
            llvm-dev [mailto:<a href="mailto:llvm-dev-bounces@lists.llvm.org" target="_blank">llvm-dev-bounces@lists.llvm.org</a>]<br>
            > On Behalf Of Russell Wallace via llvm-dev<br>
            > Subject: [llvm-dev] JIT compiler and calls to existing
            functions<br>
            <div>
              <div><br>
                > In the context of a JIT compiler, what's the
                recommended way to generate a call to an<br>
                > existing function, that is, not one that you are
                generating on-the-fly with LLVM, but<br>
                > one that's already linked into your program? For
                example the cosine function (from the<br>
                > standard math library); the Kaleidoscope tutorial
                recommends looking it up by name with<br>
                > dlsym("cos"), but it seems to me that it should be
                possible to use a more efficient and<br>
                > portable solution that takes advantage of the fact
                that you already have an actual pointer<br>
                > to cos, even if you haven't linked with debugging
                symbols.<br>
                <br>
              </div>
            </div>
            Perhaps not the most elegant, but we simply use the
            IRBuilder.CreateIntToPtr() method to construct the Callee
            argument for IRBuilder.CreateCall().  The first argument for
            CreateIntToPtr() comes from ConstantInt::get(I64,
            uintptr_t(ptr)), while the second is a function type pointer
            defined by using PointerType::get() on the result of
            FunctionType::get() with the appropriate function signature.<br>
            <br>
             - Chuck<br>
            <br>
          </blockquote>
        </div>
        <br>
      </div>
      <br>
      <fieldset></fieldset>
      <br>
      </div></div><pre>_______________________________________________
LLVM Developers mailing list
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a>
</pre>
    </blockquote>
    <br>
  </div>

</blockquote></div><br></div>
</div></blockquote></div></div></div></blockquote></div><br></div>