ikudrin created this revision.
ikudrin added reviewers: bogner, davidxl, vsk.
ikudrin added a subscriber: cfe-commits.

A valid function might not have any statement which affects the hash value, so 
the hash for that function was zero. The hash value for an unused function is 
also zero, so the loader could not distinguish the definitions and might load 
the incorrect one. This patch addresses the issue by assigning a special 
reserved value as a hash for such a functions.

http://reviews.llvm.org/D20287

Files:
  lib/CodeGen/CodeGenPGO.cpp
  lib/CodeGen/CoverageMappingGen.cpp
  test/CoverageMapping/block-storage-starts-region.m
  test/CoverageMapping/decl.c
  test/CoverageMapping/implicit-def-in-macro.m
  test/CoverageMapping/lambda.cpp
  test/CoverageMapping/loops.cpp
  test/CoverageMapping/macroception.c
  test/CoverageMapping/moremacros.c
  test/CoverageMapping/simple-function-hash.cpp
  test/CoverageMapping/system_macro.c
  test/CoverageMapping/trymacro.cpp
  test/Profile/Inputs/c-captured.proftext
  test/Profile/Inputs/c-general.proftext
  test/Profile/Inputs/c-outdated-data.proftext
  test/Profile/Inputs/c-unprofiled.proftext
  test/Profile/Inputs/cxx-class.proftext
  test/Profile/Inputs/cxx-lambda.proftext
  test/Profile/Inputs/cxx-rangefor.proftext
  test/Profile/Inputs/cxx-templates.proftext
  test/Profile/Inputs/func-entry.proftext
  test/Profile/Inputs/max-function-count.proftext
  test/Profile/Inputs/objc-general.proftext
  test/Profile/Inputs/profile-summary.proftext

Index: test/Profile/Inputs/profile-summary.proftext
===================================================================
--- test/Profile/Inputs/profile-summary.proftext
+++ test/Profile/Inputs/profile-summary.proftext
@@ -9,7 +9,7 @@
 
 main
 # Func Hash:
-0
+17
 # Num Counters:
 1
 # Counter Values:
Index: test/Profile/Inputs/objc-general.proftext
===================================================================
--- test/Profile/Inputs/objc-general.proftext
+++ test/Profile/Inputs/objc-general.proftext
@@ -11,7 +11,7 @@
 2
 
 main
-0
+17
 1
 1
 
Index: test/Profile/Inputs/max-function-count.proftext
===================================================================
--- test/Profile/Inputs/max-function-count.proftext
+++ test/Profile/Inputs/max-function-count.proftext
@@ -9,7 +9,7 @@
 
 main
 # Func Hash:
-0
+17
 # Num Counters:
 1
 # Counter Values:
Index: test/Profile/Inputs/func-entry.proftext
===================================================================
--- test/Profile/Inputs/func-entry.proftext
+++ test/Profile/Inputs/func-entry.proftext
@@ -1,5 +1,5 @@
 foo
-0
+17
 1
 1000
 
Index: test/Profile/Inputs/cxx-templates.proftext
===================================================================
--- test/Profile/Inputs/cxx-templates.proftext
+++ test/Profile/Inputs/cxx-templates.proftext
@@ -1,5 +1,5 @@
 main
-0
+17
 1
 1
 
Index: test/Profile/Inputs/cxx-rangefor.proftext
===================================================================
--- test/Profile/Inputs/cxx-rangefor.proftext
+++ test/Profile/Inputs/cxx-rangefor.proftext
@@ -8,6 +8,6 @@
 1
 
 main
-0
+17
 1
 1
Index: test/Profile/Inputs/cxx-lambda.proftext
===================================================================
--- test/Profile/Inputs/cxx-lambda.proftext
+++ test/Profile/Inputs/cxx-lambda.proftext
@@ -6,7 +6,7 @@
 9
 
 main
-0
+17
 1
 1
 
Index: test/Profile/Inputs/cxx-class.proftext
===================================================================
--- test/Profile/Inputs/cxx-class.proftext
+++ test/Profile/Inputs/cxx-class.proftext
@@ -5,7 +5,7 @@
 100
 
 main
-0
+17
 1
 1
 
Index: test/Profile/Inputs/c-unprofiled.proftext
===================================================================
--- test/Profile/Inputs/c-unprofiled.proftext
+++ test/Profile/Inputs/c-unprofiled.proftext
@@ -5,6 +5,6 @@
 0
 
 main
-0
+17
 1
 1
Index: test/Profile/Inputs/c-outdated-data.proftext
===================================================================
--- test/Profile/Inputs/c-outdated-data.proftext
+++ test/Profile/Inputs/c-outdated-data.proftext
@@ -6,7 +6,7 @@
 0
 
 main
-0
+17
 1
 1
 
Index: test/Profile/Inputs/c-general.proftext
===================================================================
--- test/Profile/Inputs/c-general.proftext
+++ test/Profile/Inputs/c-general.proftext
@@ -145,7 +145,7 @@
 8
 
 main
-0
+17
 1
 1
 
Index: test/Profile/Inputs/c-captured.proftext
===================================================================
--- test/Profile/Inputs/c-captured.proftext
+++ test/Profile/Inputs/c-captured.proftext
@@ -12,7 +12,7 @@
 1
 
 main
-0
+17
 1
 1
 
Index: test/CoverageMapping/trymacro.cpp
===================================================================
--- test/CoverageMapping/trymacro.cpp
+++ test/CoverageMapping/trymacro.cpp
@@ -1,19 +1,19 @@
 // RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -fexceptions -fcxx-exceptions -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only -main-file-name trymacro.cpp %s | FileCheck %s
 
-// CHECK: Z3fn1v:
+// CHECK: Z3fn1v
 void fn1() try { return; } // CHECK: [[@LINE]]:12 -> [[@LINE+1]]:14 = #1
 catch(...) {}              // CHECK: [[@LINE]]:12 -> [[@LINE]]:14 = #2
 
 #define RETURN_BLOCK { return; }
 
-// CHECK: Z3fn2v:
+// CHECK: Z3fn2v
 void fn2() try RETURN_BLOCK // CHECK: [[@LINE]]:12 -> [[@LINE+1]]:14 = #1
 catch(...) {}               // CHECK: [[@LINE]]:12 -> [[@LINE]]:14 = #2
 
 #define TRY try
 #define CATCH(x) catch (x)
 
-// CHECK: Z3fn3v:
+// CHECK: Z3fn3v
 void fn3() TRY { return; } // CHECK: [[@LINE]]:15 -> [[@LINE+1]]:14 = #1
 CATCH(...) {}              // CHECK: [[@LINE]]:12 -> [[@LINE]]:14 = #2
 
Index: test/CoverageMapping/system_macro.c
===================================================================
--- test/CoverageMapping/system_macro.c
+++ test/CoverageMapping/system_macro.c
@@ -11,7 +11,7 @@
 #define IS_SYSHEADER
 #include __FILE__
 
-// CHECK-LABEL: doSomething:
+// CHECK-LABEL: doSomething
 void doSomething(int x) { // CHECK: File 0, [[@LINE]]:25 -> {{[0-9:]+}} = #0
   Func(x); // CHECK: Expansion,File 0, [[@LINE]]:3 -> [[@LINE]]:7
   return;
Index: test/CoverageMapping/simple-function-hash.cpp
===================================================================
--- /dev/null
+++ test/CoverageMapping/simple-function-hash.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -main-file-name simple-function-hash.cpp %s -o %t.o -emit-llvm -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping | FileCheck %s
+
+// Hash value for unused_func() is 0 because it is an inline function which is not used in the translation unit.
+// CHECK-DAG: _Z11unused_funcv(0):
+inline int unused_func() { return 1; }
+
+// Hash value for used_func() is 17 even though it does not contain any statement which affects hash.
+// CHECK-DAG: _Z9used_funcv(17):
+inline int used_func() { return 1; }
+
+// Hash value for main() is 10 because it contains the "if" statement.
+// CHECK-DAG: main(10):
+int main() {
+  if (used_func())
+    return used_func();
+  return 0;
+}
Index: test/CoverageMapping/moremacros.c
===================================================================
--- test/CoverageMapping/moremacros.c
+++ test/CoverageMapping/moremacros.c
@@ -3,7 +3,7 @@
 #define LBRAC {
 #define RBRAC }
 
-// CHECK: main:
+// CHECK: main
 // CHECK-NEXT: File 0, [[@LINE+1]]:40 -> {{[0-9]+}}:2 = #0
 int main(int argc, const char *argv[]) {
   // CHECK-NEXT: File 0, [[@LINE+1]]:7 -> [[@LINE+1]]:12 = #0
Index: test/CoverageMapping/macroception.c
===================================================================
--- test/CoverageMapping/macroception.c
+++ test/CoverageMapping/macroception.c
@@ -5,7 +5,7 @@
 #define M22 }
 #define M11 M22
 
-// CHECK-LABEL: main:
+// CHECK-LABEL: main
 // CHECK-NEXT: Expansion,File 0, [[@LINE+2]]:12 -> [[@LINE+2]]:14 = #0
 // CHECK-NEXT: File 0, [[@LINE+1]]:14 -> [[@LINE+3]]:2 = #0
 int main() M1
@@ -15,7 +15,7 @@
 // CHECK-NEXT: Expansion,File 1, 4:12 -> 4:14 = #0
 // CHECK-NEXT: File 2, 3:12 -> 3:13 = #0
 
-// CHECK-LABEL: func2:
+// CHECK-LABEL: func2
 // CHECK-NEXT: File 0, [[@LINE+2]]:14 -> [[@LINE+4]]:4 = #0
 // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:1 -> [[@LINE+3]]:4 = #0
 void func2() {
@@ -25,7 +25,7 @@
 // CHECK-NEXT: Expansion,File 1, 6:13 -> 6:16 = #0
 // CHECK-NEXT: File 2, 5:13 -> 5:14 = #0
 
-// CHECK-LABEL: func3:
+// CHECK-LABEL: func3
 // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:14 -> [[@LINE+3]]:16 = #0
 // CHECK-NEXT: File 0, [[@LINE+2]]:16 -> [[@LINE+4]]:4 = #0
 // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:1 -> [[@LINE+3]]:4 = #0
@@ -39,7 +39,7 @@
 // CHECK-NEXT: File 3, 3:12 -> 3:13 = #0
 // CHECK-NEXT: File 4, 5:13 -> 5:14 = #0
 
-// CHECK-LABEL: func4:
+// CHECK-LABEL: func4
 // CHECK-NEXT: Expansion,File 0, [[@LINE+3]]:14 -> [[@LINE+3]]:16 = #0
 // CHECK-NEXT: File 0, [[@LINE+2]]:16 -> [[@LINE+2]]:20 = #0
 // CHECK-NEXT: Expansion,File 0, [[@LINE+1]]:17 -> [[@LINE+1]]:20 = #0
Index: test/CoverageMapping/loops.cpp
===================================================================
--- test/CoverageMapping/loops.cpp
+++ test/CoverageMapping/loops.cpp
@@ -16,7 +16,7 @@
   if (sum) {}
 }
 
-                                    // CHECK: main:
+                                    // CHECK: main
 int main() {                        // CHECK-NEXT: File 0, [[@LINE]]:12 -> [[@LINE+24]]:2 = #0
                                     // CHECK-NEXT: File 0, [[@LINE+1]]:18 -> [[@LINE+1]]:24 = (#0 + #1)
   for(int i = 0; i < 10; ++i)       // CHECK-NEXT: File 0, [[@LINE]]:26 -> [[@LINE]]:29 = #1
Index: test/CoverageMapping/lambda.cpp
===================================================================
--- test/CoverageMapping/lambda.cpp
+++ test/CoverageMapping/lambda.cpp
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -x c++ -std=c++11 -triple %itanium_abi_triple -fprofile-instrument=clang -fcoverage-mapping -dump-coverage-mapping -emit-llvm-only %s -main-file-name lambda.cpp | FileCheck %s
 
-// CHECK-LABEL: _Z3fooi:
+// CHECK-LABEL: _Z3fooi
 void foo(int i) { // CHECK: File 0, [[@LINE]]:17 -> {{[0-9]+}}:2 = #0
   auto f = [](int x) {
     return x + 1;
Index: test/CoverageMapping/implicit-def-in-macro.m
===================================================================
--- test/CoverageMapping/implicit-def-in-macro.m
+++ test/CoverageMapping/implicit-def-in-macro.m
@@ -5,7 +5,7 @@
 #define Bar Foo
 
 @implementation Blah
-// CHECK-LABEL: +[Blah load]:
+// CHECK-LABEL: +[Blah load]
 + load { // CHECK: File 0, [[@LINE]]:8 -> [[END:[0-9:]+]] = #0
   return 0;
   // CHECK: Expansion,File 0, [[@LINE+1]]:3 -> [[@LINE+1]]:6 = 0
Index: test/CoverageMapping/decl.c
===================================================================
--- test/CoverageMapping/decl.c
+++ test/CoverageMapping/decl.c
@@ -4,12 +4,12 @@
 // FileCheck -input-file %t %s
 // RUN: FileCheck -check-prefix BAR -input-file %t %s
 
-// FOO: foo:
-// FOO-NOT: foo:
+// FOO: foo
+// FOO-NOT: foo
 inline int foo() { return 0; }
 extern inline int foo();
 
-// BAR: bar:
-// BAR-NOT: bar:
+// BAR: bar
+// BAR-NOT: bar
 int bar() { return 0; }
 extern int bar();
Index: test/CoverageMapping/block-storage-starts-region.m
===================================================================
--- test/CoverageMapping/block-storage-starts-region.m
+++ test/CoverageMapping/block-storage-starts-region.m
@@ -3,7 +3,7 @@
 @interface Foo
 @end
 
-// CHECK-LABEL: doSomething:
+// CHECK-LABEL: doSomething
 void doSomething() { // CHECK: File 0, [[@LINE]]:20 -> {{[0-9:]+}} = #0
   return;
   __block Foo *f; // CHECK: File 0, [[@LINE]]:3 -> {{[0-9:]+}} = 0
Index: lib/CodeGen/CoverageMappingGen.cpp
===================================================================
--- lib/CodeGen/CoverageMappingGen.cpp
+++ lib/CodeGen/CoverageMappingGen.cpp
@@ -906,9 +906,9 @@
 }
 
 static void dump(llvm::raw_ostream &OS, StringRef FunctionName,
-                 ArrayRef<CounterExpression> Expressions,
+                 uint64_t FuncHash, ArrayRef<CounterExpression> Expressions,
                  ArrayRef<CounterMappingRegion> Regions) {
-  OS << FunctionName << ":\n";
+  OS << FunctionName << "(" << FuncHash << "):\n";
   CounterMappingContext Ctx(Expressions);
   for (const auto &R : Regions) {
     OS.indent(2);
@@ -974,7 +974,7 @@
                                     Expressions, Regions);
     if (Reader.read())
       return;
-    dump(llvm::outs(), NameValue, Expressions, Regions);
+    dump(llvm::outs(), NameValue, FuncHash, Expressions, Regions);
   }
 }
 
Index: lib/CodeGen/CodeGenPGO.cpp
===================================================================
--- lib/CodeGen/CodeGenPGO.cpp
+++ lib/CodeGen/CodeGenPGO.cpp
@@ -93,6 +93,7 @@
     BinaryOperatorLAnd,
     BinaryOperatorLOr,
     BinaryConditionalOperator,
+    SimpleFunctionHash, // Reserved for functions without aforesaid statements.
 
     // Keep this last.  It's for the static assert that follows.
     LastHashType
@@ -598,7 +599,10 @@
     // No need to byte swap here, since none of the math was endian-dependent.
     // This number will be byte-swapped as required on endianness transitions,
     // so we will see the same value on the other side.
-    return Working;
+    // If we didn't meet any known statements, return a special hash value,
+    // so that any used function will have a non-zero hash and won't be
+    // messed up with non-used functions when reading coverage data.
+    return Working ? Working : static_cast<uint64_t>(SimpleFunctionHash);
 
   // Check for remaining work in Working.
   if (Working)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to