[llvm-mca] Add bottle-neck analysis to JSON output. (#90056)
This patch implements the bottle-neck analysis data in the JSON dump mode.
This commit is contained in:
73
llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
Normal file
73
llvm/test/tools/llvm-mca/JSON/X86/views-bottleneck.s
Normal file
@@ -0,0 +1,73 @@
|
||||
# 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 --bottleneck-analysis --resource-pressure=false --instruction-info=false < %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: "Instructions": [
|
||||
# CHECK-NEXT: "vaddps\t%xmm0, %xmm0, %xmm1",
|
||||
# CHECK-NEXT: "vblendvps\t%xmm1, (%rdi), %xmm2, %xmm3"
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "Name": "",
|
||||
# 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: }
|
||||
# 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: }
|
||||
@@ -16,6 +16,9 @@ add %edx, %edx
|
||||
# CHECK: {
|
||||
# CHECK-NEXT: "CodeRegions": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 0
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
|
||||
@@ -19,6 +19,29 @@ add %edx, %edx
|
||||
# CHECK: {
|
||||
# CHECK-NEXT: "CodeRegions": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "DataDependencyCycles": 39,
|
||||
# CHECK-NEXT: "DependencyEdge": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 0,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 22,
|
||||
# CHECK-NEXT: "ToID": 1,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 1,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 22,
|
||||
# CHECK-NEXT: "ToID": 2,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "MemoryDependencyCycles": 0,
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 39,
|
||||
# CHECK-NEXT: "RegisterDependencyCycles": 39,
|
||||
# CHECK-NEXT: "ResourcePressure": [],
|
||||
# CHECK-NEXT: "ResourcePressureCycles": 0,
|
||||
# CHECK-NEXT: "TotalCycles": 103
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
@@ -175,6 +198,29 @@ add %edx, %edx
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "DataDependencyCycles": 69,
|
||||
# CHECK-NEXT: "DependencyEdge": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 0,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 24,
|
||||
# CHECK-NEXT: "ToID": 2,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 2,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 24,
|
||||
# CHECK-NEXT: "ToID": 4,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "MemoryDependencyCycles": 0,
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 69,
|
||||
# CHECK-NEXT: "RegisterDependencyCycles": 69,
|
||||
# CHECK-NEXT: "ResourcePressure": [],
|
||||
# CHECK-NEXT: "ResourcePressureCycles": 0,
|
||||
# CHECK-NEXT: "TotalCycles": 103
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
@@ -411,6 +457,29 @@ add %edx, %edx
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "DataDependencyCycles": 39,
|
||||
# CHECK-NEXT: "DependencyEdge": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 0,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 27,
|
||||
# CHECK-NEXT: "ToID": 1,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 1,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 27,
|
||||
# CHECK-NEXT: "ToID": 2,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "MemoryDependencyCycles": 0,
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 39,
|
||||
# CHECK-NEXT: "RegisterDependencyCycles": 39,
|
||||
# CHECK-NEXT: "ResourcePressure": [],
|
||||
# CHECK-NEXT: "ResourcePressureCycles": 0,
|
||||
# CHECK-NEXT: "TotalCycles": 103
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
|
||||
@@ -20,6 +20,9 @@ add %edx, %edx
|
||||
# CHECK: {
|
||||
# CHECK-NEXT: "CodeRegions": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 0
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
@@ -164,6 +167,29 @@ add %edx, %edx
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "DataDependencyCycles": 69,
|
||||
# CHECK-NEXT: "DependencyEdge": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 0,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 24,
|
||||
# CHECK-NEXT: "ToID": 2,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "FromID": 2,
|
||||
# CHECK-NEXT: "ResourceOrRegID": 24,
|
||||
# CHECK-NEXT: "ToID": 4,
|
||||
# CHECK-NEXT: "Type": 1
|
||||
# CHECK-NEXT: }
|
||||
# CHECK-NEXT: ],
|
||||
# CHECK-NEXT: "MemoryDependencyCycles": 0,
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 69,
|
||||
# CHECK-NEXT: "RegisterDependencyCycles": 69,
|
||||
# CHECK-NEXT: "ResourcePressure": [],
|
||||
# CHECK-NEXT: "ResourcePressureCycles": 0,
|
||||
# CHECK-NEXT: "TotalCycles": 103
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
|
||||
@@ -16,6 +16,9 @@ add %edx, %edx
|
||||
# CHECK: {
|
||||
# CHECK-NEXT: "CodeRegions": [
|
||||
# CHECK-NEXT: {
|
||||
# CHECK-NEXT: "BottleneckAnalysis": {
|
||||
# CHECK-NEXT: "PressureIncreaseCycles": 0
|
||||
# CHECK-NEXT: },
|
||||
# CHECK-NEXT: "DispatchStatistics": {
|
||||
# CHECK-NEXT: "GROUP": 0,
|
||||
# CHECK-NEXT: "LQ": 0,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -335,7 +335,8 @@ public:
|
||||
|
||||
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); }
|
||||
|
||||
Reference in New Issue
Block a user