summaryrefslogtreecommitdiffstats
path: root/llvm/tools/llvm-mca
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-06-04 15:43:09 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-06-04 15:43:09 +0000
commit39e5a5695fd3e560565b40d1b60b4a1e78665875 (patch)
tree3945b3ad7cc4465a52e631ce891e42a057ddb79c /llvm/tools/llvm-mca
parentab60a2823f1a6548c17c57abbbafdb4ddb3bb785 (diff)
downloadbcm5719-llvm-39e5a5695fd3e560565b40d1b60b4a1e78665875.tar.gz
bcm5719-llvm-39e5a5695fd3e560565b40d1b60b4a1e78665875.zip
[RFC][patch 3/3] Add support for variant scheduling classes in llvm-mca.
This patch is the last of a sequence of three patches related to LLVM-dev RFC "MC support for variant scheduling classes". http://lists.llvm.org/pipermail/llvm-dev/2018-May/123181.html This fixes PR36672. The main goal of this patch is to teach llvm-mca how to solve variant scheduling classes. This patch does that, plus it adds new variant scheduling classes to the BtVer2 scheduling model to identify so-called zero-idioms (i.e. so-called dependency breaking instructions that are known to generate zero, and that are optimized out in hardware at register renaming stage). Without the BtVer2 change, this patch would not have had any meaningful tests. This patch is effectively the union of two changes: 1) a change that teaches llvm-mca how to resolve variant scheduling classes. 2) a change to the BtVer2 scheduling model that allows us to special-case packed XOR zero-idioms (this partially fixes PR36671). Differential Revision: https://reviews.llvm.org/D47374 llvm-svn: 333909
Diffstat (limited to 'llvm/tools/llvm-mca')
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.cpp40
-rw-r--r--llvm/tools/llvm-mca/InstrBuilder.h3
-rw-r--r--llvm/tools/llvm-mca/InstructionInfoView.cpp11
3 files changed, 38 insertions, 16 deletions
diff --git a/llvm/tools/llvm-mca/InstrBuilder.cpp b/llvm/tools/llvm-mca/InstrBuilder.cpp
index a745e1a6150..8a66a76605f 100644
--- a/llvm/tools/llvm-mca/InstrBuilder.cpp
+++ b/llvm/tools/llvm-mca/InstrBuilder.cpp
@@ -396,18 +396,22 @@ const InstrDesc &InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
// Then obtain the scheduling class information from the instruction.
unsigned SchedClassID = MCDesc.getSchedClass();
- const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+ unsigned CPUID = SM.getProcessorID();
+
+ // Try to solve variant scheduling classes.
+ if (SchedClassID) {
+ while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
+ SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &MCI, CPUID);
+
+ if (!SchedClassID)
+ llvm::report_fatal_error("unable to resolve this variant class.");
+ }
// Create a new empty descriptor.
std::unique_ptr<InstrDesc> ID = llvm::make_unique<InstrDesc>();
- if (SCDesc.isVariant()) {
- WithColor::warning() << "don't know how to model variant opcodes.\n";
- WithColor::note() << "assume 1 micro opcode.\n";
- ID->NumMicroOps = 1U;
- } else {
- ID->NumMicroOps = SCDesc.NumMicroOps;
- }
+ const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
+ ID->NumMicroOps = SCDesc.NumMicroOps;
if (MCDesc.isCall()) {
// We don't correctly model calls.
@@ -435,14 +439,24 @@ const InstrDesc &InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n');
// Now add the new descriptor.
- Descriptors[Opcode] = std::move(ID);
- return *Descriptors[Opcode];
+ SchedClassID = MCDesc.getSchedClass();
+ if (!SM.getSchedClassDesc(SchedClassID)->isVariant()) {
+ Descriptors[MCI.getOpcode()] = std::move(ID);
+ return *Descriptors[MCI.getOpcode()];
+ }
+
+ VariantDescriptors[&MCI] = std::move(ID);
+ return *VariantDescriptors[&MCI];
}
const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI) {
- if (Descriptors.find_as(MCI.getOpcode()) == Descriptors.end())
- return createInstrDescImpl(MCI);
- return *Descriptors[MCI.getOpcode()];
+ if (Descriptors.find_as(MCI.getOpcode()) != Descriptors.end())
+ return *Descriptors[MCI.getOpcode()];
+
+ if (VariantDescriptors.find(&MCI) != VariantDescriptors.end())
+ return *VariantDescriptors[&MCI];
+
+ return createInstrDescImpl(MCI);
}
std::unique_ptr<Instruction>
diff --git a/llvm/tools/llvm-mca/InstrBuilder.h b/llvm/tools/llvm-mca/InstrBuilder.h
index c22b7dcdbc6..146e917eb62 100644
--- a/llvm/tools/llvm-mca/InstrBuilder.h
+++ b/llvm/tools/llvm-mca/InstrBuilder.h
@@ -40,9 +40,10 @@ class InstrBuilder {
llvm::SmallVector<uint64_t, 8> ProcResourceMasks;
llvm::DenseMap<unsigned short, std::unique_ptr<const InstrDesc>> Descriptors;
+ llvm::DenseMap<const llvm::MCInst *, std::unique_ptr<const InstrDesc>>
+ VariantDescriptors;
const InstrDesc &createInstrDescImpl(const llvm::MCInst &MCI);
-
InstrBuilder(const InstrBuilder &) = delete;
InstrBuilder &operator=(const InstrBuilder &) = delete;
diff --git a/llvm/tools/llvm-mca/InstructionInfoView.cpp b/llvm/tools/llvm-mca/InstructionInfoView.cpp
index 76d63d21cb2..3b1e4dc8188 100644
--- a/llvm/tools/llvm-mca/InstructionInfoView.cpp
+++ b/llvm/tools/llvm-mca/InstructionInfoView.cpp
@@ -36,9 +36,16 @@ void InstructionInfoView::printView(raw_ostream &OS) const {
for (unsigned I = 0, E = Instructions; I < E; ++I) {
const MCInst &Inst = Source.getMCInstFromIndex(I);
const MCInstrDesc &MCDesc = MCII.get(Inst.getOpcode());
- const MCSchedClassDesc &SCDesc =
- *SM.getSchedClassDesc(MCDesc.getSchedClass());
+ // Obtain the scheduling class information from the instruction.
+ unsigned SchedClassID = MCDesc.getSchedClass();
+ unsigned CPUID = SM.getProcessorID();
+
+ // Try to solve variant scheduling classes.
+ while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant())
+ SchedClassID = STI.resolveVariantSchedClass(SchedClassID, &Inst, CPUID);
+
+ const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SchedClassID);
unsigned NumMicroOpcodes = SCDesc.NumMicroOps;
unsigned Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
Optional<double> RThroughput =
OpenPOWER on IntegriCloud