diff --git a/llvm/test/tools/llvm-profdata/input-dir.test b/llvm/test/tools/llvm-profdata/input-dir.test new file mode 100644 index 000000000000..16b5d721bc1c --- /dev/null +++ b/llvm/test/tools/llvm-profdata/input-dir.test @@ -0,0 +1,22 @@ +# Create an input file. +RUN: echo "#" > %t.input +RUN: echo "%t.dir1" >> %t.input +RUN: echo "2,%t.dir2" >> %t.input + +RUN: mkdir -p %t.dir1 +RUN: mkdir -p %t.dir2/subdir + +RUN: echo ' ' > %t.dir1/bar +RUN: echo ' ' > %t.dir1/foo +RUN: echo ' ' > %t.dir2/bar +RUN: echo ' ' > %t.dir2/foo +RUN: echo ' ' > %t.dir2/subdir/baz + +RUN: llvm-profdata merge -f %t.input -dump-input-file-list -o /dev/null | FileCheck %s +RUN: llvm-profdata merge -weighted-input=2,%t.dir2 -dump-input-file-list -o /dev/null %t.dir1 | FileCheck %s + +CHECK: 1,{{.*}}.dir1/bar +CHECK-NEXT: 1,{{.*}}.dir1/foo +CHECK-NEXT: 2,{{.*}}.dir2/bar +CHECK-NEXT: 2,{{.*}}.dir2/foo +CHECK-NEXT: 2,{{.*}}.dir2/subdir/baz diff --git a/llvm/test/tools/llvm-profdata/input-filenames.test b/llvm/test/tools/llvm-profdata/input-filenames.test index da0c47bf82ac..4f29e7bea9b8 100644 --- a/llvm/test/tools/llvm-profdata/input-filenames.test +++ b/llvm/test/tools/llvm-profdata/input-filenames.test @@ -1,17 +1,19 @@ # Create an input file. RUN: echo '# comment 1' > %t.input RUN: echo ' # comment 2' >> %t.input -RUN: echo 'bar' >> %t.input -RUN: echo ' baz' >> %t.input +RUN: echo " %t.bar" >> %t.input +RUN: echo " %t.baz" >> %t.input RUN: echo "2,%t.weighted" >> %t.input -# Create the weighted file, since these actually need to exist. RUN: echo ' ' > %t.weighted +RUN: echo ' ' > %t.foo +RUN: echo ' ' > %t.bar +RUN: echo ' ' > %t.baz -RUN: llvm-profdata merge -f %t.input -dump-input-file-list -o /dev/null foo | FileCheck %s -RUN: llvm-profdata merge -input-files %t.input -dump-input-file-list -o /dev/null foo | FileCheck %s +RUN: llvm-profdata merge -f %t.input -dump-input-file-list -o /dev/null %t.foo | FileCheck %s +RUN: llvm-profdata merge -input-files %t.input -dump-input-file-list -o /dev/null %t.foo | FileCheck %s -CHECK: 1,foo -CHECK-NEXT: 1,bar -CHECK-NEXT: 1,baz +CHECK: 1,{{.*}}.foo +CHECK-NEXT: 1,{{.*}}.bar +CHECK-NEXT: 1,{{.*}}.baz CHECK-NEXT: 2,{{.*}}.weighted diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index 26ce4cc234fc..b2da3c246643 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -109,12 +109,12 @@ static void handleMergeWriterError(Error E, StringRef WhenceFile = "", } struct WeightedFile { - StringRef Filename; + std::string Filename; uint64_t Weight; WeightedFile() {} - WeightedFile(StringRef F, uint64_t W) : Filename{F}, Weight{W} {} + WeightedFile(const std::string &F, uint64_t W) : Filename{F}, Weight{W} {} }; typedef SmallVector WeightedFileVector; @@ -305,10 +305,6 @@ static WeightedFile parseWeightedFile(const StringRef &WeightedFilename) { if (WeightStr.getAsInteger(10, Weight) || Weight < 1) exitWithError("Input weight must be a positive integer."); - if (!sys::fs::exists(FileName)) - exitWithErrorCode(make_error_code(errc::no_such_file_or_directory), - FileName); - return WeightedFile(FileName, Weight); } @@ -324,6 +320,33 @@ getInputFilenamesFileBuf(const StringRef &InputFilenamesFile) { return std::move(*BufOrError); } +static void addWeightedInput(WeightedFileVector &WNI, const WeightedFile &WF) { + StringRef Filename = WF.Filename; + uint64_t Weight = WF.Weight; + llvm::sys::fs::file_status Status; + llvm::sys::fs::status(Filename, Status); + if (!llvm::sys::fs::exists(Status)) + exitWithErrorCode(make_error_code(errc::no_such_file_or_directory), + Filename); + // If it's a source file, collect it. + if (llvm::sys::fs::is_regular_file(Status)) { + WNI.emplace_back(Filename, Weight); + return; + } + + if (llvm::sys::fs::is_directory(Status)) { + std::error_code EC; + for (llvm::sys::fs::recursive_directory_iterator F(Filename, EC), E; + F != E && !EC; F.increment(EC)) { + if (llvm::sys::fs::is_regular_file(F->path())) { + addWeightedInput(WNI, {F->path(), Weight}); + } + } + if (EC) + exitWithErrorCode(EC, Filename); + } +} + static void parseInputFilenamesFile(MemoryBuffer *Buffer, WeightedFileVector &WFV) { if (!Buffer) @@ -339,9 +362,9 @@ static void parseInputFilenamesFile(MemoryBuffer *Buffer, continue; // If there's no comma, it's an unweighted profile. else if (SanitizedEntry.find(',') == StringRef::npos) - WFV.emplace_back(SanitizedEntry, 1); + addWeightedInput(WFV, {SanitizedEntry, 1}); else - WFV.emplace_back(parseWeightedFile(SanitizedEntry)); + addWeightedInput(WFV, parseWeightedFile(SanitizedEntry)); } } @@ -387,9 +410,9 @@ static int merge_main(int argc, const char *argv[]) { WeightedFileVector WeightedInputs; for (StringRef Filename : InputFilenames) - WeightedInputs.emplace_back(Filename, 1); + addWeightedInput(WeightedInputs, {Filename, 1}); for (StringRef WeightedFilename : WeightedInputFilenames) - WeightedInputs.emplace_back(parseWeightedFile(WeightedFilename)); + addWeightedInput(WeightedInputs, parseWeightedFile(WeightedFilename)); // Make sure that the file buffer stays alive for the duration of the // weighted input vector's lifetime.