CodeRegionGenerator.h 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. /// \file
  9. ///
  10. /// This file declares classes responsible for generating llvm-mca
  11. /// 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. #ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H
  16. #define LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H
  17. #include "CodeRegion.h"
  18. #include "llvm/MC/MCAsmInfo.h"
  19. #include "llvm/MC/MCContext.h"
  20. #include "llvm/MC/MCParser/MCAsmLexer.h"
  21. #include "llvm/MC/MCSubtargetInfo.h"
  22. #include "llvm/MC/TargetRegistry.h"
  23. #include "llvm/MCA/CustomBehaviour.h"
  24. #include "llvm/Support/Error.h"
  25. #include "llvm/Support/SourceMgr.h"
  26. #include <memory>
  27. namespace llvm {
  28. namespace mca {
  29. class MCACommentConsumer : public AsmCommentConsumer {
  30. protected:
  31. bool FoundError;
  32. public:
  33. MCACommentConsumer() : FoundError(false) {}
  34. bool hadErr() const { return FoundError; }
  35. };
  36. /// A comment consumer that parses strings. The only valid tokens are strings.
  37. class AnalysisRegionCommentConsumer : public MCACommentConsumer {
  38. AnalysisRegions &Regions;
  39. public:
  40. AnalysisRegionCommentConsumer(AnalysisRegions &R) : Regions(R) {}
  41. /// Parses a comment. It begins a new region if it is of the form
  42. /// LLVM-MCA-BEGIN. It ends a region if it is of the form LLVM-MCA-END.
  43. /// Regions can be optionally named if they are of the form
  44. /// LLVM-MCA-BEGIN <name> or LLVM-MCA-END <name>. Subregions are
  45. /// permitted, but a region that begins while another region is active
  46. /// must be ended before the outer region is ended. If thre is only one
  47. /// active region, LLVM-MCA-END does not need to provide a name.
  48. void HandleComment(SMLoc Loc, StringRef CommentText) override;
  49. };
  50. /// A comment consumer that parses strings to create InstrumentRegions.
  51. /// The only valid tokens are strings.
  52. class InstrumentRegionCommentConsumer : public MCACommentConsumer {
  53. llvm::SourceMgr &SM;
  54. InstrumentRegions &Regions;
  55. InstrumentManager &IM;
  56. public:
  57. InstrumentRegionCommentConsumer(llvm::SourceMgr &SM, InstrumentRegions &R,
  58. InstrumentManager &IM)
  59. : SM(SM), Regions(R), IM(IM) {}
  60. /// Parses a comment. It begins a new region if it is of the form
  61. /// LLVM-MCA-<INSTRUMENTATION_TYPE> <data> where INSTRUMENTATION_TYPE
  62. /// is a valid InstrumentKind. If there is already an active
  63. /// region of type INSTRUMENATION_TYPE, then it will end the active
  64. /// one and begin a new one using the new data.
  65. void HandleComment(SMLoc Loc, StringRef CommentText) override;
  66. };
  67. /// This abstract class is responsible for parsing the input given to
  68. /// the llvm-mca driver, and converting that into a CodeRegions instance.
  69. class CodeRegionGenerator {
  70. protected:
  71. CodeRegionGenerator(const CodeRegionGenerator &) = delete;
  72. CodeRegionGenerator &operator=(const CodeRegionGenerator &) = delete;
  73. virtual Expected<const CodeRegions &>
  74. parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) = 0;
  75. public:
  76. CodeRegionGenerator() {}
  77. virtual ~CodeRegionGenerator();
  78. };
  79. /// Abastract CodeRegionGenerator with AnalysisRegions member
  80. class AnalysisRegionGenerator : public virtual CodeRegionGenerator {
  81. protected:
  82. AnalysisRegions Regions;
  83. public:
  84. AnalysisRegionGenerator(llvm::SourceMgr &SM) : Regions(SM) {}
  85. virtual Expected<const AnalysisRegions &>
  86. parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP) = 0;
  87. };
  88. /// Abstract CodeRegionGenerator with InstrumentRegionsRegions member
  89. class InstrumentRegionGenerator : public virtual CodeRegionGenerator {
  90. protected:
  91. InstrumentRegions Regions;
  92. public:
  93. InstrumentRegionGenerator(llvm::SourceMgr &SM) : Regions(SM) {}
  94. virtual Expected<const InstrumentRegions &>
  95. parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP) = 0;
  96. };
  97. /// This abstract class is responsible for parsing input ASM and
  98. /// generating a CodeRegions instance.
  99. class AsmCodeRegionGenerator : public virtual CodeRegionGenerator {
  100. const Target &TheTarget;
  101. MCContext &Ctx;
  102. const MCAsmInfo &MAI;
  103. const MCSubtargetInfo &STI;
  104. const MCInstrInfo &MCII;
  105. unsigned AssemblerDialect; // This is set during parsing.
  106. public:
  107. AsmCodeRegionGenerator(const Target &T, MCContext &C, const MCAsmInfo &A,
  108. const MCSubtargetInfo &S, const MCInstrInfo &I)
  109. : TheTarget(T), Ctx(C), MAI(A), STI(S), MCII(I), AssemblerDialect(0) {}
  110. virtual MCACommentConsumer *getCommentConsumer() = 0;
  111. virtual CodeRegions &getRegions() = 0;
  112. unsigned getAssemblerDialect() const { return AssemblerDialect; }
  113. Expected<const CodeRegions &>
  114. parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) override;
  115. };
  116. class AsmAnalysisRegionGenerator final : public AnalysisRegionGenerator,
  117. public AsmCodeRegionGenerator {
  118. AnalysisRegionCommentConsumer CC;
  119. public:
  120. AsmAnalysisRegionGenerator(const Target &T, llvm::SourceMgr &SM, MCContext &C,
  121. const MCAsmInfo &A, const MCSubtargetInfo &S,
  122. const MCInstrInfo &I)
  123. : AnalysisRegionGenerator(SM), AsmCodeRegionGenerator(T, C, A, S, I),
  124. CC(Regions) {}
  125. MCACommentConsumer *getCommentConsumer() override { return &CC; };
  126. CodeRegions &getRegions() override { return Regions; };
  127. Expected<const AnalysisRegions &>
  128. parseAnalysisRegions(const std::unique_ptr<MCInstPrinter> &IP) override {
  129. Expected<const CodeRegions &> RegionsOrErr = parseCodeRegions(IP);
  130. if (!RegionsOrErr)
  131. return RegionsOrErr.takeError();
  132. else
  133. return static_cast<const AnalysisRegions &>(*RegionsOrErr);
  134. }
  135. Expected<const CodeRegions &>
  136. parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) override {
  137. return AsmCodeRegionGenerator::parseCodeRegions(IP);
  138. }
  139. };
  140. class AsmInstrumentRegionGenerator final : public InstrumentRegionGenerator,
  141. public AsmCodeRegionGenerator {
  142. InstrumentRegionCommentConsumer CC;
  143. public:
  144. AsmInstrumentRegionGenerator(const Target &T, llvm::SourceMgr &SM,
  145. MCContext &C, const MCAsmInfo &A,
  146. const MCSubtargetInfo &S, const MCInstrInfo &I,
  147. InstrumentManager &IM)
  148. : InstrumentRegionGenerator(SM), AsmCodeRegionGenerator(T, C, A, S, I),
  149. CC(SM, Regions, IM) {}
  150. MCACommentConsumer *getCommentConsumer() override { return &CC; };
  151. CodeRegions &getRegions() override { return Regions; };
  152. Expected<const InstrumentRegions &>
  153. parseInstrumentRegions(const std::unique_ptr<MCInstPrinter> &IP) override {
  154. Expected<const CodeRegions &> RegionsOrErr = parseCodeRegions(IP);
  155. if (!RegionsOrErr)
  156. return RegionsOrErr.takeError();
  157. else
  158. return static_cast<const InstrumentRegions &>(*RegionsOrErr);
  159. }
  160. Expected<const CodeRegions &>
  161. parseCodeRegions(const std::unique_ptr<MCInstPrinter> &IP) override {
  162. return AsmCodeRegionGenerator::parseCodeRegions(IP);
  163. }
  164. };
  165. } // namespace mca
  166. } // namespace llvm
  167. #endif // LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H