OSDN Git Service

[llvm-mca] Correctly handle zero-latency stores that consume pipeline resources.
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Mon, 30 Apr 2018 15:55:04 +0000 (15:55 +0000)
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>
Mon, 30 Apr 2018 15:55:04 +0000 (15:55 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@331193 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s [new file with mode: 0644]
tools/llvm-mca/Dispatch.cpp
tools/llvm-mca/Scheduler.cpp

diff --git a/test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s b/test/tools/llvm-mca/AArch64/Falkor/zero-latency-store.s
new file mode 100644 (file)
index 0000000..4108d0d
--- /dev/null
@@ -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]
+
index 47f8dca..9bccca7 100644 (file)
@@ -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);
 
index ead3226..a42cbef 100644 (file)
@@ -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;