1 //===- llvm-profdata.cpp - LLVM profile data tool -------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // llvm-profdata merges .profdata files.
12 //===----------------------------------------------------------------------===//
14 #include "llvm/ADT/StringRef.h"
15 #include "llvm/ProfileData/InstrProfReader.h"
16 #include "llvm/Support/CommandLine.h"
17 #include "llvm/Support/ManagedStatic.h"
18 #include "llvm/Support/MemoryBuffer.h"
19 #include "llvm/Support/PrettyStackTrace.h"
20 #include "llvm/Support/Signals.h"
21 #include "llvm/Support/raw_ostream.h"
25 static void exitWithError(const Twine &Message, StringRef Whence = "") {
28 errs() << Whence << ": ";
29 errs() << Message << "\n";
33 int merge_main(int argc, const char *argv[]) {
34 cl::opt<std::string> Filename1(cl::Positional, cl::Required,
36 cl::opt<std::string> Filename2(cl::Positional, cl::Required,
39 cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
41 cl::desc("Output file"));
42 cl::alias OutputFilenameA("o", cl::desc("Alias for --output"),
43 cl::aliasopt(OutputFilename));
45 cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n");
47 std::unique_ptr<InstrProfReader> Reader1, Reader2;
48 if (error_code ec = InstrProfReader::create(Filename1, Reader1))
49 exitWithError(ec.message(), Filename1);
50 if (error_code ec = InstrProfReader::create(Filename2, Reader2))
51 exitWithError(ec.message(), Filename2);
53 if (OutputFilename.empty())
56 std::string ErrorInfo;
57 raw_fd_ostream Output(OutputFilename.data(), ErrorInfo, sys::fs::F_Text);
58 if (!ErrorInfo.empty())
59 exitWithError(ErrorInfo, OutputFilename);
61 for (InstrProfIterator I1 = Reader1->begin(), E1 = Reader1->end(),
62 I2 = Reader2->begin(), E2 = Reader2->end();
63 I1 != E1 && I2 != E2; ++I1, ++I2) {
64 if (I1->Name != I2->Name)
65 exitWithError("Function name mismatch, " + I1->Name + " != " + I2->Name);
66 if (I1->Hash != I2->Hash)
67 exitWithError("Function hash mismatch for " + I1->Name);
68 if (I1->Counts.size() != I2->Counts.size())
69 exitWithError("Function count mismatch for " + I1->Name);
71 Output << I1->Name << "\n" << I1->Hash << "\n" << I1->Counts.size() << "\n";
73 for (size_t II = 0, EE = I1->Counts.size(); II < EE; ++II) {
74 uint64_t Sum = I1->Counts[II] + I2->Counts[II];
75 if (Sum < I1->Counts[II])
76 exitWithError("Counter overflow for " + I1->Name);
77 Output << Sum << "\n";
81 if (Reader1->hasError())
82 exitWithError(Reader1->getError().message(), Filename1);
83 if (Reader2->hasError())
84 exitWithError(Reader2->getError().message(), Filename2);
85 if (!Reader1->isEOF() || !Reader2->isEOF())
86 exitWithError("Number of instrumented functions differ.");
91 int main(int argc, const char *argv[]) {
92 // Print a stack trace if we signal out.
93 sys::PrintStackTraceOnErrorSignal();
94 PrettyStackTraceProgram X(argc, argv);
95 llvm_shutdown_obj Y; // Call llvm_shutdown() on exit.
97 StringRef ProgName(sys::path::filename(argv[0]));
99 int (*func)(int, const char *[]) = 0;
101 if (strcmp(argv[1], "merge") == 0)
105 std::string Invocation(ProgName.str() + " " + argv[1]);
106 argv[1] = Invocation.c_str();
107 return func(argc - 1, argv + 1);
110 if (strcmp(argv[1], "-h") == 0 ||
111 strcmp(argv[1], "-help") == 0 ||
112 strcmp(argv[1], "--help") == 0) {
114 errs() << "OVERVIEW: LLVM profile data tools\n\n"
115 << "USAGE: " << ProgName << " <command> [args...]\n"
116 << "USAGE: " << ProgName << " <command> -help\n\n"
117 << "Available commands: merge\n";
123 errs() << ProgName << ": No command specified!\n";
125 errs() << ProgName << ": Unknown command!\n";
127 errs() << "USAGE: " << ProgName << " <merge> [args...]\n";