diff options
-rw-r--r-- | include/llvm/ExecutionEngine/MCJIT.h | 38 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.cpp | 92 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.h | 68 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/Makefile | 13 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/TargetSelect.cpp | 91 | ||||
-rw-r--r-- | lib/ExecutionEngine/Makefile | 2 | ||||
-rw-r--r-- | tools/lli/Makefile | 2 | ||||
-rw-r--r-- | tools/lli/lli.cpp | 1 |
9 files changed, 309 insertions, 2 deletions
diff --git a/include/llvm/ExecutionEngine/MCJIT.h b/include/llvm/ExecutionEngine/MCJIT.h new file mode 100644 index 0000000000..f956a5029b --- /dev/null +++ b/include/llvm/ExecutionEngine/MCJIT.h @@ -0,0 +1,38 @@ +//===-- MCJIT.h - MC-Based Just-In-Time Execution Engine --------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file forces the MCJIT to link in on certain operating systems. +// (Windows). +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_EXECUTION_ENGINE_MCJIT_H +#define LLVM_EXECUTION_ENGINE_MCJIT_H + +#include "llvm/ExecutionEngine/ExecutionEngine.h" +#include <cstdlib> + +extern "C" void LLVMLinkInMCJIT(); + +namespace { + struct ForceMCJITLinking { + ForceMCJITLinking() { + // We must reference the passes in such a way that compilers will not + // delete it all as dead code, even with whole program optimization, + // yet is effectively a NO-OP. As the compiler isn't smart enough + // to know that getenv() never returns -1, this will do the job. + if (std::getenv("bar") != (char*) -1) + return; + + LLVMLinkInMCJIT(); + } + } ForceMCJITLinking; +} + +#endif diff --git a/lib/ExecutionEngine/MCJIT/CMakeLists.txt b/lib/ExecutionEngine/MCJIT/CMakeLists.txt new file mode 100644 index 0000000000..f7ed176fef --- /dev/null +++ b/lib/ExecutionEngine/MCJIT/CMakeLists.txt @@ -0,0 +1,4 @@ +add_llvm_library(LLVMMCJIT + MCJIT.cpp + TargetSelect.cpp + ) diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp new file mode 100644 index 0000000000..532a438ae8 --- /dev/null +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -0,0 +1,92 @@ +//===-- JIT.cpp - MC-based Just-in-Time Compiler --------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "MCJIT.h" +#include "llvm/ExecutionEngine/GenericValue.h" +#include "llvm/ExecutionEngine/MCJIT.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/System/DynamicLibrary.h" + +using namespace llvm; + +namespace { + +static struct RegisterJIT { + RegisterJIT() { MCJIT::Register(); } +} JITRegistrator; + +} + +extern "C" void LLVMLinkInMCJIT() { +} + +ExecutionEngine *MCJIT::createJIT(Module *M, + std::string *ErrorStr, + JITMemoryManager *JMM, + CodeGenOpt::Level OptLevel, + bool GVsWithCode, + CodeModel::Model CMM, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs) { + // Try to register the program as a source of symbols to resolve against. + // + // FIXME: Don't do this here. + sys::DynamicLibrary::LoadLibraryPermanently(0, NULL); + + // Pick a target either via -march or by guessing the native arch. + // + // FIXME: This should be lifted out of here, it isn't something which should + // be part of the JIT policy, rather the burden for this selection should be + // pushed to clients. + TargetMachine *TM = MCJIT::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr); + if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0; + TM->setCodeModel(CMM); + + // If the target supports JIT code generation, create the JIT. + if (TargetJITInfo *TJ = TM->getJITInfo()) + 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, + JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, + bool AllocateGVsWithCode) + : ExecutionEngine(M) { +} + +MCJIT::~MCJIT() { +} + +void *MCJIT::getPointerToBasicBlock(BasicBlock *BB) { + report_fatal_error("not yet implemented"); + return 0; +} + +void *MCJIT::getPointerToFunction(Function *F) { + report_fatal_error("not yet implemented"); + return 0; +} + +void *MCJIT::recompileAndRelinkFunction(Function *F) { + report_fatal_error("not yet implemented"); +} + +void MCJIT::freeMachineCodeForFunction(Function *F) { + report_fatal_error("not yet implemented"); +} + +GenericValue MCJIT::runFunction(Function *F, + const std::vector<GenericValue> &ArgValues) { + report_fatal_error("not yet implemented"); + return GenericValue(); +} diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h new file mode 100644 index 0000000000..cd1f989b10 --- /dev/null +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -0,0 +1,68 @@ +//===-- MCJIT.h - Class definition for the MCJIT ----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_LIB_EXECUTIONENGINE_MCJIT_H +#define LLVM_LIB_EXECUTIONENGINE_MCJIT_H + +#include "llvm/ExecutionEngine/ExecutionEngine.h" + +namespace llvm { + +class MCJIT : public ExecutionEngine { + MCJIT(Module *M, TargetMachine &tm, TargetJITInfo &tji, + JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, + bool AllocateGVsWithCode); +public: + ~MCJIT(); + + /// @name ExecutionEngine interface implementation + /// @{ + + virtual void *getPointerToBasicBlock(BasicBlock *BB); + + virtual void *getPointerToFunction(Function *F); + + virtual void *recompileAndRelinkFunction(Function *F); + + virtual void freeMachineCodeForFunction(Function *F); + + virtual GenericValue runFunction(Function *F, + const std::vector<GenericValue> &ArgValues); + + /// @} + /// @name (Private) Registration Interfaces + /// @{ + + static void Register() { + MCJITCtor = createJIT; + } + + // FIXME: This routine is scheduled for termination. Do not use it. + static TargetMachine *selectTarget(Module *M, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs, + std::string *Err); + + static ExecutionEngine *createJIT(Module *M, + std::string *ErrorStr, + JITMemoryManager *JMM, + CodeGenOpt::Level OptLevel, + bool GVsWithCode, + CodeModel::Model CMM, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs); + + // @} +}; + +} // End llvm namespace + +#endif diff --git a/lib/ExecutionEngine/MCJIT/Makefile b/lib/ExecutionEngine/MCJIT/Makefile new file mode 100644 index 0000000000..967efbc0ef --- /dev/null +++ b/lib/ExecutionEngine/MCJIT/Makefile @@ -0,0 +1,13 @@ +##===- lib/ExecutionEngine/MCJIT/Makefile ------------------*- Makefile -*-===## +# +# The LLVM Compiler Infrastructure +# +# This file is distributed under the University of Illinois Open Source +# License. See LICENSE.TXT for details. +# +##===----------------------------------------------------------------------===## + +LEVEL = ../../.. +LIBRARYNAME = LLVMMCJIT + +include $(LEVEL)/Makefile.common diff --git a/lib/ExecutionEngine/MCJIT/TargetSelect.cpp b/lib/ExecutionEngine/MCJIT/TargetSelect.cpp new file mode 100644 index 0000000000..0ade39666b --- /dev/null +++ b/lib/ExecutionEngine/MCJIT/TargetSelect.cpp @@ -0,0 +1,91 @@ +//===-- TargetSelect.cpp - Target Chooser Code ----------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This just asks the TargetRegistry for the appropriate JIT to use, and allows +// the user to specify a specific one on the commandline with -march=x. Clients +// should initialize targets prior to calling createJIT. +// +//===----------------------------------------------------------------------===// + +#include "MCJIT.h" +#include "llvm/Module.h" +#include "llvm/ADT/Triple.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/raw_ostream.h" +#include "llvm/System/Host.h" +#include "llvm/Target/SubtargetFeature.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetRegistry.h" +using namespace llvm; + +/// selectTarget - Pick a target either via -march or by guessing the native +/// arch. Add any CPU features specified via -mcpu or -mattr. +TargetMachine *MCJIT::selectTarget(Module *Mod, + StringRef MArch, + StringRef MCPU, + const SmallVectorImpl<std::string>& MAttrs, + std::string *ErrorStr) { + Triple TheTriple(Mod->getTargetTriple()); + if (TheTriple.getTriple().empty()) + TheTriple.setTriple(sys::getHostTriple()); + + // Adjust the triple to match what the user requested. + const Target *TheTarget = 0; + if (!MArch.empty()) { + for (TargetRegistry::iterator it = TargetRegistry::begin(), + ie = TargetRegistry::end(); it != ie; ++it) { + if (MArch == it->getName()) { + TheTarget = &*it; + break; + } + } + + if (!TheTarget) { + *ErrorStr = "No available targets are compatible with this -march, " + "see -version for the available targets.\n"; + return 0; + } + + // Adjust the triple to match (if known), otherwise stick with the + // module/host triple. + Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); + if (Type != Triple::UnknownArch) + TheTriple.setArch(Type); + } else { + std::string Error; + TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Error); + if (TheTarget == 0) { + if (ErrorStr) + *ErrorStr = Error; + return 0; + } + } + + if (!TheTarget->hasJIT()) { + errs() << "WARNING: This target JIT is not designed for the host you are" + << " running. If bad things happen, please choose a different " + << "-march switch.\n"; + } + + // Package up features to be passed to target/subtarget + std::string FeaturesStr; + if (!MCPU.empty() || !MAttrs.empty()) { + SubtargetFeatures Features; + Features.setCPU(MCPU); + for (unsigned i = 0; i != MAttrs.size(); ++i) + Features.AddFeature(MAttrs[i]); + FeaturesStr = Features.getString(); + } + + // Allocate a target... + TargetMachine *Target = + TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr); + assert(Target && "Could not allocate target machine!"); + return Target; +} diff --git a/lib/ExecutionEngine/Makefile b/lib/ExecutionEngine/Makefile index e0e050e897..1858d77661 100644 --- a/lib/ExecutionEngine/Makefile +++ b/lib/ExecutionEngine/Makefile @@ -8,6 +8,6 @@ ##===----------------------------------------------------------------------===## LEVEL = ../.. LIBRARYNAME = LLVMExecutionEngine -PARALLEL_DIRS = Interpreter JIT +PARALLEL_DIRS = Interpreter JIT MCJIT include $(LEVEL)/Makefile.common diff --git a/tools/lli/Makefile b/tools/lli/Makefile index 3217d23d31..80aa82b4d6 100644 --- a/tools/lli/Makefile +++ b/tools/lli/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := lli -LINK_COMPONENTS := jit interpreter nativecodegen bitreader asmparser selectiondag +LINK_COMPONENTS := mcjit jit interpreter nativecodegen bitreader asmparser selectiondag # Enable JIT support include $(LEVEL)/Makefile.common diff --git a/tools/lli/lli.cpp b/tools/lli/lli.cpp index 507e38d920..add6248fda 100644 --- a/tools/lli/lli.cpp +++ b/tools/lli/lli.cpp @@ -23,6 +23,7 @@ #include "llvm/ExecutionEngine/Interpreter.h" #include "llvm/ExecutionEngine/JIT.h" #include "llvm/ExecutionEngine/JITEventListener.h" +#include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" |