diff options
author | Matt Davis <Matthew.Davis@sony.com> | 2018-07-06 18:03:14 +0000 |
---|---|---|
committer | Matt Davis <Matthew.Davis@sony.com> | 2018-07-06 18:03:14 +0000 |
commit | 73b3f8bb2de6bb98635880b4cdc636f080d40425 (patch) | |
tree | 88b4c36c9a41b391533ab37fa69e7116da1eb5dc /tools/llvm-mca | |
parent | 80e7ea0a47d867c27fc9651ceb8e9eb70f8246a5 (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.txt | 2 | ||||
-rw-r--r-- | tools/llvm-mca/Context.cpp | 65 | ||||
-rw-r--r-- | tools/llvm-mca/Context.h | 68 | ||||
-rw-r--r-- | tools/llvm-mca/HardwareUnit.cpp | 23 | ||||
-rw-r--r-- | tools/llvm-mca/HardwareUnit.h | 31 | ||||
-rw-r--r-- | tools/llvm-mca/RegisterFile.h | 8 | ||||
-rw-r--r-- | tools/llvm-mca/RetireControlUnit.h | 3 | ||||
-rw-r--r-- | tools/llvm-mca/Scheduler.h | 3 | ||||
-rw-r--r-- | tools/llvm-mca/llvm-mca.cpp | 29 |
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) |