diff options
Diffstat (limited to 'lib/ExecutionEngine')
-rw-r--r-- | lib/ExecutionEngine/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/ExecutionEngine/ExecutionEngine.cpp | 67 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.cpp | 29 | ||||
-rw-r--r-- | lib/ExecutionEngine/JIT/JIT.h | 13 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/CMakeLists.txt | 1 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.cpp | 24 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJIT.h | 12 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h | 12 | ||||
-rw-r--r-- | lib/ExecutionEngine/MCJIT/TargetSelect.cpp | 91 | ||||
-rw-r--r-- | lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp | 31 | ||||
-rw-r--r-- | lib/ExecutionEngine/TargetSelect.cpp (renamed from lib/ExecutionEngine/JIT/TargetSelect.cpp) | 12 |
12 files changed, 99 insertions, 195 deletions
diff --git a/lib/ExecutionEngine/CMakeLists.txt b/lib/ExecutionEngine/CMakeLists.txt index 8bff265..58caae8 100644 --- a/lib/ExecutionEngine/CMakeLists.txt +++ b/lib/ExecutionEngine/CMakeLists.txt @@ -1,6 +1,7 @@ add_llvm_library(LLVMExecutionEngine ExecutionEngine.cpp ExecutionEngineBindings.cpp + TargetSelect.cpp ) add_subdirectory(Interpreter) diff --git a/lib/ExecutionEngine/ExecutionEngine.cpp b/lib/ExecutionEngine/ExecutionEngine.cpp index 2b1e878..7652090 100644 --- a/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/lib/ExecutionEngine/ExecutionEngine.cpp @@ -29,6 +29,7 @@ #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/Host.h" #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetMachine.h" #include <cmath> #include <cstring> using namespace llvm; @@ -42,20 +43,14 @@ ExecutionEngine *(*ExecutionEngine::JITCtor)( JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs) = 0; + TargetMachine *TM) = 0; ExecutionEngine *(*ExecutionEngine::MCJITCtor)( Module *M, std::string *ErrorStr, JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs) = 0; + TargetMachine *TM) = 0; ExecutionEngine *(*ExecutionEngine::InterpCtor)(Module *M, std::string *ErrorStr) = 0; @@ -419,6 +414,35 @@ ExecutionEngine *ExecutionEngine::create(Module *M, .create(); } +/// createJIT - This is the factory method for creating a JIT for the current +/// machine, it does not fall back to the interpreter. This takes ownership +/// of the module. +ExecutionEngine *ExecutionEngine::createJIT(Module *M, + std::string *ErrorStr, + JITMemoryManager *JMM, + CodeGenOpt::Level OptLevel, + bool GVsWithCode, + CodeModel::Model CMM) { + if (ExecutionEngine::JITCtor == 0) { + if (ErrorStr) + *ErrorStr = "JIT has not been linked in."; + return 0; + } + + // Use the defaults for extra parameters. Users can use EngineBuilder to + // set them. + StringRef MArch = ""; + StringRef MCPU = ""; + SmallVector<std::string, 1> MAttrs; + + TargetMachine *TM = + EngineBuilder::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr); + if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0; + TM->setCodeModel(CMM); + + return ExecutionEngine::JITCtor(M, ErrorStr, JMM, OptLevel, GVsWithCode, TM); +} + 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. @@ -441,18 +465,21 @@ ExecutionEngine *EngineBuilder::create() { // Unless the interpreter was explicitly selected or the JIT is not linked, // try making a JIT. if (WhichEngine & EngineKind::JIT) { - if (UseMCJIT && ExecutionEngine::MCJITCtor) { - ExecutionEngine *EE = - ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, OptLevel, - AllocateGVsWithCode, CMModel, - MArch, MCPU, MAttrs); - if (EE) return EE; - } else if (ExecutionEngine::JITCtor) { - ExecutionEngine *EE = - ExecutionEngine::JITCtor(M, ErrorStr, JMM, OptLevel, - AllocateGVsWithCode, CMModel, - MArch, MCPU, MAttrs); - if (EE) return EE; + if (TargetMachine *TM = + EngineBuilder::selectTarget(M, MArch, MCPU, MAttrs, ErrorStr)) { + TM->setCodeModel(CMModel); + + if (UseMCJIT && ExecutionEngine::MCJITCtor) { + ExecutionEngine *EE = + ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, OptLevel, + AllocateGVsWithCode, TM); + if (EE) return EE; + } else if (ExecutionEngine::JITCtor) { + ExecutionEngine *EE = + ExecutionEngine::JITCtor(M, ErrorStr, JMM, OptLevel, + AllocateGVsWithCode, TM); + if (EE) return EE; + } } } diff --git a/lib/ExecutionEngine/JIT/CMakeLists.txt b/lib/ExecutionEngine/JIT/CMakeLists.txt index 42020d6..cefb0ae 100644 --- a/lib/ExecutionEngine/JIT/CMakeLists.txt +++ b/lib/ExecutionEngine/JIT/CMakeLists.txt @@ -9,5 +9,4 @@ add_llvm_library(LLVMJIT JITEmitter.cpp JITMemoryManager.cpp OProfileJITEventListener.cpp - TargetSelect.cpp ) diff --git a/lib/ExecutionEngine/JIT/JIT.cpp b/lib/ExecutionEngine/JIT/JIT.cpp index d1f87ac..8fceaf2 100644 --- a/lib/ExecutionEngine/JIT/JIT.cpp +++ b/lib/ExecutionEngine/JIT/JIT.cpp @@ -203,39 +203,18 @@ void DarwinRegisterFrame(void* FrameBegin) { /// createJIT - This is the factory method for creating a JIT for the current /// machine, it does not fall back to the interpreter. This takes ownership /// of the module. -ExecutionEngine *ExecutionEngine::createJIT(Module *M, - std::string *ErrorStr, - JITMemoryManager *JMM, - CodeGenOpt::Level OptLevel, - bool GVsWithCode, - CodeModel::Model CMM) { - // Use the defaults for extra parameters. Users can use EngineBuilder to - // set them. - StringRef MArch = ""; - StringRef MCPU = ""; - SmallVector<std::string, 1> MAttrs; - return JIT::createJIT(M, ErrorStr, JMM, OptLevel, GVsWithCode, CMM, - MArch, MCPU, MAttrs); -} - ExecutionEngine *JIT::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) { + TargetMachine *TM) { // 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. - TargetMachine *TM = JIT::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 a the JIT. + // If the target supports JIT code generation, create the JIT. if (TargetJITInfo *TJ = TM->getJITInfo()) { return new JIT(M, *TM, *TJ, JMM, OptLevel, GVsWithCode); } else { diff --git a/lib/ExecutionEngine/JIT/JIT.h b/lib/ExecutionEngine/JIT/JIT.h index b576c16..b879fc3 100644 --- a/lib/ExecutionEngine/JIT/JIT.h +++ b/lib/ExecutionEngine/JIT/JIT.h @@ -181,23 +181,12 @@ public: /// 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(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); + TargetMachine *TM); // Run the JIT on F and return information about the generated code void runJITOnFunction(Function *F, MachineCodeInfo *MCI = 0); diff --git a/lib/ExecutionEngine/MCJIT/CMakeLists.txt b/lib/ExecutionEngine/MCJIT/CMakeLists.txt index 6553079..38fdffa 100644 --- a/lib/ExecutionEngine/MCJIT/CMakeLists.txt +++ b/lib/ExecutionEngine/MCJIT/CMakeLists.txt @@ -1,5 +1,4 @@ add_llvm_library(LLVMMCJIT MCJIT.cpp - TargetSelect.cpp Intercept.cpp ) diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.cpp b/lib/ExecutionEngine/MCJIT/MCJIT.cpp index 3d4ee36..4475f4d 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.cpp +++ b/lib/ExecutionEngine/MCJIT/MCJIT.cpp @@ -38,27 +38,15 @@ ExecutionEngine *MCJIT::createJIT(Module *M, JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode, - CodeModel::Model CMM, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs) { + TargetMachine *TM) { // 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, new MCJITMemoryManager(JMM), OptLevel, + return new MCJIT(M, TM, *TJ, new MCJITMemoryManager(JMM, M), OptLevel, GVsWithCode); if (ErrorStr) @@ -114,8 +102,12 @@ void *MCJIT::getPointerToFunction(Function *F) { return Addr; } - Twine Name = TM->getMCAsmInfo()->getGlobalPrefix() + F->getName(); - return (void*)Dyld.getSymbolAddress(Name.str()); + // FIXME: Should we be using the mangler for this? Probably. + StringRef BaseName = F->getName(); + if (BaseName[0] == '\1') + return (void*)Dyld.getSymbolAddress(BaseName.substr(1)); + return (void*)Dyld.getSymbolAddress((TM->getMCAsmInfo()->getGlobalPrefix() + + BaseName).str()); } void *MCJIT::recompileAndRelinkFunction(Function *F) { diff --git a/lib/ExecutionEngine/MCJIT/MCJIT.h b/lib/ExecutionEngine/MCJIT/MCJIT.h index 1b50766..b64c21a 100644 --- a/lib/ExecutionEngine/MCJIT/MCJIT.h +++ b/lib/ExecutionEngine/MCJIT/MCJIT.h @@ -76,22 +76,12 @@ public: 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); + TargetMachine *TM); // @} }; diff --git a/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h b/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h index e3c6fda..40bc031 100644 --- a/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h +++ b/lib/ExecutionEngine/MCJIT/MCJITMemoryManager.h @@ -26,7 +26,7 @@ class MCJITMemoryManager : public RTDyldMemoryManager { // FIXME: Multiple modules. Module *M; public: - MCJITMemoryManager(JITMemoryManager *jmm) : JMM(jmm) {} + MCJITMemoryManager(JITMemoryManager *jmm, Module *m) : JMM(jmm), M(m) {} // Allocate ActualSize bytes, or more, for the named function. Return // a pointer to the allocated memory and update Size to reflect how much @@ -36,6 +36,11 @@ public: // prefix. if (Name[0] == '_') ++Name; Function *F = M->getFunction(Name); + // Some ObjC names have a prefixed \01 in the IR. If we failed to find + // the symbol and it's of the ObjC conventions (starts with "-"), try + // prepending a \01 and see if we can find it that way. + if (!F && Name[0] == '-') + F = M->getFunction((Twine("\1") + Name).str()); assert(F && "No matching function in JIT IR Module!"); return JMM->startFunctionBody(F, Size); } @@ -48,6 +53,11 @@ public: // prefix. if (Name[0] == '_') ++Name; Function *F = M->getFunction(Name); + // Some ObjC names have a prefixed \01 in the IR. If we failed to find + // the symbol and it's of the ObjC conventions (starts with "-"), try + // prepending a \01 and see if we can find it that way. + if (!F && Name[0] == '-') + F = M->getFunction((Twine("\1") + Name).str()); assert(F && "No matching function in JIT IR Module!"); JMM->endFunctionBody(F, FunctionStart, FunctionEnd); } diff --git a/lib/ExecutionEngine/MCJIT/TargetSelect.cpp b/lib/ExecutionEngine/MCJIT/TargetSelect.cpp deleted file mode 100644 index 50f6593..0000000 --- a/lib/ExecutionEngine/MCJIT/TargetSelect.cpp +++ /dev/null @@ -1,91 +0,0 @@ -//===-- 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/Support/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/RuntimeDyld/RuntimeDyld.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp index 065e5e3..eda4cbb 100644 --- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp +++ b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyld.cpp @@ -129,18 +129,19 @@ void RuntimeDyldImpl::extractFunction(StringRef Name, uint8_t *StartAddress, uint8_t *EndAddress) { // Allocate memory for the function via the memory manager. uintptr_t Size = EndAddress - StartAddress + 1; - uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), Size); + uintptr_t AllocSize = Size; + uint8_t *Mem = MemMgr->startFunctionBody(Name.data(), AllocSize); assert(Size >= (uint64_t)(EndAddress - StartAddress + 1) && "Memory manager failed to allocate enough memory!"); // Copy the function payload into the memory block. - memcpy(Mem, StartAddress, EndAddress - StartAddress + 1); + memcpy(Mem, StartAddress, Size); MemMgr->endFunctionBody(Name.data(), Mem, Mem + Size); // Remember where we put it. Functions[Name] = sys::MemoryBlock(Mem, Size); // Default the assigned address for this symbol to wherever this // allocated it. SymbolTable[Name] = Mem; - DEBUG(dbgs() << " allocated to " << Mem << "\n"); + DEBUG(dbgs() << " allocated to [" << Mem << ", " << Mem + Size << "]\n"); } bool RuntimeDyldImpl:: @@ -268,9 +269,9 @@ loadSegment32(const MachOObject *Obj, if (!Sect) return Error("unable to load section: '" + Twine(SectNum) + "'"); - // FIXME: Improve check. + // FIXME: For the time being, we're only loading text segments. if (Sect->Flags != 0x80000400) - return Error("unsupported section type!"); + continue; // Address and names of symbols in the section. typedef std::pair<uint64_t, StringRef> SymbolEntry; @@ -295,11 +296,11 @@ loadSegment32(const MachOObject *Obj, // FIXME: Check the symbol type and flags. if (STE->Type != 0xF) // external, defined in this section. - return Error("unexpected symbol type!"); + continue; // Flags == 0x8 marks a thumb function for ARM, which is fine as it // doesn't require any special handling here. if (STE->Flags != 0x0 && STE->Flags != 0x8) - return Error("unexpected symbol type!"); + continue; // Remember the symbol. Symbols.push_back(SymbolEntry(STE->Value, Name)); @@ -310,6 +311,10 @@ loadSegment32(const MachOObject *Obj, // Sort the symbols by address, just in case they didn't come in that way. array_pod_sort(Symbols.begin(), Symbols.end()); + // If there weren't any functions (odd, but just in case...) + if (!Symbols.size()) + continue; + // Extract the function data. uint8_t *Base = (uint8_t*)Obj->getData(SegmentLC->FileOffset, SegmentLC->FileSize).data(); @@ -403,9 +408,9 @@ loadSegment64(const MachOObject *Obj, if (!Sect) return Error("unable to load section: '" + Twine(SectNum) + "'"); - // FIXME: Improve check. + // FIXME: For the time being, we're only loading text segments. if (Sect->Flags != 0x80000400) - return Error("unsupported section type!"); + continue; // Address and names of symbols in the section. typedef std::pair<uint64_t, StringRef> SymbolEntry; @@ -430,9 +435,9 @@ loadSegment64(const MachOObject *Obj, // FIXME: Check the symbol type and flags. if (STE->Type != 0xF) // external, defined in this section. - return Error("unexpected symbol type!"); + continue; if (STE->Flags != 0x0) - return Error("unexpected symbol type!"); + continue; // Remember the symbol. Symbols.push_back(SymbolEntry(STE->Value, Name)); @@ -443,6 +448,10 @@ loadSegment64(const MachOObject *Obj, // Sort the symbols by address, just in case they didn't come in that way. array_pod_sort(Symbols.begin(), Symbols.end()); + // If there weren't any functions (odd, but just in case...) + if (!Symbols.size()) + continue; + // Extract the function data. uint8_t *Base = (uint8_t*)Obj->getData(Segment64LC->FileOffset, Segment64LC->FileSize).data(); diff --git a/lib/ExecutionEngine/JIT/TargetSelect.cpp b/lib/ExecutionEngine/TargetSelect.cpp index 8d92ab0..a8822e5 100644 --- a/lib/ExecutionEngine/JIT/TargetSelect.cpp +++ b/lib/ExecutionEngine/TargetSelect.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "JIT.h" +#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/Module.h" #include "llvm/ADT/Triple.h" #include "llvm/Support/CommandLine.h" @@ -26,11 +26,11 @@ 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 *JIT::selectTarget(Module *Mod, - StringRef MArch, - StringRef MCPU, - const SmallVectorImpl<std::string>& MAttrs, - std::string *ErrorStr) { +TargetMachine *EngineBuilder::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()); |