1414#include " swift/Basic/Assertions.h"
1515#include " swift/SIL/DebugUtils.h"
1616#include " swift/SIL/InstructionUtils.h"
17+ #include " swift/SIL/NodeDatastructures.h"
1718#include " swift/SIL/SILArgument.h"
1819#include " swift/SIL/SILBuilder.h"
1920#include " swift/SIL/SILFunction.h"
@@ -732,14 +733,10 @@ SILValue swift::ArraySemanticsCall::getArrayElementStoragePointer() const {
732733 return getArrayUninitializedInitResult (*this , 1 );
733734}
734735
735- bool swift::ArraySemanticsCall::mapInitializationStores (
736- llvm::DenseMap<uint64_t , StoreInst *> &ElementValueMap) {
737- if (getKind () != ArrayCallKind::kArrayUninitialized &&
738- getKind () != ArrayCallKind::kArrayUninitializedIntrinsic )
739- return false ;
740- SILValue ElementBuffer = getArrayElementStoragePointer ();
736+ static SILValue getElementBaseAddress (ArraySemanticsCall initArray) {
737+ SILValue ElementBuffer = initArray.getArrayElementStoragePointer ();
741738 if (!ElementBuffer)
742- return false ;
739+ return SILValue () ;
743740
744741 // Match initialization stores into ElementBuffer. E.g.
745742 // %82 = struct_extract %element_buffer : $UnsafeMutablePointer<Int>
@@ -756,9 +753,29 @@ bool swift::ArraySemanticsCall::mapInitializationStores(
756753 // mark_dependence can be an operand of the struct_extract or its user.
757754
758755 SILValue UnsafeMutablePointerExtract;
759- if (getKind () == ArrayCallKind::kArrayUninitializedIntrinsic ) {
756+ if (initArray. getKind () == ArrayCallKind::kArrayUninitializedIntrinsic ) {
760757 UnsafeMutablePointerExtract = dyn_cast_or_null<MarkDependenceInst>(
761758 getSingleNonDebugUser (ElementBuffer));
759+ if (!UnsafeMutablePointerExtract) {
760+ SILValue array = initArray.getArrayValue ();
761+ ValueWorklist worklist (array);
762+ while (SILValue v = worklist.pop ()) {
763+ for (auto use : v->getUses ()) {
764+ switch (use->getUser ()->getKind ()) {
765+ case SILInstructionKind::UncheckedRefCastInst:
766+ case SILInstructionKind::StructExtractInst:
767+ case SILInstructionKind::BeginBorrowInst:
768+ worklist.pushIfNotVisited (cast<SingleValueInstruction>(use->getUser ()));
769+ break ;
770+ case SILInstructionKind::RefTailAddrInst:
771+ return cast<RefTailAddrInst>(use->getUser ());
772+ default :
773+ break ;
774+ }
775+ }
776+ }
777+ return SILValue ();
778+ }
762779 } else {
763780 auto user = getSingleNonDebugUser (ElementBuffer);
764781 // Match mark_dependence (struct_extract or
@@ -774,21 +791,33 @@ bool swift::ArraySemanticsCall::mapInitializationStores(
774791 }
775792 }
776793 if (!UnsafeMutablePointerExtract)
777- return false ;
794+ return SILValue () ;
778795
779796 auto *PointerToAddress = dyn_cast_or_null<PointerToAddressInst>(
780797 getSingleNonDebugUser (UnsafeMutablePointerExtract));
781798 if (!PointerToAddress)
799+ return SILValue ();
800+ return PointerToAddress;
801+ }
802+
803+ bool swift::ArraySemanticsCall::mapInitializationStores (
804+ llvm::DenseMap<uint64_t , StoreInst *> &ElementValueMap) {
805+ if (getKind () != ArrayCallKind::kArrayUninitialized &&
806+ getKind () != ArrayCallKind::kArrayUninitializedIntrinsic )
807+ return false ;
808+
809+ SILValue elementAddr = getElementBaseAddress (*this );
810+ if (!elementAddr)
782811 return false ;
783812
784813 // Match the stores. We can have either a store directly to the address or
785814 // to an index_addr projection.
786- for (auto *Op : PointerToAddress ->getUses ()) {
815+ for (auto *Op : elementAddr ->getUses ()) {
787816 auto *Inst = Op->getUser ();
788817
789818 // Store to the base.
790819 auto *SI = dyn_cast<StoreInst>(Inst);
791- if (SI && SI->getDest () == PointerToAddress ) {
820+ if (SI && SI->getDest () == elementAddr ) {
792821 // We have already seen an entry for this index bail.
793822 if (ElementValueMap.count (0 ))
794823 return false ;
0 commit comments