[llvm-commits] [llvm] r76276 - in /llvm/trunk: bindings/ocaml/executionengine/ docs/ docs/tutorial/ examples/BrainF/ examples/Fibonacci/ examples/HowToUseJIT/ examples/Kaleidoscope/ examples/ParallelJIT/ include/llvm/ExecutionEngine/ lib/ExecutionEngine/ lib/ExecutionEngine/Interpreter/ lib/ExecutionEngine/JIT/ tools/lli/ unittests/ExecutionEngine/JIT/

Reid Kleckner reid at kleckner.net
Fri Jul 17 17:42:18 PDT 2009


Author: rnk
Date: Fri Jul 17 19:42:18 2009
New Revision: 76276

URL: http://llvm.org/viewvc/llvm-project?rev=76276&view=rev
Log:
Add EngineBuilder to ExecutionEngine in favor of the five optional argument EE::create().

Also a test commit.

Modified:
    llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli
    llvm/trunk/docs/CMake.html
    llvm/trunk/docs/tutorial/LangImpl4.html
    llvm/trunk/docs/tutorial/LangImpl5.html
    llvm/trunk/docs/tutorial/LangImpl6.html
    llvm/trunk/docs/tutorial/LangImpl7.html
    llvm/trunk/examples/BrainF/BrainFDriver.cpp
    llvm/trunk/examples/Fibonacci/fibonacci.cpp
    llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp
    llvm/trunk/examples/Kaleidoscope/toy.cpp
    llvm/trunk/examples/ParallelJIT/ParallelJIT.cpp
    llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
    llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
    llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp
    llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp
    llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h
    llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
    llvm/trunk/lib/ExecutionEngine/JIT/JIT.h
    llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp
    llvm/trunk/tools/lli/lli.cpp
    llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
    llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp

Modified: llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli (original)
+++ llvm/trunk/bindings/ocaml/executionengine/llvm_executionengine.mli Fri Jul 17 19:42:18 2009
@@ -89,14 +89,14 @@
       module provider [mp] if successful. Creates a JIT if possible, else falls
       back to an interpreter. Raises [Error msg] if an error occurrs. The
       execution engine is not garbage collected and must be destroyed with
-      [dispose ee]. See the function [llvm::ExecutionEngine::create]. *)
+      [dispose ee]. See the function [llvm::EngineBuilder::create]. *)
   val create: Llvm.llmoduleprovider -> t
   
   (** [create_interpreter mp] creates a new interpreter, taking ownership of the
       module provider [mp] if successful. Raises [Error msg] if an error
       occurrs. The execution engine is not garbage collected and must be
       destroyed with [dispose ee].
-      See the function [llvm::ExecutionEngine::create]. *)
+      See the function [llvm::EngineBuilder::create]. *)
   val create_interpreter: Llvm.llmoduleprovider -> t
   
   (** [create_jit mp] creates a new JIT (just-in-time compiler), taking
@@ -104,7 +104,7 @@
       a JIT which favors code quality over compilation speed. Raises [Error msg]
       if an error occurrs. The execution engine is not garbage collected and
       must be destroyed with [dispose ee].
-      See the function [llvm::ExecutionEngine::create]. *)
+      See the function [llvm::EngineBuilder::create]. *)
   val create_jit: Llvm.llmoduleprovider -> t
   
   (** [create_fast_jit mp] creates a new JIT (just-in-time compiler) which
@@ -112,7 +112,7 @@
       module provider [mp] if successful. Raises [Error msg] if an error
       occurrs. The execution engine is not garbage collected and must be
       destroyed with [dispose ee].
-      See the function [llvm::ExecutionEngine::create]. *)
+      See the function [llvm::EngineBuilder::create]. *)
   val create_fast_jit: Llvm.llmoduleprovider -> t
   
   (** [dispose ee] releases the memory used by the execution engine and must be

Modified: llvm/trunk/docs/CMake.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CMake.html?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/docs/CMake.html (original)
+++ llvm/trunk/docs/CMake.html Fri Jul 17 19:42:18 2009
@@ -352,7 +352,7 @@
 
   <p>to your linker options. This is required for adding the relevant
     LLVM object code to the executable. Not doing this will result on
-    some methods returning NULL (<i>ExecutionEngine::create</i>, for
+    some methods returning NULL (<i>EngineBuilder::create</i>, for
     instance).</p>
 
 </div>

Modified: llvm/trunk/docs/tutorial/LangImpl4.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl4.html?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/docs/tutorial/LangImpl4.html (original)
+++ llvm/trunk/docs/tutorial/LangImpl4.html Fri Jul 17 19:42:18 2009
@@ -299,7 +299,7 @@
 int main() {
   ..
   <b>// Create the JIT.
-  TheExecutionEngine = ExecutionEngine::create(TheModule);</b>
+    TheExecutionEngine = EngineBuilder(TheModule).create();</b>
   ..
 }
 </pre>
@@ -1078,7 +1078,7 @@
   TheModule = new Module("my cool jit", getGlobalContext());
   
   // Create the JIT.
-  TheExecutionEngine = ExecutionEngine::create(TheModule);
+  TheExecutionEngine = EngineBuilder(TheModule).create();
 
   {
     ExistingModuleProvider OurModuleProvider(TheModule);

Modified: llvm/trunk/docs/tutorial/LangImpl5.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl5.html?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/docs/tutorial/LangImpl5.html (original)
+++ llvm/trunk/docs/tutorial/LangImpl5.html Fri Jul 17 19:42:18 2009
@@ -1712,7 +1712,7 @@
   TheModule = new Module("my cool jit", getGlobalContext());
   
   // Create the JIT.
-  TheExecutionEngine = ExecutionEngine::create(TheModule);
+  TheExecutionEngine = EngineBuilder(TheModule).create();
 
   {
     ExistingModuleProvider OurModuleProvider(TheModule);

Modified: llvm/trunk/docs/tutorial/LangImpl6.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl6.html?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/docs/tutorial/LangImpl6.html (original)
+++ llvm/trunk/docs/tutorial/LangImpl6.html Fri Jul 17 19:42:18 2009
@@ -1751,7 +1751,7 @@
   TheModule = new Module("my cool jit", getGlobalContext());
   
   // Create the JIT.
-  TheExecutionEngine = ExecutionEngine::create(TheModule);
+  TheExecutionEngine = EngineBuilder(TheModule).create();
 
   {
     ExistingModuleProvider OurModuleProvider(TheModule);

Modified: llvm/trunk/docs/tutorial/LangImpl7.html
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/tutorial/LangImpl7.html?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/docs/tutorial/LangImpl7.html (original)
+++ llvm/trunk/docs/tutorial/LangImpl7.html Fri Jul 17 19:42:18 2009
@@ -2103,7 +2103,7 @@
   TheModule = new Module("my cool jit", getGlobalContext());
   
   // Create the JIT.
-  TheExecutionEngine = ExecutionEngine::create(TheModule);
+  TheExecutionEngine = EngineBuilder(TheModule).create();
 
   {
     ExistingModuleProvider OurModuleProvider(TheModule);

Modified: llvm/trunk/examples/BrainF/BrainFDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/BrainF/BrainFDriver.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/examples/BrainF/BrainFDriver.cpp (original)
+++ llvm/trunk/examples/BrainF/BrainFDriver.cpp Fri Jul 17 19:42:18 2009
@@ -141,8 +141,7 @@
     InitializeNativeTarget();
 
     std::cout << "------- Running JIT -------\n";
-    ExistingModuleProvider *mp = new ExistingModuleProvider(mod);
-    ExecutionEngine *ee = ExecutionEngine::create(mp, false);
+    ExecutionEngine *ee = EngineBuilder(mod).create();
     std::vector<GenericValue> args;
     Function *brainf_func = mod->getFunction("brainf");
     GenericValue gv = ee->runFunction(brainf_func, args);

Modified: llvm/trunk/examples/Fibonacci/fibonacci.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Fibonacci/fibonacci.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/examples/Fibonacci/fibonacci.cpp (original)
+++ llvm/trunk/examples/Fibonacci/fibonacci.cpp Fri Jul 17 19:42:18 2009
@@ -100,8 +100,7 @@
   Function *FibF = CreateFibFunction(M, Context);
 
   // Now we going to create JIT
-  ExistingModuleProvider *MP = new ExistingModuleProvider(M);
-  ExecutionEngine *EE = ExecutionEngine::create(MP, false);
+  ExecutionEngine *EE = EngineBuilder(M).create();
 
   errs() << "verifying... ";
   if (verifyModule(*M)) {

Modified: llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp (original)
+++ llvm/trunk/examples/HowToUseJIT/HowToUseJIT.cpp Fri Jul 17 19:42:18 2009
@@ -104,8 +104,7 @@
   ReturnInst::Create(Add1CallRes, BB);
 
   // Now we create the JIT.
-  ExistingModuleProvider* MP = new ExistingModuleProvider(M);
-  ExecutionEngine* EE = ExecutionEngine::create(MP, false);
+  ExecutionEngine* EE = EngineBuilder(M).create();
 
   outs() << "We just constructed this LLVM module:\n\n" << *M;
   outs() << "\n\nRunning foo: ";

Modified: llvm/trunk/examples/Kaleidoscope/toy.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/Kaleidoscope/toy.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/examples/Kaleidoscope/toy.cpp (original)
+++ llvm/trunk/examples/Kaleidoscope/toy.cpp Fri Jul 17 19:42:18 2009
@@ -1103,7 +1103,7 @@
   TheModule = new Module("my cool jit", Context);
   
   // Create the JIT.
-  TheExecutionEngine = ExecutionEngine::create(TheModule);
+  TheExecutionEngine = EngineBuilder(TheModule).create();
 
   {
     ExistingModuleProvider OurModuleProvider(TheModule);
@@ -1138,4 +1138,3 @@
   
   return 0;
 }
-

Modified: llvm/trunk/examples/ParallelJIT/ParallelJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/examples/ParallelJIT/ParallelJIT.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/examples/ParallelJIT/ParallelJIT.cpp (original)
+++ llvm/trunk/examples/ParallelJIT/ParallelJIT.cpp Fri Jul 17 19:42:18 2009
@@ -242,8 +242,7 @@
   Function* fibF = CreateFibFunction( M );
 
   // Now we create the JIT.
-  ExistingModuleProvider* MP = new ExistingModuleProvider(M);
-  ExecutionEngine* EE = ExecutionEngine::create(MP, false);
+  ExecutionEngine* EE = EngineBuilder(M).create();
 
   //~ std::cout << "We just constructed this LLVM module:\n\n" << *M;
   //~ std::cout << "\n\nRunning foo: " << std::flush;

Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Fri Jul 17 19:42:18 2009
@@ -71,6 +71,8 @@
   bool SymbolSearchingDisabled;
   bool DlsymStubsEnabled;
 
+  friend class EngineBuilder;  // To allow access to JITCtor and InterpCtor.
+
 protected:
   /// Modules - This is a list of ModuleProvider's that we are JIT'ing from.  We
   /// use a smallvector to optimize for the case where there is only one module.
@@ -86,10 +88,13 @@
   // To avoid having libexecutionengine depend on the JIT and interpreter
   // libraries, the JIT and Interpreter set these functions to ctor pointers
   // at startup time if they are linked in.
-  typedef ExecutionEngine *(*EECtorFn)(ModuleProvider*, std::string*,
-                                       CodeGenOpt::Level OptLevel,
-                                       bool GVsWithCode);
-  static EECtorFn JITCtor, InterpCtor;
+  static ExecutionEngine *(*JITCtor)(ModuleProvider *MP,
+                                     std::string *ErrorStr,
+                                     JITMemoryManager *JMM,
+                                     CodeGenOpt::Level OptLevel,
+                                     bool GVsWithCode);
+  static ExecutionEngine *(*InterpCtor)(ModuleProvider *MP,
+                                        std::string *ErrorStr);
 
   /// LazyFunctionCreator - If an unknown function is needed, this function
   /// pointer is invoked to create it. If this returns null, the JIT will abort.
@@ -372,6 +377,96 @@
                            const Type *Ty);
 };
 
+namespace EngineKind {
+  // These are actually bitmasks that get or-ed together.
+  enum Kind {
+    JIT         = 0x1,
+    Interpreter = 0x2
+  };
+  const static Kind Either = (Kind)(JIT | Interpreter);
+}
+
+/// EngineBuilder - Builder class for ExecutionEngines.  Use this by
+/// stack-allocating a builder, chaining the various set* methods, and
+/// terminating it with a .create() call.
+class EngineBuilder {
+
+ private:
+  ModuleProvider *MP;
+  EngineKind::Kind WhichEngine;
+  std::string *ErrorStr;
+  CodeGenOpt::Level OptLevel;
+  JITMemoryManager *JMM;
+  bool AllocateGVsWithCode;
+
+  /// InitEngine - Does the common initialization of default options.
+  ///
+  void InitEngine() {
+    WhichEngine = EngineKind::Either;
+    ErrorStr = NULL;
+    OptLevel = CodeGenOpt::Default;
+    JMM = NULL;
+    AllocateGVsWithCode = false;
+  }
+
+ public:
+  /// EngineBuilder - Constructor for EngineBuilder.  If create() is called and
+  /// is successful, the created engine takes ownership of the module
+  /// provider.
+  EngineBuilder(ModuleProvider *mp) : MP(mp) {
+    InitEngine();
+  }
+
+  /// EngineBuilder - Overloaded constructor that automatically creates an
+  /// ExistingModuleProvider for an existing module.
+  EngineBuilder(Module *m);
+
+  /// setEngineKind - Controls whether the user wants the interpreter, the JIT,
+  /// or whichever engine works.  This option defaults to EngineKind::Either.
+  EngineBuilder &setEngineKind(EngineKind::Kind w) {
+    WhichEngine = w;
+    return *this;
+  }
+
+  /// setJITMemoryManager - Sets the memory manager to use.  This allows
+  /// clients to customize their memory allocation policies.  If create() is
+  /// called and is successful, the created engine takes ownership of the
+  /// memory manager.  This option defaults to NULL.
+  EngineBuilder &setJITMemoryManager(JITMemoryManager *jmm) {
+    JMM = jmm;
+    return *this;
+  }
+
+  /// setErrorStr - Set the error string to write to on error.  This option
+  /// defaults to NULL.
+  EngineBuilder &setErrorStr(std::string *e) {
+    ErrorStr = e;
+    return *this;
+  }
+
+  /// setOptLevel - Set the optimization level for the JIT.  This option
+  /// defaults to CodeGenOpt::Default.
+  EngineBuilder &setOptLevel(CodeGenOpt::Level l) {
+    OptLevel = l;
+    return *this;
+  }
+
+  /// setAllocateGVsWithCode - Sets whether global values should be allocated
+  /// into the same buffer as code.  For most applications this should be set
+  /// to false.  Allocating globals with code breaks freeMachineCodeForFunction
+  /// and is probably unsafe and bad for performance.  However, we have clients
+  /// who depend on this behavior, so we must support it.  This option defaults
+  /// to false so that users of the new API can safely use the new memory
+  /// manager and free machine code.
+  EngineBuilder &setAllocateGVsWithCode(bool a) {
+    AllocateGVsWithCode = a;
+    return *this;
+  }
+
+  ExecutionEngine *create();
+
+};
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Fri Jul 17 19:42:18 2009
@@ -35,8 +35,13 @@
 STATISTIC(NumInitBytes, "Number of bytes of global vars initialized");
 STATISTIC(NumGlobals  , "Number of global vars initialized");
 
-ExecutionEngine::EECtorFn ExecutionEngine::JITCtor = 0;
-ExecutionEngine::EECtorFn ExecutionEngine::InterpCtor = 0;
+ExecutionEngine *(*ExecutionEngine::JITCtor)(ModuleProvider *MP,
+                                             std::string *ErrorStr,
+                                             JITMemoryManager *JMM,
+                                             CodeGenOpt::Level OptLevel,
+                                             bool GVsWithCode) = 0;
+ExecutionEngine *(*ExecutionEngine::InterpCtor)(ModuleProvider *MP,
+                                                std::string *ErrorStr) = 0;
 ExecutionEngine::EERegisterFn ExecutionEngine::ExceptionTableRegister = 0;
 
 
@@ -382,26 +387,60 @@
                                          std::string *ErrorStr,
                                          CodeGenOpt::Level OptLevel,
                                          bool GVsWithCode) {
-  ExecutionEngine *EE = 0;
+  return EngineBuilder(MP)
+      .setEngineKind(ForceInterpreter
+                     ? EngineKind::Interpreter
+                     : EngineKind::JIT)
+      .setErrorStr(ErrorStr)
+      .setOptLevel(OptLevel)
+      .setAllocateGVsWithCode(GVsWithCode)
+      .create();
+}
+
+ExecutionEngine *ExecutionEngine::create(Module *M) {
+  return EngineBuilder(M).create();
+}
 
+/// EngineBuilder - Overloaded constructor that automatically creates an
+/// ExistingModuleProvider for an existing module.
+EngineBuilder::EngineBuilder(Module *m) : MP(new ExistingModuleProvider(m)) {
+  InitEngine();
+}
+
+ExecutionEngine *EngineBuilder::create() {
   // Make sure we can resolve symbols in the program as well. The zero arg
   // to the function tells DynamicLibrary to load the program, not a library.
   if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
     return 0;
 
-  // Unless the interpreter was explicitly selected, try making a JIT.
-  if (!ForceInterpreter && JITCtor)
-    EE = JITCtor(MP, ErrorStr, OptLevel, GVsWithCode);
-
-  // If we can't make a JIT, make an interpreter instead.
-  if (EE == 0 && InterpCtor)
-    EE = InterpCtor(MP, ErrorStr, OptLevel, GVsWithCode);
+  // If the user specified a memory manager but didn't specify which engine to
+  // create, we assume they only want the JIT, and we fail if they only want
+  // the interpreter.
+  if (JMM) {
+    if (WhichEngine & EngineKind::JIT) {
+      WhichEngine = EngineKind::JIT;
+    } else {
+      *ErrorStr = "Cannot create an interpreter with a memory manager.";
+    }
+  }
+
+  ExecutionEngine *EE = 0;
 
-  return EE;
-}
+  // Unless the interpreter was explicitly selected or the JIT is not linked,
+  // try making a JIT.
+  if (WhichEngine & EngineKind::JIT && ExecutionEngine::JITCtor) {
+    EE = ExecutionEngine::JITCtor(MP, ErrorStr, JMM, OptLevel,
+                                  AllocateGVsWithCode);
+  }
 
-ExecutionEngine *ExecutionEngine::create(Module *M) {
-  return create(new ExistingModuleProvider(M));
+  // If we can't make a JIT and we didn't request one specifically, try making
+  // an interpreter instead.
+  if (WhichEngine & EngineKind::Interpreter && EE == 0 &&
+      ExecutionEngine::InterpCtor) {
+    EE = ExecutionEngine::InterpCtor(MP, ErrorStr);
+  }
+
+  return EE;
 }
 
 /// getPointerToGlobal - This returns the address of the specified global

Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/ExecutionEngineBindings.cpp Fri Jul 17 19:42:18 2009
@@ -91,7 +91,10 @@
                               LLVMModuleProviderRef MP,
                               char **OutError) {
   std::string Error;
-  if (ExecutionEngine *EE = ExecutionEngine::create(unwrap(MP), false, &Error)){
+  EngineBuilder builder(unwrap(MP));
+  builder.setEngineKind(EngineKind::Either)
+         .setErrorStr(&Error);
+  if (ExecutionEngine *EE = builder.create()){
     *OutEE = wrap(EE);
     return 0;
   }
@@ -103,8 +106,10 @@
                           LLVMModuleProviderRef MP,
                           char **OutError) {
   std::string Error;
-  if (ExecutionEngine *Interp =
-      ExecutionEngine::create(unwrap(MP), true, &Error)) {
+  EngineBuilder builder(unwrap(MP));
+  builder.setEngineKind(EngineKind::Interpreter)
+         .setErrorStr(&Error);
+  if (ExecutionEngine *Interp = builder.create()) {
     *OutInterp = wrap(Interp);
     return 0;
   }
@@ -117,9 +122,11 @@
                           unsigned OptLevel,
                           char **OutError) {
   std::string Error;
-  if (ExecutionEngine *JIT =
-      ExecutionEngine::create(unwrap(MP), false, &Error,
-                                 (CodeGenOpt::Level)OptLevel)) {
+  EngineBuilder builder(unwrap(MP));
+  builder.setEngineKind(EngineKind::JIT)
+         .setErrorStr(&Error)
+         .setOptLevel((CodeGenOpt::Level)OptLevel);
+  if (ExecutionEngine *JIT = builder.create()) {
     *OutJIT = wrap(JIT);
     return 0;
   }

Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.cpp Fri Jul 17 19:42:18 2009
@@ -33,9 +33,7 @@
 
 /// create - Create a new interpreter object.  This can never fail.
 ///
-ExecutionEngine *Interpreter::create(ModuleProvider *MP, std::string* ErrStr,
-                                     CodeGenOpt::Level OptLevel, /*unused*/
-                                     bool GVsWithCode /* unused */) {
+ExecutionEngine *Interpreter::create(ModuleProvider *MP, std::string* ErrStr) {
   // Tell this ModuleProvide to materialize and release the module
   if (!MP->materializeModule(ErrStr))
     // We got an error, just return 0

Modified: llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h (original)
+++ llvm/trunk/lib/ExecutionEngine/Interpreter/Interpreter.h Fri Jul 17 19:42:18 2009
@@ -108,9 +108,7 @@
   
   /// create - Create an interpreter ExecutionEngine. This can never fail.
   ///
-  static ExecutionEngine *create(ModuleProvider *M, std::string *ErrorStr = 0,
-                                 CodeGenOpt::Level = CodeGenOpt::Default,
-                                 bool GVsWithCode = true);
+  static ExecutionEngine *create(ModuleProvider *M, std::string *ErrorStr = 0);
 
   /// run - Start execution with the specified function and arguments.
   ///

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Fri Jul 17 19:42:18 2009
@@ -199,14 +199,31 @@
                                             JITMemoryManager *JMM,
                                             CodeGenOpt::Level OptLevel,
                                             bool GVsWithCode) {
-  ExecutionEngine *EE = JIT::createJIT(MP, ErrorStr, JMM, OptLevel,
-                                       GVsWithCode);
-  if (!EE) return 0;
-  
+    return JIT::createJIT(MP, ErrorStr, JMM, OptLevel, GVsWithCode);
+}
+
+ExecutionEngine *JIT::createJIT(ModuleProvider *MP,
+                                std::string *ErrorStr,
+                                JITMemoryManager *JMM,
+                                CodeGenOpt::Level OptLevel,
+                                bool GVsWithCode) {
   // Make sure we can resolve symbols in the program as well. The zero arg
   // to the function tells DynamicLibrary to load the program, not a library.
-  sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr);
-  return EE;
+  if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
+    return 0;
+
+  // Pick a target either via -march or by guessing the native arch.
+  TargetMachine *TM = JIT::selectTarget(MP, ErrorStr);
+  if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0;
+
+  // If the target supports JIT code generation, create a the JIT.
+  if (TargetJITInfo *TJ = TM->getJITInfo()) {
+    return new JIT(MP, *TM, *TJ, JMM, OptLevel, GVsWithCode);
+  } else {
+    if (ErrorStr)
+      *ErrorStr = "target does not support JIT code generation";
+    return 0;
+  }
 }
 
 JIT::JIT(ModuleProvider *MP, TargetMachine &tm, TargetJITInfo &tji,

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Fri Jul 17 19:42:18 2009
@@ -79,11 +79,13 @@
   /// create - Create an return a new JIT compiler if there is one available
   /// for the current target.  Otherwise, return null.
   ///
-  static ExecutionEngine *create(ModuleProvider *MP, std::string *Err,
+  static ExecutionEngine *create(ModuleProvider *MP,
+                                 std::string *Err,
+                                 JITMemoryManager *JMM,
                                  CodeGenOpt::Level OptLevel =
                                    CodeGenOpt::Default,
-                                 bool AllocateGVsWithCode = true) {
-    return createJIT(MP, Err, 0, OptLevel, AllocateGVsWithCode);
+                                 bool GVsWithCode = true) {
+    return ExecutionEngine::createJIT(MP, Err, JMM, OptLevel, GVsWithCode);
   }
 
   virtual void addModuleProvider(ModuleProvider *MP);
@@ -152,18 +154,22 @@
   /// addPendingFunction - while jitting non-lazily, a called but non-codegen'd
   /// function was encountered.  Add it to a pending list to be processed after 
   /// the current function.
-  /// 
+  ///
   void addPendingFunction(Function *F);
-  
+
   /// getCodeEmitter - Return the code emitter this JIT is emitting into.
+  ///
   JITCodeEmitter *getCodeEmitter() const { return JCE; }
-  
+
+  /// selectTarget - Pick a target either via -march or by guessing the native
+  /// arch.  Add any CPU features specified via -mcpu or -mattr.
+  static TargetMachine *selectTarget(ModuleProvider *MP, std::string *Err);
+
   static ExecutionEngine *createJIT(ModuleProvider *MP,
-                                    std::string *Err,
+                                    std::string *ErrorStr,
                                     JITMemoryManager *JMM,
                                     CodeGenOpt::Level OptLevel,
-                                    bool AllocateGVsWithCode);
-
+                                    bool GVsWithCode);
 
   // Run the JIT on F and return information about the generated code
   void runJITOnFunction(Function *F, MachineCodeInfo *MCI = 0);

Modified: llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/TargetSelect.cpp Fri Jul 17 19:42:18 2009
@@ -38,13 +38,9 @@
   cl::desc("Target specific attributes (-mattr=help for details)"),
   cl::value_desc("a1,+a2,-a3,..."));
 
-/// createInternal - Create an return a new JIT compiler if there is one
-/// available for the current target.  Otherwise, return null.
-///
-ExecutionEngine *JIT::createJIT(ModuleProvider *MP, std::string *ErrorStr,
-                                JITMemoryManager *JMM,
-                                CodeGenOpt::Level OptLevel,
-                                bool AllocateGVsWithCode) {
+/// selectTarget - Pick a target either via -march or by guessing the native
+/// arch.  Add any CPU features specified via -mcpu or -mattr.
+TargetMachine *JIT::selectTarget(ModuleProvider *MP, std::string *ErrorStr) {
   const Target *TheTarget = 0;
   if (MArch.empty()) {
     std::string Error;
@@ -90,12 +86,5 @@
   TargetMachine *Target = 
     TheTarget->createTargetMachine(*MP->getModule(), FeaturesStr);
   assert(Target && "Could not allocate target machine!");
-
-  // If the target supports JIT code generation, return a new JIT now.
-  if (TargetJITInfo *TJ = Target->getJITInfo())
-    return new JIT(MP, *Target, *TJ, JMM, OptLevel, AllocateGVsWithCode);
-
-  if (ErrorStr)
-    *ErrorStr = "target does not support JIT code generation";
-  return 0;
+  return Target;
 }

Modified: llvm/trunk/tools/lli/lli.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/tools/lli/lli.cpp (original)
+++ llvm/trunk/tools/lli/lli.cpp Fri Jul 17 19:42:18 2009
@@ -131,6 +131,12 @@
     exit(1);
   }
 
+  EngineBuilder builder(MP);
+  builder.setErrorStr(&ErrorMsg)
+         .setEngineKind(ForceInterpreter
+                        ? EngineKind::Interpreter
+                        : EngineKind::JIT);
+
   // If we are supposed to override the target triple, do so now.
   if (!TargetTriple.empty())
     Mod->setTargetTriple(TargetTriple);
@@ -146,8 +152,9 @@
   case '2': OLvl = CodeGenOpt::Default; break;
   case '3': OLvl = CodeGenOpt::Aggressive; break;
   }
-  
-  EE = ExecutionEngine::create(MP, ForceInterpreter, &ErrorMsg, OLvl);
+  builder.setOptLevel(OLvl);
+
+  EE = builder.create();
   if (!EE) {
     if (!ErrorMsg.empty())
       errs() << argv[0] << ": error creating EE: " << ErrorMsg << "\n";

Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/JIT/JITEventListenerTest.cpp Fri Jul 17 19:42:18 2009
@@ -66,7 +66,9 @@
  protected:
   JITEventListenerTest()
       : M(new Module("module", getGlobalContext())),
-        EE(ExecutionEngine::createJIT(new ExistingModuleProvider(M))) {
+        EE(EngineBuilder(M)
+           .setEngineToCreate(EngineBuilder::ENG_JIT)
+           .create()) {
   }
 
   Module *M;
@@ -232,7 +234,7 @@
 
 class JITEnvironment : public testing::Environment {
   virtual void SetUp() {
-    // Required for ExecutionEngine::createJIT to create a JIT.
+    // Required to create a JIT.
     InitializeNativeTarget();
   }
 };

Modified: llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp?rev=76276&r1=76275&r2=76276&view=diff

==============================================================================
--- llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp (original)
+++ llvm/trunk/unittests/ExecutionEngine/JIT/JITTest.cpp Fri Jul 17 19:42:18 2009
@@ -1,4 +1,4 @@
-//===- JITEmitter.cpp - Unit tests for the JIT code emitter ---------------===//
+//===- JITTest.cpp - Unit tests for the JIT -------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -18,6 +18,7 @@
 #include "llvm/Function.h"
 #include "llvm/GlobalValue.h"
 #include "llvm/GlobalVariable.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/ModuleProvider.h"
 #include "llvm/Support/IRBuilder.h"
@@ -60,12 +61,13 @@
   // memory is more easily tested.
   MemMgr->setPoisonMemory(true);
   std::string Error;
-  OwningPtr<ExecutionEngine> JIT(ExecutionEngine::createJIT(
-      MP,
-      &Error,
-      MemMgr,
-      CodeGenOpt::Default,
-      false));  // This last argument enables the fix.
+  OwningPtr<ExecutionEngine> JIT(EngineBuilder(MP)
+                                 .setEnginePreference(EngineBuilder::JITONLY)
+                                 .setErrorStr(&Error)
+                                 .setJITMemoryManager(MemMgr)
+                                 // The next line enables the fix:
+                                 .setAllocateGVsWithCode(false)
+                                 .create());
   ASSERT_EQ(Error, "");
 
   // Create a global variable.
@@ -115,11 +117,12 @@
   EXPECT_EQ(3, *GPtr);
 }
 
-// TODO(rnk): This seems to only run once for both tests, which is unexpected.
-// That works just fine, but we shouldn't duplicate the code.
+// This code is copied from JITEventListenerTest, but it only runs once for all
+// the tests in this directory.  Everything seems fine, but that's strange
+// behavior.
 class JITEnvironment : public testing::Environment {
   virtual void SetUp() {
-    // Required for ExecutionEngine::createJIT to create a JIT.
+    // Required to create a JIT.
     InitializeNativeTarget();
   }
 };





More information about the llvm-commits mailing list