1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00
llvm-mirror/tools/llvm-mca/PipelinePrinter.cpp
Andrea Di Biagio 00b6a7730b [llvm-mca][JSON] Teach the PipelinePrinter how to deal with anonymous code regions (PR51008)
This patch addresses the last remaining problems reported in PR51008.

Previous fixes for PR51008 worked under the wrong assumption that code regions
are always named (except maybe for the default region, which was automatically
named "main").

In reality, it is quite common for users to declare multiple anonymous regions.
So we cannot really use the region name as the key string of a JSON object.  In
practice, code region names are completely optional.

Using "main" for the default region was also problematic because there can be
another region with that same name.

This patch fixes these issues by introducing a json::array of regions.  Each
region has a "Name" field, which would default to the empty string for anonymous
regions.

Added a few more tests to verify that the JSON file format is still valid, and
that multiple anonymous regions all appear in the final output.
2021-07-10 13:57:52 +01:00

99 lines
2.8 KiB
C++

//===--------------------- PipelinePrinter.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 PipelinePrinter interface.
///
//===----------------------------------------------------------------------===//
#include "PipelinePrinter.h"
#include "CodeRegion.h"
#include "Views/InstructionView.h"
#include "Views/View.h"
namespace llvm {
namespace mca {
void PipelinePrinter::printRegionHeader(llvm::raw_ostream &OS) const {
StringRef RegionName;
if (!Region.getDescription().empty())
RegionName = Region.getDescription();
OS << "\n[" << RegionIdx << "] Code Region";
if (!RegionName.empty())
OS << " - " << RegionName;
OS << "\n\n";
}
json::Object PipelinePrinter::getJSONReportRegion() const {
json::Object JO;
StringRef RegionName = "";
if (!Region.getDescription().empty())
RegionName = Region.getDescription();
JO.try_emplace("Name", RegionName);
for (const auto &V : Views)
if (V->isSerializable())
JO.try_emplace(V->getNameAsString().str(), V->toJSON());
return JO;
}
json::Object PipelinePrinter::getJSONTargetInfo() const {
json::Array Resources;
const MCSchedModel &SM = STI.getSchedModel();
StringRef MCPU = STI.getCPU();
for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) {
const MCProcResourceDesc &ProcResource = *SM.getProcResource(I);
unsigned NumUnits = ProcResource.NumUnits;
if (ProcResource.SubUnitsIdxBegin || !NumUnits)
continue;
for (unsigned J = 0; J < NumUnits; ++J) {
std::string ResourceName = ProcResource.Name;
if (NumUnits > 1) {
ResourceName += ".";
ResourceName += J;
}
Resources.push_back(ResourceName);
}
}
return json::Object({{"CPUName", MCPU}, {"Resources", std::move(Resources)}});
}
void PipelinePrinter::printReport(json::Object &JO) const {
if (!RegionIdx)
JO.try_emplace("TargetInfo", getJSONTargetInfo());
if (!RegionIdx) {
// Construct an array of regions.
JO.try_emplace("CodeRegions", json::Array());
}
json::Array *Regions = JO.getArray("CodeRegions");
assert(Regions && "This array must exist!");
Regions->push_back(getJSONReportRegion());
}
void PipelinePrinter::printReport(llvm::raw_ostream &OS) const {
// Don't print the header of this region if it is the default region, and if
// it doesn't have an end location.
if (Region.startLoc().isValid() || Region.endLoc().isValid())
printRegionHeader(OS);
for (const auto &V : Views)
V->printView(OS);
}
} // namespace mca
} // namespace llvm