[compiler-rt] 9998863 - [profile] Create only prof header when no counters

Gulfem Savrun Yeniceri via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 30 12:51:18 PDT 2022


Author: Gulfem Savrun Yeniceri
Date: 2022-08-30T19:50:41Z
New Revision: 999886325e825747d5aff5c447b20d12fec7b57a

URL: https://github.com/llvm/llvm-project/commit/999886325e825747d5aff5c447b20d12fec7b57a
DIFF: https://github.com/llvm/llvm-project/commit/999886325e825747d5aff5c447b20d12fec7b57a.diff

LOG: [profile] Create only prof header when no counters

When we use selective instrumentation and instrument a file
that is not in the selected files list provided via -fprofile-list,
we generate an empty raw profile. This leads to empty_raw_profile
error when we try to read that profile. This patch fixes the issue by
generating a raw profile that contains only a profile header when
there are no counters and profile data.

A small reproducer for the above issue:
echo "src:other.cc" > code.list
clang++ -O2 -fprofile-instr-generate -fcoverage-mapping
-fprofile-list=code.list code.cc -o code
./code
llvm-profdata show default.profraw

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

Added: 
    compiler-rt/test/profile/Posix/instrprof-empty-profile.c
    compiler-rt/test/profile/Posix/instrprof-shared-empty-profile.test

Modified: 
    compiler-rt/lib/profile/InstrProfilingWriter.c
    llvm/lib/ProfileData/InstrProfReader.cpp

Removed: 
    


################################################################################
diff  --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c
index 6fe13308a522f..366451a686c13 100644
--- a/compiler-rt/lib/profile/InstrProfilingWriter.c
+++ b/compiler-rt/lib/profile/InstrProfilingWriter.c
@@ -276,9 +276,6 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
   /* Create the header. */
   __llvm_profile_header Header;
 
-  if (!NumData && (!DebugInfoCorrelate || !NumCounters))
-    return 0;
-
   /* Determine how much padding is needed before/after the counters and after
    * the names. */
   uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters,

diff  --git a/compiler-rt/test/profile/Posix/instrprof-empty-profile.c b/compiler-rt/test/profile/Posix/instrprof-empty-profile.c
new file mode 100644
index 0000000000000..15db6bfe62f9a
--- /dev/null
+++ b/compiler-rt/test/profile/Posix/instrprof-empty-profile.c
@@ -0,0 +1,23 @@
+// Test a profile with only a header is generated when a src file is not in the
+//    selected files list provided via -fprofile-list.
+
+// RUN: mkdir -p %t.d
+// RUN: echo "src:other.c" > %t-file.list
+// RUN: %clang_profgen -fprofile-list=%t-file.list -o %t %s
+// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t
+// RUN: llvm-profdata show %t.profraw | FileCheck %s --check-prefix=RAW-PROFILE-HEADER-ONLY
+
+// RUN: llvm-profdata merge -o %t.profdata %t.profraw
+// RUN: llvm-profdata show %t.profdata | FileCheck %s --check-prefix=INDEXED-PROFILE-HEADER-ONLY
+
+int main() { return 0; }
+
+// RAW-PROFILE-HEADER-ONLY: Instrumentation level: Front-end
+// RAW-PROFILE-HEADER-ONLY-NEXT: Total functions: 0
+// RAW-PROFILE-HEADER-ONLY-NEXT: Maximum function count: 0
+// RAW-PROFILE-HEADER-ONLY-NEXT: Maximum internal block count: 0
+
+// INDEXED-PROFILE-HEADER-ONLY: Instrumentation level: Front-end
+// INDEXED-PROFILE-HEADER-ONLY-NEXT: Total functions: 0
+// INDEXED-PROFILE-HEADER-ONLY-NEXT: Maximum function count: 0
+// INDEXED-PROFILE-HEADER-ONLY-NEXT: Maximum internal block count: 0

diff  --git a/compiler-rt/test/profile/Posix/instrprof-shared-empty-profile.test b/compiler-rt/test/profile/Posix/instrprof-shared-empty-profile.test
new file mode 100644
index 0000000000000..318a4edda8de1
--- /dev/null
+++ b/compiler-rt/test/profile/Posix/instrprof-shared-empty-profile.test
@@ -0,0 +1,42 @@
+"""
+This test produces two shared libraries:
+
+1. libt-instr.so is instrumented
+2. libt-no-instr.so is built with profile rt linked in (via -u<hook>), but the object file is built
+   with instrumentation turned off.
+
+The test verifies concatenating profiles with only headers and no profile data and counters.
+"""
+
+RUN: mkdir -p %t.d
+RUN: %clang_profgen -o %t.d/libt-instr.so -fPIC -shared %S/../Inputs/instrprof-shared-lib.c
+RUN: %clang -c -o %t.d/instrprof-shared-lib-no-instr.o -fPIC  %S/../Inputs/instrprof-shared-lib.c
+RUN: %clang_profgen -o %t.d/libt-no-instr.so -fPIC -shared %t.d/instrprof-shared-lib-no-instr.o
+
+# Header + Header
+RUN: echo "src:other.c" > %t-file.list
+RUN: %clang_profgen -fprofile-list=%t-file.list -o %t-no-instr-no-instr -L%t.d -rpath %t.d -lt-no-instr  %S/../Inputs/instrprof-shared-main.c
+RUN: env LLVM_PROFILE_FILE=%t-no-instr-no-instr.profraw %run %t-no-instr-no-instr
+RUN: llvm-profdata show %t-no-instr-no-instr.profraw | FileCheck %s --check-prefix=HEADER-HEADER
+// HEADER-HEADER: Instrumentation level: Front-end
+// HEADER-HEADER-NEXT: Total functions: 0
+// HEADER-HEADER-NEXT: Maximum function count: 0
+// HEADER-HEADER-NEXT: Maximum internal block count: 0
+
+# Header + Profile
+RUN: %clang_profgen -fprofile-list=%t-file.list -o %t-no-instr-instr -L%t.d -rpath %t.d -lt-instr  %S/../Inputs/instrprof-shared-main.c
+RUN: env LLVM_PROFILE_FILE=%t-no-instr-instr.profraw %run %t-no-instr-instr
+RUN: llvm-profdata show %t-no-instr-instr.profraw | FileCheck %s --check-prefix=HEADER-PROFILE
+// HEADER-PROFILE: Instrumentation level: Front-end
+// HEADER-PROFILE-NEXT: Total functions: 1
+// HEADER-PROFILE-NEXT: Maximum function count: 1000000
+// HEADER-PROFILE-NEXT: Maximum internal block count: 360000
+
+# Profile + Header
+RUN: %clang_profgen -o %t-instr-no-instr -L%t.d -rpath %t.d -lt-no-instr %S/../Inputs/instrprof-shared-main.c
+RUN: env LLVM_PROFILE_FILE=%t-instr-no-instr.profraw %run %t-instr-no-instr
+RUN: llvm-profdata show %t-instr-no-instr.profraw | FileCheck %s --check-prefix=PROFILE-HEADER
+// PROFILE-HEADER: Instrumentation level: Front-end
+// PROFILE-HEADER-NEXT: Total functions: 1
+// PROFILE-HEADER-NEXT: Maximum function count: 1
+// PROFILE-HEADER-NEXT: Maximum internal block count: 1000000

diff  --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp
index 23804ce604c49..8f098ad31fb69 100644
--- a/llvm/lib/ProfileData/InstrProfReader.cpp
+++ b/llvm/lib/ProfileData/InstrProfReader.cpp
@@ -545,7 +545,9 @@ Error RawInstrProfReader<IntPtrT>::readValueProfilingData(
 
 template <class IntPtrT>
 Error RawInstrProfReader<IntPtrT>::readNextRecord(NamedInstrProfRecord &Record) {
-  if (atEnd())
+  // Keep reading profiles that consist of only headers and no profile data and
+  // counters.
+  while (atEnd())
     // At this point, ValueDataStart field points to the next header.
     if (Error E = readNextHeader(getNextHeaderPos()))
       return error(std::move(E));


        


More information about the llvm-commits mailing list