//===--- EnumPayload.h - Payload management for 'enum' Types ----*- C++ -*-===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://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
