mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-21 03:53:04 +02:00
3e43e69679
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
163 lines
5.2 KiB
C++
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
|