[llvm-objcopy] [COFF] Fix warnings abuilt missing field initialization. NFC.
[llvm-complete.git] / tools / llvm-mca / CodeRegionGenerator.cpp
blob5bd37adeeae999a911f208ba9d6eb2a1e7915e7b
1 //===----------------------- CodeRegionGenerator.cpp ------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 /// \file
10 ///
11 /// This file defines classes responsible for generating llvm-mca
12 /// CodeRegions from various types of input. llvm-mca only analyzes CodeRegions,
13 /// so the classes here provide the input-to-CodeRegions translation.
15 //===----------------------------------------------------------------------===//
17 #include "CodeRegionGenerator.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/StringRef.h"
20 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
21 #include "llvm/MC/MCStreamer.h"
22 #include "llvm/MC/MCTargetOptions.h"
23 #include "llvm/Support/Error.h"
24 #include "llvm/Support/SMLoc.h"
25 #include <memory>
27 namespace llvm {
28 namespace mca {
30 // This virtual dtor serves as the anchor for the CodeRegionGenerator class.
31 CodeRegionGenerator::~CodeRegionGenerator() {}
33 // A comment consumer that parses strings. The only valid tokens are strings.
34 class MCACommentConsumer : public AsmCommentConsumer {
35 public:
36 CodeRegions &Regions;
38 MCACommentConsumer(CodeRegions &R) : Regions(R) {}
39 void HandleComment(SMLoc Loc, StringRef CommentText) override;
42 // This class provides the callbacks that occur when parsing input assembly.
43 class MCStreamerWrapper final : public MCStreamer {
44 CodeRegions &Regions;
46 public:
47 MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)
48 : MCStreamer(Context), Regions(R) {}
50 // We only want to intercept the emission of new instructions.
51 virtual void EmitInstruction(const MCInst &Inst,
52 const MCSubtargetInfo & /* unused */,
53 bool /* unused */) override {
54 Regions.addInstruction(Inst);
57 bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
58 return true;
61 void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
62 unsigned ByteAlignment) override {}
63 void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
64 uint64_t Size = 0, unsigned ByteAlignment = 0,
65 SMLoc Loc = SMLoc()) override {}
66 void EmitGPRel32Value(const MCExpr *Value) override {}
67 void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
68 void EmitCOFFSymbolStorageClass(int StorageClass) override {}
69 void EmitCOFFSymbolType(int Type) override {}
70 void EndCOFFSymbolDef() override {}
72 ArrayRef<MCInst> GetInstructionSequence(unsigned Index) const {
73 return Regions.getInstructionSequence(Index);
77 void MCACommentConsumer::HandleComment(SMLoc Loc, StringRef CommentText) {
78 // Skip empty comments.
79 StringRef Comment(CommentText);
80 if (Comment.empty())
81 return;
83 // Skip spaces and tabs.
84 unsigned Position = Comment.find_first_not_of(" \t");
85 if (Position >= Comment.size())
86 // We reached the end of the comment. Bail out.
87 return;
89 Comment = Comment.drop_front(Position);
90 if (Comment.consume_front("LLVM-MCA-END")) {
91 Regions.endRegion(Loc);
92 return;
95 // Try to parse the LLVM-MCA-BEGIN comment.
96 if (!Comment.consume_front("LLVM-MCA-BEGIN"))
97 return;
99 // Skip spaces and tabs.
100 Position = Comment.find_first_not_of(" \t");
101 if (Position < Comment.size())
102 Comment = Comment.drop_front(Position);
103 // Use the rest of the string as a descriptor for this code snippet.
104 Regions.beginRegion(Comment, Loc);
107 Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions() {
108 MCTargetOptions Opts;
109 Opts.PreserveAsmComments = false;
110 MCStreamerWrapper Str(Ctx, Regions);
112 // Create a MCAsmParser and setup the lexer to recognize llvm-mca ASM
113 // comments.
114 std::unique_ptr<MCAsmParser> Parser(
115 createMCAsmParser(Regions.getSourceMgr(), Ctx, Str, MAI));
116 MCAsmLexer &Lexer = Parser->getLexer();
117 MCACommentConsumer CC(Regions);
118 Lexer.setCommentConsumer(&CC);
120 // Create a target-specific parser and perform the parse.
121 std::unique_ptr<MCTargetAsmParser> TAP(
122 TheTarget.createMCAsmParser(STI, *Parser, MCII, Opts));
123 if (!TAP)
124 return make_error<StringError>(
125 "This target does not support assembly parsing.",
126 inconvertibleErrorCode());
127 Parser->setTargetParser(*TAP);
128 Parser->Run(false);
130 // Get the assembler dialect from the input. llvm-mca will use this as the
131 // default dialect when printing reports.
132 AssemblerDialect = Parser->getAssemblerDialect();
133 return Regions;
136 } // namespace mca
137 } // namespace llvm