aboutsummaryrefslogtreecommitdiff
path: root/tools/llvm-mca
diff options
context:
space:
mode:
authorMatt Davis <Matthew.Davis@sony.com>2018-07-06 18:03:14 +0000
committerMatt Davis <Matthew.Davis@sony.com>2018-07-06 18:03:14 +0000
commit73b3f8bb2de6bb98635880b4cdc636f080d40425 (patch)
tree88b4c36c9a41b391533ab37fa69e7116da1eb5dc /tools/llvm-mca
parent80e7ea0a47d867c27fc9651ceb8e9eb70f8246a5 (diff)
[llvm-mca] Add HardwareUnit and Context classes.
This patch moves the construction of the default backend from llvm-mca.cpp and into mca::Context. The Context class is responsible for holding ownership of the simulated hardware components. These components are subclasses of HardwareUnit. Right now the HardwareUnit is pretty bare-bones, but eventually we might want to add some common functionality across all hardware components, such as isReady() or something similar. I have a feeling this patch will probably need some updates, but it's a start. One thing I am not particularly fond of is the rather large interface for createDefaultPipeline. That convenience routine takes a rather large set of inputs from the llvm-mca driver, where many of those inputs are generated via command line options. One item I think we might want to change is the separating of ownership of hardware components (owned by the context) and the pipeline (which owns Stages). In short, a Pipeline owns Stages, a Context (currently) owns hardware. The Pipeline's Stages make use of the components, and thus there is a lifetime dependency generated. The components must outlive the pipeline. We could solve this by having the Context also own the Pipeline, and not return a unique_ptr<Pipeline>. Now that I think about it, I like that idea more. Differential Revision: https://reviews.llvm.org/D48691 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@336456 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'tools/llvm-mca')
-rw-r--r--tools/llvm-mca/CMakeLists.txt2
-rw-r--r--tools/llvm-mca/Context.cpp65
-rw-r--r--tools/llvm-mca/Context.h68
-rw-r--r--tools/llvm-mca/HardwareUnit.cpp23
-rw-r--r--tools/llvm-mca/HardwareUnit.h31
-rw-r--r--tools/llvm-mca/RegisterFile.h8
-rw-r--r--tools/llvm-mca/RetireControlUnit.h3
-rw-r--r--tools/llvm-mca/Scheduler.h3
-rw-r--r--tools/llvm-mca/llvm-mca.cpp29
9 files changed, 207 insertions, 25 deletions
diff --git a/tools/llvm-mca/CMakeLists.txt b/tools/llvm-mca/CMakeLists.txt
index f98d6313f0e..bb657b8d19f 100644
--- a/tools/llvm-mca/CMakeLists.txt
+++ b/tools/llvm-mca/CMakeLists.txt
@@ -11,11 +11,13 @@ set(LLVM_LINK_COMPONENTS
add_llvm_tool(llvm-mca
CodeRegion.cpp
+ Context.cpp
DispatchStage.cpp
DispatchStatistics.cpp
ExecuteStage.cpp
FetchStage.cpp
HWEventListener.cpp
+ HardwareUnit.cpp
InstrBuilder.cpp
Instruction.cpp
InstructionInfoView.cpp
diff --git a/tools/llvm-mca/Context.cpp b/tools/llvm-mca/Context.cpp
new file mode 100644
index 00000000000..8bfc56bc569
--- /dev/null
+++ b/tools/llvm-mca/Context.cpp
@@ -0,0 +1,65 @@
+//===---------------------------- Context.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 a class for holding ownership of various simulated
+/// hardware units. A Context also provides a utility routine for constructing
+/// a default out-of-order pipeline with fetch, dispatch, execute, and retire
+/// stages).
+///
+//===----------------------------------------------------------------------===//
+
+#include "Context.h"
+#include "DispatchStage.h"
+#include "ExecuteStage.h"
+#include "FetchStage.h"
+#include "RegisterFile.h"
+#include "RetireControlUnit.h"
+#include "RetireStage.h"
+#include "Scheduler.h"
+
+namespace mca {
+
+using namespace llvm;
+
+std::unique_ptr<Pipeline>
+Context::createDefaultPipeline(const PipelineOptions &Opts, InstrBuilder &IB,
+ SourceMgr &SrcMgr) {
+ const MCSchedModel &SM = STI.getSchedModel();
+
+ // Create the hardware units defining the backend.
+ auto RCU = llvm::make_unique<RetireControlUnit>(SM);
+ auto PRF = llvm::make_unique<RegisterFile>(SM, MRI, Opts.RegisterFileSize);
+ auto HWS = llvm::make_unique<Scheduler>(
+ SM, Opts.LoadQueueSize, Opts.StoreQueueSize, Opts.AssumeNoAlias);
+
+ // Create the pipeline and its stages.
+ auto P = llvm::make_unique<Pipeline>(
+ Opts.DispatchWidth, Opts.RegisterFileSize, Opts.LoadQueueSize,
+ Opts.StoreQueueSize, Opts.AssumeNoAlias);
+ auto F = llvm::make_unique<FetchStage>(IB, SrcMgr);
+ auto D = llvm::make_unique<DispatchStage>(
+ STI, MRI, Opts.RegisterFileSize, Opts.DispatchWidth, *RCU, *PRF, *HWS);
+ auto R = llvm::make_unique<RetireStage>(*RCU, *PRF);
+ auto E = llvm::make_unique<ExecuteStage>(*RCU, *HWS);
+
+ // Add the hardware to the context.
+ addHardwareUnit(std::move(RCU));
+ addHardwareUnit(std::move(PRF));
+ addHardwareUnit(std::move(HWS));
+
+ // Build the pipeline.
+ P->appendStage(std::move(F));
+ P->appendStage(std::move(D));
+ P->appendStage(std::move(R));
+ P->appendStage(std::move(E));
+ return P;
+}
+
+} // namespace mca
diff --git a/tools/llvm-mca/Context.h b/tools/llvm-mca/Context.h
new file mode 100644
index 00000000000..cf483fa7b37
--- /dev/null
+++ b/tools/llvm-mca/Context.h
@@ -0,0 +1,68 @@
+//===---------------------------- Context.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 defines a class for holding ownership of various simulated
+/// hardware units. A Context also provides a utility routine for constructing
+/// a default out-of-order pipeline with fetch, dispatch, execute, and retire
+/// stages).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_CONTEXT_H
+#define LLVM_TOOLS_LLVM_MCA_CONTEXT_H
+#include "HardwareUnit.h"
+#include "InstrBuilder.h"
+#include "Pipeline.h"
+#include "SourceMgr.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include <memory>
+
+namespace mca {
+
+/// This is a convenience struct to hold the parameters necessary for creating
+/// the pre-built "default" out-of-order pipeline.
+struct PipelineOptions {
+ PipelineOptions(unsigned DW, unsigned RFS, unsigned LQS, unsigned SQS,
+ bool NoAlias)
+ : DispatchWidth(DW), RegisterFileSize(RFS), LoadQueueSize(LQS),
+ StoreQueueSize(SQS), AssumeNoAlias(NoAlias) {}
+ unsigned DispatchWidth;
+ unsigned RegisterFileSize;
+ unsigned LoadQueueSize;
+ unsigned StoreQueueSize;
+ bool AssumeNoAlias;
+};
+
+class Context {
+ llvm::SmallVector<std::unique_ptr<HardwareUnit>, 4> Hardware;
+ const llvm::MCRegisterInfo &MRI;
+ const llvm::MCSubtargetInfo &STI;
+
+public:
+ Context(const llvm::MCRegisterInfo &R, const llvm::MCSubtargetInfo &S)
+ : MRI(R), STI(S) {}
+ Context(const Context &C) = delete;
+ Context &operator=(const Context &C) = delete;
+
+ void addHardwareUnit(std::unique_ptr<HardwareUnit> H) {
+ Hardware.push_back(std::move(H));
+ }
+
+ /// Construct a basic pipeline for simulating an out-of-order pipeline.
+ /// This pipeline consists of Fetch, Dispatch, Execute, and Retire stages.
+ std::unique_ptr<Pipeline> createDefaultPipeline(const PipelineOptions &Opts,
+ InstrBuilder &IB,
+ SourceMgr &SrcMgr);
+};
+
+} // namespace mca
+#endif // LLVM_TOOLS_LLVM_MCA_CONTEXT_H
diff --git a/tools/llvm-mca/HardwareUnit.cpp b/tools/llvm-mca/HardwareUnit.cpp
new file mode 100644
index 00000000000..103cde9afcc
--- /dev/null
+++ b/tools/llvm-mca/HardwareUnit.cpp
@@ -0,0 +1,23 @@
+//===------------------------- HardwareUnit.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 the anchor for the base class that describes
+/// simulated hardware units.
+///
+//===----------------------------------------------------------------------===//
+
+#include "HardwareUnit.h"
+
+namespace mca {
+
+// Pin the vtable with this method.
+HardwareUnit::~HardwareUnit() = default;
+
+} // namespace mca
diff --git a/tools/llvm-mca/HardwareUnit.h b/tools/llvm-mca/HardwareUnit.h
new file mode 100644
index 00000000000..e8c496ab967
--- /dev/null
+++ b/tools/llvm-mca/HardwareUnit.h
@@ -0,0 +1,31 @@
+//===-------------------------- HardwareUnit.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 defines a base class for describing a simulated hardware
+/// unit. These units are used to construct a simulated backend.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_HARDWAREUNIT_H
+#define LLVM_TOOLS_LLVM_MCA_HARDWAREUNIT_H
+
+namespace mca {
+
+class HardwareUnit {
+ HardwareUnit(const HardwareUnit &H) = delete;
+ HardwareUnit &operator=(const HardwareUnit &H) = delete;
+
+public:
+ HardwareUnit() = default;
+ virtual ~HardwareUnit();
+};
+
+} // namespace mca
+#endif // LLVM_TOOLS_LLVM_MCA_HARDWAREUNIT_H
diff --git a/tools/llvm-mca/RegisterFile.h b/tools/llvm-mca/RegisterFile.h
index b93bdeb2eae..8817b8ba60e 100644
--- a/tools/llvm-mca/RegisterFile.h
+++ b/tools/llvm-mca/RegisterFile.h
@@ -17,6 +17,7 @@
#ifndef LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H
#define LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H
+#include "HardwareUnit.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSchedule.h"
@@ -29,12 +30,13 @@ class WriteRef;
/// Manages hardware register files, and tracks register definitions for
/// register renaming purposes.
-class RegisterFile {
+class RegisterFile : public HardwareUnit {
const llvm::MCRegisterInfo &MRI;
// Each register file is associated with an instance of
- // RegisterMappingTracker. A RegisterMappingTracker tracks the number of
- // physical registers that are dynamically allocated by the simulator.
+ // RegisterMappingTracker.
+ // A RegisterMappingTracker keeps track of the number of physical registers
+ // which have been dynamically allocated by the simulator.
struct RegisterMappingTracker {
// The total number of physical registers that are available in this
// register file for register renaming purpouses. A value of zero for this
diff --git a/tools/llvm-mca/RetireControlUnit.h b/tools/llvm-mca/RetireControlUnit.h
index 7c076561428..3530ff21ba0 100644
--- a/tools/llvm-mca/RetireControlUnit.h
+++ b/tools/llvm-mca/RetireControlUnit.h
@@ -15,6 +15,7 @@
#ifndef LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
#define LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
+#include "HardwareUnit.h"
#include "Instruction.h"
#include "llvm/MC/MCSchedule.h"
#include <vector>
@@ -32,7 +33,7 @@ namespace mca {
/// On instruction retired, register updates are all architecturally
/// committed, and any temporary registers originally allocated for the
/// retired instruction are freed.
-struct RetireControlUnit {
+struct RetireControlUnit : public HardwareUnit {
// A RUToken is created by the RCU for every instruction dispatched to the
// schedulers. These "tokens" are managed by the RCU in its token Queue.
//
diff --git a/tools/llvm-mca/Scheduler.h b/tools/llvm-mca/Scheduler.h
index d6da6c08a1c..428fbc01707 100644
--- a/tools/llvm-mca/Scheduler.h
+++ b/tools/llvm-mca/Scheduler.h
@@ -16,6 +16,7 @@
#define LLVM_TOOLS_LLVM_MCA_SCHEDULER_H
#include "HWEventListener.h"
+#include "HardwareUnit.h"
#include "Instruction.h"
#include "LSUnit.h"
#include "RetireControlUnit.h"
@@ -401,7 +402,7 @@ public:
/// issued to a (one or more) pipeline(s). This event also causes an instruction
/// state transition (i.e. from state IS_READY, to state IS_EXECUTING).
/// An Instruction leaves the IssuedQueue when it reaches the write-back stage.
-class Scheduler {
+class Scheduler : public HardwareUnit {
const llvm::MCSchedModel &SM;
// Hardware resources that are managed by this scheduler.
diff --git a/tools/llvm-mca/llvm-mca.cpp b/tools/llvm-mca/llvm-mca.cpp
index 6bea82741db..9398a547fd4 100644
--- a/tools/llvm-mca/llvm-mca.cpp
+++ b/tools/llvm-mca/llvm-mca.cpp
@@ -22,21 +22,15 @@
//===----------------------------------------------------------------------===//
#include "CodeRegion.h"
-#include "DispatchStage.h"
+#include "Context.h"
#include "DispatchStatistics.h"
-#include "ExecuteStage.h"
-#include "FetchStage.h"
#include "InstructionInfoView.h"
#include "InstructionTables.h"
#include "Pipeline.h"
#include "PipelinePrinter.h"
-#include "RegisterFile.h"
#include "RegisterFileStatistics.h"
#include "ResourcePressureView.h"
-#include "RetireControlUnit.h"
#include "RetireControlUnitStatistics.h"
-#include "RetireStage.h"
-#include "Scheduler.h"
#include "SchedulerStatistics.h"
#include "SummaryView.h"
#include "TimelineView.h"
@@ -468,6 +462,12 @@ int main(int argc, char **argv) {
// Create an instruction builder.
mca::InstrBuilder IB(*STI, *MCII, *MRI, *MCIA);
+ // Create a context to control ownership of the pipeline hardware.
+ mca::Context MCA(*MRI, *STI);
+
+ mca::PipelineOptions PO(Width, RegisterFileSize, LoadQueueSize,
+ StoreQueueSize, AssumeNoAlias);
+
// Number each region in the sequence.
unsigned RegionIdx = 0;
for (const std::unique_ptr<mca::CodeRegion> &Region : Regions) {
@@ -502,19 +502,8 @@ int main(int argc, char **argv) {
continue;
}
- // Create the hardware components required for the pipeline.
- mca::RetireControlUnit RCU(SM);
- mca::RegisterFile PRF(SM, *MRI, RegisterFileSize);
- mca::Scheduler HWS(SM, LoadQueueSize, StoreQueueSize, AssumeNoAlias);
-
- // Create the pipeline and add stages to it.
- auto P = llvm::make_unique<mca::Pipeline>(
- Width, RegisterFileSize, LoadQueueSize, StoreQueueSize, AssumeNoAlias);
- P->appendStage(llvm::make_unique<mca::FetchStage>(IB, S));
- P->appendStage(llvm::make_unique<mca::DispatchStage>(
- *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS));
- P->appendStage(llvm::make_unique<mca::RetireStage>(RCU, PRF));
- P->appendStage(llvm::make_unique<mca::ExecuteStage>(RCU, HWS));
+ // Create a basic pipeline simulating an out-of-order backend.
+ auto P = MCA.createDefaultPipeline(PO, IB, S);
mca::PipelinePrinter Printer(*P);
if (PrintSummaryView)