[llvm] r336456 - [llvm-mca] Add HardwareUnit and Context classes.

Matt Davis via llvm-commits llvm-commits at lists.llvm.org
Fri Jul 6 11:03:14 PDT 2018


Author: mattd
Date: Fri Jul  6 11:03:14 2018
New Revision: 336456

URL: http://llvm.org/viewvc/llvm-project?rev=336456&view=rev
Log:
[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

Added:
    llvm/trunk/tools/llvm-mca/Context.cpp
    llvm/trunk/tools/llvm-mca/Context.h
    llvm/trunk/tools/llvm-mca/HardwareUnit.cpp
    llvm/trunk/tools/llvm-mca/HardwareUnit.h
Modified:
    llvm/trunk/tools/llvm-mca/CMakeLists.txt
    llvm/trunk/tools/llvm-mca/RegisterFile.h
    llvm/trunk/tools/llvm-mca/RetireControlUnit.h
    llvm/trunk/tools/llvm-mca/Scheduler.h
    llvm/trunk/tools/llvm-mca/llvm-mca.cpp

Modified: llvm/trunk/tools/llvm-mca/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CMakeLists.txt?rev=336456&r1=336455&r2=336456&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-mca/CMakeLists.txt Fri Jul  6 11:03:14 2018
@@ -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

Added: llvm/trunk/tools/llvm-mca/Context.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Context.cpp?rev=336456&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/Context.cpp (added)
+++ llvm/trunk/tools/llvm-mca/Context.cpp Fri Jul  6 11:03:14 2018
@@ -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

Added: llvm/trunk/tools/llvm-mca/Context.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Context.h?rev=336456&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/Context.h (added)
+++ llvm/trunk/tools/llvm-mca/Context.h Fri Jul  6 11:03:14 2018
@@ -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

Added: llvm/trunk/tools/llvm-mca/HardwareUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/HardwareUnit.cpp?rev=336456&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/HardwareUnit.cpp (added)
+++ llvm/trunk/tools/llvm-mca/HardwareUnit.cpp Fri Jul  6 11:03:14 2018
@@ -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

Added: llvm/trunk/tools/llvm-mca/HardwareUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/HardwareUnit.h?rev=336456&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/HardwareUnit.h (added)
+++ llvm/trunk/tools/llvm-mca/HardwareUnit.h Fri Jul  6 11:03:14 2018
@@ -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

Modified: llvm/trunk/tools/llvm-mca/RegisterFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/RegisterFile.h?rev=336456&r1=336455&r2=336456&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/RegisterFile.h (original)
+++ llvm/trunk/tools/llvm-mca/RegisterFile.h Fri Jul  6 11:03:14 2018
@@ -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

Modified: llvm/trunk/tools/llvm-mca/RetireControlUnit.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/RetireControlUnit.h?rev=336456&r1=336455&r2=336456&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/RetireControlUnit.h (original)
+++ llvm/trunk/tools/llvm-mca/RetireControlUnit.h Fri Jul  6 11:03:14 2018
@@ -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.
   //

Modified: llvm/trunk/tools/llvm-mca/Scheduler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Scheduler.h?rev=336456&r1=336455&r2=336456&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Scheduler.h (original)
+++ llvm/trunk/tools/llvm-mca/Scheduler.h Fri Jul  6 11:03:14 2018
@@ -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.

Modified: llvm/trunk/tools/llvm-mca/llvm-mca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/llvm-mca.cpp?rev=336456&r1=336455&r2=336456&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/llvm-mca.cpp (original)
+++ llvm/trunk/tools/llvm-mca/llvm-mca.cpp Fri Jul  6 11:03:14 2018
@@ -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)




More information about the llvm-commits mailing list