From 39fc67b8af707f6bdcbcfbec1e17f14ffbaeecb8 Mon Sep 17 00:00:00 2001 From: Pavel Kosov Date: Tue, 4 Apr 2023 09:17:50 +0300 Subject: [PATCH] [llvm-exegesis] Factor out DisassemblerHelper from the Analysis class As part of preparing the reports, the Analysis class needs to print machine instructions in a disassembled form. For this purpose, the class has four fields (namely Context_, AsmInfo_, InstPrinter_ and Disasm_). All the constructor of the Analysis class does is conditionally initializing these four fields. This commit factors out the logic for decoding machine code and printing it in an assembler form into a separate DisassemblerHelper class. ~~ Huawei RRI, OS Lab Reviewed By: courbet Differential Revision: https://reviews.llvm.org/D147156 --- llvm/tools/llvm-exegesis/lib/Analysis.cpp | 21 ++------- llvm/tools/llvm-exegesis/lib/Analysis.h | 10 +--- llvm/tools/llvm-exegesis/lib/CMakeLists.txt | 1 + .../tools/llvm-exegesis/lib/DisassemblerHelper.cpp | 35 ++++++++++++++ llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h | 54 ++++++++++++++++++++++ 5 files changed, 95 insertions(+), 26 deletions(-) create mode 100644 llvm/tools/llvm-exegesis/lib/DisassemblerHelper.cpp create mode 100644 llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h diff --git a/llvm/tools/llvm-exegesis/lib/Analysis.cpp b/llvm/tools/llvm-exegesis/lib/Analysis.cpp index f6ee8f6..7c44373 100644 --- a/llvm/tools/llvm-exegesis/lib/Analysis.cpp +++ b/llvm/tools/llvm-exegesis/lib/Analysis.cpp @@ -102,12 +102,11 @@ template 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 @@ void Analysis::writeSnippet(raw_ostream &OS, ArrayRef Bytes, } 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 @@ Analysis::Analysis(const LLVMState &State, 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/Analysis.h b/llvm/tools/llvm-exegesis/lib/Analysis.h index 3271925..9970cfe 100644 --- 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 @@ private: 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/CMakeLists.txt b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt index e495ab3..39ad0a1 100644 --- a/llvm/tools/llvm-exegesis/lib/CMakeLists.txt +++ b/llvm/tools/llvm-exegesis/lib/CMakeLists.txt @@ -51,6 +51,7 @@ add_llvm_library(LLVMExegesis BenchmarkRunner.cpp Clustering.cpp CodeTemplate.cpp + DisassemblerHelper.cpp Error.cpp LatencyBenchmarkRunner.cpp LlvmState.cpp diff --git a/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.cpp b/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.cpp new file mode 100644 index 0000000..bc37aa4 --- /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 diff --git a/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h b/llvm/tools/llvm-exegesis/lib/DisassemblerHelper.h new file mode 100644 index 0000000..b946e97 --- /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 -- 2.7.4