summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r--llvm/tools/llvm-mca/include/Instruction.h23
-rw-r--r--llvm/tools/llvm-mca/include/SourceMgr.h20
-rw-r--r--llvm/tools/llvm-mca/include/Stages/FetchStage.h7
-rw-r--r--llvm/tools/llvm-mca/lib/Context.cpp2
-rw-r--r--llvm/tools/llvm-mca/lib/Instruction.cpp2
-rw-r--r--llvm/tools/llvm-mca/lib/Stages/FetchStage.cpp19
-rw-r--r--llvm/tools/llvm-mca/llvm-mca.cpp49
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());
OpenPOWER on IntegriCloud