mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-04-02 13:12:09 +00:00
Revert "[llvm-profdata] Add support for weighted merge of profile data"
This reverts commit b7250858d96b8ce567681214273ac0e62713c661. Reverting in order to investigate Windows test failure. llvm-svn: 254687
This commit is contained in:
parent
7cc13f2e58
commit
cb921a1d88
@ -28,7 +28,7 @@ MERGE
|
||||
SYNOPSIS
|
||||
^^^^^^^^
|
||||
|
||||
:program:`llvm-profdata merge` [*options*] [*filename[:weight]...*]
|
||||
:program:`llvm-profdata merge` [*options*] [*filenames...*]
|
||||
|
||||
DESCRIPTION
|
||||
^^^^^^^^^^^
|
||||
@ -37,10 +37,6 @@ DESCRIPTION
|
||||
generated by PGO instrumentation and merges them together into a single
|
||||
indexed profile data file.
|
||||
|
||||
The profile counts in each input file can be scaled (multiplied) by specifying
|
||||
``<filename>:<weight>``, where `<weight>` is a decimal integer >= 1.
|
||||
A default weight of 1 is assumed if only `<filename>` is given.
|
||||
|
||||
OPTIONS
|
||||
^^^^^^^
|
||||
|
||||
|
@ -218,8 +218,7 @@ struct InstrProfValueSiteRecord {
|
||||
}
|
||||
|
||||
/// Merge data from another InstrProfValueSiteRecord
|
||||
/// Optionally scale merged counts by \p Weight.
|
||||
void mergeValueData(InstrProfValueSiteRecord &Input, uint64_t Weight = 1) {
|
||||
void mergeValueData(InstrProfValueSiteRecord &Input) {
|
||||
this->sortByTargetValues();
|
||||
Input.sortByTargetValues();
|
||||
auto I = ValueData.begin();
|
||||
@ -229,11 +228,7 @@ struct InstrProfValueSiteRecord {
|
||||
while (I != IE && I->Value < J->Value)
|
||||
++I;
|
||||
if (I != IE && I->Value == J->Value) {
|
||||
// TODO: Check for counter overflow and return error if it occurs.
|
||||
uint64_t JCount = J->Count;
|
||||
if (Weight > 1)
|
||||
JCount = SaturatingMultiply(JCount, Weight);
|
||||
I->Count = SaturatingAdd(I->Count, JCount);
|
||||
I->Count = SaturatingAdd(I->Count, J->Count);
|
||||
++I;
|
||||
continue;
|
||||
}
|
||||
@ -279,8 +274,7 @@ struct InstrProfRecord {
|
||||
ValueMapType *HashKeys);
|
||||
|
||||
/// Merge the counts in \p Other into this one.
|
||||
/// Optionally scale merged counts by \p Weight.
|
||||
inline instrprof_error merge(InstrProfRecord &Other, uint64_t Weight = 1);
|
||||
inline instrprof_error merge(InstrProfRecord &Other);
|
||||
|
||||
/// Used by InstrProfWriter: update the value strings to commoned strings in
|
||||
/// the writer instance.
|
||||
@ -332,9 +326,7 @@ private:
|
||||
}
|
||||
|
||||
// Merge Value Profile data from Src record to this record for ValueKind.
|
||||
// Scale merged value counts by \p Weight.
|
||||
instrprof_error mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src,
|
||||
uint64_t Weight) {
|
||||
instrprof_error mergeValueProfData(uint32_t ValueKind, InstrProfRecord &Src) {
|
||||
uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
|
||||
uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
|
||||
if (ThisNumValueSites != OtherNumValueSites)
|
||||
@ -344,7 +336,7 @@ private:
|
||||
std::vector<InstrProfValueSiteRecord> &OtherSiteRecords =
|
||||
Src.getValueSitesForKind(ValueKind);
|
||||
for (uint32_t I = 0; I < ThisNumValueSites; I++)
|
||||
ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I], Weight);
|
||||
ThisSiteRecords[I].mergeValueData(OtherSiteRecords[I]);
|
||||
return instrprof_error::success;
|
||||
}
|
||||
};
|
||||
@ -430,8 +422,7 @@ void InstrProfRecord::updateStrings(InstrProfStringTable *StrTab) {
|
||||
VData.Value = (uint64_t)StrTab->insertString((const char *)VData.Value);
|
||||
}
|
||||
|
||||
instrprof_error InstrProfRecord::merge(InstrProfRecord &Other,
|
||||
uint64_t Weight) {
|
||||
instrprof_error InstrProfRecord::merge(InstrProfRecord &Other) {
|
||||
// If the number of counters doesn't match we either have bad data
|
||||
// or a hash collision.
|
||||
if (Counts.size() != Other.Counts.size())
|
||||
@ -441,19 +432,13 @@ instrprof_error InstrProfRecord::merge(InstrProfRecord &Other,
|
||||
|
||||
for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
|
||||
bool ResultOverflowed;
|
||||
uint64_t OtherCount = Other.Counts[I];
|
||||
if (Weight > 1) {
|
||||
OtherCount = SaturatingMultiply(OtherCount, Weight, ResultOverflowed);
|
||||
if (ResultOverflowed)
|
||||
Result = instrprof_error::counter_overflow;
|
||||
}
|
||||
Counts[I] = SaturatingAdd(Counts[I], OtherCount, ResultOverflowed);
|
||||
Counts[I] = SaturatingAdd(Counts[I], Other.Counts[I], ResultOverflowed);
|
||||
if (ResultOverflowed)
|
||||
Result = instrprof_error::counter_overflow;
|
||||
}
|
||||
|
||||
for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
|
||||
instrprof_error MergeValueResult = mergeValueProfData(Kind, Other, Weight);
|
||||
instrprof_error MergeValueResult = mergeValueProfData(Kind, Other);
|
||||
if (MergeValueResult != instrprof_error::success)
|
||||
Result = MergeValueResult;
|
||||
}
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
void updateStringTableReferences(InstrProfRecord &I);
|
||||
/// 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. Optionally scale counts by \p Weight.
|
||||
std::error_code addRecord(InstrProfRecord &&I, uint64_t Weight = 1);
|
||||
/// summed.
|
||||
std::error_code addRecord(InstrProfRecord &&I);
|
||||
/// Write the profile to \c OS
|
||||
void write(raw_fd_ostream &OS);
|
||||
/// Write the profile in text format to \c OS
|
||||
|
@ -173,25 +173,19 @@ public:
|
||||
SampleRecord() : NumSamples(0), CallTargets() {}
|
||||
|
||||
/// Increment the number of samples for this record by \p S.
|
||||
/// Optionally scale sample count \p S by \p Weight.
|
||||
///
|
||||
/// Sample counts accumulate using saturating arithmetic, to avoid wrapping
|
||||
/// around unsigned integers.
|
||||
void addSamples(uint64_t S, uint64_t Weight = 1) {
|
||||
if (Weight > 1)
|
||||
S = SaturatingMultiply(S, Weight);
|
||||
void addSamples(uint64_t S) {
|
||||
NumSamples = SaturatingAdd(NumSamples, S);
|
||||
}
|
||||
|
||||
/// Add called function \p F with samples \p S.
|
||||
/// Optionally scale sample count \p S by \p Weight.
|
||||
///
|
||||
/// Sample counts accumulate using saturating arithmetic, to avoid wrapping
|
||||
/// around unsigned integers.
|
||||
void addCalledTarget(StringRef F, uint64_t S, uint64_t Weight = 1) {
|
||||
void addCalledTarget(StringRef F, uint64_t S) {
|
||||
uint64_t &TargetSamples = CallTargets[F];
|
||||
if (Weight > 1)
|
||||
S = SaturatingMultiply(S, Weight);
|
||||
TargetSamples = SaturatingAdd(TargetSamples, S);
|
||||
}
|
||||
|
||||
@ -202,11 +196,10 @@ public:
|
||||
const CallTargetMap &getCallTargets() const { return CallTargets; }
|
||||
|
||||
/// Merge the samples in \p Other into this record.
|
||||
/// Optionally scale sample counts by \p Weight.
|
||||
void merge(const SampleRecord &Other, uint64_t Weight = 1) {
|
||||
addSamples(Other.getSamples(), Weight);
|
||||
void merge(const SampleRecord &Other) {
|
||||
addSamples(Other.getSamples());
|
||||
for (const auto &I : Other.getCallTargets())
|
||||
addCalledTarget(I.first(), I.second, Weight);
|
||||
addCalledTarget(I.first(), I.second);
|
||||
}
|
||||
|
||||
void print(raw_ostream &OS, unsigned Indent) const;
|
||||
@ -233,26 +226,16 @@ public:
|
||||
FunctionSamples() : TotalSamples(0), TotalHeadSamples(0) {}
|
||||
void print(raw_ostream &OS = dbgs(), unsigned Indent = 0) const;
|
||||
void dump() const;
|
||||
void addTotalSamples(uint64_t Num, uint64_t Weight = 1) {
|
||||
if (Weight > 1)
|
||||
Num = SaturatingMultiply(Num, Weight);
|
||||
TotalSamples += Num;
|
||||
}
|
||||
void addHeadSamples(uint64_t Num, uint64_t Weight = 1) {
|
||||
if (Weight > 1)
|
||||
Num = SaturatingMultiply(Num, Weight);
|
||||
TotalHeadSamples += Num;
|
||||
}
|
||||
void addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num,
|
||||
uint64_t Weight = 1) {
|
||||
BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(Num,
|
||||
Weight);
|
||||
void addTotalSamples(uint64_t Num) { TotalSamples += Num; }
|
||||
void addHeadSamples(uint64_t Num) { TotalHeadSamples += Num; }
|
||||
void addBodySamples(uint32_t LineOffset, uint32_t Discriminator,
|
||||
uint64_t Num) {
|
||||
BodySamples[LineLocation(LineOffset, Discriminator)].addSamples(Num);
|
||||
}
|
||||
void addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator,
|
||||
std::string FName, uint64_t Num,
|
||||
uint64_t Weight = 1) {
|
||||
BodySamples[LineLocation(LineOffset, Discriminator)].addCalledTarget(
|
||||
FName, Num, Weight);
|
||||
std::string FName, uint64_t Num) {
|
||||
BodySamples[LineLocation(LineOffset, Discriminator)].addCalledTarget(FName,
|
||||
Num);
|
||||
}
|
||||
|
||||
/// Return the number of samples collected at the given location.
|
||||
@ -301,19 +284,18 @@ public:
|
||||
}
|
||||
|
||||
/// Merge the samples in \p Other into this one.
|
||||
/// Optionally scale samples by \p Weight.
|
||||
void merge(const FunctionSamples &Other, uint64_t Weight = 1) {
|
||||
addTotalSamples(Other.getTotalSamples(), Weight);
|
||||
addHeadSamples(Other.getHeadSamples(), Weight);
|
||||
void merge(const FunctionSamples &Other) {
|
||||
addTotalSamples(Other.getTotalSamples());
|
||||
addHeadSamples(Other.getHeadSamples());
|
||||
for (const auto &I : Other.getBodySamples()) {
|
||||
const LineLocation &Loc = I.first;
|
||||
const SampleRecord &Rec = I.second;
|
||||
BodySamples[Loc].merge(Rec, Weight);
|
||||
BodySamples[Loc].merge(Rec);
|
||||
}
|
||||
for (const auto &I : Other.getCallsiteSamples()) {
|
||||
const CallsiteLocation &Loc = I.first;
|
||||
const FunctionSamples &Rec = I.second;
|
||||
functionSamplesAt(Loc).merge(Rec, Weight);
|
||||
functionSamplesAt(Loc).merge(Rec);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,8 +98,7 @@ void InstrProfWriter::updateStringTableReferences(InstrProfRecord &I) {
|
||||
I.updateStrings(&StringTable);
|
||||
}
|
||||
|
||||
std::error_code InstrProfWriter::addRecord(InstrProfRecord &&I,
|
||||
uint64_t Weight) {
|
||||
std::error_code InstrProfWriter::addRecord(InstrProfRecord &&I) {
|
||||
updateStringTableReferences(I);
|
||||
auto &ProfileDataMap = FunctionData[I.Name];
|
||||
|
||||
@ -114,18 +113,9 @@ std::error_code InstrProfWriter::addRecord(InstrProfRecord &&I,
|
||||
// We've never seen a function with this name and hash, add it.
|
||||
Dest = std::move(I);
|
||||
Result = instrprof_error::success;
|
||||
if (Weight > 1) {
|
||||
for (auto &Count : Dest.Counts) {
|
||||
bool Overflowed;
|
||||
Count = SaturatingMultiply(Count, Weight, Overflowed);
|
||||
if (Overflowed && Result == instrprof_error::success) {
|
||||
Result = instrprof_error::counter_overflow;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// We're updating a function we've seen before.
|
||||
Result = Dest.merge(I, Weight);
|
||||
Result = Dest.merge(I);
|
||||
}
|
||||
|
||||
// We keep track of the max function count as we go for simplicity.
|
||||
|
Binary file not shown.
Binary file not shown.
@ -1,8 +0,0 @@
|
||||
bar:1772037:35370
|
||||
17: 35370
|
||||
18: 35370
|
||||
19: 7005
|
||||
20: 29407
|
||||
21: 12170
|
||||
23: 18150 bar:19829
|
||||
25: 36666
|
@ -1,8 +0,0 @@
|
||||
foo:1763288:35327
|
||||
7: 35327
|
||||
8: 35327
|
||||
9: 6930
|
||||
10: 29341
|
||||
11: 11906
|
||||
13: 18185 foo:19531
|
||||
15: 36458
|
@ -1,55 +0,0 @@
|
||||
Tests for weighted merge of instrumented profiles.
|
||||
|
||||
1- Merge the foo and bar profiles with unity weight and verify the combined output
|
||||
RUN: llvm-profdata merge --instr %p/Inputs/weight-instr-bar.profdata:1 %p/Inputs/weight-instr-foo.profdata:1 -o %t
|
||||
RUN: llvm-profdata show --instr -all-functions %t | FileCheck %s --check-prefix=WEIGHT1
|
||||
WEIGHT1: Counters:
|
||||
WEIGHT1: usage:
|
||||
WEIGHT1: Hash: 0x0000000000000000
|
||||
WEIGHT1: Counters: 1
|
||||
WEIGHT1: Function count: 0
|
||||
WEIGHT1: foo:
|
||||
WEIGHT1: Hash: 0x000000000000028a
|
||||
WEIGHT1: Counters: 3
|
||||
WEIGHT1: Function count: 866988873
|
||||
WEIGHT1: bar:
|
||||
WEIGHT1: Hash: 0x000000000000028a
|
||||
WEIGHT1: Counters: 3
|
||||
WEIGHT1: Function count: 866988873
|
||||
WEIGHT1: main:
|
||||
WEIGHT1: Hash: 0x7d31c47ea98f8248
|
||||
WEIGHT1: Counters: 60
|
||||
WEIGHT1: Function count: 2
|
||||
WEIGHT1: Functions shown: 4
|
||||
WEIGHT1: Total functions: 4
|
||||
WEIGHT1: Maximum function count: 866988873
|
||||
WEIGHT1: Maximum internal block count: 267914296
|
||||
|
||||
2- Merge the foo and bar profiles with weight 3x and 5x respectively and verify the combined output
|
||||
RUN: llvm-profdata merge --instr %p/Inputs/weight-instr-bar.profdata:3 %p/Inputs/weight-instr-foo.profdata:5 -o %t
|
||||
RUN: llvm-profdata show --instr -all-functions %t | FileCheck %s --check-prefix=WEIGHT2
|
||||
WEIGHT2: Counters:
|
||||
WEIGHT2: usage:
|
||||
WEIGHT2: Hash: 0x0000000000000000
|
||||
WEIGHT2: Counters: 1
|
||||
WEIGHT2: Function count: 0
|
||||
WEIGHT2: foo:
|
||||
WEIGHT2: Hash: 0x000000000000028a
|
||||
WEIGHT2: Counters: 3
|
||||
WEIGHT2: Function count: 4334944365
|
||||
WEIGHT2: bar:
|
||||
WEIGHT2: Hash: 0x000000000000028a
|
||||
WEIGHT2: Counters: 3
|
||||
WEIGHT2: Function count: 2600966619
|
||||
WEIGHT2: main:
|
||||
WEIGHT2: Hash: 0x7d31c47ea98f8248
|
||||
WEIGHT2: Counters: 60
|
||||
WEIGHT2: Function count: 8
|
||||
WEIGHT2: Functions shown: 4
|
||||
WEIGHT2: Total functions: 4
|
||||
WEIGHT2: Maximum function count: 4334944365
|
||||
WEIGHT2: Maximum internal block count: 1339571480
|
||||
|
||||
3- Bad merge: foo and bar profiles with invalid weights
|
||||
RUN: not llvm-profdata merge --instr %p/Inputs/weight-instr-bar.profdata:3 %p/Inputs/weight-instr-foo.profdata:-5 -o %t.out 2>&1 | FileCheck %s --check-prefix=ERROR3
|
||||
ERROR3: error: Input weight must be a positive integer.
|
@ -1,43 +0,0 @@
|
||||
Tests for weighted merge of sample profiles.
|
||||
|
||||
1- Merge the foo and bar profiles with unity weight and verify the combined output
|
||||
RUN: llvm-profdata merge --sample --text %p/Inputs/weight-sample-bar.proftext:1 %p/Inputs/weight-sample-foo.proftext:1 -o - | FileCheck %s --check-prefix=WEIGHT1
|
||||
WEIGHT1: foo:1763288:35327
|
||||
WEIGHT1: 7: 35327
|
||||
WEIGHT1: 8: 35327
|
||||
WEIGHT1: 9: 6930
|
||||
WEIGHT1: 10: 29341
|
||||
WEIGHT1: 11: 11906
|
||||
WEIGHT1: 13: 18185 foo:19531
|
||||
WEIGHT1: 15: 36458
|
||||
WEIGHT1: bar:1772037:35370
|
||||
WEIGHT1: 17: 35370
|
||||
WEIGHT1: 18: 35370
|
||||
WEIGHT1: 19: 7005
|
||||
WEIGHT1: 20: 29407
|
||||
WEIGHT1: 21: 12170
|
||||
WEIGHT1: 23: 18150 bar:19829
|
||||
WEIGHT1: 25: 36666
|
||||
|
||||
2- Merge the foo and bar profiles with weight 3x and 5x respectively and verify the combined output
|
||||
RUN: llvm-profdata merge --sample --text %p/Inputs/weight-sample-bar.proftext:3 %p/Inputs/weight-sample-foo.proftext:5 -o - | FileCheck %s --check-prefix=WEIGHT2
|
||||
WEIGHT2: foo:8816440:176635
|
||||
WEIGHT2: 7: 176635
|
||||
WEIGHT2: 8: 176635
|
||||
WEIGHT2: 9: 34650
|
||||
WEIGHT2: 10: 146705
|
||||
WEIGHT2: 11: 59530
|
||||
WEIGHT2: 13: 90925 foo:97655
|
||||
WEIGHT2: 15: 182290
|
||||
WEIGHT2: bar:5316111:106110
|
||||
WEIGHT2: 17: 106110
|
||||
WEIGHT2: 18: 106110
|
||||
WEIGHT2: 19: 21015
|
||||
WEIGHT2: 20: 88221
|
||||
WEIGHT2: 21: 36510
|
||||
WEIGHT2: 23: 54450 bar:59487
|
||||
WEIGHT2: 25: 109998
|
||||
|
||||
3- Bad merge: foo and bar profiles with invalid weights
|
||||
RUN: not llvm-profdata merge --sample --text %p/Inputs/weight-sample-bar.proftext:3 %p/Inputs/weight-sample-foo.proftext:-5 -o %t.out 2>&1 | FileCheck %s --check-prefix=ERROR3
|
||||
ERROR3: error: Input weight must be a positive integer.
|
@ -12,7 +12,6 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/ProfileData/InstrProfReader.h"
|
||||
@ -28,7 +27,6 @@
|
||||
#include "llvm/Support/PrettyStackTrace.h"
|
||||
#include "llvm/Support/Signals.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <tuple>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -95,17 +93,7 @@ static void handleMergeWriterError(std::error_code &Error,
|
||||
}
|
||||
}
|
||||
|
||||
struct WeightedFile {
|
||||
StringRef Filename;
|
||||
uint64_t Weight;
|
||||
|
||||
WeightedFile() {}
|
||||
|
||||
WeightedFile(StringRef F, uint64_t W) : Filename{F}, Weight{W} {}
|
||||
};
|
||||
typedef SmallVector<WeightedFile, 5> WeightedFileVector;
|
||||
|
||||
static void mergeInstrProfile(const WeightedFileVector &Inputs,
|
||||
static void mergeInstrProfile(const cl::list<std::string> &Inputs,
|
||||
StringRef OutputFilename,
|
||||
ProfileFormat OutputFormat) {
|
||||
if (OutputFilename.compare("-") == 0)
|
||||
@ -121,21 +109,21 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
|
||||
|
||||
InstrProfWriter Writer;
|
||||
SmallSet<std::error_code, 4> WriterErrorCodes;
|
||||
for (const auto &Input : Inputs) {
|
||||
auto ReaderOrErr = InstrProfReader::create(Input.Filename);
|
||||
for (const auto &Filename : Inputs) {
|
||||
auto ReaderOrErr = InstrProfReader::create(Filename);
|
||||
if (std::error_code ec = ReaderOrErr.getError())
|
||||
exitWithErrorCode(ec, Input.Filename);
|
||||
exitWithErrorCode(ec, Filename);
|
||||
|
||||
auto Reader = std::move(ReaderOrErr.get());
|
||||
for (auto &I : *Reader) {
|
||||
if (std::error_code EC = Writer.addRecord(std::move(I), Input.Weight)) {
|
||||
if (std::error_code EC = Writer.addRecord(std::move(I))) {
|
||||
// Only show hint the first time an error occurs.
|
||||
bool firstTime = WriterErrorCodes.insert(EC).second;
|
||||
handleMergeWriterError(EC, Input.Filename, I.Name, firstTime);
|
||||
handleMergeWriterError(EC, Filename, I.Name, firstTime);
|
||||
}
|
||||
}
|
||||
if (Reader->hasError())
|
||||
exitWithErrorCode(Reader->getError(), Input.Filename);
|
||||
exitWithErrorCode(Reader->getError(), Filename);
|
||||
}
|
||||
if (OutputFormat == PF_Text)
|
||||
Writer.writeText(Output);
|
||||
@ -147,7 +135,7 @@ static sampleprof::SampleProfileFormat FormatMap[] = {
|
||||
sampleprof::SPF_None, sampleprof::SPF_Text, sampleprof::SPF_Binary,
|
||||
sampleprof::SPF_GCC};
|
||||
|
||||
static void mergeSampleProfile(const WeightedFileVector &Inputs,
|
||||
static void mergeSampleProfile(const cl::list<std::string> &Inputs,
|
||||
StringRef OutputFilename,
|
||||
ProfileFormat OutputFormat) {
|
||||
using namespace sampleprof;
|
||||
@ -159,11 +147,11 @@ static void mergeSampleProfile(const WeightedFileVector &Inputs,
|
||||
auto Writer = std::move(WriterOrErr.get());
|
||||
StringMap<FunctionSamples> ProfileMap;
|
||||
SmallVector<std::unique_ptr<sampleprof::SampleProfileReader>, 5> Readers;
|
||||
for (const auto &Input : Inputs) {
|
||||
for (const auto &Filename : Inputs) {
|
||||
auto ReaderOrErr =
|
||||
SampleProfileReader::create(Input.Filename, getGlobalContext());
|
||||
SampleProfileReader::create(Filename, getGlobalContext());
|
||||
if (std::error_code EC = ReaderOrErr.getError())
|
||||
exitWithErrorCode(EC, Input.Filename);
|
||||
exitWithErrorCode(EC, Filename);
|
||||
|
||||
// We need to keep the readers around until after all the files are
|
||||
// read so that we do not lose the function names stored in each
|
||||
@ -172,7 +160,7 @@ static void mergeSampleProfile(const WeightedFileVector &Inputs,
|
||||
Readers.push_back(std::move(ReaderOrErr.get()));
|
||||
const auto Reader = Readers.back().get();
|
||||
if (std::error_code EC = Reader->read())
|
||||
exitWithErrorCode(EC, Input.Filename);
|
||||
exitWithErrorCode(EC, Filename);
|
||||
|
||||
StringMap<FunctionSamples> &Profiles = Reader->getProfiles();
|
||||
for (StringMap<FunctionSamples>::iterator I = Profiles.begin(),
|
||||
@ -180,38 +168,15 @@ static void mergeSampleProfile(const WeightedFileVector &Inputs,
|
||||
I != E; ++I) {
|
||||
StringRef FName = I->first();
|
||||
FunctionSamples &Samples = I->second;
|
||||
ProfileMap[FName].merge(Samples, Input.Weight);
|
||||
ProfileMap[FName].merge(Samples);
|
||||
}
|
||||
}
|
||||
Writer->write(ProfileMap);
|
||||
}
|
||||
|
||||
static void parseInputFiles(const cl::list<std::string> &Inputs,
|
||||
WeightedFileVector &WeightedInputs) {
|
||||
WeightedInputs.reserve(Inputs.size());
|
||||
|
||||
for (StringRef Input : Inputs) {
|
||||
StringRef FileName;
|
||||
StringRef WeightStr;
|
||||
std::tie(FileName, WeightStr) = Input.rsplit(':');
|
||||
if (WeightStr.empty() || sys::fs::exists(Input)) {
|
||||
// No weight specified or valid path containing delimiter.
|
||||
WeightedInputs.push_back(WeightedFile(Input, 1));
|
||||
} else {
|
||||
// Input weight specified.
|
||||
uint64_t Weight;
|
||||
if (WeightStr.getAsInteger(10, Weight) || Weight < 1) {
|
||||
// Invalid input weight.
|
||||
exitWithError("Input weight must be a positive integer.");
|
||||
}
|
||||
WeightedInputs.push_back(WeightedFile(FileName, Weight));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int merge_main(int argc, const char *argv[]) {
|
||||
cl::list<std::string> Inputs(cl::Positional, cl::Required, cl::OneOrMore,
|
||||
cl::desc("<filename[:weight]...>"));
|
||||
cl::desc("<filenames...>"));
|
||||
|
||||
cl::opt<std::string> OutputFilename("output", cl::value_desc("output"),
|
||||
cl::init("-"), cl::Required,
|
||||
@ -233,13 +198,10 @@ static int merge_main(int argc, const char *argv[]) {
|
||||
|
||||
cl::ParseCommandLineOptions(argc, argv, "LLVM profile data merger\n");
|
||||
|
||||
WeightedFileVector WeightedInputs;
|
||||
parseInputFiles(Inputs, WeightedInputs);
|
||||
|
||||
if (ProfileKind == instr)
|
||||
mergeInstrProfile(WeightedInputs, OutputFilename, OutputFormat);
|
||||
mergeInstrProfile(Inputs, OutputFilename, OutputFormat);
|
||||
else
|
||||
mergeSampleProfile(WeightedInputs, OutputFilename, OutputFormat);
|
||||
mergeSampleProfile(Inputs, OutputFilename, OutputFormat);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -490,24 +490,4 @@ TEST_F(InstrProfTest, get_max_function_count) {
|
||||
ASSERT_EQ(1ULL << 63, Reader->getMaximumFunctionCount());
|
||||
}
|
||||
|
||||
TEST_F(InstrProfTest, get_weighted_function_counts) {
|
||||
InstrProfRecord Record1("foo", 0x1234, {1, 2});
|
||||
InstrProfRecord Record2("foo", 0x1235, {3, 4});
|
||||
Writer.addRecord(std::move(Record1), 3);
|
||||
Writer.addRecord(std::move(Record2), 5);
|
||||
auto Profile = Writer.writeBuffer();
|
||||
readProfile(std::move(Profile));
|
||||
|
||||
std::vector<uint64_t> Counts;
|
||||
ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1234, Counts)));
|
||||
ASSERT_EQ(2U, Counts.size());
|
||||
ASSERT_EQ(3U, Counts[0]);
|
||||
ASSERT_EQ(6U, Counts[1]);
|
||||
|
||||
ASSERT_TRUE(NoError(Reader->getFunctionCounts("foo", 0x1235, Counts)));
|
||||
ASSERT_EQ(2U, Counts.size());
|
||||
ASSERT_EQ(15U, Counts[0]);
|
||||
ASSERT_EQ(20U, Counts[1]);
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
Loading…
x
Reference in New Issue
Block a user