//===--- polly/DependenceInfo.h - Polyhedral dependency analysis *- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// 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"
#include "isl/isl-noexceptions.h"

namespace polly {

/// 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.
class Dependences final {
public:
  // 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::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, const StatementToIslMapTy &NewSchedules) const;

  /// Return true of the schedule @p NewSched is a schedule for @S that does not
  /// violate any dependences.
  bool isValidSchedule(Scop &S, isl::schedule NewSched) 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 final : 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);

    /// Invalidate the dependence information and recompute it when needed
    /// again.
    /// May be required when the underlaying Scop was changed in a way that
    /// would add new dependencies (e.g. between new statement instances
    /// insierted into the SCoP) or intentionally breaks existing ones. It is
    /// not required when updating the schedule that conforms the existing
    /// dependencies.
    void abandonDependences();
  };
  Result run(Scop &S, ScopAnalysisManager &SAM,
             ScopStandardAnalysisResults &SAR);
};

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

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

  raw_ostream &OS;
};

class DependenceInfo final : 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);

  /// Invalidate the dependence information and recompute it when needed again.
  /// May be required when the underlaying Scop was changed in a way that would
  /// add new dependencies (e.g. between new statement instances insierted into
  /// the SCoP) or intentionally breaks existing ones. It is not required when
  /// updating the schedule that conforms the existing dependencies.
  void abandonDependences();

  /// 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];
};

llvm::Pass *createDependenceInfoPass();
llvm::Pass *createDependenceInfoPrinterLegacyPass(llvm::raw_ostream &OS);

/// Construct a new DependenceInfoWrapper pass.
class DependenceInfoWrapperPass final : 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;
};

llvm::Pass *createDependenceInfoWrapperPassPass();
llvm::Pass *
createDependenceInfoPrinterLegacyFunctionPass(llvm::raw_ostream &OS);

} // namespace polly

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

#endif
