@@ -78,7 +78,7 @@ static SILValue getArrayStructPointer(ArrayCallKind K, SILValue Array) {
78
78
assert (K != ArrayCallKind::kNone );
79
79
80
80
if (K < ArrayCallKind::kMakeMutable ) {
81
- auto LI = dyn_cast<LoadInst>(Array);
81
+ auto LI = dyn_cast<LoadInst>(lookThroughCopyValueInsts ( Array) );
82
82
if (!LI) {
83
83
return Array;
84
84
}
@@ -107,20 +107,15 @@ mayChangeArraySize(SILInstruction *I, ArrayCallKind &Kind, SILValue &Array,
107
107
108
108
// TODO: What else.
109
109
if (isa<StrongRetainInst>(I) || isa<RetainValueInst>(I) ||
110
- isa<CondFailInst >(I) || isa<DeallocStackInst >(I) ||
111
- isa<AllocationInst>(I))
110
+ isa<CopyValueInst >(I) || isa<CondFailInst >(I) ||
111
+ isa<DeallocStackInst>(I) || isa< AllocationInst>(I))
112
112
return ArrayBoundsEffect::kNone ;
113
113
114
- // A retain on an arbitrary class can have sideeffects because of the deinit
114
+ // A release on an arbitrary class can have sideeffects because of the deinit
115
115
// function.
116
- if (auto SR = dyn_cast<StrongReleaseInst>(I))
117
- return isReleaseSafeArrayReference (SR->getOperand (),
118
- ReleaseSafeArrayReferences, RCIA)
119
- ? ArrayBoundsEffect::kNone
120
- : ArrayBoundsEffect::kMayChangeAny ;
121
-
122
- if (auto RV = dyn_cast<ReleaseValueInst>(I))
123
- return isReleaseSafeArrayReference (RV->getOperand (),
116
+ if (isa<StrongReleaseInst>(I) || isa<ReleaseValueInst>(I) ||
117
+ isa<DestroyValueInst>(I))
118
+ return isReleaseSafeArrayReference (I->getOperand (0 ),
124
119
ReleaseSafeArrayReferences, RCIA)
125
120
? ArrayBoundsEffect::kNone
126
121
: ArrayBoundsEffect::kMayChangeAny ;
@@ -148,12 +143,22 @@ mayChangeArraySize(SILInstruction *I, ArrayCallKind &Kind, SILValue &Array,
148
143
// A store to an alloc_stack can't possibly store to the array size which is
149
144
// stored in a runtime allocated object sub field of an alloca.
150
145
if (auto *SI = dyn_cast<StoreInst>(I)) {
146
+ if (SI->getOwnershipQualifier () == StoreOwnershipQualifier::Assign) {
147
+ // store [assign] can call a destructor with unintended effects
148
+ return ArrayBoundsEffect::kMayChangeAny ;
149
+ }
151
150
auto Ptr = SI->getDest ();
152
151
return isa<AllocStackInst>(Ptr) || isAddressOfArrayElement (SI->getDest ())
153
152
? ArrayBoundsEffect::kNone
154
153
: ArrayBoundsEffect::kMayChangeAny ;
155
154
}
156
155
156
+ if (isa<LoadInst>(I))
157
+ return ArrayBoundsEffect::kNone ;
158
+
159
+ if (isa<BeginBorrowInst>(I) || isa<EndBorrowInst>(I))
160
+ return ArrayBoundsEffect::kNone ;
161
+
157
162
return ArrayBoundsEffect::kMayChangeAny ;
158
163
}
159
164
@@ -260,7 +265,7 @@ class ABCAnalysis {
260
265
mayChangeArraySize (Inst, K, Array, ReleaseSafeArrayReferences, RCIA);
261
266
262
267
if (BoundsEffect == ArrayBoundsEffect::kMayChangeAny ) {
263
- LLVM_DEBUG (llvm::dbgs () << " no safe because kMayChangeAny " << *Inst);
268
+ LLVM_DEBUG (llvm::dbgs () << " not safe because kMayChangeAny " << *Inst);
264
269
allArraysInMemoryAreUnsafe = true ;
265
270
// No need to store specific arrays in this case.
266
271
UnsafeArrays.clear ();
@@ -420,7 +425,7 @@ static BuiltinValueKind invertCmpID(BuiltinValueKind ID) {
420
425
}
421
426
422
427
// / Checks if Start to End is the range of 0 to the count of an array.
423
- // / Returns the array is this is the case.
428
+ // / Returns the array if this is the case.
424
429
static SILValue getZeroToCountArray (SILValue Start, SILValue End) {
425
430
auto *IL = dyn_cast<IntegerLiteralInst>(Start);
426
431
if (!IL || IL->getValue () != 0 )
@@ -433,7 +438,6 @@ static SILValue getZeroToCountArray(SILValue Start, SILValue End) {
433
438
ArraySemanticsCall SemCall (SEI->getOperand ());
434
439
if (SemCall.getKind () != ArrayCallKind::kGetCount )
435
440
return SILValue ();
436
-
437
441
return SemCall.getSelf ();
438
442
}
439
443
@@ -740,9 +744,9 @@ class AccessFunction {
740
744
return nullptr ;
741
745
}
742
746
743
- // / Returns true if the loop iterates from 0 until count of \p Array .
744
- bool isZeroToCount (SILValue Array ) {
745
- return getZeroToCountArray (Ind->Start , Ind->End ) == Array ;
747
+ // / Returns true if the loop iterates from 0 until count of \p ArrayVal .
748
+ bool isZeroToCount (SILValue ArrayVal ) {
749
+ return getZeroToCountArray (Ind->Start , Ind->End ) == ArrayVal ;
746
750
}
747
751
748
752
// / Hoists the necessary check for beginning and end of the induction
@@ -901,11 +905,6 @@ class ABCOpt : public SILFunctionTransform {
901
905
return ;
902
906
903
907
SILFunction *F = getFunction ();
904
-
905
- // FIXME: Update for ownership.
906
- if (F->hasOwnership ())
907
- return ;
908
-
909
908
LI = PM->getAnalysis <SILLoopAnalysis>()->get (F);
910
909
DT = PM->getAnalysis <DominanceAnalysis>()->get (F);
911
910
IVs = PM->getAnalysis <IVAnalysis>()->get (F);
@@ -917,6 +916,8 @@ class ABCOpt : public SILFunctionTransform {
917
916
reportBoundsChecks (F);
918
917
}
919
918
#endif
919
+ LLVM_DEBUG (llvm::dbgs ()
920
+ << " ArrayBoundsCheckOpts on function: " << F->getName () << " \n " );
920
921
// Collect all arrays in this function. A release is only 'safe' if we know
921
922
// its deinitializer does not have sideeffects that could cause memory
922
923
// safety issues. A deinit could deallocate array or put a different array
@@ -931,6 +932,7 @@ class ABCOpt : public SILFunctionTransform {
931
932
// that is not calling a deinit function.
932
933
if (DestAnalysis->mayStoreToMemoryOnDestruction (rcRoot->getType ()))
933
934
continue ;
935
+ LLVM_DEBUG (llvm::dbgs () << " ReleaseSafeArray: " << rcRoot << " \n " );
934
936
ReleaseSafeArrays.insert (rcRoot);
935
937
ReleaseSafeArrays.insert (
936
938
getArrayStructPointer (ArrayCallKind::kCheckIndex , rcRoot));
0 commit comments