/// 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); } } }