Skip to content

Commit 5971f18

Browse files
committedFeb 26, 2016
[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 llvm-svn: 261949
1 parent 7ed9361 commit 5971f18

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed
 

‎llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,14 @@
2828
//
2929
//===----------------------------------------------------------------------===//
3030

31-
#include "llvm/Transforms/Instrumentation.h"
3231
#include "llvm/ADT/ArrayRef.h"
3332
#include "llvm/ADT/SmallVector.h"
3433
#include "llvm/Analysis/EHPersonalities.h"
34+
#include "llvm/IR/CFG.h"
3535
#include "llvm/IR/CallSite.h"
3636
#include "llvm/IR/DataLayout.h"
3737
#include "llvm/IR/DebugInfo.h"
38+
#include "llvm/IR/Dominators.h"
3839
#include "llvm/IR/Function.h"
3940
#include "llvm/IR/IRBuilder.h"
4041
#include "llvm/IR/InlineAsm.h"
@@ -45,6 +46,7 @@
4546
#include "llvm/Support/CommandLine.h"
4647
#include "llvm/Support/Debug.h"
4748
#include "llvm/Support/raw_ostream.h"
49+
#include "llvm/Transforms/Instrumentation.h"
4850
#include "llvm/Transforms/Scalar.h"
4951
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
5052
#include "llvm/Transforms/Utils/ModuleUtils.h"
@@ -94,6 +96,11 @@ static cl::opt<bool>
9496
"instructions"),
9597
cl::Hidden, cl::init(false));
9698

99+
static cl::opt<bool> ClPruneBlocks(
100+
"sanitizer-coverage-prune-blocks",
101+
cl::desc("Reduce the number of instrumented blocks (experimental)"),
102+
cl::Hidden, cl::init(false));
103+
97104
// Experimental 8-bit counters used as an additional search heuristic during
98105
// coverage-guided fuzzing.
99106
// The counters are not thread-friendly:
@@ -298,6 +305,22 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
298305
return true;
299306
}
300307

308+
static bool shouldInstrumentBlock(const BasicBlock *BB,
309+
const DominatorTree *DT) {
310+
if (!ClPruneBlocks)
311+
return true;
312+
if (succ_begin(BB) == succ_end(BB))
313+
return true;
314+
315+
// Check if BB dominates all its successors.
316+
for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
317+
if (!DT->dominates(BB, SUCC))
318+
return true;
319+
}
320+
321+
return false;
322+
}
323+
301324
bool SanitizerCoverageModule::runOnFunction(Function &F) {
302325
if (F.empty()) return false;
303326
if (F.getName().find(".module_ctor") != std::string::npos)
@@ -311,11 +334,15 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
311334
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
312335
SplitAllCriticalEdges(F);
313336
SmallVector<Instruction*, 8> IndirCalls;
314-
SmallVector<BasicBlock*, 16> AllBlocks;
337+
SmallVector<BasicBlock *, 16> BlocksToInstrument;
315338
SmallVector<Instruction*, 8> CmpTraceTargets;
316339
SmallVector<Instruction*, 8> SwitchTraceTargets;
340+
341+
DominatorTree DT;
342+
DT.recalculate(F);
317343
for (auto &BB : F) {
318-
AllBlocks.push_back(&BB);
344+
if (shouldInstrumentBlock(&BB, &DT))
345+
BlocksToInstrument.push_back(&BB);
319346
for (auto &Inst : BB) {
320347
if (Options.IndirectCalls) {
321348
CallSite CS(&Inst);
@@ -330,7 +357,8 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
330357
}
331358
}
332359
}
333-
InjectCoverage(F, AllBlocks);
360+
361+
InjectCoverage(F, BlocksToInstrument);
334362
InjectCoverageForIndirectCalls(F, IndirCalls);
335363
InjectTraceForCmp(F, CmpTraceTargets);
336364
InjectTraceForSwitch(F, SwitchTraceTargets);

‎llvm/test/Instrumentation/SanitizerCoverage/coverage.ll

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
; RUN: -S | FileCheck %s --check-prefix=CHECK2
1414
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 \
1515
; RUN: -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK
16+
; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=CHECKPRUNE
1617

1718
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"
1819
target triple = "x86_64-unknown-linux-gnu"
@@ -134,3 +135,11 @@ entry:
134135
; CHECK4-LABEL: define void @call_unreachable
135136
; CHECK4-NOT: __sanitizer_cov
136137
; CHECK4: unreachable
138+
139+
; CHECKPRUNE-LABEL: define void @foo
140+
; CHECKPRUNE: call void @__sanitizer_cov
141+
; CHECKPRUNE: call void asm sideeffect "", ""()
142+
; CHECKPRUNE: call void @__sanitizer_cov
143+
; CHECKPRUNE: call void asm sideeffect "", ""()
144+
; CHECKPRUNE-NOT: call void @__sanitizer_cov
145+
; CHECKPRUNE: ret void

0 commit comments

Comments
 (0)
Please sign in to comment.