//===--- EnumPayload.h - Payload management for 'enum' Types ----*- 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
//
//===----------------------------------------------------------------------===//

#ifndef SWIFT_IRGEN_ENUMPAYLOAD_H
#define SWIFT_IRGEN_ENUMPAYLOAD_H

#include "IRGenModule.h"
#include "Explosion.h"
#include "TypeInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/ADT/PointerEmbeddedInt.h"
#include "llvm/ADT/PointerUnion.h"
#include <utility>

namespace swift {
namespace irgen {
  
/// A description of how to represent an enum payload as a value.
/// A payload can either use a generic word-chunked representation, or attempt
/// to follow the explosion schema of one of its payload types.
class EnumPayloadSchema {
  using BitSizeTy = llvm::PointerEmbeddedInt<unsigned, 31>;

  const llvm::PointerUnion<ExplosionSchema *, BitSizeTy> Value;

public:
  EnumPayloadSchema() : Value((ExplosionSchema *)nullptr) {}

  explicit operator bool() {
    return Value.getOpaqueValue() != nullptr;
  }

  explicit EnumPayloadSchema(unsigned bits)
    : Value(BitSizeTy(bits)) {}

  EnumPayloadSchema(ExplosionSchema &s)
    : Value(&s) {}

  static EnumPayloadSchema withBitSize(unsigned bits) {
    return EnumPayloadSchema(bits);
  }
  
  ExplosionSchema *getSchema() const {
    return Value.dyn_cast<ExplosionSchema*>();
  }
  
  /// Invoke a functor for each element type in the schema.
  template<typename TypeFn /* void(llvm::Type *schemaType) */>
  void forEachType(IRGenModule &IGM, TypeFn &&fn) const {
    // Follow an explosion schema if we have one.
    if (auto *explosion = Value.dyn_cast<ExplosionSchema *>()) {
      for (auto &element : *explosion) {
        auto type = element.getScalarType();
        assert(IGM.DataLayout.getTypeSizeInBits(type)
                 == IGM.DataLayout.getTypeAllocSizeInBits(type)
               && "enum payload schema elements should use full alloc size");
        (void) type;
        fn(element.getScalarType());
      }
      return;
    }
    
    // Otherwise, chunk into pointer-sized integer values by default.
    unsigned bitSize = Value.get<BitSizeTy>();
    unsigned pointerSize = IGM.getPointerSize().getValueInBits();
    
    while (bitSize >= pointerSize) {
      fn(IGM.SizeTy);
      bitSize -= pointerSize;
    }
    if (bitSize > 0)
      fn(llvm::IntegerType::get(IGM.getLLVMContext(), bitSize));
  }
};

/// Is a switch default destination unreachable?
enum IsUnreachable_t: bool {
  IsNotUnreachable = false,
  IsUnreachable = true,
};

using SwitchDefaultDest
  = llvm::PointerIntPair<llvm::BasicBlock*, 1, IsUnreachable_t>;

/// An enum payload value. The payload is represented as an explosion of
/// integers and pointers that together represent the bit pattern of
/// the payload.
class EnumPayload {
public:
  /// A value, or the type of a zero value in the payload.
  using LazyValue = llvm::PointerUnion<llvm::Value *, llvm::Type *>;
  
  mutable SmallVector<LazyValue, 2> PayloadValues;
  mutable llvm::Type *StorageType = nullptr;
  
  EnumPayload() = default;

  /// Generate a "zero" enum payload.
  static EnumPayload zero(IRGenModule &IGM,
                          EnumPayloadSchema schema);

  /// Generate an enum payload containing the given bit pattern.
  static EnumPayload fromBitPattern(IRGenModule &IGM,
                                    APInt bitPattern,
                                    EnumPayloadSchema schema);
  
  /// Insert a value into the enum payload.
  ///
  /// The current payload value at the given offset is assumed to be zero.
  /// If \p numBitsUsedInValue is non-negative denotes the actual number of bits
  /// that need storing in \p value otherwise the full bit-width of \p value
  /// will be stored.
  void insertValue(IRGenFunction &IGF,
                   llvm::Value *value, unsigned bitOffset,
                   int numBitsUsedInValue = -1);
  
  /// Extract a value from the enum payload.
  llvm::Value *extractValue(IRGenFunction &IGF,
                            llvm::Type *type, unsigned bitOffset) const;
  
  /// Take an enum payload out of an explosion.
  static EnumPayload fromExplosion(IRGenModule &IGM,
                                   Explosion &in,
                                   EnumPayloadSchema schema);
  
  /// Add the payload to an explosion.
  void explode(IRGenModule &IGM, Explosion &out) const;
  
  /// Pack into another enum payload.
  void packIntoEnumPayload(IRGenFunction &IGF,
                           EnumPayload &dest,
                           unsigned bitOffset) const;
  
  /// Unpack from another enum payload.
  static EnumPayload unpackFromEnumPayload(IRGenFunction &IGF,
                                           const EnumPayload &src,
                                           unsigned bitOffset,
                                           EnumPayloadSchema schema);
  
  /// Load an enum payload from memory.
  static EnumPayload load(IRGenFunction &IGF, Address address,
                          EnumPayloadSchema schema);
  
  /// Store an enum payload to memory.
  void store(IRGenFunction &IGF, Address address) const;

  /// Emit a switch over specific bit patterns for the payload.
  /// The value will be tested as if AND-ed against the given mask.
  void emitSwitch(IRGenFunction &IGF,
                  APInt mask,
                  ArrayRef<std::pair<APInt, llvm::BasicBlock*>> cases,
                  SwitchDefaultDest dflt) const;
  
  /// Emit an equality comparison operation that payload & mask == value.
  llvm::Value *emitCompare(IRGenFunction &IGF,
                           APInt mask,
                           APInt value) const;
  
  /// Apply an AND mask to the payload.
  void emitApplyAndMask(IRGenFunction &IGF, APInt mask);
  
  /// Apply an OR mask to the payload.
  void emitApplyOrMask(IRGenFunction &IGF, APInt mask);
  
  /// Apply an OR mask to the payload.
  void emitApplyOrMask(IRGenFunction &IGF, EnumPayload mask);
  
  /// Gather bits from an enum payload based on a spare bit mask.
  llvm::Value *emitGatherSpareBits(IRGenFunction &IGF,
                                   const SpareBitVector &spareBits,
                                   unsigned firstBitOffset,
                                   unsigned bitWidth) const;
};
  
}
}

#endif
