diff --git a/include/llvm/MCA/Stages/InOrderIssueStage.h b/include/llvm/MCA/Stages/InOrderIssueStage.h index 01528ab148c..1c1f91e5176 100644 --- a/include/llvm/MCA/Stages/InOrderIssueStage.h +++ b/include/llvm/MCA/Stages/InOrderIssueStage.h @@ -11,20 +11,16 @@ /// //===----------------------------------------------------------------------===// -#ifndef LLVM_MCA_IN_ORDER_ISSUE_STAGE_H -#define LLVM_MCA_IN_ORDER_ISSUE_STAGE_H +#ifndef LLVM_MCA_STAGES_INORDERISSUESTAGE_H +#define LLVM_MCA_STAGES_INORDERISSUESTAGE_H -#include "llvm/ADT/SmallVector.h" +#include "llvm/MCA/HardwareUnits/ResourceManager.h" #include "llvm/MCA/SourceMgr.h" #include "llvm/MCA/Stages/Stage.h" namespace llvm { -struct MCSchedModel; -class MCSubtargetInfo; - namespace mca { class RegisterFile; -class ResourceManager; struct StallInfo { enum class StallKind { DEFAULT, REGISTER_DEPS, DISPATCH, DELAY }; @@ -35,41 +31,21 @@ struct StallInfo { StallInfo() : IR(), CyclesLeft(), Kind(StallKind::DEFAULT) {} - bool isValid() const { return (bool)IR; } - StallKind getStallKind() const { return Kind; } unsigned getCyclesLeft() const { return CyclesLeft; } const InstRef &getInstruction() const { return IR; } InstRef &getInstruction() { return IR; } - void clear() { - IR.invalidate(); - CyclesLeft = 0; - Kind = StallKind::DEFAULT; - } - - void update(const InstRef &Inst, unsigned Cycles, StallKind SK) { - IR = Inst; - CyclesLeft = Cycles; - Kind = SK; - } - - void cycleEnd() { - if (!isValid()) - return; - - if (!CyclesLeft) - return; - - --CyclesLeft; - } + bool isValid() const { return (bool)IR; } + void clear(); + void update(const InstRef &Inst, unsigned Cycles, StallKind SK); + void cycleEnd(); }; class InOrderIssueStage final : public Stage { - const MCSchedModel &SM; const MCSubtargetInfo &STI; RegisterFile &PRF; - std::unique_ptr RM; + ResourceManager RM; /// Instructions that were issued, but not executed yet. SmallVector IssuedInst; @@ -125,11 +101,9 @@ class InOrderIssueStage final : public Stage { void retireInstruction(InstRef &IR); public: - InOrderIssueStage(RegisterFile &PRF, const MCSchedModel &SM, - const MCSubtargetInfo &STI) - : SM(SM), STI(STI), PRF(PRF), RM(std::make_unique(SM)), - NumIssued(), SI(), CarryOver(), Bandwidth(), LastWriteBackCycle() {} + InOrderIssueStage(const MCSubtargetInfo &STI, RegisterFile &PRF); + unsigned getIssueWidth() const; bool isAvailable(const InstRef &) const override; bool hasWorkToComplete() const override; Error execute(InstRef &IR) override; @@ -140,4 +114,4 @@ public: } // namespace mca } // namespace llvm -#endif // LLVM_MCA_IN_ORDER_ISSUE_STAGE_H +#endif // LLVM_MCA_STAGES_INORDERISSUESTAGE_H diff --git a/lib/MCA/Context.cpp b/lib/MCA/Context.cpp index 8f5addbe671..4ef490747c8 100644 --- a/lib/MCA/Context.cpp +++ b/lib/MCA/Context.cpp @@ -73,15 +73,17 @@ Context::createInOrderPipeline(const PipelineOptions &Opts, SourceMgr &SrcMgr) { const MCSchedModel &SM = STI.getSchedModel(); auto PRF = std::make_unique(SM, MRI, Opts.RegisterFileSize); + // Create the pipeline stages. auto Entry = std::make_unique(SrcMgr); - auto InOrderIssue = std::make_unique(*PRF, SM, STI); - + auto InOrderIssue = std::make_unique(STI, *PRF); auto StagePipeline = std::make_unique(); - StagePipeline->appendStage(std::move(Entry)); - StagePipeline->appendStage(std::move(InOrderIssue)); + // Pass the ownership of all the hardware units to this Context. addHardwareUnit(std::move(PRF)); + // Build the pipeline. + StagePipeline->appendStage(std::move(Entry)); + StagePipeline->appendStage(std::move(InOrderIssue)); return StagePipeline; } diff --git a/lib/MCA/Stages/InOrderIssueStage.cpp b/lib/MCA/Stages/InOrderIssueStage.cpp index bf522a34d66..b24ddbee41b 100644 --- a/lib/MCA/Stages/InOrderIssueStage.cpp +++ b/lib/MCA/Stages/InOrderIssueStage.cpp @@ -13,7 +13,6 @@ #include "llvm/MCA/Stages/InOrderIssueStage.h" #include "llvm/MCA/HardwareUnits/RegisterFile.h" -#include "llvm/MCA/HardwareUnits/ResourceManager.h" #include "llvm/MCA/HardwareUnits/RetireControlUnit.h" #include "llvm/MCA/Instruction.h" @@ -21,6 +20,37 @@ namespace llvm { namespace mca { +void StallInfo::clear() { + IR.invalidate(); + CyclesLeft = 0; + Kind = StallKind::DEFAULT; +} + +void StallInfo::update(const InstRef &Inst, unsigned Cycles, StallKind SK) { + IR = Inst; + CyclesLeft = Cycles; + Kind = SK; +} + +void StallInfo::cycleEnd() { + if (!isValid()) + return; + + if (!CyclesLeft) + return; + + --CyclesLeft; +} + +InOrderIssueStage::InOrderIssueStage(const MCSubtargetInfo &STI, + RegisterFile &PRF) + : STI(STI), PRF(PRF), RM(STI.getSchedModel()), NumIssued(), SI(), + CarryOver(), Bandwidth(), LastWriteBackCycle() {} + +unsigned InOrderIssueStage::getIssueWidth() const { + return STI.getSchedModel().IssueWidth; +} + bool InOrderIssueStage::hasWorkToComplete() const { return !IssuedInst.empty() || SI.isValid() || CarriedOver; } @@ -33,7 +63,7 @@ bool InOrderIssueStage::isAvailable(const InstRef &IR) const { unsigned NumMicroOps = Inst.getNumMicroOps(); const InstrDesc &Desc = Inst.getDesc(); - bool ShouldCarryOver = NumMicroOps > SM.IssueWidth; + bool ShouldCarryOver = NumMicroOps > getIssueWidth(); if (Bandwidth < NumMicroOps && !ShouldCarryOver) return false; @@ -90,7 +120,7 @@ bool InOrderIssueStage::canExecute(const InstRef &IR) { return false; } - if (hasResourceHazard(*RM, IR)) { + if (hasResourceHazard(RM, IR)) { SI.update(IR, /* delay */ 1, StallInfo::StallKind::DISPATCH); return false; } @@ -184,13 +214,13 @@ llvm::Error InOrderIssueStage::tryIssue(InstRef &IR) { notifyInstructionDispatched(IR, NumMicroOps, UsedRegs); SmallVector UsedResources; - RM->issueInstruction(Desc, UsedResources); + RM.issueInstruction(Desc, UsedResources); IS.execute(SourceIndex); // Replace resource masks with valid resource processor IDs. for (ResourceUse &Use : UsedResources) { uint64_t Mask = Use.first.first; - Use.first.first = RM->resolveResourceMask(Mask); + Use.first.first = RM.resolveResourceMask(Mask); } notifyInstructionIssued(IR, UsedResources); @@ -308,13 +338,13 @@ void InOrderIssueStage::notifyStallEvent() { llvm::Error InOrderIssueStage::cycleStart() { NumIssued = 0; - Bandwidth = SM.IssueWidth; + Bandwidth = getIssueWidth(); PRF.cycleStart(); // Release consumed resources. SmallVector Freed; - RM->cycleEvent(Freed); + RM.cycleEvent(Freed); updateIssuedInst(); @@ -343,7 +373,7 @@ llvm::Error InOrderIssueStage::cycleStart() { } } - assert(NumIssued <= SM.IssueWidth && "Overflow."); + assert((NumIssued <= getIssueWidth()) && "Overflow."); return llvm::ErrorSuccess(); }