diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.h b/llvm/tools/llvm-exegesis/lib/Analysis.h --- a/llvm/tools/llvm-exegesis/lib/Analysis.h +++ b/llvm/tools/llvm-exegesis/lib/Analysis.h @@ -15,14 +15,11 @@ #define LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H #include "Clustering.h" +#include "DisassemblerHelper.h" #include "SchedClassResolution.h" -#include "llvm/MC/MCContext.h" -#include "llvm/MC/MCDisassembler/MCDisassembler.h" -#include "llvm/MC/MCInstPrinter.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Error.h" #include "llvm/Support/raw_ostream.h" #include @@ -112,10 +109,7 @@ const BenchmarkClustering &Clustering_; const LLVMState &State_; - std::unique_ptr Context_; - std::unique_ptr AsmInfo_; - std::unique_ptr InstPrinter_; - std::unique_ptr Disasm_; + std::unique_ptr DisasmHelper_; const double AnalysisInconsistencyEpsilonSquared_; const bool AnalysisDisplayUnstableOpcodes_; }; diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp --- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp +++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp @@ -102,12 +102,11 @@ void Analysis::writeSnippet(raw_ostream &OS, ArrayRef Bytes, const char *Separator) const { SmallVector Lines; - const auto &SI = State_.getSubtargetInfo(); // Parse the asm snippet and print it. while (!Bytes.empty()) { MCInst MI; uint64_t MISize = 0; - if (!Disasm_->getInstruction(MI, MISize, Bytes, 0, nulls())) { + if (!DisasmHelper_->decodeInst(MI, MISize, Bytes)) { writeEscaped(OS, join(Lines, Separator)); writeEscaped(OS, Separator); writeEscaped(OS, "[error decoding asm snippet]"); @@ -115,7 +114,7 @@ } SmallString<128> InstPrinterStr; // FIXME: magic number. raw_svector_ostream OSS(InstPrinterStr); - InstPrinter_->printInst(&MI, 0, "", SI, OSS); + DisasmHelper_->printInst(&MI, OSS); Bytes = Bytes.drop_front(MISize); Lines.emplace_back(InstPrinterStr.str().trim()); } @@ -163,21 +162,7 @@ if (Clustering.getPoints().empty()) return; - MCTargetOptions MCOptions; - const auto &TM = State.getTargetMachine(); - const auto &Triple = TM.getTargetTriple(); - AsmInfo_.reset(TM.getTarget().createMCAsmInfo(State_.getRegInfo(), - Triple.str(), MCOptions)); - InstPrinter_.reset(TM.getTarget().createMCInstPrinter( - Triple, 0 /*default variant*/, *AsmInfo_, State_.getInstrInfo(), - State_.getRegInfo())); - - Context_ = std::make_unique( - Triple, AsmInfo_.get(), &State_.getRegInfo(), &State_.getSubtargetInfo()); - Disasm_.reset(TM.getTarget().createMCDisassembler(State_.getSubtargetInfo(), - *Context_)); - assert(Disasm_ && "cannot create MCDisassembler. missing call to " - "InitializeXXXTargetDisassembler ?"); + DisasmHelper_ = std::make_unique(State); } template <> diff --git a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt --- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt +++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt @@ -51,6 +51,7 @@ BenchmarkRunner.cpp Clustering.cpp CodeTemplate.cpp + DisassemblerHelper.cpp Error.cpp LatencyBenchmarkRunner.cpp LlvmState.cpp diff --git a/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h b/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h new file mode 100644 --- /dev/null +++ b/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h @@ -0,0 +1,54 @@ +//===-- DisassemblerHelper.h ------------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Helper class for decoding machine instructions and printing them in an +/// assembler form. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_EXEGESIS_DISASSEMBLER_HELPER_H +#define LLVM_TOOLS_LLVM_EXEGESIS_DISASSEMBLER_HELPER_H + +#include "LlvmState.h" +#include "llvm/MC/MCAsmInfo.h" +#include "llvm/MC/MCContext.h" +#include "llvm/MC/MCDisassembler/MCDisassembler.h" +#include "llvm/MC/MCInstPrinter.h" + +#include + +namespace llvm { +namespace exegesis { + +// A helper class for decoding and printing machine instructions. +class DisassemblerHelper { +public: + DisassemblerHelper(const LLVMState &State); + + void printInst(const MCInst *MI, raw_ostream &OS) const { + const auto &STI = State_.getSubtargetInfo(); + InstPrinter_->printInst(MI, 0, "", STI, OS); + } + + bool decodeInst(MCInst &MI, uint64_t &MISize, ArrayRef Bytes) const { + return Disasm_->getInstruction(MI, MISize, Bytes, 0, nulls()); + } + +private: + const LLVMState &State_; + std::unique_ptr Context_; + std::unique_ptr AsmInfo_; + std::unique_ptr InstPrinter_; + std::unique_ptr Disasm_; +}; + +} // namespace exegesis +} // namespace llvm + +#endif // LLVM_TOOLS_LLVM_EXEGESIS_DISASSEMBLER_HELPER_H diff --git a/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.cpp b/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.cpp new file mode 100644 --- /dev/null +++ b/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.cpp @@ -0,0 +1,35 @@ +//===-- DisassemblerHelper.cpp ----------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "DisassemblerHelper.h" + +#include "llvm/MC/TargetRegistry.h" + +namespace llvm { +namespace exegesis { + +DisassemblerHelper::DisassemblerHelper(const LLVMState &State) : State_(State) { + MCTargetOptions MCOptions; + const auto &TM = State.getTargetMachine(); + const auto &Triple = TM.getTargetTriple(); + AsmInfo_.reset(TM.getTarget().createMCAsmInfo(State_.getRegInfo(), + Triple.str(), MCOptions)); + InstPrinter_.reset(TM.getTarget().createMCInstPrinter( + Triple, 0 /*default variant*/, *AsmInfo_, State_.getInstrInfo(), + State_.getRegInfo())); + + Context_ = std::make_unique( + Triple, AsmInfo_.get(), &State_.getRegInfo(), &State_.getSubtargetInfo()); + Disasm_.reset(TM.getTarget().createMCDisassembler(State_.getSubtargetInfo(), + *Context_)); + assert(Disasm_ && "cannot create MCDisassembler. missing call to " + "InitializeXXXTargetDisassembler ?"); +} + +} // namespace exegesis +} // namespace llvm