//===--- 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::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:
    Storage.get<RValueStorage>(StoredKind).Value.rewriteType(newType);
    return;
  case Kind::Expr:
    Expr *&expr = Storage.get<Expr*>(StoredKind);
    CanType oldType = expr->getType()->getCanonicalType();

    // Usually nothing is required.
    if (oldType == newType) return;

    // Sometimes we need to wrap the expression in a single-element tuple.
    // This is only necessary because we don't break down the argument list
    // when dealing with SILGenApply.
    if (auto newTuple = dyn_cast<TupleType>(newType)) {
      if (newTuple->getNumElements() == 1 &&
          newTuple.getElementType(0) == oldType) {
        expr = TupleExpr::create(newType->getASTContext(),
                                 SourceLoc(), expr, {}, {}, SourceLoc(),
                                 /*trailing closure*/ false,
                                 /*implicit*/ true, 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::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::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::RValue: {
    auto loc = getKnownRValueLocation();
    if (auto init = C.getEmitInto()) {
      std::move(*this).asKnownRValue(SGF)
                      .ensurePlusOne(SGF, loc)
                      .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::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::RValue: {
    auto loc = getKnownRValueLocation();
    std::move(*this).asKnownRValue(SGF).ensurePlusOne(SGF, loc).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).ensurePlusOne(SGF, loc).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::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::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:
    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");
}
