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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | /// |
9 | /// \file |
10 | /// |
11 | /// Utilities for manipulating contextual profiles |
12 | /// |
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 | |
24 | using namespace llvm; |
25 | |
26 | static cl::SubCommand FromYAML("fromYAML" , "Convert from yaml" ); |
27 | static cl::SubCommand ToYAML("toYAML" , "Convert to yaml" ); |
28 | |
29 | static cl::opt<std::string> InputFilename( |
30 | "input" , cl::value_desc("input" ), cl::init(Val: "-" ), |
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 | |
42 | static cl::opt<std::string> OutputFilename("output" , cl::value_desc("output" ), |
43 | cl::init(Val: "-" ), |
44 | cl::desc("Output file" ), |
45 | cl::sub(FromYAML), cl::sub(ToYAML)); |
46 | |
47 | namespace { |
48 | // Save the bitstream profile from the JSON representation. |
49 | Error convertFromYaml() { |
50 | auto BufOrError = |
51 | MemoryBuffer::getFileOrSTDIN(Filename: InputFilename, /*IsText=*/true); |
52 | if (!BufOrError) |
53 | return createFileError(F: InputFilename, EC: BufOrError.getError()); |
54 | |
55 | std::error_code EC; |
56 | // Using a fd_ostream instead of a fd_stream. The latter would be more |
57 | // efficient as the bitstream writer supports incremental flush to it, but the |
58 | // json scenario is for test, and file size scalability doesn't really concern |
59 | // us. |
60 | raw_fd_ostream Out(OutputFilename, EC); |
61 | if (EC) |
62 | return createStringError(EC, S: "failed to open output" ); |
63 | |
64 | return llvm::createCtxProfFromYAML(Profile: BufOrError.get()->getBuffer(), Out); |
65 | } |
66 | |
67 | Error convertToYaml() { |
68 | auto BufOrError = MemoryBuffer::getFileOrSTDIN(Filename: InputFilename); |
69 | if (!BufOrError) |
70 | return createFileError(F: InputFilename, EC: BufOrError.getError()); |
71 | |
72 | std::error_code EC; |
73 | raw_fd_ostream Out(OutputFilename, EC); |
74 | if (EC) |
75 | return createStringError(EC, S: "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(OS&: Out, Profile: *Prof); |
81 | Out << "\n" ; |
82 | return Error::success(); |
83 | } |
84 | } // namespace |
85 | |
86 | int main(int argc, const char **argv) { |
87 | cl::ParseCommandLineOptions(argc, argv, Overview: "LLVM Contextual Profile Utils\n" ); |
88 | ExitOnError ExitOnErr("llvm-ctxprof-util: " ); |
89 | auto HandleErr = [&](Error E) -> int { |
90 | if (E) { |
91 | handleAllErrors(E: std::move(E), Handlers: [&](const ErrorInfoBase &E) { |
92 | E.log(OS&: 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 | |