Index: llvm/trunk/tools/llvm-mca/CMakeLists.txt =================================================================== --- llvm/trunk/tools/llvm-mca/CMakeLists.txt +++ llvm/trunk/tools/llvm-mca/CMakeLists.txt @@ -11,11 +11,13 @@ 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 Index: llvm/trunk/tools/llvm-mca/Context.h =================================================================== --- llvm/trunk/tools/llvm-mca/Context.h +++ llvm/trunk/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 + +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, 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 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 createDefaultPipeline(const PipelineOptions &Opts, + InstrBuilder &IB, + SourceMgr &SrcMgr); +}; + +} // namespace mca +#endif // LLVM_TOOLS_LLVM_MCA_CONTEXT_H Index: llvm/trunk/tools/llvm-mca/Context.cpp =================================================================== --- llvm/trunk/tools/llvm-mca/Context.cpp +++ llvm/trunk/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 +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(SM); + auto PRF = llvm::make_unique(SM, MRI, Opts.RegisterFileSize); + auto HWS = llvm::make_unique( + SM, Opts.LoadQueueSize, Opts.StoreQueueSize, Opts.AssumeNoAlias); + + // Create the pipeline and its stages. + auto P = llvm::make_unique( + Opts.DispatchWidth, Opts.RegisterFileSize, Opts.LoadQueueSize, + Opts.StoreQueueSize, Opts.AssumeNoAlias); + auto F = llvm::make_unique(IB, SrcMgr); + auto D = llvm::make_unique( + STI, MRI, Opts.RegisterFileSize, Opts.DispatchWidth, *RCU, *PRF, *HWS); + auto R = llvm::make_unique(*RCU, *PRF); + auto E = llvm::make_unique(*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 Index: llvm/trunk/tools/llvm-mca/HardwareUnit.h =================================================================== --- llvm/trunk/tools/llvm-mca/HardwareUnit.h +++ llvm/trunk/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 Index: llvm/trunk/tools/llvm-mca/HardwareUnit.cpp =================================================================== --- llvm/trunk/tools/llvm-mca/HardwareUnit.cpp +++ llvm/trunk/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 Index: llvm/trunk/tools/llvm-mca/RegisterFile.h =================================================================== --- llvm/trunk/tools/llvm-mca/RegisterFile.h +++ llvm/trunk/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 @@ /// 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 Index: llvm/trunk/tools/llvm-mca/RetireControlUnit.h =================================================================== --- llvm/trunk/tools/llvm-mca/RetireControlUnit.h +++ llvm/trunk/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 @@ -32,7 +33,7 @@ /// 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. // Index: llvm/trunk/tools/llvm-mca/Scheduler.h =================================================================== --- llvm/trunk/tools/llvm-mca/Scheduler.h +++ llvm/trunk/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 @@ /// 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. Index: llvm/trunk/tools/llvm-mca/llvm-mca.cpp =================================================================== --- llvm/trunk/tools/llvm-mca/llvm-mca.cpp +++ llvm/trunk/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 &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( - Width, RegisterFileSize, LoadQueueSize, StoreQueueSize, AssumeNoAlias); - P->appendStage(llvm::make_unique(IB, S)); - P->appendStage(llvm::make_unique( - *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS)); - P->appendStage(llvm::make_unique(RCU, PRF)); - P->appendStage(llvm::make_unique(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)