Zoltan Varga
2009-Dec-15 09:05 UTC
[LLVMdev] code generation for calls in JITted code after r88984
Hi, After this commit: http://llvm.org/viewvc/llvm-project?view=rev&revision=88984 the X86 JIT no longer emits calls using call <ADDR>, but always uses mov REG, <ADDR>, call *REG. This causes problems for the usage of LLVM in JITs since the JIT can no longer patch the callsite after the callee have been compiled. According to the comments for the commit, this was done to fix the large code model on amd64, but this affects JITs which can guarantee that both the caller and callee have 32 bit addresses, since the code model is set uncoditionally to Large, even if another code model was passed to createJIT (): http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?r1=86251&r2=88984&pathrev=88984 Would it be possible to fix this or make it configurable ? thanks Zoltan -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20091215/792d6a95/attachment.html>
Reid Kleckner
2009-Dec-15 18:34 UTC
[LLVMdev] code generation for calls in JITted code after r88984
On Tue, Dec 15, 2009 at 4:05 AM, Zoltan Varga <vargaz at gmail.com> wrote:> Hi, > > After this commit: > http://llvm.org/viewvc/llvm-project?view=rev&revision=88984 > > the X86 JIT no longer emits calls using call <ADDR>, but always uses mov > REG, <ADDR>, call *REG. This causes problems for the usage of LLVM in JITs > since the JIT can no longer patch the callsite after the callee have been > compiled. According to the comments for the commit, this was done to fix the > large code model on amd64, but this affects JITs which can guarantee that > both the caller and callee have 32 bit addresses, since the code model is > set uncoditionally to Large, even if another code model was passed to > createJIT (): > > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?r1=86251&r2=88984&pathrev=88984 > > Would it be possible to fix this or make it configurable ?Jeffrey can speak more to this, but this was done specifically to fix the JIT on x86_64, because we have no way of ensuring that we can allocate all the memory for code within one 32-bit swath of the virtual address space. How are you making this guarantee in your JIT? How does this break patching the stub? Is <ADDR> the stub address or the code address? If it's the stub address, you should be able to patch the stub. I agree we shouldn't use the far call sequence on vanilla x86, since all possible addresses can be represented as immediates. Reid
Jeffrey Yasskin
2009-Dec-15 20:25 UTC
[LLVMdev] code generation for calls in JITted code after r88984
On Tue, Dec 15, 2009 at 1:05 AM, Zoltan Varga <vargaz at gmail.com> wrote:> Hi, > > After this commit: > http://llvm.org/viewvc/llvm-project?view=rev&revision=88984 > > the X86 JIT no longer emits calls using call <ADDR>, but always uses mov > REG, <ADDR>, call *REG.That should only be the x86-64 JIT. If the x86-32 JIT does that, it's definitely a bug. For x86-64, it's required unless the JITMemoryManager can guarantee that it only allocates code within 2GB of the text segment.> This causes problems for the usage of LLVM in JITs > since the JIT can no longer patch the callsite after the callee have been > compiled.As far as I know, the JIT only tries to patch the callsite when it's compiling lazily. In that case, it uses X86JITInfo::emitFunctionStub() to emit a stub with known layout that it can patch. It doesn't try to patch the call to the stub. If you've found a broken case here, could you send a (small!) test program with its compilation line, or a patch to http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp that exposes it? English descriptions of these problems tend to be too vague to reproduce.> According to the comments for the commit, this was done to fix the > large code model on amd64, but this affects JITs which can guarantee that > both the caller and callee have 32 bit addresses, since the code model is > set uncoditionally to Large, even if another code model was passed to > createJIT ():JIT::createJIT() intends to obey the CodeModel you pass it, but someone else was complaining of a bug there too. The CodeModel is definitely intended to be configurable, specifically so that users can specify the guarantees their JITMemoryManager provides. Still, it's supposed to be an optimization. The large code model should always produce correct code.> > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?r1=86251&r2=88984&pathrev=88984 > > Would it be possible to fix this or make it configurable ? > > thanks > > Zoltan > > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > >
Zoltan Varga
2009-Dec-16 00:48 UTC
[LLVMdev] code generation for calls in JITted code after r88984
Hi, On Tue, Dec 15, 2009 at 9:25 PM, Jeffrey Yasskin <jyasskin at google.com>wrote:> On Tue, Dec 15, 2009 at 1:05 AM, Zoltan Varga <vargaz at gmail.com> wrote: > > Hi, > > > > After this commit: > > http://llvm.org/viewvc/llvm-project?view=rev&revision=88984 > > > > the X86 JIT no longer emits calls using call <ADDR>, but always uses mov > > REG, <ADDR>, call *REG. > > That should only be the x86-64 JIT. If the x86-32 JIT does that, it's > definitely a bug. For x86-64, it's required unless the > JITMemoryManager can guarantee that it only allocates code within 2GB > of the text segment. > >Our memory manager allocates memory using the MAP_32BIT flag to mmap, so it can guarantee that it is a 32 bit address.> > This causes problems for the usage of LLVM in JITs > > since the JIT can no longer patch the callsite after the callee have been > > compiled. > > As far as I know, the JIT only tries to patch the callsite when it's > compiling lazily. In that case, it uses X86JITInfo::emitFunctionStub() > to emit a stub with known layout that it can patch. It doesn't try to > patch the call to the stub. > > If you've found a broken case here, could you send a (small!) test > program with its compilation line, or a patch to > > http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp > that exposes it? English descriptions of these problems tend to be too > vague to reproduce. > >We are using our pre-existing JIT code (mono), and only parts of the LLVM JIT infrastructure, we would prefer patching the calling code instead of patching the stub, to avoid the overhead of going through the stub at every call, also our JIT expects to be able to patch the call sites.> someone else was complaining of a bug there too. The CodeModel is > definitely intended to be configurable, specifically so that users can > specify the guarantees their JITMemoryManager provides. Still, it's > supposed to be an optimization. The large code model should always > produce correct code. > >It does produce current code, its just that our code depends on LLVM generating normal direct calls and we would like a way to force it to do that. Passing CodeModel::Default to createJIT () used to do that, but it doesn't any more, since it is overwritten with Large. Zoltan> > > > > http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86TargetMachine.cpp?r1=86251&r2=88984&pathrev=88984 > > > > Would it be possible to fix this or make it configurable ? > > > > thanks > > > > Zoltan > > > > _______________________________________________ > > LLVM Developers mailing list > > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev > > > > >-------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20091216/5b0ca6f8/attachment.html>
Reasonably Related Threads
- [LLVMdev] code generation for calls in JITted code after r88984
- [LLVMdev] code generation for calls in JITted code after r88984
- [LLVMdev] Getting the start and end address of JITted code
- [LLVMdev] Getting the start and end address of JITted code
- [LLVMdev] [PATH] Add sub.ovf/mul.ovf intrinsics