[llvm] r358554 - [MCA] Moved the bottleneck analysis to its own file. NFCI
Andrea Di Biagio via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 16 23:02:05 PDT 2019
Author: adibiagio
Date: Tue Apr 16 23:02:05 2019
New Revision: 358554
URL: http://llvm.org/viewvc/llvm-project?rev=358554&view=rev
Log:
[MCA] Moved the bottleneck analysis to its own file. NFCI
Added:
llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.cpp
llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.h
Modified:
llvm/trunk/tools/llvm-mca/CMakeLists.txt
llvm/trunk/tools/llvm-mca/Views/SummaryView.cpp
llvm/trunk/tools/llvm-mca/Views/SummaryView.h
llvm/trunk/tools/llvm-mca/llvm-mca.cpp
Modified: llvm/trunk/tools/llvm-mca/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CMakeLists.txt?rev=358554&r1=358553&r2=358554&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-mca/CMakeLists.txt Tue Apr 16 23:02:05 2019
@@ -17,6 +17,7 @@ add_llvm_tool(llvm-mca
CodeRegion.cpp
CodeRegionGenerator.cpp
PipelinePrinter.cpp
+ Views/BottleneckAnalysis.cpp
Views/DispatchStatistics.cpp
Views/InstructionInfoView.cpp
Views/RegisterFileStatistics.cpp
Added: llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.cpp?rev=358554&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.cpp (added)
+++ llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.cpp Tue Apr 16 23:02:05 2019
@@ -0,0 +1,142 @@
+//===--------------------- BottleneckAnalysis.cpp ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file implements the functionalities used by the BottleneckAnalysis
+/// to report bottleneck info.
+///
+//===----------------------------------------------------------------------===//
+
+#include "Views/BottleneckAnalysis.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/MCA/Support.h"
+#include "llvm/Support/Format.h"
+
+namespace llvm {
+namespace mca {
+
+#define DEBUG_TYPE "llvm-mca"
+
+BottleneckAnalysis::BottleneckAnalysis(const MCSchedModel &Model)
+ : SM(Model), TotalCycles(0), BPI({0, 0, 0, 0, 0}),
+ ResourcePressureDistribution(Model.getNumProcResourceKinds(), 0),
+ ProcResourceMasks(Model.getNumProcResourceKinds()),
+ ResIdx2ProcResID(Model.getNumProcResourceKinds(), 0),
+ PressureIncreasedBecauseOfResources(false),
+ PressureIncreasedBecauseOfDataDependencies(false),
+ SeenStallCycles(false) {
+ computeProcResourceMasks(SM, ProcResourceMasks);
+ for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
+ unsigned Index = getResourceStateIndex(ProcResourceMasks[I]);
+ ResIdx2ProcResID[Index] = I;
+ }
+}
+
+void BottleneckAnalysis::onEvent(const HWPressureEvent &Event) {
+ assert(Event.Reason != HWPressureEvent::INVALID &&
+ "Unexpected invalid event!");
+
+ switch (Event.Reason) {
+ default:
+ break;
+
+ case HWPressureEvent::RESOURCES: {
+ PressureIncreasedBecauseOfResources = true;
+ ++BPI.ResourcePressureCycles;
+ uint64_t ResourceMask = Event.ResourceMask;
+ while (ResourceMask) {
+ uint64_t Current = ResourceMask & (-ResourceMask);
+ unsigned Index = getResourceStateIndex(Current);
+ unsigned ProcResID = ResIdx2ProcResID[Index];
+ const MCProcResourceDesc &PRDesc = *SM.getProcResource(ProcResID);
+ if (!PRDesc.SubUnitsIdxBegin) {
+ ResourcePressureDistribution[Index]++;
+ ResourceMask ^= Current;
+ continue;
+ }
+
+ for (unsigned I = 0, E = PRDesc.NumUnits; I < E; ++I) {
+ unsigned OtherProcResID = PRDesc.SubUnitsIdxBegin[I];
+ unsigned OtherMask = ProcResourceMasks[OtherProcResID];
+ ResourcePressureDistribution[getResourceStateIndex(OtherMask)]++;
+ }
+
+ ResourceMask ^= Current;
+ }
+ break;
+ }
+
+ case HWPressureEvent::REGISTER_DEPS:
+ PressureIncreasedBecauseOfDataDependencies = true;
+ ++BPI.RegisterDependencyCycles;
+ break;
+ case HWPressureEvent::MEMORY_DEPS:
+ PressureIncreasedBecauseOfDataDependencies = true;
+ ++BPI.MemoryDependencyCycles;
+ break;
+ }
+}
+
+void BottleneckAnalysis::printBottleneckHints(raw_ostream &OS) const {
+ if (!SeenStallCycles || !BPI.PressureIncreaseCycles) {
+ OS << "\nNo resource or data dependency bottlenecks discovered.\n";
+ return;
+ }
+
+ double PressurePerCycle =
+ (double)BPI.PressureIncreaseCycles * 100 / TotalCycles;
+ double ResourcePressurePerCycle =
+ (double)BPI.ResourcePressureCycles * 100 / TotalCycles;
+ double DDPerCycle = (double)BPI.DataDependencyCycles * 100 / TotalCycles;
+ double RegDepPressurePerCycle =
+ (double)BPI.RegisterDependencyCycles * 100 / TotalCycles;
+ double MemDepPressurePerCycle =
+ (double)BPI.MemoryDependencyCycles * 100 / TotalCycles;
+
+ OS << "\nCycles with backend pressure increase [ "
+ << format("%.2f", floor((PressurePerCycle * 100) + 0.5) / 100) << "% ]";
+
+ OS << "\nThroughput Bottlenecks: "
+ << "\n Resource Pressure [ "
+ << format("%.2f", floor((ResourcePressurePerCycle * 100) + 0.5) / 100)
+ << "% ]";
+
+ if (BPI.PressureIncreaseCycles) {
+ for (unsigned I = 0, E = ResourcePressureDistribution.size(); I < E; ++I) {
+ if (ResourcePressureDistribution[I]) {
+ double Frequency =
+ (double)ResourcePressureDistribution[I] * 100 / TotalCycles;
+ unsigned Index = ResIdx2ProcResID[getResourceStateIndex(1ULL << I)];
+ const MCProcResourceDesc &PRDesc = *SM.getProcResource(Index);
+ OS << "\n - " << PRDesc.Name << " [ "
+ << format("%.2f", floor((Frequency * 100) + 0.5) / 100) << "% ]";
+ }
+ }
+ }
+
+ OS << "\n Data Dependencies: [ "
+ << format("%.2f", floor((DDPerCycle * 100) + 0.5) / 100) << "% ]";
+
+ OS << "\n - Register Dependencies [ "
+ << format("%.2f", floor((RegDepPressurePerCycle * 100) + 0.5) / 100)
+ << "% ]";
+
+ OS << "\n - Memory Dependencies [ "
+ << format("%.2f", floor((MemDepPressurePerCycle * 100) + 0.5) / 100)
+ << "% ]\n\n";
+}
+
+void BottleneckAnalysis::printView(raw_ostream &OS) const {
+ std::string Buffer;
+ raw_string_ostream TempStream(Buffer);
+ printBottleneckHints(TempStream);
+ TempStream.flush();
+ OS << Buffer;
+}
+} // namespace mca.
+} // namespace llvm
Added: llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.h?rev=358554&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.h (added)
+++ llvm/trunk/tools/llvm-mca/Views/BottleneckAnalysis.h Tue Apr 16 23:02:05 2019
@@ -0,0 +1,105 @@
+//===--------------------- BottleneckAnalysis.h -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file implements the bottleneck analysis view.
+///
+/// This view internally observes backend pressure increase events in order to
+/// identify potential sources of bottlenecks.
+///
+/// Example of bottleneck analysis report:
+///
+/// Cycles with backend pressure increase [ 33.40% ]
+/// Throughput Bottlenecks:
+/// Resource Pressure [ 0.52% ]
+/// - JLAGU [ 0.52% ]
+/// Data Dependencies: [ 32.88% ]
+/// - Register Dependencies [ 32.88% ]
+/// - Memory Dependencies [ 0.00% ]
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_BOTTLENECK_ANALYSIS_H
+#define LLVM_TOOLS_LLVM_MCA_BOTTLENECK_ANALYSIS_H
+
+#include "Views/View.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/Support/raw_ostream.h"
+
+namespace llvm {
+namespace mca {
+
+/// A view that collects and prints a few performance numbers.
+class BottleneckAnalysis : public View {
+ const llvm::MCSchedModel &SM;
+ unsigned TotalCycles;
+
+ struct BackPressureInfo {
+ // Cycles where backpressure increased.
+ unsigned PressureIncreaseCycles;
+ // Cycles where backpressure increased because of pipeline pressure.
+ unsigned ResourcePressureCycles;
+ // Cycles where backpressure increased because of data dependencies.
+ unsigned DataDependencyCycles;
+ // Cycles where backpressure increased because of register dependencies.
+ unsigned RegisterDependencyCycles;
+ // Cycles where backpressure increased because of memory dependencies.
+ unsigned MemoryDependencyCycles;
+ };
+ BackPressureInfo BPI;
+
+ // Resource pressure distribution. There is an element for every processor
+ // resource declared by the scheduling model. Quantities are number of cycles.
+ llvm::SmallVector<unsigned, 8> ResourcePressureDistribution;
+
+ // Each processor resource is associated with a so-called processor resource
+ // mask. This vector allows to correlate processor resource IDs with processor
+ // resource masks. There is exactly one element per each processor resource
+ // declared by the scheduling model.
+ llvm::SmallVector<uint64_t, 8> ProcResourceMasks;
+
+ // Used to map resource indices to actual processor resource IDs.
+ llvm::SmallVector<unsigned, 8> ResIdx2ProcResID;
+
+ // True if resource pressure events were notified during this cycle.
+ bool PressureIncreasedBecauseOfResources;
+ bool PressureIncreasedBecauseOfDataDependencies;
+
+ // True if throughput was affected by dispatch stalls.
+ bool SeenStallCycles;
+
+ // Prints a bottleneck message to OS.
+ void printBottleneckHints(llvm::raw_ostream &OS) const;
+
+public:
+ BottleneckAnalysis(const llvm::MCSchedModel &Model);
+
+ void onCycleEnd() override {
+ ++TotalCycles;
+ if (PressureIncreasedBecauseOfResources ||
+ PressureIncreasedBecauseOfDataDependencies) {
+ ++BPI.PressureIncreaseCycles;
+ if (PressureIncreasedBecauseOfDataDependencies)
+ ++BPI.DataDependencyCycles;
+ PressureIncreasedBecauseOfResources = false;
+ PressureIncreasedBecauseOfDataDependencies = false;
+ }
+ }
+
+ void onEvent(const HWStallEvent &Event) override { SeenStallCycles = true; }
+
+ void onEvent(const HWPressureEvent &Event) override;
+
+ void printView(llvm::raw_ostream &OS) const override;
+};
+
+} // namespace mca
+} // namespace llvm
+
+#endif
Modified: llvm/trunk/tools/llvm-mca/Views/SummaryView.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Views/SummaryView.cpp?rev=358554&r1=358553&r2=358554&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Views/SummaryView.cpp (original)
+++ llvm/trunk/tools/llvm-mca/Views/SummaryView.cpp Tue Apr 16 23:02:05 2019
@@ -23,18 +23,13 @@ namespace mca {
#define DEBUG_TYPE "llvm-mca"
SummaryView::SummaryView(const MCSchedModel &Model, ArrayRef<MCInst> S,
- unsigned Width, bool EmitBottleneckAnalysis)
+ unsigned Width)
: SM(Model), Source(S), DispatchWidth(Width?Width: Model.IssueWidth),
LastInstructionIdx(0),
- TotalCycles(0), NumMicroOps(0), BPI({0, 0, 0, 0, 0}),
- ResourcePressureDistribution(Model.getNumProcResourceKinds(), 0),
+ TotalCycles(0), NumMicroOps(0),
ProcResourceUsage(Model.getNumProcResourceKinds(), 0),
ProcResourceMasks(Model.getNumProcResourceKinds()),
- ResIdx2ProcResID(Model.getNumProcResourceKinds(), 0),
- PressureIncreasedBecauseOfResources(false),
- PressureIncreasedBecauseOfDataDependencies(false),
- SeenStallCycles(false),
- ShouldEmitBottleneckAnalysis(EmitBottleneckAnalysis) {
+ ResIdx2ProcResID(Model.getNumProcResourceKinds(), 0) {
computeProcResourceMasks(SM, ProcResourceMasks);
for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
unsigned Index = getResourceStateIndex(ProcResourceMasks[I]);
@@ -67,100 +62,6 @@ void SummaryView::onEvent(const HWInstru
}
}
-void SummaryView::onEvent(const HWPressureEvent &Event) {
- assert(Event.Reason != HWPressureEvent::INVALID &&
- "Unexpected invalid event!");
-
- switch (Event.Reason) {
- default:
- break;
-
- case HWPressureEvent::RESOURCES: {
- PressureIncreasedBecauseOfResources = true;
- ++BPI.ResourcePressureCycles;
- uint64_t ResourceMask = Event.ResourceMask;
- while (ResourceMask) {
- uint64_t Current = ResourceMask & (-ResourceMask);
- unsigned Index = getResourceStateIndex(Current);
- unsigned ProcResID = ResIdx2ProcResID[Index];
- const MCProcResourceDesc &PRDesc = *SM.getProcResource(ProcResID);
- if (!PRDesc.SubUnitsIdxBegin) {
- ResourcePressureDistribution[Index]++;
- ResourceMask ^= Current;
- continue;
- }
-
- for (unsigned I = 0, E = PRDesc.NumUnits; I < E; ++I) {
- unsigned OtherProcResID = PRDesc.SubUnitsIdxBegin[I];
- unsigned OtherMask = ProcResourceMasks[OtherProcResID];
- ResourcePressureDistribution[getResourceStateIndex(OtherMask)]++;
- }
-
- ResourceMask ^= Current;
- }
- }
-
- break;
- case HWPressureEvent::REGISTER_DEPS:
- PressureIncreasedBecauseOfDataDependencies = true;
- ++BPI.RegisterDependencyCycles;
- break;
- case HWPressureEvent::MEMORY_DEPS:
- PressureIncreasedBecauseOfDataDependencies = true;
- ++BPI.MemoryDependencyCycles;
- break;
- }
-}
-
-void SummaryView::printBottleneckHints(raw_ostream &OS) const {
- if (!SeenStallCycles || !BPI.PressureIncreaseCycles) {
- OS << "\nNo resource or data dependency bottlenecks discovered.\n";
- return;
- }
-
- double PressurePerCycle =
- (double)BPI.PressureIncreaseCycles * 100 / TotalCycles;
- double ResourcePressurePerCycle =
- (double)BPI.ResourcePressureCycles * 100 / TotalCycles;
- double DDPerCycle = (double)BPI.DataDependencyCycles * 100 / TotalCycles;
- double RegDepPressurePerCycle =
- (double)BPI.RegisterDependencyCycles * 100 / TotalCycles;
- double MemDepPressurePerCycle =
- (double)BPI.MemoryDependencyCycles * 100 / TotalCycles;
-
- OS << "\nCycles with backend pressure increase [ "
- << format("%.2f", floor((PressurePerCycle * 100) + 0.5) / 100) << "% ]";
-
- OS << "\nThroughput Bottlenecks: "
- << "\n Resource Pressure [ "
- << format("%.2f", floor((ResourcePressurePerCycle * 100) + 0.5) / 100)
- << "% ]";
-
- if (BPI.PressureIncreaseCycles) {
- for (unsigned I = 0, E = ResourcePressureDistribution.size(); I < E; ++I) {
- if (ResourcePressureDistribution[I]) {
- double Frequency =
- (double)ResourcePressureDistribution[I] * 100 / TotalCycles;
- unsigned Index = ResIdx2ProcResID[getResourceStateIndex(1ULL << I)];
- const MCProcResourceDesc &PRDesc = *SM.getProcResource(Index);
- OS << "\n - " << PRDesc.Name << " [ "
- << format("%.2f", floor((Frequency * 100) + 0.5) / 100) << "% ]";
- }
- }
- }
-
- OS << "\n Data Dependencies: [ "
- << format("%.2f", floor((DDPerCycle * 100) + 0.5) / 100) << "% ]";
-
- OS << "\n - Register Dependencies [ "
- << format("%.2f", floor((RegDepPressurePerCycle * 100) + 0.5) / 100)
- << "% ]";
-
- OS << "\n - Memory Dependencies [ "
- << format("%.2f", floor((MemDepPressurePerCycle * 100) + 0.5) / 100)
- << "% ]\n\n";
-}
-
void SummaryView::printView(raw_ostream &OS) const {
unsigned Instructions = Source.size();
unsigned Iterations = (LastInstructionIdx / Instructions) + 1;
@@ -185,10 +86,9 @@ void SummaryView::printView(raw_ostream
TempStream << "\nBlock RThroughput: "
<< format("%.1f", floor((BlockRThroughput * 10) + 0.5) / 10)
<< '\n';
- if (ShouldEmitBottleneckAnalysis)
- printBottleneckHints(TempStream);
TempStream.flush();
OS << Buffer;
}
+
} // namespace mca.
} // namespace llvm
Modified: llvm/trunk/tools/llvm-mca/Views/SummaryView.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/Views/SummaryView.h?rev=358554&r1=358553&r2=358554&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/Views/SummaryView.h (original)
+++ llvm/trunk/tools/llvm-mca/Views/SummaryView.h Tue Apr 16 23:02:05 2019
@@ -46,24 +46,6 @@ class SummaryView : public View {
// The total number of micro opcodes contributed by a block of instructions.
unsigned NumMicroOps;
- struct BackPressureInfo {
- // Cycles where backpressure increased.
- unsigned PressureIncreaseCycles;
- // Cycles where backpressure increased because of pipeline pressure.
- unsigned ResourcePressureCycles;
- // Cycles where backpressure increased because of data dependencies.
- unsigned DataDependencyCycles;
- // Cycles where backpressure increased because of register dependencies.
- unsigned RegisterDependencyCycles;
- // Cycles where backpressure increased because of memory dependencies.
- unsigned MemoryDependencyCycles;
- };
- BackPressureInfo BPI;
-
- // Resource pressure distribution. There is an element for every processor
- // resource declared by the scheduling model. Quantities are number of cycles.
- llvm::SmallVector<unsigned, 8> ResourcePressureDistribution;
-
// For each processor resource, this vector stores the cumulative number of
// resource cycles consumed by the analyzed code block.
llvm::SmallVector<unsigned, 8> ProcResourceUsage;
@@ -77,49 +59,21 @@ class SummaryView : public View {
// Used to map resource indices to actual processor resource IDs.
llvm::SmallVector<unsigned, 8> ResIdx2ProcResID;
- // True if resource pressure events were notified during this cycle.
- bool PressureIncreasedBecauseOfResources;
- bool PressureIncreasedBecauseOfDataDependencies;
-
- // True if throughput was affected by dispatch stalls.
- bool SeenStallCycles;
-
- // True if the bottleneck analysis should be displayed.
- bool ShouldEmitBottleneckAnalysis;
-
// Compute the reciprocal throughput for the analyzed code block.
// The reciprocal block throughput is computed as the MAX between:
// - NumMicroOps / DispatchWidth
// - Total Resource Cycles / #Units (for every resource consumed).
double getBlockRThroughput() const;
- // Prints a bottleneck message to OS.
- void printBottleneckHints(llvm::raw_ostream &OS) const;
-
public:
SummaryView(const llvm::MCSchedModel &Model, llvm::ArrayRef<llvm::MCInst> S,
- unsigned Width, bool EmitBottleneckAnalysis);
+ unsigned Width);
- void onCycleEnd() override {
- ++TotalCycles;
- if (PressureIncreasedBecauseOfResources ||
- PressureIncreasedBecauseOfDataDependencies) {
- ++BPI.PressureIncreaseCycles;
- if (PressureIncreasedBecauseOfDataDependencies)
- ++BPI.DataDependencyCycles;
- PressureIncreasedBecauseOfResources = false;
- PressureIncreasedBecauseOfDataDependencies = false;
- }
- }
+ void onCycleEnd() override { ++TotalCycles; }
void onEvent(const HWInstructionEvent &Event) override;
- void onEvent(const HWStallEvent &Event) override {
- SeenStallCycles = true;
- }
-
- void onEvent(const HWPressureEvent &Event) override;
-
void printView(llvm::raw_ostream &OS) const override;
};
+
} // namespace mca
} // namespace llvm
Modified: llvm/trunk/tools/llvm-mca/llvm-mca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/llvm-mca.cpp?rev=358554&r1=358553&r2=358554&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/llvm-mca.cpp (original)
+++ llvm/trunk/tools/llvm-mca/llvm-mca.cpp Tue Apr 16 23:02:05 2019
@@ -23,6 +23,7 @@
#include "CodeRegion.h"
#include "CodeRegionGenerator.h"
#include "PipelinePrinter.h"
+#include "Views/BottleneckAnalysis.h"
#include "Views/DispatchStatistics.h"
#include "Views/InstructionInfoView.h"
#include "Views/RegisterFileStatistics.h"
@@ -477,7 +478,10 @@ int main(int argc, char **argv) {
if (PrintSummaryView)
Printer.addView(llvm::make_unique<mca::SummaryView>(
- SM, Insts, DispatchWidth, EnableBottleneckAnalysis));
+ SM, Insts, DispatchWidth));
+
+ if (EnableBottleneckAnalysis)
+ Printer.addView(llvm::make_unique<mca::BottleneckAnalysis>(SM));
if (PrintInstructionInfoView)
Printer.addView(
More information about the llvm-commits
mailing list