brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.0 KiB · d08f47f Raw
160 lines · cpp
1//===- RemarkCount.cpp ----------------------------------------------------===//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-exception6//7//===----------------------------------------------------------------------===//8//9// Count remarks using `instruction-count` for asm-printer remarks and10// `annotation-count` for annotation-remarks11//12//===----------------------------------------------------------------------===//13#include "RemarkUtilHelpers.h"14#include "RemarkUtilRegistry.h"15 16using namespace llvm;17using namespace remarks;18using namespace llvm::remarkutil;19 20static cl::SubCommand InstructionCount(21    "instruction-count",22    "Function instruction count information (requires asm-printer remarks)");23static cl::SubCommand24    AnnotationCount("annotation-count",25                    "Collect count information from annotation remarks (uses "26                    "AnnotationRemarksPass)");27 28namespace instructioncount {29INPUT_FORMAT_COMMAND_LINE_OPTIONS(InstructionCount)30INPUT_OUTPUT_COMMAND_LINE_OPTIONS(InstructionCount)31DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(InstructionCount)32} // namespace instructioncount33 34namespace annotationcount {35INPUT_FORMAT_COMMAND_LINE_OPTIONS(AnnotationCount)36static cl::opt<std::string> AnnotationTypeToCollect(37    "annotation-type", cl::desc("annotation-type remark to collect count for"),38    cl::sub(AnnotationCount));39INPUT_OUTPUT_COMMAND_LINE_OPTIONS(AnnotationCount)40DEBUG_LOC_INFO_COMMAND_LINE_OPTIONS(AnnotationCount)41} // namespace annotationcount42 43static bool shouldSkipRemark(bool UseDebugLoc, Remark &Remark) {44  return UseDebugLoc && !Remark.Loc.has_value();45}46 47namespace instructioncount {48/// Outputs all instruction count remarks in the file as a CSV.49/// \returns Error::success() on success, and an Error otherwise.50static Error tryInstructionCount() {51  // Create the output buffer.52  auto MaybeOF = getOutputFileWithFlags(OutputFileName,53                                        /*Flags = */ sys::fs::OF_TextWithCRLF);54  if (!MaybeOF)55    return MaybeOF.takeError();56  auto OF = std::move(*MaybeOF);57  // Create a parser for the user-specified input format.58  auto MaybeBuf = getInputMemoryBuffer(InputFileName);59  if (!MaybeBuf)60    return MaybeBuf.takeError();61  auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());62  if (!MaybeParser)63    return MaybeParser.takeError();64  // Emit CSV header.65  if (UseDebugLoc)66    OF->os() << "Source,";67  OF->os() << "Function,InstructionCount\n";68  // Parse all remarks. Whenever we see an instruction count remark, output69  // the file name and the number of instructions.70  auto &Parser = **MaybeParser;71  auto MaybeRemark = Parser.next();72  for (; MaybeRemark; MaybeRemark = Parser.next()) {73    auto &Remark = **MaybeRemark;74    if (Remark.RemarkName != "InstructionCount")75      continue;76    if (shouldSkipRemark(UseDebugLoc, Remark))77      continue;78    auto *InstrCountArg = find_if(Remark.Args, [](const Argument &Arg) {79      return Arg.Key == "NumInstructions";80    });81    assert(InstrCountArg != Remark.Args.end() &&82           "Expected instruction count remarks to have a NumInstructions key?");83    if (UseDebugLoc) {84      std::string Loc = Remark.Loc->SourceFilePath.str() + ":" +85                        std::to_string(Remark.Loc->SourceLine) + +":" +86                        std::to_string(Remark.Loc->SourceColumn);87      OF->os() << Loc << ",";88    }89    OF->os() << Remark.FunctionName << "," << InstrCountArg->Val << "\n";90  }91  auto E = MaybeRemark.takeError();92  if (!E.isA<EndOfFileError>())93    return E;94  consumeError(std::move(E));95  OF->keep();96  return Error::success();97}98} // namespace instructioncount99 100namespace annotationcount {101static Error tryAnnotationCount() {102  // Create the output buffer.103  auto MaybeOF = getOutputFileWithFlags(OutputFileName,104                                        /*Flags = */ sys::fs::OF_TextWithCRLF);105  if (!MaybeOF)106    return MaybeOF.takeError();107  auto OF = std::move(*MaybeOF);108  // Create a parser for the user-specified input format.109  auto MaybeBuf = getInputMemoryBuffer(InputFileName);110  if (!MaybeBuf)111    return MaybeBuf.takeError();112  auto MaybeParser = createRemarkParser(InputFormat, (*MaybeBuf)->getBuffer());113  if (!MaybeParser)114    return MaybeParser.takeError();115  // Emit CSV header.116  if (UseDebugLoc)117    OF->os() << "Source,";118  OF->os() << "Function,Count\n";119  // Parse all remarks. When we see the specified remark collect the count120  // information.121  auto &Parser = **MaybeParser;122  auto MaybeRemark = Parser.next();123  for (; MaybeRemark; MaybeRemark = Parser.next()) {124    auto &Remark = **MaybeRemark;125    if (Remark.RemarkName != "AnnotationSummary")126      continue;127    if (shouldSkipRemark(UseDebugLoc, Remark))128      continue;129    auto *RemarkNameArg = find_if(Remark.Args, [](const Argument &Arg) {130      return Arg.Key == "type" && Arg.Val == AnnotationTypeToCollect;131    });132    if (RemarkNameArg == Remark.Args.end())133      continue;134    auto *CountArg = find_if(135        Remark.Args, [](const Argument &Arg) { return Arg.Key == "count"; });136    assert(CountArg != Remark.Args.end() &&137           "Expected annotation-type remark to have a count key?");138    if (UseDebugLoc) {139      std::string Loc = Remark.Loc->SourceFilePath.str() + ":" +140                        std::to_string(Remark.Loc->SourceLine) + +":" +141                        std::to_string(Remark.Loc->SourceColumn);142      OF->os() << Loc << ",";143    }144    OF->os() << Remark.FunctionName << "," << CountArg->Val << "\n";145  }146  auto E = MaybeRemark.takeError();147  if (!E.isA<EndOfFileError>())148    return E;149  consumeError(std::move(E));150  OF->keep();151  return Error::success();152}153} // namespace annotationcount154 155static CommandRegistration156    InstructionCountReg(&InstructionCount,157                        instructioncount::tryInstructionCount);158static CommandRegistration Yaml2Bitstream(&AnnotationCount,159                                          annotationcount::tryAnnotationCount);160