Skip to content

Commit 9c2de99

Browse files
authored
[nfc][BoundsChecking] Refactor BoundsCheckingOptions (#122346)
Remove ReportingMode and ReportingOpts.
1 parent 211bcf6 commit 9c2de99

File tree

4 files changed

+77
-103
lines changed

4 files changed

+77
-103
lines changed

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,26 +1025,21 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
10251025
// Register callbacks to schedule sanitizer passes at the appropriate part
10261026
// of the pipeline.
10271027
if (LangOpts.Sanitize.has(SanitizerKind::LocalBounds))
1028-
PB.registerScalarOptimizerLateEPCallback(
1029-
[this](FunctionPassManager &FPM, OptimizationLevel Level) {
1030-
BoundsCheckingPass::ReportingMode Mode;
1031-
bool Merge = CodeGenOpts.SanitizeMergeHandlers.has(
1032-
SanitizerKind::LocalBounds);
1033-
1034-
if (CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
1035-
Mode = BoundsCheckingPass::ReportingMode::Trap;
1036-
} else if (CodeGenOpts.SanitizeMinimalRuntime) {
1037-
Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds)
1038-
? BoundsCheckingPass::ReportingMode::MinRuntime
1039-
: BoundsCheckingPass::ReportingMode::MinRuntimeAbort;
1040-
} else {
1041-
Mode = CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds)
1042-
? BoundsCheckingPass::ReportingMode::FullRuntime
1043-
: BoundsCheckingPass::ReportingMode::FullRuntimeAbort;
1044-
}
1045-
BoundsCheckingPass::BoundsCheckingOptions Options(Mode, Merge);
1046-
FPM.addPass(BoundsCheckingPass(Options));
1047-
});
1028+
PB.registerScalarOptimizerLateEPCallback([this](FunctionPassManager &FPM,
1029+
OptimizationLevel Level) {
1030+
BoundsCheckingPass::BoundsCheckingOptions Options;
1031+
Options.Merge =
1032+
CodeGenOpts.SanitizeMergeHandlers.has(SanitizerKind::LocalBounds);
1033+
if (!CodeGenOpts.SanitizeTrap.has(SanitizerKind::LocalBounds)) {
1034+
Options.Rt = {
1035+
/*MinRuntime=*/static_cast<bool>(
1036+
CodeGenOpts.SanitizeMinimalRuntime),
1037+
/*MayReturn=*/
1038+
CodeGenOpts.SanitizeRecover.has(SanitizerKind::LocalBounds),
1039+
};
1040+
}
1041+
FPM.addPass(BoundsCheckingPass(Options));
1042+
});
10481043

10491044
// Don't add sanitizers if we are here from ThinLTO PostLink. That already
10501045
// done on PreLink stage.

llvm/include/llvm/Transforms/Instrumentation/BoundsChecking.h

Lines changed: 9 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#define LLVM_TRANSFORMS_INSTRUMENTATION_BOUNDSCHECKING_H
1111

1212
#include "llvm/IR/PassManager.h"
13+
#include <optional>
1314

1415
namespace llvm {
1516
class Function;
@@ -19,19 +20,15 @@ class Function;
1920
class BoundsCheckingPass : public PassInfoMixin<BoundsCheckingPass> {
2021

2122
public:
22-
enum class ReportingMode {
23-
Trap,
24-
MinRuntime,
25-
MinRuntimeAbort,
26-
FullRuntime,
27-
FullRuntimeAbort,
28-
};
29-
3023
struct BoundsCheckingOptions {
31-
BoundsCheckingOptions(ReportingMode Mode, bool Merge);
32-
33-
ReportingMode Mode;
34-
bool Merge;
24+
struct Runtime {
25+
Runtime(bool MinRuntime, bool MayReturn)
26+
: MinRuntime(MinRuntime), MayReturn(MayReturn) {}
27+
bool MinRuntime;
28+
bool MayReturn;
29+
};
30+
std::optional<Runtime> Rt; // Trap if empty.
31+
bool Merge = false;
3532
};
3633

3734
BoundsCheckingPass(BoundsCheckingOptions Options) : Options(Options) {}

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1286,21 +1286,32 @@ parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
12861286

12871287
Expected<BoundsCheckingPass::BoundsCheckingOptions>
12881288
parseBoundsCheckingOptions(StringRef Params) {
1289-
BoundsCheckingPass::BoundsCheckingOptions Options(
1290-
BoundsCheckingPass::ReportingMode::Trap, false);
1289+
BoundsCheckingPass::BoundsCheckingOptions Options;
12911290
while (!Params.empty()) {
12921291
StringRef ParamName;
12931292
std::tie(ParamName, Params) = Params.split(';');
12941293
if (ParamName == "trap") {
1295-
Options.Mode = BoundsCheckingPass::ReportingMode::Trap;
1294+
Options.Rt = std::nullopt;
12961295
} else if (ParamName == "rt") {
1297-
Options.Mode = BoundsCheckingPass::ReportingMode::FullRuntime;
1296+
Options.Rt = {
1297+
/*MinRuntime=*/false,
1298+
/*MayReturn=*/true,
1299+
};
12981300
} else if (ParamName == "rt-abort") {
1299-
Options.Mode = BoundsCheckingPass::ReportingMode::FullRuntimeAbort;
1301+
Options.Rt = {
1302+
/*MinRuntime=*/false,
1303+
/*MayReturn=*/false,
1304+
};
13001305
} else if (ParamName == "min-rt") {
1301-
Options.Mode = BoundsCheckingPass::ReportingMode::MinRuntime;
1306+
Options.Rt = {
1307+
/*MinRuntime=*/true,
1308+
/*MayReturn=*/true,
1309+
};
13021310
} else if (ParamName == "min-rt-abort") {
1303-
Options.Mode = BoundsCheckingPass::ReportingMode::MinRuntimeAbort;
1311+
Options.Rt = {
1312+
/*MinRuntime=*/true,
1313+
/*MayReturn=*/false,
1314+
};
13041315
} else if (ParamName == "merge") {
13051316
Options.Merge = true;
13061317
} else {

llvm/lib/Transforms/Instrumentation/BoundsChecking.cpp

Lines changed: 35 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ STATISTIC(ChecksUnable, "Bounds checks unable to add");
4343

4444
using BuilderTy = IRBuilder<TargetFolder>;
4545

46-
BoundsCheckingPass::BoundsCheckingOptions::BoundsCheckingOptions(
47-
ReportingMode Mode, bool Merge)
48-
: Mode(Mode), Merge(Merge) {}
49-
5046
/// Gets the conditions under which memory accessing instructions will overflow.
5147
///
5248
/// \p Ptr is the pointer that will be read/written, and \p InstVal is either
@@ -166,42 +162,19 @@ static void insertBoundsCheck(Value *Or, BuilderTy &IRB, GetTrapBBT GetTrapBB) {
166162
BranchInst::Create(TrapBB, Cont, Or, OldBB);
167163
}
168164

169-
struct ReportingOpts {
170-
bool MayReturn = false;
171-
bool UseTrap = false;
172-
bool MinRuntime = false;
173-
bool MayMerge = true;
174-
StringRef Name;
175-
176-
ReportingOpts(BoundsCheckingPass::ReportingMode Mode, bool Merge) {
177-
switch (Mode) {
178-
case BoundsCheckingPass::ReportingMode::Trap:
179-
UseTrap = true;
180-
break;
181-
case BoundsCheckingPass::ReportingMode::MinRuntime:
182-
Name = "__ubsan_handle_local_out_of_bounds_minimal";
183-
MinRuntime = true;
184-
MayReturn = true;
185-
break;
186-
case BoundsCheckingPass::ReportingMode::MinRuntimeAbort:
187-
Name = "__ubsan_handle_local_out_of_bounds_minimal_abort";
188-
MinRuntime = true;
189-
break;
190-
case BoundsCheckingPass::ReportingMode::FullRuntime:
191-
Name = "__ubsan_handle_local_out_of_bounds";
192-
MayReturn = true;
193-
break;
194-
case BoundsCheckingPass::ReportingMode::FullRuntimeAbort:
195-
Name = "__ubsan_handle_local_out_of_bounds_abort";
196-
break;
197-
}
198-
199-
MayMerge = Merge;
200-
}
201-
};
165+
static std::string getRuntimeCallName(
166+
const BoundsCheckingPass::BoundsCheckingOptions::Runtime &Opts) {
167+
std::string Name = "__ubsan_handle_local_out_of_bounds";
168+
if (Opts.MinRuntime)
169+
Name += "_minimal";
170+
if (!Opts.MayReturn)
171+
Name += "_abort";
172+
return Name;
173+
}
202174

203-
static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
204-
ScalarEvolution &SE, const ReportingOpts &Opts) {
175+
static bool
176+
addBoundsChecking(Function &F, TargetLibraryInfo &TLI, ScalarEvolution &SE,
177+
const BoundsCheckingPass::BoundsCheckingOptions &Opts) {
205178
if (F.hasFnAttribute(Attribute::NoSanitizeBounds))
206179
return false;
207180

@@ -239,11 +212,16 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
239212
TrapInfo.push_back(std::make_pair(&I, Or));
240213
}
241214

215+
std::string Name;
216+
if (Opts.Rt)
217+
Name = getRuntimeCallName(*Opts.Rt);
218+
242219
// Create a trapping basic block on demand using a callback. Depending on
243220
// flags, this will either create a single block for the entire function or
244221
// will create a fresh block every time it is called.
245222
BasicBlock *ReuseTrapBB = nullptr;
246-
auto GetTrapBB = [&ReuseTrapBB, &Opts](BuilderTy &IRB, BasicBlock *Cont) {
223+
auto GetTrapBB = [&ReuseTrapBB, &Opts, &Name](BuilderTy &IRB,
224+
BasicBlock *Cont) {
247225
Function *Fn = IRB.GetInsertBlock()->getParent();
248226
auto DebugLoc = IRB.getCurrentDebugLocation();
249227
IRBuilder<>::InsertPointGuard Guard(IRB);
@@ -257,23 +235,24 @@ static bool addBoundsChecking(Function &F, TargetLibraryInfo &TLI,
257235
BasicBlock *TrapBB = BasicBlock::Create(Fn->getContext(), "trap", Fn);
258236
IRB.SetInsertPoint(TrapBB);
259237

260-
bool DebugTrapBB = !Opts.MayMerge;
261-
CallInst *TrapCall = Opts.UseTrap
262-
? InsertTrap(IRB, DebugTrapBB)
263-
: InsertCall(IRB, Opts.MayReturn, Opts.Name);
238+
bool DebugTrapBB = !Opts.Merge;
239+
CallInst *TrapCall = Opts.Rt ? InsertCall(IRB, Opts.Rt->MayReturn, Name)
240+
: InsertTrap(IRB, DebugTrapBB);
264241
if (DebugTrapBB)
265242
TrapCall->addFnAttr(llvm::Attribute::NoMerge);
266243

267244
TrapCall->setDoesNotThrow();
268245
TrapCall->setDebugLoc(DebugLoc);
269-
if (Opts.MayReturn) {
246+
247+
bool MayReturn = Opts.Rt && Opts.Rt->MayReturn;
248+
if (MayReturn) {
270249
IRB.CreateBr(Cont);
271250
} else {
272251
TrapCall->setDoesNotReturn();
273252
IRB.CreateUnreachable();
274253
}
275254

276-
if (!Opts.MayReturn && SingleTrapBB && !DebugTrapBB)
255+
if (!MayReturn && SingleTrapBB && !DebugTrapBB)
277256
ReuseTrapBB = TrapBB;
278257

279258
return TrapBB;
@@ -292,8 +271,7 @@ PreservedAnalyses BoundsCheckingPass::run(Function &F, FunctionAnalysisManager &
292271
auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
293272
auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
294273

295-
if (!addBoundsChecking(F, TLI, SE,
296-
ReportingOpts(Options.Mode, Options.Merge)))
274+
if (!addBoundsChecking(F, TLI, SE, Options))
297275
return PreservedAnalyses::all();
298276

299277
return PreservedAnalyses::none();
@@ -303,22 +281,15 @@ void BoundsCheckingPass::printPipeline(
303281
raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
304282
static_cast<PassInfoMixin<BoundsCheckingPass> *>(this)->printPipeline(
305283
OS, MapClassName2PassName);
306-
switch (Options.Mode) {
307-
case ReportingMode::Trap:
308-
OS << "<trap";
309-
break;
310-
case ReportingMode::MinRuntime:
311-
OS << "<min-rt";
312-
break;
313-
case ReportingMode::MinRuntimeAbort:
314-
OS << "<min-rt-abort";
315-
break;
316-
case ReportingMode::FullRuntime:
317-
OS << "<rt";
318-
break;
319-
case ReportingMode::FullRuntimeAbort:
320-
OS << "<rt-abort";
321-
break;
284+
OS << "<";
285+
if (Options.Rt) {
286+
if (Options.Rt->MinRuntime)
287+
OS << "min-";
288+
OS << "rt";
289+
if (!Options.Rt->MayReturn)
290+
OS << "-abort";
291+
} else {
292+
OS << "trap";
322293
}
323294
if (Options.Merge)
324295
OS << ";merge";

0 commit comments

Comments
 (0)