55// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66//
77// ===----------------------------------------------------------------------===//
8- //
9- //
10- // ===----------------------------------------------------------------------===//
118
129#include " llvm/Transforms/Instrumentation/RemoveTrapsPass.h"
1310
1714#include " llvm/IR/Instructions.h"
1815#include " llvm/IR/IntrinsicInst.h"
1916#include " llvm/IR/Intrinsics.h"
20- #include < cstdint>
17+ #include " llvm/Support/RandomNumberGenerator.h"
18+ #include < memory>
19+ #include < random>
2120
2221using namespace llvm ;
2322
2423#define DEBUG_TYPE " remove-traps"
2524
26- static constexpr unsigned MaxRandomRate = 1000 ;
27-
2825static cl::opt<int > HotPercentileCutoff (
2926 " remove-traps-percentile-cutoff-hot" , cl::init(0 ),
3027 cl::desc(" Alternative hot percentile cuttoff. By default "
3128 " `-profile-summary-cutoff-hot` is used." ));
29+
3230static cl::opt<float > RandomRate (
3331 " remove-traps-random-rate" , cl::init(0.0 ),
34- cl::desc(
35- " Probability to use for pseudorandom unconditional checks removal." ));
32+ cl::desc(" Probability of unconditional pseudorandom checks removal." ));
3633
3734STATISTIC (NumChecksTotal, " Number of checks" );
3835STATISTIC (NumChecksRemoved, " Number of removed checks" );
3936
40- static SmallVector<IntrinsicInst *, 16 >
41- removeUbsanTraps (Function &F, FunctionAnalysisManager &FAM,
42- ProfileSummaryInfo *PSI) {
37+ static bool removeUbsanTraps (Function &F, const BlockFrequencyInfo &BFI,
38+ const ProfileSummaryInfo *PSI) {
4339 SmallVector<IntrinsicInst *, 16 > Remove;
40+ std::unique_ptr<RandomNumberGenerator> Rng;
4441
45- if (F.isDeclaration ())
46- return {};
47-
48- auto &BFI = FAM.getResult <BlockFrequencyAnalysis>(F);
49-
50- int BBCounter = 0 ;
5142 for (BasicBlock &BB : F) {
5243 for (Instruction &I : BB) {
5344 IntrinsicInst *II = dyn_cast<IntrinsicInst>(&I);
@@ -65,18 +56,34 @@ removeUbsanTraps(Function &F, FunctionAnalysisManager &FAM,
6556 Count += BFI.getBlockProfileCount (PR).value_or (0 );
6657
6758 IsHot = HotPercentileCutoff.getNumOccurrences ()
68- ? PSI->isHotCountNthPercentile (HotPercentileCutoff, Count)
59+ ? (HotPercentileCutoff > 0 &&
60+ PSI->isHotCountNthPercentile (HotPercentileCutoff, Count))
6961 : PSI->isHotCount (Count);
7062 }
7163
72- if ((IsHot) || ((F.getGUID () + BBCounter++) % MaxRandomRate) <
73- RandomRate * RandomRate) {
64+ auto ShouldRemove = [&]() {
65+ if (IsHot)
66+ return true ;
67+ if (!Rng) {
68+ if (!RandomRate.getNumOccurrences ())
69+ return false ;
70+ Rng = F.getParent ()->createRNG (F.getName ());
71+ }
72+ std::bernoulli_distribution D (RandomRate);
73+ return D (*Rng);
74+ };
75+
76+ if (ShouldRemove ()) {
7477 Remove.push_back (II);
7578 ++NumChecksRemoved;
7679 }
7780 }
7881 }
79- return Remove;
82+
83+ for (auto *I : Remove)
84+ I->eraseFromParent ();
85+
86+ return !Remove.empty ();
8087}
8188
8289PreservedAnalyses RemoveTrapsPass::run (Function &F,
@@ -86,10 +93,8 @@ PreservedAnalyses RemoveTrapsPass::run(Function &F,
8693 auto &MAMProxy = AM.getResult <ModuleAnalysisManagerFunctionProxy>(F);
8794 ProfileSummaryInfo *PSI =
8895 MAMProxy.getCachedResult <ProfileSummaryAnalysis>(*F.getParent ());
96+ BlockFrequencyInfo &BFI = AM.getResult <BlockFrequencyAnalysis>(F);
8997
90- auto Remove = removeUbsanTraps (F, AM, PSI);
91- for (auto *I : Remove)
92- I->eraseFromParent ();
93-
94- return Remove.empty () ? PreservedAnalyses::all () : PreservedAnalyses::none ();
98+ return removeUbsanTraps (F, BFI, PSI) ? PreservedAnalyses::none ()
99+ : PreservedAnalyses::all ();
95100}
0 commit comments