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