/// Use the summary analysis to check whether a call to the given
/// function would conflict with any in progress accesses. The starting
/// index indicates what index into the the callee's parameters the
/// arguments array starts at -- this is useful for partial_apply functions,
/// which pass only a suffix of the callee's arguments at the apply site.
static void checkForViolationWithCall(
    const StorageMap &Accesses, SILFunction *Callee, unsigned StartingAtIndex,
    OperandValueArrayRef Arguments, AccessSummaryAnalysis *ASA,
    llvm::SmallVectorImpl<ConflictingAccess> &ConflictingAccesses) {
  const AccessSummaryAnalysis::FunctionSummary &FS =
      ASA->getOrCreateSummary(Callee);

  // For each argument in the suffix of the callee arguments being passed
  // at this call site, determine whether the arguments will be accessed
  // in a way that conflicts with any currently in progress accesses.
  // If so, diagnose.
  for (unsigned ArgumentIndex : indices(Arguments)) {
    unsigned CalleeIndex = StartingAtIndex + ArgumentIndex;

    const AccessSummaryAnalysis::ArgumentSummary &AS =
        FS.getAccessForArgument(CalleeIndex);

    const auto &SubAccesses = AS.getSubAccesses();

    // Is the capture accessed in the callee?
    if (SubAccesses.size() == 0)
      continue;

    SILValue Argument = Arguments[ArgumentIndex];
    assert(Argument->getType().isAddress());

    const AccessedStorage &Storage = findAccessedStorage(Argument);
    auto AccessIt = Accesses.find(Storage);

    // Are there any accesses in progress at the time of the call?
    if (AccessIt == Accesses.end())
      continue;

    const AccessInfo &Info = AccessIt->getSecond();
    if (auto Conflict = findConflictingArgumentAccess(AS, Storage, Info)) {
      ConflictingAccesses.push_back(*Conflict);
    }
  }
}