summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm/Target/TargetMachine.h3
-rw-r--r--lib/CodeGen/LLVMTargetMachine.cpp26
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.cpp32
-rw-r--r--lib/ExecutionEngine/MCJIT/MCJIT.h21
-rw-r--r--tools/lli/lli.cpp1
5 files changed, 77 insertions, 6 deletions
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index 030bf5b89f..7dd5c4ef15 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -38,6 +38,7 @@ class PassManager;
class Pass;
class TargetELFWriterInfo;
class formatted_raw_ostream;
+class raw_ostream;
// Relocation model types.
namespace Reloc {
@@ -267,6 +268,7 @@ public:
///
virtual bool addPassesToEmitMC(PassManagerBase &,
MCContext *&,
+ raw_ostream &OS,
CodeGenOpt::Level,
bool = true) {
return true;
@@ -324,6 +326,7 @@ public:
///
virtual bool addPassesToEmitMC(PassManagerBase &PM,
MCContext *&Ctx,
+ raw_ostream &OS,
CodeGenOpt::Level OptLevel,
bool DisableVerify = true);
diff --git a/lib/CodeGen/LLVMTargetMachine.cpp b/lib/CodeGen/LLVMTargetMachine.cpp
index 377f80db7b..a9e8045918 100644
--- a/lib/CodeGen/LLVMTargetMachine.cpp
+++ b/lib/CodeGen/LLVMTargetMachine.cpp
@@ -224,11 +224,37 @@ bool LLVMTargetMachine::addPassesToEmitMachineCode(PassManagerBase &PM,
///
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();
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
index f1e9dab250..2b5ec5de7f 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp
@@ -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 @@ ExecutionEngine *MCJIT::createJIT(Module *M,
// 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::getPointerToBasicBlock(BasicBlock *BB) {
}
void *MCJIT::getPointerToFunction(Function *F) {
- report_fatal_error("not yet implemented");
return 0;
}
@@ -87,6 +105,10 @@ void MCJIT::freeMachineCodeForFunction(Function *F) {
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();
}
diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h
index cd1f989b10..e81e7c7d34 100644
--- a/lib/ExecutionEngine/MCJIT/MCJIT.h
+++ b/lib/ExecutionEngine/MCJIT/MCJIT.h
@@ -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();
diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp
index a756459ecc..014925c1a9 100644
--- a/tools/lli/lli.cpp
+++ b/tools/lli/lli.cpp
@@ -133,6 +133,7 @@ int main(int argc, char **argv, char * const *envp) {
// 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");