@@ -849,6 +849,21 @@ static bool analyzeBeginAccess(BeginAccessInst *BI,
849849 return true ;
850850}
851851
852+ static bool hasOwnershipOperandsOrResults (SILInstruction *inst) {
853+ if (!inst->getFunction ()->hasOwnership ())
854+ return false ;
855+
856+ for (SILValue result : inst->getResults ()) {
857+ if (result->getOwnershipKind () != OwnershipKind::None)
858+ return true ;
859+ }
860+ for (Operand &op : inst->getAllOperands ()) {
861+ if (op.get ()->getOwnershipKind () != OwnershipKind::None)
862+ return true ;
863+ }
864+ return false ;
865+ }
866+
852867// Analyzes current loop for hosting/sinking potential:
853868// Computes set of instructions we may be able to move out of the loop
854869// Important Note:
@@ -887,6 +902,10 @@ void LoopTreeOptimization::analyzeCurrentLoop(
887902 for (auto *BB : Loop->getBlocks ()) {
888903 SmallVector<SILInstruction *, 8 > sideEffectsInBlock;
889904 for (auto &Inst : *BB) {
905+ if (hasOwnershipOperandsOrResults (&Inst)) {
906+ checkSideEffects (Inst, sideEffects, sideEffectsInBlock);
907+ continue ;
908+ }
890909 switch (Inst.getKind ()) {
891910 case SILInstructionKind::FixLifetimeInst: {
892911 auto *FL = cast<FixLifetimeInst>(&Inst);
@@ -1084,11 +1103,14 @@ SingleValueInstruction *LoopTreeOptimization::splitLoad(
10841103 SILValue splitAddress, ArrayRef<AccessPath::Index> remainingPath,
10851104 SILBuilder &builder, SmallVectorImpl<LoadInst *> &Loads, unsigned ldstIdx) {
10861105 auto loc = LoadsAndStores[ldstIdx]->getLoc ();
1106+ LoadOwnershipQualifier ownership = builder.getFunction ().hasOwnership () ?
1107+ LoadOwnershipQualifier::Trivial :
1108+ LoadOwnershipQualifier::Unqualified;
1109+
10871110 // Recurse until we have a load that matches accessPath.
10881111 if (remainingPath.empty ()) {
10891112 // Create a load that matches the stored access path.
1090- LoadInst *load = builder.createLoad (loc, splitAddress,
1091- LoadOwnershipQualifier::Unqualified);
1113+ LoadInst *load = builder.createLoad (loc, splitAddress, ownership);
10921114 Loads.push_back (load);
10931115 // Replace the outer load in the list of loads and stores to hoist and
10941116 // sink. LoadsAndStores must remain in instruction order.
@@ -1112,8 +1134,7 @@ SingleValueInstruction *LoopTreeOptimization::splitLoad(
11121134 elementVal = splitLoad (projection, remainingPath.drop_back (), builder,
11131135 Loads, ldstIdx);
11141136 } else {
1115- elementVal = builder.createLoad (loc, projection,
1116- LoadOwnershipQualifier::Unqualified);
1137+ elementVal = builder.createLoad (loc, projection, ownership);
11171138 recordDisjointLoad (cast<LoadInst>(elementVal));
11181139 }
11191140 elements.push_back (elementVal);
@@ -1136,8 +1157,7 @@ SingleValueInstruction *LoopTreeOptimization::splitLoad(
11361157 fieldVal = splitLoad (projection, remainingPath.drop_back (), builder,
11371158 Loads, ldstIdx);
11381159 else {
1139- fieldVal = builder.createLoad (loc, projection,
1140- LoadOwnershipQualifier::Unqualified);
1160+ fieldVal = builder.createLoad (loc, projection, ownership);
11411161 recordDisjointLoad (cast<LoadInst>(fieldVal));
11421162 }
11431163 elements.push_back (fieldVal);
@@ -1431,9 +1451,13 @@ hoistLoadsAndStores(AccessPath accessPath, SILLoop *loop) {
14311451 if (!initialAddr)
14321452 return ;
14331453
1454+ LoadOwnershipQualifier ownership = B.getFunction ().hasOwnership () ?
1455+ LoadOwnershipQualifier::Trivial :
1456+ LoadOwnershipQualifier::Unqualified;
1457+
14341458 LoadInst *initialLoad =
14351459 B.createLoad (RegularLocation::getAutoGeneratedLocation (), initialAddr,
1436- LoadOwnershipQualifier::Unqualified );
1460+ ownership );
14371461 LLVM_DEBUG (llvm::dbgs () << " Creating preload " << *initialLoad);
14381462 ssaUpdater.addAvailableValue (preheader, initialLoad);
14391463
@@ -1480,9 +1504,12 @@ hoistLoadsAndStores(AccessPath accessPath, SILLoop *loop) {
14801504 assert (succ->getSinglePredecessorBlock ()
14811505 && " should have split critical edges" );
14821506 SILBuilder B (succ->begin ());
1507+ StoreOwnershipQualifier ownership = B.getFunction ().hasOwnership () ?
1508+ StoreOwnershipQualifier::Trivial :
1509+ StoreOwnershipQualifier::Unqualified;
14831510 auto *SI = B.createStore (
14841511 loc.value (), ssaUpdater.getValueInMiddleOfBlock (succ), initialAddr,
1485- StoreOwnershipQualifier::Unqualified );
1512+ ownership );
14861513 (void )SI;
14871514 LLVM_DEBUG (llvm::dbgs () << " Creating loop-exit store " << *SI);
14881515 }
@@ -1529,10 +1556,6 @@ class LICM : public SILFunctionTransform {
15291556 void run () override {
15301557 SILFunction *F = getFunction ();
15311558
1532- // If our function has ownership, skip it.
1533- if (F->hasOwnership ())
1534- return ;
1535-
15361559 SILLoopAnalysis *LA = PM->getAnalysis <SILLoopAnalysis>();
15371560 SILLoopInfo *LoopInfo = LA->get (F);
15381561
0 commit comments