This allows failing more gracefully.
namespace llvm {
namespace exegesis {
-LLVMState::LLVMState(const std::string &Triple, const std::string &CpuName,
- const std::string &Features) {
+Expected<LLVMState> LLVMState::Create(std::string Triple, std::string CpuName,
+ const StringRef Features) {
+ if (Triple.empty())
+ Triple = sys::getProcessTriple();
+ if (CpuName.empty())
+ CpuName = sys::getHostCPUName().str();
std::string Error;
const Target *const TheTarget = TargetRegistry::lookupTarget(Triple, Error);
- assert(TheTarget && "unknown target for host");
+ if (!TheTarget) {
+ return llvm::make_error<llvm::StringError>(
+ "no LLVM target for triple " + Triple, llvm::inconvertibleErrorCode());
+ }
const TargetOptions Options;
- TheTargetMachine.reset(
+ std::unique_ptr<const TargetMachine> TM(
static_cast<LLVMTargetMachine *>(TheTarget->createTargetMachine(
Triple, CpuName, Features, Options, Reloc::Model::Static)));
- assert(TheTargetMachine && "unable to create target machine");
- TheExegesisTarget = ExegesisTarget::lookup(TheTargetMachine->getTargetTriple());
- if (!TheExegesisTarget) {
- errs() << "no exegesis target for " << Triple << ", using default\n";
- TheExegesisTarget = &ExegesisTarget::getDefault();
+ if (!TM) {
+ return llvm::make_error<llvm::StringError>(
+ "unable to create target machine", llvm::inconvertibleErrorCode());
+ }
+
+ const ExegesisTarget *ET =
+ Triple.empty() ? &ExegesisTarget::getDefault()
+ : ExegesisTarget::lookup(TM->getTargetTriple());
+ if (!ET) {
+ return llvm::make_error<llvm::StringError>(
+ "no Exegesis target for triple " + Triple,
+ llvm::inconvertibleErrorCode());
}
+ return LLVMState(std::move(TM), ET, CpuName);
+}
+
+LLVMState::LLVMState(std::unique_ptr<const TargetMachine> TM,
+ const ExegesisTarget *ET, const StringRef CpuName)
+ : TheExegesisTarget(ET), TheTargetMachine(std::move(TM)) {
PfmCounters = &TheExegesisTarget->getPfmCounters(CpuName);
BitVector ReservedRegs = getFunctionReservedRegs(getTargetMachine());
IC.reset(new InstructionsCache(getInstrInfo(), getRATC()));
}
-LLVMState::LLVMState(const std::string &CpuName)
- : LLVMState(sys::getProcessTriple(),
- CpuName.empty() ? sys::getHostCPUName().str() : CpuName, "") {}
-
std::unique_ptr<LLVMTargetMachine> LLVMState::createTargetMachine() const {
return std::unique_ptr<LLVMTargetMachine>(static_cast<LLVMTargetMachine *>(
TheTargetMachine->getTarget().createTargetMachine(
// measurements.
class LLVMState {
public:
- // Uses the host triple. If CpuName is empty, uses the host CPU.
- LLVMState(const std::string &CpuName);
-
- LLVMState(const std::string &Triple,
- const std::string &CpuName,
- const std::string &Features = ""); // For tests.
+ // Factory function.
+ // If `Triple` is empty, uses the host triple.
+ // If `CpuName` is empty, uses the host CPU.
+ // `Features` is intended for tests.
+ static Expected<LLVMState> Create(std::string Triple, std::string CpuName,
+ StringRef Features = "");
const TargetMachine &getTargetMachine() const { return *TheTargetMachine; }
std::unique_ptr<LLVMTargetMachine> createTargetMachine() const;
const PfmCountersInfo &getPfmCounters() const { return *PfmCounters; }
private:
+ LLVMState(std::unique_ptr<const TargetMachine> TM, const ExegesisTarget *ET,
+ StringRef CpuName);
+
const ExegesisTarget *TheExegesisTarget;
std::unique_ptr<const TargetMachine> TheTargetMachine;
std::unique_ptr<const RegisterAliasingTrackerCache> RATC;
InitializeAllAsmParsers();
InitializeNativeExegesisTarget();
- const LLVMState State(CpuName);
+ const LLVMState State = ExitOnErr(LLVMState::Create("", CpuName));
// Preliminary check to ensure features needed for requested
// benchmark mode are present on target CPU and/or OS.
InitializeNativeTarget();
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetDisassembler();
+ InitializeNativeExegesisTarget();
// Read benchmarks.
- const LLVMState State("");
+ const LLVMState State = ExitOnErr(LLVMState::Create("", ""));
const std::vector<InstructionBenchmark> Points = ExitOnFileError(
BenchmarkFile, InstructionBenchmark::readYamls(State, BenchmarkFile));
class MipsTestBase : public ::testing::Test {
protected:
- MipsTestBase() : State("mips-unknown-linux", "mips32") {}
+ MipsTestBase()
+ : State(cantFail(LLVMState::Create("mips-unknown-linux", "mips32"))) {}
static void SetUpTestCase() {
LLVMInitializeMipsTargetInfo();
class PPCTestBase : public ::testing::Test {
protected:
- PPCTestBase() : State("powerpc64le-unknown-linux", "ppc64le") {}
+ PPCTestBase()
+ : State(cantFail(
+ LLVMState::Create("powerpc64le-unknown-linux", "ppc64le"))) {}
static void SetUpTestCase() {
LLVMInitializePowerPCTargetInfo();
namespace llvm {
namespace exegesis {
+void InitializeX86ExegesisTarget();
+
static std::string Dump(const MCInst &McInst) {
std::string Buffer;
raw_string_ostream OS(Buffer);
LLVMInitializeX86TargetInfo();
LLVMInitializeX86Target();
LLVMInitializeX86TargetMC();
+ InitializeX86ExegesisTarget();
// Read benchmarks.
- const LLVMState State("x86_64-unknown-linux", "haswell");
+ const LLVMState State =
+ cantFail(LLVMState::Create("x86_64-unknown-linux", "haswell"));
ExitOnError ExitOnErr;
class X86TargetTest : public ::testing::Test {
protected:
- X86TargetTest(const char *Features) : State(kTriple, "core2", Features) {}
+ X86TargetTest(const char *Features)
+ : State(cantFail(LLVMState::Create(kTriple, "core2", Features))) {}
static void SetUpTestCase() {
LLVMInitializeX86TargetInfo();
class X86TestBase : public ::testing::Test {
protected:
- X86TestBase() : State("x86_64-unknown-linux", "haswell") {}
+ X86TestBase()
+ : State(cantFail(LLVMState::Create("x86_64-unknown-linux", "haswell"))) {}
static void SetUpTestCase() {
LLVMInitializeX86TargetInfo();