@@ -251,26 +251,56 @@ struct ClosureOperandState {
251
251
// / points.
252
252
DebugValueInst *singleDebugValue = nullptr ;
253
253
254
- // / If set to true, this closure invocation propagates a use upwards that will
255
- // / result in an error.
256
- bool isUpwardsUse = false ;
257
-
258
- // / If set to true, then the var in the callee is reinited and or destroyed
259
- // / with a destroy_addr. We can convert the inout_aliasable to an out
260
- // / parameter.
261
- bool isUpwardsConsume = false ;
262
-
263
- // / We do not propagate inits towards function exits, we just use them to stop
264
- // / propagating uses or consumes. This is because we only care about analyzing
265
- // / the address while the parameter value has not be reinited over. We can
266
- // / rely on SILGen when working with vars (the only way this can happen).
267
- bool isUpwardsInit = false ;
254
+ bool isUpwardsUse () const {
255
+ return result == DownwardScanResult::ClosureUse;
256
+ }
257
+
258
+ bool isUpwardsConsume () const {
259
+ return result == DownwardScanResult::ClosureConsume;
260
+ }
268
261
};
269
262
270
263
} // namespace
271
264
265
+ static void convertMemoryReinitToInitForm (SILInstruction *memInst) {
266
+ switch (memInst->getKind ()) {
267
+ default :
268
+ llvm_unreachable (" unsupported?!" );
269
+
270
+ case SILInstructionKind::CopyAddrInst: {
271
+ auto *cai = cast<CopyAddrInst>(memInst);
272
+ cai->setIsInitializationOfDest (IsInitialization_t::IsInitialization);
273
+ return ;
274
+ }
275
+ case SILInstructionKind::StoreInst: {
276
+ auto *si = cast<StoreInst>(memInst);
277
+ si->setOwnershipQualifier (StoreOwnershipQualifier::Init);
278
+ return ;
279
+ }
280
+ }
281
+ }
282
+
283
+ static bool memInstMustReinitialize (Operand *memOper) {
284
+ SILValue address = memOper->get ();
285
+ auto *memInst = memOper->getUser ();
286
+ switch (memInst->getKind ()) {
287
+ default :
288
+ return false ;
289
+
290
+ case SILInstructionKind::CopyAddrInst: {
291
+ auto *CAI = cast<CopyAddrInst>(memInst);
292
+ return CAI->getDest () == address && !CAI->isInitializationOfDest ();
293
+ }
294
+ case SILInstructionKind::StoreInst: {
295
+ auto *si = cast<StoreInst>(memInst);
296
+ return si->getDest () == address &&
297
+ si->getOwnershipQualifier () == StoreOwnershipQualifier::Assign;
298
+ }
299
+ }
300
+ }
301
+
272
302
// ===----------------------------------------------------------------------===//
273
- // Use Gathering
303
+ // Use State
274
304
// ===----------------------------------------------------------------------===//
275
305
276
306
namespace {
@@ -704,7 +734,6 @@ bool ClosureArgDataflowState::handleSingleBlockCase(
704
734
return false ;
705
735
706
736
state.pairedConsumingInsts .push_back (dvi);
707
- state.isUpwardsConsume = true ;
708
737
state.result = DownwardScanResult::ClosureConsume;
709
738
return true ;
710
739
}
@@ -718,7 +747,6 @@ bool ClosureArgDataflowState::handleSingleBlockCase(
718
747
return false ;
719
748
720
749
state.pairedConsumingInsts .push_back (&inst);
721
- state.isUpwardsConsume = true ;
722
750
state.result = DownwardScanResult::ClosureConsume;
723
751
return true ;
724
752
}
@@ -728,7 +756,6 @@ bool ClosureArgDataflowState::handleSingleBlockCase(
728
756
LLVM_DEBUG (llvm::dbgs ()
729
757
<< " ClosureArgDataflow: Found liveness use: " << inst);
730
758
state.pairedUseInsts .push_back (&inst);
731
- state.isUpwardsUse = true ;
732
759
state.result = DownwardScanResult::ClosureUse;
733
760
return true ;
734
761
}
@@ -923,7 +950,6 @@ bool ClosureArgDataflowState::process(
923
950
state.pairedUseInsts .push_back (ptr);
924
951
}
925
952
}
926
- state.isUpwardsUse = true ;
927
953
state.result = DownwardScanResult::ClosureUse;
928
954
return true ;
929
955
}
@@ -960,7 +986,6 @@ bool ClosureArgDataflowState::process(
960
986
return false ;
961
987
postDominatingConsumingUsers.insert (ptr);
962
988
}
963
- state.isUpwardsConsume = true ;
964
989
state.result = DownwardScanResult::ClosureConsume;
965
990
return true ;
966
991
}
0 commit comments