Index: tools/llvm-mca/Backend.h =================================================================== --- tools/llvm-mca/Backend.h +++ tools/llvm-mca/Backend.h @@ -19,6 +19,7 @@ #include "FetchStage.h" #include "InstrBuilder.h" #include "Scheduler.h" +#include "llvm/ADT/SmallVector.h" namespace mca { @@ -53,10 +54,8 @@ class Backend { const llvm::MCSubtargetInfo &STI; - /// This is the initial stage of the pipeline. - /// TODO: Eventually this will become a list of unique Stage* that this - /// backend pipeline executes. - std::unique_ptr Fetch; + /// This container represents the stages of an instruction pipeline. + llvm::SmallVector, 2> Stages; std::unique_ptr HWS; std::unique_ptr DU; @@ -71,7 +70,7 @@ std::unique_ptr InitialStage, unsigned DispatchWidth = 0, unsigned RegisterFileSize = 0, unsigned LoadQueueSize = 0, unsigned StoreQueueSize = 0, bool AssumeNoAlias = false) - : STI(Subtarget), Fetch(std::move(InitialStage)), + : STI(Subtarget), HWS(llvm::make_unique(this, Subtarget.getSchedModel(), LoadQueueSize, StoreQueueSize, AssumeNoAlias)), @@ -79,11 +78,16 @@ RegisterFileSize, DispatchWidth, HWS.get())), Cycles(0) { + appendStage(std::move(InitialStage)); HWS->setDispatchUnit(DU.get()); } + // Append a stage to the pipeline. + void appendStage(std::unique_ptr S) { Stages.push_back(std::move(S)); } + void run(); void addEventListener(HWEventListener *Listener); + Stage &getInitialStage(); void notifyCycleBegin(unsigned Cycle); void notifyInstructionEvent(const HWInstructionEvent &Event); void notifyStallEvent(const HWStallEvent &Event); Index: tools/llvm-mca/Backend.cpp =================================================================== --- tools/llvm-mca/Backend.cpp +++ tools/llvm-mca/Backend.cpp @@ -30,20 +30,27 @@ } void Backend::run() { - while (Fetch->isReady() || !DU->isRCUEmpty()) + while (getInitialStage().isReady() || !DU->isRCUEmpty()) runCycle(Cycles++); } +Stage &Backend::getInitialStage() { + assert(Stages.size() > 0 && "No initial pipeline stage registered."); + assert(Stages[0] && "Invalid initial pipeline stage."); + return *Stages[0]; +} + void Backend::runCycle(unsigned Cycle) { notifyCycleBegin(Cycle); InstRef IR; - while (Fetch->execute(IR)) { + Stage &Fetch = getInitialStage(); + while (Fetch.execute(IR)) { const InstrDesc &Desc = IR.getInstruction()->getDesc(); if (!DU->isAvailable(Desc.NumMicroOps) || !DU->canDispatch(IR)) break; DU->dispatch(IR, STI); - Fetch->postExecute(IR); + Fetch.postExecute(IR); } notifyCycleEnd(Cycle);