[llvm-commits] [llvm] r127916 - in /llvm/trunk: include/llvm/Target/TargetMachine.h lib/CodeGen/LLVMTargetMachine.cpp lib/ExecutionEngine/MCJIT/MCJIT.cpp lib/ExecutionEngine/MCJIT/MCJIT.h tools/lli/lli.cpp

Jim Grosbach grosbach at apple.com
Fri Mar 18 15:48:41 PDT 2011


Author: grosbach
Date: Fri Mar 18 17:48:41 2011
New Revision: 127916

URL: http://llvm.org/viewvc/llvm-project?rev=127916&view=rev
Log:
Beginnings of MC-JIT code generation.

Proof-of-concept code that code-gens a module to an in-memory MachO object.
This will be hooked up to a run-time dynamic linker library (see: llvm-rtdyld
for similarly conceptual work for that part) which will take the compiled
object and link it together with the rest of the system, providing back to the
JIT a table of available symbols which will be used to respond to the
getPointerTo*() queries.


Modified:
    llvm/trunk/include/llvm/Target/TargetMachine.h
    llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
    llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
    llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
    llvm/trunk/tools/lli/lli.cpp

Modified: llvm/trunk/include/llvm/Target/TargetMachine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetMachine.h?rev=127916&r1=127915&r2=127916&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetMachine.h (original)
+++ llvm/trunk/include/llvm/Target/TargetMachine.h Fri Mar 18 17:48:41 2011
@@ -38,6 +38,7 @@
 class Pass;
 class TargetELFWriterInfo;
 class formatted_raw_ostream;
+class raw_ostream;
 
 // Relocation model types.
 namespace Reloc {
@@ -267,6 +268,7 @@
   ///
   virtual bool addPassesToEmitMC(PassManagerBase &,
                                  MCContext *&,
+                                 raw_ostream &OS,
                                  CodeGenOpt::Level,
                                  bool = true) {
     return true;
@@ -324,6 +326,7 @@
   ///
   virtual bool addPassesToEmitMC(PassManagerBase &PM,
                                  MCContext *&Ctx,
+                                 raw_ostream &OS,
                                  CodeGenOpt::Level OptLevel,
                                  bool DisableVerify = true);
 

Modified: llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp?rev=127916&r1=127915&r2=127916&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp (original)
+++ llvm/trunk/lib/CodeGen/LLVMTargetMachine.cpp Fri Mar 18 17:48:41 2011
@@ -224,11 +224,37 @@
 ///
 bool LLVMTargetMachine::addPassesToEmitMC(PassManagerBase &PM,
                                           MCContext *&Ctx,
+                                          raw_ostream &Out,
                                           CodeGenOpt::Level OptLevel,
                                           bool DisableVerify) {
   // Add common CodeGen passes.
   if (addCommonCodeGenPasses(PM, OptLevel, DisableVerify, Ctx))
     return true;
+
+  // Create the code emitter for the target if it exists.  If not, .o file
+  // emission fails.
+  MCCodeEmitter *MCE = getTarget().createCodeEmitter(*this, *Ctx);
+  TargetAsmBackend *TAB = getTarget().createAsmBackend(TargetTriple);
+  if (MCE == 0 || TAB == 0)
+    return true;
+
+  OwningPtr<MCStreamer> AsmStreamer;
+  AsmStreamer.reset(getTarget().createObjectStreamer(TargetTriple, *Ctx,
+                                                     *TAB, Out, MCE,
+                                                     hasMCRelaxAll(),
+                                                     hasMCNoExecStack()));
+  AsmStreamer.get()->InitSections();
+
+  // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.
+  FunctionPass *Printer = getTarget().createAsmPrinter(*this, *AsmStreamer);
+  if (Printer == 0)
+    return true;
+
+  // If successful, createAsmPrinter took ownership of AsmStreamer.
+  AsmStreamer.take();
+
+  PM.add(Printer);
+
   // Make sure the code model is set.
   setCodeModelForJIT();
 

Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp?rev=127916&r1=127915&r2=127916&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.cpp Fri Mar 18 17:48:41 2011
@@ -8,10 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCJIT.h"
+#include "llvm/Function.h"
 #include "llvm/ExecutionEngine/GenericValue.h"
 #include "llvm/ExecutionEngine/MCJIT.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/DynamicLibrary.h"
+#include "llvm/Target/TargetData.h"
 
 using namespace llvm;
 
@@ -51,17 +53,34 @@
 
   // If the target supports JIT code generation, create the JIT.
   if (TargetJITInfo *TJ = TM->getJITInfo())
-    return new MCJIT(M, *TM, *TJ, JMM, OptLevel, GVsWithCode);
+    return new MCJIT(M, TM, *TJ, JMM, OptLevel, GVsWithCode);
 
   if (ErrorStr)
     *ErrorStr = "target does not support JIT code generation";
   return 0;
 }
 
-MCJIT::MCJIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
+MCJIT::MCJIT(Module *m, TargetMachine *tm, TargetJITInfo &tji,
              JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
              bool AllocateGVsWithCode)
-  : ExecutionEngine(M) {
+  : ExecutionEngine(m), TM(tm), M(m), OS(Buffer) {
+
+  PM.add(new TargetData(*TM->getTargetData()));
+
+  // Turn the machine code intermediate representation into bytes in memory
+  // that may be executed.
+  if (TM->addPassesToEmitMC(PM, Ctx, OS, CodeGenOpt::Default, false)) {
+    report_fatal_error("Target does not support MC emission!");
+  }
+
+  // Initialize passes.
+  ExecutionEngine::addModule(M);
+  // FIXME: When we support multiple modules, we'll want to move the code
+  // gen and finalization out of the constructor here and do it more
+  // on-demand as part of getPointerToFunction().
+  PM.run(*M);
+  // Flush the output buffer so the SmallVector gets its data.
+  OS.flush();
 }
 
 MCJIT::~MCJIT() {
@@ -73,7 +92,6 @@
 }
 
 void *MCJIT::getPointerToFunction(Function *F) {
-  report_fatal_error("not yet implemented");
   return 0;
 }
 
@@ -87,6 +105,10 @@
 
 GenericValue MCJIT::runFunction(Function *F,
                                 const std::vector<GenericValue> &ArgValues) {
-  report_fatal_error("not yet implemented");
+  assert(ArgValues.size() == 0 && "JIT arg passing not supported yet");
+  void *FPtr = getPointerToFunction(F);
+  if (!FPtr)
+    report_fatal_error("Unable to locate function: '" + F->getName() + "'");
+  ((void(*)(void))FPtr)();
   return GenericValue();
 }

Modified: llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h?rev=127916&r1=127915&r2=127916&view=diff
==============================================================================
--- llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h (original)
+++ llvm/trunk/lib/ExecutionEngine/MCJIT/MCJIT.h Fri Mar 18 17:48:41 2011
@@ -10,14 +10,33 @@
 #ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_H
 #define LLVM_LIB_EXECUTIONENGINE_MCJIT_H
 
+#include "llvm/PassManager.h"
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/raw_ostream.h"
 
 namespace llvm {
 
+// FIXME: This makes all kinds of horrible assumptions for the time being,
+// like only having one module, not needing to worry about multi-threading,
+// blah blah. Purely in get-it-up-and-limping mode for now.
+
 class MCJIT : public ExecutionEngine {
-  MCJIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
+  MCJIT(Module *M, TargetMachine *tm, TargetJITInfo &tji,
         JITMemoryManager *JMM, CodeGenOpt::Level OptLevel,
         bool AllocateGVsWithCode);
+
+  TargetMachine *TM;
+  MCContext *Ctx;
+
+  // FIXME: These may need moved to a separate 'jitstate' member like the
+  // non-MC JIT does for multithreading and such. Just keep them here for now.
+  PassManager PM;
+  Module *M;
+  // FIXME: This really doesn't belong here.
+  SmallVector<char, 4096> Buffer; // Working buffer into which we JIT.
+  raw_svector_ostream OS;
+
 public:
   ~MCJIT();
 

Modified: llvm/trunk/tools/lli/lli.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lli/lli.cpp?rev=127916&r1=127915&r2=127916&view=diff
==============================================================================
--- llvm/trunk/tools/lli/lli.cpp (original)
+++ llvm/trunk/tools/lli/lli.cpp Fri Mar 18 17:48:41 2011
@@ -133,6 +133,7 @@
   // If we have a native target, initialize it to ensure it is linked in and
   // usable by the JIT.
   InitializeNativeTarget();
+  InitializeNativeTargetAsmPrinter();
 
   cl::ParseCommandLineOptions(argc, argv,
                               "llvm interpreter & dynamic compiler\n");





More information about the llvm-commits mailing list