[llvm] r261949 - [sancov] Pruning full dominator blocks from instrumentation.

Mike Aizatsky via llvm-commits llvm-commits at lists.llvm.org
Thu Feb 25 17:17:22 PST 2016


Author: aizatsky
Date: Thu Feb 25 19:17:22 2016
New Revision: 261949

URL: http://llvm.org/viewvc/llvm-project?rev=261949&view=rev
Log:
[sancov] Pruning full dominator blocks from instrumentation.

Summary:
This is the first simple attempt to reduce number of coverage-
instrumented blocks.

If a basic block dominates all its successors, then its coverage
information is useless to us. Ingore such blocks if
santizer-coverage-prune-tree option is set.

Differential Revision: http://reviews.llvm.org/D17626

Modified:
    llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
    llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll

Modified: llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp?rev=261949&r1=261948&r2=261949&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/SanitizerCoverage.cpp Thu Feb 25 19:17:22 2016
@@ -28,13 +28,14 @@
 //
 //===----------------------------------------------------------------------===//
 
-#include "llvm/Transforms/Instrumentation.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Analysis/EHPersonalities.h"
+#include "llvm/IR/CFG.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/DataLayout.h"
 #include "llvm/IR/DebugInfo.h"
+#include "llvm/IR/Dominators.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/IRBuilder.h"
 #include "llvm/IR/InlineAsm.h"
@@ -45,6 +46,7 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Scalar.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -94,6 +96,11 @@ static cl::opt<bool>
                                       "instructions"),
                              cl::Hidden, cl::init(false));
 
+static cl::opt<bool> ClPruneBlocks(
+    "sanitizer-coverage-prune-blocks",
+    cl::desc("Reduce the number of instrumented blocks (experimental)"),
+    cl::Hidden, cl::init(false));
+
 // Experimental 8-bit counters used as an additional search heuristic during
 // coverage-guided fuzzing.
 // The counters are not thread-friendly:
@@ -298,6 +305,22 @@ bool SanitizerCoverageModule::runOnModul
   return true;
 }
 
+static bool shouldInstrumentBlock(const BasicBlock *BB,
+                                  const DominatorTree *DT) {
+  if (!ClPruneBlocks)
+    return true;
+  if (succ_begin(BB) == succ_end(BB))
+    return true;
+
+  // Check if BB dominates all its successors.
+  for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
+    if (!DT->dominates(BB, SUCC))
+      return true;
+  }
+
+  return false;
+}
+
 bool SanitizerCoverageModule::runOnFunction(Function &F) {
   if (F.empty()) return false;
   if (F.getName().find(".module_ctor") != std::string::npos)
@@ -311,11 +334,15 @@ bool SanitizerCoverageModule::runOnFunct
   if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
     SplitAllCriticalEdges(F);
   SmallVector<Instruction*, 8> IndirCalls;
-  SmallVector<BasicBlock*, 16> AllBlocks;
+  SmallVector<BasicBlock *, 16> BlocksToInstrument;
   SmallVector<Instruction*, 8> CmpTraceTargets;
   SmallVector<Instruction*, 8> SwitchTraceTargets;
+
+  DominatorTree DT;
+  DT.recalculate(F);
   for (auto &BB : F) {
-    AllBlocks.push_back(&BB);
+    if (shouldInstrumentBlock(&BB, &DT))
+      BlocksToInstrument.push_back(&BB);
     for (auto &Inst : BB) {
       if (Options.IndirectCalls) {
         CallSite CS(&Inst);
@@ -330,7 +357,8 @@ bool SanitizerCoverageModule::runOnFunct
       }
     }
   }
-  InjectCoverage(F, AllBlocks);
+
+  InjectCoverage(F, BlocksToInstrument);
   InjectCoverageForIndirectCalls(F, IndirCalls);
   InjectTraceForCmp(F, CmpTraceTargets);
   InjectTraceForSwitch(F, SwitchTraceTargets);

Modified: llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll?rev=261949&r1=261948&r2=261949&view=diff
==============================================================================
--- llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll (original)
+++ llvm/trunk/test/Instrumentation/SanitizerCoverage/coverage.ll Thu Feb 25 19:17:22 2016
@@ -13,6 +13,7 @@
 ; RUN:      -S | FileCheck %s --check-prefix=CHECK2
 ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 \
 ; RUN:      -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK
+; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=CHECKPRUNE
 
 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
 target triple = "x86_64-unknown-linux-gnu"
@@ -134,3 +135,11 @@ entry:
 ; CHECK4-LABEL: define void @call_unreachable
 ; CHECK4-NOT: __sanitizer_cov
 ; CHECK4: unreachable
+
+; CHECKPRUNE-LABEL: define void @foo
+; CHECKPRUNE: call void @__sanitizer_cov
+; CHECKPRUNE: call void asm sideeffect "", ""()
+; CHECKPRUNE: call void @__sanitizer_cov
+; CHECKPRUNE: call void asm sideeffect "", ""()
+; CHECKPRUNE-NOT: call void @__sanitizer_cov
+; CHECKPRUNE: ret void




More information about the llvm-commits mailing list