[llvm/Object] - Convert SectionRef::getName() to return Expected<>
[llvm-complete.git] / tools / llvm-mca / CodeRegionGenerator.cpp
blob8ddcd2f4abe21749d9e5ec556efa421f6a7f294d
1 //===----------------------- CodeRegionGenerator.cpp ------------*- 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 defines 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.
14 //===----------------------------------------------------------------------===//
16 #include "CodeRegionGenerator.h"
17 #include "llvm/ADT/ArrayRef.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/MC/MCParser/MCTargetAsmParser.h"
20 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/MCTargetOptions.h"
22 #include "llvm/Support/Error.h"
23 #include "llvm/Support/SMLoc.h"
24 #include <memory>
26 namespace llvm {
27 namespace mca {
29 // This virtual dtor serves as the anchor for the CodeRegionGenerator class.
30 CodeRegionGenerator::~CodeRegionGenerator() {}
32 // A comment consumer that parses strings. The only valid tokens are strings.
33 class MCACommentConsumer : public AsmCommentConsumer {
34 public:
35 CodeRegions &Regions;
37 MCACommentConsumer(CodeRegions &R) : Regions(R) {}
38 void HandleComment(SMLoc Loc, StringRef CommentText) override;
41 // This class provides the callbacks that occur when parsing input assembly.
42 class MCStreamerWrapper final : public MCStreamer {
43 CodeRegions &Regions;
45 public:
46 MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)
47 : MCStreamer(Context), Regions(R) {}
49 // We only want to intercept the emission of new instructions.
50 virtual void EmitInstruction(const MCInst &Inst,
51 const MCSubtargetInfo &/* unused */) override {
52 Regions.addInstruction(Inst);
55 bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
56 return true;
59 void EmitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
60 unsigned ByteAlignment) override {}
61 void EmitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
62 uint64_t Size = 0, unsigned ByteAlignment = 0,
63 SMLoc Loc = SMLoc()) override {}
64 void EmitGPRel32Value(const MCExpr *Value) override {}
65 void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
66 void EmitCOFFSymbolStorageClass(int StorageClass) override {}
67 void EmitCOFFSymbolType(int Type) override {}
68 void EndCOFFSymbolDef() override {}
70 ArrayRef<MCInst> GetInstructionSequence(unsigned Index) const {
71 return Regions.getInstructionSequence(Index);
75 void MCACommentConsumer::HandleComment(SMLoc Loc, StringRef CommentText) {
76 // Skip empty comments.
77 StringRef Comment(CommentText);
78 if (Comment.empty())
79 return;
81 // Skip spaces and tabs.
82 unsigned Position = Comment.find_first_not_of(" \t");
83 if (Position >= Comment.size())
84 // We reached the end of the comment. Bail out.
85 return;
87 Comment = Comment.drop_front(Position);
88 if (Comment.consume_front("LLVM-MCA-END")) {
89 // Skip spaces and tabs.
90 Position = Comment.find_first_not_of(" \t");
91 if (Position < Comment.size())
92 Comment = Comment.drop_front(Position);
93 Regions.endRegion(Comment, Loc);
94 return;
97 // Try to parse the LLVM-MCA-BEGIN comment.
98 if (!Comment.consume_front("LLVM-MCA-BEGIN"))
99 return;
101 // Skip spaces and tabs.
102 Position = Comment.find_first_not_of(" \t");
103 if (Position < Comment.size())
104 Comment = Comment.drop_front(Position);
105 // Use the rest of the string as a descriptor for this code snippet.
106 Regions.beginRegion(Comment, Loc);
109 Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions() {
110 MCTargetOptions Opts;
111 Opts.PreserveAsmComments = false;
112 MCStreamerWrapper Str(Ctx, Regions);
114 // Create a MCAsmParser and setup the lexer to recognize llvm-mca ASM
115 // comments.
116 std::unique_ptr<MCAsmParser> Parser(
117 createMCAsmParser(Regions.getSourceMgr(), Ctx, Str, MAI));
118 MCAsmLexer &Lexer = Parser->getLexer();
119 MCACommentConsumer CC(Regions);
120 Lexer.setCommentConsumer(&CC);
121 // Enable support for MASM literal numbers (example: 05h, 101b).
122 Lexer.setLexMasmIntegers(true);
124 std::unique_ptr<MCTargetAsmParser> TAP(
125 TheTarget.createMCAsmParser(STI, *Parser, MCII, Opts));
126 if (!TAP)
127 return make_error<StringError>(
128 "This target does not support assembly parsing.",
129 inconvertibleErrorCode());
130 Parser->setTargetParser(*TAP);
131 Parser->Run(false);
133 // Set the assembler dialect from the input. llvm-mca will use this as the
134 // default dialect when printing reports.
135 AssemblerDialect = Parser->getAssemblerDialect();
136 return Regions;
139 } // namespace mca
140 } // namespace llvm