@@ -849,6 +849,21 @@ static bool analyzeBeginAccess(BeginAccessInst *BI,
849
849
return true ;
850
850
}
851
851
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
+
852
867
// Analyzes current loop for hosting/sinking potential:
853
868
// Computes set of instructions we may be able to move out of the loop
854
869
// Important Note:
@@ -887,6 +902,10 @@ void LoopTreeOptimization::analyzeCurrentLoop(
887
902
for (auto *BB : Loop->getBlocks ()) {
888
903
SmallVector<SILInstruction *, 8 > sideEffectsInBlock;
889
904
for (auto &Inst : *BB) {
905
+ if (hasOwnershipOperandsOrResults (&Inst)) {
906
+ checkSideEffects (Inst, sideEffects, sideEffectsInBlock);
907
+ continue ;
908
+ }
890
909
switch (Inst.getKind ()) {
891
910
case SILInstructionKind::FixLifetimeInst: {
892
911
auto *FL = cast<FixLifetimeInst>(&Inst);
@@ -1084,11 +1103,14 @@ SingleValueInstruction *LoopTreeOptimization::splitLoad(
1084
1103
SILValue splitAddress, ArrayRef<AccessPath::Index> remainingPath,
1085
1104
SILBuilder &builder, SmallVectorImpl<LoadInst *> &Loads, unsigned ldstIdx) {
1086
1105
auto loc = LoadsAndStores[ldstIdx]->getLoc ();
1106
+ LoadOwnershipQualifier ownership = builder.getFunction ().hasOwnership () ?
1107
+ LoadOwnershipQualifier::Trivial :
1108
+ LoadOwnershipQualifier::Unqualified;
1109
+
1087
1110
// Recurse until we have a load that matches accessPath.
1088
1111
if (remainingPath.empty ()) {
1089
1112
// 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);
1092
1114
Loads.push_back (load);
1093
1115
// Replace the outer load in the list of loads and stores to hoist and
1094
1116
// sink. LoadsAndStores must remain in instruction order.
@@ -1112,8 +1134,7 @@ SingleValueInstruction *LoopTreeOptimization::splitLoad(
1112
1134
elementVal = splitLoad (projection, remainingPath.drop_back (), builder,
1113
1135
Loads, ldstIdx);
1114
1136
} else {
1115
- elementVal = builder.createLoad (loc, projection,
1116
- LoadOwnershipQualifier::Unqualified);
1137
+ elementVal = builder.createLoad (loc, projection, ownership);
1117
1138
recordDisjointLoad (cast<LoadInst>(elementVal));
1118
1139
}
1119
1140
elements.push_back (elementVal);
@@ -1136,8 +1157,7 @@ SingleValueInstruction *LoopTreeOptimization::splitLoad(
1136
1157
fieldVal = splitLoad (projection, remainingPath.drop_back (), builder,
1137
1158
Loads, ldstIdx);
1138
1159
else {
1139
- fieldVal = builder.createLoad (loc, projection,
1140
- LoadOwnershipQualifier::Unqualified);
1160
+ fieldVal = builder.createLoad (loc, projection, ownership);
1141
1161
recordDisjointLoad (cast<LoadInst>(fieldVal));
1142
1162
}
1143
1163
elements.push_back (fieldVal);
@@ -1431,9 +1451,13 @@ hoistLoadsAndStores(AccessPath accessPath, SILLoop *loop) {
1431
1451
if (!initialAddr)
1432
1452
return ;
1433
1453
1454
+ LoadOwnershipQualifier ownership = B.getFunction ().hasOwnership () ?
1455
+ LoadOwnershipQualifier::Trivial :
1456
+ LoadOwnershipQualifier::Unqualified;
1457
+
1434
1458
LoadInst *initialLoad =
1435
1459
B.createLoad (RegularLocation::getAutoGeneratedLocation (), initialAddr,
1436
- LoadOwnershipQualifier::Unqualified );
1460
+ ownership );
1437
1461
LLVM_DEBUG (llvm::dbgs () << " Creating preload " << *initialLoad);
1438
1462
ssaUpdater.addAvailableValue (preheader, initialLoad);
1439
1463
@@ -1480,9 +1504,12 @@ hoistLoadsAndStores(AccessPath accessPath, SILLoop *loop) {
1480
1504
assert (succ->getSinglePredecessorBlock ()
1481
1505
&& " should have split critical edges" );
1482
1506
SILBuilder B (succ->begin ());
1507
+ StoreOwnershipQualifier ownership = B.getFunction ().hasOwnership () ?
1508
+ StoreOwnershipQualifier::Trivial :
1509
+ StoreOwnershipQualifier::Unqualified;
1483
1510
auto *SI = B.createStore (
1484
1511
loc.value (), ssaUpdater.getValueInMiddleOfBlock (succ), initialAddr,
1485
- StoreOwnershipQualifier::Unqualified );
1512
+ ownership );
1486
1513
(void )SI;
1487
1514
LLVM_DEBUG (llvm::dbgs () << " Creating loop-exit store " << *SI);
1488
1515
}
@@ -1529,10 +1556,6 @@ class LICM : public SILFunctionTransform {
1529
1556
void run () override {
1530
1557
SILFunction *F = getFunction ();
1531
1558
1532
- // If our function has ownership, skip it.
1533
- if (F->hasOwnership ())
1534
- return ;
1535
-
1536
1559
SILLoopAnalysis *LA = PM->getAnalysis <SILLoopAnalysis>();
1537
1560
SILLoopInfo *LoopInfo = LA->get (F);
1538
1561
0 commit comments