Home | History | Annotate | Line # | Download | only in lib
      1 //===-- Analysis.h ----------------------------------------------*- C++ -*-===//
      2 //
      3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
      4 // See https://llvm.org/LICENSE.txt for license information.
      5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
      6 //
      7 //===----------------------------------------------------------------------===//
      8 ///
      9 /// \file
     10 /// Analysis output for benchmark results.
     11 ///
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H
     15 #define LLVM_TOOLS_LLVM_EXEGESIS_ANALYSIS_H
     16 
     17 #include "Clustering.h"
     18 #include "SchedClassResolution.h"
     19 #include "llvm/MC/MCContext.h"
     20 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
     21 #include "llvm/MC/MCInstPrinter.h"
     22 #include "llvm/MC/MCInstrInfo.h"
     23 #include "llvm/MC/MCObjectFileInfo.h"
     24 #include "llvm/MC/MCSubtargetInfo.h"
     25 #include "llvm/Support/Error.h"
     26 #include "llvm/Support/TargetRegistry.h"
     27 #include "llvm/Support/raw_ostream.h"
     28 #include <memory>
     29 #include <set>
     30 #include <string>
     31 #include <unordered_map>
     32 
     33 namespace llvm {
     34 namespace exegesis {
     35 
     36 // A helper class to analyze benchmark results for a target.
     37 class Analysis {
     38 public:
     39   Analysis(const Target &Target, std::unique_ptr<MCInstrInfo> InstrInfo,
     40            const InstructionBenchmarkClustering &Clustering,
     41            double AnalysisInconsistencyEpsilon,
     42            bool AnalysisDisplayUnstableOpcodes,
     43            const std::string &ForceCpuName = "");
     44 
     45   // Prints a csv of instructions for each cluster.
     46   struct PrintClusters {};
     47   // Find potential errors in the scheduling information given measurements.
     48   struct PrintSchedClassInconsistencies {};
     49 
     50   template <typename Pass> Error run(raw_ostream &OS) const;
     51 
     52 private:
     53   using ClusterId = InstructionBenchmarkClustering::ClusterId;
     54 
     55   // Represents the intersection of a sched class and a cluster.
     56   class SchedClassCluster {
     57   public:
     58     const InstructionBenchmarkClustering::ClusterId &id() const {
     59       return ClusterId;
     60     }
     61 
     62     const std::vector<size_t> &getPointIds() const { return PointIds; }
     63 
     64     void addPoint(size_t PointId,
     65                   const InstructionBenchmarkClustering &Clustering);
     66 
     67     // Return the cluster centroid.
     68     const SchedClassClusterCentroid &getCentroid() const { return Centroid; }
     69 
     70     // Returns true if the cluster representative measurements match that of SC.
     71     bool
     72     measurementsMatch(const MCSubtargetInfo &STI, const ResolvedSchedClass &SC,
     73                       const InstructionBenchmarkClustering &Clustering,
     74                       const double AnalysisInconsistencyEpsilonSquared_) const;
     75 
     76   private:
     77     InstructionBenchmarkClustering::ClusterId ClusterId;
     78     std::vector<size_t> PointIds;
     79     // Measurement stats for the points in the SchedClassCluster.
     80     SchedClassClusterCentroid Centroid;
     81   };
     82 
     83   void printInstructionRowCsv(size_t PointId, raw_ostream &OS) const;
     84 
     85   void printClusterRawHtml(const InstructionBenchmarkClustering::ClusterId &Id,
     86                            StringRef display_name, llvm::raw_ostream &OS) const;
     87 
     88   void printPointHtml(const InstructionBenchmark &Point,
     89                       llvm::raw_ostream &OS) const;
     90 
     91   void
     92   printSchedClassClustersHtml(const std::vector<SchedClassCluster> &Clusters,
     93                               const ResolvedSchedClass &SC,
     94                               raw_ostream &OS) const;
     95   void printSchedClassDescHtml(const ResolvedSchedClass &SC,
     96                                raw_ostream &OS) const;
     97 
     98   // A pair of (Sched Class, indices of points that belong to the sched
     99   // class).
    100   struct ResolvedSchedClassAndPoints {
    101     explicit ResolvedSchedClassAndPoints(ResolvedSchedClass &&RSC);
    102 
    103     ResolvedSchedClass RSC;
    104     std::vector<size_t> PointIds;
    105   };
    106 
    107   // Builds a list of ResolvedSchedClassAndPoints.
    108   std::vector<ResolvedSchedClassAndPoints> makePointsPerSchedClass() const;
    109 
    110   template <typename EscapeTag, EscapeTag Tag>
    111   void writeSnippet(raw_ostream &OS, ArrayRef<uint8_t> Bytes,
    112                     const char *Separator) const;
    113 
    114   const InstructionBenchmarkClustering &Clustering_;
    115   std::unique_ptr<MCContext> Context_;
    116   std::unique_ptr<MCSubtargetInfo> SubtargetInfo_;
    117   std::unique_ptr<MCInstrInfo> InstrInfo_;
    118   std::unique_ptr<MCRegisterInfo> RegInfo_;
    119   std::unique_ptr<MCAsmInfo> AsmInfo_;
    120   std::unique_ptr<MCInstPrinter> InstPrinter_;
    121   std::unique_ptr<MCDisassembler> Disasm_;
    122   const double AnalysisInconsistencyEpsilonSquared_;
    123   const bool AnalysisDisplayUnstableOpcodes_;
    124 };
    125 
    126 } // namespace exegesis
    127 } // namespace llvm
    128 
    129 #endif // LLVM_TOOLS_LLVM_EXEGESIS_CLUSTERING_H
    130