[llvm] [llvm-mca] Add bottle-neck analysis to JSON output. (PR #90056)

Phil Camp via llvm-commits llvm-commits at lists.llvm.org
Fri Apr 26 05:25:08 PDT 2024


https://github.com/FlameTop updated https://github.com/llvm/llvm-project/pull/90056

>From 010509461d609899836ac4d554bcd42d37351e79 Mon Sep 17 00:00:00 2001
From: Phil Camp <phil.camp at sony.com>
Date: Thu, 25 Apr 2024 14:43:18 +0100
Subject: [PATCH 1/2] Add bottle-neck analysis to JSON output.

---
 .../llvm-mca/JSON/X86/views-bottleneck.s      | 166 ++++++++++++++++++
 .../llvm-mca/Views/BottleneckAnalysis.cpp     |  46 +++++
 .../tools/llvm-mca/Views/BottleneckAnalysis.h |   3 +-
 3 files changed, 214 insertions(+), 1 deletion(-)
 create mode 100644 llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s

diff --git a/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s b/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
new file mode 100644
index 00000000000000..2267e623b5e997
--- /dev/null
+++ b/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
@@ -0,0 +1,166 @@
+# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=haswell --json --timeline-max-iterations=1 --timeline --all-stats --all-views < %s | FileCheck %s
+vaddps %xmm0, %xmm0, %xmm1
+vblendvps %xmm1, (%rdi), %xmm2, %xmm3
+
+# CHECK:      {
+# CHECK-NEXT:   "CodeRegions": [
+# CHECK-NEXT:     {
+# CHECK-NEXT:       "BottleneckAnalysis": {
+# CHECK-NEXT:         "DataDependencyCycles": 0,
+# CHECK-NEXT:         "DependencyEdge": [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "FromID": 1,
+# CHECK-NEXT:             "ResourceOrRegID": 128,
+# CHECK-NEXT:             "ToID": 3,
+# CHECK-NEXT:             "Type": 3
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "FromID": 3,
+# CHECK-NEXT:             "ResourceOrRegID": 128,
+# CHECK-NEXT:             "ToID": 5,
+# CHECK-NEXT:             "Type": 3
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ],
+# CHECK-NEXT:         "MemoryDependencyCycles": 0,
+# CHECK-NEXT:         "PressureIncreaseCycles": 56,
+# CHECK-NEXT:         "RegisterDependencyCycles": 0,
+# CHECK-NEXT:         "ResourcePressure": [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "HWPort5": 56
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ],
+# CHECK-NEXT:         "ResourcePressureCycles": 56,
+# CHECK-NEXT:         "TotalCycles": 209
+# CHECK-NEXT:       },
+# CHECK-NEXT:       "DispatchStatistics": {
+# CHECK-NEXT:         "GROUP": 0,
+# CHECK-NEXT:         "LQ": 0,
+# CHECK-NEXT:         "RAT": 0,
+# CHECK-NEXT:         "RCU": 13,
+# CHECK-NEXT:         "SCHEDQ": 0,
+# CHECK-NEXT:         "SQ": 0,
+# CHECK-NEXT:         "USH": 0
+# CHECK-NEXT:       },
+# CHECK-NEXT:       "InstructionInfoView": {
+# CHECK-NEXT:         "InstructionList": [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "Instruction": 0,
+# CHECK-NEXT:             "Latency": 3,
+# CHECK-NEXT:             "NumMicroOpcodes": 1,
+# CHECK-NEXT:             "RThroughput": 1,
+# CHECK-NEXT:             "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:             "mayLoad": false,
+# CHECK-NEXT:             "mayStore": false
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "Instruction": 1,
+# CHECK-NEXT:             "Latency": 8,
+# CHECK-NEXT:             "NumMicroOpcodes": 3,
+# CHECK-NEXT:             "RThroughput": 2,
+# CHECK-NEXT:             "hasUnmodeledSideEffects": false,
+# CHECK-NEXT:             "mayLoad": true,
+# CHECK-NEXT:             "mayStore": false
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       },
+# CHECK-NEXT:       "Instructions": [
+# CHECK-NEXT:         "vaddps\t%xmm0, %xmm0, %xmm1",
+# CHECK-NEXT:         "vblendvps\t%xmm1, (%rdi), %xmm2, %xmm3"
+# CHECK-NEXT:       ],
+# CHECK-NEXT:       "Name": "",
+# CHECK-NEXT:       "ResourcePressureView": {
+# CHECK-NEXT:         "ResourcePressureInfo": [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 0,
+# CHECK-NEXT:             "ResourceIndex": 3,
+# CHECK-NEXT:             "ResourceUsage": 1
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 1,
+# CHECK-NEXT:             "ResourceIndex": 4,
+# CHECK-NEXT:             "ResourceUsage": 0.5
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 1,
+# CHECK-NEXT:             "ResourceIndex": 5,
+# CHECK-NEXT:             "ResourceUsage": 0.5
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 1,
+# CHECK-NEXT:             "ResourceIndex": 7,
+# CHECK-NEXT:             "ResourceUsage": 2
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 2,
+# CHECK-NEXT:             "ResourceIndex": 3,
+# CHECK-NEXT:             "ResourceUsage": 1
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 2,
+# CHECK-NEXT:             "ResourceIndex": 4,
+# CHECK-NEXT:             "ResourceUsage": 0.5
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 2,
+# CHECK-NEXT:             "ResourceIndex": 5,
+# CHECK-NEXT:             "ResourceUsage": 0.5
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "InstructionIndex": 2,
+# CHECK-NEXT:             "ResourceIndex": 7,
+# CHECK-NEXT:             "ResourceUsage": 2
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       },
+# CHECK-NEXT:       "SummaryView": {
+# CHECK-NEXT:         "BlockRThroughput": 2,
+# CHECK-NEXT:         "DispatchWidth": 4,
+# CHECK-NEXT:         "IPC": 0.9569377990430622,
+# CHECK-NEXT:         "Instructions": 200,
+# CHECK-NEXT:         "Iterations": 100,
+# CHECK-NEXT:         "TotalCycles": 209,
+# CHECK-NEXT:         "TotaluOps": 400,
+# CHECK-NEXT:         "uOpsPerCycle": 1.9138755980861244
+# CHECK-NEXT:       },
+# CHECK-NEXT:       "TimelineView": {
+# CHECK-NEXT:         "TimelineInfo": [
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "CycleDispatched": 0,
+# CHECK-NEXT:             "CycleExecuted": 4,
+# CHECK-NEXT:             "CycleIssued": 1,
+# CHECK-NEXT:             "CycleReady": 0,
+# CHECK-NEXT:             "CycleRetired": 5
+# CHECK-NEXT:           },
+# CHECK-NEXT:           {
+# CHECK-NEXT:             "CycleDispatched": 0,
+# CHECK-NEXT:             "CycleExecuted": 9,
+# CHECK-NEXT:             "CycleIssued": 1,
+# CHECK-NEXT:             "CycleReady": 1,
+# CHECK-NEXT:             "CycleRetired": 10
+# CHECK-NEXT:           }
+# CHECK-NEXT:         ]
+# CHECK-NEXT:       }
+# CHECK-NEXT:     }
+# CHECK-NEXT:   ],
+# CHECK-NEXT:   "SimulationParameters": {
+# CHECK-NEXT:     "-march": "x86_64",
+# CHECK-NEXT:     "-mcpu": "haswell",
+# CHECK-NEXT:     "-mtriple": "x86_64-unknown-unknown"
+# CHECK-NEXT:   },
+# CHECK-NEXT:   "TargetInfo": {
+# CHECK-NEXT:     "CPUName": "haswell",
+# CHECK-NEXT:     "Resources": [
+# CHECK-NEXT:       "HWDivider",
+# CHECK-NEXT:       "HWFPDivider",
+# CHECK-NEXT:       "HWPort0",
+# CHECK-NEXT:       "HWPort1",
+# CHECK-NEXT:       "HWPort2",
+# CHECK-NEXT:       "HWPort3",
+# CHECK-NEXT:       "HWPort4",
+# CHECK-NEXT:       "HWPort5",
+# CHECK-NEXT:       "HWPort6",
+# CHECK-NEXT:       "HWPort7"
+# CHECK-NEXT:     ]
+# CHECK-NEXT:   }
+# CHECK-NEXT: }
diff --git a/llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp b/llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp
index 409a7010b80c8d..ece5b6709a2e4c 100644
--- a/llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp
+++ b/llvm/tools/llvm-mca/Views/BottleneckAnalysis.cpp
@@ -641,5 +641,51 @@ void BottleneckAnalysis::printView(raw_ostream &OS) const {
   printCriticalSequence(OS);
 }
 
+json::Value BottleneckAnalysis::toJSON() const {
+  if (!SeenStallCycles || !BPI.PressureIncreaseCycles) {
+    json::Object JO({{"PressureIncreaseCycles", 0}});
+    return JO;
+  }
+
+  json::Array CriticalSequence;
+  // get critical sequence
+  SmallVector<const DependencyEdge *, 16> Seq;
+  DG.getCriticalSequence(Seq);
+  if (!Seq.empty()) {
+    for (const DependencyEdge *&DE : Seq) {
+      json::Object DEJO({{"FromID", DE->FromIID},
+                         {"ToID", DE->ToIID},
+                         {"Type", static_cast<unsigned>(DE->Dep.Type)},
+                         {"ResourceOrRegID", DE->Dep.ResourceOrRegID}});
+      CriticalSequence.push_back(std::move(DEJO));
+    }
+  }
+
+  json::Array ResourcePressure;
+  if (BPI.PressureIncreaseCycles) {
+    ArrayRef<unsigned> Distribution = Tracker.getResourcePressureDistribution();
+    const MCSchedModel &SM = getSubTargetInfo().getSchedModel();
+    for (unsigned I = 0, E = Distribution.size(); I < E; ++I) {
+      unsigned ReleaseAtCycles = Distribution[I];
+      if (ReleaseAtCycles) {
+        const MCProcResourceDesc &PRDesc = *SM.getProcResource(I);
+        json::Object RPJO({{PRDesc.Name, ReleaseAtCycles}});
+        ResourcePressure.push_back(std::move(RPJO));
+      }
+    }
+  }
+
+  json::Object JO({{"PressureIncreaseCycles", BPI.PressureIncreaseCycles},
+                   {"ResourcePressureCycles", BPI.ResourcePressureCycles},
+                   {"DataDependencyCycles", BPI.DataDependencyCycles},
+                   {"RegisterDependencyCycles", BPI.RegisterDependencyCycles},
+                   {"MemoryDependencyCycles", BPI.MemoryDependencyCycles},
+                   {"TotalCycles", TotalCycles},
+                   {"DependencyEdge", std::move(CriticalSequence)},
+                   {"ResourcePressure", std::move(ResourcePressure)}});
+
+  return JO;
+}
+
 } // namespace mca.
 } // namespace llvm
diff --git a/llvm/tools/llvm-mca/Views/BottleneckAnalysis.h b/llvm/tools/llvm-mca/Views/BottleneckAnalysis.h
index e709b25c3f7680..529090cf543fc4 100644
--- a/llvm/tools/llvm-mca/Views/BottleneckAnalysis.h
+++ b/llvm/tools/llvm-mca/Views/BottleneckAnalysis.h
@@ -335,7 +335,8 @@ class BottleneckAnalysis : public InstructionView {
 
   void printView(raw_ostream &OS) const override;
   StringRef getNameAsString() const override { return "BottleneckAnalysis"; }
-  bool isSerializable() const override { return false; }
+  bool isSerializable() const override { return true; }
+  json::Value toJSON() const override;
 
 #ifndef NDEBUG
   void dump(raw_ostream &OS, MCInstPrinter &MCIP) const { DG.dump(OS, MCIP); }

>From 731bc9a032a98e2c65797bba1732fbbda16f9c1d Mon Sep 17 00:00:00 2001
From: Phil Camp <phil.camp at sony.com>
Date: Fri, 26 Apr 2024 13:24:28 +0100
Subject: [PATCH 2/2] Removed non-bottleneck views from test

---
 .../llvm-mca/JSON/X86/views-bottleneck.s      | 95 +------------------
 1 file changed, 1 insertion(+), 94 deletions(-)

diff --git a/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s b/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
index 2267e623b5e997..c8ad60ee542093 100644
--- a/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
+++ b/llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
@@ -1,5 +1,5 @@
 # NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
-# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=haswell --json --timeline-max-iterations=1 --timeline --all-stats --all-views < %s | FileCheck %s
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=haswell --json --timeline-max-iterations=1 --bottleneck-analysis --resource-pressure=false --instruction-info=false < %s | FileCheck %s
 vaddps %xmm0, %xmm0, %xmm1
 vblendvps %xmm1, (%rdi), %xmm2, %xmm3
 
@@ -33,86 +33,11 @@ vblendvps %xmm1, (%rdi), %xmm2, %xmm3
 # CHECK-NEXT:         "ResourcePressureCycles": 56,
 # CHECK-NEXT:         "TotalCycles": 209
 # CHECK-NEXT:       },
-# CHECK-NEXT:       "DispatchStatistics": {
-# CHECK-NEXT:         "GROUP": 0,
-# CHECK-NEXT:         "LQ": 0,
-# CHECK-NEXT:         "RAT": 0,
-# CHECK-NEXT:         "RCU": 13,
-# CHECK-NEXT:         "SCHEDQ": 0,
-# CHECK-NEXT:         "SQ": 0,
-# CHECK-NEXT:         "USH": 0
-# CHECK-NEXT:       },
-# CHECK-NEXT:       "InstructionInfoView": {
-# CHECK-NEXT:         "InstructionList": [
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "Instruction": 0,
-# CHECK-NEXT:             "Latency": 3,
-# CHECK-NEXT:             "NumMicroOpcodes": 1,
-# CHECK-NEXT:             "RThroughput": 1,
-# CHECK-NEXT:             "hasUnmodeledSideEffects": false,
-# CHECK-NEXT:             "mayLoad": false,
-# CHECK-NEXT:             "mayStore": false
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "Instruction": 1,
-# CHECK-NEXT:             "Latency": 8,
-# CHECK-NEXT:             "NumMicroOpcodes": 3,
-# CHECK-NEXT:             "RThroughput": 2,
-# CHECK-NEXT:             "hasUnmodeledSideEffects": false,
-# CHECK-NEXT:             "mayLoad": true,
-# CHECK-NEXT:             "mayStore": false
-# CHECK-NEXT:           }
-# CHECK-NEXT:         ]
-# CHECK-NEXT:       },
 # CHECK-NEXT:       "Instructions": [
 # CHECK-NEXT:         "vaddps\t%xmm0, %xmm0, %xmm1",
 # CHECK-NEXT:         "vblendvps\t%xmm1, (%rdi), %xmm2, %xmm3"
 # CHECK-NEXT:       ],
 # CHECK-NEXT:       "Name": "",
-# CHECK-NEXT:       "ResourcePressureView": {
-# CHECK-NEXT:         "ResourcePressureInfo": [
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 0,
-# CHECK-NEXT:             "ResourceIndex": 3,
-# CHECK-NEXT:             "ResourceUsage": 1
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 1,
-# CHECK-NEXT:             "ResourceIndex": 4,
-# CHECK-NEXT:             "ResourceUsage": 0.5
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 1,
-# CHECK-NEXT:             "ResourceIndex": 5,
-# CHECK-NEXT:             "ResourceUsage": 0.5
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 1,
-# CHECK-NEXT:             "ResourceIndex": 7,
-# CHECK-NEXT:             "ResourceUsage": 2
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 2,
-# CHECK-NEXT:             "ResourceIndex": 3,
-# CHECK-NEXT:             "ResourceUsage": 1
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 2,
-# CHECK-NEXT:             "ResourceIndex": 4,
-# CHECK-NEXT:             "ResourceUsage": 0.5
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 2,
-# CHECK-NEXT:             "ResourceIndex": 5,
-# CHECK-NEXT:             "ResourceUsage": 0.5
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "InstructionIndex": 2,
-# CHECK-NEXT:             "ResourceIndex": 7,
-# CHECK-NEXT:             "ResourceUsage": 2
-# CHECK-NEXT:           }
-# CHECK-NEXT:         ]
-# CHECK-NEXT:       },
 # CHECK-NEXT:       "SummaryView": {
 # CHECK-NEXT:         "BlockRThroughput": 2,
 # CHECK-NEXT:         "DispatchWidth": 4,
@@ -122,24 +47,6 @@ vblendvps %xmm1, (%rdi), %xmm2, %xmm3
 # CHECK-NEXT:         "TotalCycles": 209,
 # CHECK-NEXT:         "TotaluOps": 400,
 # CHECK-NEXT:         "uOpsPerCycle": 1.9138755980861244
-# CHECK-NEXT:       },
-# CHECK-NEXT:       "TimelineView": {
-# CHECK-NEXT:         "TimelineInfo": [
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "CycleDispatched": 0,
-# CHECK-NEXT:             "CycleExecuted": 4,
-# CHECK-NEXT:             "CycleIssued": 1,
-# CHECK-NEXT:             "CycleReady": 0,
-# CHECK-NEXT:             "CycleRetired": 5
-# CHECK-NEXT:           },
-# CHECK-NEXT:           {
-# CHECK-NEXT:             "CycleDispatched": 0,
-# CHECK-NEXT:             "CycleExecuted": 9,
-# CHECK-NEXT:             "CycleIssued": 1,
-# CHECK-NEXT:             "CycleReady": 1,
-# CHECK-NEXT:             "CycleRetired": 10
-# CHECK-NEXT:           }
-# CHECK-NEXT:         ]
 # CHECK-NEXT:       }
 # CHECK-NEXT:     }
 # CHECK-NEXT:   ],



More information about the llvm-commits mailing list