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