<div dir="ltr">Hi Matt,<div><br></div><div>CCing the Dev list, as I accidentally dropped them off my last reply.</div><div><br></div><div>Regarding loadObject, that API is very much hypothetical at the moment (there is a RuntimeDyld::loadObject, but it returns something else). Some background may make it clearer where I'm thinking of going with this though:</div><div><br></div><div>MCJIT builds on RuntimeDyld. RuntimeDyld is responsible for making object files in memory (instances of llvm::object::ObjectFile) runnable. It does this by allocating memory for the sections, applying relocations, and providing symbol lookup. To a very rough approximation, MCJIT is just:</div><div><br></div><div>class MCJIT {</div><div>private:</div><div>  RuntimeDyld Dyld;</div><div>public:</div><div>  void* getSymbolAddress(StringRef Name) { return Dyld.getSymbolAddress(Name); }</div><div>  void addModule(Module *M) { Dyld.loadObject(CodeGenIRToObject(M)); }</div><div>};</div><div><br></div><div>All the interesting parts of MCJIT have to do with module ownership, setting up the CodeGen pipeline, etc.</div><div><br></div><div>If you're happy to handle codegen and module ownership yourself, you could actually talk to RuntimeDyld directly, rather than going through MCJIT. That's what I'm doing in that example, just for the sake of simplicity. For clients who want to keep using MCJIT we just need to add an API to get at the underlying Dyld state so that, if they want to, clients can inspect RuntimeDyld::JITObjects (these don't exist yet either, but are easy to add). Exactly what that API will look like I'm not sure yet. It may be as simple as 'RuntimeDyld::JITObject getJITObject(Module *M)' in the end.</div><div><br></div><div>So short version: The loadObject API in the example above doesn't exist yet, and even if it did you probably wouldn't want to use it. However, there's a plan to get this kind of information to JIT clients in the future.</div><div><br></div><div>On a related note, the demand for this kind of API usually comes from a desire to debug either the JIT or the JIT'd code. If we had a proper debugger registration system (i.e. a way to get relocated Dwarf to JIT clients and system debuggers), that could be used to find out most of the interesting things about relocated sections (including their, size, address, etc). This is also on the drawing board, but waiting for me to find time to do it.</div><div><br></div><div>Cheers,</div><div>Lang.</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Sep 18, 2014 at 1:11 PM, Matt Godbolt <span dir="ltr"><<a href="mailto:matt@godbolt.org" target="_blank">matt@godbolt.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Thanks Lang, I guessed as much.  I already have the MCDisassembler<br>
stuff all sorted (we're using it already with the JIT callback<br>
NotifyFunctionEmitted) and we do in fact use it for non-debug too<br>
(it's a one-time startup cost for us and it's useful to log to disc<br>
all this stuff to spot regressions etc).<br>
<br>
I really appreciate you taking the time to have a think about this for us :)<br>
<br>
I realise you're busy but if you have a second or two it seems both<br>
Philip and I are unaware of the loadObject() style way of JITting.<br>
We're also using the ExecutionEngine to build our code - can you point<br>
us both in the direction of how one might use the loadObject style,<br>
should you think it worthwhile?<br>
<br>
Cheers, Matt :)<br>
<div class="HOEnZb"><div class="h5"><br>
On Thu, Sep 18, 2014 at 1:46 PM, Lang Hames <<a href="mailto:lhames@gmail.com">lhames@gmail.com</a>> wrote:<br>
> Hi Matt,<br>
><br>
> "Disassemble" is just pseudocode there, but the MCDisassembler in LLVM does<br>
> have a reasonably friendly interface. You can look at the code in<br>
> tools/llvm-mc to see how it's used.<br>
><br>
> DEBUG is just a macro to wrap code so that it only executes for Debug<br>
> builds. My assumption was that you were disassembling for some sort of debug<br>
> dump (I've written things like that in the past for debugging the JIT<br>
> infrastructure). If this is functionality that you want to be compiled into<br>
> your project all the time you can just drop the reference to DEBUG.<br>
><br>
> - Lang.<br>
><br>
> On Thu, Sep 18, 2014 at 11:00 AM, Matt Godbolt <<a href="mailto:matt@godbolt.org">matt@godbolt.org</a>> wrote:<br>
>><br>
>> Hi Lang,<br>
>><br>
>> Thanks for the reply, I'm glad it sounds like you have a fairly simple<br>
>> suggested improvement.<br>
>><br>
>> I'm not too familiar with the inner workings of llvm, so apologies if<br>
>> this is a dumb question; what's the "Disassemble" and DEBUG() parts<br>
>> doing here?  Are these the in the user code? I don't interact with the<br>
>> RuntimeDyld directly anywhere in my code, so I'm not sure where this<br>
>> code would go. If it's user code and I can somehow get hold of a<br>
>> RuntimeDyld then this seems like a good match, as it seems pretty much<br>
>> what I'm doing in NotifyObjectEmitted already.<br>
>><br>
>> Cheers, Matt :)<br>
>><br>
>> On Thu, Sep 18, 2014 at 12:17 PM, Lang Hames <<a href="mailto:lhames@gmail.com">lhames@gmail.com</a>> wrote:<br>
>> > Hi Matt, Philip,<br>
>> ><br>
>> > You could get the data you want by recording the addresses returned by<br>
>> > the<br>
>> > allocateCodeSection and allocateDataSection methods on your<br>
>> > RTDyldMemoryManager, then disassembling those sections after you've<br>
>> > called<br>
>> > resolveRelocations. That's a little unsatisfying though. For one thing,<br>
>> > unless you very carefully maintain the association with the original<br>
>> > object<br>
>> > via back-channels there will be no way of knowing which section belongs<br>
>> > to<br>
>> > which object file.<br>
>> ><br>
>> > With a bit of cleanup though, we could do something more like this:<br>
>> ><br>
>> > const RuntimeDyld::JITObject& JO = RTDyld.loadObject(Object);<br>
>> > // ...<br>
>> > RTDyld.resolveRelocations();<br>
>> ><br>
>> > DEBUG(<br>
>> >   for (const RuntimeDyld::JITObject::Section& S : JO.sections())<br>
>> >     if (S.isText())<br>
>> >       Disassemble(S.getAddr(), S.getSize());<br>
>> > );<br>
>> ><br>
>> > How does that look?<br>
>> ><br>
>> > Cheers,<br>
>> > Lang.<br>
>> ><br>
>> ><br>
>> > On Wed, Sep 17, 2014 at 3:08 PM, Philip Reames<br>
>> > <<a href="mailto:listmail@philipreames.com">listmail@philipreames.com</a>><br>
>> > wrote:<br>
>> >><br>
>> >><br>
>> >> On 09/17/2014 12:45 PM, Matt Godbolt wrote:<br>
>> >>><br>
>> >>> Great stuff; thanks both!<br>
>> >>><br>
>> >>> I'm also looking to turn my MCJIT conversion spike into our main use<br>
>> >>> case. The only thing I'm missing is the ability to get a post-linked<br>
>> >>> copy of the generated assembly.<br>
>> >>><br>
>> >>> In JIT I used JITEventListener's NotifyFunctionEmitted and used a<br>
>> >>> MCDisassembler to disassemble the stream (with my own custom<br>
>> >>> annotators), and redirected the output to the relevant place for<br>
>> >>> auditing of our app.<br>
>> >>><br>
>> >>> With MCJIT I notice that NotifyFunctionEmitted is gone<br>
>> >>> (understandably) and so I hook NotifyObjectEmitted. I then run through<br>
>> >>> all the function symbols and dump them as before. Yay.  Except that in<br>
>> >>> MCJIT terms the linking hasn't happened, so all the globals and<br>
>> >>> external functions are all zeros at this point. (If I hackily observe<br>
>> >>> the same code later on I see the linker has appropriately populated<br>
>> >>> these addresses).  This makes my nicely annotated code a little<br>
>> >>> unreadable, unfortunately.<br>
>> >>><br>
>> >>> Does anyone have any suggestions as to how I might get to disassemble<br>
>> >>> the post-linked code?<br>
>> >><br>
>> >> my 2 cents: It seems like we need a different event type.  Having<br>
>> >> access<br>
>> >> to the object before linking (and relocation?) seems useful, but I<br>
>> >> suspect<br>
>> >> most users (myself included) want the final object after everything is<br>
>> >> done.<br>
>> >><br>
>> >> Philip<br>
>> >><br>
>> >><br>
>> >> On Wed, Sep 17, 2014 at 2:35 PM, Yaron Keren <<a href="mailto:yaron.keren@gmail.com">yaron.keren@gmail.com</a>><br>
>> >> wrote:<br>
>> >>>><br>
>> >>>> Hi,<br>
>> >>>><br>
>> >>>> You need to call llvm::sys::getHostCPUName() and pass the result to<br>
>> >>>> createTargetMachine() passed to the JIT. This patch should be<br>
>> >>>> applied:<br>
>> >>>><br>
>> >>>>   <a href="http://llvm.org/bugs/show_bug.cgi?id=17422" target="_blank">http://llvm.org/bugs/show_bug.cgi?id=17422</a><br>
>> >>>><br>
>> >>>> Anyhow, the JIT was removed from current code and will not be in next<br>
>> >>>> LLVM<br>
>> >>>> release.<br>
>> >>>><br>
>> >>>> Yaron<br>
>> >>>><br>
>> >>>><br>
>> >>>> 2014-09-17 22:27 GMT+03:00 Matt Godbolt <<a href="mailto:matt@godbolt.org">matt@godbolt.org</a>>:<br>
>> >>>>><br>
>> >>>>> Hi Jim,<br>
>> >>>>><br>
>> >>>>> Thanks for a very quick reply! That indeed does the trick!<br>
>> >>>>><br>
>> >>>>> Presumably the default has changed in 3.5 to be a "generic" CPU<br>
>> >>>>> instead of the native one? If that's the case I wonder why:<br>
>> >>>>> especially<br>
>> >>>>> when JITting it really only makes sense to target the actual CPU -<br>
>> >>>>> unless I'm missing something? :)<br>
>> >>>>><br>
>> >>>>> Thanks again,<br>
>> >>>>><br>
>> >>>>> Matt<br>
>> >>>>><br>
>> >>>>> On Wed, Sep 17, 2014 at 2:16 PM, Jim Grosbach <<a href="mailto:grosbach@apple.com">grosbach@apple.com</a>><br>
>> >>>>> wrote:<br>
>> >>>>>><br>
>> >>>>>> Hi Matt,<br>
>> >>>>>><br>
>> >>>>>> I suspect you need to specify the target CPU when you create the<br>
>> >>>>>> JIT.<br>
>> >>>>>> It’s just a method on the builder (e.g., builder.setMCPU(MCPU)). If<br>
>> >>>>>> you want<br>
>> >>>>>> auto-detection based on the host CPU, sys::getHostCPUName() returns<br>
>> >>>>>> a<br>
>> >>>>>> value<br>
>> >>>>>> suitable to be passed directly into the builder.<br>
>> >>>>>><br>
>> >>>>>> -Jim<br>
>> >>>>>><br>
>> >>>>>>> On Sep 17, 2014, at 11:44 AM, Matt Godbolt <<a href="mailto:matt@godbolt.org">matt@godbolt.org</a>><br>
>> >>>>>>> wrote:<br>
>> >>>>>>><br>
>> >>>>>>> Hi guys,<br>
>> >>>>>>><br>
>> >>>>>>> I just upgraded our JIT system to use llvm 3.5 and noticed one big<br>
>> >>>>>>> change in our generated code: we don't see any non-destructive VEX<br>
>> >>>>>>> prefix instructions being emitted any more (vmulsd xmm0, xmm1,<br>
>> >>>>>>> blah)<br>
>> >>>>>>> etc.<br>
>> >>>>>>><br>
>> >>>>>>> It's long been on my list of things to investigate anyway as I<br>
>> >>>>>>> noticed<br>
>> >>>>>>> llvm didn't emit VZEROUPPER calls either, so I supposed it might<br>
>> >>>>>>> not<br>
>> >>>>>>> be a bad thing to disable vex.<br>
>> >>>>>>><br>
>> >>>>>>> That being said, try as I might I can't force avx on<br>
>> >>>>>>> (builder.setMCPU("core-avx-i") and/or<br>
>> >>>>>>> builder.setMAttrs(vector<string>{"+avx"});). We're still using the<br>
>> >>>>>>> old<br>
>> >>>>>>> JIT but I just spiked out a move to MCJIT and I still don't see<br>
>> >>>>>>> the<br>
>> >>>>>>> VEX instructions.<br>
>> >>>>>>><br>
>> >>>>>>> Was there a deliberate change on the llvm-side to discourage VEX<br>
>> >>>>>>> instructions unless they make a big enough difference (and/or is<br>
>> >>>>>>> VZEROUPPER now emitted?).<br>
>> >>>>>>><br>
>> >>>>>>> If not, how might I go about digging further into this?<br>
>> >>>>>>><br>
>> >>>>>>> Many thanks in advance, Matt<br>
>> >>>>>>><br>
>> >>>>>>> --<br>
>> >>>>>>> Matt<br>
>> >>>>>>> _______________________________________________<br>
>> >>>>>>> LLVM Developers mailing list<br>
>> >>>>>>> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
>> >>>>>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
>> >>>>><br>
>> >>>>><br>
>> >>>>><br>
>> >>>>> --<br>
>> >>>>> Matt<br>
>> >>>>><br>
>> >>>>> _______________________________________________<br>
>> >>>>> LLVM Developers mailing list<br>
>> >>>>> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
>> >>>>> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
>> >>>><br>
>> >>>><br>
>> >>><br>
>> >>><br>
>> >><br>
>> >> _______________________________________________<br>
>> >> LLVM Developers mailing list<br>
>> >> <a href="mailto:LLVMdev@cs.uiuc.edu">LLVMdev@cs.uiuc.edu</a>         <a href="http://llvm.cs.uiuc.edu" target="_blank">http://llvm.cs.uiuc.edu</a><br>
>> >> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev</a><br>
>> ><br>
>> ><br>
>><br>
>><br>
>><br>
>> --<br>
>> Matt<br>
><br>
><br>
<br>
<br>
<br>
</div></div><span class="HOEnZb"><font color="#888888">--<br>
Matt<br>
</font></span></blockquote></div><br></div>