//===- ForwardOpTree.h ------------------------------------------*- C++ -*-===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// Move instructions between statements.
//
//===----------------------------------------------------------------------===//

#include "polly/ForwardOpTree.h"
#include "polly/Options.h"
#include "polly/ScopBuilder.h"
#include "polly/ScopInfo.h"
#include "polly/ScopPass.h"
#include "polly/Support/GICHelper.h"
#include "polly/Support/ISLOStream.h"
#include "polly/Support/ISLTools.h"
#include "polly/Support/VirtualInstruction.h"
#include "polly/ZoneAlgo.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "isl/ctx.h"
#include "isl/isl-noexceptions.h"
#include <cassert>
#include <memory>

#define DEBUG_TYPE "polly-optree"

using namespace llvm;
using namespace polly;

static cl::opt<bool>
    AnalyzeKnown("polly-optree-analyze-known",
                 cl::desc("Analyze array contents for load forwarding"),
                 cl::cat(PollyCategory), cl::init(true), cl::Hidden);

static cl::opt<bool>
    NormalizePHIs("polly-optree-normalize-phi",
                  cl::desc("Replace PHIs by their incoming values"),
                  cl::cat(PollyCategory), cl::init(false), cl::Hidden);

static cl::opt<unsigned>
    MaxOps("polly-optree-max-ops",
           cl::desc("Maximum number of ISL operations to invest for known "
                    "analysis; 0=no limit"),
           cl::init(1000000), cl::cat(PollyCategory), cl::Hidden);

STATISTIC(KnownAnalyzed, "Number of successfully analyzed SCoPs");
STATISTIC(KnownOutOfQuota,
          "Analyses aborted because max_operations was reached");

STATISTIC(TotalInstructionsCopied, "Number of copied instructions");
STATISTIC(TotalKnownLoadsForwarded,
          "Number of forwarded loads because their value was known");
STATISTIC(TotalReloads, "Number of reloaded values");
STATISTIC(TotalReadOnlyCopied, "Number of copied read-only accesses");
STATISTIC(TotalForwardedTrees, "Number of forwarded operand trees");
STATISTIC(TotalModifiedStmts,
          "Number of statements with at least one forwarded tree");

STATISTIC(ScopsModified, "Number of SCoPs with at least one forwarded tree");

STATISTIC(NumValueWrites, "Number of scalar value writes after OpTree");
STATISTIC(NumValueWritesInLoops,
          "Number of scalar value writes nested in affine loops after OpTree");
STATISTIC(NumPHIWrites, "Number of scalar phi writes after OpTree");
STATISTIC(NumPHIWritesInLoops,
          "Number of scalar phi writes nested in affine loops after OpTree");
STATISTIC(NumSingletonWrites, "Number of singleton writes after OpTree");
STATISTIC(NumSingletonWritesInLoops,
          "Number of singleton writes nested in affine loops after OpTree");

namespace {

/// The state of whether an operand tree was/can be forwarded.
///
/// The items apply to an instructions and its operand tree with the instruction
/// as the root element. If the value in question is not an instruction in the
/// SCoP, it can be a leaf of an instruction's operand tree.
enum ForwardingDecision {
  /// The root instruction or value cannot be forwarded at all.
  FD_CannotForward,

  /// The root instruction or value can be forwarded as a leaf of a larger
  /// operand tree.
  /// It does not make sense to move the value itself, it would just replace it
  /// by a use of itself. For instance, a constant "5" used in a statement can
  /// be forwarded, but it would just replace it by the same constant "5".
  /// However, it makes sense to move as an operand of
  ///
  ///   %add = add 5, 5
  ///
  /// where "5" is moved as part of a larger operand tree. "5" would be placed
  /// (disregarding for a moment that literal constants don't have a location
  /// and can be used anywhere) into the same statement as %add would.
  FD_CanForwardLeaf,

  /// The root instruction can be forwarded and doing so avoids a scalar
  /// dependency.
  ///
  /// This can be either because the operand tree can be moved to the target
  /// statement, or a memory access is redirected to read from a different
  /// location.
  FD_CanForwardProfitably,

  /// Used to indicate that a forwarding has be carried out successfully, and
  /// the forwarded memory access can be deleted.
  FD_DidForwardTree,

  /// Used to indicate that a forwarding has be carried out successfully, and
  /// the forwarded memory access is being reused.
  FD_DidForwardLeaf,

  /// A forwarding method cannot be applied to the operand tree.
  /// The difference to FD_CannotForward is that there might be other methods
  /// that can handle it.
  /// The conditions that make an operand tree applicable must be checked even
  /// with DoIt==true because a method following the one that returned
  /// FD_NotApplicable might have returned FD_CanForwardTree.
  FD_NotApplicable
};

/// Implementation of operand tree forwarding for a specific SCoP.
///
/// For a statement that requires a scalar value (through a value read
/// MemoryAccess), see if its operand can be moved into the statement. If so,
/// the MemoryAccess is removed and the all the operand tree instructions are
/// moved into the statement. All original instructions are left in the source
/// statements. The simplification pass can clean these up.
class ForwardOpTreeImpl : ZoneAlgorithm {
private:
  /// Scope guard to limit the number of isl operations for this pass.
  IslMaxOperationsGuard &MaxOpGuard;

  /// How many instructions have been copied to other statements.
  int NumInstructionsCopied = 0;

  /// Number of loads forwarded because their value was known.
  int NumKnownLoadsForwarded = 0;

  /// Number of values reloaded from known array elements.
  int NumReloads = 0;

  /// How many read-only accesses have been copied.
  int NumReadOnlyCopied = 0;

  /// How many operand trees have been forwarded.
  int NumForwardedTrees = 0;

  /// Number of statements with at least one forwarded operand tree.
  int NumModifiedStmts = 0;

  /// Whether we carried out at least one change to the SCoP.
  bool Modified = false;

  /// Contains the zones where array elements are known to contain a specific
  /// value.
  /// { [Element[] -> Zone[]] -> ValInst[] }
  /// @see computeKnown()
  isl::union_map Known;

  /// Translator for newly introduced ValInsts to already existing ValInsts such
  /// that new introduced load instructions can reuse the Known analysis of its
  /// original load. { ValInst[] -> ValInst[] }
  isl::union_map Translator;

  /// Get list of array elements that do contain the same ValInst[] at Domain[].
  ///
  /// @param ValInst { Domain[] -> ValInst[] }
  ///                The values for which we search for alternative locations,
  ///                per statement instance.
  ///
  /// @return { Domain[] -> Element[] }
  ///         For each statement instance, the array elements that contain the
  ///         same ValInst.
  isl::union_map findSameContentElements(isl::union_map ValInst) {
    assert(!ValInst.is_single_valued().is_false());

    // { Domain[] }
    isl::union_set Domain = ValInst.domain();

    // { Domain[] -> Scatter[] }
    isl::union_map Schedule = getScatterFor(Domain);

    // { Element[] -> [Scatter[] -> ValInst[]] }
    isl::union_map MustKnownCurried =
        convertZoneToTimepoints(Known, isl::dim::in, false, true).curry();

    // { [Domain[] -> ValInst[]] -> Scatter[] }
    isl::union_map DomValSched = ValInst.domain_map().apply_range(Schedule);

    // { [Scatter[] -> ValInst[]] -> [Domain[] -> ValInst[]] }
    isl::union_map SchedValDomVal =
        DomValSched.range_product(ValInst.range_map()).reverse();

    // { Element[] -> [Domain[] -> ValInst[]] }
    isl::union_map MustKnownInst = MustKnownCurried.apply_range(SchedValDomVal);

    // { Domain[] -> Element[] }
    isl::union_map MustKnownMap =
        MustKnownInst.uncurry().domain().unwrap().reverse();
    simplify(MustKnownMap);

    return MustKnownMap;
  }

  /// Find a single array element for each statement instance, within a single
  /// array.
  ///
  /// @param MustKnown { Domain[] -> Element[] }
  ///                  Set of candidate array elements.
  /// @param Domain    { Domain[] }
  ///                  The statement instance for which we need elements for.
  ///
  /// @return { Domain[] -> Element[] }
  ///         For each statement instance, an array element out of @p MustKnown.
  ///         All array elements must be in the same array (Polly does not yet
  ///         support reading from different accesses using the same
  ///         MemoryAccess). If no mapping for all of @p Domain exists, returns
  ///         null.
  isl::map singleLocation(isl::union_map MustKnown, isl::set Domain) {
    // { Domain[] -> Element[] }
    isl::map Result;

    // MemoryAccesses can read only elements from a single array
    // (i.e. not: { Dom[0] -> A[0]; Dom[1] -> B[1] }).
    // Look through all spaces until we find one that contains at least the
    // wanted statement instance.s
    MustKnown.foreach_map([&](isl::map Map) -> isl::stat {
      // Get the array this is accessing.
      isl::id ArrayId = Map.get_tuple_id(isl::dim::out);
      ScopArrayInfo *SAI = static_cast<ScopArrayInfo *>(ArrayId.get_user());

      // No support for generation of indirect array accesses.
      if (SAI->getBasePtrOriginSAI())
        return isl::stat::ok; // continue

      // Determine whether this map contains all wanted values.
      isl::set MapDom = Map.domain();
      if (!Domain.is_subset(MapDom).is_true())
        return isl::stat::ok; // continue

      // There might be multiple array elements that contain the same value, but
      // choose only one of them. lexmin is used because it returns a one-value
      // mapping, we do not care about which one.
      // TODO: Get the simplest access function.
      Result = Map.lexmin();
      return isl::stat::error; // break
    });

    return Result;
  }

public:
  ForwardOpTreeImpl(Scop *S, LoopInfo *LI, IslMaxOperationsGuard &MaxOpGuard)
      : ZoneAlgorithm("polly-optree", S, LI), MaxOpGuard(MaxOpGuard) {}

  /// Compute the zones of known array element contents.
  ///
  /// @return True if the computed #Known is usable.
  bool computeKnownValues() {
    isl::union_map MustKnown, KnownFromLoad, KnownFromInit;

    // Check that nothing strange occurs.
    collectCompatibleElts();

    {
      IslQuotaScope QuotaScope = MaxOpGuard.enter();

      computeCommon();
      if (NormalizePHIs)
        computeNormalizedPHIs();
      Known = computeKnown(true, true);

      // Preexisting ValInsts use the known content analysis of themselves.
      Translator = makeIdentityMap(Known.range(), false);
    }

    if (!Known || !Translator || !NormalizeMap) {
      assert(isl_ctx_last_error(IslCtx.get()) == isl_error_quota);
      Known = nullptr;
      Translator = nullptr;
      NormalizeMap = nullptr;
      DEBUG(dbgs() << "Known analysis exceeded max_operations\n");
      return false;
    }

    KnownAnalyzed++;
    DEBUG(dbgs() << "All known: " << Known << "\n");

    return true;
  }

  void printStatistics(raw_ostream &OS, int Indent = 0) {
    OS.indent(Indent) << "Statistics {\n";
    OS.indent(Indent + 4) << "Instructions copied: " << NumInstructionsCopied
                          << '\n';
    OS.indent(Indent + 4) << "Known loads forwarded: " << NumKnownLoadsForwarded
                          << '\n';
    OS.indent(Indent + 4) << "Reloads: " << NumReloads << '\n';
    OS.indent(Indent + 4) << "Read-only accesses copied: " << NumReadOnlyCopied
                          << '\n';
    OS.indent(Indent + 4) << "Operand trees forwarded: " << NumForwardedTrees
                          << '\n';
    OS.indent(Indent + 4) << "Statements with forwarded operand trees: "
                          << NumModifiedStmts << '\n';
    OS.indent(Indent) << "}\n";
  }

  void printStatements(raw_ostream &OS, int Indent = 0) const {
    OS.indent(Indent) << "After statements {\n";
    for (auto &Stmt : *S) {
      OS.indent(Indent + 4) << Stmt.getBaseName() << "\n";
      for (auto *MA : Stmt)
        MA->print(OS);

      OS.indent(Indent + 12);
      Stmt.printInstructions(OS);
    }
    OS.indent(Indent) << "}\n";
  }

  /// Create a new MemoryAccess of type read and MemoryKind::Array.
  ///
  /// @param Stmt           The statement in which the access occurs.
  /// @param LI             The instruction that does the access.
  /// @param AccessRelation The array element that each statement instance
  ///                       accesses.
  ///
  /// @param The newly created access.
  MemoryAccess *makeReadArrayAccess(ScopStmt *Stmt, LoadInst *LI,
                                    isl::map AccessRelation) {
    isl::id ArrayId = AccessRelation.get_tuple_id(isl::dim::out);
    ScopArrayInfo *SAI = reinterpret_cast<ScopArrayInfo *>(ArrayId.get_user());

    // Create a dummy SCEV access, to be replaced anyway.
    SmallVector<const SCEV *, 4> Sizes;
    Sizes.reserve(SAI->getNumberOfDimensions());
    SmallVector<const SCEV *, 4> Subscripts;
    Subscripts.reserve(SAI->getNumberOfDimensions());
    for (unsigned i = 0; i < SAI->getNumberOfDimensions(); i += 1) {
      Sizes.push_back(SAI->getDimensionSize(i));
      Subscripts.push_back(nullptr);
    }

    MemoryAccess *Access =
        new MemoryAccess(Stmt, LI, MemoryAccess::READ, SAI->getBasePtr(),
                         LI->getType(), true, {}, Sizes, LI, MemoryKind::Array);
    S->addAccessFunction(Access);
    Stmt->addAccess(Access, true);

    Access->setNewAccessRelation(AccessRelation);

    return Access;
  }

  /// For an llvm::Value defined in @p DefStmt, compute the RAW dependency for a
  /// use in every instance of @p UseStmt.
  ///
  /// @param UseStmt Statement a scalar is used in.
  /// @param DefStmt Statement a scalar is defined in.
  ///
  /// @return { DomainUse[] -> DomainDef[] }
  isl::map computeUseToDefFlowDependency(ScopStmt *UseStmt, ScopStmt *DefStmt) {
    // { DomainUse[] -> Scatter[] }
    isl::map UseScatter = getScatterFor(UseStmt);

    // { Zone[] -> DomainDef[] }
    isl::map ReachDefZone = getScalarReachingDefinition(DefStmt);

    // { Scatter[] -> DomainDef[] }
    isl::map ReachDefTimepoints =
        convertZoneToTimepoints(ReachDefZone, isl::dim::in, false, true);

    // { DomainUse[] -> DomainDef[] }
    return UseScatter.apply_range(ReachDefTimepoints);
  }

  /// Forward a load by reading from an array element that contains the same
  /// value. Typically the location it was loaded from.
  ///
  /// @param TargetStmt  The statement the operand tree will be copied to.
  /// @param Inst        The (possibly speculatable) instruction to forward.
  /// @param UseStmt     The statement that uses @p Inst.
  /// @param UseLoop     The loop @p Inst is used in.
  /// @param UseToTarget { DomainUse[] -> DomainTarget[] }
  ///                    A mapping from the statement instance @p Inst is used
  ///                    to the statement instance it is forwarded to.
  /// @param DefStmt     The statement @p Inst is defined in.
  /// @param DefLoop     The loop which contains @p Inst.
  /// @param DefToTarget { DomainDef[] -> DomainTarget[] }
  ///                    A mapping from the statement instance @p Inst is
  ///                    defined to the statement instance it is forwarded to.
  /// @param DoIt        If false, only determine whether an operand tree can be
  ///                    forwarded. If true, carry out the forwarding. Do not
  ///                    use DoIt==true if an operand tree is not known to be
  ///                    forwardable.
  ///
  /// @return FD_NotApplicable  if @p Inst cannot be forwarded by creating a new
  ///                           load.
  ///         FD_CannotForward  if the pointer operand cannot be forwarded.
  ///         FD_CanForwardProfitably if @p Inst is forwardable.
  ///         FD_DidForwardTree if @p DoIt was true.
  ForwardingDecision forwardKnownLoad(ScopStmt *TargetStmt, Instruction *Inst,
                                      ScopStmt *UseStmt, Loop *UseLoop,
                                      isl::map UseToTarget, ScopStmt *DefStmt,
                                      Loop *DefLoop, isl::map DefToTarget,
                                      bool DoIt) {
    // Cannot do anything without successful known analysis.
    if (Known.is_null() || Translator.is_null() || UseToTarget.is_null() ||
        DefToTarget.is_null() || MaxOpGuard.hasQuotaExceeded())
      return FD_NotApplicable;

    LoadInst *LI = dyn_cast<LoadInst>(Inst);
    if (!LI)
      return FD_NotApplicable;

    // If the load is already in the statement, no forwarding is necessary.
    // However, it might happen that the LoadInst is already present in the
    // statement's instruction list. In that case we do as follows:
    // - For the evaluation (DoIt==false), we can trivially forward it as it is
    //   benefit of forwarding an already present instruction.
    // - For the execution (DoIt==true), prepend the instruction (to make it
    //   available to all instructions following in the instruction list), but
    //   do not add another MemoryAccess.
    MemoryAccess *Access = TargetStmt->getArrayAccessOrNULLFor(LI);
    if (Access && !DoIt)
      return FD_CanForwardProfitably;

    ForwardingDecision OpDecision =
        forwardTree(TargetStmt, LI->getPointerOperand(), DefStmt, DefLoop,
                    DefToTarget, DoIt);
    switch (OpDecision) {
    case FD_CannotForward:
      assert(!DoIt);
      return OpDecision;

    case FD_CanForwardLeaf:
    case FD_CanForwardProfitably:
      assert(!DoIt);
      break;

    case FD_DidForwardLeaf:
    case FD_DidForwardTree:
      assert(DoIt);
      break;

    default:
      llvm_unreachable("Shouldn't return this");
    }

    IslQuotaScope QuotaScope = MaxOpGuard.enter(!DoIt);

    // { DomainDef[] -> ValInst[] }
    isl::map ExpectedVal = makeValInst(Inst, UseStmt, UseLoop);
    assert(isNormalized(ExpectedVal) && "LoadInsts are always normalized");

    // { DomainTarget[] -> ValInst[] }
    isl::map TargetExpectedVal = ExpectedVal.apply_domain(UseToTarget);
    isl::union_map TranslatedExpectedVal =
        isl::union_map(TargetExpectedVal).apply_range(Translator);

    // { DomainTarget[] -> Element[] }
    isl::union_map Candidates = findSameContentElements(TranslatedExpectedVal);

    isl::map SameVal = singleLocation(Candidates, getDomainFor(TargetStmt));
    if (!SameVal)
      return FD_NotApplicable;

    if (DoIt)
      TargetStmt->prependInstruction(LI);

    if (!DoIt)
      return FD_CanForwardProfitably;

    if (Access) {
      DEBUG(dbgs() << "    forwarded known load with preexisting MemoryAccess"
                   << Access << "\n");
    } else {
      Access = makeReadArrayAccess(TargetStmt, LI, SameVal);
      DEBUG(dbgs() << "    forwarded known load with new MemoryAccess" << Access
                   << "\n");

      // { ValInst[] }
      isl::space ValInstSpace = ExpectedVal.get_space().range();

      // After adding a new load to the SCoP, also update the Known content
      // about it. The new load will have a known ValInst of
      // { [DomainTarget[] -> Value[]] }
      // but which -- because it is a copy of it -- has same value as the
      // { [DomainDef[] -> Value[]] }
      // that it replicates. Instead of  cloning the known content of
      // [DomainDef[] -> Value[]]
      // for DomainTarget[], we add a 'translator' that maps
      // [DomainTarget[] -> Value[]] to [DomainDef[] -> Value[]]
      // before comparing to the known content.
      // TODO: 'Translator' could also be used to map PHINodes to their incoming
      // ValInsts.
      if (ValInstSpace.is_wrapping()) {
        // { DefDomain[] -> Value[] }
        isl::map ValInsts = ExpectedVal.range().unwrap();

        // { DefDomain[] }
        isl::set DefDomain = ValInsts.domain();

        // { Value[] }
        isl::space ValSpace = ValInstSpace.unwrap().range();

        // { Value[] -> Value[] }
        isl::map ValToVal =
            isl::map::identity(ValSpace.map_from_domain_and_range(ValSpace));

        // { [TargetDomain[] -> Value[]] -> [DefDomain[] -> Value] }
        isl::map LocalTranslator = DefToTarget.reverse().product(ValToVal);

        Translator = Translator.add_map(LocalTranslator);
        DEBUG(dbgs() << "      local translator is " << LocalTranslator
                     << "\n");
      }
    }
    DEBUG(dbgs() << "      expected values where " << TargetExpectedVal
                 << "\n");
    DEBUG(dbgs() << "      candidate elements where " << Candidates << "\n");
    assert(Access);

    NumKnownLoadsForwarded++;
    TotalKnownLoadsForwarded++;
    return FD_DidForwardTree;
  }

  /// Forward a scalar by redirecting the access to an array element that stores
  /// the same value.
  ///
  /// @param TargetStmt  The statement the operand tree will be copied to.
  /// @param Inst        The scalar to forward.
  /// @param UseStmt     The statement that uses @p Inst.
  /// @param UseLoop     The loop @p Inst is used in.
  /// @param UseToTarget { DomainUse[] -> DomainTarget[] }
  ///                    A mapping from the statement instance @p Inst is used
  ///                    in, to the statement instance it is forwarded to.
  /// @param DefStmt     The statement @p Inst is defined in.
  /// @param DefLoop     The loop which contains @p Inst.
  /// @param DefToTarget { DomainDef[] -> DomainTarget[] }
  ///                    A mapping from the statement instance @p Inst is
  ///                    defined in, to the statement instance it is forwarded
  ///                    to.
  /// @param DoIt        If false, only determine whether an operand tree can be
  ///                    forwarded. If true, carry out the forwarding. Do not
  ///                    use DoIt==true if an operand tree is not known to be
  ///                    forwardable.
  ///
  /// @return FD_NotApplicable        if @p Inst cannot be reloaded.
  ///         FD_CanForwardLeaf       if @p Inst can be reloaded.
  ///         FD_CanForwardProfitably if @p Inst has been reloaded.
  ///         FD_DidForwardLeaf       if @p DoIt was true.
  ForwardingDecision reloadKnownContent(ScopStmt *TargetStmt, Instruction *Inst,
                                        ScopStmt *UseStmt, Loop *UseLoop,
                                        isl::map UseToTarget, ScopStmt *DefStmt,
                                        Loop *DefLoop, isl::map DefToTarget,
                                        bool DoIt) {
    // Cannot do anything without successful known analysis.
    if (Known.is_null() || Translator.is_null() || UseToTarget.is_null() ||
        DefToTarget.is_null() || MaxOpGuard.hasQuotaExceeded())
      return FD_NotApplicable;

    MemoryAccess *Access = TargetStmt->lookupInputAccessOf(Inst);
    if (Access && Access->isLatestArrayKind()) {
      if (DoIt)
        return FD_DidForwardLeaf;
      return FD_CanForwardLeaf;
    }

    // Don't spend too much time analyzing whether it can be reloaded. When
    // carrying-out the forwarding, we cannot bail-out in the middle of the
    // transformation. It also shouldn't take as long because some results are
    // cached.
    IslQuotaScope QuotaScope = MaxOpGuard.enter(!DoIt);

    // { DomainDef[] -> ValInst[] }
    isl::union_map ExpectedVal = makeNormalizedValInst(Inst, UseStmt, UseLoop);

    // { DomainTarget[] -> ValInst[] }
    isl::union_map TargetExpectedVal = ExpectedVal.apply_domain(UseToTarget);
    isl::union_map TranslatedExpectedVal =
        TargetExpectedVal.apply_range(Translator);

    // { DomainTarget[] -> Element[] }
    isl::union_map Candidates = findSameContentElements(TranslatedExpectedVal);

    isl::map SameVal = singleLocation(Candidates, getDomainFor(TargetStmt));
    if (!SameVal)
      return FD_NotApplicable;

    if (!DoIt)
      return FD_CanForwardProfitably;

    if (!Access)
      Access = TargetStmt->ensureValueRead(Inst);

    simplify(SameVal);
    Access->setNewAccessRelation(SameVal);

    TotalReloads++;
    NumReloads++;
    return FD_DidForwardLeaf;
  }

  /// Forwards a speculatively executable instruction.
  ///
  /// @param TargetStmt  The statement the operand tree will be copied to.
  /// @param UseInst     The (possibly speculatable) instruction to forward.
  /// @param DefStmt     The statement @p UseInst is defined in.
  /// @param DefLoop     The loop which contains @p UseInst.
  /// @param DefToTarget { DomainDef[] -> DomainTarget[] }
  ///                    A mapping from the statement instance @p UseInst is
  ///                    defined to the statement instance it is forwarded to.
  /// @param DoIt        If false, only determine whether an operand tree can be
  ///                    forwarded. If true, carry out the forwarding. Do not
  ///                    use DoIt==true if an operand tree is not known to be
  ///                    forwardable.
  ///
  /// @return FD_NotApplicable  if @p UseInst is not speculatable.
  ///         FD_CannotForward  if one of @p UseInst's operands is not
  ///                           forwardable.
  ///         FD_CanForwardTree if @p UseInst is forwardable.
  ///         FD_DidForward     if @p DoIt was true.
  ForwardingDecision forwardSpeculatable(ScopStmt *TargetStmt,
                                         Instruction *UseInst,
                                         ScopStmt *DefStmt, Loop *DefLoop,
                                         isl::map DefToTarget, bool DoIt) {
    // PHIs, unless synthesizable, are not yet supported.
    if (isa<PHINode>(UseInst))
      return FD_NotApplicable;

    // Compatible instructions must satisfy the following conditions:
    // 1. Idempotent (instruction will be copied, not moved; although its
    //    original instance might be removed by simplification)
    // 2. Not access memory (There might be memory writes between)
    // 3. Not cause undefined behaviour (we might copy to a location when the
    //    original instruction was no executed; this is currently not possible
    //    because we do not forward PHINodes)
    // 4. Not leak memory if executed multiple times (i.e. malloc)
    //
    // Instruction::mayHaveSideEffects is not sufficient because it considers
    // malloc to not have side-effects. llvm::isSafeToSpeculativelyExecute is
    // not sufficient because it allows memory accesses.
    if (mayBeMemoryDependent(*UseInst))
      return FD_NotApplicable;

    if (DoIt) {
      // To ensure the right order, prepend this instruction before its
      // operands. This ensures that its operands are inserted before the
      // instruction using them.
      // TODO: The operand tree is not really a tree, but a DAG. We should be
      // able to handle DAGs without duplication.
      TargetStmt->prependInstruction(UseInst);
      NumInstructionsCopied++;
      TotalInstructionsCopied++;
    }

    for (Value *OpVal : UseInst->operand_values()) {
      ForwardingDecision OpDecision =
          forwardTree(TargetStmt, OpVal, DefStmt, DefLoop, DefToTarget, DoIt);
      switch (OpDecision) {
      case FD_CannotForward:
        assert(!DoIt);
        return FD_CannotForward;

      case FD_CanForwardLeaf:
      case FD_CanForwardProfitably:
        assert(!DoIt);
        break;

      case FD_DidForwardLeaf:
      case FD_DidForwardTree:
        assert(DoIt);
        break;

      case FD_NotApplicable:
        llvm_unreachable("forwardTree should never return FD_NotApplicable");
      }
    }

    if (DoIt)
      return FD_DidForwardTree;
    return FD_CanForwardProfitably;
  }

  /// Determines whether an operand tree can be forwarded or carries out a
  /// forwarding, depending on the @p DoIt flag.
  ///
  /// @param TargetStmt  The statement the operand tree will be copied to.
  /// @param UseVal      The value (usually an instruction) which is root of an
  ///                    operand tree.
  /// @param UseStmt     The statement that uses @p UseVal.
  /// @param UseLoop     The loop @p UseVal is used in.
  /// @param UseToTarget { DomainUse[] -> DomainTarget[] }
  ///                    A mapping from the statement instance @p UseVal is used
  ///                    to the statement instance it is forwarded to.
  /// @param DoIt        If false, only determine whether an operand tree can be
  ///                    forwarded. If true, carry out the forwarding. Do not
  ///                    use DoIt==true if an operand tree is not known to be
  ///                    forwardable.
  ///
  /// @return If DoIt==false, return whether the operand tree can be forwarded.
  ///         If DoIt==true, return FD_DidForward.
  ForwardingDecision forwardTree(ScopStmt *TargetStmt, Value *UseVal,
                                 ScopStmt *UseStmt, Loop *UseLoop,
                                 isl::map UseToTarget, bool DoIt) {
    ScopStmt *DefStmt = nullptr;
    Loop *DefLoop = nullptr;

    // { DefDomain[] -> TargetDomain[] }
    isl::map DefToTarget;

    VirtualUse VUse = VirtualUse::create(UseStmt, UseLoop, UseVal, true);
    switch (VUse.getKind()) {
    case VirtualUse::Constant:
    case VirtualUse::Block:
    case VirtualUse::Hoisted:
      // These can be used anywhere without special considerations.
      if (DoIt)
        return FD_DidForwardTree;
      return FD_CanForwardLeaf;

    case VirtualUse::Synthesizable: {
      // ScopExpander will take care for of generating the code at the new
      // location.
      if (DoIt)
        return FD_DidForwardTree;

      // Check if the value is synthesizable at the new location as well. This
      // might be possible when leaving a loop for which ScalarEvolution is
      // unable to derive the exit value for.
      // TODO: If there is a LCSSA PHI at the loop exit, use that one.
      // If the SCEV contains a SCEVAddRecExpr, we currently depend on that we
      // do not forward past its loop header. This would require us to use a
      // previous loop induction variable instead the current one. We currently
      // do not allow forwarding PHI nodes, thus this should never occur (the
      // only exception where no phi is necessary being an unreachable loop
      // without edge from the outside).
      VirtualUse TargetUse = VirtualUse::create(
          S, TargetStmt, TargetStmt->getSurroundingLoop(), UseVal, true);
      if (TargetUse.getKind() == VirtualUse::Synthesizable)
        return FD_CanForwardLeaf;

      DEBUG(dbgs() << "    Synthesizable would not be synthesizable anymore: "
                   << *UseVal << "\n");
      return FD_CannotForward;
    }

    case VirtualUse::ReadOnly:
      // Note that we cannot return FD_CanForwardTree here. With a operand tree
      // depth of 0, UseVal is the use in TargetStmt that we try to replace.
      // With -polly-analyze-read-only-scalars=true we would ensure the
      // existence of a MemoryAccess (which already exists for a leaf) and be
      // removed again by tryForwardTree because it's goal is to remove this
      // scalar MemoryAccess. It interprets FD_CanForwardTree as the permission
      // to do so.
      if (!DoIt)
        return FD_CanForwardLeaf;

      // If we model read-only scalars, we need to create a MemoryAccess for it.
      if (ModelReadOnlyScalars)
        TargetStmt->ensureValueRead(UseVal);

      NumReadOnlyCopied++;
      TotalReadOnlyCopied++;
      return FD_DidForwardLeaf;

    case VirtualUse::Intra:
      // Knowing that UseStmt and DefStmt are the same statement instance, just
      // reuse the information about UseStmt for DefStmt
      DefStmt = UseStmt;
      DefToTarget = UseToTarget;

      LLVM_FALLTHROUGH;
    case VirtualUse::Inter:
      Instruction *Inst = cast<Instruction>(UseVal);

      if (!DefStmt) {
        DefStmt = S->getStmtFor(Inst);
        if (!DefStmt)
          return FD_CannotForward;
      }

      DefLoop = LI->getLoopFor(Inst->getParent());

      if (DefToTarget.is_null() && !Known.is_null()) {
        IslQuotaScope QuotaScope = MaxOpGuard.enter(!DoIt);

        // { UseDomain[] -> DefDomain[] }
        isl::map UseToDef = computeUseToDefFlowDependency(UseStmt, DefStmt);

        // { DefDomain[] -> UseDomain[] -> TargetDomain[] } shortened to
        // { DefDomain[] -> TargetDomain[] }
        DefToTarget = UseToTarget.apply_domain(UseToDef);
        simplify(DefToTarget);
      }

      ForwardingDecision SpeculativeResult = forwardSpeculatable(
          TargetStmt, Inst, DefStmt, DefLoop, DefToTarget, DoIt);
      if (SpeculativeResult != FD_NotApplicable)
        return SpeculativeResult;

      ForwardingDecision KnownResult =
          forwardKnownLoad(TargetStmt, Inst, UseStmt, UseLoop, UseToTarget,
                           DefStmt, DefLoop, DefToTarget, DoIt);
      if (KnownResult != FD_NotApplicable)
        return KnownResult;

      ForwardingDecision ReloadResult =
          reloadKnownContent(TargetStmt, Inst, UseStmt, UseLoop, UseToTarget,
                             DefStmt, DefLoop, DefToTarget, DoIt);
      if (ReloadResult != FD_NotApplicable)
        return ReloadResult;

      // When no method is found to forward the operand tree, we effectively
      // cannot handle it.
      DEBUG(dbgs() << "    Cannot forward instruction: " << *Inst << "\n");
      return FD_CannotForward;
    }

    llvm_unreachable("Case unhandled");
  }

  /// Try to forward an operand tree rooted in @p RA.
  bool tryForwardTree(MemoryAccess *RA) {
    assert(RA->isLatestScalarKind());
    DEBUG(dbgs() << "Trying to forward operand tree " << RA << "...\n");

    ScopStmt *Stmt = RA->getStatement();
    Loop *InLoop = Stmt->getSurroundingLoop();

    isl::map TargetToUse;
    if (!Known.is_null()) {
      isl::space DomSpace = Stmt->getDomainSpace();
      TargetToUse =
          isl::map::identity(DomSpace.map_from_domain_and_range(DomSpace));
    }

    ForwardingDecision Assessment = forwardTree(
        Stmt, RA->getAccessValue(), Stmt, InLoop, TargetToUse, false);
    assert(Assessment != FD_DidForwardTree && Assessment != FD_DidForwardLeaf);
    if (Assessment != FD_CanForwardProfitably)
      return false;

    ForwardingDecision Execution = forwardTree(Stmt, RA->getAccessValue(), Stmt,
                                               InLoop, TargetToUse, true);
    assert(((Execution == FD_DidForwardTree) ||
            (Execution == FD_DidForwardLeaf)) &&
           "A previous positive assessment must also be executable");

    if (Execution == FD_DidForwardTree)
      Stmt->removeSingleMemoryAccess(RA);
    return true;
  }

  /// Return which SCoP this instance is processing.
  Scop *getScop() const { return S; }

  /// Run the algorithm: Use value read accesses as operand tree roots and try
  /// to forward them into the statement.
  bool forwardOperandTrees() {
    for (ScopStmt &Stmt : *S) {
      bool StmtModified = false;

      // Because we are modifying the MemoryAccess list, collect them first to
      // avoid iterator invalidation.
      SmallVector<MemoryAccess *, 16> Accs;
      for (MemoryAccess *RA : Stmt) {
        if (!RA->isRead())
          continue;
        if (!RA->isLatestScalarKind())
          continue;

        Accs.push_back(RA);
      }

      for (MemoryAccess *RA : Accs) {
        if (tryForwardTree(RA)) {
          Modified = true;
          StmtModified = true;
          NumForwardedTrees++;
          TotalForwardedTrees++;
        }
      }

      if (StmtModified) {
        NumModifiedStmts++;
        TotalModifiedStmts++;
      }
    }

    if (Modified)
      ScopsModified++;
    return Modified;
  }

  /// Print the pass result, performed transformations and the SCoP after the
  /// transformation.
  void print(raw_ostream &OS, int Indent = 0) {
    printStatistics(OS, Indent);

    if (!Modified) {
      // This line can easily be checked in regression tests.
      OS << "ForwardOpTree executed, but did not modify anything\n";
      return;
    }

    printStatements(OS, Indent);
  }
};

/// Pass that redirects scalar reads to array elements that are known to contain
/// the same value.
///
/// This reduces the number of scalar accesses and therefore potentially
/// increases the freedom of the scheduler. In the ideal case, all reads of a
/// scalar definition are redirected (We currently do not care about removing
/// the write in this case).  This is also useful for the main DeLICM pass as
/// there are less scalars to be mapped.
class ForwardOpTree : public ScopPass {
private:
  /// The pass implementation, also holding per-scop data.
  std::unique_ptr<ForwardOpTreeImpl> Impl;

public:
  static char ID;

  explicit ForwardOpTree() : ScopPass(ID) {}
  ForwardOpTree(const ForwardOpTree &) = delete;
  ForwardOpTree &operator=(const ForwardOpTree &) = delete;

  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.addRequiredTransitive<ScopInfoRegionPass>();
    AU.addRequired<LoopInfoWrapperPass>();
    AU.setPreservesAll();
  }

  bool runOnScop(Scop &S) override {
    // Free resources for previous SCoP's computation, if not yet done.
    releaseMemory();

    LoopInfo &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();

    {
      IslMaxOperationsGuard MaxOpGuard(S.getIslCtx().get(), MaxOps, false);
      Impl = llvm::make_unique<ForwardOpTreeImpl>(&S, &LI, MaxOpGuard);

      if (AnalyzeKnown) {
        DEBUG(dbgs() << "Prepare forwarders...\n");
        Impl->computeKnownValues();
      }

      DEBUG(dbgs() << "Forwarding operand trees...\n");
      Impl->forwardOperandTrees();

      if (MaxOpGuard.hasQuotaExceeded()) {
        DEBUG(dbgs() << "Not all operations completed because of "
                        "max_operations exceeded\n");
        KnownOutOfQuota++;
      }
    }

    DEBUG(dbgs() << "\nFinal Scop:\n");
    DEBUG(dbgs() << S);

    // Update statistics
    auto ScopStats = S.getStatistics();
    NumValueWrites += ScopStats.NumValueWrites;
    NumValueWritesInLoops += ScopStats.NumValueWritesInLoops;
    NumPHIWrites += ScopStats.NumPHIWrites;
    NumPHIWritesInLoops += ScopStats.NumPHIWritesInLoops;
    NumSingletonWrites += ScopStats.NumSingletonWrites;
    NumSingletonWritesInLoops += ScopStats.NumSingletonWritesInLoops;

    return false;
  }

  void printScop(raw_ostream &OS, Scop &S) const override {
    if (!Impl)
      return;

    assert(Impl->getScop() == &S);
    Impl->print(OS);
  }

  void releaseMemory() override { Impl.reset(); }
}; // class ForwardOpTree

char ForwardOpTree::ID;

} // namespace

ScopPass *polly::createForwardOpTreePass() { return new ForwardOpTree(); }

INITIALIZE_PASS_BEGIN(ForwardOpTree, "polly-optree",
                      "Polly - Forward operand tree", false, false)
INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
INITIALIZE_PASS_END(ForwardOpTree, "polly-optree",
                    "Polly - Forward operand tree", false, false)
