aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-04-30 15:55:04 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-04-30 15:55:04 +0000
commite047d3529baa0920dc55ae278c39e40f03baa2af (patch)
tree810cfa6949204c8677c6d4e971f09791bf60f36a
parent79e5cd2fc50f810f9ebfef41422695773caaffa7 (diff)
downloadllvm-e047d3529baa0920dc55ae278c39e40f03baa2af.zip
llvm-e047d3529baa0920dc55ae278c39e40f03baa2af.tar.gz
llvm-e047d3529baa0920dc55ae278c39e40f03baa2af.tar.bz2
[llvm-mca] Correctly handle zero-latency stores that consume pipeline resources.
This fixes PR37293. We can have scheduling classes with no write latency entries, that still consume processor resources. We don't want to treat those instructions as zero-latency instructions; they still have to be issued to the underlying pipelines, so they still consume resource cycles. This is likely to be a regression which I have accidentally introduced at revision 330807. Now, if an instruction has a non-empty set of write processor resources, we conservatively treat it as a normal (i.e. non zero-latency) instruction. llvm-svn: 331193
-rw-r--r--llvm/test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s44
-rw-r--r--llvm/tools/llvm-mca/Dispatch.cpp3
-rw-r--r--llvm/tools/llvm-mca/Scheduler.cpp3
3 files changed, 48 insertions, 2 deletions
diff --git a/llvm/test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s b/llvm/test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s
new file mode 100644
index 0000000..4108d0d
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s
@@ -0,0 +1,44 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -march=aarch64 -mcpu=falkor -iterations=2 < %s | FileCheck %s
+
+ stp d0, d1, [x0]
+
+# CHECK: Iterations: 2
+# CHECK-NEXT: Instructions: 2
+# CHECK-NEXT: Total Cycles: 4
+# CHECK-NEXT: Dispatch Width: 8
+# CHECK-NEXT: IPC: 0.50
+
+# CHECK: Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
+# CHECK-NEXT: 2 0 1.00 * stp d0, d1, [x0]
+
+# CHECK: Resources:
+# CHECK-NEXT: [0] - FalkorUnitB
+# CHECK-NEXT: [1] - FalkorUnitGTOV
+# CHECK-NEXT: [2] - FalkorUnitLD
+# CHECK-NEXT: [3] - FalkorUnitSD
+# CHECK-NEXT: [4] - FalkorUnitST
+# CHECK-NEXT: [5] - FalkorUnitVSD
+# CHECK-NEXT: [6] - FalkorUnitVTOG
+# CHECK-NEXT: [7] - FalkorUnitVX
+# CHECK-NEXT: [8] - FalkorUnitVY
+# CHECK-NEXT: [9] - FalkorUnitX
+# CHECK-NEXT: [10] - FalkorUnitY
+# CHECK-NEXT: [11] - FalkorUnitZ
+
+# CHECK: Resource pressure per iteration:
+# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11]
+# CHECK-NEXT: - - - - 1.00 1.00 - - - - - -
+
+# CHECK: Resource pressure by instruction:
+# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] Instructions:
+# CHECK-NEXT: - - - - 1.00 1.00 - - - - - - stp d0, d1, [x0]
+
diff --git a/llvm/tools/llvm-mca/Dispatch.cpp b/llvm/tools/llvm-mca/Dispatch.cpp
index 47f8dca..9bccca7 100644
--- a/llvm/tools/llvm-mca/Dispatch.cpp
+++ b/llvm/tools/llvm-mca/Dispatch.cpp
@@ -411,7 +411,8 @@ void DispatchUnit::dispatch(unsigned IID, Instruction *NewInst,
// instruction. The assumption is that a zero-latency instruction doesn't
// require to be issued to the scheduler for execution. More importantly, it
// doesn't have to wait on the register input operands.
- if (NewInst->getDesc().MaxLatency)
+ const InstrDesc &Desc = NewInst->getDesc();
+ if (Desc.MaxLatency || !Desc.Resources.empty())
for (std::unique_ptr<ReadState> &RS : NewInst->getUses())
updateRAWDependencies(*RS, STI);
diff --git a/llvm/tools/llvm-mca/Scheduler.cpp b/llvm/tools/llvm-mca/Scheduler.cpp
index ead3226..a42cbef 100644
--- a/llvm/tools/llvm-mca/Scheduler.cpp
+++ b/llvm/tools/llvm-mca/Scheduler.cpp
@@ -258,12 +258,13 @@ void Scheduler::scheduleInstruction(unsigned Idx, Instruction &MCIS) {
// targets, zero-idiom instructions (for example: a xor that clears the value
// of a register) are treated speacially, and are often eliminated at register
// renaming stage.
+ bool IsZeroLatency = !Desc.MaxLatency && Desc.Resources.empty();
// Instructions that use an in-order dispatch/issue processor resource must be
// issued immediately to the pipeline(s). Any other in-order buffered
// resources (i.e. BufferSize=1) is consumed.
- if (Desc.MaxLatency && !Resources->mustIssueImmediately(Desc)) {
+ if (!IsZeroLatency && !Resources->mustIssueImmediately(Desc)) {
DEBUG(dbgs() << "[SCHEDULER] Adding " << Idx << " to the Ready Queue\n");
ReadyQueue[Idx] = &MCIS;
return;