1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 03:53:04 +02:00
llvm-mirror/tools/llvm-mca/ResourcePressureView.cpp
Matt Davis 3e43e69679 [llvm-mca] Avoid exposing index values in the MCA interfaces.
Summary:
This patch eliminates many places where we originally needed to  pass index
values to represent an instruction.  The index is still used as a key, in various parts of 
MCA.  I'm  not comfortable eliminating the index just yet.    By burying the index in
the instruction, we can avoid exposing that value in many places.

Eventually, we should consider removing the Instructions list in the Backend 
all together,   it's only used to hold and reclaim the memory for the allocated 
Instruction instances.  Instead we could pass around a smart pointer.  But that's
a separate discussion/patch.

Reviewers: andreadb, courbet, RKSimon

Reviewed By: andreadb

Subscribers: javed.absar, tschuett, gbedwell, llvm-commits

Differential Revision: https://reviews.llvm.org/D46367

llvm-svn: 331660
2018-05-07 18:29:15 +00:00

163 lines
5.2 KiB
C++

//===--------------------- ResourcePressureView.cpp -------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
///
/// This file implements methods in the ResourcePressureView interface.
///
//===----------------------------------------------------------------------===//
#include "ResourcePressureView.h"
#include "llvm/Support/raw_ostream.h"
namespace mca {
using namespace llvm;
void ResourcePressureView::initialize() {
// Populate the map of resource descriptors.
unsigned R2VIndex = 0;
const MCSchedModel &SM = STI.getSchedModel();
for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) {
const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
unsigned NumUnits = ProcResource.NumUnits;
// Skip groups and invalid resources with zero units.
if (ProcResource.SubUnitsIdxBegin || !NumUnits)
continue;
Resource2VecIndex.insert(std::pair<unsigned, unsigned>(I, R2VIndex));
R2VIndex += ProcResource.NumUnits;
}
NumResourceUnits = R2VIndex;
ResourceUsage.resize(NumResourceUnits * (Source.size() + 1));
std::fill(ResourceUsage.begin(), ResourceUsage.end(), 0.0);
}
void ResourcePressureView::onInstructionEvent(const HWInstructionEvent &Event) {
// We're only interested in Issue events.
if (Event.Type != HWInstructionEvent::Issued)
return;
const auto &IssueEvent = static_cast<const HWInstructionIssuedEvent &>(Event);
const unsigned SourceIdx = Event.IR.getSourceIndex() % Source.size();
for (const std::pair<ResourceRef, double> &Use : IssueEvent.UsedResources) {
const ResourceRef &RR = Use.first;
assert(Resource2VecIndex.find(RR.first) != Resource2VecIndex.end());
unsigned R2VIndex = Resource2VecIndex[RR.first];
R2VIndex += countTrailingZeros(RR.second);
ResourceUsage[R2VIndex + NumResourceUnits * SourceIdx] += Use.second;
ResourceUsage[R2VIndex + NumResourceUnits * Source.size()] += Use.second;
}
}
static void printColumnNames(raw_string_ostream &OS, const MCSchedModel &SM) {
for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
I < E; ++I) {
const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
unsigned NumUnits = ProcResource.NumUnits;
// Skip groups and invalid resources with zero units.
if (ProcResource.SubUnitsIdxBegin || !NumUnits)
continue;
if (NumUnits == 1) {
OS << '[' << ResourceIndex << ']';
if (ResourceIndex < 10)
OS << " ";
else
OS << " ";
} else {
for (unsigned J = 0; J < NumUnits; ++J) {
OS << "[" << ResourceIndex << '.' << J << ']';
if (ResourceIndex < 10)
OS << " ";
else
OS << ' ';
}
}
ResourceIndex++;
}
}
static void printResourcePressure(raw_string_ostream &OS, double Pressure) {
if (!Pressure || Pressure < 0.005) {
OS << " - ";
return;
}
// Round to the value to the nearest hundredth and then print it.
OS << format("%.2f", floor((Pressure * 100) + 0.5)/100);
if (Pressure < 10.0)
OS << " ";
else if (Pressure < 100.0)
OS << " ";
else
OS << ' ';
}
void ResourcePressureView::printResourcePressurePerIteration(
raw_ostream &OS, unsigned Executions) const {
std::string Buffer;
raw_string_ostream TempStream(Buffer);
TempStream << "\n\nResources:\n";
const MCSchedModel &SM = STI.getSchedModel();
for (unsigned I = 1, ResourceIndex = 0, E = SM.getNumProcResourceKinds();
I < E; ++I) {
const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
unsigned NumUnits = ProcResource.NumUnits;
// Skip groups and invalid resources with zero units.
if (ProcResource.SubUnitsIdxBegin || !NumUnits)
continue;
for (unsigned J = 0; J < NumUnits; ++J) {
TempStream << '[' << ResourceIndex;
if (NumUnits > 1)
TempStream << '.' << J;
TempStream << "] - " << ProcResource.Name << '\n';
}
ResourceIndex++;
}
TempStream << "\n\nResource pressure per iteration:\n";
printColumnNames(TempStream, SM);
TempStream << '\n';
for (unsigned I = 0, E = NumResourceUnits; I < E; ++I) {
double Usage = ResourceUsage[I + Source.size() * E];
printResourcePressure(TempStream, Usage / Executions);
}
TempStream.flush();
OS << Buffer;
}
void ResourcePressureView::printResourcePressurePerInstruction(
raw_ostream &OS, unsigned Executions) const {
std::string Buffer;
raw_string_ostream TempStream(Buffer);
TempStream << "\n\nResource pressure by instruction:\n";
printColumnNames(TempStream, STI.getSchedModel());
TempStream << "\tInstructions:\n";
for (unsigned I = 0, E = Source.size(); I < E; ++I) {
for (unsigned J = 0; J < NumResourceUnits; ++J) {
double Usage = ResourceUsage[J + I * NumResourceUnits];
printResourcePressure(TempStream, Usage / Executions);
}
MCIP.printInst(&Source.getMCInstFromIndex(I), TempStream, "", STI);
TempStream << '\n';
TempStream.flush();
OS << Buffer;
Buffer = "";
}
}
} // namespace mca