123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- //===----------------------- CodeRegionGenerator.cpp ------------*- C++ -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- /// \file
- ///
- /// This file defines classes responsible for generating llvm-mca
- /// CodeRegions from various types of input. llvm-mca only analyzes CodeRegions,
- /// so the classes here provide the input-to-CodeRegions translation.
- //
- //===----------------------------------------------------------------------===//
- #include "CodeRegionGenerator.h"
- #include "llvm/ADT/ArrayRef.h"
- #include "llvm/ADT/StringRef.h"
- #include "llvm/MC/MCParser/MCTargetAsmParser.h"
- #include "llvm/MC/MCStreamer.h"
- #include "llvm/MC/MCTargetOptions.h"
- #include "llvm/Support/Error.h"
- #include "llvm/Support/SMLoc.h"
- #include <memory>
- namespace llvm {
- namespace mca {
- // This virtual dtor serves as the anchor for the CodeRegionGenerator class.
- CodeRegionGenerator::~CodeRegionGenerator() {}
- // A comment consumer that parses strings. The only valid tokens are strings.
- class MCACommentConsumer : public AsmCommentConsumer {
- public:
- CodeRegions &Regions;
- MCACommentConsumer(CodeRegions &R) : Regions(R) {}
- void HandleComment(SMLoc Loc, StringRef CommentText) override;
- };
- // This class provides the callbacks that occur when parsing input assembly.
- class MCStreamerWrapper final : public MCStreamer {
- CodeRegions &Regions;
- public:
- MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)
- : MCStreamer(Context), Regions(R) {}
- // We only want to intercept the emission of new instructions.
- virtual void emitInstruction(const MCInst &Inst,
- const MCSubtargetInfo & /* unused */) override {
- Regions.addInstruction(Inst);
- }
- bool emitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
- return true;
- }
- void emitCommonSymbol(MCSymbol *Symbol, uint64_t Size,
- unsigned ByteAlignment) override {}
- void emitZerofill(MCSection *Section, MCSymbol *Symbol = nullptr,
- uint64_t Size = 0, unsigned ByteAlignment = 0,
- SMLoc Loc = SMLoc()) override {}
- void emitGPRel32Value(const MCExpr *Value) override {}
- void BeginCOFFSymbolDef(const MCSymbol *Symbol) override {}
- void EmitCOFFSymbolStorageClass(int StorageClass) override {}
- void EmitCOFFSymbolType(int Type) override {}
- void EndCOFFSymbolDef() override {}
- ArrayRef<MCInst> GetInstructionSequence(unsigned Index) const {
- return Regions.getInstructionSequence(Index);
- }
- };
- void MCACommentConsumer::HandleComment(SMLoc Loc, StringRef CommentText) {
- // Skip empty comments.
- StringRef Comment(CommentText);
- if (Comment.empty())
- return;
- // Skip spaces and tabs.
- unsigned Position = Comment.find_first_not_of(" \t");
- if (Position >= Comment.size())
- // We reached the end of the comment. Bail out.
- return;
- Comment = Comment.drop_front(Position);
- if (Comment.consume_front("LLVM-MCA-END")) {
- // Skip spaces and tabs.
- Position = Comment.find_first_not_of(" \t");
- if (Position < Comment.size())
- Comment = Comment.drop_front(Position);
- Regions.endRegion(Comment, Loc);
- return;
- }
- // Try to parse the LLVM-MCA-BEGIN comment.
- if (!Comment.consume_front("LLVM-MCA-BEGIN"))
- return;
- // Skip spaces and tabs.
- Position = Comment.find_first_not_of(" \t");
- if (Position < Comment.size())
- Comment = Comment.drop_front(Position);
- // Use the rest of the string as a descriptor for this code snippet.
- Regions.beginRegion(Comment, Loc);
- }
- Expected<const CodeRegions &> AsmCodeRegionGenerator::parseCodeRegions() {
- MCTargetOptions Opts;
- Opts.PreserveAsmComments = false;
- MCStreamerWrapper Str(Ctx, Regions);
- // Create a MCAsmParser and setup the lexer to recognize llvm-mca ASM
- // comments.
- std::unique_ptr<MCAsmParser> Parser(
- createMCAsmParser(Regions.getSourceMgr(), Ctx, Str, MAI));
- MCAsmLexer &Lexer = Parser->getLexer();
- MCACommentConsumer CC(Regions);
- Lexer.setCommentConsumer(&CC);
- // Enable support for MASM literal numbers (example: 05h, 101b).
- Lexer.setLexMasmIntegers(true);
- std::unique_ptr<MCTargetAsmParser> TAP(
- TheTarget.createMCAsmParser(STI, *Parser, MCII, Opts));
- if (!TAP)
- return make_error<StringError>(
- "This target does not support assembly parsing.",
- inconvertibleErrorCode());
- Parser->setTargetParser(*TAP);
- Parser->Run(false);
- // Set the assembler dialect from the input. llvm-mca will use this as the
- // default dialect when printing reports.
- AssemblerDialect = Parser->getAssemblerDialect();
- return Regions;
- }
- } // namespace mca
- } // namespace llvm
|