From: Rong Xu Date: Mon, 8 Jul 2019 21:03:12 +0000 (+0000) Subject: llvm-profdata] Handle the cases of overlapping input file and output file X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7609dbd9af3a98d7296151c63b79ddcf02491d8d;p=llvm 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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@365386 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-profdata/Inputs/same-name-1.proftext b/test/tools/llvm-profdata/Inputs/same-name-1.proftext new file mode 100644 index 00000000000..3e0e3c3e842 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/same-name-1.proftext @@ -0,0 +1,10 @@ +# IR level Instrumentation Flag +:ir +main +# Func Hash: +12884901887 +# Num Counters: +1 +# Counter Values: +1 + diff --git a/test/tools/llvm-profdata/Inputs/same-name-2.proftext b/test/tools/llvm-profdata/Inputs/same-name-2.proftext new file mode 100644 index 00000000000..a42ef32b83a --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/same-name-2.proftext @@ -0,0 +1,10 @@ +# IR level Instrumentation Flag +:ir +main +# Func Hash: +12884901887 +# Num Counters: +1 +# Counter Values: +2 + diff --git a/test/tools/llvm-profdata/Inputs/same-name-3.proftext b/test/tools/llvm-profdata/Inputs/same-name-3.proftext new file mode 100644 index 00000000000..e34128faabc --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/same-name-3.proftext @@ -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 diff --git a/test/tools/llvm-profdata/Inputs/same-name-4.proftext b/test/tools/llvm-profdata/Inputs/same-name-4.proftext new file mode 100644 index 00000000000..1ba5b8001f1 --- /dev/null +++ b/test/tools/llvm-profdata/Inputs/same-name-4.proftext @@ -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 diff --git a/test/tools/llvm-profdata/same-filename.test b/test/tools/llvm-profdata/same-filename.test new file mode 100644 index 00000000000..f73caa1dfc4 --- /dev/null +++ b/test/tools/llvm-profdata/same-filename.test @@ -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 diff --git a/tools/llvm-profdata/llvm-profdata.cpp b/tools/llvm-profdata/llvm-profdata.cpp index 10551fd98e1..16d3ebe3fcb 100644 --- a/tools/llvm-profdata/llvm-profdata.cpp +++ b/tools/llvm-profdata/llvm-profdata.cpp @@ -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 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 ProfileMap; SmallVector, 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)