Skip to content

Commit 41ae316

Browse files
authored
Merge pull request swiftlang#76045 from kubamracek/mergeable-traps
Add -Xfrontend -mergeable-traps as a way to emit mergeable traps
2 parents 6463dcb + b08f630 commit 41ae316

File tree

12 files changed

+103
-5
lines changed

12 files changed

+103
-5
lines changed

SwiftCompilerSources/Sources/Optimizer/FunctionPasses/MergeCondFails.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,12 @@ private func runMergeCondFails(function: Function, context: FunctionPassContext)
3939

4040
for inst in block.instructions {
4141
if let cfi = inst as? CondFailInst {
42+
let messageIsSame = condFailToMerge.isEmpty || cfi.message == condFailToMerge.first!.message
43+
let forceAllowMerge = context.options.enableMergeableTraps
44+
4245
// Do not process arithmetic overflow checks. We typically generate more
4346
// efficient code with separate jump-on-overflow.
44-
if !hasOverflowConditionOperand(cfi) &&
45-
(condFailToMerge.isEmpty || cfi.message == condFailToMerge.first!.message) {
47+
if !hasOverflowConditionOperand(cfi) && (messageIsSame || forceAllowMerge) {
4648
condFailToMerge.push(cfi)
4749
}
4850
} else if inst.mayHaveSideEffects || inst.mayReadFromMemory {

SwiftCompilerSources/Sources/Optimizer/PassManager/Options.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ struct Options {
4040
_bridged.hasFeature(.Embedded)
4141
}
4242

43+
var enableMergeableTraps: Bool {
44+
_bridged.enableMergeableTraps()
45+
}
46+
4347
func hasFeature(_ feature: BridgedFeature) -> Bool {
4448
_bridged.hasFeature(feature)
4549
}

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@ class IRGenOptions {
540540
// variants.
541541
unsigned UseCoroCCArm64 : 1;
542542

543+
// Whether to emit mergeable or non-mergeable traps.
544+
unsigned MergeableTraps : 1;
545+
543546
/// The number of threads for multi-threaded code generation.
544547
unsigned NumThreads = 0;
545548

@@ -646,6 +649,7 @@ class IRGenOptions {
646649
EmitAsyncFramePushPopMetadata(true), EmitTypeMallocForCoroFrame(false),
647650
AsyncFramePointerAll(false), UseProfilingMarkerThunks(false),
648651
UseCoroCCX8664(false), UseCoroCCArm64(false),
652+
MergeableTraps(false),
649653
DebugInfoForProfiling(false), CmdArgs(),
650654
SanitizeCoverage(llvm::SanitizerCoverageOptions()),
651655
TypeInfoFilter(TypeInfoDumpFilter::All),

include/swift/AST/SILOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -335,6 +335,9 @@ class SILOptions {
335335
/// Temporarily used to bootstrap the AddressableParameters feature.
336336
bool EnableAddressDependencies = true;
337337

338+
// Whether to allow merging traps and cond_fails.
339+
bool MergeableTraps = false;
340+
338341
SILOptions() {}
339342

340343
/// Return a hash code of any components from these options that should

include/swift/Option/FrontendOptions.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,6 +1401,10 @@ def disable_split_cold_code :
14011401
Flag<["-"], "disable-split-cold-code">,
14021402
HelpText<"Disable splitting of cold code when optimizing">;
14031403

1404+
def mergeable_traps :
1405+
Flag<["-"], "mergeable-traps">,
1406+
HelpText<"Emit mergeable traps even in optimized builds">;
1407+
14041408
def enable_new_llvm_pass_manager :
14051409
Flag<["-"], "enable-new-llvm-pass-manager">,
14061410
HelpText<"Enable the new llvm pass manager">;

include/swift/SILOptimizer/OptimizerBridging.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,6 +376,7 @@ struct BridgedPassContext {
376376

377377
BRIDGED_INLINE bool useAggressiveReg2MemForCodeSize() const;
378378
BRIDGED_INLINE bool enableStackProtection() const;
379+
BRIDGED_INLINE bool enableMergeableTraps() const;
379380
BRIDGED_INLINE bool hasFeature(BridgedFeature feature) const;
380381
BRIDGED_INLINE bool enableMoveInoutStackProtection() const;
381382
BRIDGED_INLINE AssertConfiguration getAssertConfiguration() const;

include/swift/SILOptimizer/OptimizerBridgingImpl.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,11 @@ bool BridgedPassContext::enableStackProtection() const {
543543
return mod->getOptions().EnableStackProtection;
544544
}
545545

546+
bool BridgedPassContext::enableMergeableTraps() const {
547+
swift::SILModule *mod = invocation->getPassManager()->getModule();
548+
return mod->getOptions().MergeableTraps;
549+
}
550+
546551
bool BridgedPassContext::hasFeature(BridgedFeature feature) const {
547552
swift::SILModule *mod = invocation->getPassManager()->getModule();
548553
return mod->getASTContext().LangOpts.hasFeature((swift::Feature)feature);

lib/DriverTool/sil_opt_main.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,10 @@ struct SILOptOptions {
596596
llvm::cl::opt<bool> EnableAddressDependencies = llvm::cl::opt<bool>(
597597
"enable-address-dependencies",
598598
llvm::cl::desc("Enable enforcement of lifetime dependencies on addressable values."));
599+
600+
llvm::cl::opt<bool> MergeableTraps = llvm::cl::opt<bool>(
601+
"mergeable-traps",
602+
llvm::cl::desc("Enable cond_fail merging."));
599603
};
600604

601605
/// Regular expression corresponding to the value given in one of the
@@ -914,6 +918,7 @@ int sil_opt_main(ArrayRef<const char *> argv, void *MainAddr) {
914918
options.EnablePackMetadataStackPromotion;
915919

916920
SILOpts.EnableAddressDependencies = options.EnableAddressDependencies;
921+
SILOpts.MergeableTraps = options.MergeableTraps;
917922

918923
if (options.OptModeFlag == OptimizationMode::NotSet) {
919924
if (options.OptimizationGroup == OptGroup::Diagnostics)

lib/Frontend/CompilerInvocation.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3127,11 +3127,11 @@ static bool ParseSILArgs(SILOptions &Opts, ArgList &Args,
31273127
Opts.ShouldFunctionsBePreservedToDebugger &=
31283128
LTOKind.value() == IRGenLLVMLTOKind::None;
31293129

3130-
3131-
Opts.EnableAddressDependencies =
3130+
Opts.EnableAddressDependencies =
31323131
Args.hasFlag(OPT_enable_address_dependencies,
31333132
OPT_disable_address_dependencies,
31343133
Opts.EnableAddressDependencies);
3134+
Opts.MergeableTraps = Args.hasArg(OPT_mergeable_traps);
31353135

31363136
return false;
31373137
}
@@ -3800,6 +3800,8 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
38003800
return true;
38013801
}
38023802

3803+
Opts.MergeableTraps = Args.hasArg(OPT_mergeable_traps);
3804+
38033805
Opts.EnableObjectiveCProtocolSymbolicReferences =
38043806
Args.hasFlag(OPT_enable_objective_c_protocol_symbolic_references,
38053807
OPT_disable_objective_c_protocol_symbolic_references,

lib/IRGen/IRGenFunction.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -503,7 +503,7 @@ llvm::CallInst *IRBuilder::CreateNonMergeableTrap(IRGenModule &IGM,
503503
}
504504
}
505505

506-
if (IGM.IRGen.Opts.shouldOptimize()) {
506+
if (IGM.IRGen.Opts.shouldOptimize() && !IGM.IRGen.Opts.MergeableTraps) {
507507
// Emit unique side-effecting inline asm calls in order to eliminate
508508
// the possibility that an LLVM optimization or code generation pass
509509
// will merge these blocks back together again. We emit an empty asm

0 commit comments

Comments
 (0)