xref: /llvm-project/llvm/tools/llvm-ctxprof-util/llvm-ctxprof-util.cpp (revision c70f246251fb62b8ecf94f2365688cd361adec97)
137f42cfbSMircea Trofin //===--- llvm-ctxprof-util - utilities for ctxprof --------------*- C++ -*-===//
2a737b870SMircea Trofin //
3a737b870SMircea Trofin // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4a737b870SMircea Trofin // See https://llvm.org/LICENSE.txt for license information.
5a737b870SMircea Trofin // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6a737b870SMircea Trofin //
7a737b870SMircea Trofin //===----------------------------------------------------------------------===//
8a737b870SMircea Trofin ///
9a737b870SMircea Trofin /// \file
10a737b870SMircea Trofin ///
1137f42cfbSMircea Trofin /// Utilities for manipulating contextual profiles
12a737b870SMircea Trofin ///
13a737b870SMircea Trofin //===----------------------------------------------------------------------===//
14a737b870SMircea Trofin 
15a737b870SMircea Trofin #include "llvm/IR/GlobalValue.h"
16*c70f2462SMircea Trofin #include "llvm/ProfileData/PGOCtxProfReader.h"
17a737b870SMircea Trofin #include "llvm/ProfileData/PGOCtxProfWriter.h"
18a737b870SMircea Trofin #include "llvm/Support/CommandLine.h"
19a737b870SMircea Trofin #include "llvm/Support/Error.h"
20a737b870SMircea Trofin #include "llvm/Support/ErrorHandling.h"
21a737b870SMircea Trofin #include "llvm/Support/MemoryBuffer.h"
22a737b870SMircea Trofin #include "llvm/Support/raw_ostream.h"
23a737b870SMircea Trofin 
24a737b870SMircea Trofin using namespace llvm;
25a737b870SMircea Trofin 
2663293558SMircea Trofin static cl::SubCommand FromYAML("fromYAML", "Convert from yaml");
27*c70f2462SMircea Trofin static cl::SubCommand ToYAML("toYAML", "Convert to yaml");
28a737b870SMircea Trofin 
29a737b870SMircea Trofin static cl::opt<std::string> InputFilename(
30a737b870SMircea Trofin     "input", cl::value_desc("input"), cl::init("-"),
31a737b870SMircea Trofin     cl::desc(
32a737b870SMircea Trofin         "Input file. The format is an array of contexts.\n"
33a737b870SMircea Trofin         "Each context is a dictionary with the following keys:\n"
34a737b870SMircea Trofin         "'Guid', mandatory. The value is a 64-bit integer.\n"
35a737b870SMircea Trofin         "'Counters', mandatory. An array of 32-bit ints. These are the "
36a737b870SMircea Trofin         "counter values.\n"
37a737b870SMircea Trofin         "'Contexts', optional. An array containing arrays of contexts. The "
38a737b870SMircea Trofin         "context array at a position 'i' is the set of callees at that "
39a737b870SMircea Trofin         "callsite index. Use an empty array to indicate no callees."),
40*c70f2462SMircea Trofin     cl::sub(FromYAML), cl::sub(ToYAML));
41a737b870SMircea Trofin 
42a737b870SMircea Trofin static cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
43a737b870SMircea Trofin                                            cl::init("-"),
44a737b870SMircea Trofin                                            cl::desc("Output file"),
45*c70f2462SMircea Trofin                                            cl::sub(FromYAML), cl::sub(ToYAML));
46a737b870SMircea Trofin 
47*c70f2462SMircea Trofin namespace {
48a737b870SMircea Trofin // Save the bitstream profile from the JSON representation.
49*c70f2462SMircea Trofin Error convertFromYaml() {
500de1e3e7SZibi Sarbinowski   auto BufOrError =
510de1e3e7SZibi Sarbinowski       MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true);
52a737b870SMircea Trofin   if (!BufOrError)
53a737b870SMircea Trofin     return createFileError(InputFilename, BufOrError.getError());
54a737b870SMircea Trofin 
55a737b870SMircea Trofin   std::error_code EC;
561022323cSMircea Trofin   // Using a fd_ostream instead of a fd_stream. The latter would be more
571022323cSMircea Trofin   // efficient as the bitstream writer supports incremental flush to it, but the
581022323cSMircea Trofin   // json scenario is for test, and file size scalability doesn't really concern
591022323cSMircea Trofin   // us.
601022323cSMircea Trofin   raw_fd_ostream Out(OutputFilename, EC);
61a737b870SMircea Trofin   if (EC)
62a737b870SMircea Trofin     return createStringError(EC, "failed to open output");
631022323cSMircea Trofin 
6463293558SMircea Trofin   return llvm::createCtxProfFromYAML(BufOrError.get()->getBuffer(), Out);
65a737b870SMircea Trofin }
66a737b870SMircea Trofin 
67*c70f2462SMircea Trofin Error convertToYaml() {
68*c70f2462SMircea Trofin   auto BufOrError = MemoryBuffer::getFileOrSTDIN(InputFilename);
69*c70f2462SMircea Trofin   if (!BufOrError)
70*c70f2462SMircea Trofin     return createFileError(InputFilename, BufOrError.getError());
71*c70f2462SMircea Trofin 
72*c70f2462SMircea Trofin   std::error_code EC;
73*c70f2462SMircea Trofin   raw_fd_ostream Out(OutputFilename, EC);
74*c70f2462SMircea Trofin   if (EC)
75*c70f2462SMircea Trofin     return createStringError(EC, "failed to open output");
76*c70f2462SMircea Trofin   PGOCtxProfileReader Reader(BufOrError.get()->getBuffer());
77*c70f2462SMircea Trofin   auto Prof = Reader.loadContexts();
78*c70f2462SMircea Trofin   if (!Prof)
79*c70f2462SMircea Trofin     return Prof.takeError();
80*c70f2462SMircea Trofin   llvm::convertCtxProfToYaml(Out, *Prof);
81*c70f2462SMircea Trofin   Out << "\n";
82*c70f2462SMircea Trofin   return Error::success();
83*c70f2462SMircea Trofin }
84*c70f2462SMircea Trofin } // namespace
85*c70f2462SMircea Trofin 
867f3dcf4bSMircea Trofin int main(int argc, const char **argv) {
87a737b870SMircea Trofin   cl::ParseCommandLineOptions(argc, argv, "LLVM Contextual Profile Utils\n");
88a737b870SMircea Trofin   ExitOnError ExitOnErr("llvm-ctxprof-util: ");
89*c70f2462SMircea Trofin   auto HandleErr = [&](Error E) -> int {
90*c70f2462SMircea Trofin     if (E) {
91a737b870SMircea Trofin       handleAllErrors(std::move(E), [&](const ErrorInfoBase &E) {
92a737b870SMircea Trofin         E.log(errs());
93a737b870SMircea Trofin         errs() << "\n";
94a737b870SMircea Trofin       });
95a737b870SMircea Trofin       return 1;
96a737b870SMircea Trofin     }
97a737b870SMircea Trofin     return 0;
98*c70f2462SMircea Trofin   };
99*c70f2462SMircea Trofin 
100*c70f2462SMircea Trofin   if (FromYAML)
101*c70f2462SMircea Trofin     return HandleErr(convertFromYaml());
102*c70f2462SMircea Trofin 
103*c70f2462SMircea Trofin   if (ToYAML)
104*c70f2462SMircea Trofin     return HandleErr(convertToYaml());
105*c70f2462SMircea Trofin 
1067f3dcf4bSMircea Trofin   cl::PrintHelpMessage();
1077f3dcf4bSMircea Trofin   return 1;
108a737b870SMircea Trofin }
109