//===--- ManagedValue.h - Exploded RValue Representation --------*- C++ -*-===//
//
// 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 storage structure for holding a destructured rvalue with an optional
// cleanup(s).
// Ownership of the rvalue can be "forwarded" to disable the associated
// cleanup(s).
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_LOWERING_MANAGEDVALUE_H
#define SWIFT_LOWERING_MANAGEDVALUE_H

#include "Cleanup.h"
#include "llvm/ADT/PointerIntPair.h"
#include "swift/SIL/Consumption.h"
#include "swift/SIL/SILValue.h"

namespace swift {

enum class CastConsumptionKind : unsigned char;

namespace Lowering {

class Initialization;
class SILGenFunction;

/// ManagedValue - represents a singular SIL value and an optional cleanup.
/// Ownership of the ManagedValue can be "forwarded" to disable its cleanup when
/// the rvalue is consumed. A ManagedValue can also represent an LValue used as
/// a value, such as an inout function argument, and can be null.
///
/// Interesting relevant cases include:
///   LValue: the SILValue will always have an isAddress() SILType. LValues
///           never have an associated cleanup.
///   RValue, isAddress() type: an address-only RValue.
///   RValue, !isAddress() type: a loadable RValue.
///   "InContext": Represented with the lvalue flag set but with no SILValue,
///                this represents a value that was emitted directly into an
///                initialization stored by an SGFContext.
///
/// The RValue cases may or may not have a cleanup associated with the value.  A
/// cleanup is associated with +1 values of non-trivial type and +0 values of
/// non-trivial type.
///
class ManagedValue {
  /// The value (or address of an address-only value) being managed, and
  /// whether it represents an lvalue.  InContext is represented with the lvalue
  /// flag set but with a null SILValue.
  llvm::PointerIntPair<SILValue, 1, bool> valueAndFlag;
  
  /// A handle to the cleanup that destroys this value, or
  /// CleanupHandle::invalid() if the value has no cleanup.
  CleanupHandle cleanup;

  explicit ManagedValue(SILValue value, bool isLValue, CleanupHandle cleanup)
    : valueAndFlag(value, isLValue), cleanup(cleanup) {
  }

public:
  
  ManagedValue() = default;

  /// Create a managed value for a +1 rvalue.
  ///
  /// Please do not introduce new uses of this method! Instead use one of the
  /// static constructors below.
  ManagedValue(SILValue value, CleanupHandle cleanup)
    : valueAndFlag(value, false), cleanup(cleanup) {
    assert(value && "No value specified?!");
    assert((!getType().isObject() ||
            value.getOwnershipKind() != ValueOwnershipKind::Trivial ||
            !hasCleanup()) &&
           "Objects with trivial ownership should never have a cleanup");
  }

  /// Create a managed value for a +0 rvalue.
  ///
  /// Please do not introduce new uses of this method! Instead use one of the
  /// static constructors below!
  static ManagedValue forUnmanaged(SILValue value) {
    assert(value && "No value specified");
    return ManagedValue(value, false, CleanupHandle::invalid());
  }

  /// Create a managed value for a +1 rvalue object.
  static ManagedValue forOwnedObjectRValue(SILValue value,
                                           CleanupHandle cleanup) {
    assert(value && "No value specified");
    assert(value->getType().isObject() &&
           "Expected borrowed rvalues to be objects");
    assert(value.getOwnershipKind() != ValueOwnershipKind::Trivial);
    return ManagedValue(value, false, cleanup);
  }

  /// Create a managed value for a +1 rvalue address.
  ///
  /// From a high level perspective, this consists of a temporary buffer.
  static ManagedValue forOwnedAddressRValue(SILValue value,
                                            CleanupHandle cleanup) {
    assert(value && "No value specified");
    assert(value->getType().isAddress() && "Expected value to be an address");
    assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial &&
           "Addresses always have trivial ownership");
    return ManagedValue(value, false, cleanup);
  }

  /// Create a managed value for a +1 non-trivial rvalue.
  static ManagedValue forOwnedRValue(SILValue value, CleanupHandle cleanup) {
    if (value->getType().isAddress())
      return ManagedValue::forOwnedAddressRValue(value, cleanup);
    return ManagedValue::forOwnedObjectRValue(value, cleanup);
  }

  /// Create a managed value for a +0 borrowed non-trivial rvalue object.
  static ManagedValue
  forBorrowedObjectRValue(SILValue value) {
    assert(value && "No value specified");
    assert(value->getType().isObject() &&
           "Expected borrowed rvalues to be objects");
    assert(value.getOwnershipKind() != ValueOwnershipKind::Trivial);
    return ManagedValue(value, false, CleanupHandle::invalid());
  }

  /// Create a managed value for a +0 borrowed non-trivial rvalue address.
  static ManagedValue
  forBorrowedAddressRValue(SILValue value) {
    assert(value && "No value specified");
    assert(value->getType().isAddress() && "Expected value to be an address");
    assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial &&
           "Addresses always have trivial ownership");
    return ManagedValue(value, false, CleanupHandle::invalid());
  }

  /// Create a managed value for a +0 guaranteed rvalue.
  static ManagedValue
  forBorrowedRValue(SILValue value) {
    if (value->getType().isAddress())
      return ManagedValue::forBorrowedAddressRValue(value);
    return ManagedValue::forBorrowedObjectRValue(value);
  }

  /// Create a managed value for a +0 trivial object rvalue.
  static ManagedValue forTrivialObjectRValue(SILValue value) {
    assert(value->getType().isObject() && "Expected an object");
    assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial);
    return ManagedValue(value, false, CleanupHandle::invalid());
  }

  /// Create a managed value for a +0 trivial address rvalue.
  static ManagedValue forTrivialAddressRValue(SILValue value) {
    assert(value->getType().isAddress() && "Expected an address");
    assert(value.getOwnershipKind() == ValueOwnershipKind::Trivial);
    return ManagedValue(value, false, CleanupHandle::invalid());
  }

  /// Create a managed value for a +0 trivial rvalue.
  static ManagedValue forTrivialRValue(SILValue value) {
    if (value->getType().isObject())
      return ManagedValue::forTrivialObjectRValue(value);
    return ManagedValue::forTrivialAddressRValue(value);
  }

  /// Create a managed value for an l-value.
  static ManagedValue forLValue(SILValue value) {
    assert(value && "No value specified");
    assert(value->getType().isAddress() &&
           "lvalues always have isAddress() type");
    return ManagedValue(value, true, CleanupHandle::invalid());
  }
  
  /// Create a managed value that indicates that the value you're looking for
  /// got stored into an initialization specified by an SGFContext, instead of
  /// being represented by this ManagedValue.
  static ManagedValue forInContext() {
    return ManagedValue(SILValue(), true, CleanupHandle::invalid());
  }

  bool isLValue() const {
    return valueAndFlag.getInt() && valueAndFlag.getPointer();
  }
  bool isInContext() const {
    return valueAndFlag.getInt() && !valueAndFlag.getPointer();
  }

  /// Return true if this is an +0 rvalue, or has trivial type.
  bool isPlusZeroRValueOrTrivial() const {
    // If this is an lvalue or isInContext() then it is not an RValue.
    if (isLValue() || isInContext()) return false;
    
    // If this has a cleanup attached, then it is +1 rvalue.  If not, it is
    // either +0 or trivial (in which case +0 vs +1 doesn't matter).
    return !hasCleanup();
  }
  
  SILValue getLValueAddress() const {
    assert(isLValue() && "This isn't an lvalue");
    return getValue();
  }
  
  SILValue getUnmanagedValue() const {
    assert(!hasCleanup());
    return getValue();
  }
  SILValue getValue() const { return valueAndFlag.getPointer(); }
  
  SILType getType() const { return getValue()->getType(); }

  ValueOwnershipKind getOwnershipKind() const {
    return getValue().getOwnershipKind();
  }

  /// Transform the given ManagedValue, replacing the underlying value, but
  /// keeping the same cleanup.
  ///
  /// For owned values, this is equivalent to forwarding the cleanup and
  /// creating a new cleanup of the same type on the new value. This is useful
  /// for forwarding sequences.
  ///
  /// For all other values, it is a move.
  ManagedValue transform(SILValue newValue) && {
    assert(getValue().getOwnershipKind() == newValue.getOwnershipKind() &&
           "New value and old value must have the same ownership kind");
    ManagedValue M(newValue, isLValue(), getCleanup());
    *this = ManagedValue();
    return M;
  }

  /// Emit a copy of this value with independent ownership.
  ManagedValue copy(SILGenFunction &SGF, SILLocation loc) const;

  /// Emit a copy of this value with independent ownership into the current
  /// formal evaluation scope.
  ManagedValue formalAccessCopy(SILGenFunction &SGF, SILLocation loc);

  /// Store a copy of this value with independent ownership into the given
  /// uninitialized address.
  void copyInto(SILGenFunction &SGF, SILValue dest, SILLocation loc);

  /// This is the same operation as 'copy', but works on +0 values that don't
  /// have cleanups.  It returns a +1 value with one.
  ManagedValue copyUnmanaged(SILGenFunction &SGF, SILLocation loc);

  /// This is the same operation as 'formalAccessCopy', but works on +0 values
  /// that don't have cleanups.  It returns a +1 value with one.
  ManagedValue formalAccessCopyUnmanaged(SILGenFunction &SGF, SILLocation loc);

  bool hasCleanup() const { return cleanup.isValid(); }
  CleanupHandle getCleanup() const { return cleanup; }

  /// Return a "borrowed" version of this value.
  ///
  /// An l-value is borrowed as itself.  A +1 r-value is borrowed as a
  /// +0 r-value, with the assumption that the original ManagedValue
  /// will not be forwarded until the borrowed value is fully used.
  ManagedValue borrow(SILGenFunction &SGF, SILLocation loc) const;

  /// Return a formally evaluated "borrowed" version of this value.
  ManagedValue formalAccessBorrow(SILGenFunction &SGF, SILLocation loc) const;

  ManagedValue unmanagedBorrow() const {
    return isLValue() ? *this : ManagedValue::forUnmanaged(getValue());
  }

  /// Given a scalar value, materialize it into memory with the
  /// exact same level of cleanup it had before.
  ManagedValue materialize(SILGenFunction &SGF, SILLocation loc) const;

  /// Disable the cleanup for this value.
  void forwardCleanup(SILGenFunction &SGF) const;
  
  /// Forward this value, deactivating the cleanup and returning the
  /// underlying value.
  SILValue forward(SILGenFunction &SGF) const;
  
  /// Forward this value into memory by storing it to the given address.
  ///
  /// \param SGF - The SILGenFunction.
  /// \param loc - the AST location to associate with emitted instructions.
  /// \param address - the address to assign to.
  void forwardInto(SILGenFunction &SGF, SILLocation loc, SILValue address);

  /// Forward this value into the given initialization.
  ///
  /// \param SGF - The SILGenFunction.
  /// \param loc - the AST location to associate with emitted instructions.
  /// \param dest - the destination to forward into
  void forwardInto(SILGenFunction &SGF, SILLocation loc, Initialization *dest);
  
  /// Assign this value into memory, destroying the existing
  /// value at the destination address.
  ///
  /// \param SGF - The SILGenFunction.
  /// \param loc - the AST location to associate with emitted instructions.
  /// \param address - the address to assign to.
  void assignInto(SILGenFunction &SGF, SILLocation loc, SILValue address);
  
  explicit operator bool() const {
    // "InContext" is not considered false.
    return bool(getValue()) || valueAndFlag.getInt();
  }

  void dump() const;
  void dump(raw_ostream &os, unsigned indent = 0) const;
  void print(raw_ostream &os) const;
};

/// A ManagedValue which may not be intended to be consumed.
///
/// The invariant is that the cleanup on a ManagedValue that's not
/// meant to be consumed should be free to clear.
///
/// Code which gets a ManagedValue from a ConsumableManagedValue
/// must be careful before handing the MV off to an API.  Many
/// SILGen APIs expect that an MV is +1, but ConsumableManagedValue
/// often traffics in borrowed values.  A value is only +1 if
/// the associated consumption is TakeAlways, but conditional
/// operation should turn TakeOnSuccess consumptions into TakeAlways
/// consumptions on their success path.
class ConsumableManagedValue {
  ManagedValue Value;
  CastConsumptionKind FinalConsumption;

public:
  /// Create an invalid CMV.
  ConsumableManagedValue() = default;

  /// Create a CMV with a specific value and consumption rule.
  /*implicit*/ ConsumableManagedValue(ManagedValue value,
                                      CastConsumptionKind finalConsumption)
    : Value(value), FinalConsumption(finalConsumption) {}

  /// Create a CMV for a value of trivial type.
  static ConsumableManagedValue forUnmanaged(SILValue value) {
    return { ManagedValue::forUnmanaged(value),
             CastConsumptionKind::TakeAlways };
  }

  /// Create a CMV for an owned value.
  static ConsumableManagedValue forOwned(ManagedValue value) {
    return { value, CastConsumptionKind::TakeAlways };
  }

  /// Has this been filled in with meaningful data?
  bool isValid() const { return (bool) Value; }

  bool isOwned() const {
    assert(isValid());
    return FinalConsumption == CastConsumptionKind::TakeAlways;
  }

  /// Return true if there's a cleanup associated with this value.
  bool hasCleanup() const { return Value.hasCleanup(); }
  CleanupHandle getCleanup() const { return Value.getCleanup(); }

  SILType getType() const { return Value.getType(); }
  SILValue getValue() const { return Value.getValue(); }
  ValueOwnershipKind getOwnershipKind() const {
    return Value.getOwnershipKind();
  }

  /// Return a managed value appropriate for the final use of this CMV.
  ManagedValue getFinalManagedValue() const { return Value; }

  /// Get the value as an unmanaged ManagedValue.
  ///
  /// You probably should not be using this; it's here to make it easy
  /// to find code that is probably wrong.
  ManagedValue asUnmanagedValue() const {
    return ManagedValue::forUnmanaged(Value.getValue());
  }

  /// Return the consumption rules appropriate for the final use of
  /// this CMV.
  CastConsumptionKind getFinalConsumption() const { return FinalConsumption; }

  /// Return a managed value that's appropriate for borrowing this
  /// value and promising not to consume it.
  ConsumableManagedValue asBorrowedOperand() const {
    return { asUnmanagedValue(), CastConsumptionKind::CopyOnSuccess };
  }

  /// Return a managed value that's appropriate for copying this value and
  /// always consuming it.
  ConsumableManagedValue copy(SILGenFunction &SGF, SILLocation loc) const {
    return ConsumableManagedValue::forOwned(asUnmanagedValue().copy(SGF, loc));
  }
};

} // namespace Lowering
} // namespace swift

namespace swift {

template <typename To> inline bool isa(const Lowering::ManagedValue &M) {
  return isa<To>(M.getValue());
}

} // end namespace swift

#endif
