//===--- FormalEvaluation.cpp ---------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "FormalEvaluation.h"
#include "LValue.h"
#include "SILGenFunction.h"

using namespace swift;
using namespace Lowering;

//===----------------------------------------------------------------------===//
//                               Formal Access
//===----------------------------------------------------------------------===//

void FormalAccess::_anchor() {}

void FormalAccess::verify(SILGenFunction &SGF) const {
#ifndef NDEBUG
  // If this access was already finished, continue. This can happen if an
  // owned formal access was forwarded.
  if (isFinished()) {
    assert(getKind() == FormalAccess::Owned &&
           "Only owned formal accesses should be forwarded.");
    // We can not check that our cleanup is actually dead since the cleanup
    // may have been popped at this point and the stack may have new values.
    return;
  }

  assert(!isFinished() && "Can not finish a formal access cleanup "
         "twice");

  // Now try to look up the cleanup handle of the formal access.
  SGF.Cleanups.checkIterator(getCleanup());
#endif
}

//===----------------------------------------------------------------------===//
//                      Shared Borrow Formal Evaluation
//===----------------------------------------------------------------------===//

void SharedBorrowFormalAccess::finishImpl(SILGenFunction &SGF) {
  SGF.B.createEndBorrow(CleanupLocation::get(loc), borrowedValue,
                        originalValue);
}

//===----------------------------------------------------------------------===//
//                             OwnedFormalAccess
//===----------------------------------------------------------------------===//

void OwnedFormalAccess::finishImpl(SILGenFunction &SGF) {
  auto cleanupLoc = CleanupLocation::get(loc);
  if (value->getType().isAddress())
    SGF.B.createDestroyAddr(cleanupLoc, value);
  else
    SGF.B.emitDestroyValueOperation(cleanupLoc, value);
}

//===----------------------------------------------------------------------===//
//                          Formal Evaluation Scope
//===----------------------------------------------------------------------===//

FormalEvaluationScope::FormalEvaluationScope(SILGenFunction &SGF)
    : SGF(SGF), savedDepth(SGF.FormalEvalContext.stable_begin()),
      previous(SGF.FormalEvalContext.innermostScope),
      wasInInOutConversionScope(SGF.InInOutConversionScope) {
  if (wasInInOutConversionScope) {
    savedDepth.reset();
    assert(isPopped());
    return;
  }
  SGF.FormalEvalContext.innermostScope = this;
}

FormalEvaluationScope::FormalEvaluationScope(FormalEvaluationScope &&o)
    : SGF(o.SGF), savedDepth(o.savedDepth), previous(o.previous),
      wasInInOutConversionScope(o.wasInInOutConversionScope) {

  // Replace the scope in the active-scope chain if it's present.
  if (!o.isPopped()) {
    for (auto c = &SGF.FormalEvalContext.innermostScope; ; c = &(*c)->previous){
      if (*c == &o) {
        *c = this;
        break;
      }
    }
  }

  o.savedDepth.reset();
  assert(o.isPopped());
}

void FormalEvaluationScope::popImpl() {
  auto &context = SGF.FormalEvalContext;

  // Remove the innermost scope from the chain.
  assert(context.innermostScope == this &&
         "popping formal-evaluation scopes out of order");
  context.innermostScope = previous;

  auto endDepth = *savedDepth;

  // Check to see if there is anything going on here.
  if (endDepth == context.stable_begin())
    return;

#ifndef NDEBUG
  // Verify that all the accesses are valid.
  for (auto i = context.begin(), e = context.find(endDepth); i != e; ++i) {
    i->verify(SGF);
  }
#endif

  // Save our start point to make sure that we are not adding any new cleanups
  // to the front of the stack.
  auto originalBegin = context.stable_begin();

  // Then working down the stack until we visit unwrappedSavedDepth...
  auto i = originalBegin;
  do {
    // Grab the next evaluation.
    FormalAccess &access = context.findAndAdvance(i);

    // If this access was already finished, continue. This can happen if an
    // owned formal access was forwarded.
    if (access.isFinished()) {
      assert(access.getKind() == FormalAccess::Owned &&
             "Only owned formal accesses should be forwarded.");
      // We can not check that our cleanup is actually dead since the cleanup
      // may have been popped at this point and the stack may have new values.
      continue;
    }

    assert(!access.isFinished() && "Can not finish a formal access cleanup "
                                   "twice");

    // Set the finished bit to appease various invariants.
    access.setFinished();

    // Deactivate the cleanup.
    SGF.Cleanups.setCleanupState(access.getCleanup(), CleanupState::Dead);

    // Attempt to diagnose problems where obvious aliasing introduces illegal
    // code. We do a simple N^2 comparison here to detect this because it is
    // extremely unlikely more than a few writebacks are active at once.
    if (access.getKind() == FormalAccess::Exclusive) {
      // Note that we already advanced 'iter' above, so we can just start
      // iterating from there.  Also, this doesn't invalidate the iterators.
      for (auto j = context.find(i), je = context.find(endDepth); j != je; ++j){
        FormalAccess &other = *j;
        if (other.getKind() != FormalAccess::Exclusive)
          continue;
        auto &lhs = static_cast<ExclusiveBorrowFormalAccess &>(access);
        auto &rhs = static_cast<ExclusiveBorrowFormalAccess &>(other);
        lhs.diagnoseConflict(rhs, SGF);
      }
    }

    // Claim the address of each and then perform the writeback from the
    // temporary allocation to the source we copied from.
    //
    // This evaluates arbitrary code, so it's best to be paranoid
    // about iterators on the context.
    DiverseValueBuffer<FormalAccess> copiedAccess(access);
    copiedAccess.getCopy().finish(SGF);

  } while (i != endDepth);

  // Then check that we did not add any additional cleanups to the beginning of
  // the stack...
  assert(originalBegin == context.stable_begin() &&
         "pushed more formal evaluations while popping formal evaluations?!");

  // And then pop off all stack elements until we reach the savedDepth.
  context.pop(endDepth);
}

void FormalEvaluationScope::verify() const {
  // Walk up the stack to the saved depth.
  auto &context = SGF.FormalEvalContext;
  for (auto i = context.begin(), e = context.find(*savedDepth); i != e; ++i) {
    i->verify(SGF);
  }
}

//===----------------------------------------------------------------------===//
//                         Formal Evaluation Context
//===----------------------------------------------------------------------===//

void FormalEvaluationContext::dump(SILGenFunction &SGF) {
  for (auto II = begin(), IE = end(); II != IE; ++II) {
    FormalAccess &access = *II;
    SGF.Cleanups.dump(access.getCleanup());
  }
}
