llvm-profdata] Handle the cases of overlapping input file and output file

Currently llvm-profdata does not expect the same file name for the input profile
and the output profile.
>llvm-profdata merge A.profraw B.profraw -o B.profraw
The above command runs successfully but the resulted B.profraw is not correct.
This patch fixes the issue by moving the initialization of writer after loading
the profile.

For the show command, the following will report a confusing error of
"Empty raw profile file":
>llvm-profdata show B.profraw -o B.profraw
It's harder to fix as we need to output something before loading the input profile.
I don't think that a fix for this is worth the effort. I just make the error explicit for
the show command.

Differential Revision: https://reviews.llvm.org/D64360

llvm-svn: 365386
This commit is contained in:
Rong Xu 2019-07-08 21:03:12 +00:00
parent c5630ac641
commit f0d3dcec97
6 changed files with 96 additions and 11 deletions

View File

@ -0,0 +1,10 @@
# IR level Instrumentation Flag
:ir
main
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
1

View File

@ -0,0 +1,10 @@
# IR level Instrumentation Flag
:ir
main
# Func Hash:
12884901887
# Num Counters:
1
# Counter Values:
2

View File

@ -0,0 +1,16 @@
_Z3bari:20301:1437
1: 1437
_Z3fooi:7711:610
1: 610
main:184019:0
4: 534
4.2: 534
5: 1075
5.1: 1075
6: 2080
7: 534
9: 2064 _Z3bari:1471 _Z3fooi:631
10: inline1:1000
1: 1000
10: inline2:2000
1: 2000

View File

@ -0,0 +1,16 @@
_Z3bari:40602:2874
1: 2874
_Z3fooi:15422:1220
1: 1220
main:368038:0
4: 1068
4.2: 1068
5: 2150
5.1: 2150
6: 4160
7: 1068
9: 4128 _Z3bari:2942 _Z3fooi:1262
10: inline1:2000
1: 2000
10: inline2:4000
1: 4000

View File

@ -0,0 +1,27 @@
Test the input file names overlap with the output file names.
This is OK for merging instrument profiles.
RUN: cp %S/Inputs/same-name-1.proftext %t.0.proftext
RUN: llvm-profdata merge -o %t.0.proftext -text %t.0.proftext %t.0.proftext
RUN: llvm-profdata show -counts -all-functions %t.0.proftext -o %t_show_0
RUN: llvm-profdata show -counts -all-functions %S/Inputs/same-name-2.proftext -o %t_show_1
RUN: diff %t_show_0 %t_show_1
RUN: llvm-profdata merge -o %t.1.profdata %S/Inputs/same-name-1.proftext
RUN: llvm-profdata merge -o %t.1.profdata %t.1.profdata %t.1.profdata
RUN: llvm-profdata show -counts -all-functions %t.1.profdata -o %t_show_2
RUN: diff %t_show_2 %t_show_1
We report error for the show command.
RUN: not llvm-profdata show -o %t.1.profdata %t.1.profdata 2>&1 | FileCheck %s
CHECK: llvm-profdata show: Input file name cannot be the same as the output file name!
This is OK for merging sample fdo profiles.
RUN: cp %S/Inputs/same-name-3.proftext %t.3.proftext
RUN: llvm-profdata merge --sample -o %t.3.proftext -text %t.3.proftext %t.3.proftext
RUN: llvm-profdata show --sample -counts -all-functions %t.3.proftext -o %t_show_3
RUN: llvm-profdata show --sample -counts -all-functions %S/Inputs/same-name-4.proftext -o %t_show_4
RUN: diff %t_show_3 %t_show_4
RUN: llvm-profdata merge --sample -o %t.5.profdata %S/Inputs/same-name-3.proftext
RUN: llvm-profdata merge --sample -o %t.5.profdata %t.5.profdata %t.5.profdata
RUN: llvm-profdata show --sample -counts -all-functions %t.5.profdata -o %t_show_6
RUN: diff %t_show_6 %t_show_4

View File

@ -317,11 +317,6 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
OutputFormat != PF_Text)
exitWithError("Unknown format is specified.");
std::error_code EC;
raw_fd_ostream Output(OutputFilename.data(), EC, sys::fs::F_None);
if (EC)
exitWithErrorCode(EC, OutputFilename);
std::mutex ErrorLock;
SmallSet<instrprof_error, 4> WriterErrorCodes;
@ -384,6 +379,11 @@ static void mergeInstrProfile(const WeightedFileVector &Inputs,
WC->ErrWhence);
}
std::error_code EC;
raw_fd_ostream Output(OutputFilename.data(), EC, sys::fs::F_None);
if (EC)
exitWithErrorCode(EC, OutputFilename);
InstrProfWriter &Writer = Contexts[0]->Writer;
if (OutputFormat == PF_Text) {
if (Error E = Writer.writeText(Output))
@ -433,12 +433,6 @@ static void mergeSampleProfile(const WeightedFileVector &Inputs,
StringRef OutputFilename,
ProfileFormat OutputFormat) {
using namespace sampleprof;
auto WriterOrErr =
SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]);
if (std::error_code EC = WriterOrErr.getError())
exitWithErrorCode(EC, OutputFilename);
auto Writer = std::move(WriterOrErr.get());
StringMap<FunctionSamples> ProfileMap;
SmallVector<std::unique_ptr<sampleprof::SampleProfileReader>, 5> Readers;
LLVMContext Context;
@ -473,6 +467,12 @@ static void mergeSampleProfile(const WeightedFileVector &Inputs,
}
}
}
auto WriterOrErr =
SampleProfileWriter::create(OutputFilename, FormatMap[OutputFormat]);
if (std::error_code EC = WriterOrErr.getError())
exitWithErrorCode(EC, OutputFilename);
auto Writer = std::move(WriterOrErr.get());
Writer->write(ProfileMap);
}
@ -1020,6 +1020,12 @@ static int show_main(int argc, const char *argv[]) {
if (OutputFilename.empty())
OutputFilename = "-";
if (!Filename.compare(OutputFilename)) {
errs() << sys::path::filename(argv[0])
<< ": Input file name cannot be the same as the output file name!\n";
return 1;
}
std::error_code EC;
raw_fd_ostream OS(OutputFilename.data(), EC, sys::fs::F_Text);
if (EC)