//===--- SILOpenedArchetypesTracker.h - Track opened archetypes -*- 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_SIL_SILOPENEDARCHETYPESTRACKER_H
#define SWIFT_SIL_SILOPENEDARCHETYPESTRACKER_H

#include "swift/SIL/Notifications.h"
#include "swift/SIL/SILModule.h"
#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILUndef.h"

namespace swift {

/// SILOpenedArchetypesTracker is a helper class that can be used to create
/// and maintain a mapping from opened archetypes to instructions
/// defining them, e.g. open_existential_ref, open_existential_addr,
/// open_existential_metatype.
///
/// This information is useful for representing and maintaining the
/// dependencies of instructions on opened archetypes they are using.
///
/// The intended clients of this class are SILGen, SIL deserializers, etc.
class SILOpenedArchetypesTracker : public DeleteNotificationHandler {
public:
  using OpenedArchetypeDefsMap =
    llvm::DenseMap<ArchetypeType*, SingleValueInstruction*>;

  SILOpenedArchetypesTracker(SILOpenedArchetypesTracker &Tracker)
      : SILOpenedArchetypesTracker(Tracker.F, Tracker) {}

  // Re-use pre-populated map if available.
  SILOpenedArchetypesTracker(const SILFunction *F,
                             SILOpenedArchetypesTracker &Tracker)
      : F(F), OpenedArchetypeDefs(Tracker.OpenedArchetypeDefs) { }

  // Re-use pre-populated map if available.
  SILOpenedArchetypesTracker(const SILFunction *F,
                             OpenedArchetypeDefsMap &OpenedArchetypeDefs)
      : F(F), OpenedArchetypeDefs(OpenedArchetypeDefs) { }

  // Use its own local map if no pre-populated map is provided.
  SILOpenedArchetypesTracker(const SILFunction *F)
      : F(F), OpenedArchetypeDefs(LocalOpenedArchetypeDefs) { }


  const SILFunction *getFunction() const {
    assert(F && "no function context available");
    return F;
  }

  // Register a definition of a given opened archetype.
  void addOpenedArchetypeDef(CanArchetypeType archetype,
                             SingleValueInstruction *def);

  // Return the SILInstruciton* defining a given archetype.
  // If the defining value is not known, return a null instruction.
  SingleValueInstruction *
  getOpenedArchetypeDef(CanArchetypeType archetype) const {
    return OpenedArchetypeDefs.lookup(archetype);
  }

  const OpenedArchetypeDefsMap &getOpenedArchetypeDefs() const {
    return OpenedArchetypeDefs;
  }

  // Register archetypes opened by a given instruction.
  // Can be used to incrementally populate the mapping, e.g.
  // if it is done when performing a scan of all instructions
  // inside a function.
  // Returns true if any opened archetypes were registered.
  bool registerOpenedArchetypes(const SILInstruction *I);

  // Register opened archetypes whose definitions are referenced by
  // the typedef operands of this instruction.
  // Returns true if any opened archetypes were registered.
  bool registerUsedOpenedArchetypes(const SILInstruction *I);

  // Register opened archetypes referenced by this type, if they
  // are not registered yet. Create placeholders representing forward
  // definitions of these opened archetypes.
  // Returns true if any opened archetypes were registered.
  bool registerUsedOpenedArchetypes(CanType Ty);

  // Unregister archetypes opened by a given instruction.
  // Should be only called when this instruction is to be removed.
  void unregisterOpenedArchetypes(const SILInstruction *I);

  // Returns true of some of the forward opened archetype definitions
  // are unresolved.
  bool hasUnresolvedOpenedArchetypeDefinitions();

  // Handling of instruction removal notifications.
  bool needsNotifications() { return true; }

  // Handle notifications about removals of instructions.
  void handleDeleteNotification(SILNode *node);

  // Dump the contents.
  void dump() const;

  virtual ~SILOpenedArchetypesTracker() {
    // Unregister the handler.
    if (F)
      F->getModule().removeDeleteNotificationHandler(this);
  }

private:
  // Never copy
  SILOpenedArchetypesTracker &operator = (const SILOpenedArchetypesTracker &) = delete;
  /// The function whose opened archetypes are being tracked.
  /// Used only for verification purposes.
  const SILFunction *F;

  /// Mapping from opened archetypes to their definitions.
  OpenedArchetypeDefsMap &OpenedArchetypeDefs;
  /// Local map to be used if no other map was provided in the
  /// constructor.
  OpenedArchetypeDefsMap LocalOpenedArchetypeDefs;
};

// A state object containing information about opened archetypes.
// This information can be used by constructors of SILInstructions,
// their create methods, etc.
// The object can be configured to use different sources for providing
// archetypes, but none of those archetype sets can be modified through
// this object, which makes it essentially immutable.
class SILOpenedArchetypesState {
  // A set of opened archetypes operands for quick lookup.
  // It usually provides opened archetypes operands of the
  // instruction being currently processed.
  ArrayRef<Operand> OpenedArchetypeOperands;
  // A non-modifiable mapping provided by the tracker.
  const SILOpenedArchetypesTracker *OpenedArchetypesTracker;
public:
  SILOpenedArchetypesState(const SILOpenedArchetypesTracker *Tracker = nullptr)
      : OpenedArchetypesTracker(Tracker) {}

  SILOpenedArchetypesState(const SILOpenedArchetypesTracker &Tracker)
      : OpenedArchetypesTracker(&Tracker) { }

  void setOpenedArchetypesTracker(const SILOpenedArchetypesTracker *Tracker) {
    OpenedArchetypesTracker = Tracker;
  }

  void addOpenedArchetypeOperands(ArrayRef<Operand> Operands) {
    OpenedArchetypeOperands = Operands;
  }

  const SILOpenedArchetypesTracker *getOpenedArchetypesTracker() const {
    return OpenedArchetypesTracker;
  }

  /// Lookup the instruction defining an opened archetype by first 
  /// performing a quick lookup in the opened archetypes operands
  /// and then in the opened archetypes tracker.
  SILValue getOpenedArchetypeDef(CanArchetypeType archetypeTy) const;

  // Dump the contents.
  void dump() const;
};

/// Find an opened archetype defined by an instruction.
/// \returns The found archetype or empty type otherwise.
CanArchetypeType getOpenedArchetypeOf(const SILInstruction *I);

/// Find an opened archetype represented by this type.
/// It is assumed by this method that the type contains
/// at most one opened archetype.
/// Typically, it would be called from a type visitor.
/// It checks only the type itself, but does not try to
/// recursively check any children of this type, because
/// this is the task of the type visitor invoking it.
/// \returns The found archetype or empty type otherwise.
CanArchetypeType getOpenedArchetypeOf(CanType Ty);

} // end swift namespace
#endif
