//===- polly/ScopBuilder.h -------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Create a polyhedral description for a static control flow region.
//
// The pass creates a polyhedral description of the Scops detected by the SCoP
// detection derived from their LLVM-IR code.
//
//===----------------------------------------------------------------------===//

#ifndef POLLY_SCOP_BUILDER_H
#define POLLY_SCOP_BUILDER_H

#include "polly/ScopInfo.h"

namespace polly {

/// @brief Build the Polly IR (Scop and ScopStmt) on a Region.
class ScopBuilder {
  //===-------------------------------------------------------------------===//
  ScopBuilder(const ScopBuilder &) = delete;
  const ScopBuilder &operator=(const ScopBuilder &) = delete;

  /// @brief The AliasAnalysis to build AliasSetTracker.
  AliasAnalysis &AA;

  /// @brief Target data for element size computing.
  const DataLayout &DL;

  /// @brief DominatorTree to reason about guaranteed execution.
  DominatorTree &DT;

  /// @brief LoopInfo for information about loops
  LoopInfo &LI;

  /// @biref Valid Regions for Scop
  ScopDetection &SD;

  /// @brief The ScalarEvolution to help building Scop.
  ScalarEvolution &SE;

  /// @brief Set of instructions that might read any memory location.
  SmallVector<Instruction *, 16> GlobalReads;

  /// @brief Set of all accessed array base pointers.
  SmallSetVector<Value *, 16> ArrayBasePointers;

  // The Scop
  std::unique_ptr<Scop> scop;

  // Build the SCoP for Region @p R.
  void buildScop(Region &R, AssumptionCache &AC);

  /// @brief Try to build a multi-dimensional fixed sized MemoryAccess from
  ///        the Load/Store instruction.
  ///
  /// @param Inst       The Load/Store instruction that access the memory
  /// @param L          The parent loop of the instruction
  ///
  /// @returns True if the access could be built, False otherwise.
  bool buildAccessMultiDimFixed(MemAccInst Inst, Loop *L);

  /// @brief Try to build a multi-dimensional parameteric sized MemoryAccess
  ///        from the Load/Store instruction.
  ///
  /// @param Inst       The Load/Store instruction that access the memory
  /// @param L          The parent loop of the instruction
  ///
  /// @returns True if the access could be built, False otherwise.
  bool buildAccessMultiDimParam(MemAccInst Inst, Loop *L);

  /// @brief Try to build a MemoryAccess for a memory intrinsic.
  ///
  /// @param Inst       The instruction that access the memory
  /// @param L          The parent loop of the instruction
  ///
  /// @returns True if the access could be built, False otherwise.
  bool buildAccessMemIntrinsic(MemAccInst Inst, Loop *L);

  /// @brief Try to build a MemoryAccess for a call instruction.
  ///
  /// @param Inst       The call instruction that access the memory
  /// @param L          The parent loop of the instruction
  ///
  /// @returns True if the access could be built, False otherwise.
  bool buildAccessCallInst(MemAccInst Inst, Loop *L);

  /// @brief Build a single-dimensional parameteric sized MemoryAccess
  ///        from the Load/Store instruction.
  ///
  /// @param Inst       The Load/Store instruction that access the memory
  /// @param L          The parent loop of the instruction
  void buildAccessSingleDim(MemAccInst Inst, Loop *L);

  /// @brief Build an instance of MemoryAccess from the Load/Store instruction.
  ///
  /// @param Inst       The Load/Store instruction that access the memory
  /// @param L          The parent loop of the instruction
  void buildMemoryAccess(MemAccInst Inst, Loop *L);

  /// @brief Analyze and extract the cross-BB scalar dependences (or,
  ///        dataflow dependencies) of an instruction.
  ///
  /// @param Inst    The instruction to be analyzed.
  void buildScalarDependences(Instruction *Inst);

  /// @brief Search for uses of the llvm::Value defined by @p Inst that are not
  ///        within the SCoP. If there is such use, add a SCALAR WRITE such that
  ///        it is available after the SCoP as escaping value.
  ///
  /// @param Inst The instruction to be analyzed.
  void buildEscapingDependences(Instruction *Inst);

  /// @brief Create MemoryAccesses for the given PHI node in the given region.
  ///
  /// @param PHI                The PHI node to be handled
  /// @param NonAffineSubRegion The non affine sub-region @p PHI is in.
  /// @param IsExitBlock        Flag to indicate that @p PHI is in the exit BB.
  void buildPHIAccesses(PHINode *PHI, Region *NonAffineSubRegion,
                        bool IsExitBlock = false);

  /// @brief Build the access functions for the subregion @p SR.
  ///
  /// @param SR           A subregion of @p R.
  /// @param InsnToMemAcc The Instruction to MemoryAccess mapping.
  void buildAccessFunctions(Region &SR);

  /// @brief Create ScopStmt for all BBs and non-affine subregions of @p SR.
  ///
  /// @param SR A subregion of @p R.
  ///
  /// Some of the statments might be optimized away later when they do not
  /// access any memory and thus have no effect.
  void buildStmts(Region &SR);

  /// @brief Build the access functions for the basic block @p BB
  ///
  /// @param BB                 A basic block in @p R.
  /// @param NonAffineSubRegion The non affine sub-region @p BB is in.
  /// @param IsExitBlock        Flag to indicate that @p BB is in the exit BB.
  void buildAccessFunctions(BasicBlock &BB,
                            Region *NonAffineSubRegion = nullptr,
                            bool IsExitBlock = false);

  /// @brief Create a new MemoryAccess object and add it to #AccFuncMap.
  ///
  /// @param BB          The block where the access takes place.
  /// @param Inst        The instruction doing the access. It is not necessarily
  ///                    inside @p BB.
  /// @param AccType     The kind of access.
  /// @param BaseAddress The accessed array's base address.
  /// @param ElemType    The type of the accessed array elements.
  /// @param Affine      Whether all subscripts are affine expressions.
  /// @param AccessValue Value read or written.
  /// @param Subscripts  Access subscripts per dimension.
  /// @param Sizes       The array diminsion's sizes.
  /// @param Kind        The kind of memory accessed.
  ///
  /// @return The created MemoryAccess, or nullptr if the access is not within
  ///         the SCoP.
  MemoryAccess *addMemoryAccess(BasicBlock *BB, Instruction *Inst,
                                MemoryAccess::AccessType AccType,
                                Value *BaseAddress, Type *ElemType, bool Affine,
                                Value *AccessValue,
                                ArrayRef<const SCEV *> Subscripts,
                                ArrayRef<const SCEV *> Sizes,
                                ScopArrayInfo::MemoryKind Kind);

  /// @brief Create a MemoryAccess that represents either a LoadInst or
  /// StoreInst.
  ///
  /// @param MemAccInst  The LoadInst or StoreInst.
  /// @param AccType     The kind of access.
  /// @param BaseAddress The accessed array's base address.
  /// @param ElemType    The type of the accessed array elements.
  /// @param IsAffine    Whether all subscripts are affine expressions.
  /// @param Subscripts  Access subscripts per dimension.
  /// @param Sizes       The array dimension's sizes.
  /// @param AccessValue Value read or written.
  ///
  /// @see ScopArrayInfo::MemoryKind
  void addArrayAccess(MemAccInst MemAccInst, MemoryAccess::AccessType AccType,
                      Value *BaseAddress, Type *ElemType, bool IsAffine,
                      ArrayRef<const SCEV *> Subscripts,
                      ArrayRef<const SCEV *> Sizes, Value *AccessValue);

  /// @brief Create a MemoryAccess for writing an llvm::Instruction.
  ///
  /// The access will be created at the position of @p Inst.
  ///
  /// @param Inst The instruction to be written.
  ///
  /// @see ensureValueRead()
  /// @see ScopArrayInfo::MemoryKind
  void ensureValueWrite(Instruction *Inst);

  /// @brief Ensure an llvm::Value is available in the BB's statement, creating
  ///        a MemoryAccess for reloading it if necessary.
  ///
  /// @param V      The value expected to be loaded.
  /// @param UserBB Where to reload the value.
  ///
  /// @see ensureValueStore()
  /// @see ScopArrayInfo::MemoryKind
  void ensureValueRead(Value *V, BasicBlock *UserBB);

  /// @brief Create a write MemoryAccess for the incoming block of a phi node.
  ///
  /// Each of the incoming blocks write their incoming value to be picked in the
  /// phi's block.
  ///
  /// @param PHI           PHINode under consideration.
  /// @param IncomingBlock Some predecessor block.
  /// @param IncomingValue @p PHI's value when coming from @p IncomingBlock.
  /// @param IsExitBlock   When true, uses the .s2a alloca instead of the
  ///                      .phiops one. Required for values escaping through a
  ///                      PHINode in the SCoP region's exit block.
  /// @see addPHIReadAccess()
  /// @see ScopArrayInfo::MemoryKind
  void ensurePHIWrite(PHINode *PHI, BasicBlock *IncomingBlock,
                      Value *IncomingValue, bool IsExitBlock);

  /// @brief Create a MemoryAccess for reading the value of a phi.
  ///
  /// The modeling assumes that all incoming blocks write their incoming value
  /// to the same location. Thus, this access will read the incoming block's
  /// value as instructed by this @p PHI.
  ///
  /// @param PHI PHINode under consideration; the READ access will be added
  /// here.
  ///
  /// @see ensurePHIWrite()
  /// @see ScopArrayInfo::MemoryKind
  void addPHIReadAccess(PHINode *PHI);

public:
  explicit ScopBuilder(Region *R, AssumptionCache &AC, AliasAnalysis &AA,
                       const DataLayout &DL, DominatorTree &DT, LoopInfo &LI,
                       ScopDetection &SD, ScalarEvolution &SE);
  ~ScopBuilder() {}

  /// @brief Try to build the Polly IR of static control part on the current
  ///        SESE-Region.
  ///
  /// @return Give up the ownership of the scop object or static control part
  ///         for the region
  std::unique_ptr<Scop> getScop() { return std::move(scop); }
};

} // end namespace polly

namespace llvm {
class PassRegistry;
void initializeScopInfoRegionPassPass(llvm::PassRegistry &);
void initializeScopInfoWrapperPassPass(llvm::PassRegistry &);
} // namespace llvm

#endif
