Skip to content

Commit 8b563d2

Browse files
authored
Merge pull request #35790 from gottesmm/pr-1fe4c56db40fbe22618e6ca72f441f2e2059152d
[capture-promotion] Eliminate non-OSSA support/tests.
2 parents 12164c9 + e33ce42 commit 8b563d2

File tree

5 files changed

+253
-794
lines changed

5 files changed

+253
-794
lines changed

lib/SILOptimizer/Mandatory/CapturePromotion.cpp

Lines changed: 43 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#include "swift/AST/DiagnosticsSIL.h"
4848
#include "swift/AST/GenericEnvironment.h"
4949
#include "swift/Basic/FrozenMultiMap.h"
50+
#include "swift/SIL/OwnershipUtils.h"
5051
#include "swift/SIL/SILCloner.h"
5152
#include "swift/SIL/SILInstruction.h"
5253
#include "swift/SIL/TypeSubstCloner.h"
@@ -313,11 +314,11 @@ class ClosureCloner : public SILClonerWithScopes<ClosureCloner> {
313314
SILValue getProjectBoxMappedVal(SILValue operandValue);
314315

315316
void visitDebugValueAddrInst(DebugValueAddrInst *inst);
316-
void visitStrongReleaseInst(StrongReleaseInst *inst);
317317
void visitDestroyValueInst(DestroyValueInst *inst);
318318
void visitStructElementAddrInst(StructElementAddrInst *inst);
319319
void visitLoadInst(LoadInst *inst);
320320
void visitLoadBorrowInst(LoadBorrowInst *inst);
321+
void visitEndBorrowInst(EndBorrowInst *inst);
321322
void visitProjectBoxInst(ProjectBoxInst *inst);
322323
void visitBeginAccessInst(BeginAccessInst *inst);
323324
void visitEndAccessInst(EndAccessInst *inst);
@@ -467,9 +468,6 @@ ClosureCloner::initCloned(SILOptFunctionBuilder &functionBuilder,
467468
orig->getEffectsKind(), orig, orig->getDebugScope());
468469
for (auto &attr : orig->getSemanticsAttrs())
469470
fn->addSemanticsAttr(attr);
470-
if (!orig->hasOwnership()) {
471-
fn->setOwnershipEliminated();
472-
}
473471
return fn;
474472
}
475473

@@ -510,8 +508,7 @@ void ClosureCloner::populateCloned() {
510508
// If SIL ownership is enabled, we need to perform a borrow here if we have
511509
// a non-trivial value. We know that our value is not written to and it does
512510
// not escape. The use of a borrow enforces this.
513-
if (cloned->hasOwnership() &&
514-
mappedValue.getOwnershipKind() != OwnershipKind::None) {
511+
if (mappedValue.getOwnershipKind() != OwnershipKind::None) {
515512
SILLocation loc(const_cast<ValueDecl *>((*ai)->getDecl()));
516513
mappedValue = getBuilder().emitBeginBorrowOperation(loc, mappedValue);
517514
}
@@ -565,7 +562,6 @@ SILFunction *ClosureCloner::constructClonedFunction(
565562
SILValue ClosureCloner::getProjectBoxMappedVal(SILValue operandValue) {
566563
if (auto *bai = dyn_cast<BeginAccessInst>(operandValue))
567564
operandValue = bai->getSource();
568-
569565
if (auto *pbi = dyn_cast<ProjectBoxInst>(operandValue)) {
570566
auto iter = projectBoxArgumentMap.find(pbi);
571567
if (iter != projectBoxArgumentMap.end())
@@ -586,50 +582,25 @@ void ClosureCloner::visitDebugValueAddrInst(DebugValueAddrInst *inst) {
586582
SILCloner<ClosureCloner>::visitDebugValueAddrInst(inst);
587583
}
588584

589-
/// Handle a strong_release instruction during cloning of a closure; if
590-
/// it is a strong release of a promoted box argument, then it is replaced with
591-
/// a ReleaseValue of the new object type argument, otherwise it is handled
592-
/// normally.
593-
void ClosureCloner::visitStrongReleaseInst(StrongReleaseInst *inst) {
594-
assert(
595-
!inst->getFunction()->hasOwnership() &&
596-
"Should not see strong release in a function with qualified ownership");
597-
SILValue operandValue = inst->getOperand();
598-
if (auto *arg = dyn_cast<SILArgument>(operandValue)) {
599-
auto iter = boxArgumentMap.find(arg);
600-
if (iter != boxArgumentMap.end()) {
601-
// Releases of the box arguments get replaced with ReleaseValue of the new
602-
// object type argument.
603-
auto &typeLowering =
604-
getBuilder().getTypeLowering(iter->second->getType());
605-
SILBuilderWithPostProcess<ClosureCloner, 1> b(this, inst);
606-
typeLowering.emitDestroyValue(b, inst->getLoc(), iter->second);
607-
return;
608-
}
609-
}
610-
611-
SILCloner<ClosureCloner>::visitStrongReleaseInst(inst);
612-
}
613-
614-
/// Handle a destroy_value instruction during cloning of a closure; if
615-
/// it is a strong release of a promoted box argument, then it is replaced with
616-
/// a destroy_value of the new object type argument, otherwise it is handled
585+
/// Handle a destroy_value instruction during cloning of a closure; if it is a
586+
/// destroy_value of a promoted box argument, then it is replaced with a
587+
/// destroy_value of the new object type argument, otherwise it is handled
617588
/// normally.
618589
void ClosureCloner::visitDestroyValueInst(DestroyValueInst *inst) {
619590
SILValue operand = inst->getOperand();
620591
if (auto *arg = dyn_cast<SILArgument>(operand)) {
621592
auto iter = boxArgumentMap.find(arg);
622593
if (iter != boxArgumentMap.end()) {
623-
// Releases of the box arguments get replaced with an end_borrow,
594+
// destroy_value of the box arguments get replaced with an end_borrow,
624595
// destroy_value of the new object type argument.
625596
SILFunction &f = getBuilder().getFunction();
626597
auto &typeLowering = f.getTypeLowering(iter->second->getType());
627598
SILBuilderWithPostProcess<ClosureCloner, 1> b(this, inst);
628599
SILValue value = iter->second;
629600

630-
// If ownership is enabled, then we must emit a begin_borrow for any
631-
// non-trivial value.
632-
if (f.hasOwnership() && value.getOwnershipKind() != OwnershipKind::None) {
601+
// We must have emitted a begin_borrow for any non-trivial value. Insert
602+
// an end_borrow if so.
603+
if (value.getOwnershipKind() != OwnershipKind::None) {
633604
auto *bbi = cast<BeginBorrowInst>(value);
634605
value = bbi->getOperand();
635606
b.emitEndBorrowOperation(inst->getLoc(), bbi);
@@ -643,6 +614,29 @@ void ClosureCloner::visitDestroyValueInst(DestroyValueInst *inst) {
643614
SILCloner<ClosureCloner>::visitDestroyValueInst(inst);
644615
}
645616

617+
/// Handle an end_borrow instruction during cloning of a closure; if it is a
618+
/// end_borrow from a load_borrow of a promoted box argument, then it is
619+
/// deleted, otherwise it is handled normally.
620+
void ClosureCloner::visitEndBorrowInst(EndBorrowInst *inst) {
621+
SILValue operand = inst->getOperand();
622+
623+
if (auto *lbi = dyn_cast<LoadBorrowInst>(operand)) {
624+
SILValue op = lbi->getOperand();
625+
// When we check if we can do this, we only need to look through a single
626+
// struct_element_addr since when checking if this is safe, we only look
627+
// through a single struct_element_addr.
628+
if (auto *sea = dyn_cast<StructElementAddrInst>(op))
629+
op = sea->getOperand();
630+
631+
// If after optionally looking through a gep, we have our project_box, just
632+
// eliminate the end_borrow.
633+
if (getProjectBoxMappedVal(op))
634+
return;
635+
}
636+
637+
SILCloner<ClosureCloner>::visitEndBorrowInst(inst);
638+
}
639+
646640
/// Handle a struct_element_addr instruction during cloning of a closure.
647641
///
648642
/// If its operand is the promoted address argument then ignore it, otherwise it
@@ -798,6 +792,8 @@ static SILArgument *getBoxFromIndex(SILFunction *f, unsigned index) {
798792
}
799793

800794
static bool isNonMutatingLoad(SILInstruction *inst) {
795+
if (isa<LoadBorrowInst>(inst))
796+
return true;
801797
auto *li = dyn_cast<LoadInst>(inst);
802798
if (!li)
803799
return false;
@@ -1573,14 +1569,17 @@ class CapturePromotionPass : public SILModuleTransform {
15731569
void run() override {
15741570
SmallVector<SILFunction *, 128> worklist;
15751571
for (auto &f : *getModule()) {
1576-
if (f.wasDeserializedCanonical())
1572+
if (f.wasDeserializedCanonical() || !f.hasOwnership())
15771573
continue;
15781574

15791575
processFunction(&f, worklist);
15801576
}
15811577

15821578
while (!worklist.empty()) {
1583-
processFunction(worklist.pop_back_val(), worklist);
1579+
auto *f = worklist.pop_back_val();
1580+
if (!f->hasOwnership())
1581+
continue;
1582+
processFunction(f, worklist);
15841583
}
15851584
}
15861585

@@ -1592,6 +1591,9 @@ class CapturePromotionPass : public SILModuleTransform {
15921591

15931592
void CapturePromotionPass::processFunction(
15941593
SILFunction *func, SmallVectorImpl<SILFunction *> &worklist) {
1594+
assert(func->hasOwnership() &&
1595+
"Only can perform capture promotion on functions with ownership. All "
1596+
"functions in raw SIL should have OSSA now out of SILGen");
15951597
LLVM_DEBUG(llvm::dbgs() << "******** Performing Capture Promotion on: "
15961598
<< func->getName() << "********\n");
15971599
// This is a map from each partial apply to a set of indices of promotable

0 commit comments

Comments
 (0)