diff --git a/llvm/docs/CommandGuide/llvm-mca.rst b/llvm/docs/CommandGuide/llvm-mca.rst --- a/llvm/docs/CommandGuide/llvm-mca.rst +++ b/llvm/docs/CommandGuide/llvm-mca.rst @@ -997,7 +997,7 @@ purpose or the instruction's behaviour is quite complex). The CustomBehaviour class can be used in these cases to enforce proper instruction modeling (often by customizing data dependencies and detecting -hazards that :program:`llvm-ma` has no way of knowing about). +hazards that :program:`llvm-mca` has no way of knowing about). :program:`llvm-mca` comes with one generic and multiple target specific CustomBehaviour classes. The generic class will be used if the ``-disable-cb`` @@ -1017,3 +1017,22 @@ already have one, refer to an existing implementation to see how to set it up. The classes are implemented within the target specific backend (for example `/llvm/lib/Target/AMDGPU/MCA/`) so that they can access backend symbols. + +Custom Views +"""""""""""""""""""""""""""""""""""" +:program:`llvm-mca` comes with several Views such as the Timeline View and +Summary View. These Views are generic and can work with most (if not all) +targets. If you wish to add a new View to :program:`llvm-mca` and it does not +require any backend functionality, please add it to the `/tools/llvm-mca/View/` +directory. However, if your new View is target specific AND requires backend +symbols or functionality, you can define it in the +`/lib/Target//MCA/` directory. + +To enable this target specific View, you will have to use this target's +CustomBehaviour class to override the `CustomBehaviour::getCBViews()` method. +This method returns a vector of Views so you will want to return a vector +containing all of the target specific Views for the target in question. + +Because these target specific (and backend dependent) Views require the +`CustomBehaviour::getCBViews()` method, these Views will not be enabled if +the `-disable-cb` flag is used. diff --git a/llvm/include/llvm/MCA/CustomBehaviour.h b/llvm/include/llvm/MCA/CustomBehaviour.h --- a/llvm/include/llvm/MCA/CustomBehaviour.h +++ b/llvm/include/llvm/MCA/CustomBehaviour.h @@ -22,6 +22,7 @@ #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MCA/SourceMgr.h" +#include "llvm/MCA/View.h" namespace llvm { namespace mca { @@ -65,19 +66,35 @@ virtual ~CustomBehaviour(); - // Before the llvm-mca pipeline dispatches an instruction, it first checks - // for any register or resource dependencies / hazards. If it doesn't find - // any, this method will be invoked to determine if there are any custom - // hazards that the instruction needs to wait for. - // The return value of this method is the number of cycles that the - // instruction needs to wait for. - // It's safe to underestimate the number of cycles to wait for since these - // checks will be invoked again before the intruction gets dispatched. - // However, it's not safe (accurate) to overestimate the number of cycles - // to wait for since the instruction will wait for AT LEAST that number of - // cycles before attempting to be dispatched again. + /// Before the llvm-mca pipeline dispatches an instruction, it first checks + /// for any register or resource dependencies / hazards. If it doesn't find + /// any, this method will be invoked to determine if there are any custom + /// hazards that the instruction needs to wait for. + /// The return value of this method is the number of cycles that the + /// instruction needs to wait for. + /// It's safe to underestimate the number of cycles to wait for since these + /// checks will be invoked again before the intruction gets dispatched. + /// However, it's not safe (accurate) to overestimate the number of cycles + /// to wait for since the instruction will wait for AT LEAST that number of + /// cycles before attempting to be dispatched again. virtual unsigned checkCustomHazard(ArrayRef IssuedInst, const InstRef &IR); + + /// Function that target CBs can override to return a list of + /// target specific Views that need to live within /lib/Target/ so that + /// they can benefit from the target CB or from backend functionality. + /// Keep in mind that how this function is used is that the function is + /// called within llvm-mca.cpp and then each unique_ptr is passed into + /// the PipelinePrinter::addView() function. This function will then + /// std::move the View into its own vector of Views. So any CB that overrides + /// this function needs to make sure that they are not relying on the + /// current address or reference of the View unique_ptrs. + /// If you do need the CB and View to be able to communicate with each other, + /// consider giving the View a reference or pointer to the CB when the View + /// is constructed. Then the View can query the CB for information when it + /// needs it. + virtual std::vector> + getCBViews(llvm::MCInstPrinter &IP, llvm::ArrayRef Insts); }; } // namespace mca diff --git a/llvm/tools/llvm-mca/Views/View.h b/llvm/include/llvm/MCA/View.h rename from llvm/tools/llvm-mca/Views/View.h rename to llvm/include/llvm/MCA/View.h --- a/llvm/tools/llvm-mca/Views/View.h +++ b/llvm/include/llvm/MCA/View.h @@ -12,8 +12,8 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_TOOLS_LLVM_MCA_VIEW_H -#define LLVM_TOOLS_LLVM_MCA_VIEW_H +#ifndef LLVM_MCA_VIEW_H +#define LLVM_MCA_VIEW_H #include "llvm/MC/MCInstPrinter.h" #include "llvm/MCA/HWEventListener.h" diff --git a/llvm/lib/MCA/CMakeLists.txt b/llvm/lib/MCA/CMakeLists.txt --- a/llvm/lib/MCA/CMakeLists.txt +++ b/llvm/lib/MCA/CMakeLists.txt @@ -21,6 +21,7 @@ Stages/RetireStage.cpp Stages/Stage.cpp Support.cpp + View.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/MCA diff --git a/llvm/lib/MCA/CustomBehaviour.cpp b/llvm/lib/MCA/CustomBehaviour.cpp --- a/llvm/lib/MCA/CustomBehaviour.cpp +++ b/llvm/lib/MCA/CustomBehaviour.cpp @@ -24,5 +24,11 @@ return 0; } +std::vector> +CustomBehaviour::getCBViews(llvm::MCInstPrinter &IP, + llvm::ArrayRef Insts) { + return std::vector>(); +} + } // namespace mca } // namespace llvm diff --git a/llvm/tools/llvm-mca/Views/View.cpp b/llvm/lib/MCA/View.cpp rename from llvm/tools/llvm-mca/Views/View.cpp rename to llvm/lib/MCA/View.cpp --- a/llvm/tools/llvm-mca/Views/View.cpp +++ b/llvm/lib/MCA/View.cpp @@ -11,7 +11,7 @@ /// //===----------------------------------------------------------------------===// -#include "Views/View.h" +#include "llvm/MCA/View.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" diff --git a/llvm/tools/llvm-mca/CMakeLists.txt b/llvm/tools/llvm-mca/CMakeLists.txt --- a/llvm/tools/llvm-mca/CMakeLists.txt +++ b/llvm/tools/llvm-mca/CMakeLists.txt @@ -27,7 +27,6 @@ Views/SchedulerStatistics.cpp Views/SummaryView.cpp Views/TimelineView.cpp - Views/View.cpp ) set(LLVM_MCA_SOURCE_DIR ${CURRENT_SOURCE_DIR}) diff --git a/llvm/tools/llvm-mca/PipelinePrinter.h b/llvm/tools/llvm-mca/PipelinePrinter.h --- a/llvm/tools/llvm-mca/PipelinePrinter.h +++ b/llvm/tools/llvm-mca/PipelinePrinter.h @@ -16,11 +16,11 @@ #ifndef LLVM_TOOLS_LLVM_MCA_PIPELINEPRINTER_H #define LLVM_TOOLS_LLVM_MCA_PIPELINEPRINTER_H -#include "Views/View.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCSubtargetInfo.h" #include "llvm/MCA/Context.h" #include "llvm/MCA/Pipeline.h" +#include "llvm/MCA/View.h" #include "llvm/Support/raw_ostream.h" #define DEBUG_TYPE "llvm-mca" diff --git a/llvm/tools/llvm-mca/PipelinePrinter.cpp b/llvm/tools/llvm-mca/PipelinePrinter.cpp --- a/llvm/tools/llvm-mca/PipelinePrinter.cpp +++ b/llvm/tools/llvm-mca/PipelinePrinter.cpp @@ -14,7 +14,6 @@ #include "PipelinePrinter.h" #include "CodeRegion.h" #include "Views/InstructionView.h" -#include "Views/View.h" namespace llvm { namespace mca { diff --git a/llvm/tools/llvm-mca/Views/DispatchStatistics.h b/llvm/tools/llvm-mca/Views/DispatchStatistics.h --- a/llvm/tools/llvm-mca/Views/DispatchStatistics.h +++ b/llvm/tools/llvm-mca/Views/DispatchStatistics.h @@ -33,9 +33,9 @@ #ifndef LLVM_TOOLS_LLVM_MCA_DISPATCHVIEW_H #define LLVM_TOOLS_LLVM_MCA_DISPATCHVIEW_H -#include "Views/View.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MCA/View.h" #include namespace llvm { diff --git a/llvm/tools/llvm-mca/Views/InstructionView.h b/llvm/tools/llvm-mca/Views/InstructionView.h --- a/llvm/tools/llvm-mca/Views/InstructionView.h +++ b/llvm/tools/llvm-mca/Views/InstructionView.h @@ -15,7 +15,7 @@ #ifndef LLVM_TOOLS_LLVM_MCA_INSTRUCTIONVIEW_H #define LLVM_TOOLS_LLVM_MCA_INSTRUCTIONVIEW_H -#include "Views/View.h" +#include "llvm/MCA/View.h" #include "llvm/Support/JSON.h" #include "llvm/Support/raw_ostream.h" diff --git a/llvm/tools/llvm-mca/Views/RegisterFileStatistics.h b/llvm/tools/llvm-mca/Views/RegisterFileStatistics.h --- a/llvm/tools/llvm-mca/Views/RegisterFileStatistics.h +++ b/llvm/tools/llvm-mca/Views/RegisterFileStatistics.h @@ -35,9 +35,9 @@ #ifndef LLVM_TOOLS_LLVM_MCA_REGISTERFILESTATISTICS_H #define LLVM_TOOLS_LLVM_MCA_REGISTERFILESTATISTICS_H -#include "Views/View.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MCA/View.h" namespace llvm { namespace mca { diff --git a/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.h b/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.h --- a/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.h +++ b/llvm/tools/llvm-mca/Views/RetireControlUnitStatistics.h @@ -28,8 +28,8 @@ #ifndef LLVM_TOOLS_LLVM_MCA_RETIRECONTROLUNITSTATISTICS_H #define LLVM_TOOLS_LLVM_MCA_RETIRECONTROLUNITSTATISTICS_H -#include "Views/View.h" #include "llvm/MC/MCSchedule.h" +#include "llvm/MCA/View.h" #include namespace llvm { diff --git a/llvm/tools/llvm-mca/Views/SchedulerStatistics.h b/llvm/tools/llvm-mca/Views/SchedulerStatistics.h --- a/llvm/tools/llvm-mca/Views/SchedulerStatistics.h +++ b/llvm/tools/llvm-mca/Views/SchedulerStatistics.h @@ -36,9 +36,9 @@ #ifndef LLVM_TOOLS_LLVM_MCA_SCHEDULERSTATISTICS_H #define LLVM_TOOLS_LLVM_MCA_SCHEDULERSTATISTICS_H -#include "Views/View.h" #include "llvm/ADT/SmallVector.h" #include "llvm/MC/MCSubtargetInfo.h" +#include "llvm/MCA/View.h" #include namespace llvm { diff --git a/llvm/tools/llvm-mca/Views/SummaryView.h b/llvm/tools/llvm-mca/Views/SummaryView.h --- a/llvm/tools/llvm-mca/Views/SummaryView.h +++ b/llvm/tools/llvm-mca/Views/SummaryView.h @@ -28,9 +28,9 @@ #ifndef LLVM_TOOLS_LLVM_MCA_SUMMARYVIEW_H #define LLVM_TOOLS_LLVM_MCA_SUMMARYVIEW_H -#include "Views/View.h" #include "llvm/ADT/DenseMap.h" #include "llvm/MC/MCSchedule.h" +#include "llvm/MCA/View.h" #include "llvm/Support/raw_ostream.h" namespace llvm { diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -640,6 +640,20 @@ TimelineMaxCycles)); } + // Targets can define their own custom Views that exist within their + // /lib/Target/ directory so that the View can utilize their CustomBehaviour + // or other backend symbols / functionality. These Views will be initialized + // using the CustomBehaviour::getCBViews() function. + // If a target makes a custom View that does not depend on their target + // CB or their backend, they should put the View within + // /tools/llvm-mca/Views/ instead. + if (!DisableCustomBehaviour) { + std::vector> CBViews = + CB->getCBViews(*IP, Insts); + for (auto &CBView : CBViews) + Printer.addView(std::move(CBView)); + } + if (!runPipeline(*P)) return 1;