Make it feasible for clients using EngineBuilder to capture the TargetMachine that is created as part of selecting the appropriate target.

This is necessary if the client wants to be able to mutate TargetOptions (for example, fast FP math mode) after the initial creation of the ExecutionEngine.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@153342 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Owen Anderson 2012-03-23 17:40:56 +00:00
parent f1113ef452
commit 8e1fc56b24
3 changed files with 53 additions and 48 deletions

View File

@ -602,19 +602,20 @@ public:
return *this; return *this;
} }
TargetMachine *selectTarget();
/// selectTarget - Pick a target either via -march or by guessing the native /// selectTarget - Pick a target either via -march or by guessing the native
/// arch. Add any CPU features specified via -mcpu or -mattr. /// arch. Add any CPU features specified via -mcpu or -mattr.
static TargetMachine *selectTarget(const Triple &TargetTriple, TargetMachine *selectTarget(const Triple &TargetTriple,
StringRef MArch, StringRef MArch,
StringRef MCPU, StringRef MCPU,
const SmallVectorImpl<std::string>& MAttrs, const SmallVectorImpl<std::string>& MAttrs);
const TargetOptions &Options,
Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL,
std::string *Err);
ExecutionEngine *create(); ExecutionEngine *create() {
return create(selectTarget());
}
ExecutionEngine *create(TargetMachine *TM);
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -402,14 +402,15 @@ ExecutionEngine *ExecutionEngine::create(Module *M,
std::string *ErrorStr, std::string *ErrorStr,
CodeGenOpt::Level OptLevel, CodeGenOpt::Level OptLevel,
bool GVsWithCode) { bool GVsWithCode) {
return EngineBuilder(M) EngineBuilder EB = EngineBuilder(M)
.setEngineKind(ForceInterpreter .setEngineKind(ForceInterpreter
? EngineKind::Interpreter ? EngineKind::Interpreter
: EngineKind::JIT) : EngineKind::JIT)
.setErrorStr(ErrorStr) .setErrorStr(ErrorStr)
.setOptLevel(OptLevel) .setOptLevel(OptLevel)
.setAllocateGVsWithCode(GVsWithCode) .setAllocateGVsWithCode(GVsWithCode);
.create();
return EB.create();
} }
/// createJIT - This is the factory method for creating a JIT for the current /// createJIT - This is the factory method for creating a JIT for the current
@ -430,21 +431,23 @@ ExecutionEngine *ExecutionEngine::createJIT(Module *M,
// Use the defaults for extra parameters. Users can use EngineBuilder to // Use the defaults for extra parameters. Users can use EngineBuilder to
// set them. // set them.
StringRef MArch = ""; EngineBuilder EB(M);
StringRef MCPU = ""; EB.setEngineKind(EngineKind::JIT);
SmallVector<std::string, 1> MAttrs; EB.setErrorStr(ErrorStr);
EB.setRelocationModel(RM);
EB.setCodeModel(CMM);
EB.setAllocateGVsWithCode(GVsWithCode);
EB.setOptLevel(OL);
EB.setJITMemoryManager(JMM);
Triple TT(M->getTargetTriple());
// TODO: permit custom TargetOptions here // TODO: permit custom TargetOptions here
TargetMachine *TM = TargetMachine *TM = EB.selectTarget();
EngineBuilder::selectTarget(TT, MArch, MCPU, MAttrs, TargetOptions(), RM,
CMM, OL, ErrorStr);
if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0; if (!TM || (ErrorStr && ErrorStr->length() > 0)) return 0;
return ExecutionEngine::JITCtor(M, ErrorStr, JMM, GVsWithCode, TM); return ExecutionEngine::JITCtor(M, ErrorStr, JMM, GVsWithCode, TM);
} }
ExecutionEngine *EngineBuilder::create() { ExecutionEngine *EngineBuilder::create(TargetMachine *TM) {
// Make sure we can resolve symbols in the program as well. The zero arg // 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. // to the function tells DynamicLibrary to load the program, not a library.
if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr)) if (sys::DynamicLibrary::LoadLibraryPermanently(0, ErrorStr))
@ -465,29 +468,24 @@ ExecutionEngine *EngineBuilder::create() {
// Unless the interpreter was explicitly selected or the JIT is not linked, // Unless the interpreter was explicitly selected or the JIT is not linked,
// try making a JIT. // try making a JIT.
if (WhichEngine & EngineKind::JIT) { if ((WhichEngine & EngineKind::JIT) && TM) {
Triple TT(M->getTargetTriple()); Triple TT(M->getTargetTriple());
if (TargetMachine *TM = EngineBuilder::selectTarget(TT, MArch, MCPU, MAttrs, if (!TM->getTarget().hasJIT()) {
Options, errs() << "WARNING: This target JIT is not designed for the host"
RelocModel, CMModel, << " you are running. If bad things happen, please choose"
OptLevel, ErrorStr)) { << " a different -march switch.\n";
if (!TM->getTarget().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";
}
if (UseMCJIT && ExecutionEngine::MCJITCtor) { if (UseMCJIT && ExecutionEngine::MCJITCtor) {
ExecutionEngine *EE = ExecutionEngine *EE =
ExecutionEngine::MCJITCtor(M, ErrorStr, JMM, ExecutionEngine::MCJITCtor(M, ErrorStr, JMM,
AllocateGVsWithCode, TM);
if (EE) return EE;
} else if (ExecutionEngine::JITCtor) {
ExecutionEngine *EE =
ExecutionEngine::JITCtor(M, ErrorStr, JMM,
AllocateGVsWithCode, TM); AllocateGVsWithCode, TM);
if (EE) return EE; if (EE) return EE;
} } else if (ExecutionEngine::JITCtor) {
ExecutionEngine *EE =
ExecutionEngine::JITCtor(M, ErrorStr, JMM,
AllocateGVsWithCode, TM);
if (EE) return EE;
} }
} }

View File

@ -15,6 +15,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/ExecutionEngine.h"
#include "llvm/Module.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/Triple.h"
#include "llvm/MC/SubtargetFeature.h" #include "llvm/MC/SubtargetFeature.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetMachine.h"
@ -24,17 +25,21 @@
using namespace llvm; using namespace llvm;
TargetMachine *EngineBuilder::selectTarget() {
StringRef MArch = "";
StringRef MCPU = "";
SmallVector<std::string, 1> MAttrs;
Triple TT(M->getTargetTriple());
return selectTarget(TT, MArch, MCPU, MAttrs);
}
/// selectTarget - Pick a target either via -march or by guessing the native /// selectTarget - Pick a target either via -march or by guessing the native
/// arch. Add any CPU features specified via -mcpu or -mattr. /// arch. Add any CPU features specified via -mcpu or -mattr.
TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple, TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
StringRef MArch, StringRef MArch,
StringRef MCPU, StringRef MCPU,
const SmallVectorImpl<std::string>& MAttrs, const SmallVectorImpl<std::string>& MAttrs) {
const TargetOptions &Options,
Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL,
std::string *ErrorStr) {
Triple TheTriple(TargetTriple); Triple TheTriple(TargetTriple);
if (TheTriple.getTriple().empty()) if (TheTriple.getTriple().empty())
TheTriple.setTriple(sys::getDefaultTargetTriple()); TheTriple.setTriple(sys::getDefaultTargetTriple());
@ -84,7 +89,8 @@ TargetMachine *EngineBuilder::selectTarget(const Triple &TargetTriple,
TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(), TargetMachine *Target = TheTarget->createTargetMachine(TheTriple.getTriple(),
MCPU, FeaturesStr, MCPU, FeaturesStr,
Options, Options,
RM, CM, OL); RelocModel, CMModel,
OptLevel);
assert(Target && "Could not allocate target machine!"); assert(Target && "Could not allocate target machine!");
return Target; return Target;
} }