//===--- ArgumentSource.cpp - Latent value representation -----------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// A structure for holding a r-value or l-value
//
//===----------------------------------------------------------------------===//

#include "ArgumentSource.h"
#include "Conversion.h"
#include "Initialization.h"

using namespace swift;
using namespace Lowering;

RValue &ArgumentSource::forceAndPeekRValue(SILGenFunction &SGF) & {
  if (isRValue()) {
    return peekRValue();
  }

  // Extract an r-value.
  SILLocation loc = getLocation();
  RValue value = std::move(*this).getAsRValue(SGF);

  // Destroy the current state.
  Storage.destruct(StoredKind);

  // Emplace the r-value back into the source.
  StoredKind = Kind::RValue;
  Storage.emplaceAggregate<RValueStorage>(StoredKind, std::move(value), loc);

  return peekRValue();
}

RValue &ArgumentSource::peekRValue() & {
  assert(isRValue() && "Undefined behavior to call this method without the "
         "ArgumentSource actually being an RValue");
  return Storage.get<RValueStorage>(StoredKind).Value;
}

void ArgumentSource::rewriteType(CanType newType) & {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot rewrite type of l-value");
  case Kind::Tuple:
    llvm_unreachable("cannot rewrite type of tuple");
  case Kind::RValue:
  case Kind::DelayedBorrowedRValue:
    Storage.get<RValueStorage>(StoredKind).Value.rewriteType(newType);
    return;
  case Kind::Expr:
    Expr *expr = Storage.get<Expr*>(StoredKind);
    if (expr->getType()->isEqual(newType)) return;
    llvm_unreachable("unimplemented! hope it doesn't happen");
  }
  llvm_unreachable("bad kind");
}

bool ArgumentSource::requiresCalleeToEvaluate() const {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::RValue:
  case Kind::DelayedBorrowedRValue:
  case Kind::LValue:
    return false;
  case Kind::Expr:
    // FIXME: TupleShuffleExprs come in two flavors:
    //
    // 1) as apply arguments, where they're used to insert default
    // argument value and collect varargs
    //
    // 2) as tuple conversions, where they can introduce, eliminate
    // and re-order fields
    //
    // Case 1) must be emitted by ArgEmitter, and Case 2) must be
    // emitted by RValueEmitter.
    //
    // It would be good to split up TupleShuffleExpr into these two
    // cases, and simplify ArgEmitter since it no longer has to deal
    // with re-ordering. However for now, SubscriptExpr emits the
    // index argument via the RValueEmitter, so the RValueEmitter has
    // to know about varargs, duplicating some of the logic in
    // ArgEmitter.
    //
    // Once this is fixed, we can also consider allowing subscripts
    // to have default arguments.
    if (auto *shuffleExpr = dyn_cast<TupleShuffleExpr>(asKnownExpr())) {
      for (auto index : shuffleExpr->getElementMapping()) {
        if (index == TupleShuffleExpr::DefaultInitialize ||
            index == TupleShuffleExpr::CallerDefaultInitialize ||
            index == TupleShuffleExpr::Variadic)
          return true;
      }
    }
    return false;
  case Kind::Tuple:
    for (auto &source : Storage.get<TupleStorage>(StoredKind).Elements) {
      if (source.requiresCalleeToEvaluate())
        return true;
    }
    return false;
  }
  llvm_unreachable("bad kind");
}

RValue ArgumentSource::getAsRValue(SILGenFunction &SGF, SGFContext C) && {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot get l-value as r-value");
  case Kind::DelayedBorrowedRValue:
    return std::move(*this).asKnownRValue(SGF).borrow(SGF,
                                                      getKnownRValueLocation());
  case Kind::RValue:
    return std::move(*this).asKnownRValue(SGF);
  case Kind::Expr:
    return SGF.emitRValue(std::move(*this).asKnownExpr(), C);
  case Kind::Tuple:
    return std::move(*this).getKnownTupleAsRValue(SGF, C);
  }
  llvm_unreachable("bad kind");
}

RValue
ArgumentSource::getKnownTupleAsRValue(SILGenFunction &SGF, SGFContext C) && {

  return std::move(*this).withKnownTupleElementSources<RValue>(
                            [&](SILLocation loc, CanTupleType type,
                                MutableArrayRef<ArgumentSource> elements) {
    // If there's a target initialization, and we can split it, do so.
    if (auto init = C.getEmitInto()) {
      if (init->canSplitIntoTupleElements()) {
        // Split the tuple.
        SmallVector<InitializationPtr, 4> scratch;
        auto eltInits = init->splitIntoTupleElements(SGF, loc, type, scratch);

        // Emit each element into the corresponding element initialization.
        for (auto i : indices(eltInits)) {
          std::move(elements[i]).forwardInto(SGF, eltInits[i].get());
        }

        // Finish initialization.
        init->finishInitialization(SGF);

        return RValue::forInContext();
      }
    }

    // Otherwise, emit all of the elements into a single big r-value.
    RValue result(type);
    for (auto &element : elements) {
      result.addElement(std::move(element).getAsRValue(SGF));
    }
    return result;
  });
}

ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &SGF,
                                              SGFContext C) && {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue: {
    auto loc = getKnownLValueLocation();
    return SGF.emitAddressOfLValue(loc, std::move(*this).asKnownLValue(),
                                   AccessKind::ReadWrite);
  }
  case Kind::DelayedBorrowedRValue: {
    assert(!C.getEmitInto() &&
           "Can not put a delayed borrowed rvalue into an initialization");
    auto loc = getKnownRValueLocation();
    return std::move(*this)
        .asKnownRValue(SGF)
        .getAsSingleValue(SGF, loc)
        .borrow(SGF, loc);
  }
  case Kind::RValue: {
    auto loc = getKnownRValueLocation();
    if (auto init = C.getEmitInto()) {
      std::move(*this).asKnownRValue(SGF).forwardInto(SGF, loc, init);
      return ManagedValue::forInContext();
    } else {
      return std::move(*this).asKnownRValue(SGF).getAsSingleValue(SGF, loc);
    }
  }
  case Kind::Expr: {
    auto e = std::move(*this).asKnownExpr();
    if (e->isSemanticallyInOutExpr()) {
      return SGF.emitAddressOfLValue(e, SGF.emitLValue(e, AccessKind::ReadWrite),
                                     AccessKind::ReadWrite);
    } else {
      return SGF.emitRValueAsSingleValue(e, C);
    }
  }
  case Kind::Tuple: {
    auto loc = getKnownTupleLocation();
    auto rvalue = std::move(*this).getKnownTupleAsRValue(SGF, C);
    if (rvalue.isInContext())
      return ManagedValue::forInContext();
    return std::move(rvalue).getAsSingleValue(SGF, loc);
  }
  }
  llvm_unreachable("bad kind");
}


ManagedValue ArgumentSource::getAsSingleValue(SILGenFunction &SGF,
                                              AbstractionPattern origFormalType,
                                              SGFContext C) && {
  auto substFormalType = getSubstType();
  auto conversion = Conversion::getSubstToOrig(origFormalType, substFormalType);
  return std::move(*this).getConverted(SGF, conversion, C);
}

ManagedValue ArgumentSource::getConverted(SILGenFunction &SGF,
                                          const Conversion &conversion,
                                          SGFContext C) && {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot get converted l-value");
  case Kind::DelayedBorrowedRValue:
    // TODO: We probably can, but we would need to introduce a copy.
    llvm_unreachable("cannot get converted borrowed r-value");
  case Kind::RValue:
  case Kind::Expr:
  case Kind::Tuple:
    return SGF.emitConvertedRValue(getLocation(), conversion, C,
                [&](SILGenFunction &SGF, SILLocation loc, SGFContext C) {
      return std::move(*this).getAsSingleValue(SGF, C);
    });
  }
  llvm_unreachable("bad kind");
}

void ArgumentSource::forwardInto(SILGenFunction &SGF, Initialization *dest) && {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot forward an l-value");
  case Kind::DelayedBorrowedRValue:
    llvm_unreachable("cannot forward a delayed borrowed r-value");
  case Kind::RValue: {
    auto loc = getKnownRValueLocation();
    std::move(*this).asKnownRValue(SGF).forwardInto(SGF, loc, dest);
    return;
  }
  case Kind::Expr: {
    auto e = std::move(*this).asKnownExpr();
    SGF.emitExprInto(e, dest);
    return;
  }
  case Kind::Tuple: {
    auto loc = getKnownTupleLocation();
    auto rvalue = std::move(*this).getKnownTupleAsRValue(SGF, SGFContext(dest));
    if (!rvalue.isInContext())
      std::move(rvalue).forwardInto(SGF, loc, dest);
    return;
  }
  }
  llvm_unreachable("bad kind");
}

// FIXME: Once uncurrying is removed, get rid of this constructor.
ArgumentSource::ArgumentSource(SILLocation loc, RValue &&rv, Kind kind)
    : Storage(), StoredKind(kind) {
  Storage.emplaceAggregate<RValueStorage>(StoredKind, std::move(rv), loc);
}

ArgumentSource ArgumentSource::delayedBorrow(SILGenFunction &SGF) const & {
  assert(isRValue() && "Can only perform a delayed borrow on an rvalue");
  // We are doing something evil here since we know that we are going to perform
  // a borrow.
  //
  // Once uncurrying is removed from the compiler, we will no longer need to
  // perform delayed borrows and this evilness can be expunged.
  const RValue &rv = asKnownRValue();
  return ArgumentSource(getKnownRValueLocation(),
                        RValue(&SGF, rv.values, rv.type),
                        Kind::DelayedBorrowedRValue);
}

ArgumentSource ArgumentSource::borrow(SILGenFunction &SGF) const & {
  switch (StoredKind) {
  case Kind::Invalid:
    llvm_unreachable("argument source is invalid");
  case Kind::LValue:
    llvm_unreachable("cannot borrow an l-value");
  case Kind::DelayedBorrowedRValue:
  case Kind::RValue: {
    auto loc = getKnownRValueLocation();
    return ArgumentSource(loc, asKnownRValue().borrow(SGF, loc));
  }
  case Kind::Expr: {
    llvm_unreachable("cannot borrow an expression");
  }
  case Kind::Tuple: {
    // FIXME: We can if we check the sub argument sources.
    llvm_unreachable("cannot borrow a tuple");
  }
  }
  llvm_unreachable("bad kind");
}

ManagedValue ArgumentSource::materialize(SILGenFunction &SGF) && {
  if (isRValue()) {
    auto loc = getKnownRValueLocation();
    return std::move(*this).asKnownRValue(SGF).materialize(SGF, loc);
  }

  auto loc = getLocation();
  auto temp = SGF.emitTemporary(loc, SGF.getTypeLowering(getSubstType()));
  std::move(*this).forwardInto(SGF, temp.get());
  return temp->getManagedAddress();
}

ManagedValue ArgumentSource::materialize(SILGenFunction &SGF,
                                         AbstractionPattern origFormalType,
                                         SILType destType) && {
  auto substFormalType = CanType(getSubstType()->getInOutObjectType());
  assert(!destType || destType.getObjectType() ==
               SGF.SGM.Types.getLoweredType(origFormalType,
                                            substFormalType).getObjectType());

  // Fast path: if the types match exactly, no abstraction difference
  // is possible and we can just materialize as normal.
  if (origFormalType.isExactType(substFormalType))
    return std::move(*this).materialize(SGF);

  auto &destTL =
    (destType ? SGF.getTypeLowering(destType)
              : SGF.getTypeLowering(origFormalType, substFormalType));
  if (!destType) destType = destTL.getLoweredType();

  // If there's no abstraction difference, we can just materialize as normal.
  if (destTL.getLoweredType() == SGF.getLoweredType(substFormalType)) {
    return std::move(*this).materialize(SGF);
  }

  // Emit a temporary at the given address.
  auto temp = SGF.emitTemporary(getLocation(), destTL);

  // Forward into it.
  std::move(*this).forwardInto(SGF, origFormalType, temp.get(), destTL);

  return temp->getManagedAddress();
}

void ArgumentSource::forwardInto(SILGenFunction &SGF,
                                 AbstractionPattern origFormalType,
                                 Initialization *dest,
                                 const TypeLowering &destTL) && {
  auto substFormalType = getSubstType();
  assert(destTL.getLoweredType() ==
                        SGF.getLoweredType(origFormalType, substFormalType));

  // If there are no abstraction changes, we can just forward
  // normally.
  if (origFormalType.isExactType(substFormalType) ||
      destTL.getLoweredType() == SGF.getLoweredType(substFormalType)) {
    std::move(*this).forwardInto(SGF, dest);
    return;
  }

  // Otherwise, emit as a single independent value.
  SILLocation loc = getLocation();
  ManagedValue outputValue =
      std::move(*this).getAsSingleValue(SGF, origFormalType,
                                        SGFContext(dest));

  if (outputValue.isInContext()) return;

  // Use RValue's forward-into-initialization code.  We have to lie to
  // RValue about the formal type (by using the lowered type) because
  // we're emitting into an abstracted value, which RValue doesn't
  // really handle.
  auto substLoweredType = destTL.getLoweredType().getSwiftRValueType();
  RValue(SGF, loc, substLoweredType, outputValue).forwardInto(SGF, loc, dest);
}

SILType ArgumentSource::getSILSubstRValueType(SILGenFunction &SGF) const & {
  CanSILFunctionType funcType = SGF.F.getLoweredFunctionType();
  CanType substType = getSubstType();
  AbstractionPattern origType(funcType->getGenericSignature(), substType);
  return SGF.getLoweredType(origType, substType);
}

SILType ArgumentSource::getSILSubstType(SILGenFunction &SGF) const & {
  CanSILFunctionType funcType = SGF.F.getLoweredFunctionType();
  CanType substType = getSubstType();
  AbstractionPattern origType(funcType->getGenericSignature(), substType);
  return SGF.getLoweredType(origType, substType);
}

void ArgumentSource::dump() const {
  dump(llvm::errs());
}

void ArgumentSource::dump(raw_ostream &out, unsigned indent) const {
  out.indent(indent) << "ArgumentSource::";
  switch (StoredKind) {
  case Kind::Invalid:
    out << "Invalid\n";
    return;
  case Kind::LValue:
    out << "LValue\n";
    Storage.get<LValueStorage>(StoredKind).Value.dump(out, indent + 2);
    return;
  case Kind::Tuple: {
    out << "Tuple\n";
    auto &storage = Storage.get<TupleStorage>(StoredKind);
    storage.SubstType.dump(out, indent + 2);
    for (auto &elt : storage.Elements) {
      elt.dump(out, indent + 2);
      out << '\n';
    }
    return;
  }
  case Kind::RValue:
  case Kind::DelayedBorrowedRValue:
    out << "RValue\n";
    Storage.get<RValueStorage>(StoredKind).Value.dump(out, indent + 2);
    return;
  case Kind::Expr:
    out << "Expr\n";
    Storage.get<Expr*>(StoredKind)->dump(out); // FIXME: indent
    return;
  }
  llvm_unreachable("bad kind");
}
