diff options
Diffstat (limited to 'llvm/tools/llvm-mca/llvm-mca.cpp')
-rw-r--r-- | llvm/tools/llvm-mca/llvm-mca.cpp | 147 |
1 files changed, 105 insertions, 42 deletions
diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp index 91bcb90b3a4..3f9682da17f 100644 --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -23,6 +23,7 @@ #include "BackendPrinter.h" #include "BackendStatistics.h" +#include "CodeRegion.h" #include "InstructionInfoView.h" #include "InstructionTables.h" #include "RegisterFileStatistics.h" @@ -158,6 +159,44 @@ const Target *getTarget(const char *ProgName) { 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.drop_front(Position); + // Use the rest of the string as a descriptor for this code snippet. + Regions.beginRegion(Comment, Loc); + } +}; + int AssembleInput(const char *ProgName, MCAsmParser &Parser, const Target *TheTarget, MCSubtargetInfo &STI, MCInstrInfo &MCII, MCTargetOptions &MCOptions) { @@ -186,17 +225,16 @@ ErrorOr<std::unique_ptr<ToolOutputFile>> getOutputStream() { } class MCStreamerWrapper final : public MCStreamer { - using InstVec = std::vector<std::unique_ptr<const MCInst>>; - InstVec &Insts; + mca::CodeRegions &Regions; public: - MCStreamerWrapper(MCContext &Context, InstVec &Vec) - : MCStreamer(Context), Insts(Vec) {} + 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 &STI, bool /* unused */) override { - Insts.emplace_back(new MCInst(Inst)); + Regions.addInstruction(llvm::make_unique<const MCInst>(Inst)); } bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override { @@ -213,7 +251,10 @@ public: void EmitCOFFSymbolType(int Type) override {} void EndCOFFSymbolDef() override {} - const InstVec &GetInstructionSequence() const { return Insts; } + const std::vector<std::unique_ptr<const MCInst>> & + GetInstructionSequence(unsigned Index) const { + return Regions.getInstructionSequence(Index); + } }; } // end of anonymous namespace @@ -272,9 +313,8 @@ int main(int argc, char **argv) { std::unique_ptr<buffer_ostream> BOS; - std::unique_ptr<mca::SourceMgr> S = llvm::make_unique<mca::SourceMgr>( - PrintInstructionTables ? 1 : Iterations); - MCStreamerWrapper Str(Ctx, S->getSequence()); + mca::CodeRegions Regions(SrcMgr); + MCStreamerWrapper Str(Ctx, Regions); std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI( @@ -310,10 +350,14 @@ int main(int argc, char **argv) { } std::unique_ptr<MCAsmParser> P(createMCAsmParser(SrcMgr, Ctx, Str, *MAI)); + MCAsmLexer &Lexer = P->getLexer(); + MCACommentConsumer CC(Regions); + Lexer.setCommentConsumer(&CC); + if (AssembleInput(ProgName, *P, TheTarget, *STI, *MCII, MCOptions)) return 1; - if (S->isEmpty()) { + if (Regions.empty()) { errs() << "error: no assembly instructions found.\n"; return 1; } @@ -336,49 +380,68 @@ int main(int argc, char **argv) { // Create an instruction builder. mca::InstrBuilder IB(*STI, *MCII); - if (PrintInstructionTables) { - mca::InstructionTables IT(STI->getSchedModel(), IB, *S); - - if (PrintInstructionInfoView) { - IT.addView( - llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, *S, *IP)); + // Number each region in the sequence. + unsigned RegionIdx = 0; + for (const std::unique_ptr<mca::CodeRegion> &Region : Regions) { + // Skip empty code regions. + if (Region->empty()) + continue; + + // Don't print the header of this region if it is the default region, and + // it doesn't have an end location. + if (Region->startLoc().isValid() || Region->endLoc().isValid()) { + TOF->os() << "\n[" << RegionIdx++ << "] Code Region"; + StringRef Desc = Region->getDescription(); + if (!Desc.empty()) + TOF->os() << " - " << Desc; + TOF->os() << "\n\n"; } - IT.addView(llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S)); - IT.run(); - IT.printReport(TOF->os()); - TOF->keep(); - return 0; - } + mca::SourceMgr S(Region->getInstructions(), + PrintInstructionTables ? 1 : Iterations); + + if (PrintInstructionTables) { + mca::InstructionTables IT(STI->getSchedModel(), IB, S); + + if (PrintInstructionInfoView) { + IT.addView( + llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, S, *IP)); + } - mca::Backend B(*STI, *MRI, IB, *S, Width, RegisterFileSize, LoadQueueSize, - StoreQueueSize, AssumeNoAlias); - mca::BackendPrinter Printer(B); + IT.addView(llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, S)); + IT.run(); + IT.printReport(TOF->os()); + continue; + } + + mca::Backend B(*STI, *MRI, IB, S, Width, RegisterFileSize, LoadQueueSize, + StoreQueueSize, AssumeNoAlias); + mca::BackendPrinter Printer(B); - Printer.addView(llvm::make_unique<mca::SummaryView>(*S, Width)); + Printer.addView(llvm::make_unique<mca::SummaryView>(S, Width)); + if (PrintInstructionInfoView) + Printer.addView( + llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, S, *IP)); - if (PrintInstructionInfoView) - Printer.addView( - llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, *S, *IP)); + if (PrintModeVerbose) + Printer.addView(llvm::make_unique<mca::BackendStatistics>(*STI)); - if (PrintModeVerbose) - Printer.addView(llvm::make_unique<mca::BackendStatistics>(*STI)); + if (PrintRegisterFileStats) + Printer.addView(llvm::make_unique<mca::RegisterFileStatistics>(*STI)); - if (PrintRegisterFileStats) - Printer.addView(llvm::make_unique<mca::RegisterFileStatistics>(*STI)); + if (PrintResourcePressureView) + Printer.addView( + llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, S)); - if (PrintResourcePressureView) - Printer.addView( - llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S)); + if (PrintTimelineView) { + Printer.addView(llvm::make_unique<mca::TimelineView>( + *STI, *IP, S, TimelineMaxIterations, TimelineMaxCycles)); + } - if (PrintTimelineView) { - Printer.addView(llvm::make_unique<mca::TimelineView>( - *STI, *IP, *S, TimelineMaxIterations, TimelineMaxCycles)); + B.run(); + Printer.printReport(TOF->os()); } - B.run(); - Printer.printReport(TOF->os()); TOF->keep(); - return 0; } |