[llvm-commits] [llvm] r85295 - in /llvm/trunk: docs/tutorial/LangImpl4.html docs/tutorial/OCamlLangImpl4.html include/llvm/ExecutionEngine/ExecutionEngine.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JITEmitter.cpp tools/lli/lli.cpp unittests/ExecutionEngine/JIT/JITTest.cpp

Evan Cheng evan.cheng at apple.com
Tue Oct 27 13:54:24 PDT 2009


On Oct 27, 2009, at 1:30 PM, Jeffrey Yasskin wrote:

> Author: jyasskin
> Date: Tue Oct 27 15:30:28 2009
> New Revision: 85295
>
> URL: http://llvm.org/viewvc/llvm-project?rev=85295&view=rev
> Log:
> Change the JIT to compile eagerly by default as agreed in
> http://llvm.org/PR5184, and beef up the comments to describe what  
> both options
> do and the risks of lazy compilation in the presence of threads.

Hi Jeffrey,

In the future I'd prefer API changes be agreed upon by the greater  
community, not just in a bugzilla report.

Lazy compilation is being used by some important clients. They will be  
caught off guard by this change. Does this change lli default behavior?

Evan

>
> Modified:
>    llvm/trunk/docs/tutorial/LangImpl4.html
>    llvm/trunk/docs/tutorial/OCamlLangImpl4.html
>    llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
>    llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
>    llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
>    llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
>    llvm/trunk/tools/lli/lli.cpp
>    llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
>
> Modified: llvm/trunk/docs/tutorial/LangImpl4.html
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/docs/tutorial/LangImpl4.html (original)
> +++ llvm/trunk/docs/tutorial/LangImpl4.html Tue Oct 27 15:30:28 2009
> @@ -388,24 +388,19 @@
> </pre>
> </div>
>
> -<p>This illustrates that we can now call user code, but there is  
> something a bit subtle
> -going on here.  Note that we only invoke the JIT on the anonymous  
> functions
> -that <em>call testfunc</em>, but we never invoked it on <em>testfunc
> -</em>itself.</p>
> -
> -<p>What actually happened here is that the anonymous function was
> -JIT'd when requested.  When the Kaleidoscope app calls through the  
> function
> -pointer that is returned, the anonymous function starts executing.   
> It ends up
> -making the call to the "testfunc" function, and ends up in a stub  
> that invokes
> -the JIT, lazily, on testfunc.  Once the JIT finishes lazily  
> compiling testfunc,
> -it returns and the code re-executes the call.</p>
> -
> -<p>In summary, the JIT will lazily JIT code, on the fly, as it is  
> needed.  The
> -JIT provides a number of other more advanced interfaces for things  
> like freeing
> -allocated machine code, rejit'ing functions to update them, etc.   
> However, even
> -with this simple code, we get some surprisingly powerful  
> capabilities - check
> -this out (I removed the dump of the anonymous functions, you should  
> get the idea
> -by now :) :</p>
> +<p>This illustrates that we can now call user code, but there is  
> something a bit
> +subtle going on here.  Note that we only invoke the JIT on the  
> anonymous
> +functions that <em>call testfunc</em>, but we never invoked it
> +on <em>testfunc</em> itself.  What actually happened here is that  
> the JIT
> +scanned for all non-JIT'd functions transitively called from the  
> anonymous
> +function and compiled all of them before returning
> +from <tt>getPointerToFunction()</tt>.</p>
> +
> +<p>The JIT provides a number of other more advanced interfaces for  
> things like
> +freeing allocated machine code, rejit'ing functions to update them,  
> etc.
> +However, even with this simple code, we get some surprisingly  
> powerful
> +capabilities - check this out (I removed the dump of the anonymous  
> functions,
> +you should get the idea by now :) :</p>
>
> <div class="doc_code">
> <pre>
> @@ -453,8 +448,8 @@
> resolved.  It allows you to establish explicit mappings between IR  
> objects and
> addresses (useful for LLVM global variables that you want to map to  
> static
> tables, for example), allows you to dynamically decide on the fly  
> based on the
> -function name, and even allows you to have the JIT abort itself if  
> any lazy
> -compilation is attempted.</p>
> +function name, and even allows you to have the JIT compile  
> functions lazily the
> +first time they're called.</p>
>
> <p>One interesting application of this is that we can now extend the  
> language
> by writing arbitrary C++ code to implement operations.  For example,  
> if we add:
>
> Modified: llvm/trunk/docs/tutorial/OCamlLangImpl4.html
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/OCamlLangImpl4.html?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/docs/tutorial/OCamlLangImpl4.html (original)
> +++ llvm/trunk/docs/tutorial/OCamlLangImpl4.html Tue Oct 27 15:30:28  
> 2009
> @@ -406,22 +406,17 @@
>
> <p>This illustrates that we can now call user code, but there is  
> something a bit
> subtle going on here.  Note that we only invoke the JIT on the  
> anonymous
> -functions that <em>call testfunc</em>, but we never invoked it on  
> <em>testfunc
> -</em>itself.</p>
> -
> -<p>What actually happened here is that the anonymous function was  
> JIT'd when
> -requested.  When the Kaleidoscope app calls through the function  
> pointer that is
> -returned, the anonymous function starts executing.  It ends up  
> making the call
> -to the "testfunc" function, and ends up in a stub that invokes the  
> JIT, lazily,
> -on testfunc.  Once the JIT finishes lazily compiling testfunc,
> -it returns and the code re-executes the call.</p>
> -
> -<p>In summary, the JIT will lazily JIT code, on the fly, as it is  
> needed.  The
> -JIT provides a number of other more advanced interfaces for things  
> like freeing
> -allocated machine code, rejit'ing functions to update them, etc.   
> However, even
> -with this simple code, we get some surprisingly powerful  
> capabilities - check
> -this out (I removed the dump of the anonymous functions, you should  
> get the idea
> -by now :) :</p>
> +functions that <em>call testfunc</em>, but we never invoked it
> +on <em>testfunc</em> itself.  What actually happened here is that  
> the JIT
> +scanned for all non-JIT'd functions transitively called from the  
> anonymous
> +function and compiled all of them before returning
> +from <tt>run_function</tt>.</p>
> +
> +<p>The JIT provides a number of other more advanced interfaces for  
> things like
> +freeing allocated machine code, rejit'ing functions to update them,  
> etc.
> +However, even with this simple code, we get some surprisingly  
> powerful
> +capabilities - check this out (I removed the dump of the anonymous  
> functions,
> +you should get the idea by now :) :</p>
>
> <div class="doc_code">
> <pre>
> @@ -467,8 +462,8 @@
> get resolved.  It allows you to establish explicit mappings between  
> IR objects
> and addresses (useful for LLVM global variables that you want to map  
> to static
> tables, for example), allows you to dynamically decide on the fly  
> based on the
> -function name, and even allows you to have the JIT abort itself if  
> any lazy
> -compilation is attempted.</p>
> +function name, and even allows you to have the JIT compile  
> functions lazily the
> +first time they're called.</p>
>
> <p>One interesting application of this is that we can now extend the  
> language
> by writing arbitrary C code to implement operations.  For example,  
> if we add:
>
> Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h  
> (original)
> +++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Tue  
> Oct 27 15:30:28 2009
> @@ -88,7 +88,7 @@
> class ExecutionEngine {
>   const TargetData *TD;
>   ExecutionEngineState EEState;
> -  bool LazyCompilationDisabled;
> +  bool CompilingLazily;
>   bool GVCompilationDisabled;
>   bool SymbolSearchingDisabled;
>   bool DlsymStubsEnabled;
> @@ -319,13 +319,24 @@
>   virtual void RegisterJITEventListener(JITEventListener *) {}
>   virtual void UnregisterJITEventListener(JITEventListener *) {}
>
> -  /// DisableLazyCompilation - If called, the JIT will abort if  
> lazy compilation
> -  /// is ever attempted.
> -  void DisableLazyCompilation(bool Disabled = true) {
> -    LazyCompilationDisabled = Disabled;
> +  /// EnableLazyCompilation - When lazy compilation is off (the  
> default), the
> +  /// JIT will eagerly compile every function reachable from the  
> argument to
> +  /// getPointerToFunction.  If lazy compilation is turned on, the  
> JIT will only
> +  /// compile the one function and emit stubs to compile the rest  
> when they're
> +  /// first called.  If lazy compilation is turned off again while  
> some lazy
> +  /// stubs are still around, and one of those stubs is called, the  
> program will
> +  /// abort.
> +  ///
> +  /// In order to safely compile lazily in a threaded program, the  
> user must
> +  /// ensure that 1) only one thread at a time can call any  
> particular lazy
> +  /// stub, and 2) any thread modifying LLVM IR must hold the JIT's  
> lock
> +  /// (ExecutionEngine::lock) or otherwise ensure that no other  
> thread calls a
> +  /// lazy stub.  See http://llvm.org/PR5184 for details.
> +  void EnableLazyCompilation(bool Enabled = true) {
> +    CompilingLazily = Enabled;
>   }
> -  bool isLazyCompilationDisabled() const {
> -    return LazyCompilationDisabled;
> +  bool isCompilingLazily() const {
> +    return CompilingLazily;
>   }
>
>   /// DisableGVCompilation - If called, the JIT will abort if it's  
> asked to
>
> Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Tue Oct 27  
> 15:30:28 2009
> @@ -49,7 +49,7 @@
> ExecutionEngine::ExecutionEngine(ModuleProvider *P)
>   : EEState(*this),
>     LazyFunctionCreator(0) {
> -  LazyCompilationDisabled = false;
> +  CompilingLazily         = false;
>   GVCompilationDisabled   = false;
>   SymbolSearchingDisabled = false;
>   DlsymStubsEnabled       = false;
>
> Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Tue Oct 27 15:30:28  
> 2009
> @@ -599,7 +599,7 @@
>   isAlreadyCodeGenerating = false;
>
>   // If the function referred to another function that had not yet  
> been
> -  // read from bitcode, but we are jitting non-lazily, emit it now.
> +  // read from bitcode, and we are jitting non-lazily, emit it now.
>   while (!jitstate->getPendingFunctions(locked).empty()) {
>     Function *PF = jitstate->getPendingFunctions(locked).back();
>     jitstate->getPendingFunctions(locked).pop_back();
> @@ -616,7 +616,7 @@
>
>   // If the JIT is configured to emit info so that dlsym can be used  
> to
>   // rewrite stubs to external globals, do so now.
> -  if (areDlsymStubsEnabled() && isLazyCompilationDisabled())
> +  if (areDlsymStubsEnabled() && !isCompilingLazily())
>     updateDlsymStubTable();
> }
>
>
> Modified: llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp (original)
> +++ llvm/trunk/lib/ExecutionEngine/JIT/JITEmitter.cpp Tue Oct 27  
> 15:30:28 2009
> @@ -295,11 +295,11 @@
>   void *&Stub = state.getFunctionToStubMap(locked)[F];
>   if (Stub) return Stub;
>
> -  // Call the lazy resolver function unless we are JIT'ing non- 
> lazily, in which
> -  // case we must resolve the symbol now.
> -  void *Actual = TheJIT->isLazyCompilationDisabled()
> -    ? (void *)0 : (void *)(intptr_t)LazyResolverFn;
> -
> +  // Call the lazy resolver function if we are JIT'ing lazily.   
> Otherwise we
> +  // must resolve the symbol now.
> +  void *Actual = TheJIT->isCompilingLazily()
> +    ? (void *)(intptr_t)LazyResolverFn : (void *)0;
> +
>   // If this is an external declaration, attempt to resolve the  
> address now
>   // to place in the stub.
>   if (F->isDeclaration() && !F->hasNotBeenReadFromBitcode()) {
> @@ -334,7 +334,7 @@
>   // If we are JIT'ing non-lazily but need to call a function that  
> does not
>   // exist yet, add it to the JIT's work list so that we can fill in  
> the stub
>   // address later.
> -  if (!Actual && TheJIT->isLazyCompilationDisabled())
> +  if (!Actual && !TheJIT->isCompilingLazily())
>     if (!F->isDeclaration() || F->hasNotBeenReadFromBitcode())
>       TheJIT->addPendingFunction(F);
>
> @@ -471,7 +471,7 @@
>     // Otherwise we don't have it, do lazy compilation now.
>
>     // If lazy compilation is disabled, emit a useful error message  
> and abort.
> -    if (TheJIT->isLazyCompilationDisabled()) {
> +    if (!TheJIT->isCompilingLazily()) {
>       llvm_report_error("LLVM JIT requested to do lazy compilation  
> of function '"
>                         + F->getName() + "' when lazy compiles are  
> disabled!");
>     }
> @@ -769,7 +769,7 @@
>   // mechanism is capable of rewriting the instruction directly,  
> prefer to do
>   // that instead of emitting a stub.  This uses the lazy resolver,  
> so is not
>   // legal if lazy compilation is disabled.
> -  if (DoesntNeedStub && !TheJIT->isLazyCompilationDisabled())
> +  if (DoesntNeedStub && TheJIT->isCompilingLazily())
>     return Resolver.AddCallbackAtLocation(F, Reference);
>
>   // Otherwise, we have to emit a stub.
>
> Modified: llvm/trunk/tools/lli/lli.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/tools/lli/lli.cpp (original)
> +++ llvm/trunk/tools/lli/lli.cpp Tue Oct 27 15:30:28 2009
> @@ -165,8 +165,7 @@
>
>   EE->RegisterJITEventListener(createOProfileJITEventListener());
>
> -  if (NoLazyCompilation)
> -    EE->DisableLazyCompilation();
> +  EE->EnableLazyCompilation(!NoLazyCompilation);
>
>   // If the user specifically requested an argv[0] to pass into the  
> program,
>   // do it now.
>
> Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=85295&r1=85294&r2=85295&view=diff
>
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> = 
> ======================================================================
> --- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
> +++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Tue Oct 27  
> 15:30:28 2009
> @@ -304,7 +304,7 @@
>   Builder.CreateRet(result);
>
>   TheJIT->EnableDlsymStubs(false);
> -  TheJIT->DisableLazyCompilation();
> +  TheJIT->EnableLazyCompilation(false);
>   int (*TestFunctionPtr)() = reinterpret_cast<int(*)()>(
>       (intptr_t)TheJIT->getPointerToFunction(TestFunction));
>   // This used to crash in trying to call PlusOne().
> @@ -314,7 +314,7 @@
> #if !defined(__arm__) && !defined(__powerpc__) && !defined(__ppc__)
> // Test a function C which calls A and B which call each other.
> TEST_F(JITTest, NonLazyCompilationStillNeedsStubs) {
> -  TheJIT->DisableLazyCompilation();
> +  TheJIT->EnableLazyCompilation(false);
>
>   const FunctionType *Func1Ty =
>       cast<FunctionType>(TypeBuilder<void(void), false>::get 
> (Context));
> @@ -370,7 +370,7 @@
> // Regression test for PR5162.  This used to trigger an AssertingVH  
> inside the
> // JIT's Function to stub mapping.
> TEST_F(JITTest, NonLazyLeaksNoStubs) {
> -  TheJIT->DisableLazyCompilation();
> +  TheJIT->EnableLazyCompilation(false);
>
>   // Create two functions with a single basic block each.
>   const FunctionType *FuncTy =
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list