@@ -156,13 +156,21 @@ void ARCRegionState::mergePredTopDown(ARCRegionState &PredRegionState) {
156
156
// Bottom Up Dataflow
157
157
//
158
158
159
- static bool processBlockBottomUpInsts (
160
- ARCRegionState &State, SILBasicBlock &BB,
161
- BottomUpDataflowRCStateVisitor<ARCRegionState> &DataflowVisitor,
162
- AliasAnalysis *AA, ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
159
+ bool ARCRegionState::processBlockBottomUp (
160
+ const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
161
+ EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
162
+ bool FreezeOwnedArgEpilogueReleases,
163
+ BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
164
+ ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
165
+ LLVM_DEBUG (llvm::dbgs () << " >>>> Bottom Up!\n " );
163
166
164
- auto II = State.summarizedinterestinginsts_rbegin ();
165
- auto IE = State.summarizedinterestinginsts_rend ();
167
+ SILBasicBlock &BB = *R->getBlock ();
168
+ BottomUpDataflowRCStateVisitor<ARCRegionState> DataflowVisitor (
169
+ RCIA, EAFI, *this , FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
170
+ SetFactory);
171
+
172
+ auto II = summarizedinterestinginsts_rbegin ();
173
+ auto IE = summarizedinterestinginsts_rend ();
166
174
167
175
// If we do not have any interesting instructions, bail and return false since
168
176
// we can not have any nested instructions.
@@ -196,9 +204,15 @@ static bool processBlockBottomUpInsts(
196
204
// that the instruction "visits".
197
205
SILValue Op = Result.RCIdentity ;
198
206
207
+ std::function<bool (SILInstruction *)> checkIfRefCountInstIsMatched =
208
+ [&IncToDecStateMap](SILInstruction *Inst) {
209
+ assert (isa<StrongRetainInst>(Inst) || isa<RetainValueInst>(Inst));
210
+ return IncToDecStateMap.find (Inst) != IncToDecStateMap.end ();
211
+ };
212
+
199
213
// For all other (reference counted value, ref count state) we are
200
214
// tracking...
201
- for (auto &OtherState : State. getBottomupStates ()) {
215
+ for (auto &OtherState : getBottomupStates ()) {
202
216
// If the other state's value is blotted, skip it.
203
217
if (!OtherState.hasValue ())
204
218
continue ;
@@ -208,33 +222,15 @@ static bool processBlockBottomUpInsts(
208
222
if (Op && OtherState->first == Op)
209
223
continue ;
210
224
211
- OtherState->second .updateForSameLoopInst (I, SetFactory, AA);
225
+ OtherState->second .updateForSameLoopInst (I, AA);
226
+ OtherState->second .checkAndResetKnownSafety (
227
+ I, OtherState->first , checkIfRefCountInstIsMatched, RCIA, AA);
212
228
}
213
229
}
214
230
215
231
return NestingDetected;
216
232
}
217
233
218
- bool ARCRegionState::processBlockBottomUp (
219
- const LoopRegion *R, AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
220
- EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
221
- bool FreezeOwnedArgEpilogueReleases,
222
- BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
223
- ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
224
- LLVM_DEBUG (llvm::dbgs () << " >>>> Bottom Up!\n " );
225
-
226
- SILBasicBlock &BB = *R->getBlock ();
227
- BottomUpDataflowRCStateVisitor<ARCRegionState> DataflowVisitor (
228
- RCIA, EAFI, *this , FreezeOwnedArgEpilogueReleases, IncToDecStateMap,
229
- SetFactory);
230
-
231
- // Visit each arc relevant instruction I in BB visited in reverse...
232
- bool NestingDetected =
233
- processBlockBottomUpInsts (*this , BB, DataflowVisitor, AA, SetFactory);
234
-
235
- return NestingDetected;
236
- }
237
-
238
234
// Returns true if any of the non-local successors of the region are leaking
239
235
// blocks. We currently do not handle early exits, but do handle trapping
240
236
// blocks. Returns false if otherwise
@@ -257,8 +253,9 @@ static bool hasEarlyExits(
257
253
258
254
bool ARCRegionState::processLoopBottomUp (
259
255
const LoopRegion *R, AliasAnalysis *AA, LoopRegionFunctionInfo *LRFI,
256
+ RCIdentityFunctionInfo *RCIA,
260
257
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
261
- ImmutablePointerSetFactory <SILInstruction> &SetFactory ) {
258
+ llvm::DenseSet <SILInstruction * > &UnmatchedRefCountInsts ) {
262
259
ARCRegionState *State = RegionStateInfo[R];
263
260
264
261
// If we find that we have non-leaking early exits, clear state
@@ -268,14 +265,23 @@ bool ARCRegionState::processLoopBottomUp(
268
265
return false ;
269
266
}
270
267
268
+ std::function<bool (SILInstruction *)> checkIfRefCountInstIsMatched =
269
+ [&UnmatchedRefCountInsts](SILInstruction *Inst) {
270
+ assert (isa<StrongRetainInst>(Inst) || isa<RetainValueInst>(Inst));
271
+ return UnmatchedRefCountInsts.find (Inst) == UnmatchedRefCountInsts.end ();
272
+ };
273
+
271
274
// For each state that we are currently tracking, apply our summarized
272
275
// instructions to it.
273
276
for (auto &OtherState : getBottomupStates ()) {
274
277
if (!OtherState.hasValue ())
275
278
continue ;
276
279
277
- for (auto *I : State->getSummarizedInterestingInsts ())
278
- OtherState->second .updateForDifferentLoopInst (I, SetFactory, AA);
280
+ for (auto *I : State->getSummarizedInterestingInsts ()) {
281
+ OtherState->second .updateForDifferentLoopInst (I, AA);
282
+ OtherState->second .checkAndResetKnownSafety (
283
+ I, OtherState->first , checkIfRefCountInstIsMatched, RCIA, AA);
284
+ }
279
285
}
280
286
281
287
return false ;
@@ -285,6 +291,7 @@ bool ARCRegionState::processBottomUp(
285
291
AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
286
292
EpilogueARCFunctionInfo *EAFI, LoopRegionFunctionInfo *LRFI,
287
293
bool FreezeOwnedArgEpilogueReleases,
294
+ llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
288
295
BlotMapVector<SILInstruction *, BottomUpRefCountState> &IncToDecStateMap,
289
296
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
290
297
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
@@ -293,7 +300,8 @@ bool ARCRegionState::processBottomUp(
293
300
// We only process basic blocks for now. This ensures that we always propagate
294
301
// the empty set from loops.
295
302
if (!R->isBlock ())
296
- return processLoopBottomUp (R, AA, LRFI, RegionStateInfo, SetFactory);
303
+ return processLoopBottomUp (R, AA, LRFI, RCIA, RegionStateInfo,
304
+ UnmatchedRefCountInsts);
297
305
298
306
return processBlockBottomUp (R, AA, RCIA, EAFI, LRFI, FreezeOwnedArgEpilogueReleases,
299
307
IncToDecStateMap, SetFactory);
@@ -349,6 +357,12 @@ bool ARCRegionState::processBlockTopDown(
349
357
// that the instruction "visits".
350
358
SILValue Op = Result.RCIdentity ;
351
359
360
+ std::function<bool (SILInstruction *)> checkIfRefCountInstIsMatched =
361
+ [&DecToIncStateMap](SILInstruction *Inst) {
362
+ assert (isa<StrongReleaseInst>(Inst) || isa<ReleaseValueInst>(Inst));
363
+ return DecToIncStateMap.find (Inst) != DecToIncStateMap.end ();
364
+ };
365
+
352
366
// For all other [(SILValue, TopDownState)] we are tracking...
353
367
for (auto &OtherState : getTopDownStates ()) {
354
368
// If the other state's value is blotted, skip it.
@@ -361,7 +375,9 @@ bool ARCRegionState::processBlockTopDown(
361
375
if (Op && OtherState->first == Op)
362
376
continue ;
363
377
364
- OtherState->second .updateForSameLoopInst (I, SetFactory, AA);
378
+ OtherState->second .updateForSameLoopInst (I, AA);
379
+ OtherState->second .checkAndResetKnownSafety (
380
+ I, OtherState->first , checkIfRefCountInstIsMatched, RCIA, AA);
365
381
}
366
382
}
367
383
@@ -370,8 +386,8 @@ bool ARCRegionState::processBlockTopDown(
370
386
371
387
bool ARCRegionState::processLoopTopDown (
372
388
const LoopRegion *R, ARCRegionState *State, AliasAnalysis *AA,
373
- LoopRegionFunctionInfo *LRFI,
374
- ImmutablePointerSetFactory <SILInstruction> &SetFactory ) {
389
+ LoopRegionFunctionInfo *LRFI, RCIdentityFunctionInfo *RCIA,
390
+ llvm::DenseSet <SILInstruction * > &UnmatchedRefCountInsts ) {
375
391
376
392
assert (R->isLoop () && " We assume we are processing a loop" );
377
393
@@ -387,14 +403,23 @@ bool ARCRegionState::processLoopTopDown(
387
403
assert (PredRegion->isBlock () && " Expected the predecessor region to be a "
388
404
" block" );
389
405
406
+ std::function<bool (SILInstruction *)> checkIfRefCountInstIsMatched =
407
+ [&UnmatchedRefCountInsts](SILInstruction *Inst) {
408
+ assert (isa<StrongReleaseInst>(Inst) || isa<ReleaseValueInst>(Inst));
409
+ return UnmatchedRefCountInsts.find (Inst) == UnmatchedRefCountInsts.end ();
410
+ };
411
+
390
412
// For each state that we are currently tracking, apply our summarized
391
413
// instructions to it.
392
414
for (auto &OtherState : getTopDownStates ()) {
393
415
if (!OtherState.hasValue ())
394
416
continue ;
395
417
396
- for (auto *I : State->getSummarizedInterestingInsts ())
397
- OtherState->second .updateForDifferentLoopInst (I, SetFactory, AA);
418
+ for (auto *I : State->getSummarizedInterestingInsts ()) {
419
+ OtherState->second .updateForDifferentLoopInst (I, AA);
420
+ OtherState->second .checkAndResetKnownSafety (
421
+ I, OtherState->first , checkIfRefCountInstIsMatched, RCIA, AA);
422
+ }
398
423
}
399
424
400
425
return false ;
@@ -403,6 +428,7 @@ bool ARCRegionState::processLoopTopDown(
403
428
bool ARCRegionState::processTopDown (
404
429
AliasAnalysis *AA, RCIdentityFunctionInfo *RCIA,
405
430
LoopRegionFunctionInfo *LRFI,
431
+ llvm::DenseSet<SILInstruction *> &UnmatchedRefCountInsts,
406
432
BlotMapVector<SILInstruction *, TopDownRefCountState> &DecToIncStateMap,
407
433
llvm::DenseMap<const LoopRegion *, ARCRegionState *> &RegionStateInfo,
408
434
ImmutablePointerSetFactory<SILInstruction> &SetFactory) {
@@ -411,7 +437,8 @@ bool ARCRegionState::processTopDown(
411
437
// We only process basic blocks for now. This ensures that we always propagate
412
438
// the empty set from loops.
413
439
if (!R->isBlock ())
414
- return processLoopTopDown (R, RegionStateInfo[R], AA, LRFI, SetFactory);
440
+ return processLoopTopDown (R, RegionStateInfo[R], AA, LRFI, RCIA,
441
+ UnmatchedRefCountInsts);
415
442
416
443
return processBlockTopDown (*R->getBlock (), AA, RCIA, DecToIncStateMap,
417
444
SetFactory);
0 commit comments