109 lines · cpp
1//===--- llvm-ctxprof-util - utilities for ctxprof --------------*- 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-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10///11/// Utilities for manipulating contextual profiles12///13//===----------------------------------------------------------------------===//14 15#include "llvm/IR/GlobalValue.h"16#include "llvm/ProfileData/PGOCtxProfReader.h"17#include "llvm/ProfileData/PGOCtxProfWriter.h"18#include "llvm/Support/CommandLine.h"19#include "llvm/Support/Error.h"20#include "llvm/Support/ErrorHandling.h"21#include "llvm/Support/MemoryBuffer.h"22#include "llvm/Support/raw_ostream.h"23 24using namespace llvm;25 26static cl::SubCommand FromYAML("fromYAML", "Convert from yaml");27static cl::SubCommand ToYAML("toYAML", "Convert to yaml");28 29static cl::opt<std::string> InputFilename(30 "input", cl::value_desc("input"), cl::init("-"),31 cl::desc(32 "Input file. The format is an array of contexts.\n"33 "Each context is a dictionary with the following keys:\n"34 "'Guid', mandatory. The value is a 64-bit integer.\n"35 "'Counters', mandatory. An array of 32-bit ints. These are the "36 "counter values.\n"37 "'Contexts', optional. An array containing arrays of contexts. The "38 "context array at a position 'i' is the set of callees at that "39 "callsite index. Use an empty array to indicate no callees."),40 cl::sub(FromYAML), cl::sub(ToYAML));41 42static cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),43 cl::init("-"),44 cl::desc("Output file"),45 cl::sub(FromYAML), cl::sub(ToYAML));46 47namespace {48// Save the bitstream profile from the JSON representation.49Error convertFromYaml() {50 auto BufOrError =51 MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true);52 if (!BufOrError)53 return createFileError(InputFilename, BufOrError.getError());54 55 std::error_code EC;56 // Using a fd_ostream instead of a fd_stream. The latter would be more57 // efficient as the bitstream writer supports incremental flush to it, but the58 // json scenario is for test, and file size scalability doesn't really concern59 // us.60 raw_fd_ostream Out(OutputFilename, EC);61 if (EC)62 return createStringError(EC, "failed to open output");63 64 return llvm::createCtxProfFromYAML(BufOrError.get()->getBuffer(), Out);65}66 67Error convertToYaml() {68 auto BufOrError = MemoryBuffer::getFileOrSTDIN(InputFilename);69 if (!BufOrError)70 return createFileError(InputFilename, BufOrError.getError());71 72 std::error_code EC;73 raw_fd_ostream Out(OutputFilename, EC);74 if (EC)75 return createStringError(EC, "failed to open output");76 PGOCtxProfileReader Reader(BufOrError.get()->getBuffer());77 auto Prof = Reader.loadProfiles();78 if (!Prof)79 return Prof.takeError();80 llvm::convertCtxProfToYaml(Out, *Prof);81 Out << "\n";82 return Error::success();83}84} // namespace85 86int main(int argc, const char **argv) {87 cl::ParseCommandLineOptions(argc, argv, "LLVM Contextual Profile Utils\n");88 ExitOnError ExitOnErr("llvm-ctxprof-util: ");89 auto HandleErr = [&](Error E) -> int {90 if (E) {91 handleAllErrors(std::move(E), [&](const ErrorInfoBase &E) {92 E.log(errs());93 errs() << "\n";94 });95 return 1;96 }97 return 0;98 };99 100 if (FromYAML)101 return HandleErr(convertFromYaml());102 103 if (ToYAML)104 return HandleErr(convertToYaml());105 106 cl::PrintHelpMessage();107 return 1;108}109