1
- // ===--- OSSALifetimeCompletion .cpp ---------------------------------------===//
1
+ // ===--- OSSACompleteLifetime .cpp ---------------------------------------===//
2
2
//
3
3
// This source file is part of the Swift.org open source project
4
4
//
49
49
// /
50
50
// ===----------------------------------------------------------------------===//
51
51
52
- #include " swift/SIL/OSSALifetimeCompletion .h"
52
+ #include " swift/SIL/OSSACompleteLifetime .h"
53
53
#include " swift/Basic/Assertions.h"
54
54
#include " swift/SIL/AddressWalker.h"
55
55
#include " swift/SIL/BasicBlockUtils.h"
@@ -64,17 +64,17 @@ using namespace swift;
64
64
// FIXME: remove this option after fixing:
65
65
// rdar://145994924 (Mem2Reg calls lifetime completion without checking for
66
66
// pointer escapes)
67
- llvm::cl::opt<bool > VerifyLifetimeCompletion (
68
- " verify-lifetime-completion " , llvm::cl::init(false ),
69
- llvm::cl::desc(" ." ));
67
+ llvm::cl::opt<bool > VerifyLifetimeCompletion (" verify-lifetime-completion " ,
68
+ llvm::cl::init (false ),
69
+ llvm::cl::desc(" ." ));
70
70
71
71
static SILInstruction *endOSSALifetime (SILValue value,
72
- OSSALifetimeCompletion ::LifetimeEnd end,
72
+ OSSACompleteLifetime ::LifetimeEnd end,
73
73
SILBuilder &builder,
74
74
DeadEndBlocks &deb) {
75
75
auto loc =
76
- RegularLocation::getAutoGeneratedLocation (builder.getInsertionPointLoc ());
77
- if (end == OSSALifetimeCompletion ::LifetimeEnd::Loop) {
76
+ RegularLocation::getAutoGeneratedLocation (builder.getInsertionPointLoc ());
77
+ if (end == OSSACompleteLifetime ::LifetimeEnd::Loop) {
78
78
return builder.createExtendLifetime (loc, value);
79
79
}
80
80
auto isDeadEnd = IsDeadEnd_t (deb.isDeadEnd (builder.getInsertionBB ()));
@@ -101,21 +101,21 @@ static bool endLifetimeAtLivenessBoundary(SILValue value,
101
101
102
102
bool changed = false ;
103
103
for (SILInstruction *lastUser : boundary.lastUsers ) {
104
- if (liveness.isInterestingUser (lastUser)
105
- != PrunedLiveness::LifetimeEndingUse) {
104
+ if (liveness.isInterestingUser (lastUser) !=
105
+ PrunedLiveness::LifetimeEndingUse) {
106
106
changed = true ;
107
- SILBuilderWithScope::insertAfter (lastUser, [value,
108
- &deb](SILBuilder &builder) {
109
- endOSSALifetime (value, OSSALifetimeCompletion ::LifetimeEnd::Boundary,
110
- builder, deb);
111
- });
107
+ SILBuilderWithScope::insertAfter (
108
+ lastUser, [value, &deb](SILBuilder &builder) {
109
+ endOSSALifetime (value, OSSACompleteLifetime ::LifetimeEnd::Boundary,
110
+ builder, deb);
111
+ });
112
112
}
113
113
}
114
114
for (SILBasicBlock *edge : boundary.boundaryEdges ) {
115
115
changed = true ;
116
116
SILBuilderWithScope builder (edge->begin ());
117
- endOSSALifetime (value, OSSALifetimeCompletion ::LifetimeEnd::Boundary,
118
- builder, deb);
117
+ endOSSALifetime (value, OSSACompleteLifetime ::LifetimeEnd::Boundary, builder ,
118
+ deb);
119
119
}
120
120
for (SILNode *deadDef : boundary.deadDefs ) {
121
121
SILInstruction *next = nullptr ;
@@ -126,8 +126,8 @@ static bool endLifetimeAtLivenessBoundary(SILValue value,
126
126
}
127
127
changed = true ;
128
128
SILBuilderWithScope builder (next);
129
- endOSSALifetime (value, OSSALifetimeCompletion ::LifetimeEnd::Boundary,
130
- builder, deb);
129
+ endOSSALifetime (value, OSSACompleteLifetime ::LifetimeEnd::Boundary, builder ,
130
+ deb);
131
131
}
132
132
return changed;
133
133
}
@@ -174,7 +174,7 @@ namespace {
174
174
// / Visits the latest instructions at which `value` is available.
175
175
// /
176
176
// / Together with visitUsersOutsideLinearLivenessBoundary, implements
177
- // / OSSALifetimeCompletion ::visitAvailabilityBoundary.
177
+ // / OSSACompleteLifetime ::visitAvailabilityBoundary.
178
178
// /
179
179
// / Finding these positions is a three step process:
180
180
// / 1) computeRegion: Forward CFG walk from non-lifetime-ending boundary to find
@@ -200,7 +200,7 @@ class AvailabilityBoundaryVisitor {
200
200
region(value->getFunction ()) {}
201
201
202
202
using Visit = llvm::function_ref<void (SILInstruction *,
203
- OSSALifetimeCompletion ::LifetimeEnd)>;
203
+ OSSACompleteLifetime ::LifetimeEnd)>;
204
204
205
205
struct Result ;
206
206
@@ -311,8 +311,8 @@ void AvailabilityBoundaryVisitor::computeRegion(
311
311
// ScopedAddresses) are available only up to their last extend_lifetime on
312
312
// non-dead-end paths. They cannot be consumed, but are only "available" up to
313
313
// the end of their scope.
314
- if (value->getOwnershipKind () != OwnershipKind::None
315
- || ScopedAddressValue (value)) {
314
+ if (value->getOwnershipKind () != OwnershipKind::None ||
315
+ ScopedAddressValue (value)) {
316
316
for (auto *endBlock : boundary.endBlocks ) {
317
317
if (!consumingBlocks.contains (endBlock)) {
318
318
collect (endBlock);
@@ -338,8 +338,8 @@ void AvailabilityBoundaryVisitor::computeRegion(
338
338
->getModule ()
339
339
.getASTContext ()
340
340
.SILOpts .VerifySILOwnership ) {
341
- llvm::errs () << " Invalid SIL provided to OSSALifetimeCompletion ?! {{\n " ;
342
- llvm::errs () << " OSSALifetimeCompletion is visiting the availability "
341
+ llvm::errs () << " Invalid SIL provided to OSSACompleteLifetime ?! {{\n " ;
342
+ llvm::errs () << " OSSACompleteLifetime is visiting the availability "
343
343
" boundary of " ;
344
344
value->print (llvm::errs ());
345
345
llvm::errs ()
@@ -353,8 +353,8 @@ void AvailabilityBoundaryVisitor::computeRegion(
353
353
" value was leaked. The function with the leak is as follows:\n " ;
354
354
block->getFunction ()->print (llvm::errs ());
355
355
llvm::errs ()
356
- << " Invalid SIL provided to OSSALifetimeCompletion ?! }}\n "
357
- << " Something that ran before OSSALifetimeCompletion (the current "
356
+ << " Invalid SIL provided to OSSACompleteLifetime ?! }}\n "
357
+ << " Something that ran before OSSACompleteLifetime (the current "
358
358
" pass, an earlier pass, SILGen) has introduced a leak of this "
359
359
" value.\n "
360
360
<< " Please rerun the crashing swift-frontend command with the "
@@ -419,7 +419,7 @@ void AvailabilityBoundaryVisitor::propagateAvailablity(Result &result) {
419
419
void AvailabilityBoundaryVisitor::visitAvailabilityBoundary (
420
420
Result const &result,
421
421
llvm::function_ref<void (SILInstruction *,
422
- OSSALifetimeCompletion ::LifetimeEnd end)>
422
+ OSSACompleteLifetime ::LifetimeEnd end)>
423
423
visit) {
424
424
for (auto *block : region) {
425
425
auto available = result.getState (block) == State::Available;
@@ -441,13 +441,12 @@ void AvailabilityBoundaryVisitor::visitAvailabilityBoundary(
441
441
->getModule ()
442
442
.getASTContext ()
443
443
.SILOpts .VerifySILOwnership );
444
- visit (block->getTerminator (),
445
- OSSALifetimeCompletion::LifetimeEnd::Boundary);
444
+ visit (block->getTerminator (), OSSACompleteLifetime::LifetimeEnd::Boundary);
446
445
}
447
446
}
448
447
} // end anonymous namespace
449
448
450
- void OSSALifetimeCompletion ::visitAvailabilityBoundary (
449
+ void OSSACompleteLifetime ::visitAvailabilityBoundary (
451
450
SILValue value, const SSAPrunedLiveness &liveness,
452
451
llvm::function_ref<void (SILInstruction *, LifetimeEnd end)> visit) {
453
452
@@ -468,7 +467,7 @@ static bool endLifetimeAtAvailabilityBoundary(SILValue value,
468
467
const SSAPrunedLiveness &liveness,
469
468
DeadEndBlocks &deb) {
470
469
bool changed = false ;
471
- OSSALifetimeCompletion ::visitAvailabilityBoundary (
470
+ OSSACompleteLifetime ::visitAvailabilityBoundary (
472
471
value, liveness, [&](auto *unreachable, auto end) {
473
472
SILBuilderWithScope builder (unreachable);
474
473
endOSSALifetime (value, end, builder, deb);
@@ -479,33 +478,33 @@ static bool endLifetimeAtAvailabilityBoundary(SILValue value,
479
478
480
479
static bool endLifetimeAtBoundary (SILValue value,
481
480
SSAPrunedLiveness const &liveness,
482
- OSSALifetimeCompletion ::Boundary boundary,
481
+ OSSACompleteLifetime ::Boundary boundary,
483
482
DeadEndBlocks &deadEndBlocks) {
484
483
bool changed = false ;
485
484
switch (boundary) {
486
- case OSSALifetimeCompletion ::Boundary::Liveness:
485
+ case OSSACompleteLifetime ::Boundary::Liveness:
487
486
changed |= endLifetimeAtLivenessBoundary (value, liveness, deadEndBlocks);
488
487
break ;
489
- case OSSALifetimeCompletion ::Boundary::Availability:
488
+ case OSSACompleteLifetime ::Boundary::Availability:
490
489
changed |=
491
490
endLifetimeAtAvailabilityBoundary (value, liveness, deadEndBlocks);
492
491
break ;
493
492
}
494
493
return changed;
495
494
}
496
495
497
- bool OSSALifetimeCompletion ::analyzeAndUpdateLifetime (
496
+ bool OSSACompleteLifetime ::analyzeAndUpdateLifetime (
498
497
ScopedAddressValue scopedAddress, Boundary boundary) {
499
498
SmallVector<SILBasicBlock *, 8 > discoveredBlocks;
500
499
SSAPrunedLiveness liveness (scopedAddress->getFunction (), &discoveredBlocks);
501
500
liveness.initializeDef (scopedAddress.value );
502
501
503
502
struct Walker : TransitiveAddressWalker<Walker> {
504
- OSSALifetimeCompletion &completion;
503
+ OSSACompleteLifetime &completion;
505
504
ScopedAddressValue scopedAddress;
506
505
Boundary boundary;
507
506
SSAPrunedLiveness &liveness;
508
- Walker (OSSALifetimeCompletion &completion, ScopedAddressValue scopedAddress,
507
+ Walker (OSSACompleteLifetime &completion, ScopedAddressValue scopedAddress,
509
508
Boundary boundary, SSAPrunedLiveness &liveness)
510
509
: completion(completion), scopedAddress(scopedAddress),
511
510
boundary (boundary), liveness(liveness) {}
@@ -555,8 +554,8 @@ bool OSSALifetimeCompletion::analyzeAndUpdateLifetime(
555
554
// / End the lifetime of \p value at unreachable instructions.
556
555
// /
557
556
// / Returns true if any new instructions were created to complete the lifetime.
558
- bool OSSALifetimeCompletion ::analyzeAndUpdateLifetime (SILValue value,
559
- Boundary boundary) {
557
+ bool OSSACompleteLifetime ::analyzeAndUpdateLifetime (SILValue value,
558
+ Boundary boundary) {
560
559
if (auto scopedAddress = ScopedAddressValue (value)) {
561
560
return analyzeAndUpdateLifetime (scopedAddress, boundary);
562
561
}
@@ -577,8 +576,8 @@ bool OSSALifetimeCompletion::analyzeAndUpdateLifetime(SILValue value,
577
576
}
578
577
InteriorLiveness liveness (value);
579
578
liveness.compute (domInfo, handleInnerScope);
580
- if (VerifyLifetimeCompletion && boundary != Boundary::Availability
581
- && liveness.getAddressUseKind () != AddressUseKind::NonEscaping) {
579
+ if (VerifyLifetimeCompletion && boundary != Boundary::Availability &&
580
+ liveness.getAddressUseKind () != AddressUseKind::NonEscaping) {
582
581
llvm::errs () << " Incomplete liveness for: " << value;
583
582
if (auto *escapingUse = liveness.escapingUse ) {
584
583
llvm::errs () << " escapes at:\n " ;
@@ -596,20 +595,19 @@ namespace swift::test {
596
595
// - string: either "liveness" or "availability"
597
596
// Dumps:
598
597
// - function
599
- static FunctionTest OSSALifetimeCompletionTest (
600
- " ossa_lifetime_completion" ,
601
- [](auto &function, auto &arguments, auto &test) {
598
+ static FunctionTest OSSACompleteLifetimeTest (
599
+ " ossa_complete_lifetime" , [](auto &function, auto &arguments, auto &test) {
602
600
SILValue value = arguments.takeValue ();
603
- OSSALifetimeCompletion ::Boundary kind =
604
- llvm::StringSwitch<OSSALifetimeCompletion ::Boundary>(
601
+ OSSACompleteLifetime ::Boundary kind =
602
+ llvm::StringSwitch<OSSACompleteLifetime ::Boundary>(
605
603
arguments.takeString ())
606
- .Case (" liveness" , OSSALifetimeCompletion ::Boundary::Liveness)
604
+ .Case (" liveness" , OSSACompleteLifetime ::Boundary::Liveness)
607
605
.Case (" availability" ,
608
- OSSALifetimeCompletion ::Boundary::Availability);
606
+ OSSACompleteLifetime ::Boundary::Availability);
609
607
auto *deb = test.getDeadEndBlocks ();
610
608
llvm::outs () << " OSSA lifetime completion on " << kind
611
609
<< " boundary: " << value;
612
- OSSALifetimeCompletion completion (&function, /* domInfo*/ nullptr , *deb);
610
+ OSSACompleteLifetime completion (&function, /* domInfo*/ nullptr , *deb);
613
611
completion.completeOSSALifetime (value, kind);
614
612
function.print (llvm::outs ());
615
613
});
@@ -686,12 +684,12 @@ bool UnreachableLifetimeCompletion::completeLifetimes() {
686
684
}
687
685
}
688
686
689
- OSSALifetimeCompletion completion (function, domInfo, deadEndBlocks);
687
+ OSSACompleteLifetime completion (function, domInfo, deadEndBlocks);
690
688
691
689
bool changed = false ;
692
690
for (auto value : incompleteValues) {
693
691
if (completion.completeOSSALifetime (
694
- value, OSSALifetimeCompletion ::Boundary::Availability) ==
692
+ value, OSSACompleteLifetime ::Boundary::Availability) ==
695
693
LifetimeCompletion::WasCompleted) {
696
694
changed = true ;
697
695
}
0 commit comments