|
52 | 52 | #include "llvm/Support/Casting.h"
|
53 | 53 | #include "llvm/Support/CommandLine.h"
|
54 | 54 | #include "llvm/Support/Debug.h"
|
| 55 | +#include "llvm/Support/RandomNumberGenerator.h" |
55 | 56 | #include "llvm/Support/raw_ostream.h"
|
56 | 57 | #include "llvm/TargetParser/Triple.h"
|
57 | 58 | #include "llvm/Transforms/Instrumentation/AddressSanitizerCommon.h"
|
|
61 | 62 | #include "llvm/Transforms/Utils/ModuleUtils.h"
|
62 | 63 | #include "llvm/Transforms/Utils/PromoteMemToReg.h"
|
63 | 64 | #include <optional>
|
| 65 | +#include <random> |
64 | 66 |
|
65 | 67 | using namespace llvm;
|
66 | 68 |
|
@@ -181,16 +183,23 @@ static cl::opt<bool> ClWithTls(
|
181 | 183 | cl::Hidden, cl::init(true));
|
182 | 184 |
|
183 | 185 | static cl::opt<bool>
|
184 |
| - CSkipHotCode("hwasan-skip-hot-code", |
185 |
| - cl::desc("Do not instument hot functions based on FDO."), |
186 |
| - cl::Hidden, cl::init(false)); |
| 186 | + CSelectiveInstrumentation("hwasan-selective-instrumentation", |
| 187 | + cl::desc("Use selective instrumentation"), |
| 188 | + cl::Hidden, cl::init(false)); |
187 | 189 |
|
188 |
| -static cl::opt<int> HotPercentileCutoff("hwasan-percentile-cutoff-hot", |
189 |
| - cl::init(0)); |
| 190 | +static cl::opt<int> HotPercentileCutoff( |
| 191 | + "hwasan-percentile-cutoff-hot", cl::init(0), |
| 192 | + cl::desc("Alternative hot percentile cuttoff." |
| 193 | + "By default `-profile-summary-cutoff-hot` is used.")); |
190 | 194 |
|
191 |
| -STATISTIC(NumTotalFuncs, "Number of total funcs HWASAN"); |
192 |
| -STATISTIC(NumInstrumentedFuncs, "Number of HWASAN instrumented funcs"); |
193 |
| -STATISTIC(NumNoProfileSummaryFuncs, "Number of HWASAN funcs without PS"); |
| 195 | +static cl::opt<float> |
| 196 | + RandomSkipRate("hwasan-random-skip-rate", cl::init(0), |
| 197 | + cl::desc("Probability value in the range [0.0, 1.0] " |
| 198 | + "to skip instrumentation of a function.")); |
| 199 | + |
| 200 | +STATISTIC(NumTotalFuncs, "Number of total funcs"); |
| 201 | +STATISTIC(NumInstrumentedFuncs, "Number of instrumented funcs"); |
| 202 | +STATISTIC(NumNoProfileSummaryFuncs, "Number of funcs without PS"); |
194 | 203 |
|
195 | 204 | // Mode for selecting how to insert frame record info into the stack ring
|
196 | 205 | // buffer.
|
@@ -291,6 +300,8 @@ class HWAddressSanitizer {
|
291 | 300 | this->CompileKernel = ClEnableKhwasan.getNumOccurrences() > 0
|
292 | 301 | ? ClEnableKhwasan
|
293 | 302 | : CompileKernel;
|
| 303 | + this->Rng = |
| 304 | + RandomSkipRate.getNumOccurrences() ? M.createRNG("hwasan") : nullptr; |
294 | 305 |
|
295 | 306 | initializeModule();
|
296 | 307 | }
|
@@ -372,6 +383,7 @@ class HWAddressSanitizer {
|
372 | 383 | Module &M;
|
373 | 384 | const StackSafetyGlobalInfo *SSI;
|
374 | 385 | Triple TargetTriple;
|
| 386 | + std::unique_ptr<RandomNumberGenerator> Rng; |
375 | 387 |
|
376 | 388 | /// This struct defines the shadow mapping using the rule:
|
377 | 389 | /// shadow = (mem >> Scale) + Offset.
|
@@ -1526,19 +1538,26 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
|
1526 | 1538 | return;
|
1527 | 1539 |
|
1528 | 1540 | NumTotalFuncs++;
|
1529 |
| - if (CSkipHotCode) { |
1530 |
| - auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F); |
1531 |
| - ProfileSummaryInfo *PSI = |
1532 |
| - MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent()); |
1533 |
| - if (PSI && PSI->hasProfileSummary()) { |
1534 |
| - auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F); |
1535 |
| - if ((HotPercentileCutoff.getNumOccurrences() && HotPercentileCutoff >= 0) |
1536 |
| - ? PSI->isFunctionHotInCallGraphNthPercentile(HotPercentileCutoff, |
1537 |
| - &F, BFI) |
1538 |
| - : PSI->isFunctionHotInCallGraph(&F, BFI)) |
| 1541 | + if (CSelectiveInstrumentation) { |
| 1542 | + if (RandomSkipRate.getNumOccurrences()) { |
| 1543 | + std::bernoulli_distribution D(RandomSkipRate); |
| 1544 | + if (D(*Rng)) |
1539 | 1545 | return;
|
1540 | 1546 | } else {
|
1541 |
| - ++NumNoProfileSummaryFuncs; |
| 1547 | + auto &MAMProxy = FAM.getResult<ModuleAnalysisManagerFunctionProxy>(F); |
| 1548 | + ProfileSummaryInfo *PSI = |
| 1549 | + MAMProxy.getCachedResult<ProfileSummaryAnalysis>(*F.getParent()); |
| 1550 | + if (PSI && PSI->hasProfileSummary()) { |
| 1551 | + auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F); |
| 1552 | + if ((HotPercentileCutoff.getNumOccurrences() && |
| 1553 | + HotPercentileCutoff >= 0) |
| 1554 | + ? PSI->isFunctionHotInCallGraphNthPercentile( |
| 1555 | + HotPercentileCutoff, &F, BFI) |
| 1556 | + : PSI->isFunctionHotInCallGraph(&F, BFI)) |
| 1557 | + return; |
| 1558 | + } else { |
| 1559 | + ++NumNoProfileSummaryFuncs; |
| 1560 | + } |
1542 | 1561 | }
|
1543 | 1562 | }
|
1544 | 1563 | NumInstrumentedFuncs++;
|
|
0 commit comments