//===--- 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()),
      wasInFormalEvaluationScope(SGF.InFormalEvaluationScope),
      wasInInOutConversionScope(SGF.InInOutConversionScope) {
  if (wasInInOutConversionScope) {
    savedDepth.reset();
    return;
  }
  SGF.InFormalEvaluationScope = true;
}

FormalEvaluationScope::FormalEvaluationScope(FormalEvaluationScope &&o)
    : SGF(o.SGF), savedDepth(o.savedDepth),
      wasInFormalEvaluationScope(o.wasInFormalEvaluationScope),
      wasInInOutConversionScope(o.wasInInOutConversionScope) {
  o.savedDepth.reset();
}

void FormalEvaluationScope::popImpl() {
  // Pop the SGF.InFormalEvaluationScope bit.
  SGF.InFormalEvaluationScope = wasInFormalEvaluationScope;

  // Check to see if there is anything going on here.

  auto &context = SGF.FormalEvalContext;
  using iterator = FormalEvaluationContext::iterator;
  using stable_iterator = FormalEvaluationContext::stable_iterator;

  iterator unwrappedSavedDepth = context.find(savedDepth.getValue());
  iterator iter = context.begin();
  if (iter == unwrappedSavedDepth)
    return;

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

  // Then working down the stack until we visit unwrappedSavedDepth...
  for (; iter != unwrappedSavedDepth; ++iter) {
    // Grab the next evaluation...
    FormalAccess &access = *iter;

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

    // and deactivate the cleanup. This will set the isFinished bit for owned
    // FormalAccess.
    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) {
      iterator j = iter;
      ++j;

      for (; j != unwrappedSavedDepth; ++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.
    access.finish(SGF);
  }

  // Then check that we did not add any additional cleanups to the beginning of
  // the stack...
  assert(originalBegin == context.stable_begin() &&
         "more formal eval cleanups placed onto context during formal eval scope pop?!");

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

void FormalEvaluationScope::verify() const {
  // Check to see if there is anything going on here.
  auto &context = SGF.FormalEvalContext;
  using iterator = FormalEvaluationContext::iterator;

  iterator unwrappedSavedDepth = context.find(savedDepth.getValue());
  iterator iter = context.begin();
  if (iter == unwrappedSavedDepth)
    return;

  // Then working down the stack until we visit unwrappedSavedDepth...
  for (; iter != unwrappedSavedDepth; ++iter) {
    // Grab the next evaluation verify that we can successfully access this
    // formal access.
    (*iter).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());
  }
}
