<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">In thinking about this we could use a Mutex::tryacquire(...) (non-recursive), around JIT::runJITOnFunctionUnlocked(...)'s<div>while loop, and use your JITEmitter:: getLazyFunctionStub(...) suggestion in place of forceEmitFunctionStub(...). Is the lock</div><div>attempt too heavy, even if it is implemented with atomics? I'll implement this when I have time.</div><div><br></div><div>Garrison</div><div><br><div><div>On Feb 17, 2010, at 15:42, Garrison Venn wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Hi Olivier,<div><br></div><div>Thanks for responding! I get to learn this way.</div><div><br><div><div>On Feb 17, 2010, at 12:50, Olivier Meurant wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite">Hi Garrison,<br><br>I am not a specialist of the code but here is my 2 cents:<br><br>- I like the idea that in lazy-mode the call (in module or not) is treated by a stub (like every calls).<br></blockquote><br>If we go further with this, I'll have to add test cases for lazy mode. I kind of ignored it thinking I'll wait to see what</div><div>the group thinks about the approach.</div><div><br><blockquote type="cite"><br>- If the jit is in non-lazy mode, I'm not really fan of the "stub" solution. Is it not possible to use the same mechanism as it already exists : add the function to pending list and emit it after the current functions ? In fact, can you replace forEmitFunctionStub with getLazyFunctionStub ? With a non-lazy jit, I want the first execution of my function to be the same execution speed as the second one. A stub in non-lazy mode doesn't fell natural to me.<br></blockquote><div><br></div>So as best as I can determine, the problem with leveraging pending, as used by getLazyFunctionStub(...) is that </div><div>I don't know when to call JIT::updateFunctionStub(...). Ideally this behavior should be invoked in the outermost</div><div>getPointerToFunctionCall(), but one doesn't know, as currently implemented, when this is. </div><div><br></div><div>To be clearer, in order to prevent recursive function compilation cases, one needs to delay the compilation of a </div><div>function being called until after the current calling function is compiled. In other words to deal with the scenario </div><div>where Fa (module A), calls Fb (module B), which in turn calls Fa, we delay the compilation of Fb until we have </div><div>finished the compilation of  Fa, unless Fb has previously been compiled. Let's say we used JITEmitter::getLazyFunctionStub(...). </div><div>If a user called getPointerToFunction(...) on Fa, everything would work fine. In compiling Fa, getPointerToFunction(...)</div><div>(via JIT::runJITOnFunctionUnlocked(...)) would encounter Fb in module B, run getLazyFunctionStub(...) on it, and </div><div>then finish with the evaluation of the pending list; again via runJITOnFunctionUnlocked(). The latter functionality</div><div>would result in the compilation of Fb. Say however we instead had Fa1 call Fb, and Fa2 in sequence (Fa1, Fa2</div><div>in module A, Fa2 not previously compiled). The former description would still hold up to the point Fa2 is encountered. </div><div>Since Fa2 is in Fa1's module, runJITOnFunctionUnlocked(...) would compile it, check the pending list, and update the </div><div>contained functions. Since the stub for Fb is in that pending list, Fb would be compiled at this time. However the compilation </div><div>of Fa1 is still not finished, and we have what I was trying to prevent. Any errors in my logic, or my understanding of the </div><div>code? MutexGuards are just mutexes, right? Seems one could use reader/writer lock semantics to force the handing of </div><div>the pending list only in the outmost runJITOnFunctionUnlocked(...) call. I should also add a test case for the above Fa1, </div><div>Fa2, Fb, use case in the bug's attachments.</div><div><br></div><div>Having said this I might be going down a rat hole. It would seem such recursive compilations dependencies would exist</div><div>for functions in the same module, and these are handled. So I should probably look at that code. We are of course</div><div>limited by the existing code, since this is a bug fix not a design change. </div><div><br></div><div>You also have another point. It is dissatisfactory to have the first call delayed just because it is in another module.</div><div>We could use another semantic where the pending list is handled outside of the outermost getPointerToFunction(...)</div><div>is called. This is of course a design change.</div><div><br></div><div><blockquote type="cite">
<br>- I don't see why functions external to every modules (let's say "printf" ?) are delayed with your mechanism. In the last part of your modified getPointerToFunction, you call "getPointerToNamedFunction". AFAICT a printf call will be catch by this code, no ?<br></blockquote><div><br></div>If I understand what your saying correctly: the printf will be caught here, but only after the module search is finished. In</div><div>essence I was saying that with the bug fix, as compared to the pre-existing implementation, the handling of such</div><div>external functions is delayed. If I could tell that the function belonged to this category before I did the module search</div><div>then there would obviously be no delay. Is this possible? I have to say I'm being rather theoretical here. Delay, no delay;</div><div>sounds like I'm trying to predict whether the tree fell in the forest. ;-) I just don't yet have the requisite LLVM knowledge to</div><div>run empirical tests. I tend to hide behind worries of falling timber given the erudite nature of this list's membership. :-)</div><div> <br><blockquote type="cite">
<br>- I like the ideas to be flexible, to be able to say this global variable declaration should point here (with addGlobalMapping), even if there is another module which have a global variable. And in fact, as the workaround is relatively easy, I wonder if it worth the change ?<br></blockquote><div><br></div>I agree, I wonder if there should be a separate mode where a cross module find is turned on, with the default set to off. </div><div>In the optional new mode, stubs would be gathered and processed (until done), as a separate phase--a linking phase</div><div>for JIT as exists in other LLVM JIT tools. I have not looked at those either.</div><div><br></div><div>1) Should we close the bug by dismissing it as no longer appropriate?</div><div>2) Apply the approach as given, with possible changes, and fix the bug?</div><div>3) Create a new approach, still viewing the bug as valid?</div><div>4) Keep the bug open because the implied features are desired but require a minor design change to resolve?</div><div>5) Do other? </div><div><br></div><div>Thanks again for looking at this Olivier.</div><div><br></div><div>Garrison</div><div><br><blockquote type="cite">
<br>Anyway, thanks for asking opinion on this and for contributions you've made on code !<br><br>Olivier.<br><br><br><div class="gmail_quote">On Tue, Feb 16, 2010 at 2:10 PM, Garrison Venn <span dir="ltr"><<a href="mailto:gvenn.cfe.dev@gmail.com">gvenn.cfe.dev@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); margin-top: 0pt; margin-right: 0pt; margin-bottom: 0pt; margin-left: 0.8ex; padding-left: 1ex; position: static; z-index: auto; "><div style="word-wrap: break-word;">The patch I recently attached to bug <span style="font-family: sans-serif;"><a href="http://llvm.org/bugs/show_bug.cgi?id=2606" style="color: rgb(102, 51, 102);" target="_blank">2606</a>, reproduced here, is my first attempt to solve this issue</span><div>
<font face="sans-serif"><span>as represented by the attached test cases. To solve the foreign Module GlobalVariable problem,</span></font></div><div><font face="sans-serif"><span>I modified JIT::getOrEmitGlobalVariable(...) to directly attempt to map a found "external" GlobalVariable.</span></font></div>
<div><font face="sans-serif"><span>To solve the foreign Module Function problem, I modified both JIT.{h,cpp} and JITEmitter.cpp to emit</span></font></div><div><font face="sans-serif"><span>a stub for a found "external" Function instance, when that foreign Module defined Function has not</span></font></div>
<div><font face="sans-serif"><span>yet been compiled.</span></font></div><div><font face="sans-serif"><span><br></span></font></div><div><font face="sans-serif"><span>All areas of interest are marked with // GMV Mod:</span></font></div>
<div><font face="sans-serif"><span><br></span></font></div><div><font face="sans-serif"><span>As I've taken liberties with existing code, and thereby may have touched test cases that will fail, I would like</span></font></div>
<div><font face="sans-serif"><span>to have those members of the list that have time, review this proposal for comments/changes.</span></font></div><div><font class="Apple-style-span" face="sans-serif"><br></font></div></div></blockquote></div></blockquote><br>[snip]</div><div><br><blockquote type="cite"><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left-width: 1px; border-left-style: solid; border-left-color: rgb(204, 204, 204); margin-top: 0pt; margin-right: 0pt; margin-bottom: 0pt; margin-left: 0.8ex; padding-left: 1ex; position: static; z-index: auto; "><div style="word-wrap: break-word;"><div><font face="sans-serif"><span>Thanks for any time spent on this</span></font></div><div><font face="sans-serif"><span><br></span></font></div><font color="#888888"><div>
<font face="sans-serif"><span>Garrison</span></font></div><div><font face="sans-serif"><span><br></span></font></div><div><font face="sans-serif"><span></span></font></div></font></div><br><div style="word-wrap: break-word;">
<div><font face="sans-serif"><span></span></font></div><div><font face="sans-serif"><span><br></span></font></div><div><font face="sans-serif"><span><span style="white-space: pre;">     </span></span></font></div><div><font face="sans-serif"><span><br>
</span></font></div><div><font face="sans-serif"><span><br></span></font></div></div><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></blockquote></div><br>
</blockquote></div><br></div></div></blockquote></div><br></div></body></html>