1 //===--------------------- PipelinePrinter.cpp ------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// 10 /// This file implements the PipelinePrinter interface. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "PipelinePrinter.h" 15 #include "CodeRegion.h" 16 #include "Views/InstructionView.h" 17 18 namespace llvm { 19 namespace mca { 20 21 void PipelinePrinter::printRegionHeader(llvm::raw_ostream &OS) const { 22 StringRef RegionName; 23 if (!Region.getDescription().empty()) 24 RegionName = Region.getDescription(); 25 26 OS << "\n[" << RegionIdx << "] Code Region"; 27 if (!RegionName.empty()) 28 OS << " - " << RegionName; 29 OS << "\n\n"; 30 } 31 32 json::Object PipelinePrinter::getJSONReportRegion() const { 33 json::Object JO; 34 35 StringRef RegionName = ""; 36 if (!Region.getDescription().empty()) 37 RegionName = Region.getDescription(); 38 39 JO.try_emplace("Name", RegionName); 40 for (const auto &V : Views) 41 if (V->isSerializable()) 42 JO.try_emplace(V->getNameAsString().str(), V->toJSON()); 43 44 return JO; 45 } 46 47 json::Object PipelinePrinter::getJSONSimulationParameters() const { 48 json::Object SimParameters({{"-mcpu", STI.getCPU()}, 49 {"-mtriple", STI.getTargetTriple().getTriple()}, 50 {"-march", STI.getTargetTriple().getArchName()}}); 51 52 const MCSchedModel &SM = STI.getSchedModel(); 53 if (!SM.isOutOfOrder()) 54 return SimParameters; 55 56 if (PO.RegisterFileSize) 57 SimParameters.try_emplace("-register-file-size", PO.RegisterFileSize); 58 59 if (!PO.AssumeNoAlias) 60 SimParameters.try_emplace("-noalias", PO.AssumeNoAlias); 61 62 if (PO.DecodersThroughput) 63 SimParameters.try_emplace("-decoder-throughput", PO.DecodersThroughput); 64 65 if (PO.MicroOpQueueSize) 66 SimParameters.try_emplace("-micro-op-queue-size", PO.MicroOpQueueSize); 67 68 if (PO.DispatchWidth) 69 SimParameters.try_emplace("-dispatch", PO.DispatchWidth); 70 71 if (PO.LoadQueueSize) 72 SimParameters.try_emplace("-lqueue", PO.LoadQueueSize); 73 74 if (PO.StoreQueueSize) 75 SimParameters.try_emplace("-squeue", PO.StoreQueueSize); 76 77 return SimParameters; 78 } 79 80 json::Object PipelinePrinter::getJSONTargetInfo() const { 81 json::Array Resources; 82 const MCSchedModel &SM = STI.getSchedModel(); 83 StringRef MCPU = STI.getCPU(); 84 85 for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { 86 const MCProcResourceDesc &ProcResource = *SM.getProcResource(I); 87 unsigned NumUnits = ProcResource.NumUnits; 88 if (ProcResource.SubUnitsIdxBegin || !NumUnits) 89 continue; 90 91 for (unsigned J = 0; J < NumUnits; ++J) { 92 std::string ResourceName = ProcResource.Name; 93 if (NumUnits > 1) { 94 ResourceName += "."; 95 ResourceName += J; 96 } 97 98 Resources.push_back(ResourceName); 99 } 100 } 101 102 return json::Object({{"CPUName", MCPU}, {"Resources", std::move(Resources)}}); 103 } 104 105 void PipelinePrinter::printReport(json::Object &JO) const { 106 if (!RegionIdx) { 107 JO.try_emplace("TargetInfo", getJSONTargetInfo()); 108 JO.try_emplace("SimulationParameters", getJSONSimulationParameters()); 109 // Construct an array of regions. 110 JO.try_emplace("CodeRegions", json::Array()); 111 } 112 113 json::Array *Regions = JO.getArray("CodeRegions"); 114 assert(Regions && "This array must exist!"); 115 Regions->push_back(getJSONReportRegion()); 116 } 117 118 void PipelinePrinter::printReport(llvm::raw_ostream &OS) const { 119 // Don't print the header of this region if it is the default region, and if 120 // it doesn't have an end location. 121 if (Region.startLoc().isValid() || Region.endLoc().isValid()) 122 printRegionHeader(OS); 123 124 for (const auto &V : Views) 125 V->printView(OS); 126 } 127 128 } // namespace mca 129 } // namespace llvm 130