/// Helper for visitApplyAccesses that visits address-type call arguments, /// including arguments to @noescape functions that are passed as closures to /// the current call. static void visitApplyAccesses(ApplySite apply, llvm::function_ref<void(Operand *)> visitor) { for (Operand &oper : apply.getArgumentOperands()) { // Consider any address-type operand an access. Whether it is read or modify // depends on the argument convention. if (oper.get()->getType().isAddress()) { visitor(&oper); continue; } auto fnType = oper.get()->getType().getAs<SILFunctionType>(); if (!fnType || !fnType->isNoEscape()) continue; // When @noescape function closures are passed as arguments, their // arguments are considered accessed at the call site. TinyPtrVector<PartialApplyInst *> partialApplies; findClosuresForFunctionValue(oper.get(), partialApplies); // Recursively visit @noescape function closure arguments. for (auto *PAI : partialApplies) visitApplyAccesses(PAI, visitor); } }
/// Helper for visitApplyAccesses that visits address-type call arguments, /// including arguments to @noescape functions that are passed as closures to /// the current call. static void visitApplyAccesses(ApplySite apply, llvm::function_ref<void(Operand *)> visitor) { for (Operand &oper : apply.getArgumentOperands()) { // Consider any address-type operand an access. Whether it is read or modify // depends on the argument convention. if (oper.get()->getType().isAddress()) { visitor(&oper); continue; } auto fnType = oper.get()->getType().getAs<SILFunctionType>(); if (!fnType || !fnType->isNoEscape()) continue; // When @noescape function closures are passed as arguments, their // arguments are considered accessed at the call site. FindClosureResult result = findClosureForAppliedArg(oper.get()); if (!result.PAI) continue; // Recursively visit @noescape function closure arguments. visitApplyAccesses(result.PAI, visitor); } }