//===--- AccessSummaryAnalysis.h - SIL Access Summary Analysis --*- 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
//
//===----------------------------------------------------------------------===//
//
// This file implements an interprocedural analysis pass that summarizes
// the formal accesses that a function makes to its address-type arguments.
// These summaries are used to statically diagnose violations of exclusive
// accesses for noescape closures.
//
//===----------------------------------------------------------------------===//
#ifndef SWIFT_SILOPTIMIZER_ANALYSIS_ACCESS_SUMMARY_ANALYSIS_H_
#define SWIFT_SILOPTIMIZER_ANALYSIS_ACCESS_SUMMARY_ANALYSIS_H_

#include "swift/SIL/SILFunction.h"
#include "swift/SIL/SILInstruction.h"
#include "swift/SILOptimizer/Analysis/BottomUpIPAnalysis.h"
#include "swift/SILOptimizer/Utils/IndexTrie.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"

namespace swift {

class AccessSummaryAnalysis : public BottomUpIPAnalysis {
public:
  class SubAccessSummary {
  private:
    /// The kind of access begun on the argument.
    SILAccessKind Kind;

    /// The location of the access. Used for diagnostics.
    SILLocation AccessLoc = SILLocation((Expr *)nullptr);

    const IndexTrieNode *SubPath = nullptr;

  public:
    SubAccessSummary(SILAccessKind Kind, SILLocation AccessLoc,
                     const IndexTrieNode *SubPath)
        : Kind(Kind), AccessLoc(AccessLoc), SubPath(SubPath) {}

    SILAccessKind getAccessKind() const { return Kind; }

    SILLocation getAccessLoc() const { return AccessLoc; }

    const IndexTrieNode *getSubPath() const { return SubPath; }

    /// The lattice operation on SubAccessSummaries summaries.
    bool mergeWith(const SubAccessSummary &other);

    /// Merge in an access to the argument of the given kind at the given
    /// location with the given suppath. Returns true if the merge caused the
    /// summary to change.
    bool mergeWith(SILAccessKind otherKind, SILLocation otherLoc,
                   const IndexTrieNode *otherSubPath);

    /// Returns a description of the summary. For debugging and testing
    /// purposes.
    std::string getDescription(SILType BaseType, SILModule &M) const;
  };

  typedef llvm::SmallDenseMap<const IndexTrieNode *, SubAccessSummary, 8>
      SubAccessMap;

  /// Summarizes the accesses that a function begins on an argument, including
  /// the projection subpath that was accessed.
  class ArgumentSummary {
  private:
    SubAccessMap SubAccesses;

  public:
    /// The lattice operation on argument summaries.
    bool mergeWith(const ArgumentSummary &other);

    /// Merge in an access to the argument of the given kind at the given
    /// location. Returns true if the merge caused the summary to change.
    bool mergeWith(SILAccessKind otherKind, SILLocation otherLoc,
                   const IndexTrieNode *otherSubPath);

    /// Returns a description of the summary. For debugging and testing
    /// purposes.
    std::string getDescription(SILType BaseType, SILModule &M) const;

    /// Returns the accesses that the function performs to subpaths of the
    /// argument.
    const SubAccessMap &getSubAccesses() const { return SubAccesses; }

    /// Returns the sorted subaccess summaries into the passed-in storage.
    /// The accesses are sorted lexicographically by increasing subpath
    /// length and projection index.
    void getSortedSubAccesses(SmallVectorImpl<SubAccessSummary> &storage) const;
  };

  /// Summarizes the accesses that a function begins on its arguments or
  /// projections from its arguments.
  class FunctionSummary {
  private:
    llvm::SmallVector<ArgumentSummary, 6> ArgAccesses;

  public:
    FunctionSummary(unsigned argCount) : ArgAccesses(argCount) {}

    /// Returns of summary of the the function accesses that argument at the
    /// given index.
    ArgumentSummary &getAccessForArgument(unsigned argument) {
      return ArgAccesses[argument];
    }

    const ArgumentSummary &getAccessForArgument(unsigned argument) const {
      return ArgAccesses[argument];
    }

    /// Returns the number of argument in the summary.
    unsigned getArgumentCount() const { return ArgAccesses.size(); }

    void print(raw_ostream &os, SILFunction *fn) const;
  };

  class FunctionInfo;
  /// Records a flow of a caller's argument to a called function.
  /// This flow is used to iterate the interprocedural analysis to a fixpoint.
  struct ArgumentFlow {
    /// The index of the argument in the caller.
    const unsigned CallerArgumentIndex;

    /// The index of the argument in the callee.
    const unsigned CalleeArgumentIndex;

    FunctionInfo *const CalleeFunctionInfo;
  };

  /// Records the summary and argument flows for a given function.
  /// Used by the BottomUpIPAnalysis to propagate information
  /// from callees to callers.
  class FunctionInfo : public FunctionInfoBase<FunctionInfo> {
  private:
    FunctionSummary FS;

    SILFunction *F;

    llvm::SmallVector<ArgumentFlow, 8> RecordedArgumentFlows;

  public:
    FunctionInfo(SILFunction *F) : FS(F->getArguments().size()), F(F) {}

    SILFunction *getFunction() const { return F; }

    ArrayRef<ArgumentFlow> getArgumentFlows() const {
      return RecordedArgumentFlows;
    }

    const FunctionSummary &getSummary() const { return FS; }
    FunctionSummary &getSummary() { return FS; }

    /// Record a flow of an argument in this function to a callee.
    void recordFlow(const ArgumentFlow &flow) {
      flow.CalleeFunctionInfo->addCaller(this, nullptr);
      RecordedArgumentFlows.push_back(flow);
    }
  };

private:
  /// Maps functions to the information the analysis keeps for each function.
  llvm::DenseMap<SILFunction *, FunctionInfo *> FunctionInfos;

  llvm::SpecificBumpPtrAllocator<FunctionInfo> Allocator;

  /// A trie of integer indices that gives pointer identity to a path of
  /// projections. This is shared between all functions in the module.
  std::unique_ptr<IndexTrieNode> SubPathTrie;

public:
  AccessSummaryAnalysis() : BottomUpIPAnalysis(SILAnalysisKind::AccessSummary) {
    SubPathTrie.reset(new IndexTrieNode());
  }

  /// Returns a summary of the accesses performed by the given function.
  const FunctionSummary &getOrCreateSummary(SILFunction *Fn);

  IndexTrieNode *getSubPathTrieRoot() {
    return SubPathTrie.get();
  }

  /// Returns an IndexTrieNode that represents the single subpath accessed from
  /// BAI or the root if no such node exists.
  const IndexTrieNode *findSubPathAccessed(BeginAccessInst *BAI);

  virtual void initialize(SILPassManager *PM) override {}
  virtual void invalidate() override;
  virtual void invalidate(SILFunction *F, InvalidationKind K) override;
  virtual void notifyAddedOrModifiedFunction(SILFunction *F) override {}
  virtual void notifyWillDeleteFunction(SILFunction *F) override {
    invalidate(F, InvalidationKind::Nothing);
  }
  virtual void invalidateFunctionTables() override {}

  static bool classof(const SILAnalysis *S) {
    return S->getKind() == SILAnalysisKind::AccessSummary;
  }

  /// Returns a description of the subpath suitable for use in diagnostics.
  /// The base type must be the type of the root of the path.
  static std::string getSubPathDescription(SILType BaseType,
                                           const IndexTrieNode *SubPath,
                                           SILModule &M);

  /// Performs a lexicographic comparison of two subpaths, first by path length
  /// and then by index of the last path component. Returns true when lhs
  /// is less than rhs.
  static bool compareSubPaths(const IndexTrieNode *lhs,
                              const IndexTrieNode *rhs);
private:
  typedef BottomUpFunctionOrder<FunctionInfo> FunctionOrder;

  /// Returns the BottomUpIPAnalysis information for the given function.
  FunctionInfo *getFunctionInfo(SILFunction *F);

  /// Summarizes the given function and iterates the interprocedural analysis
  /// to a fixpoint.
  void recompute(FunctionInfo *initial);

  /// Propagate the access summary from the argument of a called function
  /// to the caller.
  bool propagateFromCalleeToCaller(FunctionInfo *callerInfo,
                                   ArgumentFlow site);

  /// Summarize the given function and schedule it for interprocedural
  /// analysis.
  void processFunction(FunctionInfo *info, FunctionOrder &order);

  /// Summarize how the function uses the given argument.
  void processArgument(FunctionInfo *info, SILFunctionArgument *argment,
                        ArgumentSummary &summary, FunctionOrder &order);

  /// Summarize a partial_apply instruction.
  void processPartialApply(FunctionInfo *callerInfo,
                           unsigned callerArgumentIndex,
                           PartialApplyInst *apply,
                           Operand *applyArgumentOperand, FunctionOrder &order);

  /// Summarize apply or try_apply
  void processFullApply(FunctionInfo *callerInfo, unsigned callerArgumentIndex,
                        FullApplySite apply, Operand *argumentOperand,
                        FunctionOrder &order);

  /// Summarize a call site and schedule it for interprocedural analysis.
  void processCall(FunctionInfo *callerInfo, unsigned callerArgumentIndex,
                   SILFunction *calledFunction, unsigned argumentIndex,
                   FunctionOrder &order);
};

} // end namespace swift

#endif

