[llvm] r346344 - [llvm-mca] Move the AssembleInput logic into its own class.
Matt Davis via llvm-commits
llvm-commits at lists.llvm.org
Wed Nov 7 11:20:04 PST 2018
Author: mattd
Date: Wed Nov 7 11:20:04 2018
New Revision: 346344
URL: http://llvm.org/viewvc/llvm-project?rev=346344&view=rev
Log:
[llvm-mca] Move the AssembleInput logic into its own class.
Summary:
This patch introduces a CodeRegionGenerator class which is responsible for parsing some type of input and creating a 'CodeRegions' instance for use by llvm-mca. In the future, we will also have a CodeRegionGenerator subclass for converting an input object file into CodeRegions. For now, we only have the subclass for converting input assembly into CodeRegions.
This is mostly a NFC patch, as the logic remains close to the original, but now encapsulated in its own class and moved outside of llvm-mca.cpp.
Reviewers: andreadb, courbet, RKSimon
Reviewed By: andreadb
Subscribers: mgorny, tschuett, gbedwell, llvm-commits
Differential Revision: https://reviews.llvm.org/D54179
Added:
llvm/trunk/tools/llvm-mca/CodeRegionGenerator.cpp
llvm/trunk/tools/llvm-mca/CodeRegionGenerator.h
Modified:
llvm/trunk/tools/llvm-mca/CMakeLists.txt
llvm/trunk/tools/llvm-mca/CodeRegion.h
llvm/trunk/tools/llvm-mca/llvm-mca.cpp
Modified: llvm/trunk/tools/llvm-mca/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CMakeLists.txt?rev=346344&r1=346343&r2=346344&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-mca/CMakeLists.txt Wed Nov 7 11:20:04 2018
@@ -14,6 +14,7 @@ set(LLVM_LINK_COMPONENTS
add_llvm_tool(llvm-mca
llvm-mca.cpp
CodeRegion.cpp
+ CodeRegionGenerator.cpp
PipelinePrinter.cpp
Views/DispatchStatistics.cpp
Views/InstructionInfoView.cpp
Modified: llvm/trunk/tools/llvm-mca/CodeRegion.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CodeRegion.h?rev=346344&r1=346343&r2=346344&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/CodeRegion.h (original)
+++ llvm/trunk/tools/llvm-mca/CodeRegion.h Wed Nov 7 11:20:04 2018
@@ -106,6 +106,7 @@ public:
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc);
void endRegion(llvm::SMLoc Loc);
void addInstruction(const llvm::MCInst &Instruction);
+ llvm::SourceMgr &getSourceMgr() const { return SM; }
CodeRegions(llvm::SourceMgr &S) : SM(S) {
// Create a default region for the input code sequence.
Added: llvm/trunk/tools/llvm-mca/CodeRegionGenerator.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CodeRegionGenerator.cpp?rev=346344&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/CodeRegionGenerator.cpp (added)
+++ llvm/trunk/tools/llvm-mca/CodeRegionGenerator.cpp Wed Nov 7 11:20:04 2018
@@ -0,0 +1,137 @@
+//===----------------------- CodeRegionGenerator.cpp ------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \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 */,
+ bool /* 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")) {
+ Regions.endRegion(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);
+
+ // Create a target-specific parser and perform the parse.
+ 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);
+
+ // Get 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
Added: llvm/trunk/tools/llvm-mca/CodeRegionGenerator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CodeRegionGenerator.h?rev=346344&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/CodeRegionGenerator.h (added)
+++ llvm/trunk/tools/llvm-mca/CodeRegionGenerator.h Wed Nov 7 11:20:04 2018
@@ -0,0 +1,70 @@
+//===----------------------- CodeRegionGenerator.h --------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file declares 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.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H
+#define LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H
+
+#include "CodeRegion.h"
+#include "llvm/MC/MCAsmInfo.h"
+#include "llvm/MC/MCContext.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include "llvm/Support/Error.h"
+#include "llvm/Support/SourceMgr.h"
+#include "llvm/Support/TargetRegistry.h"
+#include <memory>
+
+namespace llvm {
+namespace mca {
+
+/// This class is responsible for parsing the input given to the llvm-mca
+/// driver, and converting that into a CodeRegions instance.
+class CodeRegionGenerator {
+protected:
+ CodeRegions Regions;
+ CodeRegionGenerator(const CodeRegionGenerator &) = delete;
+ CodeRegionGenerator &operator=(const CodeRegionGenerator &) = delete;
+
+public:
+ CodeRegionGenerator(SourceMgr &SM) : Regions(SM) {}
+ virtual ~CodeRegionGenerator();
+ virtual Expected<const CodeRegions &> parseCodeRegions() = 0;
+};
+
+/// This class is responsible for parsing input ASM and generating
+/// a CodeRegions instance.
+class AsmCodeRegionGenerator final : public CodeRegionGenerator {
+ const Target &TheTarget;
+ MCContext &Ctx;
+ const MCAsmInfo &MAI;
+ const MCSubtargetInfo &STI;
+ const MCInstrInfo &MCII;
+ unsigned AssemblerDialect; // This is set during parsing.
+
+public:
+ AsmCodeRegionGenerator(const Target &T, SourceMgr &SM, MCContext &C,
+ const MCAsmInfo &A, const MCSubtargetInfo &S,
+ const MCInstrInfo &I)
+ : CodeRegionGenerator(SM), TheTarget(T), Ctx(C), MAI(A), STI(S), MCII(I),
+ AssemblerDialect(0) {}
+
+ unsigned getAssemblerDialect() const { return AssemblerDialect; }
+ Expected<const CodeRegions &> parseCodeRegions() override;
+};
+
+} // namespace mca
+} // namespace llvm
+
+#endif // LLVM_TOOLS_LLVM_MCA_CODEREGION_GENERATOR_H
Modified: llvm/trunk/tools/llvm-mca/llvm-mca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/llvm-mca.cpp?rev=346344&r1=346343&r2=346344&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/llvm-mca.cpp (original)
+++ llvm/trunk/tools/llvm-mca/llvm-mca.cpp Wed Nov 7 11:20:04 2018
@@ -22,6 +22,7 @@
//===----------------------------------------------------------------------===//
#include "CodeRegion.h"
+#include "CodeRegionGenerator.h"
#include "PipelinePrinter.h"
#include "Stages/FetchStage.h"
#include "Stages/InstructionTables.h"
@@ -39,9 +40,7 @@
#include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCObjectFileInfo.h"
-#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
-#include "llvm/MC/MCStreamer.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ErrorOr.h"
@@ -199,59 +198,6 @@ const Target *getTarget(const char *Prog
return TheTarget;
}
-// A comment consumer that parses strings.
-// The only valid tokens are strings.
-class MCACommentConsumer : public AsmCommentConsumer {
-public:
- mca::CodeRegions &Regions;
-
- MCACommentConsumer(mca::CodeRegions &R) : Regions(R) {}
- void HandleComment(SMLoc Loc, StringRef CommentText) override {
- // 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")) {
- Regions.endRegion(Loc);
- return;
- }
-
- // Now try to parse string LLVM-MCA-BEGIN
- 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);
- }
-};
-
-int AssembleInput(MCAsmParser &Parser, const Target *TheTarget,
- MCSubtargetInfo &STI, MCInstrInfo &MCII,
- MCTargetOptions &MCOptions) {
- std::unique_ptr<MCTargetAsmParser> TAP(
- TheTarget->createMCAsmParser(STI, Parser, MCII, MCOptions));
-
- if (!TAP) {
- WithColor::error() << "this target does not support assembly parsing.\n";
- return 1;
- }
-
- Parser.setTargetParser(*TAP);
- return Parser.Run(false);
-}
-
ErrorOr<std::unique_ptr<ToolOutputFile>> getOutputStream() {
if (OutputFilename == "")
OutputFilename = "-";
@@ -262,40 +208,6 @@ ErrorOr<std::unique_ptr<ToolOutputFile>>
return std::move(Out);
return EC;
}
-
-class MCStreamerWrapper final : public MCStreamer {
- mca::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 */,
- bool /* 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);
- }
-};
} // end of anonymous namespace
static void processOptionImpl(cl::opt<bool> &O, const cl::opt<bool> &Default) {
@@ -352,9 +264,6 @@ int main(int argc, char **argv) {
cl::ParseCommandLineOptions(argc, argv,
"llvm machine code performance analyzer.\n");
- MCTargetOptions MCOptions;
- MCOptions.PreserveAsmComments = false;
-
// Get the target from the triple. If a triple is not specified, then select
// the default triple for the host. If the triple doesn't correspond to any
// registered target, then exit with an error message.
@@ -394,9 +303,6 @@ int main(int argc, char **argv) {
std::unique_ptr<buffer_ostream> BOS;
- mca::CodeRegions Regions(SrcMgr);
- MCStreamerWrapper Str(Ctx, Regions);
-
std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
std::unique_ptr<MCInstrAnalysis> MCIA(
@@ -429,14 +335,14 @@ int main(int argc, char **argv) {
return 1;
}
- std::unique_ptr<MCAsmParser> P(createMCAsmParser(SrcMgr, Ctx, Str, *MAI));
- MCAsmLexer &Lexer = P->getLexer();
- MCACommentConsumer CC(Regions);
- Lexer.setCommentConsumer(&CC);
-
- if (AssembleInput(*P, TheTarget, *STI, *MCII, MCOptions))
+ // Parse the input and create CodeRegions that llvm-mca can analyze.
+ mca::AsmCodeRegionGenerator CRG(*TheTarget, SrcMgr, Ctx, *MAI, *STI, *MCII);
+ Expected<const mca::CodeRegions &> RegionsOrErr = CRG.parseCodeRegions();
+ if (auto Err = RegionsOrErr.takeError()) {
+ WithColor::error() << Err << "\n";
return 1;
-
+ }
+ const mca::CodeRegions &Regions = *RegionsOrErr;
if (Regions.empty()) {
WithColor::error() << "no assembly instructions found.\n";
return 1;
@@ -449,7 +355,7 @@ int main(int argc, char **argv) {
return 1;
}
- unsigned AssemblerDialect = P->getAssemblerDialect();
+ unsigned AssemblerDialect = CRG.getAssemblerDialect();
if (OutputAsmVariant >= 0)
AssemblerDialect = static_cast<unsigned>(OutputAsmVariant);
std::unique_ptr<MCInstPrinter> IP(TheTarget->createMCInstPrinter(
More information about the llvm-commits
mailing list