forked from OSchip/llvm-project
[ORC] Extract and tidy up JITTargetMachineBuilder, add unit test.
(1) Adds comments for the API. (2) Removes the setArch method: This is redundant: the setArchStr method on the triple should be used instead. (3) Turns EmulatedTLS on by default. This matches EngineBuilder's behavior. llvm-svn: 343423
This commit is contained in:
parent
0f8f0d6d1d
commit
d435ce4343
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ExecutionEngine/ObjectCache.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
#include "llvm/Object/Binary.h"
|
||||
#include "llvm/Object/ObjectFile.h"
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
#include "llvm/ExecutionEngine/Orc/OrcError.h"
|
||||
#include "llvm/ExecutionEngine/RuntimeDyld.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <algorithm>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
@ -39,48 +38,6 @@ class Value;
|
|||
|
||||
namespace orc {
|
||||
|
||||
/// A utility class for building TargetMachines for JITs.
|
||||
class JITTargetMachineBuilder {
|
||||
public:
|
||||
JITTargetMachineBuilder(Triple TT);
|
||||
static Expected<JITTargetMachineBuilder> detectHost();
|
||||
Expected<std::unique_ptr<TargetMachine>> createTargetMachine();
|
||||
|
||||
JITTargetMachineBuilder &setArch(std::string Arch) {
|
||||
this->Arch = std::move(Arch);
|
||||
return *this;
|
||||
}
|
||||
JITTargetMachineBuilder &setCPU(std::string CPU) {
|
||||
this->CPU = std::move(CPU);
|
||||
return *this;
|
||||
}
|
||||
JITTargetMachineBuilder &setRelocationModel(Optional<Reloc::Model> RM) {
|
||||
this->RM = std::move(RM);
|
||||
return *this;
|
||||
}
|
||||
JITTargetMachineBuilder &setCodeModel(Optional<CodeModel::Model> CM) {
|
||||
this->CM = std::move(CM);
|
||||
return *this;
|
||||
}
|
||||
JITTargetMachineBuilder &
|
||||
addFeatures(const std::vector<std::string> &FeatureVec);
|
||||
SubtargetFeatures &getFeatures() { return Features; }
|
||||
TargetOptions &getOptions() { return Options; }
|
||||
|
||||
Triple& getTargetTriple() { return TT; }
|
||||
const Triple& getTargetTriple() const { return TT; }
|
||||
|
||||
private:
|
||||
Triple TT;
|
||||
std::string Arch;
|
||||
std::string CPU;
|
||||
SubtargetFeatures Features;
|
||||
TargetOptions Options;
|
||||
Optional<Reloc::Model> RM;
|
||||
Optional<CodeModel::Model> CM;
|
||||
CodeGenOpt::Level OptLevel = CodeGenOpt::Default;
|
||||
};
|
||||
|
||||
/// This iterator provides a convenient way to iterate over the elements
|
||||
/// of an llvm.global_ctors/llvm.global_dtors instance.
|
||||
///
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
//===- JITTargetMachineBuilder.h - Build TargetMachines for JIT -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// A utitily for building TargetMachines for JITs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_EXECUTIONENGINE_ORC_JITTARGETMACHINEBUILDER_H
|
||||
#define LLVM_EXECUTIONENGINE_ORC_JITTARGETMACHINEBUILDER_H
|
||||
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/MC/SubtargetFeature.h"
|
||||
#include "llvm/Support/CodeGen.h"
|
||||
#include "llvm/Support/Error.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
/// A utility class for building TargetMachines for JITs.
|
||||
class JITTargetMachineBuilder {
|
||||
public:
|
||||
/// Create a JITTargetMachineBuilder based on the given triple.
|
||||
///
|
||||
/// Note: TargetOptions is default-constructed, then EmulatedTLS and
|
||||
/// ExplicitEmulatedTLS are set to true. If EmulatedTLS is not
|
||||
/// required, these values should be reset before calling
|
||||
/// createTargetMachine.
|
||||
JITTargetMachineBuilder(Triple TT);
|
||||
|
||||
/// Create a JITTargetMachineBuilder for the host system.
|
||||
///
|
||||
/// Note: TargetOptions is default-constructed, then EmulatedTLS and
|
||||
/// ExplicitEmulatedTLS are set to true. If EmulatedTLS is not
|
||||
/// required, these values should be reset before calling
|
||||
/// createTargetMachine.
|
||||
static Expected<JITTargetMachineBuilder> detectHost();
|
||||
|
||||
/// Create a TargetMachine.
|
||||
///
|
||||
/// This operation will fail if the requested target is not registered,
|
||||
/// in which case see llvm/Support/TargetSelect.h. To JIT IR the Target and
|
||||
/// the target's AsmPrinter must both be registered. To JIT assembly
|
||||
/// (including inline and module level assembly) the target's AsmParser must
|
||||
/// also be registered.
|
||||
Expected<std::unique_ptr<TargetMachine>> createTargetMachine();
|
||||
|
||||
/// Set the CPU string.
|
||||
JITTargetMachineBuilder &setCPU(std::string CPU) {
|
||||
this->CPU = std::move(CPU);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Set the relocation model.
|
||||
JITTargetMachineBuilder &setRelocationModel(Optional<Reloc::Model> RM) {
|
||||
this->RM = std::move(RM);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Set the code model.
|
||||
JITTargetMachineBuilder &setCodeModel(Optional<CodeModel::Model> CM) {
|
||||
this->CM = std::move(CM);
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Set the LLVM CodeGen optimization level.
|
||||
JITTargetMachineBuilder &setCodeGenOptLevel(CodeGenOpt::Level OptLevel) {
|
||||
this->OptLevel = OptLevel;
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Add subtarget features.
|
||||
JITTargetMachineBuilder &
|
||||
addFeatures(const std::vector<std::string> &FeatureVec);
|
||||
|
||||
/// Access subtarget features.
|
||||
SubtargetFeatures &getFeatures() { return Features; }
|
||||
|
||||
/// Access subtarget features.
|
||||
const SubtargetFeatures &getFeatures() const { return Features; }
|
||||
|
||||
/// Access TargetOptions.
|
||||
TargetOptions &getOptions() { return Options; }
|
||||
|
||||
/// Access TargetOptions.
|
||||
const TargetOptions &getOptions() const { return Options; }
|
||||
|
||||
/// Access Triple.
|
||||
Triple &getTargetTriple() { return TT; }
|
||||
|
||||
/// Access Triple.
|
||||
const Triple &getTargetTriple() const { return TT; }
|
||||
|
||||
private:
|
||||
Triple TT;
|
||||
std::string CPU;
|
||||
SubtargetFeatures Features;
|
||||
TargetOptions Options;
|
||||
Optional<Reloc::Model> RM;
|
||||
Optional<CodeModel::Model> CM;
|
||||
CodeGenOpt::Level OptLevel = CodeGenOpt::None;
|
||||
};
|
||||
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_EXECUTIONENGINE_ORC_JITTARGETMACHINEBUILDER_H
|
|
@ -19,6 +19,7 @@
|
|||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ObjectTransformLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ThreadSafeModule.h"
|
||||
|
@ -51,6 +52,8 @@ public:
|
|||
/// Convenience method for defining an absolute symbol.
|
||||
Error defineAbsolute(StringRef Name, JITEvaluatedSymbol Address);
|
||||
|
||||
/// Convenience method for defining an
|
||||
|
||||
/// Adds an IR module to the given JITDylib.
|
||||
Error addIRModule(JITDylib &JD, ThreadSafeModule TSM);
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ add_llvm_library(LLVMOrcJIT
|
|||
IndirectionUtils.cpp
|
||||
IRCompileLayer.cpp
|
||||
IRTransformLayer.cpp
|
||||
JITTargetMachineBuilder.cpp
|
||||
LazyReexports.cpp
|
||||
Legacy.cpp
|
||||
Layer.cpp
|
||||
|
|
|
@ -19,45 +19,6 @@
|
|||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
|
||||
: TT(std::move(TT)) {}
|
||||
|
||||
Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
|
||||
return JITTargetMachineBuilder(Triple(sys::getProcessTriple()));
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<TargetMachine>>
|
||||
JITTargetMachineBuilder::createTargetMachine() {
|
||||
if (!Arch.empty()) {
|
||||
Triple::ArchType Type = Triple::getArchTypeForLLVMName(Arch);
|
||||
|
||||
if (Type == Triple::UnknownArch)
|
||||
return make_error<StringError>(std::string("Unknown arch: ") + Arch,
|
||||
inconvertibleErrorCode());
|
||||
}
|
||||
|
||||
std::string ErrMsg;
|
||||
auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg);
|
||||
if (!TheTarget)
|
||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
||||
|
||||
auto *TM =
|
||||
TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(),
|
||||
Options, RM, CM, OptLevel, /*JIT*/ true);
|
||||
if (!TM)
|
||||
return make_error<StringError>("Could not allocate target machine",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
return std::unique_ptr<TargetMachine>(TM);
|
||||
}
|
||||
|
||||
JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures(
|
||||
const std::vector<std::string> &FeatureVec) {
|
||||
for (const auto &F : FeatureVec)
|
||||
Features.AddFeature(F);
|
||||
return *this;
|
||||
}
|
||||
|
||||
CtorDtorIterator::CtorDtorIterator(const GlobalVariable *GV, bool End)
|
||||
: InitList(
|
||||
GV ? dyn_cast_or_null<ConstantArray>(GV->getInitializer()) : nullptr),
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
//===----- JITTargetMachineBuilder.cpp - Build TargetMachines for JIT -----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
JITTargetMachineBuilder::JITTargetMachineBuilder(Triple TT)
|
||||
: TT(std::move(TT)) {
|
||||
Options.EmulatedTLS = true;
|
||||
Options.ExplicitEmulatedTLS = true;
|
||||
}
|
||||
|
||||
Expected<JITTargetMachineBuilder> JITTargetMachineBuilder::detectHost() {
|
||||
// FIXME: getProcessTriple is bogus. It returns the host LLVM was compiled on,
|
||||
// rather than a valid triple for the current process.
|
||||
return JITTargetMachineBuilder(Triple(sys::getProcessTriple()));
|
||||
}
|
||||
|
||||
Expected<std::unique_ptr<TargetMachine>>
|
||||
JITTargetMachineBuilder::createTargetMachine() {
|
||||
|
||||
std::string ErrMsg;
|
||||
auto *TheTarget = TargetRegistry::lookupTarget(TT.getTriple(), ErrMsg);
|
||||
if (!TheTarget)
|
||||
return make_error<StringError>(std::move(ErrMsg), inconvertibleErrorCode());
|
||||
|
||||
auto *TM =
|
||||
TheTarget->createTargetMachine(TT.getTriple(), CPU, Features.getString(),
|
||||
Options, RM, CM, OptLevel, /*JIT*/ true);
|
||||
if (!TM)
|
||||
return make_error<StringError>("Could not allocate target machine",
|
||||
inconvertibleErrorCode());
|
||||
|
||||
return std::unique_ptr<TargetMachine>(TM);
|
||||
}
|
||||
|
||||
JITTargetMachineBuilder &JITTargetMachineBuilder::addFeatures(
|
||||
const std::vector<std::string> &FeatureVec) {
|
||||
for (const auto &F : FeatureVec)
|
||||
Features.AddFeature(F);
|
||||
return *this;
|
||||
}
|
||||
|
||||
} // End namespace orc.
|
||||
} // End namespace llvm.
|
|
@ -26,6 +26,7 @@
|
|||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/ObjectCache.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LLJIT.h"
|
||||
#include "llvm/ExecutionEngine/Orc/OrcRemoteTargetClient.h"
|
||||
#include "llvm/ExecutionEngine/OrcMCJITReplacement.h"
|
||||
|
@ -773,8 +774,10 @@ int runOrcLazyJIT(const char *ProgName) {
|
|||
TT.empty() ? ExitOnErr(orc::JITTargetMachineBuilder::detectHost())
|
||||
: orc::JITTargetMachineBuilder(Triple(TT));
|
||||
|
||||
JTMB.setArch(MArch)
|
||||
.setCPU(getCPUStr())
|
||||
if (!MArch.empty())
|
||||
JTMB.getTargetTriple().setArchName(MArch);
|
||||
|
||||
JTMB.setCPU(getCPUStr())
|
||||
.addFeatures(getFeatureList())
|
||||
.setRelocationModel(RelocModel.getNumOccurrences()
|
||||
? Optional<Reloc::Model>(RelocModel)
|
||||
|
@ -782,6 +785,7 @@ int runOrcLazyJIT(const char *ProgName) {
|
|||
.setCodeModel(CMModel.getNumOccurrences()
|
||||
? Optional<CodeModel::Model>(CMModel)
|
||||
: None);
|
||||
|
||||
DataLayout DL("");
|
||||
{
|
||||
// Create a throwaway TargetMachine to get the data layout.
|
||||
|
|
|
@ -14,6 +14,7 @@ add_llvm_unittest(OrcJITTests
|
|||
CoreAPIsTest.cpp
|
||||
IndirectionUtilsTest.cpp
|
||||
GlobalMappingLayerTest.cpp
|
||||
JITTargetMachineBuilderTest.cpp
|
||||
LazyCallThroughAndReexportsTest.cpp
|
||||
LazyEmittingLayerTest.cpp
|
||||
LegacyAPIInteropTest.cpp
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
//===----------- CoreAPIsTest.cpp - Unit tests for Core ORC APIs ----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "OrcTestCommon.h"
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::orc;
|
||||
|
||||
namespace {
|
||||
|
||||
TEST(ExecutionUtilsTest, JITTargetMachineBuilder) {
|
||||
// Tests basic API usage.
|
||||
// Bails out on error, as it is valid to run this test without any targets
|
||||
// built.
|
||||
|
||||
// Make sure LLVM has been initialized.
|
||||
OrcNativeTarget::initialize();
|
||||
|
||||
auto JTMB = cantFail(JITTargetMachineBuilder::detectHost());
|
||||
|
||||
// Test API by performing a bunch of no-ops.
|
||||
JTMB.setCPU("");
|
||||
JTMB.setRelocationModel(None);
|
||||
JTMB.setCodeModel(None);
|
||||
JTMB.setCodeGenOptLevel(CodeGenOpt::None);
|
||||
JTMB.addFeatures(std::vector<std::string>());
|
||||
SubtargetFeatures &STF = JTMB.getFeatures();
|
||||
(void)STF;
|
||||
TargetOptions &TO = JTMB.getOptions();
|
||||
(void)TO;
|
||||
Triple &TT = JTMB.getTargetTriple();
|
||||
(void)TT;
|
||||
|
||||
auto TM = JTMB.createTargetMachine();
|
||||
|
||||
if (!TM)
|
||||
consumeError(TM.takeError());
|
||||
else {
|
||||
EXPECT_NE(TM.get(), nullptr)
|
||||
<< "JITTargetMachineBuilder should return a non-null TargetMachine "
|
||||
"on success";
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
|
@ -1,5 +1,5 @@
|
|||
#include "OrcTestCommon.h"
|
||||
#include "llvm/ExecutionEngine/Orc/ExecutionUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/JITTargetMachineBuilder.h"
|
||||
#include "llvm/ExecutionEngine/Orc/LazyReexports.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
|
|
Loading…
Reference in New Issue