AccessedStorage swift::findAccessedStorage(SILValue sourceAddr) { SmallVector<SILValue, 8> addressWorklist({sourceAddr}); SmallPtrSet<SILPhiArgument *, 4> visitedPhis; Optional<AccessedStorage> storage; while (!addressWorklist.empty()) { AccessedStorageResult result = getAccessedStorageFromAddress(addressWorklist.pop_back_val()); if (!result.isComplete()) { SILValue operAddr = result.getAddress(); if (auto *phiArg = dyn_cast<SILPhiArgument>(operAddr)) { if (phiArg->isPhiArgument()) { if (visitedPhis.insert(phiArg).second) phiArg->getIncomingPhiValues(addressWorklist); continue; } } addressWorklist.push_back(operAddr); continue; } if (!storage.hasValue()) { storage = result.getStorage(); continue; } if (!accessingIdenticalLocations(storage.getValue(), result.getStorage())) return AccessedStorage(); } return storage.getValueOr(AccessedStorage()); }
AccessedStorage swift::findAccessedStorage(SILValue sourceAddr) { SmallVector<SILValue, 8> addressWorklist({sourceAddr}); SmallPtrSet<SILPhiArgument *, 4> visitedPhis; Optional<AccessedStorage> storage; while (!addressWorklist.empty()) { AccessedStorageResult result = getAccessedStorageFromAddress(addressWorklist.pop_back_val()); if (!result.isComplete()) { SILValue operAddr = result.getAddress(); if (auto *phiArg = dyn_cast<SILPhiArgument>(operAddr)) { if (phiArg->isPhiArgument()) { if (visitedPhis.insert(phiArg).second) phiArg->getIncomingPhiValues(addressWorklist); continue; } } addressWorklist.push_back(operAddr); continue; } if (!storage.hasValue()) { storage = result.getStorage(); continue; } // `storage` may still be invalid. If both `storage` and `result` are // invalid, this check passes, but we return an invalid storage below. if (!storage.getValue().hasIdenticalBase(result.getStorage())) return AccessedStorage(); } return storage.getValueOr(AccessedStorage()); }