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``
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 that is not already exposed through MC layer
+classes (MCSubtargetInfo, MCInstrInfo, etc.), please add it to the
+`/tools/llvm-mca/View/` directory. However, if your new View is target specific
+AND requires unexposed backend symbols or functionality, you can define it in
+the `/lib/Target/<TargetName>/MCA/` directory.
+
+To enable this target specific View, you will have to use this target's
+CustomBehaviour class to override the `CustomBehaviour::getViews()` methods.
+There are 3 variations of these methods based on where you want your View to
+appear in the output: `getStartViews()`, `getPostInstrInfoViews()`, and
+`getEndViews()`. These methods 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::getViews()` variants, these Views will not be enabled if
+the `-disable-cb` flag is used.
+
+Enabling these custom Views does not affect the non-custom (generic) Views.
+Continue to use the usual command line arguments to enable / disable those
+Views.
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MCA/SourceMgr.h"
+#include "llvm/MCA/View.h"
namespace llvm {
namespace mca {
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<InstRef> IssuedInst,
const InstRef &IR);
+
+ // Functions 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 that is
+ // not already exposed through MC-layer classes. Keep in mind that how this
+ // function is used is that the function is called within llvm-mca.cpp and
+ // then each unique_ptr<View> 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.
+ /// Return a vector of Views that will be added before all other Views.
+ virtual std::vector<std::unique_ptr<View>>
+ getStartViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
+ /// Return a vector of Views that will be added after the InstructionInfoView.
+ virtual std::vector<std::unique_ptr<View>>
+ getPostInstrInfoViews(llvm::MCInstPrinter &IP,
+ llvm::ArrayRef<llvm::MCInst> Insts);
+ /// Return a vector of Views that will be added after all other Views.
+ virtual std::vector<std::unique_ptr<View>>
+ getEndViews(llvm::MCInstPrinter &IP, llvm::ArrayRef<llvm::MCInst> Insts);
};
} // namespace mca
///
//===----------------------------------------------------------------------===//
-#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"
Stages/RetireStage.cpp
Stages/Stage.cpp
Support.cpp
+ View.cpp
ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm/MCA
return 0;
}
+std::vector<std::unique_ptr<View>>
+CustomBehaviour::getStartViews(llvm::MCInstPrinter &IP,
+ llvm::ArrayRef<llvm::MCInst> Insts) {
+ return std::vector<std::unique_ptr<View>>();
+}
+
+std::vector<std::unique_ptr<View>>
+CustomBehaviour::getPostInstrInfoViews(llvm::MCInstPrinter &IP,
+ llvm::ArrayRef<llvm::MCInst> Insts) {
+ return std::vector<std::unique_ptr<View>>();
+}
+
+std::vector<std::unique_ptr<View>>
+CustomBehaviour::getEndViews(llvm::MCInstPrinter &IP,
+ llvm::ArrayRef<llvm::MCInst> Insts) {
+ return std::vector<std::unique_ptr<View>>();
+}
+
} // namespace mca
} // namespace llvm
///
//===----------------------------------------------------------------------===//
-#include "Views/View.h"
+#include "llvm/MCA/View.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCSubtargetInfo.h"
Views/SchedulerStatistics.cpp
Views/SummaryView.cpp
Views/TimelineView.cpp
- Views/View.cpp
)
set(LLVM_MCA_SOURCE_DIR ${CURRENT_SOURCE_DIR})
#include "PipelinePrinter.h"
#include "CodeRegion.h"
#include "Views/InstructionView.h"
-#include "Views/View.h"
namespace llvm {
namespace mca {
#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"
#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 <map>
namespace llvm {
#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"
#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 {
#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 <map>
namespace llvm {
#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 <map>
namespace llvm {
#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 {
mca::PipelinePrinter Printer(*P, *Region, RegionIdx, *STI, PO);
+ // 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 that are not already exposed
+ // through one of the MC-layer classes. These Views will be initialized
+ // using the CustomBehaviour::getViews() variants.
+ // 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<std::unique_ptr<mca::View>> CBViews =
+ CB->getStartViews(*IP, Insts);
+ for (auto &CBView : CBViews)
+ Printer.addView(std::move(CBView));
+ }
+
// When we output JSON, we add a view that contains the instructions
// and CPU resource information.
if (PrintJson) {
Printer.addView(std::make_unique<mca::InstructionInfoView>(
*STI, *MCII, CE, ShowEncoding, Insts, *IP));
+ // Fetch custom Views that are to be placed after the InstructionInfoView.
+ // Refer to the comment paired with the CB->getStartViews(*IP, Insts); line
+ // for more info.
+ if (!DisableCustomBehaviour) {
+ std::vector<std::unique_ptr<mca::View>> CBViews =
+ CB->getPostInstrInfoViews(*IP, Insts);
+ for (auto &CBView : CBViews)
+ Printer.addView(std::move(CBView));
+ }
+
if (PrintDispatchStats)
Printer.addView(std::make_unique<mca::DispatchStatistics>());
TimelineMaxCycles));
}
+ // Fetch custom Views that are to be placed after all other Views.
+ // Refer to the comment paired with the CB->getStartViews(*IP, Insts); line
+ // for more info.
+ if (!DisableCustomBehaviour) {
+ std::vector<std::unique_ptr<mca::View>> CBViews =
+ CB->getEndViews(*IP, Insts);
+ for (auto &CBView : CBViews)
+ Printer.addView(std::move(CBView));
+ }
+
if (!runPipeline(*P))
return 1;