[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

llvm-svn: 336456
diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp
index 6bea827..9398a54 100644
--- a/llvm/tools/llvm-mca/llvm-mca.cpp
+++ b/llvm/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 @@
   // 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 @@
       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)