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 --- include/llvm/Profile/ProfileData.h | 56 --- include/llvm/Profile/ProfileDataReader.h | 91 ----- include/llvm/Profile/ProfileDataWriter.h | 47 --- include/llvm/Support/LineIterator.h | 1 - lib/CMakeLists.txt | 1 - lib/LLVMBuild.txt | 2 +- lib/Makefile | 2 +- lib/Profile/CMakeLists.txt | 5 - lib/Profile/LLVMBuild.txt | 21 -- lib/Profile/Makefile | 14 - lib/Profile/ProfileData.cpp | 54 --- lib/Profile/ProfileDataReader.cpp | 167 --------- lib/Profile/ProfileDataWriter.cpp | 71 ---- .../Inputs/bad-function-count.profdata | 2 + .../llvm-profdata/Inputs/bad-hash.profdata.input | 4 - test/tools/llvm-profdata/Inputs/bar3-1.profdata | 4 + .../llvm-profdata/Inputs/bar3-1.profdata.input | 6 - test/tools/llvm-profdata/Inputs/empty.profdata | 0 .../llvm-profdata/Inputs/empty.profdata.input | 0 .../tools/llvm-profdata/Inputs/extra-word.profdata | 2 + .../llvm-profdata/Inputs/extra-word.profdata.input | 2 - test/tools/llvm-profdata/Inputs/foo3-1.profdata | 4 + .../llvm-profdata/Inputs/foo3-1.profdata.input | 6 - test/tools/llvm-profdata/Inputs/foo3-2.profdata | 4 + .../llvm-profdata/Inputs/foo3-2.profdata.input | 6 - .../tools/llvm-profdata/Inputs/foo3bar3-1.profdata | 9 + .../llvm-profdata/Inputs/foo3bar3-1.profdata.input | 13 - .../tools/llvm-profdata/Inputs/foo3bar3-2.profdata | 9 + .../llvm-profdata/Inputs/foo3bar3-2.profdata.input | 13 - test/tools/llvm-profdata/Inputs/foo4-1.profdata | 5 + .../llvm-profdata/Inputs/foo4-1.profdata.input | 7 - test/tools/llvm-profdata/Inputs/foo4-2.profdata | 5 + .../llvm-profdata/Inputs/foo4-2.profdata.input | 7 - .../Inputs/invalid-count-later.profdata | 2 + .../Inputs/invalid-count-later.profdata.input | 4 - test/tools/llvm-profdata/Inputs/overflow.profdata | 2 + .../llvm-profdata/Inputs/overflow.profdata.input | 4 - .../llvm-profdata/Inputs/three-words-long.profdata | 1 + .../Inputs/three-words-long.profdata.input | 1 - .../Inputs/wrong-count.profdata.input | 4 - test/tools/llvm-profdata/errors.test | 22 ++ test/tools/llvm-profdata/generate.test | 38 --- test/tools/llvm-profdata/merge-errors.test | 21 -- test/tools/llvm-profdata/simple-merges.test | 33 -- test/tools/llvm-profdata/simple.test | 25 ++ tools/llvm-profdata/CMakeLists.txt | 2 +- tools/llvm-profdata/LLVMBuild.txt | 2 +- tools/llvm-profdata/Makefile | 2 +- tools/llvm-profdata/llvm-profdata.cpp | 380 +++++++-------------- 49 files changed, 218 insertions(+), 965 deletions(-) delete mode 100644 include/llvm/Profile/ProfileData.h delete mode 100644 include/llvm/Profile/ProfileDataReader.h delete mode 100644 include/llvm/Profile/ProfileDataWriter.h delete mode 100644 lib/Profile/CMakeLists.txt delete mode 100644 lib/Profile/LLVMBuild.txt delete mode 100644 lib/Profile/Makefile delete mode 100644 lib/Profile/ProfileData.cpp delete mode 100644 lib/Profile/ProfileDataReader.cpp delete mode 100644 lib/Profile/ProfileDataWriter.cpp create mode 100644 test/tools/llvm-profdata/Inputs/bad-function-count.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/bad-hash.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/bar3-1.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/bar3-1.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/empty.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/empty.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/extra-word.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/extra-word.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/foo3-1.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/foo3-1.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/foo3-2.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/foo3-2.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/foo4-1.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/foo4-1.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/foo4-2.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/foo4-2.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/invalid-count-later.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/invalid-count-later.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/overflow.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/overflow.profdata.input create mode 100644 test/tools/llvm-profdata/Inputs/three-words-long.profdata delete mode 100644 test/tools/llvm-profdata/Inputs/three-words-long.profdata.input delete mode 100644 test/tools/llvm-profdata/Inputs/wrong-count.profdata.input create mode 100644 test/tools/llvm-profdata/errors.test delete mode 100644 test/tools/llvm-profdata/generate.test delete mode 100644 test/tools/llvm-profdata/merge-errors.test delete mode 100644 test/tools/llvm-profdata/simple-merges.test create mode 100644 test/tools/llvm-profdata/simple.test diff --git a/include/llvm/Profile/ProfileData.h b/include/llvm/Profile/ProfileData.h deleted file mode 100644 index 72cc840e80..0000000000 --- a/include/llvm/Profile/ProfileData.h +++ /dev/null @@ -1,56 +0,0 @@ -//=-- ProfileData.h - Instrumented profiling format support -------*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for instrumentation based PGO and coverage. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_PROFILE_PROFILEDATA_H__ -#define LLVM_PROFILE_PROFILEDATA_H__ - -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/system_error.h" - -#include - -namespace llvm { - -const char PROFILEDATA_MAGIC[4] = {'L', 'P', 'R', 'F'}; -const uint32_t PROFILEDATA_VERSION = 1; -const uint32_t PROFILEDATA_HEADER_SIZE = 24; - -const error_category &profiledata_category(); - -struct profiledata_error { - enum ErrorType { - success = 0, - bad_magic, - unsupported_version, - too_large, - truncated, - malformed, - unknown_function - }; - ErrorType V; - - profiledata_error(ErrorType V) : V(V) {} - operator ErrorType() const { return V; } -}; - -inline error_code make_error_code(profiledata_error E) { - return error_code(static_cast(E), profiledata_category()); -} - -template <> struct is_error_code_enum : std::true_type {}; -template <> struct is_error_code_enum - : std::true_type {}; - -} // end namespace llvm - -#endif // LLVM_PROFILE_PROFILEDATA_H__ diff --git a/include/llvm/Profile/ProfileDataReader.h b/include/llvm/Profile/ProfileDataReader.h deleted file mode 100644 index 0f771f23fd..0000000000 --- a/include/llvm/Profile/ProfileDataReader.h +++ /dev/null @@ -1,91 +0,0 @@ -//=-- ProfileDataReader.h - Instrumented profiling reader ---------*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for reading profiling data for instrumentation -// based PGO and coverage. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_PROFILE_PROFILEDATA_READER_H__ -#define LLVM_PROFILE_PROFILEDATA_READER_H__ - -#include "llvm/ADT/StringMap.h" -#include "llvm/Support/Compiler.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/ErrorOr.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/raw_ostream.h" - -#include - -namespace llvm { - -class ProfileDataCursor; - -/// Reader for the profile data that is used for instrumentation based PGO. -class ProfileDataReader { -private: - /// The profile data file contents. - std::unique_ptr DataBuffer; - /// Offsets into DataBuffer for each function's counters. - StringMap DataOffsets; - /// The maximal execution count among all functions. - uint64_t MaxFunctionCount; - - ProfileDataReader(const ProfileDataReader &) LLVM_DELETED_FUNCTION; - ProfileDataReader &operator=(const ProfileDataReader &) LLVM_DELETED_FUNCTION; -protected: - ProfileDataReader(std::unique_ptr &DataBuffer) - : DataBuffer(DataBuffer.release()) {} - - /// Populate internal state using the profile data's index - error_code readIndex(); -public: - - class name_iterator { - typedef StringMap::const_iterator IterTy; - IterTy Ix; - public: - explicit name_iterator(const IterTy &Ix) : Ix(Ix) {} - - StringRef operator*() const { return Ix->getKey(); } - - bool operator==(const name_iterator &RHS) const { return Ix == RHS.Ix; } - bool operator!=(const name_iterator &RHS) const { return Ix != RHS.Ix; } - - inline name_iterator& operator++() { ++Ix; return *this; } - }; - - /// Iterators over the names of indexed items - name_iterator begin() const { - return name_iterator(DataOffsets.begin()); - } - name_iterator end() const { - return name_iterator(DataOffsets.end()); - } - -private: - error_code findFunctionCounts(StringRef FuncName, uint64_t &FunctionHash, - ProfileDataCursor &Cursor); -public: - /// The number of profiled functions - size_t numProfiledFunctions() { return DataOffsets.size(); } - /// Fill Counts with the profile data for the given function name. - error_code getFunctionCounts(StringRef FuncName, uint64_t &FunctionHash, - std::vector &Counts); - /// Return the maximum of all known function counts. - uint64_t getMaximumFunctionCount() { return MaxFunctionCount; } - - static error_code create(std::string Path, - std::unique_ptr &Result); -}; - -} // end namespace llvm - -#endif // LLVM_PROFILE_PROFILEDATA_READER_H__ diff --git a/include/llvm/Profile/ProfileDataWriter.h b/include/llvm/Profile/ProfileDataWriter.h deleted file mode 100644 index 3498d2eca3..0000000000 --- a/include/llvm/Profile/ProfileDataWriter.h +++ /dev/null @@ -1,47 +0,0 @@ -//=-- ProfileDataWriter.h - Instrumented profiling writer ---------*- C++ -*-=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for writing profiling data for instrumentation -// based PGO and coverage. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_PROFILE_PROFILEDATA_WRITER_H__ -#define LLVM_PROFILE_PROFILEDATA_WRITER_H__ - -#include "llvm/ADT/StringMap.h" -#include "llvm/Profile/ProfileData.h" -#include "llvm/Support/DataTypes.h" -#include "llvm/Support/raw_ostream.h" - -#include - -namespace llvm { - -/// Writer for instrumentation based profile data -class ProfileDataWriter { - StringMap FunctionOffsets; - std::vector FunctionData; - uint32_t DataStart; - uint64_t MaxFunctionCount; - - void write32(raw_ostream &OS, uint32_t Value); - void write64(raw_ostream &OS, uint64_t Value); -public: - ProfileDataWriter() - : DataStart(PROFILEDATA_HEADER_SIZE), MaxFunctionCount(0) {} - - void addFunctionCounts(StringRef FuncName, uint64_t FunctionHash, - uint64_t NumCounters, const uint64_t *Counters); - void write(raw_ostream &OS); -}; - -} // end namespace llvm - -#endif // LLVM_PROFILE_PROFILEDATA_WRITER_H__ diff --git a/include/llvm/Support/LineIterator.h b/include/llvm/Support/LineIterator.h index 92a9cc5c57..861c19881f 100644 --- a/include/llvm/Support/LineIterator.h +++ b/include/llvm/Support/LineIterator.h @@ -56,7 +56,6 @@ public: /// \brief Get the current line as a \c StringRef. StringRef operator*() const { return CurrentLine; } - const StringRef *operator->() const { return &CurrentLine; } friend bool operator==(const line_iterator &LHS, const line_iterator &RHS) { return LHS.Buffer == RHS.Buffer && diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index a4496f9e58..9367f55313 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -16,4 +16,3 @@ add_subdirectory(ExecutionEngine) add_subdirectory(Target) add_subdirectory(AsmParser) add_subdirectory(LineEditor) -add_subdirectory(Profile) diff --git a/lib/LLVMBuild.txt b/lib/LLVMBuild.txt index c75ca4e903..a0984d410c 100644 --- a/lib/LLVMBuild.txt +++ b/lib/LLVMBuild.txt @@ -16,7 +16,7 @@ ;===------------------------------------------------------------------------===; [common] -subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine LineEditor Linker IR IRReader LTO MC Object Option Profile Support TableGen Target Transforms +subdirectories = Analysis AsmParser Bitcode CodeGen DebugInfo ExecutionEngine LineEditor Linker IR IRReader LTO MC Object Option Support TableGen Target Transforms [component_0] type = Group diff --git a/lib/Makefile b/lib/Makefile index 1f55dd7f96..a97f71aded 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -12,6 +12,6 @@ include $(LEVEL)/Makefile.config PARALLEL_DIRS := IR AsmParser Bitcode Analysis Transforms CodeGen Target \ ExecutionEngine Linker LTO MC Object Option DebugInfo \ - IRReader LineEditor Profile + IRReader LineEditor include $(LEVEL)/Makefile.common diff --git a/lib/Profile/CMakeLists.txt b/lib/Profile/CMakeLists.txt deleted file mode 100644 index e0a4f0a1ba..0000000000 --- a/lib/Profile/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -add_llvm_library(LLVMProfile - ProfileData.cpp - ProfileDataReader.cpp - ProfileDataWriter.cpp - ) diff --git a/lib/Profile/LLVMBuild.txt b/lib/Profile/LLVMBuild.txt deleted file mode 100644 index ae1fdd61c7..0000000000 --- a/lib/Profile/LLVMBuild.txt +++ /dev/null @@ -1,21 +0,0 @@ -;===- ./lib/Profile/LLVMBuild.txt ------------------------------*- Conf -*--===; -; -; The LLVM Compiler Infrastructure -; -; This file is distributed under the University of Illinois Open Source -; License. See LICENSE.TXT for details. -; -;===------------------------------------------------------------------------===; -; -; This is an LLVMBuild description file for the components in this subdirectory. -; -; For more information on the LLVMBuild system, please see: -; -; http://llvm.org/docs/LLVMBuild.html -; -;===------------------------------------------------------------------------===; - -[component_0] -type = Library -name = Profile -parent = Libraries diff --git a/lib/Profile/Makefile b/lib/Profile/Makefile deleted file mode 100644 index fb80a12097..0000000000 --- a/lib/Profile/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -##===- lib/Profile/Makefile --------------------------------*- Makefile -*-===## -# -# The LLVM Compiler Infrastructure -# -# This file is distributed under the University of Illinois Open Source -# License. See LICENSE.TXT for details. -# -##===----------------------------------------------------------------------===## - -LEVEL = ../.. -LIBRARYNAME = LLVMProfile -BUILD_ARCHIVE := 1 - -include $(LEVEL)/Makefile.common diff --git a/lib/Profile/ProfileData.cpp b/lib/Profile/ProfileData.cpp deleted file mode 100644 index 65dca9db2b..0000000000 --- a/lib/Profile/ProfileData.cpp +++ /dev/null @@ -1,54 +0,0 @@ -//=-- ProfileData.cpp - Instrumented profiling format support ---------------=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for clang's instrumentation based PGO and -// coverage. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Profile/ProfileData.h" -#include "llvm/Support/ErrorHandling.h" - -using namespace llvm; - -namespace { -class ProfileDataErrorCategoryType : public _do_message { - const char *name() const override { return "llvm.profiledata"; } - std::string message(int IE) const { - profiledata_error::ErrorType E = - static_cast(IE); - switch (E) { - case profiledata_error::success: return "Success"; - case profiledata_error::bad_magic: - return "Invalid file format (bad magic)"; - case profiledata_error::unsupported_version: - return "Unsupported format version"; - case profiledata_error::too_large: - return "Too much profile data"; - case profiledata_error::truncated: - return "Truncated profile data"; - case profiledata_error::malformed: - return "Malformed profile data"; - case profiledata_error::unknown_function: - return "No profile data available for function"; - } - llvm_unreachable("A value of profiledata_error has no message."); - } - error_condition default_error_condition(int EV) const { - if (EV == profiledata_error::success) - return errc::success; - return errc::invalid_argument; - } -}; -} - -const error_category &llvm::profiledata_category() { - static ProfileDataErrorCategoryType C; - return C; -} diff --git a/lib/Profile/ProfileDataReader.cpp b/lib/Profile/ProfileDataReader.cpp deleted file mode 100644 index e679d9eec0..0000000000 --- a/lib/Profile/ProfileDataReader.cpp +++ /dev/null @@ -1,167 +0,0 @@ -//=-- ProfileDataReader.cpp - Instrumented profiling reader -----------------=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for reading profiling data for clang's -// instrumentation based PGO and coverage. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Profile/ProfileDataReader.h" -#include "llvm/Profile/ProfileData.h" -#include "llvm/Support/Endian.h" - -#include - -using namespace llvm; - -error_code ProfileDataReader::create( - std::string Path, std::unique_ptr &Result) { - std::unique_ptr Buffer; - if (error_code EC = MemoryBuffer::getFileOrSTDIN(Path, Buffer)) - return EC; - - if (Buffer->getBufferSize() > std::numeric_limits::max()) - return profiledata_error::too_large; - - Result.reset(new ProfileDataReader(Buffer)); - if (error_code EC = Result->readIndex()) - return EC; - return profiledata_error::success; -} - -class llvm::ProfileDataCursor { - const char *Start; - const char *Next; - const char *End; - - error_code skip(unsigned bytes) { - if (Next + bytes > End) - return profiledata_error::malformed; - Next += bytes; - return profiledata_error::success; - } - - template - error_code read(T &Result) { - typedef support::detail::packed_endian_specific_integral - Endian_t; - const char *Prev = Next; - if (error_code EC = skip(sizeof(T))) - return EC; - Result = *reinterpret_cast(Prev); - return profiledata_error::success; - } -public: - ProfileDataCursor(const MemoryBuffer *Buf) - : Start(Buf->getBufferStart()), Next(Start), End(Buf->getBufferEnd()) {} - bool offsetReached(size_t Offset) { return Start + Offset <= Next; } - bool offsetInBounds(size_t Offset) { return Start + Offset < End; } - - error_code skipToOffset(size_t Offset) { - if (!offsetInBounds(Offset)) - return profiledata_error::malformed; - Next = Start + Offset; - return profiledata_error::success; - } - - error_code skip32() { return skip(4); } - error_code skip64() { return skip(8); } - error_code read32(uint32_t &Result) { return read(Result); } - error_code read64(uint64_t &Result) { return read(Result); } - - error_code readChars(StringRef &Result, uint32_t Len) { - error_code EC; - const char *Prev = Next; - if (error_code EC = skip(Len)) - return EC; - Result = StringRef(Prev, Len); - return profiledata_error::success; - } - error_code readString(StringRef &Result) { - uint32_t Len; - if (error_code EC = read32(Len)) - return EC; - return readChars(Result, Len); - } -}; - -error_code ProfileDataReader::readIndex() { - ProfileDataCursor Cursor(DataBuffer.get()); - error_code EC; - StringRef Magic; - uint32_t Version, IndexEnd, DataStart; - - if ((EC = Cursor.readChars(Magic, 4))) - return EC; - if (StringRef(PROFILEDATA_MAGIC, 4) != Magic) - return profiledata_error::bad_magic; - if ((EC = Cursor.read32(Version))) - return EC; - if (Version != PROFILEDATA_VERSION) - return profiledata_error::unsupported_version; - if ((EC = Cursor.read32(IndexEnd))) - return EC; - if ((EC = Cursor.skip32())) - return EC; - if ((EC = Cursor.read64(MaxFunctionCount))) - return EC; - - DataStart = IndexEnd + (sizeof(uint64_t) - IndexEnd % sizeof(uint64_t)); - while (!Cursor.offsetReached(IndexEnd)) { - StringRef FuncName; - uint32_t Offset, TotalOffset; - if ((EC = Cursor.readString(FuncName))) - return EC; - if ((EC = Cursor.read32(Offset))) - return EC; - TotalOffset = DataStart + Offset; - if (!Cursor.offsetInBounds(TotalOffset)) - return profiledata_error::truncated; - DataOffsets[FuncName] = TotalOffset; - } - - return profiledata_error::success; -} - -error_code ProfileDataReader::findFunctionCounts(StringRef FuncName, - uint64_t &FunctionHash, - ProfileDataCursor &Cursor) { - error_code EC; - // Find the relevant section of the pgo-data file. - const auto &OffsetIter = DataOffsets.find(FuncName); - if (OffsetIter == DataOffsets.end()) - return profiledata_error::unknown_function; - // Go there and read the function data - if ((EC = Cursor.skipToOffset(OffsetIter->getValue()))) - return EC; - if ((EC = Cursor.read64(FunctionHash))) - return EC; - return profiledata_error::success; -} - -error_code ProfileDataReader::getFunctionCounts(StringRef FuncName, - uint64_t &FunctionHash, - std::vector &Counts) { - ProfileDataCursor Cursor(DataBuffer.get()); - error_code EC; - if ((EC = findFunctionCounts(FuncName, FunctionHash, Cursor))) - return EC; - - uint64_t NumCounters; - if ((EC = Cursor.read64(NumCounters))) - return EC; - for (uint64_t I = 0; I < NumCounters; ++I) { - uint64_t Count; - if ((EC = Cursor.read64(Count))) - return EC; - Counts.push_back(Count); - } - - return profiledata_error::success; -} diff --git a/lib/Profile/ProfileDataWriter.cpp b/lib/Profile/ProfileDataWriter.cpp deleted file mode 100644 index b5993dd45e..0000000000 --- a/lib/Profile/ProfileDataWriter.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//=-- ProfileDataWriter.cpp - Instrumented profiling writer -----------------=// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file contains support for writing profiling data for clang's -// instrumentation based PGO and coverage. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Profile/ProfileDataWriter.h" -#include "llvm/Profile/ProfileData.h" -#include "llvm/Support/Endian.h" - -using namespace llvm; - -template -struct LEBytes { - const T &Data; - LEBytes(const T &Data) : Data(Data) {} - void print(raw_ostream &OS) const { - for (uint32_t Shift = 0; Shift < sizeof(Data); ++Shift) - OS << (char)((Data >> (8 * Shift)) & 0xFF); - } -}; -template -static raw_ostream &operator<<(raw_ostream &OS, const LEBytes &Bytes) { - Bytes.print(OS); - return OS; -} - -void ProfileDataWriter::addFunctionCounts(StringRef FuncName, - uint64_t FunctionHash, - uint64_t NumCounters, - const uint64_t *Counters) { - DataStart += 2 * sizeof(uint32_t) + FuncName.size(); - FunctionOffsets[FuncName] = FunctionData.size() * sizeof(uint64_t); - FunctionData.push_back(FunctionHash); - FunctionData.push_back(NumCounters); - assert(NumCounters > 0 && "Function call counter missing!"); - if (Counters[0] > MaxFunctionCount) - MaxFunctionCount = Counters[0]; - for (uint64_t I = 0; I < NumCounters; ++I) - FunctionData.push_back(Counters[I]); -} - -void ProfileDataWriter::write(raw_ostream &OS) { - for (char C : PROFILEDATA_MAGIC) - OS << C; - OS << LEBytes(PROFILEDATA_VERSION); - OS << LEBytes(DataStart); - OS << LEBytes(0); - OS << LEBytes(MaxFunctionCount); - - for (const auto &I : FunctionOffsets) { - StringRef Name = I.getKey(); - OS << LEBytes(Name.size()); - OS << Name; - OS << LEBytes(I.getValue()); - } - - for (unsigned I = 0; I < sizeof(uint64_t) - DataStart % sizeof(uint64_t); ++I) - OS << '\0'; - - for (uint64_t Value : FunctionData) - OS << LEBytes(Value); -} diff --git a/test/tools/llvm-profdata/Inputs/bad-function-count.profdata b/test/tools/llvm-profdata/Inputs/bad-function-count.profdata new file mode 100644 index 0000000000..7d247626e5 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/bad-function-count.profdata @@ -0,0 +1,2 @@ +function_count_not 1count +1 diff --git a/test/tools/llvm-profdata/Inputs/bad-hash.profdata.input b/test/tools/llvm-profdata/Inputs/bad-hash.profdata.input deleted file mode 100644 index faa6f40152..0000000000 --- a/test/tools/llvm-profdata/Inputs/bad-hash.profdata.input +++ /dev/null @@ -1,4 +0,0 @@ -function_count_not -badhash -1 -1 diff --git a/test/tools/llvm-profdata/Inputs/bar3-1.profdata b/test/tools/llvm-profdata/Inputs/bar3-1.profdata new file mode 100644 index 0000000000..cb8b409891 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/bar3-1.profdata @@ -0,0 +1,4 @@ +bar 3 +1 +2 +3 diff --git a/test/tools/llvm-profdata/Inputs/bar3-1.profdata.input b/test/tools/llvm-profdata/Inputs/bar3-1.profdata.input deleted file mode 100644 index 5486e9d84d..0000000000 --- a/test/tools/llvm-profdata/Inputs/bar3-1.profdata.input +++ /dev/null @@ -1,6 +0,0 @@ -bar -3 -3 -1 -2 -3 diff --git a/test/tools/llvm-profdata/Inputs/empty.profdata b/test/tools/llvm-profdata/Inputs/empty.profdata new file mode 100644 index 0000000000..e69de29bb2 diff --git a/test/tools/llvm-profdata/Inputs/empty.profdata.input b/test/tools/llvm-profdata/Inputs/empty.profdata.input deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/test/tools/llvm-profdata/Inputs/extra-word.profdata b/test/tools/llvm-profdata/Inputs/extra-word.profdata new file mode 100644 index 0000000000..67a662909c --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/extra-word.profdata @@ -0,0 +1,2 @@ +extra 1 word +1 diff --git a/test/tools/llvm-profdata/Inputs/extra-word.profdata.input b/test/tools/llvm-profdata/Inputs/extra-word.profdata.input deleted file mode 100644 index 67a662909c..0000000000 --- a/test/tools/llvm-profdata/Inputs/extra-word.profdata.input +++ /dev/null @@ -1,2 +0,0 @@ -extra 1 word -1 diff --git a/test/tools/llvm-profdata/Inputs/foo3-1.profdata b/test/tools/llvm-profdata/Inputs/foo3-1.profdata new file mode 100644 index 0000000000..d6f9f648b7 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/foo3-1.profdata @@ -0,0 +1,4 @@ +foo 3 +1 +2 +3 diff --git a/test/tools/llvm-profdata/Inputs/foo3-1.profdata.input b/test/tools/llvm-profdata/Inputs/foo3-1.profdata.input deleted file mode 100644 index 14a6200435..0000000000 --- a/test/tools/llvm-profdata/Inputs/foo3-1.profdata.input +++ /dev/null @@ -1,6 +0,0 @@ -foo -3 -3 -1 -2 -3 diff --git a/test/tools/llvm-profdata/Inputs/foo3-2.profdata b/test/tools/llvm-profdata/Inputs/foo3-2.profdata new file mode 100644 index 0000000000..94fd034391 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/foo3-2.profdata @@ -0,0 +1,4 @@ +foo 3 +7 +5 +3 diff --git a/test/tools/llvm-profdata/Inputs/foo3-2.profdata.input b/test/tools/llvm-profdata/Inputs/foo3-2.profdata.input deleted file mode 100644 index 801846e440..0000000000 --- a/test/tools/llvm-profdata/Inputs/foo3-2.profdata.input +++ /dev/null @@ -1,6 +0,0 @@ -foo -3 -3 -7 -5 -3 diff --git a/test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata b/test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata new file mode 100644 index 0000000000..85b702d497 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata @@ -0,0 +1,9 @@ +foo 3 +2 +3 +5 + +bar 3 +7 +11 +13 diff --git a/test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata.input b/test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata.input deleted file mode 100644 index 12157b9f9a..0000000000 --- a/test/tools/llvm-profdata/Inputs/foo3bar3-1.profdata.input +++ /dev/null @@ -1,13 +0,0 @@ -foo -3 -3 -2 -3 -5 - -bar -3 -3 -7 -11 -13 diff --git a/test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata b/test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata new file mode 100644 index 0000000000..d652781a35 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata @@ -0,0 +1,9 @@ +foo 3 +17 +19 +23 + +bar 3 +29 +31 +37 diff --git a/test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata.input b/test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata.input deleted file mode 100644 index f1f10bd6f3..0000000000 --- a/test/tools/llvm-profdata/Inputs/foo3bar3-2.profdata.input +++ /dev/null @@ -1,13 +0,0 @@ -foo -3 -3 -17 -19 -23 - -bar -3 -3 -29 -31 -37 diff --git a/test/tools/llvm-profdata/Inputs/foo4-1.profdata b/test/tools/llvm-profdata/Inputs/foo4-1.profdata new file mode 100644 index 0000000000..4d694080bf --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/foo4-1.profdata @@ -0,0 +1,5 @@ +foo 4 +11 +22 +33 +44 diff --git a/test/tools/llvm-profdata/Inputs/foo4-1.profdata.input b/test/tools/llvm-profdata/Inputs/foo4-1.profdata.input deleted file mode 100644 index 31d2a2ce75..0000000000 --- a/test/tools/llvm-profdata/Inputs/foo4-1.profdata.input +++ /dev/null @@ -1,7 +0,0 @@ -foo -4 -4 -11 -22 -33 -44 diff --git a/test/tools/llvm-profdata/Inputs/foo4-2.profdata b/test/tools/llvm-profdata/Inputs/foo4-2.profdata new file mode 100644 index 0000000000..8d91d8bbef --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/foo4-2.profdata @@ -0,0 +1,5 @@ +foo 4 +7 +6 +5 +4 diff --git a/test/tools/llvm-profdata/Inputs/foo4-2.profdata.input b/test/tools/llvm-profdata/Inputs/foo4-2.profdata.input deleted file mode 100644 index 01d8309b5c..0000000000 --- a/test/tools/llvm-profdata/Inputs/foo4-2.profdata.input +++ /dev/null @@ -1,7 +0,0 @@ -foo -4 -4 -7 -6 -5 -4 diff --git a/test/tools/llvm-profdata/Inputs/invalid-count-later.profdata b/test/tools/llvm-profdata/Inputs/invalid-count-later.profdata new file mode 100644 index 0000000000..5575df3fda --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/invalid-count-later.profdata @@ -0,0 +1,2 @@ +invalid_count 1 +1later diff --git a/test/tools/llvm-profdata/Inputs/invalid-count-later.profdata.input b/test/tools/llvm-profdata/Inputs/invalid-count-later.profdata.input deleted file mode 100644 index 2b61c55a67..0000000000 --- a/test/tools/llvm-profdata/Inputs/invalid-count-later.profdata.input +++ /dev/null @@ -1,4 +0,0 @@ -invalid_count -1 -1 -1later diff --git a/test/tools/llvm-profdata/Inputs/overflow.profdata b/test/tools/llvm-profdata/Inputs/overflow.profdata new file mode 100644 index 0000000000..bfb9a52d2e --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/overflow.profdata @@ -0,0 +1,2 @@ +overflow 1 +9223372036854775808 diff --git a/test/tools/llvm-profdata/Inputs/overflow.profdata.input b/test/tools/llvm-profdata/Inputs/overflow.profdata.input deleted file mode 100644 index c9a9d697ec..0000000000 --- a/test/tools/llvm-profdata/Inputs/overflow.profdata.input +++ /dev/null @@ -1,4 +0,0 @@ -overflow -1 -1 -9223372036854775808 diff --git a/test/tools/llvm-profdata/Inputs/three-words-long.profdata b/test/tools/llvm-profdata/Inputs/three-words-long.profdata new file mode 100644 index 0000000000..a4d45fb3bf --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/three-words-long.profdata @@ -0,0 +1 @@ +three words long diff --git a/test/tools/llvm-profdata/Inputs/three-words-long.profdata.input b/test/tools/llvm-profdata/Inputs/three-words-long.profdata.input deleted file mode 100644 index a4d45fb3bf..0000000000 --- a/test/tools/llvm-profdata/Inputs/three-words-long.profdata.input +++ /dev/null @@ -1 +0,0 @@ -three words long diff --git a/test/tools/llvm-profdata/Inputs/wrong-count.profdata.input b/test/tools/llvm-profdata/Inputs/wrong-count.profdata.input deleted file mode 100644 index 129db626d1..0000000000 --- a/test/tools/llvm-profdata/Inputs/wrong-count.profdata.input +++ /dev/null @@ -1,4 +0,0 @@ -wrong_count -3 -3 -1 diff --git a/test/tools/llvm-profdata/errors.test b/test/tools/llvm-profdata/errors.test new file mode 100644 index 0000000000..6335ea95f9 --- /dev/null +++ b/test/tools/llvm-profdata/errors.test @@ -0,0 +1,22 @@ +RUN: not llvm-profdata %p/Inputs/empty.profdata %p/Inputs/foo3-1.profdata 2>&1 | FileCheck %s --check-prefix=LENGTH +RUN: not llvm-profdata %p/Inputs/foo3-1.profdata %p/Inputs/foo3bar3-1.profdata 2>&1 | FileCheck %s --check-prefix=LENGTH +RUN: not llvm-profdata %p/Inputs/foo4-1.profdata %p/Inputs/empty.profdata 2>&1 | FileCheck %s --check-prefix=LENGTH +LENGTH: error: {{.*}}: truncated file + +RUN: not llvm-profdata %p/Inputs/foo3-1.profdata %p/Inputs/bar3-1.profdata 2>&1 | FileCheck %s --check-prefix=NAME +NAME: error: {{.*}}: function name mismatch + +RUN: not llvm-profdata %p/Inputs/foo3-1.profdata %p/Inputs/foo4-1.profdata 2>&1 | FileCheck %s --check-prefix=COUNT +COUNT: error: {{.*}}: function count mismatch + +RUN: not llvm-profdata %p/Inputs/overflow.profdata %p/Inputs/overflow.profdata 2>&1 | FileCheck %s --check-prefix=OVERFLOW +OVERFLOW: error: {{.*}}: counter overflow + +RUN: not llvm-profdata %p/Inputs/invalid-count-later.profdata %p/Inputs/invalid-count-later.profdata 2>&1 | FileCheck %s --check-prefix=INVALID-COUNT-LATER +INVALID-COUNT-LATER: error: {{.*}}: invalid counter + +RUN: not llvm-profdata %p/Inputs/bad-function-count.profdata %p/Inputs/bad-function-count.profdata 2>&1 | FileCheck %s --check-prefix=BAD-FUNCTION-COUNT +BAD-FUNCTION-COUNT: error: {{.*}}: bad function count + +RUN: not llvm-profdata %p/Inputs/three-words-long.profdata %p/Inputs/three-words-long.profdata 2>&1 | FileCheck %s --check-prefix=INVALID-DATA +INVALID-DATA: error: {{.*}}: invalid data diff --git a/test/tools/llvm-profdata/generate.test b/test/tools/llvm-profdata/generate.test deleted file mode 100644 index 71e8b50fca..0000000000 --- a/test/tools/llvm-profdata/generate.test +++ /dev/null @@ -1,38 +0,0 @@ -RUN: llvm-profdata generate %p/Inputs/empty.profdata.input | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=EMPTY - -EMPTY: Total functions: 0 -EMPTY: Maximum function count: 0 -EMPTY: Maximum internal block count: 0 - -RUN: llvm-profdata generate %p/Inputs/foo3-1.profdata.input | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO3 - -FOO3: foo: -FOO3: Counters: 3 -FOO3: Function count: 1 -FOO3: Block counts: [2, 3] -FOO3: Total functions: 1 -FOO3: Maximum function count: 1 -FOO3: Maximum internal block count: 3 - -RUN: llvm-profdata generate %p/Inputs/foo3bar3-1.profdata.input | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO3BAR3 - -FOO3BAR3: foo: -FOO3BAR3: Counters: 3 -FOO3BAR3: Function count: 2 -FOO3BAR3: Block counts: [3, 5] -FOO3BAR3: bar: -FOO3BAR3: Counters: 3 -FOO3BAR3: Function count: 7 -FOO3BAR3: Block counts: [11, 13] -FOO3BAR3: Total functions: 2 -FOO3BAR3: Maximum function count: 7 -FOO3BAR3: Maximum internal block count: 13 - -RUN: not llvm-profdata generate %p/Inputs/invalid-count-later.profdata.input -o /dev/null 2>&1 | FileCheck %s --check-prefix=INVALID-COUNT-LATER -INVALID-COUNT-LATER: error: {{.*}}: Failed to read counter - -RUN: not llvm-profdata generate %p/Inputs/bad-hash.profdata.input -o /dev/null 2>&1 | FileCheck %s --check-prefix=BAD-HASH -BAD-HASH: error: {{.*}}: Failed to read hash - -RUN: not llvm-profdata generate %p/Inputs/wrong-count.profdata.input -o /dev/null 2>&1 | FileCheck %s --check-prefix=BAD-FUNCTION-COUNT -BAD-FUNCTION-COUNT: error: {{.*}}: Truncated file diff --git a/test/tools/llvm-profdata/merge-errors.test b/test/tools/llvm-profdata/merge-errors.test deleted file mode 100644 index 1ab08be9f1..0000000000 --- a/test/tools/llvm-profdata/merge-errors.test +++ /dev/null @@ -1,21 +0,0 @@ -RUN: llvm-profdata generate %p/Inputs/empty.profdata.input > %t-empty.profdata -RUN: llvm-profdata generate %p/Inputs/foo3-1.profdata.input > %t-foo3-1.profdata -RUN: llvm-profdata generate %p/Inputs/bar3-1.profdata.input > %t-bar3-1.profdata -RUN: llvm-profdata generate %p/Inputs/foo3bar3-1.profdata.input > %t-foo3bar3-1.profdata -RUN: llvm-profdata generate %p/Inputs/foo4-1.profdata.input > %t-foo4-1.profdata - -RUN: not llvm-profdata merge %t-empty.profdata %t-foo3-1.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=LENGTH -RUN: not llvm-profdata merge %t-foo3-1.profdata %t-foo3bar3-1.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=LENGTH -RUN: not llvm-profdata merge %t-foo4-1.profdata %t-empty.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=LENGTH -LENGTH: error: {{.*}}: Truncated file - -RUN: not llvm-profdata merge %t-foo3-1.profdata %t-bar3-1.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=NAME -NAME: error: {{.*}}: Function name mismatch - -RUN: not llvm-profdata merge %t-foo3-1.profdata %t-foo4-1.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=COUNT -COUNT: error: {{.*}}: Function count mismatch - -RUN: llvm-profdata generate %p/Inputs/overflow.profdata.input > %t-overflow.profdata - -RUN: not llvm-profdata merge %t-overflow.profdata %t-overflow.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW -OVERFLOW: error: {{.*}}: Counter overflow diff --git a/test/tools/llvm-profdata/simple-merges.test b/test/tools/llvm-profdata/simple-merges.test deleted file mode 100644 index 401ae6b58e..0000000000 --- a/test/tools/llvm-profdata/simple-merges.test +++ /dev/null @@ -1,33 +0,0 @@ -RUN: llvm-profdata generate %p/Inputs/foo3-1.profdata.input > %t-foo3-1.profdata -RUN: llvm-profdata generate %p/Inputs/foo3-2.profdata.input > %t-foo3-2.profdata - -RUN: llvm-profdata merge %t-foo3-1.profdata %t-foo3-2.profdata 2>&1 | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO3 -RUN: llvm-profdata merge %t-foo3-2.profdata %t-foo3-1.profdata 2>&1 | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO3 -FOO3: foo: -FOO3: Counters: 3 -FOO3: Function count: 8 -FOO3: Block counts: [7, 6] - -RUN: llvm-profdata generate %p/Inputs/foo4-1.profdata.input > %t-foo4-1.profdata -RUN: llvm-profdata generate %p/Inputs/foo4-2.profdata.input > %t-foo4-2.profdata - -RUN: llvm-profdata merge %t-foo4-1.profdata %t-foo4-2.profdata 2>&1 | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO4 -RUN: llvm-profdata merge %t-foo4-2.profdata %t-foo4-1.profdata 2>&1 | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO4 -FOO4: foo: -FOO4: Counters: 4 -FOO4: Function count: 18 -FOO4: Block counts: [28, 38, 48] - -RUN: llvm-profdata generate %p/Inputs/foo3bar3-1.profdata.input > %t-foo3bar3-1.profdata -RUN: llvm-profdata generate %p/Inputs/foo3bar3-2.profdata.input > %t-foo3bar3-2.profdata - -RUN: llvm-profdata merge %t-foo3bar3-1.profdata %t-foo3bar3-2.profdata 2>&1 | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO3BAR3 -RUN: llvm-profdata merge %t-foo3bar3-2.profdata %t-foo3bar3-1.profdata 2>&1 | llvm-profdata show -all-functions -counts - | FileCheck %s --check-prefix=FOO3BAR3 -FOO3BAR3: foo: -FOO3BAR3: Counters: 3 -FOO3BAR3: Function count: 19 -FOO3BAR3: Block counts: [22, 28] -FOO3BAR3: bar: -FOO3BAR3: Counters: 3 -FOO3BAR3: Function count: 36 -FOO3BAR3: Block counts: [42, 50] diff --git a/test/tools/llvm-profdata/simple.test b/test/tools/llvm-profdata/simple.test new file mode 100644 index 0000000000..87073fad9c --- /dev/null +++ b/test/tools/llvm-profdata/simple.test @@ -0,0 +1,25 @@ +RUN: llvm-profdata %p/Inputs/foo3-1.profdata %p/Inputs/foo3-2.profdata 2>&1 | FileCheck %s --check-prefix=FOO3 +RUN: llvm-profdata %p/Inputs/foo3-2.profdata %p/Inputs/foo3-1.profdata 2>&1 | FileCheck %s --check-prefix=FOO3 +FOO3: {{^foo 3$}} +FOO3-NEXT: {{^8$}} +FOO3-NEXT: {{^7$}} +FOO3-NEXT: {{^6$}} + +RUN: llvm-profdata %p/Inputs/foo4-1.profdata %p/Inputs/foo4-2.profdata 2>&1 | FileCheck %s --check-prefix=FOO4 +RUN: llvm-profdata %p/Inputs/foo4-2.profdata %p/Inputs/foo4-1.profdata 2>&1 | FileCheck %s --check-prefix=FOO4 +FOO4: {{^foo 4$}} +FOO4-NEXT: {{^18$}} +FOO4-NEXT: {{^28$}} +FOO4-NEXT: {{^38$}} +FOO4-NEXT: {{^48$}} + +RUN: llvm-profdata %p/Inputs/foo3bar3-1.profdata %p/Inputs/foo3bar3-2.profdata 2>&1 | FileCheck %s --check-prefix=FOO3BAR3 +RUN: llvm-profdata %p/Inputs/foo3bar3-2.profdata %p/Inputs/foo3bar3-1.profdata 2>&1 | FileCheck %s --check-prefix=FOO3BAR3 +FOO3BAR3: {{^foo 3$}} +FOO3BAR3-NEXT: {{^19$}} +FOO3BAR3-NEXT: {{^22$}} +FOO3BAR3-NEXT: {{^28$}} +FOO3BAR3: {{^bar 3$}} +FOO3BAR3-NEXT: {{^36$}} +FOO3BAR3-NEXT: {{^42$}} +FOO3BAR3-NEXT: {{^50$}} 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