llvm.org GIT mirror llvm / 5e86c5c
[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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@261949 91177308-0d34-0410-b5e6-96231b3b80d8 Mike Aizatsky 4 years ago
2 changed file(s) with 41 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
2727 //
2828 //===----------------------------------------------------------------------===//
2929
30 #include "llvm/Transforms/Instrumentation.h"
3130 #include "llvm/ADT/ArrayRef.h"
3231 #include "llvm/ADT/SmallVector.h"
3332 #include "llvm/Analysis/EHPersonalities.h"
33 #include "llvm/IR/CFG.h"
3434 #include "llvm/IR/CallSite.h"
3535 #include "llvm/IR/DataLayout.h"
3636 #include "llvm/IR/DebugInfo.h"
37 #include "llvm/IR/Dominators.h"
3738 #include "llvm/IR/Function.h"
3839 #include "llvm/IR/IRBuilder.h"
3940 #include "llvm/IR/InlineAsm.h"
4445 #include "llvm/Support/CommandLine.h"
4546 #include "llvm/Support/Debug.h"
4647 #include "llvm/Support/raw_ostream.h"
48 #include "llvm/Transforms/Instrumentation.h"
4749 #include "llvm/Transforms/Scalar.h"
4850 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
4951 #include "llvm/Transforms/Utils/ModuleUtils.h"
9294 cl::desc("Experimental tracing of CMP and similar "
9395 "instructions"),
9496 cl::Hidden, cl::init(false));
97
98 static cl::opt ClPruneBlocks(
99 "sanitizer-coverage-prune-blocks",
100 cl::desc("Reduce the number of instrumented blocks (experimental)"),
101 cl::Hidden, cl::init(false));
95102
96103 // Experimental 8-bit counters used as an additional search heuristic during
97104 // coverage-guided fuzzing.
297304 return true;
298305 }
299306
307 static bool shouldInstrumentBlock(const BasicBlock *BB,
308 const DominatorTree *DT) {
309 if (!ClPruneBlocks)
310 return true;
311 if (succ_begin(BB) == succ_end(BB))
312 return true;
313
314 // Check if BB dominates all its successors.
315 for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
316 if (!DT->dominates(BB, SUCC))
317 return true;
318 }
319
320 return false;
321 }
322
300323 bool SanitizerCoverageModule::runOnFunction(Function &F) {
301324 if (F.empty()) return false;
302325 if (F.getName().find(".module_ctor") != std::string::npos)
310333 if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
311334 SplitAllCriticalEdges(F);
312335 SmallVector IndirCalls;
313 SmallVector*, 16> AllBlocks;
336 SmallVector *, 16> BlocksToInstrument;
314337 SmallVector CmpTraceTargets;
315338 SmallVector SwitchTraceTargets;
339
340 DominatorTree DT;
341 DT.recalculate(F);
316342 for (auto &BB : F) {
317 AllBlocks.push_back(&BB);
343 if (shouldInstrumentBlock(&BB, &DT))
344 BlocksToInstrument.push_back(&BB);
318345 for (auto &Inst : BB) {
319346 if (Options.IndirectCalls) {
320347 CallSite CS(&Inst);
329356 }
330357 }
331358 }
332 InjectCoverage(F, AllBlocks);
359
360 InjectCoverage(F, BlocksToInstrument);
333361 InjectCoverageForIndirectCalls(F, IndirCalls);
334362 InjectTraceForCmp(F, CmpTraceTargets);
335363 InjectTraceForSwitch(F, SwitchTraceTargets);
1212 ; RUN: -S | FileCheck %s --check-prefix=CHECK2
1313 ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-block-threshold=1 \
1414 ; RUN: -S | FileCheck %s --check-prefix=CHECK_WITH_CHECK
15 ; RUN: opt < %s -sancov -sanitizer-coverage-level=2 -sanitizer-coverage-prune-blocks=1 -S | FileCheck %s --check-prefix=CHECKPRUNE
1516
1617 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"
1718 target triple = "x86_64-unknown-linux-gnu"
133134 ; CHECK4-LABEL: define void @call_unreachable
134135 ; CHECK4-NOT: __sanitizer_cov
135136 ; CHECK4: unreachable
137
138 ; CHECKPRUNE-LABEL: define void @foo
139 ; CHECKPRUNE: call void @__sanitizer_cov
140 ; CHECKPRUNE: call void asm sideeffect "", ""()
141 ; CHECKPRUNE: call void @__sanitizer_cov
142 ; CHECKPRUNE: call void asm sideeffect "", ""()
143 ; CHECKPRUNE-NOT: call void @__sanitizer_cov
144 ; CHECKPRUNE: ret void