diff options
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r-- | llvm/tools/llvm-mca/include/Instruction.h | 23 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/include/SourceMgr.h | 20 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/include/Stages/FetchStage.h | 7 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/lib/Context.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/lib/Instruction.cpp | 2 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/lib/Stages/FetchStage.cpp | 19 | ||||
-rw-r--r-- | llvm/tools/llvm-mca/llvm-mca.cpp | 49 |
7 files changed, 63 insertions, 59 deletions
diff --git a/llvm/tools/llvm-mca/include/Instruction.h b/llvm/tools/llvm-mca/include/Instruction.h index 9d1c91ad441..bbb40c42576 100644 --- a/llvm/tools/llvm-mca/include/Instruction.h +++ b/llvm/tools/llvm-mca/include/Instruction.h @@ -88,7 +88,7 @@ class ReadState; /// register write. It also tracks how many cycles are left before the write /// back stage. class WriteState { - const WriteDescriptor &WD; + const WriteDescriptor *WD; // On instruction issue, this field is set equal to the write latency. // Before instruction issue, this field defaults to -512, a special // value that represents an "unknown" number of cycles. @@ -133,14 +133,17 @@ class WriteState { public: WriteState(const WriteDescriptor &Desc, unsigned RegID, bool clearsSuperRegs = false, bool writesZero = false) - : WD(Desc), CyclesLeft(UNKNOWN_CYCLES), RegisterID(RegID), + : WD(&Desc), CyclesLeft(UNKNOWN_CYCLES), RegisterID(RegID), ClearsSuperRegs(clearsSuperRegs), WritesZero(writesZero), IsEliminated(false), DependentWrite(nullptr), NumWriteUsers(0U) {} + WriteState(const WriteState &Other) = default; + WriteState &operator=(const WriteState &Other) = default; + int getCyclesLeft() const { return CyclesLeft; } - unsigned getWriteResourceID() const { return WD.SClassOrWriteResourceID; } + unsigned getWriteResourceID() const { return WD->SClassOrWriteResourceID; } unsigned getRegisterID() const { return RegisterID; } - unsigned getLatency() const { return WD.Latency; } + unsigned getLatency() const { return WD->Latency; } void addUser(ReadState *Use, int ReadAdvance); @@ -178,7 +181,7 @@ public: /// A read may be dependent on more than one write. This occurs when some /// writes only partially update the register associated to this read. class ReadState { - const ReadDescriptor &RD; + const ReadDescriptor *RD; // Physical register identified associated to this read. unsigned RegisterID; // Number of writes that contribute to the definition of RegisterID. @@ -202,16 +205,16 @@ class ReadState { public: ReadState(const ReadDescriptor &Desc, unsigned RegID) - : RD(Desc), RegisterID(RegID), DependentWrites(0), + : RD(&Desc), RegisterID(RegID), DependentWrites(0), CyclesLeft(UNKNOWN_CYCLES), TotalCycles(0), IsReady(true), IndependentFromDef(false) {} - const ReadDescriptor &getDescriptor() const { return RD; } - unsigned getSchedClass() const { return RD.SchedClassID; } + const ReadDescriptor &getDescriptor() const { return *RD; } + unsigned getSchedClass() const { return RD->SchedClassID; } unsigned getRegisterID() const { return RegisterID; } bool isReady() const { return IsReady; } - bool isImplicitRead() const { return RD.isImplicitRead(); } + bool isImplicitRead() const { return RD->isImplicitRead(); } bool isIndependentFromDef() const { return IndependentFromDef; } void setIndependentFromDef() { IndependentFromDef = true; } @@ -387,8 +390,6 @@ public: Instruction(const InstrDesc &D) : InstructionBase(D), Stage(IS_INVALID), CyclesLeft(UNKNOWN_CYCLES), RCUTokenID(0) {} - Instruction(const Instruction &Other) = delete; - Instruction &operator=(const Instruction &Other) = delete; unsigned getRCUTokenID() const { return RCUTokenID; } int getCyclesLeft() const { return CyclesLeft; } diff --git a/llvm/tools/llvm-mca/include/SourceMgr.h b/llvm/tools/llvm-mca/include/SourceMgr.h index 12713588246..54b1a2c31ce 100644 --- a/llvm/tools/llvm-mca/include/SourceMgr.h +++ b/llvm/tools/llvm-mca/include/SourceMgr.h @@ -17,35 +17,35 @@ #define LLVM_TOOLS_LLVM_MCA_SOURCEMGR_H #include "llvm/ADT/ArrayRef.h" -#include "llvm/MC/MCInst.h" -#include <vector> namespace mca { -typedef std::pair<unsigned, const llvm::MCInst &> SourceRef; +class Instruction; + +typedef std::pair<unsigned, const Instruction &> SourceRef; class SourceMgr { - llvm::ArrayRef<llvm::MCInst> Sequence; + using UniqueInst = std::unique_ptr<Instruction>; + llvm::ArrayRef<UniqueInst> Sequence; unsigned Current; const unsigned Iterations; static const unsigned DefaultIterations = 100; public: - SourceMgr(llvm::ArrayRef<llvm::MCInst> MCInstSequence, unsigned NumIterations) - : Sequence(MCInstSequence), Current(0), - Iterations(NumIterations ? NumIterations : DefaultIterations) {} + SourceMgr(llvm::ArrayRef<UniqueInst> S, unsigned Iter) + : Sequence(S), Current(0), Iterations(Iter ? Iter : DefaultIterations) {} unsigned getNumIterations() const { return Iterations; } unsigned size() const { return Sequence.size(); } bool hasNext() const { return Current < (Iterations * Sequence.size()); } void updateNext() { ++Current; } - const SourceRef peekNext() const { + SourceRef peekNext() const { assert(hasNext() && "Already at end of sequence!"); - return SourceRef(Current, Sequence[Current % Sequence.size()]); + return SourceRef(Current, *Sequence[Current % Sequence.size()]); } - using const_iterator = llvm::ArrayRef<llvm::MCInst>::const_iterator; + using const_iterator = llvm::ArrayRef<UniqueInst>::const_iterator; const_iterator begin() const { return Sequence.begin(); } const_iterator end() const { return Sequence.end(); } }; diff --git a/llvm/tools/llvm-mca/include/Stages/FetchStage.h b/llvm/tools/llvm-mca/include/Stages/FetchStage.h index 45e30e17b4d..a7aba2276d9 100644 --- a/llvm/tools/llvm-mca/include/Stages/FetchStage.h +++ b/llvm/tools/llvm-mca/include/Stages/FetchStage.h @@ -16,7 +16,6 @@ #ifndef LLVM_TOOLS_LLVM_MCA_FETCH_STAGE_H #define LLVM_TOOLS_LLVM_MCA_FETCH_STAGE_H -#include "InstrBuilder.h" #include "SourceMgr.h" #include "Stages/Stage.h" #include <map> @@ -27,18 +26,16 @@ class FetchStage final : public Stage { InstRef CurrentInstruction; using InstMap = std::map<unsigned, std::unique_ptr<Instruction>>; InstMap Instructions; - InstrBuilder &IB; SourceMgr &SM; // Updates the program counter, and sets 'CurrentInstruction'. - llvm::Error getNextInstruction(); + void getNextInstruction(); FetchStage(const FetchStage &Other) = delete; FetchStage &operator=(const FetchStage &Other) = delete; public: - FetchStage(InstrBuilder &IB, SourceMgr &SM) - : CurrentInstruction(), IB(IB), SM(SM) {} + FetchStage(SourceMgr &SM) : CurrentInstruction(), SM(SM) {} bool isAvailable(const InstRef &IR) const override; bool hasWorkToComplete() const override; diff --git a/llvm/tools/llvm-mca/lib/Context.cpp b/llvm/tools/llvm-mca/lib/Context.cpp index c84ea73c4d2..4e30fc9de31 100644 --- a/llvm/tools/llvm-mca/lib/Context.cpp +++ b/llvm/tools/llvm-mca/lib/Context.cpp @@ -41,7 +41,7 @@ Context::createDefaultPipeline(const PipelineOptions &Opts, InstrBuilder &IB, auto HWS = llvm::make_unique<Scheduler>(SM, LSU.get()); // Create the pipeline stages. - auto Fetch = llvm::make_unique<FetchStage>(IB, SrcMgr); + auto Fetch = llvm::make_unique<FetchStage>(SrcMgr); auto Dispatch = llvm::make_unique<DispatchStage>(STI, MRI, Opts.DispatchWidth, *RCU, *PRF); auto Execute = llvm::make_unique<ExecuteStage>(*HWS); diff --git a/llvm/tools/llvm-mca/lib/Instruction.cpp b/llvm/tools/llvm-mca/lib/Instruction.cpp index 12b6e185ced..42f5cd38ee9 100644 --- a/llvm/tools/llvm-mca/lib/Instruction.cpp +++ b/llvm/tools/llvm-mca/lib/Instruction.cpp @@ -93,7 +93,7 @@ void ReadState::cycleEvent() { #ifndef NDEBUG void WriteState::dump() const { - dbgs() << "{ OpIdx=" << WD.OpIndex << ", Lat=" << getLatency() << ", RegID " + dbgs() << "{ OpIdx=" << WD->OpIndex << ", Lat=" << getLatency() << ", RegID " << getRegisterID() << ", Cycles Left=" << getCyclesLeft() << " }"; } diff --git a/llvm/tools/llvm-mca/lib/Stages/FetchStage.cpp b/llvm/tools/llvm-mca/lib/Stages/FetchStage.cpp index 515dc15c5b3..85d06d2d183 100644 --- a/llvm/tools/llvm-mca/lib/Stages/FetchStage.cpp +++ b/llvm/tools/llvm-mca/lib/Stages/FetchStage.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "Stages/FetchStage.h" +#include "Instruction.h" namespace mca { @@ -25,20 +26,15 @@ bool FetchStage::isAvailable(const InstRef & /* unused */) const { return false; } -llvm::Error FetchStage::getNextInstruction() { +void FetchStage::getNextInstruction() { assert(!CurrentInstruction && "There is already an instruction to process!"); if (!SM.hasNext()) - return llvm::ErrorSuccess(); - const SourceRef SR = SM.peekNext(); - llvm::Expected<std::unique_ptr<Instruction>> InstOrErr = - IB.createInstruction(SR.second); - if (!InstOrErr) - return InstOrErr.takeError(); - std::unique_ptr<Instruction> Inst = std::move(InstOrErr.get()); + return; + SourceRef SR = SM.peekNext(); + std::unique_ptr<Instruction> Inst = llvm::make_unique<Instruction>(SR.second); CurrentInstruction = InstRef(SR.first, Inst.get()); Instructions[SR.first] = std::move(Inst); SM.updateNext(); - return llvm::ErrorSuccess(); } llvm::Error FetchStage::execute(InstRef & /*unused */) { @@ -48,12 +44,13 @@ llvm::Error FetchStage::execute(InstRef & /*unused */) { // Move the program counter. CurrentInstruction.invalidate(); - return getNextInstruction(); + getNextInstruction(); + return llvm::ErrorSuccess(); } llvm::Error FetchStage::cycleStart() { if (!CurrentInstruction) - return getNextInstruction(); + getNextInstruction(); return llvm::ErrorSuccess(); } diff --git a/llvm/tools/llvm-mca/llvm-mca.cpp b/llvm/tools/llvm-mca/llvm-mca.cpp index b89e4bd9551..8f4e0717bd2 100644 --- a/llvm/tools/llvm-mca/llvm-mca.cpp +++ b/llvm/tools/llvm-mca/llvm-mca.cpp @@ -328,26 +328,12 @@ static void processViewOptions() { } // Returns true on success. -static bool runPipeline(mca::Pipeline &P, MCInstPrinter &MCIP, - const MCSubtargetInfo &STI) { +static bool runPipeline(mca::Pipeline &P) { // Handle pipeline errors here. if (auto Err = P.run()) { - if (auto NewE = handleErrors( - std::move(Err), - [&MCIP, &STI](const mca::InstructionError<MCInst> &IE) { - std::string InstructionStr; - raw_string_ostream SS(InstructionStr); - WithColor::error() << IE.Message << '\n'; - MCIP.printInst(&IE.Inst, SS, "", STI); - SS.flush(); - WithColor::note() << "instruction: " << InstructionStr << '\n'; - })) { - // Default case. - WithColor::error() << toString(std::move(NewE)); - } + WithColor::error() << toString(std::move(Err)); return false; } - return true; } @@ -513,14 +499,37 @@ int main(int argc, char **argv) { TOF->os() << "\n\n"; } + // Lower the MCInst sequence into an mca::Instruction sequence. ArrayRef<MCInst> Insts = Region->getInstructions(); - mca::SourceMgr S(Region->getInstructions(), + std::vector<std::unique_ptr<mca::Instruction>> LoweredSequence; + for (const MCInst &MCI : Insts) { + llvm::Expected<std::unique_ptr<mca::Instruction>> Inst = IB.createInstruction(MCI); + if (!Inst) { + if (auto NewE = handleErrors(Inst.takeError(), + [&IP, &STI](const mca::InstructionError<MCInst> &IE) { + std::string InstructionStr; + raw_string_ostream SS(InstructionStr); + WithColor::error() << IE.Message << '\n'; + IP->printInst(&IE.Inst, SS, "", *STI); + SS.flush(); + WithColor::note() << "instruction: " << InstructionStr << '\n'; + })) { + // Default case. + WithColor::error() << toString(std::move(NewE)); + } + return 1; + } + + LoweredSequence.emplace_back(std::move(Inst.get())); + } + + mca::SourceMgr S(LoweredSequence, PrintInstructionTables ? 1 : Iterations); if (PrintInstructionTables) { // Create a pipeline, stages, and a printer. auto P = llvm::make_unique<mca::Pipeline>(); - P->appendStage(llvm::make_unique<mca::FetchStage>(IB, S)); + P->appendStage(llvm::make_unique<mca::FetchStage>(S)); P->appendStage(llvm::make_unique<mca::InstructionTables>(SM)); mca::PipelinePrinter Printer(*P); @@ -532,7 +541,7 @@ int main(int argc, char **argv) { Printer.addView( llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, Insts)); - if (!runPipeline(*P, *IP, *STI)) + if (!runPipeline(*P)) return 1; Printer.printReport(TOF->os()); @@ -574,7 +583,7 @@ int main(int argc, char **argv) { TimelineMaxCycles)); } - if (!runPipeline(*P, *IP, *STI)) + if (!runPipeline(*P)) return 1; Printer.printReport(TOF->os()); |