28
28
//
29
29
// ===----------------------------------------------------------------------===//
30
30
31
- #include " llvm/Transforms/Instrumentation.h"
32
31
#include " llvm/ADT/ArrayRef.h"
33
32
#include " llvm/ADT/SmallVector.h"
34
33
#include " llvm/Analysis/EHPersonalities.h"
34
+ #include " llvm/IR/CFG.h"
35
35
#include " llvm/IR/CallSite.h"
36
36
#include " llvm/IR/DataLayout.h"
37
37
#include " llvm/IR/DebugInfo.h"
38
+ #include " llvm/IR/Dominators.h"
38
39
#include " llvm/IR/Function.h"
39
40
#include " llvm/IR/IRBuilder.h"
40
41
#include " llvm/IR/InlineAsm.h"
45
46
#include " llvm/Support/CommandLine.h"
46
47
#include " llvm/Support/Debug.h"
47
48
#include " llvm/Support/raw_ostream.h"
49
+ #include " llvm/Transforms/Instrumentation.h"
48
50
#include " llvm/Transforms/Scalar.h"
49
51
#include " llvm/Transforms/Utils/BasicBlockUtils.h"
50
52
#include " llvm/Transforms/Utils/ModuleUtils.h"
@@ -94,6 +96,11 @@ static cl::opt<bool>
94
96
" instructions" ),
95
97
cl::Hidden, cl::init(false ));
96
98
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
+
97
104
// Experimental 8-bit counters used as an additional search heuristic during
98
105
// coverage-guided fuzzing.
99
106
// The counters are not thread-friendly:
@@ -298,6 +305,22 @@ bool SanitizerCoverageModule::runOnModule(Module &M) {
298
305
return true ;
299
306
}
300
307
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
+
301
324
bool SanitizerCoverageModule::runOnFunction (Function &F) {
302
325
if (F.empty ()) return false ;
303
326
if (F.getName ().find (" .module_ctor" ) != std::string::npos)
@@ -311,11 +334,15 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
311
334
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
312
335
SplitAllCriticalEdges (F);
313
336
SmallVector<Instruction*, 8 > IndirCalls;
314
- SmallVector<BasicBlock*, 16 > AllBlocks ;
337
+ SmallVector<BasicBlock *, 16 > BlocksToInstrument ;
315
338
SmallVector<Instruction*, 8 > CmpTraceTargets;
316
339
SmallVector<Instruction*, 8 > SwitchTraceTargets;
340
+
341
+ DominatorTree DT;
342
+ DT.recalculate (F);
317
343
for (auto &BB : F) {
318
- AllBlocks.push_back (&BB);
344
+ if (shouldInstrumentBlock (&BB, &DT))
345
+ BlocksToInstrument.push_back (&BB);
319
346
for (auto &Inst : BB) {
320
347
if (Options.IndirectCalls ) {
321
348
CallSite CS (&Inst);
@@ -330,7 +357,8 @@ bool SanitizerCoverageModule::runOnFunction(Function &F) {
330
357
}
331
358
}
332
359
}
333
- InjectCoverage (F, AllBlocks);
360
+
361
+ InjectCoverage (F, BlocksToInstrument);
334
362
InjectCoverageForIndirectCalls (F, IndirCalls);
335
363
InjectTraceForCmp (F, CmpTraceTargets);
336
364
InjectTraceForSwitch (F, SwitchTraceTargets);
0 commit comments