Repository: apple/swift
File: lib/IRGen/LoadableByAddress.cpp (C++)

Code before:
            // Delete all dealloc_stack instructions for this allocation
            for (auto *use : stackAlloc->getUses()) {
              if (auto *dealloc = dyn_cast<DeallocStackInst>(use->getUser())) {
                dealloc->eraseFromParent();
              }
            }

            stackAlloc->replaceAllUsesWith(newApply);
            stackAlloc->eraseFromParent();
          }
        }
      }
    }

    break;
  }
  case SILInstructionKind::TryApplyInst: {
    auto *castedApply = cast<TryApplyInst>(applyInst);
    auto *newTryApply = applyBuilder.createTryApply(
        castedApply->getLoc(), callee, applySite.getSubstitutionMap(), callArgs,
        castedApply->getNormalBB(), castedApply->getErrorBB(),
        castedApply->getApplyOptions());

    // For guaranteed address results, replace the pre-allocated stack slot
    // with the returned address (which comes as the normal BB argument)
    if (modNonFuncTypeResultType(genEnv, origSILFunctionType, *currIRMod)) {
      auto allocIt = allApplyRetToAllocMap.find(applyInst);
      if (allocIt != allApplyRetToAllocMap.end()) {
        // Check if the new function returns a guaranteed address
        if (newSILFunctionType->getNumResults() == 1) {
          auto resultInfo = newSILFunctionType->getSingleResult();
          if (resultInfo.getConvention() ==
              ResultConvention::GuaranteedAddress) {
            auto *stackAlloc = cast<AllocStackInst>(allocIt->second);
            auto *normalBB = newTryApply->getNormalBB();
            if (normalBB->getNumArguments() > 0) {
              auto *resultArg = normalBB->getArgument(0);

              // Delete all dealloc_stack instructions for this allocation
              for (auto *use : stackAlloc->getUses()) {
                if (auto *dealloc =
                        dyn_cast<DeallocStackInst>(use->getUser())) {
                  dealloc->eraseFromParent();
                }
              }

              stackAlloc->replaceAllUsesWith(resultArg);
              stackAlloc->eraseFromParent();
            }
          }
        }

Review comment (suggestion):
We don't support `borrow` accessors with `throws` yet. So this is not really needed yet and we can add an invariant that we never see a borrow accessor here. 

Code after:
            dealloc->eraseFromParent();
          }
        }
        stackAlloc->replaceAllUsesWith(newApply);
        stackAlloc->eraseFromParent();
      }
    }

    break;
  }
  case SILInstructionKind::TryApplyInst: {
    auto *castedApply = cast<TryApplyInst>(applyInst);
    applyBuilder.createTryApply(
        castedApply->getLoc(), callee, applySite.getSubstitutionMap(), callArgs,
        castedApply->getNormalBB(), castedApply->getErrorBB(),
        castedApply->getApplyOptions());

    break;
  }
  case SILInstructionKind::BeginApplyInst: {
    auto oldApply = cast<BeginApplyInst>(applyInst);
    auto newApply =
      applyBuilder.createBeginApply(oldApply->getLoc(), callee,
                                    applySite.getSubstitutionMap(), callArgs,
                                    oldApply->getApplyOptions());

    // Use the new token result.
    oldApply->getTokenResult()->replaceAllUsesWith(newApply->getTokenResult());

    if (auto *allocation = oldApply->getCalleeAllocationResult()) {
      allocation->replaceAllUsesWith(newApply->getCalleeAllocationResult());
    }

    // Rewrite all the yields.
    auto oldYields = oldApply->getOrigCalleeType()->getYields();
    auto oldYieldedValues = oldApply->getYieldedValues();
    auto newYields = newApply->getOrigCalleeType()->getYields();
    auto newYieldedValues = newApply->getYieldedValues();
    assert(oldYields.size() == newYields.size() &&
           oldYields.size() == oldYieldedValues.size() &&
           newYields.size() == newYieldedValues.size());
    (void)newYields;
    for (auto i : indices(oldYields)) {
      SILValue oldValue = oldYieldedValues[i];
      SILValue newValue = newYieldedValues[i];

      // For now, just replace the value with an immediate load if the old value
      // was direct.
      if (oldValue->getType() != newValue->getType() &&
          !oldValue->getType().isAddress()) {
        LoadOwnershipQualifier ownership;