summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-03-08 20:21:55 +0000
committerAndrea Di Biagio <Andrea_DiBiagio@sn.scee.net>2018-03-08 20:21:55 +0000
commit373c38a2db3787b60a5d2588922e8b8eac389d17 (patch)
tree1e20157e34fc430c6152e4c3c1bd75d0de7ce16c
parentf0bcbfef5cc86e0f805ffeb64733e774f7c7bc0e (diff)
downloadbcm5719-llvm-373c38a2db3787b60a5d2588922e8b8eac389d17.tar.gz
bcm5719-llvm-373c38a2db3787b60a5d2588922e8b8eac389d17.zip
[llvm-mca] Fix handling of zero-latency instructions.
This patch fixes a problem found when testing zero latency instructions on target AArch64 -mcpu=exynos-m3 / -mcpu=exynos-m1. On Exynos-m3/m1, direct branches are zero-latency instructions that don't consume any processor resources. The DispatchUnit marks zero-latency instructions as "executed", so that no scheduling is required. The event of instruction executed is then notified to all the listeners, and the reorder buffer (managed by the RetireControlUnit) is updated. In particular, the entry associated to the zero-latency instruction in the reorder buffer is marked as executed. Before this patch, the DispatchUnit forgot to assign a retire control unit token (RCUToken) to the zero-latency instruction. As a consequence, the RCUToken was used uninitialized. This was causing a crash in the RetireControlUnit logic. Fixes PR36650. llvm-svn: 327056
-rw-r--r--llvm/test/tools/llvm-mca/AArch64/CortexA57/direct-branch.s61
-rw-r--r--llvm/test/tools/llvm-mca/AArch64/Exynos/direct-branch.s37
-rw-r--r--llvm/test/tools/llvm-mca/AArch64/lit.local.cfg2
-rw-r--r--llvm/tools/llvm-mca/Backend.cpp5
-rw-r--r--llvm/tools/llvm-mca/Dispatch.cpp1
-rw-r--r--llvm/tools/llvm-mca/Scheduler.cpp1
6 files changed, 102 insertions, 5 deletions
diff --git a/llvm/test/tools/llvm-mca/AArch64/CortexA57/direct-branch.s b/llvm/test/tools/llvm-mca/AArch64/CortexA57/direct-branch.s
new file mode 100644
index 00000000000..4bacbc17d4d
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/AArch64/CortexA57/direct-branch.s
@@ -0,0 +1,61 @@
+# RUN: llvm-mca -march=aarch64 -mcpu=cortex-a57 -iterations=600 -timeline < %s | FileCheck %s
+
+ b t
+
+# CHECK: Iterations: 600
+# CHECK-NEXT: Instructions: 600
+# CHECK-NEXT: Total Cycles: 603
+# CHECK-NEXT: Dispatch Width: 3
+# CHECK-NEXT: IPC: 1.00
+
+
+# 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: 1 1 1.00 b t
+
+
+# CHECK: Resources:
+# CHECK-NEXT: [0] - A57UnitB
+# CHECK-NEXT: [1.0] - A57UnitI
+# CHECK-NEXT: [1.1] - A57UnitI
+# CHECK-NEXT: [2] - A57UnitL
+# CHECK-NEXT: [3] - A57UnitM
+# CHECK-NEXT: [4] - A57UnitS
+# CHECK-NEXT: [5] - A57UnitW
+# CHECK-NEXT: [6] - A57UnitX
+
+
+# CHECK: Resource pressure per iteration:
+# CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6]
+# CHECK-NEXT: 1.00 - - - - - - -
+
+# CHECK: Resource pressure by instruction:
+# CHECK-NEXT: [0] [1.0] [1.1] [2] [3] [4] [5] [6] Instructions:
+# CHECK-NEXT: 1.00 - - - - - - - b t
+
+
+# CHECK: Timeline view:
+# CHECK-NEXT: 012
+# CHECK-NEXT: Index 0123456789
+
+# CHECK: [0,0] DeER . . . b t
+# CHECK: [1,0] D=eER. . . b t
+# CHECK: [2,0] D==eER . . b t
+# CHECK: [3,0] .D==eER . . b t
+
+
+# CHECK: Average Wait times (based on the timeline view):
+# CHECK-NEXT: [0]: Executions
+# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
+# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
+# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage
+
+# CHECK: [0] [1] [2] [3]
+# CHECK-NEXT: 0. 10 4.3 4.3 0.0 b t
diff --git a/llvm/test/tools/llvm-mca/AArch64/Exynos/direct-branch.s b/llvm/test/tools/llvm-mca/AArch64/Exynos/direct-branch.s
new file mode 100644
index 00000000000..eb0a78374ed
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/AArch64/Exynos/direct-branch.s
@@ -0,0 +1,37 @@
+# RUN: llvm-mca -march=aarch64 -mcpu=exynos-m3 -iterations=300 -timeline < %s | FileCheck %s -check-prefix=ALL -check-prefix=M3
+# RUN: llvm-mca -march=aarch64 -mcpu=exynos-m1 -iterations=300 -timeline < %s | FileCheck %s -check-prefix=ALL -check-prefix=M1
+
+ b t
+
+# ALL: Iterations: 300
+# ALL-NEXT: Instructions: 300
+
+# M3-NEXT: Total Cycles: 51
+# M3-NEXT: Dispatch Width: 6
+# M3-NEXT: IPC: 5.88
+
+# M1-NEXT: Total Cycles: 76
+# M1-NEXT: Dispatch Width: 4
+# M1-NEXT: IPC: 3.95
+
+
+# ALL: Instruction Info:
+# ALL-NEXT: [1]: #uOps
+# ALL-NEXT: [2]: Latency
+# ALL-NEXT: [3]: RThroughput
+# ALL-NEXT: [4]: MayLoad
+# ALL-NEXT: [5]: MayStore
+# ALL-NEXT: [6]: HasSideEffects
+
+# ALL: [1] [2] [3] [4] [5] [6] Instructions:
+# ALL-NEXT: 1 0 - b t
+
+
+# ALL: Average Wait times (based on the timeline view):
+# ALL-NEXT: [0]: Executions
+# ALL-NEXT: [1]: Average time spent waiting in a scheduler's queue
+# ALL-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
+# ALL-NEXT: [3]: Average time elapsed from WB until retire stage
+
+# ALL: [0] [1] [2] [3]
+# ALL-NEXT: 0. 10 0.0 0.0 0.0 b t
diff --git a/llvm/test/tools/llvm-mca/AArch64/lit.local.cfg b/llvm/test/tools/llvm-mca/AArch64/lit.local.cfg
new file mode 100644
index 00000000000..7184443994b
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/AArch64/lit.local.cfg
@@ -0,0 +1,2 @@
+if not 'AArch64' in config.root.targets:
+ config.unsupported = True
diff --git a/llvm/tools/llvm-mca/Backend.cpp b/llvm/tools/llvm-mca/Backend.cpp
index 62e239524dd..fab725aecf7 100644
--- a/llvm/tools/llvm-mca/Backend.cpp
+++ b/llvm/tools/llvm-mca/Backend.cpp
@@ -43,11 +43,6 @@ void Backend::runCycle(unsigned Cycle) {
Instructions[IR.first] = std::unique_ptr<Instruction>(NewIS);
NewIS->setRCUTokenID(DU->dispatch(IR.first, NewIS));
- // If this is a zero latency instruction, then we don't need to dispatch
- // it. Instead, we can mark it as executed.
- if (NewIS->isZeroLatency())
- notifyInstructionExecuted(IR.first);
-
// Check if we have dispatched all the instructions.
SM.updateNext();
if (!SM.hasNext())
diff --git a/llvm/tools/llvm-mca/Dispatch.cpp b/llvm/tools/llvm-mca/Dispatch.cpp
index c5c560ca2f3..8a08339265a 100644
--- a/llvm/tools/llvm-mca/Dispatch.cpp
+++ b/llvm/tools/llvm-mca/Dispatch.cpp
@@ -242,6 +242,7 @@ unsigned DispatchUnit::dispatch(unsigned IID, Instruction *NewInst) {
// Reserve slots in the RCU.
unsigned RCUTokenID = RCU->reserveSlot(IID, NumMicroOps);
+ NewInst->setRCUTokenID(RCUTokenID);
Owner->notifyInstructionDispatched(IID);
SC->scheduleInstruction(IID, NewInst);
diff --git a/llvm/tools/llvm-mca/Scheduler.cpp b/llvm/tools/llvm-mca/Scheduler.cpp
index 8608a06b8df..6c0c44bd4d7 100644
--- a/llvm/tools/llvm-mca/Scheduler.cpp
+++ b/llvm/tools/llvm-mca/Scheduler.cpp
@@ -264,6 +264,7 @@ Instruction *Scheduler::scheduleInstruction(unsigned Idx, Instruction *MCIS) {
// eliminated at register renaming stage, since we know in advance that those
// clear their output register.
if (MCIS->isZeroLatency()) {
+ notifyInstructionReady(Idx);
MCIS->forceExecuted();
notifyInstructionIssued(Idx, {});
notifyInstructionExecuted(Idx);
OpenPOWER on IntegriCloud