-
Notifications
You must be signed in to change notification settings - Fork 14.8k
[MCA] Enable customization of individual instructions #155420
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 32 commits
b1a67b7
4abee0f
1298dd3
b5c3b95
302b994
2338978
0be9fbf
f1ad060
757fec3
452bb40
4d655f8
ef2a0f0
77eefdb
d44bfbe
bd8cedf
6e0d12b
08cc266
1282e70
71403fb
b805a3c
801b0da
ed4e0bd
042b3ba
5fb0db7
e124416
74482dd
37d0734
5824130
5029c24
7c40f7b
9e276b6
129b7e4
e28c48c
7e90de7
4065142
f8113c4
6043f89
0d00426
7bf43cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -134,6 +134,27 @@ class Instrument { | |
StringRef getData() const { return Data; } | ||
}; | ||
|
||
class LatencyInstrument : public Instrument { | ||
std::optional<unsigned> Latency; | ||
|
||
public: | ||
static const llvm::StringRef DESC_NAME; | ||
|
||
LatencyInstrument(StringRef Data) : Instrument(DESC_NAME, Data) { | ||
// Skip spaces and tabs. | ||
unsigned Position = Data.find_first_not_of(" \t"); | ||
if (Position >= Data.size()) | ||
// We reached the end of the comment. Bail out. | ||
return; | ||
Data = Data.drop_front(Position); | ||
|
||
unsigned L = 0; | ||
if (!Data.getAsInteger(10, L)) | ||
Latency = L; | ||
} | ||
|
||
bool hasValue() const { return bool(Latency); } | ||
unsigned getLatency() { return *Latency; } | ||
|
||
}; | ||
|
||
using UniqueInstrument = std::unique_ptr<Instrument>; | ||
|
||
/// This class allows targets to optionally customize the logic that resolves | ||
|
@@ -143,19 +164,21 @@ class LLVM_ABI InstrumentManager { | |
protected: | ||
const MCSubtargetInfo &STI; | ||
const MCInstrInfo &MCII; | ||
bool EnableInstruments; | ||
mshockwave marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
public: | ||
InstrumentManager(const MCSubtargetInfo &STI, const MCInstrInfo &MCII) | ||
: STI(STI), MCII(MCII) {} | ||
InstrumentManager(const MCSubtargetInfo &STI, const MCInstrInfo &MCII, | ||
bool EnableInstruments = true) | ||
: STI(STI), MCII(MCII), EnableInstruments(EnableInstruments) {}; | ||
|
||
virtual ~InstrumentManager() = default; | ||
|
||
/// Returns true if llvm-mca should ignore instruments. | ||
virtual bool shouldIgnoreInstruments() const { return true; } | ||
virtual bool shouldIgnoreInstruments() const { return !EnableInstruments; } | ||
|
||
// Returns true if this supports processing Instrument with | ||
// Instrument.Desc equal to Type | ||
virtual bool supportsInstrumentType(StringRef Type) const { return false; } | ||
virtual bool supportsInstrumentType(StringRef Type) const; | ||
|
||
/// Allocate an Instrument, and return a unique pointer to it. This function | ||
/// may be useful to create instruments coming from comments in the assembly. | ||
|
@@ -175,6 +198,13 @@ class LLVM_ABI InstrumentManager { | |
/// it returns the SchedClassID that belongs to MCI. | ||
virtual unsigned getSchedClassID(const MCInstrInfo &MCII, const MCInst &MCI, | ||
const SmallVector<Instrument *> &IVec) const; | ||
|
||
// Return true if instruments can modify instruction description | ||
virtual bool canCustomize(const SmallVector<Instrument *> &IVec) const; | ||
|
||
|
||
// Customize instruction description | ||
virtual void customize(const SmallVector<Instrument *> &IVec, | ||
|
||
llvm::mca::InstrDesc &Desc) const; | ||
}; | ||
|
||
} // namespace mca | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,6 +12,7 @@ | |
//===----------------------------------------------------------------------===// | ||
|
||
#include "llvm/MCA/CustomBehaviour.h" | ||
#include "llvm/MCA/Instruction.h" | ||
|
||
namespace llvm { | ||
namespace mca { | ||
|
@@ -42,8 +43,45 @@ CustomBehaviour::getEndViews(llvm::MCInstPrinter &IP, | |
return std::vector<std::unique_ptr<View>>(); | ||
} | ||
|
||
const llvm::StringRef LatencyInstrument::DESC_NAME = "LATENCY"; | ||
|
||
bool InstrumentManager::supportsInstrumentType(StringRef Type) const { | ||
return EnableInstruments && Type == LatencyInstrument::DESC_NAME; | ||
mshockwave marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
bool InstrumentManager::canCustomize( | ||
const llvm::SmallVector<Instrument *> &IVec) const { | ||
for (const auto I : IVec) { | ||
if (I->getDesc() == LatencyInstrument::DESC_NAME) { | ||
auto LatInst = static_cast<LatencyInstrument *>(I); | ||
return LatInst->hasValue(); | ||
} | ||
} | ||
return false; | ||
} | ||
|
||
void InstrumentManager::customize(const llvm::SmallVector<Instrument *> &IVec, | ||
InstrDesc &ID) const { | ||
for (const auto I : IVec) { | ||
if (I->getDesc() == LatencyInstrument::DESC_NAME) { | ||
auto LatInst = static_cast<LatencyInstrument *>(I); | ||
if (LatInst->hasValue()) { | ||
auto Latency = LatInst->getLatency(); | ||
|
||
// TODO Allow to customize a subset of ID.Writes | ||
for (auto &W : ID.Writes) | ||
W.Latency = Latency; | ||
ID.MaxLatency = Latency; | ||
} | ||
} | ||
} | ||
} | ||
|
||
UniqueInstrument InstrumentManager::createInstrument(llvm::StringRef Desc, | ||
llvm::StringRef Data) { | ||
if (EnableInstruments) { | ||
if (Desc == LatencyInstrument::DESC_NAME) | ||
return std::make_unique<LatencyInstrument>(Data); | ||
} | ||
return std::make_unique<Instrument>(Desc, Data); | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py | ||
# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=10 %s 2>&1 | FileCheck %s | ||
|
||
# LLVM-MCA-LATENCY 100 | ||
add (%eax), %eax | ||
# LLVM-MCA-LATENCY | ||
mov %eax, (%ebx) | ||
|
||
# CHECK: Iterations: 10 | ||
# CHECK-NEXT: Instructions: 20 | ||
# CHECK-NEXT: Total Cycles: 1004 | ||
# CHECK-NEXT: Total uOps: 20 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py | ||
# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=10 %s 2>&1 | FileCheck %s | ||
|
||
# LLVM-MCA-LATENCY 100 | ||
add (%eax), %eax | ||
mov %eax, (%ebx) | ||
|
||
# CHECK: Iterations: 10 | ||
# CHECK-NEXT: Instructions: 20 | ||
# CHECK-NEXT: Total Cycles: 1103 | ||
# CHECK-NEXT: Total uOps: 20 |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,6 +24,7 @@ | |
#include "llvm/MC/MCTargetOptions.h" | ||
#include "llvm/MC/TargetRegistry.h" | ||
#include "llvm/MCA/Context.h" | ||
#include "llvm/MCA/InstrBuilder.h" | ||
#include "llvm/TargetParser/SubtargetFeature.h" | ||
#include "llvm/TargetParser/Triple.h" | ||
|
||
|
@@ -73,9 +74,11 @@ class MCATestBase : public ::testing::Test { | |
/// Utility function to run MCA with (nearly) the same configuration as the | ||
/// `llvm-mca` tool to verify result correctness. | ||
/// This function only displays on SummaryView by default. | ||
virtual Error runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts, | ||
ArrayRef<mca::View *> Views = {}, | ||
const mca::PipelineOptions *PO = nullptr); | ||
virtual Error | ||
runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts, | ||
ArrayRef<mca::View *> Views = {}, | ||
const mca::PipelineOptions *PO = nullptr, | ||
SmallVector<std::pair<StringRef, StringRef>> Descs = {}); | ||
|
||
}; | ||
|
||
} // end namespace mca | ||
|
Uh oh!
There was an error while loading. Please reload this page.