Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ProfileData: Introduce InstrProfWriter using the naive text format
This isn't a format we'll want to write out in practice, but moving it to the writer library simplifies llvm-profdata and isolates it from further changes to the format. This also allows us to update the tests to not rely on the text output format. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@204489 91177308-0d34-0410-b5e6-96231b3b80d8
- Loading branch information
Showing
8 changed files
with
205 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//=-- InstrProfWriter.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_PROFILEDATA_INSTRPROF_WRITER_H__ | ||
#define LLVM_PROFILEDATA_INSTRPROF_WRITER_H__ | ||
|
||
#include "llvm/ADT/ArrayRef.h" | ||
#include "llvm/ADT/StringMap.h" | ||
#include "llvm/ProfileData/InstrProf.h" | ||
#include "llvm/Support/DataTypes.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
|
||
#include <vector> | ||
|
||
namespace llvm { | ||
|
||
/// Writer for instrumentation based profile data. | ||
class InstrProfWriter { | ||
public: | ||
struct CounterData { | ||
uint64_t Hash; | ||
std::vector<uint64_t> Counts; | ||
}; | ||
private: | ||
StringMap<CounterData> FunctionData; | ||
public: | ||
/// Add function counts for the given function. If there are already counts | ||
/// for this function and the hash and number of counts match, each counter is | ||
/// summed. | ||
error_code addFunctionCounts(StringRef FunctionName, uint64_t FunctionHash, | ||
ArrayRef<uint64_t> Counters); | ||
/// Ensure that all data is written to disk. | ||
void write(raw_ostream &OS); | ||
}; | ||
|
||
} // end namespace llvm | ||
|
||
#endif // LLVM_PROFILE_INSTRPROF_WRITER_H__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
add_llvm_library(LLVMProfileData | ||
InstrProf.cpp | ||
InstrProfReader.cpp | ||
InstrProfWriter.cpp | ||
|
||
LINK_LIBS | ||
LLVMSupport | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
//=-- InstrProfWriter.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/ProfileData/InstrProfWriter.h" | ||
#include "llvm/Support/Endian.h" | ||
|
||
using namespace llvm; | ||
|
||
error_code InstrProfWriter::addFunctionCounts(StringRef FunctionName, | ||
uint64_t FunctionHash, | ||
ArrayRef<uint64_t> Counters) { | ||
auto Where = FunctionData.find(FunctionName); | ||
if (Where == FunctionData.end()) { | ||
// If this is the first time we've seen this function, just add it. | ||
FunctionData[FunctionName] = {FunctionHash, Counters}; | ||
return instrprof_error::success;; | ||
} | ||
|
||
auto &Data = Where->getValue(); | ||
// We can only add to existing functions if they match, so we check the hash | ||
// and number of counters. | ||
if (Data.Hash != FunctionHash) | ||
return instrprof_error::hash_mismatch; | ||
if (Data.Counts.size() != Counters.size()) | ||
return instrprof_error::count_mismatch; | ||
// These match, add up the counters. | ||
for (size_t I = 0, E = Counters.size(); I < E; ++I) { | ||
if (Data.Counts[I] + Counters[I] < Data.Counts[I]) | ||
return instrprof_error::counter_overflow; | ||
Data.Counts[I] += Counters[I]; | ||
} | ||
return instrprof_error::success; | ||
} | ||
|
||
void InstrProfWriter::write(raw_ostream &OS) { | ||
// Write out the counts for each function. | ||
for (const auto &I : FunctionData) { | ||
StringRef Name = I.getKey(); | ||
uint64_t Hash = I.getValue().Hash; | ||
const std::vector<uint64_t> &Counts = I.getValue().Counts; | ||
|
||
OS << Name << "\n" << Hash << "\n" << Counts.size() << "\n"; | ||
for (uint64_t Count : Counts) | ||
OS << Count << "\n"; | ||
OS << "\n"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,19 +1,11 @@ | ||
RUN: not llvm-profdata merge %p/Inputs/empty.profdata %p/Inputs/foo3-1.profdata 2>&1 | FileCheck %s --check-prefix=LENGTH | ||
RUN: not llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/foo3bar3-1.profdata 2>&1 | FileCheck %s --check-prefix=LENGTH | ||
RUN: not llvm-profdata merge %p/Inputs/foo4-1.profdata %p/Inputs/empty.profdata 2>&1 | FileCheck %s --check-prefix=LENGTH | ||
LENGTH: error: Number of instrumented functions differ | ||
RUN: llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/foo4-1.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=HASH | ||
HASH: foo4-1.profdata: foo: Function hash mismatch | ||
|
||
RUN: not llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/bar3-1.profdata 2>&1 | FileCheck %s --check-prefix=NAME | ||
NAME: error: Function name mismatch, foo != bar | ||
|
||
RUN: not llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/foo4-1.profdata 2>&1 | FileCheck %s --check-prefix=HASH | ||
HASH: error: Function hash mismatch for foo | ||
|
||
RUN: not llvm-profdata merge %p/Inputs/overflow.profdata %p/Inputs/overflow.profdata 2>&1 | FileCheck %s --check-prefix=OVERFLOW | ||
OVERFLOW: error: Counter overflow for overflow | ||
RUN: llvm-profdata merge %p/Inputs/overflow.profdata %p/Inputs/overflow.profdata -o /dev/null 2>&1 | FileCheck %s --check-prefix=OVERFLOW | ||
OVERFLOW: overflow.profdata: overflow: Counter overflow | ||
|
||
RUN: not llvm-profdata merge %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: {{.*}}: Malformed profile data | ||
INVALID-COUNT-LATER: error: {{.*}}invalid-count-later.profdata: Malformed profile data | ||
|
||
RUN: not llvm-profdata merge %p/Inputs/bad-hash.profdata %p/Inputs/bad-hash.profdata 2>&1 | FileCheck %s --check-prefix=BAD-HASH | ||
BAD-HASH: error: {{.*}}: Malformed profile data | ||
BAD-HASH: error: {{.*}}bad-hash.profdata: Malformed profile data |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,68 @@ | ||
RUN: llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/foo3-2.profdata 2>&1 | FileCheck %s --check-prefix=FOO3 | ||
RUN: llvm-profdata merge %p/Inputs/foo3-2.profdata %p/Inputs/foo3-1.profdata 2>&1 | FileCheck %s --check-prefix=FOO3 | ||
FOO3: {{^foo$}} | ||
FOO3-NEXT: {{^3$}} | ||
FOO3-NEXT: {{^3$}} | ||
FOO3-NEXT: {{^8$}} | ||
FOO3-NEXT: {{^7$}} | ||
FOO3-NEXT: {{^6$}} | ||
RUN: llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/foo3-2.profdata 2>&1 | llvm-profdata show - -all-functions -counts | FileCheck %s --check-prefix=FOO3 | ||
RUN: llvm-profdata merge %p/Inputs/foo3-2.profdata %p/Inputs/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] | ||
FOO3: Total functions: 1 | ||
FOO3: Maximum function count: 8 | ||
FOO3: Maximum internal block count: 7 | ||
|
||
RUN: llvm-profdata merge %p/Inputs/foo4-1.profdata %p/Inputs/foo4-2.profdata 2>&1 | FileCheck %s --check-prefix=FOO4 | ||
RUN: llvm-profdata merge %p/Inputs/foo4-2.profdata %p/Inputs/foo4-1.profdata 2>&1 | FileCheck %s --check-prefix=FOO4 | ||
FOO4: {{^foo$}} | ||
FOO4-NEXT: {{^4$}} | ||
FOO4-NEXT: {{^4$}} | ||
FOO4-NEXT: {{^18$}} | ||
FOO4-NEXT: {{^28$}} | ||
FOO4-NEXT: {{^38$}} | ||
FOO4-NEXT: {{^48$}} | ||
RUN: llvm-profdata merge %p/Inputs/foo4-1.profdata %p/Inputs/foo4-2.profdata 2>&1 | llvm-profdata show - -all-functions -counts | FileCheck %s --check-prefix=FOO4 | ||
RUN: llvm-profdata merge %p/Inputs/foo4-2.profdata %p/Inputs/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] | ||
FOO4: Total functions: 1 | ||
FOO4: Maximum function count: 18 | ||
FOO4: Maximum internal block count: 48 | ||
|
||
RUN: llvm-profdata merge %p/Inputs/foo3bar3-1.profdata %p/Inputs/foo3bar3-2.profdata 2>&1 | FileCheck %s --check-prefix=FOO3BAR3 | ||
RUN: llvm-profdata merge %p/Inputs/foo3bar3-2.profdata %p/Inputs/foo3bar3-1.profdata 2>&1 | FileCheck %s --check-prefix=FOO3BAR3 | ||
FOO3BAR3: {{^foo$}} | ||
FOO3BAR3-NEXT: {{^3$}} | ||
FOO3BAR3-NEXT: {{^3$}} | ||
FOO3BAR3-NEXT: {{^19$}} | ||
FOO3BAR3-NEXT: {{^22$}} | ||
FOO3BAR3-NEXT: {{^28$}} | ||
FOO3BAR3: {{^bar$}} | ||
FOO3BAR3-NEXT: {{^3$}} | ||
FOO3BAR3-NEXT: {{^3$}} | ||
FOO3BAR3-NEXT: {{^36$}} | ||
FOO3BAR3-NEXT: {{^42$}} | ||
FOO3BAR3-NEXT: {{^50$}} | ||
RUN: llvm-profdata merge %p/Inputs/foo3bar3-1.profdata %p/Inputs/foo3bar3-2.profdata 2>&1 | llvm-profdata show - -all-functions -counts | FileCheck %s --check-prefix=FOO3BAR3 | ||
RUN: llvm-profdata merge %p/Inputs/foo3bar3-2.profdata %p/Inputs/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] | ||
FOO3BAR3: Total functions: 2 | ||
FOO3BAR3: Maximum function count: 36 | ||
FOO3BAR3: Maximum internal block count: 50 | ||
|
||
RUN: llvm-profdata merge %p/Inputs/empty.profdata %p/Inputs/foo3-1.profdata 2>&1 | llvm-profdata show - -all-functions -counts | FileCheck %s --check-prefix=FOO3EMPTY | ||
FOO3EMPTY: foo: | ||
FOO3EMPTY: Counters: 3 | ||
FOO3EMPTY: Function count: 1 | ||
FOO3EMPTY: Block counts: [2, 3] | ||
FOO3EMPTY: Total functions: 1 | ||
FOO3EMPTY: Maximum function count: 1 | ||
FOO3EMPTY: Maximum internal block count: 3 | ||
|
||
RUN: llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/foo3bar3-1.profdata 2>&1 | llvm-profdata show - -all-functions -counts | FileCheck %s --check-prefix=FOO3FOO3BAR3 | ||
FOO3FOO3BAR3: foo: | ||
FOO3FOO3BAR3: Counters: 3 | ||
FOO3FOO3BAR3: Function count: 3 | ||
FOO3FOO3BAR3: Block counts: [5, 8] | ||
FOO3FOO3BAR3: bar: | ||
FOO3FOO3BAR3: Counters: 3 | ||
FOO3FOO3BAR3: Function count: 7 | ||
FOO3FOO3BAR3: Block counts: [11, 13] | ||
FOO3FOO3BAR3: Total functions: 2 | ||
FOO3FOO3BAR3: Maximum function count: 7 | ||
FOO3FOO3BAR3: Maximum internal block count: 13 | ||
|
||
RUN: llvm-profdata merge %p/Inputs/foo3-1.profdata %p/Inputs/bar3-1.profdata 2>&1 | llvm-profdata show - -all-functions -counts | FileCheck %s --check-prefix=DISJOINT | ||
DISJOINT: foo: | ||
DISJOINT: Counters: 3 | ||
DISJOINT: Function count: 1 | ||
DISJOINT: Block counts: [2, 3] | ||
DISJOINT: bar: | ||
DISJOINT: Counters: 3 | ||
DISJOINT: Function count: 1 | ||
DISJOINT: Block counts: [2, 3] | ||
DISJOINT: Total functions: 2 | ||
DISJOINT: Maximum function count: 1 | ||
DISJOINT: Maximum internal block count: 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters