r206322 - CodeGen: Emit warnings for out of date profile data during PGO

Justin Bogner mail at justinbogner.com
Tue Apr 15 14:22:35 PDT 2014


Author: bogner
Date: Tue Apr 15 16:22:35 2014
New Revision: 206322

URL: http://llvm.org/viewvc/llvm-project?rev=206322&view=rev
Log:
CodeGen: Emit warnings for out of date profile data during PGO

This adds a warning that triggers when profile data doesn't match for
the source that's being compiled with -fprofile-instr-use=. This fires
only once per translation unit, as warning on every mismatched
function would be quite noisy.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/CodeGen/CodeGenModule.cpp
    cfe/trunk/lib/CodeGen/CodeGenModule.h
    cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
    cfe/trunk/test/Profile/c-outdated-data.c

Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=206322&r1=206321&r2=206322&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Apr 15 16:22:35 2014
@@ -665,3 +665,6 @@ def BackendInlineAsm : DiagGroup<"inline
 def BackendFrameLargerThan : DiagGroup<"frame-larger-than">;
 def BackendPlugin : DiagGroup<"backend-plugin">;
 def RemarkBackendPlugin : DiagGroup<"remark-backend-plugin">;
+
+// Instrumentation based profiling warnings.
+def ProfileInstrOutOfDate : DiagGroup<"profile-instr-out-of-date">;

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=206322&r1=206321&r2=206322&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Apr 15 16:22:35 2014
@@ -6984,4 +6984,11 @@ def warn_not_a_doxygen_trailing_member_c
   "not a Doxygen trailing comment">, InGroup<Documentation>, DefaultIgnore;
 } // end of documentation issue category
 
+let CategoryName = "Instrumentation Issue" in {
+def warn_profile_data_out_of_date : Warning<
+  "profile data may be out of date: of %0 function%s0, %1 %plural{1:has|:have}1"
+  " no data and %2 %plural{1:has|:have}2 mismatched data that will be ignored">,
+  InGroup<ProfileInstrOutOfDate>;
+} // end of instrumentation issue category
+
 } // end of sema component.

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=206322&r1=206321&r2=206322&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Apr 15 16:22:35 2014
@@ -286,6 +286,9 @@ void CodeGenModule::Release() {
   if (getCodeGenOpts().ProfileInstrGenerate)
     if (llvm::Function *PGOInit = CodeGenPGO::emitInitialization(*this))
       AddGlobalCtor(PGOInit, 0);
+  if (PGOData && PGOStats.isOutOfDate())
+    getDiags().Report(diag::warn_profile_data_out_of_date)
+        << PGOStats.Visited << PGOStats.Missing << PGOStats.Mismatched;
   EmitCtorList(GlobalCtors, "llvm.global_ctors");
   EmitCtorList(GlobalDtors, "llvm.global_dtors");
   EmitGlobalAnnotations();

Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=206322&r1=206321&r2=206322&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Apr 15 16:22:35 2014
@@ -220,6 +220,15 @@ struct ARCEntrypoints {
   llvm::Constant *clang_arc_use;
 };
 
+/// This class records statistics on instrumentation based profiling.
+struct InstrProfStats {
+  InstrProfStats() : Visited(0), Missing(0), Mismatched(0) {}
+  bool isOutOfDate() { return Missing || Mismatched; }
+  uint32_t Visited;
+  uint32_t Missing;
+  uint32_t Mismatched;
+};
+
 /// CodeGenModule - This class organizes the cross-function state that is used
 /// while generating LLVM code.
 class CodeGenModule : public CodeGenTypeCache {
@@ -258,6 +267,7 @@ class CodeGenModule : public CodeGenType
   llvm::MDNode *NoObjCARCExceptionsMetadata;
   RREntrypoints *RRData;
   PGOProfileData *PGOData;
+  InstrProfStats PGOStats;
 
   // WeakRefReferences - A set of references that have only been seen via
   // a weakref so far. This is used to remove the weak of the reference if we
@@ -483,6 +493,10 @@ public:
     return *RRData;
   }
 
+  InstrProfStats &getPGOStats() {
+    return PGOStats;
+  }
+
   PGOProfileData *getPGOData() const {
     return PGOData;
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenPGO.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenPGO.cpp?rev=206322&r1=206321&r2=206322&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenPGO.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenPGO.cpp Tue Apr 15 16:22:35 2014
@@ -908,11 +908,17 @@ void CodeGenPGO::emitCounterIncrement(CG
 }
 
 void CodeGenPGO::loadRegionCounts(PGOProfileData *PGOData) {
+  CGM.getPGOStats().Visited++;
   RegionCounts.reset(new std::vector<uint64_t>);
   uint64_t Hash;
-  if (PGOData->getFunctionCounts(getFuncName(), Hash, *RegionCounts) ||
-      Hash != FunctionHash || RegionCounts->size() != NumRegionCounters)
+  if (PGOData->getFunctionCounts(getFuncName(), Hash, *RegionCounts)) {
+    CGM.getPGOStats().Missing++;
     RegionCounts.reset();
+  } else if (Hash != FunctionHash ||
+             RegionCounts->size() != NumRegionCounters) {
+    CGM.getPGOStats().Mismatched++;
+    RegionCounts.reset();
+  }
 }
 
 void CodeGenPGO::destroyRegionCounters() {

Modified: cfe/trunk/test/Profile/c-outdated-data.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Profile/c-outdated-data.c?rev=206322&r1=206321&r2=206322&view=diff
==============================================================================
--- cfe/trunk/test/Profile/c-outdated-data.c (original)
+++ cfe/trunk/test/Profile/c-outdated-data.c Tue Apr 15 16:22:35 2014
@@ -1,11 +1,11 @@
 // Test that outdated data is ignored.
 
-// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o - -emit-llvm -fprofile-instr-use=%S/Inputs/c-outdated-data.profdata | FileCheck -check-prefix=PGOUSE %s
+// FIXME: It would be nice to use -verify here instead of FileCheck, but -verify
+// doesn't play well with warnings that have no line number.
 
-// TODO: We should have a warning or a remark that tells us the profile data was
-// discarded, rather than just checking that we fail to add metadata.
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9 -main-file-name c-outdated-data.c %s -o /dev/null -emit-llvm -fprofile-instr-use=%S/Inputs/c-outdated-data.profdata -Wprofile-instr-dropped 2>&1 | FileCheck %s
+// CHECK: warning: profile data may be out of date: of 3 functions, 1 has no data and 1 has mismatched data that will be ignored
 
-// PGOUSE-LABEL: @no_usable_data()
 void no_usable_data() {
   int i = 0;
 
@@ -14,9 +14,12 @@ void no_usable_data() {
 #ifdef GENERATE_OUTDATED_DATA
   if (i) {}
 #endif
+}
 
-  // PGOUSE-NOT: br {{.*}} !prof ![0-9]+
+#ifndef GENERATE_OUTDATED_DATA
+void no_data() {
 }
+#endif
 
 int main(int argc, const char *argv[]) {
   no_usable_data();





More information about the cfe-commits mailing list