forked from OSchip/llvm-project
parent
843a3caa71
commit
3562248825
|
@ -60,8 +60,8 @@ public:
|
|||
class HWInstructionIssuedEvent : public HWInstructionEvent {
|
||||
public:
|
||||
using ResourceRef = std::pair<uint64_t, uint64_t>;
|
||||
HWInstructionIssuedEvent(
|
||||
unsigned Index, llvm::ArrayRef<std::pair<ResourceRef, unsigned>> UR)
|
||||
HWInstructionIssuedEvent(unsigned Index,
|
||||
llvm::ArrayRef<std::pair<ResourceRef, unsigned>> UR)
|
||||
: HWInstructionEvent(HWInstructionEvent::Issued, Index),
|
||||
UsedResources(UR) {}
|
||||
|
||||
|
@ -134,7 +134,6 @@ public:
|
|||
private:
|
||||
virtual void anchor();
|
||||
};
|
||||
|
||||
} // namespace mca
|
||||
|
||||
#endif
|
||||
|
|
|
@ -409,10 +409,9 @@ void InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
|
|||
}
|
||||
|
||||
const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI) {
|
||||
auto it = Descriptors.find(MCI.getOpcode());
|
||||
if (it == Descriptors.end())
|
||||
if (Descriptors.find_as(MCI.getOpcode()) == Descriptors.end())
|
||||
createInstrDescImpl(MCI);
|
||||
return *Descriptors[MCI.getOpcode()].get();
|
||||
return *Descriptors[MCI.getOpcode()];
|
||||
}
|
||||
|
||||
std::unique_ptr<Instruction>
|
||||
|
@ -448,12 +447,11 @@ InstrBuilder::createInstruction(unsigned Idx, const MCInst &MCI) {
|
|||
for (const WriteDescriptor &WD : D.Writes) {
|
||||
unsigned RegID =
|
||||
WD.OpIndex == -1 ? WD.RegisterID : MCI.getOperand(WD.OpIndex).getReg();
|
||||
assert((RegID || WD.IsOptionalDef) && "Expected a valid register ID!");
|
||||
// Special case where this is a optional definition, and the actual register
|
||||
// is 0.
|
||||
// Check if this is a optional definition that references NoReg.
|
||||
if (WD.IsOptionalDef && !RegID)
|
||||
continue;
|
||||
|
||||
assert(RegID && "Expected a valid register ID!");
|
||||
NewIS->getDefs().emplace_back(llvm::make_unique<WriteState>(WD, RegID));
|
||||
}
|
||||
|
||||
|
|
|
@ -92,17 +92,13 @@ void WriteState::dump() const {
|
|||
}
|
||||
#endif
|
||||
|
||||
bool Instruction::isReady() {
|
||||
if (Stage == IS_READY)
|
||||
return true;
|
||||
void Instruction::dispatch() {
|
||||
assert(Stage == IS_INVALID);
|
||||
Stage = IS_AVAILABLE;
|
||||
|
||||
assert(Stage == IS_AVAILABLE);
|
||||
for (const UniqueUse &Use : Uses)
|
||||
if (!Use.get()->isReady())
|
||||
return false;
|
||||
|
||||
setReady();
|
||||
return true;
|
||||
if (std::all_of(Uses.begin(), Uses.end(),
|
||||
[](const UniqueUse &Use) { return Use->isReady(); }))
|
||||
Stage = IS_READY;
|
||||
}
|
||||
|
||||
void Instruction::execute() {
|
||||
|
@ -110,6 +106,8 @@ void Instruction::execute() {
|
|||
Stage = IS_EXECUTING;
|
||||
for (UniqueDef &Def : Defs)
|
||||
Def->onInstructionIssued();
|
||||
if (!CyclesLeft)
|
||||
Stage = IS_EXECUTED;
|
||||
}
|
||||
|
||||
bool Instruction::isZeroLatency() const {
|
||||
|
@ -117,18 +115,27 @@ bool Instruction::isZeroLatency() const {
|
|||
}
|
||||
|
||||
void Instruction::cycleEvent() {
|
||||
if (isReady())
|
||||
return;
|
||||
|
||||
if (isDispatched()) {
|
||||
for (UniqueUse &Use : Uses)
|
||||
bool IsReady = true;
|
||||
for (UniqueUse &Use : Uses) {
|
||||
Use->cycleEvent();
|
||||
IsReady &= Use->isReady();
|
||||
}
|
||||
|
||||
if (IsReady)
|
||||
Stage = IS_READY;
|
||||
return;
|
||||
}
|
||||
if (isExecuting()) {
|
||||
for (UniqueDef &Def : Defs)
|
||||
Def->cycleEvent();
|
||||
CyclesLeft--;
|
||||
}
|
||||
|
||||
assert(isExecuting() && "Instruction not in-flight?");
|
||||
assert(CyclesLeft && "Instruction already executed?");
|
||||
for (UniqueDef &Def : Defs)
|
||||
Def->cycleEvent();
|
||||
CyclesLeft--;
|
||||
if (!CyclesLeft)
|
||||
Stage = IS_EXECUTED;
|
||||
}
|
||||
|
||||
} // namespace mca
|
||||
|
|
|
@ -276,12 +276,6 @@ class Instruction {
|
|||
// One entry per each implicit and explicit register use.
|
||||
VecUses Uses;
|
||||
|
||||
// This instruction has already been dispatched, and all operands are ready.
|
||||
void setReady() {
|
||||
assert(Stage == IS_AVAILABLE);
|
||||
Stage = IS_READY;
|
||||
}
|
||||
|
||||
public:
|
||||
Instruction(const InstrDesc &D)
|
||||
: Desc(D), Stage(IS_INVALID), CyclesLeft(-1) {}
|
||||
|
@ -301,10 +295,7 @@ public:
|
|||
|
||||
// Transition to the dispatch stage.
|
||||
// No definition is updated because the instruction is not "executing".
|
||||
void dispatch() {
|
||||
assert(Stage == IS_INVALID);
|
||||
Stage = IS_AVAILABLE;
|
||||
}
|
||||
void dispatch();
|
||||
|
||||
// Instruction issued. Transition to the IS_EXECUTING state, and update
|
||||
// all the definitions.
|
||||
|
@ -316,17 +307,14 @@ public:
|
|||
Stage = IS_EXECUTED;
|
||||
}
|
||||
|
||||
// Checks if operands are available. If all operands area ready,
|
||||
// then this forces a transition from IS_AVAILABLE to IS_READY.
|
||||
bool isReady();
|
||||
|
||||
bool isDispatched() const { return Stage == IS_AVAILABLE; }
|
||||
bool isReady() const { return Stage == IS_READY; }
|
||||
bool isExecuting() const { return Stage == IS_EXECUTING; }
|
||||
bool isExecuted() const { return Stage == IS_EXECUTED; }
|
||||
bool isZeroLatency() const;
|
||||
|
||||
void retire() {
|
||||
assert(Stage == IS_EXECUTED);
|
||||
assert(isExecuted() && "Instruction is in an invalid state!");
|
||||
Stage = IS_RETIRED;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ void ResourcePressureView::initialize() {
|
|||
if (ProcResource.SubUnitsIdxBegin || !NumUnits)
|
||||
continue;
|
||||
|
||||
Resource2VecIndex.insert(std::pair<uint64_t, unsigned>(I, R2VIndex));
|
||||
Resource2VecIndex.insert(std::pair<unsigned, unsigned>(I, R2VIndex));
|
||||
R2VIndex += ProcResource.NumUnits;
|
||||
}
|
||||
|
||||
|
@ -70,16 +70,14 @@ static void printColumnNames(raw_string_ostream &OS, const MCSchedModel &SM) {
|
|||
OS << " ";
|
||||
else
|
||||
OS << " ";
|
||||
ResourceIndex++;
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned J = 0; J < NumUnits; ++J) {
|
||||
OS << "[" << ResourceIndex << '.' << J << ']';
|
||||
if (ResourceIndex < 10)
|
||||
OS << " ";
|
||||
else
|
||||
OS << ' ';
|
||||
} else {
|
||||
for (unsigned J = 0; J < NumUnits; ++J) {
|
||||
OS << "[" << ResourceIndex << '.' << J << ']';
|
||||
if (ResourceIndex < 10)
|
||||
OS << " ";
|
||||
else
|
||||
OS << ' ';
|
||||
}
|
||||
}
|
||||
ResourceIndex++;
|
||||
}
|
||||
|
@ -114,8 +112,8 @@ void ResourcePressureView::printResourcePressurePerIteration(
|
|||
printColumnNames(TempStream, SM);
|
||||
TempStream << '\n';
|
||||
|
||||
for (unsigned I = 0; I < NumResourceUnits; ++I) {
|
||||
unsigned Usage = ResourceUsage[I + Source.size() * NumResourceUnits];
|
||||
for (unsigned I = 0, E = NumResourceUnits; I < E; ++I) {
|
||||
unsigned Usage = ResourceUsage[I + Source.size() * E];
|
||||
if (!Usage) {
|
||||
TempStream << " - ";
|
||||
continue;
|
||||
|
|
|
@ -60,6 +60,7 @@
|
|||
|
||||
#include "SourceMgr.h"
|
||||
#include "View.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include <map>
|
||||
|
@ -75,8 +76,9 @@ class ResourcePressureView : public View {
|
|||
llvm::MCInstPrinter &MCIP;
|
||||
const SourceMgr &Source;
|
||||
|
||||
// Map to quickly get a resource descriptor from a mask.
|
||||
std::map<uint64_t, unsigned> Resource2VecIndex;
|
||||
// Map to quickly obtain the ResourceUsage column index from a processor
|
||||
// resource ID.
|
||||
llvm::DenseMap<unsigned, unsigned> Resource2VecIndex;
|
||||
|
||||
// Table of resources used by instructions.
|
||||
std::vector<unsigned> ResourceUsage;
|
||||
|
@ -90,9 +92,9 @@ class ResourcePressureView : public View {
|
|||
void initialize();
|
||||
|
||||
public:
|
||||
ResourcePressureView(const llvm::MCSubtargetInfo &ST,
|
||||
ResourcePressureView(const llvm::MCSubtargetInfo &sti,
|
||||
llvm::MCInstPrinter &Printer, const SourceMgr &SM)
|
||||
: STI(ST), MCIP(Printer), Source(SM) {
|
||||
: STI(sti), MCIP(Printer), Source(SM) {
|
||||
initialize();
|
||||
}
|
||||
|
||||
|
|
|
@ -352,14 +352,16 @@ void Scheduler::issueInstruction(Instruction &IS, unsigned InstrIndex) {
|
|||
// This updates the internal state of each write.
|
||||
IS.execute();
|
||||
|
||||
notifyInstructionIssued(InstrIndex, UsedResources);
|
||||
if (D.MaxLatency) {
|
||||
assert(IS.isExecuting() && "A zero latency instruction?");
|
||||
IssuedQueue[InstrIndex] = &IS;
|
||||
notifyInstructionIssued(InstrIndex, UsedResources);
|
||||
} else {
|
||||
// A zero latency instruction which reads and/or updates registers.
|
||||
notifyInstructionIssued(InstrIndex, UsedResources);
|
||||
notifyInstructionExecuted(InstrIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
// A zero latency instruction which reads and/or updates registers.
|
||||
assert(IS.isExecuted() && "Instruction still executing!");
|
||||
notifyInstructionExecuted(InstrIndex);
|
||||
}
|
||||
|
||||
void Scheduler::issue() {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
//===--------------------- Support.cpp ----------------------------*- C++
|
||||
//-*-===//
|
||||
//===--------------------- Support.cpp --------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--------------------- TimelineView.cpp ---------------*- C++ -*-===//
|
||||
//===--------------------- TimelineView.cpp ---------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--------------------- TimelineView.h ---------------*- C++ -*-===//
|
||||
//===--------------------- TimelineView.h -----------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -150,6 +150,8 @@ class TimelineView : public View {
|
|||
|
||||
const unsigned DEFAULT_ITERATIONS = 10;
|
||||
|
||||
void initialize(unsigned MaxIterations);
|
||||
|
||||
public:
|
||||
TimelineView(const llvm::MCSubtargetInfo &sti, llvm::MCInstPrinter &Printer,
|
||||
const SourceMgr &Sequence, unsigned MaxIterations,
|
||||
|
@ -159,8 +161,6 @@ public:
|
|||
initialize(MaxIterations);
|
||||
}
|
||||
|
||||
void initialize(unsigned MaxIterations);
|
||||
|
||||
// Event handlers.
|
||||
void onCycleBegin(unsigned Cycle) override { CurrentCycle = Cycle; }
|
||||
void onInstructionEvent(const HWInstructionEvent &Event) override;
|
||||
|
|
|
@ -198,7 +198,6 @@ public:
|
|||
|
||||
const InstVec &GetInstructionSequence() const { return Insts; }
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
|
@ -324,25 +323,17 @@ int main(int argc, char **argv) {
|
|||
std::unique_ptr<mca::BackendPrinter> Printer =
|
||||
llvm::make_unique<mca::BackendPrinter>(*B);
|
||||
|
||||
std::unique_ptr<mca::SummaryView> SV =
|
||||
llvm::make_unique<mca::SummaryView>(*STI, *MCII, *S, *IP, Width);
|
||||
Printer->addView(std::move(SV));
|
||||
Printer->addView(
|
||||
llvm::make_unique<mca::SummaryView>(*STI, *MCII, *S, *IP, Width));
|
||||
|
||||
if (PrintModeVerbose) {
|
||||
std::unique_ptr<mca::BackendStatistics> BS =
|
||||
llvm::make_unique<mca::BackendStatistics>(*STI);
|
||||
Printer->addView(std::move(BS));
|
||||
}
|
||||
if (PrintModeVerbose)
|
||||
Printer->addView(llvm::make_unique<mca::BackendStatistics>(*STI));
|
||||
|
||||
std::unique_ptr<mca::ResourcePressureView> RPV =
|
||||
llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S);
|
||||
Printer->addView(std::move(RPV));
|
||||
Printer->addView(llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S));
|
||||
|
||||
if (PrintTimelineView) {
|
||||
std::unique_ptr<mca::TimelineView> TV =
|
||||
llvm::make_unique<mca::TimelineView>(
|
||||
*STI, *IP, *S, TimelineMaxIterations, TimelineMaxCycles);
|
||||
Printer->addView(std::move(TV));
|
||||
Printer->addView(llvm::make_unique<mca::TimelineView>(
|
||||
*STI, *IP, *S, TimelineMaxIterations, TimelineMaxCycles));
|
||||
}
|
||||
|
||||
B->run();
|
||||
|
|
Loading…
Reference in New Issue