//===--- polly/DependenceInfo.h - Polyhedral dependency analysis *- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Calculate the data dependency relations for a Scop using ISL.
//
// The integer set library (ISL) from Sven has an integrated dependency analysis
// to calculate data dependences. This pass takes advantage of this and
// calculates those dependences of a Scop.
//
// The dependences in this pass are exact in terms that for a specific read
// statement instance only the last write statement instance is returned. In
// case of may-writes, a set of possible write instances is returned. This
// analysis will never produce redundant dependences.
//
//===----------------------------------------------------------------------===//

#ifndef POLLY_DEPENDENCE_INFO_H
#define POLLY_DEPENDENCE_INFO_H

#include "polly/ScopPass.h"
#include "isl/ctx.h"

struct isl_pw_aff;
struct isl_union_map;
struct isl_union_set;
struct isl_map;
struct isl_set;
struct clast_for;

using namespace llvm;

namespace polly {

class Scop;
class ScopStmt;
class MemoryAccess;

/// The accumulated dependence information for a SCoP.
///
/// The Dependences struct holds all dependence information we collect and
/// compute for one SCoP. It also offers an interface that allows users to
/// query only specific parts.
struct Dependences {
  // Granularities of the current dependence analysis
  enum AnalysisLevel {
    AL_Statement = 0,
    // Distinguish accessed memory references in the same statement
    AL_Reference,
    // Distinguish memory access instances in the same statement
    AL_Access,

    NumAnalysisLevels
  };

  /// Map type for reduction dependences.
  using ReductionDependencesMapTy = DenseMap<MemoryAccess *, isl_map *>;

  /// Map type to associate statements with schedules.
  using StatementToIslMapTy = DenseMap<ScopStmt *, isl_map *>;

  /// The type of the dependences.
  ///
  /// Reduction dependences are separated from RAW/WAW/WAR dependences because
  /// we can ignore them during the scheduling. That's because the order
  /// in which the reduction statements are executed does not matter. However,
  /// if they are executed in parallel we need to take additional measures
  /// (e.g, privatization) to ensure a correct result. The (reverse) transitive
  /// closure of the reduction dependences are used to check for parallel
  /// executed reduction statements during code generation. These dependences
  /// connect all instances of a reduction with each other, they are therefore
  /// cyclic and possibly "reversed".
  enum Type {
    // Write after read
    TYPE_WAR = 1 << 0,

    // Read after write
    TYPE_RAW = 1 << 1,

    // Write after write
    TYPE_WAW = 1 << 2,

    // Reduction dependences
    TYPE_RED = 1 << 3,

    // Transitive closure of the reduction dependences (& the reverse)
    TYPE_TC_RED = 1 << 4,
  };

  const std::shared_ptr<isl_ctx> &getSharedIslCtx() const { return IslCtx; }

  /// Get the dependences of type @p Kinds.
  ///
  /// @param Kinds This integer defines the different kinds of dependences
  ///              that will be returned. To return more than one kind, the
  ///              different kinds are 'ored' together.
  __isl_give isl_union_map *getDependences(int Kinds) const;

  /// Report if valid dependences are available.
  bool hasValidDependences() const;

  /// Return the reduction dependences caused by @p MA.
  ///
  /// @return The reduction dependences caused by @p MA or nullptr if none.
  __isl_give isl_map *getReductionDependences(MemoryAccess *MA) const;

  /// Return all reduction dependences.
  const ReductionDependencesMapTy &getReductionDependences() const {
    return ReductionDependences;
  }

  /// Check if a partial schedule is parallel wrt to @p Deps.
  ///
  /// @param Schedule       The subset of the schedule space that we want to
  ///                       check.
  /// @param Deps           The dependences @p Schedule needs to respect.
  /// @param MinDistancePtr If not nullptr, the minimal dependence distance will
  ///                       be returned at the address of that pointer
  ///
  /// @return Returns true, if executing parallel the outermost dimension of
  ///         @p Schedule is valid according to the dependences @p Deps.
  bool isParallel(__isl_keep isl_union_map *Schedule,
                  __isl_take isl_union_map *Deps,
                  __isl_give isl_pw_aff **MinDistancePtr = nullptr) const;

  /// Check if a new schedule is valid.
  ///
  /// @param S             The current SCoP.
  /// @param NewSchedules  The new schedules
  ///
  /// @return True if the new schedule is valid, false if it reverses
  ///         dependences.
  bool isValidSchedule(Scop &S, StatementToIslMapTy *NewSchedules) const;

  /// Print the stored dependence information.
  void print(llvm::raw_ostream &OS) const;

  /// Dump the dependence information stored to the dbgs stream.
  void dump() const;

  /// Return the granularity of this dependence analysis.
  AnalysisLevel getDependenceLevel() { return Level; }

  /// Allow the DependenceInfo access to private members and methods.
  ///
  /// To restrict access to the internal state, only the DependenceInfo class
  /// is able to call or modify a Dependences struct.
  friend struct DependenceAnalysis;
  friend struct DependenceInfoPrinterPass;
  friend class DependenceInfo;
  friend class DependenceInfoWrapperPass;

  /// Destructor that will free internal objects.
  ~Dependences() { releaseMemory(); }

private:
  /// Create an empty dependences struct.
  explicit Dependences(const std::shared_ptr<isl_ctx> &IslCtx,
                       AnalysisLevel Level)
      : RAW(nullptr), WAR(nullptr), WAW(nullptr), RED(nullptr), TC_RED(nullptr),
        IslCtx(IslCtx), Level(Level) {}

  /// Calculate and add at the privatization dependences.
  void addPrivatizationDependences();

  /// Calculate the dependences for a certain SCoP @p S.
  void calculateDependences(Scop &S);

  /// Set the reduction dependences for @p MA to @p Deps.
  void setReductionDependences(MemoryAccess *MA, __isl_take isl_map *Deps);

  /// Free the objects associated with this Dependences struct.
  ///
  /// The Dependences struct will again be "empty" afterwards.
  void releaseMemory();

  /// The different basic kinds of dependences we calculate.
  isl_union_map *RAW;
  isl_union_map *WAR;
  isl_union_map *WAW;

  /// The special reduction dependences.
  isl_union_map *RED;

  /// The (reverse) transitive closure of reduction dependences.
  isl_union_map *TC_RED;

  /// Mapping from memory accesses to their reduction dependences.
  ReductionDependencesMapTy ReductionDependences;

  /// Isl context from the SCoP.
  std::shared_ptr<isl_ctx> IslCtx;

  /// Granularity of this dependence analysis.
  const AnalysisLevel Level;
};

struct DependenceAnalysis : public AnalysisInfoMixin<DependenceAnalysis> {
  static AnalysisKey Key;
  struct Result {
    Scop &S;
    std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];

    /// Return the dependence information for the current SCoP.
    ///
    /// @param Level The granularity of dependence analysis result.
    ///
    /// @return The dependence analysis result
    ///
    const Dependences &getDependences(Dependences::AnalysisLevel Level);

    /// Recompute dependences from schedule and memory accesses.
    const Dependences &recomputeDependences(Dependences::AnalysisLevel Level);
  };
  Result run(Scop &S, ScopAnalysisManager &SAM,
             ScopStandardAnalysisResults &SAR);
};

struct DependenceInfoPrinterPass
    : public PassInfoMixin<DependenceInfoPrinterPass> {
  DependenceInfoPrinterPass(raw_ostream &OS) : OS(OS) {}

  PreservedAnalyses run(Scop &S, ScopAnalysisManager &,
                        ScopStandardAnalysisResults &, SPMUpdater &);

  raw_ostream &OS;
};

class DependenceInfo : public ScopPass {
public:
  static char ID;

  /// Construct a new DependenceInfo pass.
  DependenceInfo() : ScopPass(ID) {}

  /// Return the dependence information for the current SCoP.
  ///
  /// @param Level The granularity of dependence analysis result.
  ///
  /// @return The dependence analysis result
  ///
  const Dependences &getDependences(Dependences::AnalysisLevel Level);

  /// Recompute dependences from schedule and memory accesses.
  const Dependences &recomputeDependences(Dependences::AnalysisLevel Level);

  /// Compute the dependence information for the SCoP @p S.
  bool runOnScop(Scop &S) override;

  /// Print the dependences for the given SCoP to @p OS.
  void printScop(raw_ostream &OS, Scop &) const override;

  /// Release the internal memory.
  void releaseMemory() override {
    for (auto &d : D)
      d.reset();
  }

  /// Register all analyses and transformation required.
  void getAnalysisUsage(AnalysisUsage &AU) const override;

private:
  Scop *S;

  /// Dependences struct for the current SCoP.
  std::unique_ptr<Dependences> D[Dependences::NumAnalysisLevels];
};

/// Construct a new DependenceInfoWrapper pass.
class DependenceInfoWrapperPass : public FunctionPass {
public:
  static char ID;

  /// Construct a new DependenceInfoWrapper pass.
  DependenceInfoWrapperPass() : FunctionPass(ID) {}

  /// Return the dependence information for the given SCoP.
  ///
  /// @param S     SCoP object.
  /// @param Level The granularity of dependence analysis result.
  ///
  /// @return The dependence analysis result
  ///
  const Dependences &getDependences(Scop *S, Dependences::AnalysisLevel Level);

  /// Recompute dependences from schedule and memory accesses.
  const Dependences &recomputeDependences(Scop *S,
                                          Dependences::AnalysisLevel Level);

  /// Compute the dependence information on-the-fly for the function.
  bool runOnFunction(Function &F) override;

  /// Print the dependences for the current function to @p OS.
  void print(raw_ostream &OS, const Module *M = nullptr) const override;

  /// Release the internal memory.
  void releaseMemory() override { ScopToDepsMap.clear(); }

  /// Register all analyses and transformation required.
  void getAnalysisUsage(AnalysisUsage &AU) const override;

private:
  using ScopToDepsMapTy = DenseMap<Scop *, std::unique_ptr<Dependences>>;

  /// Scop to Dependence map for the current function.
  ScopToDepsMapTy ScopToDepsMap;
};

} // namespace polly

namespace llvm {
class PassRegistry;
void initializeDependenceInfoPass(llvm::PassRegistry &);
void initializeDependenceInfoWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm

#endif
