//===--- RValue.h - Exploded RValue Representation --------------*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2018 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
//
//===----------------------------------------------------------------------===//
///
/// \file
///
/// 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_RVALUE_H
#define SWIFT_LOWERING_RVALUE_H

#include "ManagedValue.h"
#include "swift/Basic/NullablePtr.h"
#include "llvm/ADT/SmallVector.h"

namespace swift {
namespace Lowering {

class ArgumentSource;
class Initialization;
class Scope;
class SILGenFunction;
class TypeLowering;

/// An "exploded" SIL rvalue, in which tuple values are recursively
/// destructured.
///
/// In terms of implementation, an RValue is a collection of ManagedValues that
/// the RValue class allows to be worked with as if they were one tuple. This
/// allows for tuples to represent tuples without needing to canonicalize into
/// the actual tuple value.
///
/// Once constructed, RValues obey the following invariants:
///
///   1. All non-trivially typed sub-ManagedValues must consistently have
///   cleanups. This is verified upon construction of an RValue.
///
///   2. All sub-ManagedValues with non-trivial ValueOwnershipKind must have the
///   same ValueOwnershipKind. There is a subtle thing occuring here. Since all
///   addresses are viewed from an ownership perspective as having trivial
///   ownership, this causes the verification to ignore address only
///   values. Once we transition to opaque values, the verification will
///   proceed.
///
///   3. All loadable sub-ManagedValues of an RValue must be of object
///   type. This means that if the lowered type of an RValue is loadable, then
///   the RValue's sub-parts must also be objects (i.e. not
///   addresses). Originally this was a hard invariant of RValue constructors,
///   but some parts of ArgEmission pass in addresses for loadable values. So
///   RValue loads them in the constructor.
///
///  FIXME(opaque_values): Update invariant #2 once address only types are no
///  longer emitted by SILGen.
///
/// *NOTE* In SILGen we don't try to explode structs, because doing so would
/// require considering resilience, a job we want to delegate to IRGen.
class RValue {
  friend class swift::Lowering::Scope;
  friend class swift::Lowering::ArgumentSource;

  std::vector<ManagedValue> values;
  CanType type;
  unsigned elementsToBeAdded;
  
  /// Flag value used to mark an rvalue as invalid.
  ///
  /// The reasons why this can be true is:
  ///
  /// 1. The RValue was consumed.
  /// 2. The RValue was default-initialized.
  /// 3. The RValue was emitted into an SGFContext initialization.
  enum : unsigned {
    Null = ~0U,
    Used = Null - 1,
    InContext = Used - 1,
  };

  bool isInSpecialState() const {
    return elementsToBeAdded >= InContext;
  }
  
  // Don't copy.
  RValue(const RValue &) = delete;
  RValue &operator=(const RValue &) = delete;
  
  void makeUsed() {
    elementsToBeAdded = Used;
    values = {};
  }

  /// Private constructor used by copy() and borrow().
  RValue(SILGenFunction &SGF, std::vector<ManagedValue> &&values, CanType type,
         unsigned elementsToBeAdded)
      : values(std::move(values)), type(type),
        elementsToBeAdded(elementsToBeAdded) {
    verify(SGF);
  }

  /// Private constructor for RValue::extractElement and pre-exploded element
  /// constructor.
  ///
  /// If SGF is nullptr, this constructor assumes that it is passed a
  /// pre-exploded set of ManagedValues that have already been verified as being
  /// RValue compatible since they once made up an RValue. If SGF is non-null,
  /// then we verify as well that all objects of loadable type are actually
  /// loaded (i.e. are objects).
  ///
  /// *NOTE* This constructor assumes that the constructed RValue is fully
  /// formed and thus has elementsToBeAdded set to zero.
  RValue(SILGenFunction *SGF, ArrayRef<ManagedValue> values, CanType type);

  RValue(unsigned state) : elementsToBeAdded(state) {
    assert(isInSpecialState());
  }

public:
  RValue() : elementsToBeAdded(Null) {}
  
  RValue(RValue &&rv) : values(std::move(rv.values)),
                        type(rv.type),
                        elementsToBeAdded(rv.elementsToBeAdded) {
    assert((rv.isComplete() || rv.isInSpecialState())
           && "moving rvalue that wasn't complete?!");
    rv.elementsToBeAdded = Used;
  }

  RValue &operator=(RValue &&rv) {
    assert((isNull() || isUsed()) && "reassigning an valid rvalue?!");
    
    assert((rv.isComplete() || rv.isInSpecialState())
           && "moving rvalue that wasn't complete?!");
    values = std::move(rv.values);
    type = rv.type;
    elementsToBeAdded = rv.elementsToBeAdded;
    rv.elementsToBeAdded = Used;
    return *this;
  }
  
  /// Create an RValue from a single value. If the value is of tuple type, it
  /// will be exploded.
  ///
  /// \param expr - the expression which yielded this r-value; its type
  ///   will become the substituted formal type of this r-value
  RValue(SILGenFunction &SGF, Expr *expr, ManagedValue v);

  /// Create an RValue from a single value. If the value is of tuple type, it
  /// will be exploded.
  RValue(SILGenFunction &SGF, SILLocation l, CanType type, ManagedValue v);

  /// Create a complete RValue from a pre-exploded set of elements.
  ///
  /// Since the RValue is assumed to be complete, no further values can be
  /// added.
  RValue(SILGenFunction &SGF, ArrayRef<ManagedValue> values, CanType type)
      : RValue(&SGF, values, type) {}

  /// Creates an invalid RValue object, in an "in-context" state.
  static RValue forInContext() {
    return RValue(InContext);
  }

  static unsigned getRValueSize(CanType substType);
  static unsigned getRValueSize(AbstractionPattern origType, CanType substType);
  
  /// Create an RValue to which values will be subsequently added using
  /// addElement(), with the level of tuple expansion in the input specified
  /// by the abstraction pattern. The RValue will not be complete until all
  /// the elements have been added.
  explicit RValue(AbstractionPattern pattern, CanType type);
  
  /// Create an RValue to which values will be subsequently added using
  /// addElement(). The RValue will not be complete until all the elements have
  /// been added.
  explicit RValue(CanType type);

  /// Return true if the rvalue was null-initialized. The intention is so one
  /// can trampoline RValue results using if statements, i.e.:
  ///
  /// if (RValue rv = foo()) {
  ///   return rv;
  /// }
  operator bool() const & { return isComplete() || isInContext(); }

  /// True if the rvalue has been completely initialized by adding all its
  /// elements.
  bool isComplete() const & { return elementsToBeAdded == 0; }

  /// True if the rvalue was null-initialized.
  bool isNull() const & { return elementsToBeAdded == Null; }
  
  /// True if this rvalue has been used.
  bool isUsed() const & { return elementsToBeAdded == Used; }

  /// True if this rvalue was emitted into context.
  bool isInContext() const & { return elementsToBeAdded == InContext; }
  
  /// Add an element to the rvalue. The rvalue must not yet be complete.
  void addElement(RValue &&element) &;
  
  /// Add a ManagedValue element to the rvalue, exploding tuples if necessary.
  /// The rvalue must not yet be complete.
  void addElement(SILGenFunction &SGF, ManagedValue element,
                  CanType formalType, SILLocation l) &;
  
  /// Forward an rvalue into a single value, imploding tuples if necessary.
  SILValue forwardAsSingleValue(SILGenFunction &SGF, SILLocation l) &&;

  /// Forward an rvalue into a single value, imploding tuples if necessary, and
  /// introducing a potential conversion from semantic type to storage type.
  SILValue forwardAsSingleStorageValue(SILGenFunction &SGF,
                                       SILType storageType,
                                       SILLocation l) &&;

  /// Get the rvalue as a single value, imploding tuples if necessary.
  ManagedValue getAsSingleValue(SILGenFunction &SGF, SILLocation l) &&;
  
  /// Get the rvalue as a single unmanaged value, imploding tuples if necessary.
  /// The values must not require any cleanups.
  SILValue getUnmanagedSingleValue(SILGenFunction &SGF, SILLocation l) const &;

  ManagedValue getScalarValue() && {
    assert(!isa<TupleType>(type) && "getScalarValue of a tuple rvalue");
    assert(values.size() == 1);
    auto value = values[0];
    makeUsed();
    return value;
  }

  /// Returns true if this is an rvalue that can be used safely as a +1 rvalue.
  ///
  /// This returns true iff:
  ///
  /// 1. All sub-values are trivially typed.
  /// 2. There exists at least one non-trivial typed sub-value and all such
  /// sub-values all have cleanups.
  ///
  /// *NOTE* Due to 1. isPlusOne and isPlusZero both return true for rvalues
  /// consisting of only trivial values.
  bool isPlusOne(SILGenFunction &SGF) const &;

  /// Returns true if this is an rvalue that can be used safely as a +0 rvalue.
  ///
  /// Specifically, we return true if:
  ///
  /// 1. All sub-values are trivially typed.
  /// 2. At least 1 subvalue is non-trivial and all such non-trivial values do
  /// not have a cleanup.
  ///
  /// *NOTE* Due to 1. isPlusOne and isPlusZero both return true for rvalues
  /// consisting of only trivial values.
  bool isPlusZero(SILGenFunction &SGF) const &;

  /// Use this rvalue to initialize an Initialization.
  void forwardInto(SILGenFunction &SGF, SILLocation loc, Initialization *I) &&;

  /// Copy this rvalue to initialize an Initialization without consuming the
  /// rvalue.
  void copyInto(SILGenFunction &SGF, SILLocation loc, Initialization *I) const&;

  /// Assign this r-value into the destination.
  void assignInto(SILGenFunction &SGF, SILLocation loc, SILValue destAddr) &&;
  
  /// Forward the exploded SILValues into a SmallVector.
  void forwardAll(SILGenFunction &SGF,
                  SmallVectorImpl<SILValue> &values) &&;

  ManagedValue materialize(SILGenFunction &SGF, SILLocation loc) &&;
  
  /// Take the ManagedValues from this RValue into a SmallVector.
  void getAll(SmallVectorImpl<ManagedValue> &values) &&;
  
  /// Store the unmanaged SILValues into a SmallVector. The values must not
  /// require any cleanups.
  void getAllUnmanaged(SmallVectorImpl<SILValue> &values) const &;
  
  /// Extract a single tuple element from the rvalue.
  RValue extractElement(unsigned element) &&;
  
  /// Extract the tuple elements from the rvalue.
  void extractElements(SmallVectorImpl<RValue> &elements) &&;
  
  CanType getType() const & { return type; }

  /// Return the lowered type associated with the given CanType's type lowering.
  SILType getLoweredType(SILGenFunction &SGF) const &;

  /// Return the type lowering of RValue::getType().
  const Lowering::TypeLowering &getTypeLowering(SILGenFunction &SGF) const &;

  /// Return the lowered SILType that would be used to implode the given RValue
  /// into 1 tuple value.
  ///
  /// This means that if any sub-objects are address only, an address type will
  /// be returned. Otherwise, an object will be returned. So this is a
  /// convenient way to determine if an RValue needs an address.
  SILType getLoweredImplodedTupleType(SILGenFunction &SGF) const &;
  
  /// Emit an equivalent value with independent ownership.
  RValue copy(SILGenFunction &SGF, SILLocation loc) const &;

  /// If this RValue is a +0 value, copy the RValue and return. Otherwise,
  /// return std::move(*this);
  RValue ensurePlusOne(SILGenFunction &SGF, SILLocation loc) &&;

  /// Borrow all subvalues of the rvalue.
  RValue borrow(SILGenFunction &SGF, SILLocation loc) const &;

  RValue copyForDiagnostics() const;

  static bool areObviouslySameValue(SILValue lhs, SILValue rhs);
  bool isObviouslyEqual(const RValue &rhs) const;

  void dump() const;
  void dump(raw_ostream &OS, unsigned indent = 0) const;

  /// Verify RValue invariants.
  ///
  /// This checks ownership invariants and also checks that all sub managed
  /// values that are loadable are actually objects.
  ///
  /// *NOTE* This is a no-op in non-assert builds.
  void verify(SILGenFunction &SGF) const &;
};

} // end namespace Lowering
} // end namespace swift

#endif
