From efa9416a21d7cac98996b92a805321ad061f54c0 Mon Sep 17 00:00:00 2001 From: Justin Bogner Date: Wed, 12 Mar 2014 22:00:57 +0000 Subject: Back out Profile library and dependent commits Chandler voiced some concern with checking this in without some discussion first. Reverting for now. This reverts r203703, r203704, r203708, and 203709. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203723 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llvm-profdata/CMakeLists.txt | 2 +- tools/llvm-profdata/LLVMBuild.txt | 2 +- tools/llvm-profdata/Makefile | 2 +- tools/llvm-profdata/llvm-profdata.cpp | 380 +++++++++++----------------------- 4 files changed, 120 insertions(+), 266 deletions(-) (limited to 'tools/llvm-profdata') diff --git a/tools/llvm-profdata/CMakeLists.txt b/tools/llvm-profdata/CMakeLists.txt index f0667f16f9..4b1357d87e 100644 --- a/tools/llvm-profdata/CMakeLists.txt +++ b/tools/llvm-profdata/CMakeLists.txt @@ -1,4 +1,4 @@ -set(LLVM_LINK_COMPONENTS core profile support) +set(LLVM_LINK_COMPONENTS core support ) add_llvm_tool(llvm-profdata llvm-profdata.cpp diff --git a/tools/llvm-profdata/LLVMBuild.txt b/tools/llvm-profdata/LLVMBuild.txt index f6492da26c..fc9e469199 100644 --- a/tools/llvm-profdata/LLVMBuild.txt +++ b/tools/llvm-profdata/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-profdata parent = Tools -required_libraries = Profile Support +required_libraries = Support diff --git a/tools/llvm-profdata/Makefile b/tools/llvm-profdata/Makefile index 11276e25b9..9d7ad527b1 100644 --- a/tools/llvm-profdata/Makefile +++ b/tools/llvm-profdata/Makefile @@ -9,7 +9,7 @@ LEVEL := ../.. TOOLNAME := llvm-profdata -LINK_COMPONENTS := core profile support +LINK_COMPONENTS := core support # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS := 1 diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp index 989c4281f8..b338efd27e 100644 --- a/tools/llvm-profdata/llvm-profdata.cpp +++ b/tools/llvm-profdata/llvm-profdata.cpp @@ -12,10 +12,7 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/StringRef.h" -#include "llvm/Profile/ProfileDataReader.h" -#include "llvm/Profile/ProfileDataWriter.h" #include "llvm/Support/CommandLine.h" -#include "llvm/Support/LineIterator.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" @@ -24,211 +21,91 @@ using namespace llvm; -static void exitWithError(const std::string &Message, - const std::string &Filename, int64_t Line = -1) { - errs() << "error: " << Filename; - if (Line >= 0) - errs() << ":" << Line; - errs() << ": " << Message << "\n"; - ::exit(1); -} - -int merge_main(int argc, const char *argv[]) { - cl::opt Filename1(cl::Positional, cl::Required, - cl::desc("file1")); - cl::opt Filename2(cl::Positional, cl::Required, - cl::desc("file2")); - - cl::opt OutputFilename("output", cl::value_desc("output"), - cl::init("-"), - cl::desc("Output file")); - cl::alias OutputFilenameA("o", cl::desc("Alias for --output"), - cl::aliasopt(OutputFilename)); - - cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n"); - - std::unique_ptr Reader1, Reader2; - if (error_code EC = ProfileDataReader::create(Filename1, Reader1)) - exitWithError(EC.message(), Filename1); - if (error_code EC = ProfileDataReader::create(Filename2, Reader2)) - exitWithError(EC.message(), Filename2); - - if (OutputFilename.empty()) - OutputFilename = "-"; - - std::string ErrorInfo; - raw_fd_ostream Output(OutputFilename.data(), ErrorInfo, sys::fs::F_Text); - if (!ErrorInfo.empty()) - exitWithError(ErrorInfo, OutputFilename); - - if (Output.is_displayed()) - exitWithError("Refusing to write a binary file to stdout", OutputFilename); - - StringRef Name1, Name2; - std::vector Counts1, Counts2, NewCounts; - uint64_t Hash1, Hash2; - ProfileDataWriter Writer; - ProfileDataReader::name_iterator I1 = Reader1->begin(), - E1 = Reader1->end(), - I2 = Reader2->begin(), - E2 = Reader2->end(); - for (; I1 != E1 && I2 != E2; ++I1, ++I2) { - Name1 = *I1; - Name2 = *I2; - if (Name1 != Name2) - exitWithError("Function name mismatch", Filename2); // ??? - - if (error_code EC = Reader1->getFunctionCounts(Name1, Hash1, Counts1)) - exitWithError(EC.message(), Filename1); - if (error_code EC = Reader2->getFunctionCounts(Name2, Hash2, Counts2)) - exitWithError(EC.message(), Filename2); - - if (Counts1.size() != Counts2.size()) - exitWithError("Function count mismatch", Filename2); // ??? - if (Hash1 != Hash2) - exitWithError("Function hash mismatch", Filename2); // ??? - - for (size_t II = 0, EE = Counts1.size(); II < EE; ++II) { - uint64_t Sum = Counts1[II] + Counts2[II]; - if (Sum < Counts1[II]) - exitWithError("Counter overflow", Filename2); // ??? - NewCounts.push_back(Sum); +static cl::opt Filename1(cl::Positional, cl::Required, + cl::desc("file1")); +static cl::opt Filename2(cl::Positional, cl::Required, + cl::desc("file2")); + +static cl::opt OutputFilename("output", cl::value_desc("output"), + cl::init("-"), + cl::desc("Output file")); +static cl::alias OutputFilenameA("o", cl::desc("Alias for --output"), + cl::aliasopt(OutputFilename)); + +static bool readLine(const char *&Start, const char *End, StringRef &S) { + if (Start == End) + return false; + + for (const char *I = Start; I != End; ++I) { + assert(*I && "unexpected binary data"); + if (*I == '\n') { + S = StringRef(Start, I - Start); + Start = I + 1; + return true; } - - Writer.addFunctionCounts(Name1, Hash1, NewCounts.size(), NewCounts.data()); - - Counts1.clear(); - Counts2.clear(); - NewCounts.clear(); } - if (I1 != E1 || I2 != E2) - exitWithError("Truncated file", Filename2); - - Writer.write(Output); - return 0; + S = StringRef(Start, End - Start); + Start = End; + return true; } -struct HashPrinter { - uint64_t Hash; - HashPrinter(uint64_t Hash) : Hash(Hash) {} - void print(raw_ostream &OS) const { - char Buf[18], *Cur = Buf; - *Cur++ = '0'; *Cur++ = 'x'; - for (unsigned I = 16; I;) { - char Digit = 0xF & (Hash >> (--I * 4)); - *Cur++ = (Digit < 10 ? '0' + Digit : 'A' + Digit - 10); +static StringRef getWord(const char *&Start, const char *End) { + for (const char *I = Start; I != End; ++I) + if (*I == ' ') { + StringRef S(Start, I - Start); + Start = I + 1; + return S; } - OS.write(Buf, 18); - } -}; -static raw_ostream &operator<<(raw_ostream &OS, const HashPrinter &Hash) { - Hash.print(OS); - return OS; + StringRef S(Start, End - Start); + Start = End; + return S; } -struct FreqPrinter { - double Freq; - FreqPrinter(double Freq) : Freq(Freq) {} - void print(raw_ostream &OS) const { - OS << (unsigned)(Freq * 100) << "." << ((unsigned)(Freq * 1000) % 10) - << ((unsigned)(Freq * 10000) % 10) << "%"; - } -}; -static raw_ostream &operator<<(raw_ostream &OS, const FreqPrinter &Freq) { - Freq.print(OS); - return OS; +static size_t splitWords(const StringRef &Line, std::vector &Words) { + const char *Start = Line.data(); + const char *End = Line.data() + Line.size(); + Words.clear(); + while (Start != End) + Words.push_back(getWord(Start, End)); + return Words.size(); } -int show_main(int argc, const char *argv[]) { - cl::opt Filename(cl::Positional, cl::Required, - cl::desc("")); - - cl::opt ShowCounts("counts", cl::init(false)); - cl::opt ShowAllFunctions("all-functions", cl::init(false)); - cl::opt ShowFunction("function"); - - cl::opt OutputFilename("output", cl::value_desc("output"), - cl::init("-"), - cl::desc("Output file")); - cl::alias OutputFilenameA("o", cl::desc("Alias for --output"), - cl::aliasopt(OutputFilename)); - - cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n"); - - std::unique_ptr Reader; - if (error_code EC = ProfileDataReader::create(Filename, Reader)) - exitWithError(EC.message(), Filename); - - if (OutputFilename.empty()) - OutputFilename = "-"; - - std::string ErrorInfo; - raw_fd_ostream OS(OutputFilename.data(), ErrorInfo, sys::fs::F_Text); - if (!ErrorInfo.empty()) - exitWithError(ErrorInfo, OutputFilename); - - if (ShowAllFunctions && !ShowFunction.empty()) - errs() << "warning: -function argument ignored: showing all functions\n"; - - uint64_t MaxFunctionCount = Reader->getMaximumFunctionCount(); - - uint64_t MaxBlockCount = 0; - uint64_t Hash; - size_t ShownFunctions = false; - std::vector Counts; - for (const auto &Name : *Reader) { - bool Show = ShowAllFunctions || Name.find(ShowFunction) != Name.npos; - if (error_code EC = Reader->getFunctionCounts(Name, Hash, Counts)) - exitWithError(EC.message(), Filename); - - if (Show) { - double CallFreq = Counts[0] / (double)MaxFunctionCount; - - if (!ShownFunctions) - OS << "Counters:\n"; - ++ShownFunctions; +static bool getNumber(const StringRef &S, uint64_t &N) { + N = 0; + for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) + if (*I >= '0' && *I <= '9') + N = N * 10 + (*I - '0'); + else + return false; - OS << " " << Name << ":\n" - << " Hash: " << HashPrinter(Hash) << "\n" - << " Relative call frequency: " << FreqPrinter(CallFreq) << "\n" - << " Counters: " << Counts.size() << "\n" - << " Function count: " << Counts[0] << "\n"; - } - - if (Show && ShowCounts) - OS << " Block counts: ["; - for (size_t I = 1, E = Counts.size(); I < E; ++I) { - if (Counts[I] > MaxBlockCount) - MaxBlockCount = Counts[I]; - if (Show && ShowCounts) - OS << (I == 1 ? "" : ", ") << Counts[I]; - } - if (Show && ShowCounts) - OS << "]\n"; - - Counts.clear(); - } + return true; +} - if (ShowAllFunctions || !ShowFunction.empty()) - OS << "Functions shown: " << ShownFunctions << "\n"; - OS << "Total functions: " << Reader->numProfiledFunctions() << "\n"; - OS << "Maximum function count: " << MaxFunctionCount << "\n"; - OS << "Maximum internal block count: " << MaxBlockCount << "\n"; - return 0; +static void exitWithError(const std::string &Message, + const std::string &Filename, int64_t Line = -1) { + errs() << "error: " << Filename; + if (Line >= 0) + errs() << ":" << Line; + errs() << ": " << Message << "\n"; + ::exit(1); } -int generate_main(int argc, const char *argv[]) { - cl::opt InputName(cl::Positional, cl::Required, - cl::desc("")); +//===----------------------------------------------------------------------===// +int main(int argc, char **argv) { + // Print a stack trace if we signal out. + sys::PrintStackTraceOnErrorSignal(); + PrettyStackTraceProgram X(argc, argv); + llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - cl::opt OutputFilename("output", cl::value_desc("output"), - cl::init("-"), - cl::desc("Output file")); - cl::alias OutputFilenameA("o", cl::desc("Alias for --output"), - cl::aliasopt(OutputFilename)); + cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n"); - cl::ParseCommandLineOptions(argc, argv, "LLVM profile data generator\n"); + std::unique_ptr File1; + std::unique_ptr File2; + if (error_code ec = MemoryBuffer::getFile(Filename1, File1)) + exitWithError(ec.message(), Filename1); + if (error_code ec = MemoryBuffer::getFile(Filename2, File2)) + exitWithError(ec.message(), Filename2); if (OutputFilename.empty()) OutputFilename = "-"; @@ -238,86 +115,63 @@ int generate_main(int argc, const char *argv[]) { if (!ErrorInfo.empty()) exitWithError(ErrorInfo, OutputFilename); - if (Output.is_displayed()) - exitWithError("Refusing to write a binary file to stdout", OutputFilename); - - std::unique_ptr Buffer; - if (error_code EC = MemoryBuffer::getFile(InputName, Buffer)) - exitWithError(EC.message(), InputName); - - ProfileDataWriter Writer; - StringRef Name; - uint64_t Hash, NumCounters; - std::vector Counters; - for (line_iterator I(*Buffer, '#'); !I.is_at_end(); ++I) { - if (I->empty()) + const char *Start1 = File1->getBufferStart(); + const char *Start2 = File2->getBufferStart(); + const char *End1 = File1->getBufferEnd(); + const char *End2 = File2->getBufferEnd(); + const char *P1 = Start1; + const char *P2 = Start2; + + StringRef Line1, Line2; + int64_t Num = 0; + while (readLine(P1, End1, Line1)) { + ++Num; + if (!readLine(P2, End2, Line2)) + exitWithError("truncated file", Filename2, Num); + + std::vector Words1, Words2; + if (splitWords(Line1, Words1) != splitWords(Line2, Words2)) + exitWithError("data mismatch", Filename2, Num); + + if (Words1.size() > 2) + exitWithError("invalid data", Filename1, Num); + + if (Words1.empty()) { + Output << "\n"; continue; - Name = *I; - if ((++I).is_at_end()) - exitWithError("Truncated file", InputName, I.line_number()); - if (I->getAsInteger(10, Hash)) - exitWithError("Failed to read hash", InputName, I.line_number()); - if ((++I).is_at_end()) - exitWithError("Truncated file", InputName, I.line_number()); - if (I->getAsInteger(10, NumCounters)) - exitWithError("Failed to read num counters", InputName, I.line_number()); - for (uint64_t CurCounter = 0; CurCounter < NumCounters; ++CurCounter) { - uint64_t Counter; - if ((++I).is_at_end()) - exitWithError("Truncated file", InputName, I.line_number()); - if (I->getAsInteger(10, Counter)) - exitWithError("Failed to read counter", InputName, I.line_number()); - Counters.push_back(Counter); } - Writer.addFunctionCounts(Name, Hash, NumCounters, Counters.data()); - Counters.clear(); - } - Writer.write(Output); + if (Words1.size() == 2) { + if (Words1[0] != Words2[0]) + exitWithError("function name mismatch", Filename2, Num); - return 0; -} + uint64_t N1, N2; + if (!getNumber(Words1[1], N1)) + exitWithError("bad function count", Filename1, Num); + if (!getNumber(Words2[1], N2)) + exitWithError("bad function count", Filename2, Num); -int main(int argc, const char *argv[]) { - // Print a stack trace if we signal out. - sys::PrintStackTraceOnErrorSignal(); - PrettyStackTraceProgram X(argc, argv); - llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. - - StringRef ProgName(sys::path::filename(argv[0])); - if (argc > 1) { - int (*func)(int, const char *[]) = 0; - - if (strcmp(argv[1], "merge") == 0) - func = merge_main; - else if (strcmp(argv[1], "show") == 0) - func = show_main; - else if (strcmp(argv[1], "generate") == 0) - func = generate_main; + if (N1 != N2) + exitWithError("function count mismatch", Filename2, Num); - if (func) { - std::string Invocation(ProgName.str() + " " + argv[1]); - argv[1] = Invocation.c_str(); - return func(argc - 1, argv + 1); + Output << Line1 << "\n"; + continue; } - if (strcmp(argv[1], "-h") == 0 || - strcmp(argv[1], "-help") == 0 || - strcmp(argv[1], "--help") == 0) { + uint64_t N1, N2; + if (!getNumber(Words1[0], N1)) + exitWithError("invalid counter", Filename1, Num); + if (!getNumber(Words2[0], N2)) + exitWithError("invalid counter", Filename2, Num); - errs() << "OVERVIEW: LLVM profile data tools\n\n" - << "USAGE: " << ProgName << " [args...]\n" - << "USAGE: " << ProgName << " -help\n\n" - << "Available commands: merge, show, generate\n"; - return 0; - } - } + uint64_t Sum = N1 + N2; + if (Sum < N1) + exitWithError("counter overflow", Filename2, Num); - if (argc < 2) - errs() << ProgName << ": No command specified!\n"; - else - errs() << ProgName << ": Unknown command!\n"; + Output << N1 + N2 << "\n"; + } + if (readLine(P2, End2, Line2)) + exitWithError("truncated file", Filename1, Num + 1); - errs() << "USAGE: " << ProgName << " [args...]\n"; - return 1; + return 0; } -- cgit v1.2.3