xref: /llvm-project/llvm/tools/llvm-ctxprof-util/llvm-ctxprof-util.cpp (revision 0de1e3e787c6d78b87ccb865ba2f2daf8d8e4ecc)
1 //===--- PGOCtxProfJSONReader.h - JSON format  ------------------*- 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 ///
9 /// \file
10 ///
11 /// JSON format for the contextual profile for testing.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "llvm/ADT/STLExtras.h"
16 #include "llvm/IR/GlobalValue.h"
17 #include "llvm/ProfileData/CtxInstrContextNode.h"
18 #include "llvm/ProfileData/PGOCtxProfWriter.h"
19 #include "llvm/Support/CommandLine.h"
20 #include "llvm/Support/Error.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/InitLLVM.h"
23 #include "llvm/Support/JSON.h"
24 #include "llvm/Support/MemoryBuffer.h"
25 #include "llvm/Support/raw_ostream.h"
26 
27 using namespace llvm;
28 
29 static cl::SubCommand FromJSON("fromJSON", "Convert from json");
30 
31 static cl::opt<std::string> InputFilename(
32     "input", cl::value_desc("input"), cl::init("-"),
33     cl::desc(
34         "Input file. The format is an array of contexts.\n"
35         "Each context is a dictionary with the following keys:\n"
36         "'Guid', mandatory. The value is a 64-bit integer.\n"
37         "'Counters', mandatory. An array of 32-bit ints. These are the "
38         "counter values.\n"
39         "'Contexts', optional. An array containing arrays of contexts. The "
40         "context array at a position 'i' is the set of callees at that "
41         "callsite index. Use an empty array to indicate no callees."),
42     cl::sub(FromJSON));
43 
44 static cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
45                                            cl::init("-"),
46                                            cl::desc("Output file"),
47                                            cl::sub(FromJSON));
48 
49 // Save the bitstream profile from the JSON representation.
50 Error convertFromJSON() {
51   auto BufOrError =
52       MemoryBuffer::getFileOrSTDIN(InputFilename, /*IsText=*/true);
53   if (!BufOrError)
54     return createFileError(InputFilename, BufOrError.getError());
55 
56   std::error_code EC;
57   // Using a fd_ostream instead of a fd_stream. The latter would be more
58   // efficient as the bitstream writer supports incremental flush to it, but the
59   // json scenario is for test, and file size scalability doesn't really concern
60   // us.
61   raw_fd_ostream Out(OutputFilename, EC);
62   if (EC)
63     return createStringError(EC, "failed to open output");
64 
65   return llvm::createCtxProfFromJSON(BufOrError.get()->getBuffer(), Out);
66 }
67 
68 int main(int argc, const char **argv) {
69   cl::ParseCommandLineOptions(argc, argv, "LLVM Contextual Profile Utils\n");
70   ExitOnError ExitOnErr("llvm-ctxprof-util: ");
71   if (FromJSON) {
72     if (auto E = convertFromJSON()) {
73       handleAllErrors(std::move(E), [&](const ErrorInfoBase &E) {
74         E.log(errs());
75         errs() << "\n";
76       });
77       return 1;
78     }
79     return 0;
80   }
81   cl::PrintHelpMessage();
82   return 1;
83 }
84