brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · c30f67a Raw
284 lines · c
1//===----------------------- CodeRegionGenerator.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-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file declares classes responsible for generating llvm-mca11/// CodeRegions from various types of input. llvm-mca only analyzes CodeRegions,12/// so the classes here provide the input-to-CodeRegions translation.13//14//===----------------------------------------------------------------------===//15 16#ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H17#define LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H18 19#include "CodeRegion.h"20#include "llvm/MC/MCAsmInfo.h"21#include "llvm/MC/MCContext.h"22#include "llvm/MC/MCParser/AsmLexer.h"23#include "llvm/MC/MCStreamer.h"24#include "llvm/MC/MCSubtargetInfo.h"25#include "llvm/MC/TargetRegistry.h"26#include "llvm/MCA/CustomBehaviour.h"27#include "llvm/Support/Error.h"28#include "llvm/Support/SourceMgr.h"29#include <memory>30 31namespace llvm {32namespace mca {33 34class MCACommentConsumer : public AsmCommentConsumer {35protected:36  bool FoundError = false;37 38public:39  MCACommentConsumer() = default;40 41  bool hadErr() const { return FoundError; }42};43 44/// A comment consumer that parses strings.  The only valid tokens are strings.45class AnalysisRegionCommentConsumer : public MCACommentConsumer {46  AnalysisRegions &Regions;47 48public:49  AnalysisRegionCommentConsumer(AnalysisRegions &R) : Regions(R) {}50 51  /// Parses a comment. It begins a new region if it is of the form52  /// LLVM-MCA-BEGIN. It ends a region if it is of the form LLVM-MCA-END.53  /// Regions can be optionally named if they are of the form54  /// LLVM-MCA-BEGIN <name> or LLVM-MCA-END <name>. Subregions are55  /// permitted, but a region that begins while another region is active56  /// must be ended before the outer region is ended. If thre is only one57  /// active region, LLVM-MCA-END does not need to provide a name.58  void HandleComment(SMLoc Loc, StringRef CommentText) override;59};60 61/// A comment consumer that parses strings to create InstrumentRegions.62/// The only valid tokens are strings.63class InstrumentRegionCommentConsumer : public MCACommentConsumer {64  llvm::SourceMgr &SM;65 66  InstrumentRegions &Regions;67 68  InstrumentManager &IM;69 70public:71  InstrumentRegionCommentConsumer(llvm::SourceMgr &SM, InstrumentRegions &R,72                                  InstrumentManager &IM)73      : SM(SM), Regions(R), IM(IM) {}74 75  /// Parses a comment. It begins a new region if it is of the form76  /// LLVM-MCA-<INSTRUMENTATION_TYPE> <data> where INSTRUMENTATION_TYPE77  /// is a valid InstrumentKind. If there is already an active78  /// region of type INSTRUMENATION_TYPE, then it will end the active79  /// one and begin a new one using the new data.80  void HandleComment(SMLoc Loc, StringRef CommentText) override;81 82  InstrumentManager &getInstrumentManager() { return IM; }83};84 85// This class provides the callbacks that occur when parsing input assembly.86class MCStreamerWrapper : public MCStreamer {87protected:88  CodeRegions &Regions;89 90public:91  MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)92      : MCStreamer(Context), Regions(R) {}93 94  // We only want to intercept the emission of new instructions.95  void emitInstruction(const MCInst &Inst,96                       const MCSubtargetInfo & /* unused */) override {97    Regions.addInstruction(Inst);98  }99 100  bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {101    return true;102  }103 104  void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,105                        Align ByteAlignment) override {}106  void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,107                    uint64_t Size = 0, Align ByteAlignment = Align(1),108                    SMLoc Loc = SMLoc()) override {}109  void beginCOFFSymbolDef(const MCSymbol *Symbol) override {}110  void emitCOFFSymbolStorageClass(int StorageClass) override {}111  void emitCOFFSymbolType(int Type) override {}112  void endCOFFSymbolDef() override {}113 114  ArrayRef<MCInst> GetInstructionSequence(unsigned Index) const {115    return Regions.getInstructionSequence(Index);116  }117};118 119class InstrumentMCStreamer : public MCStreamerWrapper {120  InstrumentManager &IM;121 122public:123  InstrumentMCStreamer(MCContext &Context, mca::InstrumentRegions &R,124                       InstrumentManager &IM)125      : MCStreamerWrapper(Context, R), IM(IM) {}126 127  void emitInstruction(const MCInst &Inst,128                       const MCSubtargetInfo &MCSI) override {129    MCStreamerWrapper::emitInstruction(Inst, MCSI);130 131    // We know that Regions is an InstrumentRegions by the constructor.132    for (UniqueInstrument &I : IM.createInstruments(Inst)) {133      StringRef InstrumentKind = I.get()->getDesc();134      // End InstrumentType region if one is open135      if (Regions.isRegionActive(InstrumentKind))136        Regions.endRegion(InstrumentKind, Inst.getLoc());137      // Start new instrumentation region138      Regions.beginRegion(InstrumentKind, Inst.getLoc(), std::move(I));139    }140  }141};142 143/// This abstract class is responsible for parsing the input given to144/// the llvm-mca driver, and converting that into a CodeRegions instance.145class CodeRegionGenerator {146protected:147  CodeRegionGenerator(const CodeRegionGenerator &) = delete;148  CodeRegionGenerator &operator=(const CodeRegionGenerator &) = delete;149  virtual Expected<const CodeRegions &>150  parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP,151                   bool SkipFailures) = 0;152 153public:154  CodeRegionGenerator() = default;155  virtual ~CodeRegionGenerator();156};157 158/// Abastract CodeRegionGenerator with AnalysisRegions member159class AnalysisRegionGenerator : public virtual CodeRegionGenerator {160protected:161  AnalysisRegions Regions;162 163public:164  AnalysisRegionGenerator(llvm::SourceMgr &SM) : Regions(SM) {}165 166  virtual Expected<const AnalysisRegions &>167  parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP,168                       bool SkipFailures) = 0;169};170 171/// Abstract CodeRegionGenerator with InstrumentRegionsRegions member172class InstrumentRegionGenerator : public virtual CodeRegionGenerator {173protected:174  InstrumentRegions Regions;175 176public:177  InstrumentRegionGenerator(llvm::SourceMgr &SM) : Regions(SM) {}178 179  virtual Expected<const InstrumentRegions &>180  parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP,181                         bool SkipFailures) = 0;182};183 184/// This abstract class is responsible for parsing input ASM and185/// generating a CodeRegions instance.186class AsmCodeRegionGenerator : public virtual CodeRegionGenerator {187  const Target &TheTarget;188  const MCAsmInfo &MAI;189  const MCSubtargetInfo &STI;190  const MCInstrInfo &MCII;191  unsigned AssemblerDialect; // This is set during parsing.192 193protected:194  MCContext &Ctx;195 196public:197  AsmCodeRegionGenerator(const Target &T, MCContext &C, const MCAsmInfo &A,198                         const MCSubtargetInfo &S, const MCInstrInfo &I)199      : TheTarget(T), MAI(A), STI(S), MCII(I), AssemblerDialect(0), Ctx(C) {}200 201  virtual MCACommentConsumer *getCommentConsumer() = 0;202  virtual CodeRegions &getRegions() = 0;203  virtual MCStreamerWrapper *getMCStreamer() = 0;204 205  unsigned getAssemblerDialect() const { return AssemblerDialect; }206  Expected<const CodeRegions &>207  parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP,208                   bool SkipFailures) override;209};210 211class AsmAnalysisRegionGenerator final : public AnalysisRegionGenerator,212                                         public AsmCodeRegionGenerator {213  AnalysisRegionCommentConsumer CC;214  MCStreamerWrapper Streamer;215 216public:217  AsmAnalysisRegionGenerator(const Target &T, llvm::SourceMgr &SM, MCContext &C,218                             const MCAsmInfo &A, const MCSubtargetInfo &S,219                             const MCInstrInfo &I)220      : AnalysisRegionGenerator(SM), AsmCodeRegionGenerator(T, C, A, S, I),221        CC(Regions), Streamer(Ctx, Regions) {}222 223  MCACommentConsumer *getCommentConsumer() override { return &CC; };224  CodeRegions &getRegions() override { return Regions; };225  MCStreamerWrapper *getMCStreamer() override { return &Streamer; }226 227  Expected<const AnalysisRegions &>228  parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP,229                       bool SkipFailures) override {230    Expected<const CodeRegions &> RegionsOrErr =231        parseCodeRegions(IP, SkipFailures);232    if (!RegionsOrErr)233      return RegionsOrErr.takeError();234    else235      return static_cast<const AnalysisRegions &>(*RegionsOrErr);236  }237 238  Expected<const CodeRegions &>239  parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP,240                   bool SkipFailures) override {241    return AsmCodeRegionGenerator::parseCodeRegions(IP, SkipFailures);242  }243};244 245class AsmInstrumentRegionGenerator final : public InstrumentRegionGenerator,246                                           public AsmCodeRegionGenerator {247  InstrumentRegionCommentConsumer CC;248  InstrumentMCStreamer Streamer;249 250public:251  AsmInstrumentRegionGenerator(const Target &T, llvm::SourceMgr &SM,252                               MCContext &C, const MCAsmInfo &A,253                               const MCSubtargetInfo &S, const MCInstrInfo &I,254                               InstrumentManager &IM)255      : InstrumentRegionGenerator(SM), AsmCodeRegionGenerator(T, C, A, S, I),256        CC(SM, Regions, IM), Streamer(Ctx, Regions, IM) {}257 258  MCACommentConsumer *getCommentConsumer() override { return &CC; };259  CodeRegions &getRegions() override { return Regions; };260  MCStreamerWrapper *getMCStreamer() override { return &Streamer; }261 262  Expected<const InstrumentRegions &>263  parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP,264                         bool SkipFailures) override {265    Expected<const CodeRegions &> RegionsOrErr =266        parseCodeRegions(IP, SkipFailures);267    if (!RegionsOrErr)268      return RegionsOrErr.takeError();269    else270      return static_cast<const InstrumentRegions &>(*RegionsOrErr);271  }272 273  Expected<const CodeRegions &>274  parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP,275                   bool SkipFailures) override {276    return AsmCodeRegionGenerator::parseCodeRegions(IP, SkipFailures);277  }278};279 280} // namespace mca281} // namespace llvm282 283#endif // LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H284