[libFuzzer] Optimize handle unstable checks by reducing iterations

Summary:
We only run the 3rd check if 2nd check finds unstable edges. 
3rd UpdateUnstableCounters is now merged with ApplyUnstableCounters to only run 1 iteration.

Patch by Kyungtak Woo (@kevinwkt).

Reviewers: Dor1s, metzman, morehouse

Reviewed By: Dor1s, morehouse

Subscribers: delcypher, #sanitizers, llvm-commits, kcc

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

git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk/lib/fuzzer@339249 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/FuzzerTracePC.cpp b/FuzzerTracePC.cpp
index 7874f13..1aba816 100644
--- a/FuzzerTracePC.cpp
+++ b/FuzzerTracePC.cpp
@@ -81,9 +81,11 @@
 
 // Compares the current counters with counters from previous runs
 // and records differences as unstable edges.
-void TracePC::UpdateUnstableCounters(int UnstableMode) {
+bool TracePC::UpdateUnstableCounters(int UnstableMode) {
+  bool Updated = false;
   IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
     if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) {
+      Updated = true;
       UnstableCounters[UnstableIdx].IsUnstable = true;
       if (UnstableMode == ZeroUnstable)
         UnstableCounters[UnstableIdx].Counter = 0;
@@ -92,12 +94,20 @@
             ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter);
     }
   });
+  return Updated;
 }
 
-// Moves the minimum hit counts to ModuleCounters.
-void TracePC::ApplyUnstableCounters() {
+// Updates and applies unstable counters to ModuleCounters in single iteration
+void TracePC::UpdateAndApplyUnstableCounters(int UnstableMode) {
   IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
-    ModuleCounters[i].Start[j] = UnstableCounters[UnstableIdx].Counter;
+    if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) {
+      UnstableCounters[UnstableIdx].IsUnstable = true;
+      if (UnstableMode == ZeroUnstable)
+        ModuleCounters[i].Start[j] = 0;
+      else if (UnstableMode == MinUnstable)
+        ModuleCounters[i].Start[j] = std::min(
+            ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter);
+    }
   });
 }