//===-- Analysis.h ----------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// /// /// \file /// Analysis output for benchmark results. /// //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H #define LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H #include "Clustering.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/Support/Error.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/raw_ostream.h" #include #include #include #include namespace exegesis { // A helper class to analyze benchmark results for a target. class Analysis { public: Analysis(const llvm::Target &Target, const InstructionBenchmarkClustering &Clustering); // Prints a csv of instructions for each cluster. struct PrintClusters {}; // Find potential errors in the scheduling information given measurements. struct PrintSchedClassInconsistencies {}; template llvm::Error run(llvm::raw_ostream &OS) const; private: using ClusterId = InstructionBenchmarkClustering::ClusterId; // An llvm::MCSchedClassDesc augmented with some additional data. struct SchedClass { SchedClass(const llvm::MCSchedClassDesc &SD, const llvm::MCSubtargetInfo &STI); const llvm::MCSchedClassDesc *const SCDesc; const llvm::SmallVector NonRedundantWriteProcRes; const std::vector> IdealizedProcResPressure; }; // Represents the intersection of a sched class and a cluster. class SchedClassCluster { public: const InstructionBenchmarkClustering::ClusterId &id() const { return ClusterId; } const std::vector &getPointIds() const { return PointIds; } // Return the cluster centroid. const std::vector &getRepresentative() const { return Representative; } // Returns true if the cluster representative measurements match that of SC. bool measurementsMatch(const llvm::MCSubtargetInfo &STI, const SchedClass &SC, const InstructionBenchmarkClustering &Clustering) const; void addPoint(size_t PointId, const InstructionBenchmarkClustering &Clustering); private: InstructionBenchmarkClustering::ClusterId ClusterId; std::vector PointIds; // Measurement stats for the points in the SchedClassCluster. std::vector Representative; }; void printInstructionRowCsv(size_t PointId, llvm::raw_ostream &OS) const; void printSchedClassClustersHtml(const std::vector &Clusters, const SchedClass &SC, llvm::raw_ostream &OS) const; void printSchedClassDescHtml(const SchedClass &SC, llvm::raw_ostream &OS) const; // Builds a map of Sched Class -> indices of points that belong to the sched // class. std::unordered_map> makePointsPerSchedClass() const; template void writeSnippet(llvm::raw_ostream &OS, llvm::ArrayRef Bytes, const char *Separator) const; const InstructionBenchmarkClustering &Clustering_; llvm::MCObjectFileInfo ObjectFileInfo_; std::unique_ptr Context_; std::unique_ptr SubtargetInfo_; std::unique_ptr InstrInfo_; std::unique_ptr RegInfo_; std::unique_ptr AsmInfo_; std::unique_ptr InstPrinter_; std::unique_ptr Disasm_; }; // Computes the idealized ProcRes Unit pressure. This is the expected // distribution if the CPU scheduler can distribute the load as evenly as // possible. std::vector> computeIdealizedProcResPressure( const llvm::MCSchedModel &SM, llvm::SmallVector WPRS); } // namespace exegesis #endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H