Пример #1
0
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());
}
Пример #2
0
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());
}