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