// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef RUNTIME_VM_COMPILER_BACKEND_LOOPS_H_
#define RUNTIME_VM_COMPILER_BACKEND_LOOPS_H_

#if defined(DART_PRECOMPILED_RUNTIME)
#error "AOT runtime should not use compiler sources (including header files)"
#endif  // defined(DART_PRECOMPILED_RUNTIME)

#include <utility>

#include "vm/allocation.h"
#include "vm/compiler/backend/il.h"

namespace dart {

// Information on an induction variable in a particular loop.
//
// Invariant:
//     offset + mult * def
// Linear:
//     initial + next * i, for invariant initial and next,
//                       and a "normalized" loop index i
// Wrap-around:
//     initial then next, for invariant initial and any next
// Periodic:
//     alternate initial and next, for invariant initial and next
//
class InductionVar : public ZoneAllocated {
 public:
  enum Kind {
    kInvariant,
    kLinear,
    kWrapAround,
    kPeriodic,
  };

  // Strict (exclusive) upper or lower bound on unit stride linear induction:
  //   i < U (i++)
  //   i > L (i--)
  struct Bound {
    Bound(BranchInstr* b, InductionVar* l) : branch_(b), limit_(l) {}
    BranchInstr* branch_;
    InductionVar* limit_;
  };

  // Constructor for an invariant.
  InductionVar(int64_t offset, int64_t mult, Definition* def)
      : kind_(kInvariant), offset_(offset), mult_(mult), def_(def), bounds_() {
    ASSERT(mult_ == 0 || def != nullptr);
  }

  // Constructor for a constant.
  explicit InductionVar(int64_t offset) : InductionVar(offset, 0, nullptr) {}

  // Constructor for an induction.
  InductionVar(Kind kind, InductionVar* initial, InductionVar* next)
      : kind_(kind), initial_(initial), next_(next), bounds_() {
    ASSERT(IsInvariant(initial));
    switch (kind) {
      case kLinear:
      case kPeriodic:
        ASSERT(IsInvariant(next));
        break;
      case kWrapAround:
        ASSERT(next != nullptr);
        break;
      default:
        UNREACHABLE();
    }
  }

  // Returns true if the other induction is structurally equivalent.
  bool IsEqual(const InductionVar* other) const {
    ASSERT(other != nullptr);
    if (kind_ == other->kind_) {
      switch (kind_) {
        case kInvariant:
          return offset_ == other->offset_ && mult_ == other->mult_ &&
                 (mult_ == 0 || def_ == other->def_);
        case kLinear:
        case kWrapAround:
        case kPeriodic:
          return initial_->IsEqual(other->initial_) &&
                 next_->IsEqual(other->next_);
      }
    }
    return false;
  }

  // Returns true if a fixed difference between this and the other induction
  // can be computed. Sets the output parameter diff on success.
  bool CanComputeDifferenceWith(const InductionVar* other, int64_t* diff) const;

  // Returns true if this induction in the given loop can be bounded as
  // min <= this <= max by using bounds of more outer loops. On success
  // the output parameters min and max are set, which are always loop
  // invariant expressions inside the given loop.
  bool CanComputeBounds(LoopInfo* loop,
                        Instruction* pos,
                        InductionVar** min,
                        InductionVar** max);

  // Getters.
  Kind kind() const { return kind_; }
  int64_t offset() const {
    ASSERT(kind_ == kInvariant);
    return offset_;
  }
  int64_t mult() const {
    ASSERT(kind_ == kInvariant);
    return mult_;
  }
  Definition* def() const {
    ASSERT(kind_ == kInvariant);
    return def_;
  }
  InductionVar* initial() const {
    ASSERT(kind_ != kInvariant);
    return initial_;
  }
  InductionVar* next() const {
    ASSERT(kind_ != kInvariant);
    return next_;
  }
  const GrowableArray<Bound>& bounds() { return bounds_; }

  // For debugging.
  void PrintTo(BaseTextBuffer* f) const;
  const char* ToCString() const;

  // Returns true if x is invariant.
  static bool IsInvariant(const InductionVar* x) {
    return x != nullptr && x->kind_ == kInvariant;
  }

  // Returns true if x is a constant (and invariant).
  static bool IsConstant(const InductionVar* x) {
    return x != nullptr && x->kind_ == kInvariant && x->mult_ == 0;
  }

  // Returns true if x is a constant. Sets the value.
  static bool IsConstant(const InductionVar* x, int64_t* c) {
    if (IsConstant(x)) {
      *c = x->offset_;
      return true;
    }
    return false;
  }

  // Returns true if x is linear.
  static bool IsLinear(const InductionVar* x) {
    return x != nullptr && x->kind_ == kLinear;
  }

  // Returns true if x is linear with constant stride. Sets the stride.
  static bool IsLinear(const InductionVar* x, int64_t* s) {
    if (IsLinear(x)) {
      return IsConstant(x->next_, s);
    }
    return false;
  }

  // Returns true if x is wrap-around.
  static bool IsWrapAround(const InductionVar* x) {
    return x != nullptr && x->kind_ == kWrapAround;
  }

  // Returns true if x is periodic.
  static bool IsPeriodic(const InductionVar* x) {
    return x != nullptr && x->kind_ == kPeriodic;
  }

  // Returns true if x is any induction.
  static bool IsInduction(const InductionVar* x) {
    return x != nullptr && x->kind_ != kInvariant;
  }

 private:
  friend class InductionVarAnalysis;

  // Induction classification.
  const Kind kind_;
  union {
    struct {
      int64_t offset_;
      int64_t mult_;
      Definition* def_;
    };
    struct {
      InductionVar* initial_;
      InductionVar* next_;
    };
  };

  bool CanComputeBoundsImpl(LoopInfo* loop,
                            Instruction* pos,
                            InductionVar** min,
                            InductionVar** max);

  // Bounds on induction.
  GrowableArray<Bound> bounds_;

  DISALLOW_COPY_AND_ASSIGN(InductionVar);
};

// Information on a "natural loop" in the flow graph.
class LoopInfo : public ZoneAllocated {
 public:
  LoopInfo(intptr_t id, BlockEntryInstr* header, BitVector* blocks);

  // Merges given blocks to this loop.
  void AddBlocks(BitVector* blocks);

  // Adds back edge to this loop.
  void AddBackEdge(BlockEntryInstr* block);

  // Returns true if given block is backedge of this loop.
  bool IsBackEdge(BlockEntryInstr* block) const;

  // Returns true if given block is alway taken in this loop.
  bool IsAlwaysTaken(BlockEntryInstr* block) const;

  // Returns true if given definition is a header phi for this loop.
  bool IsHeaderPhi(Definition* def) const;

  // Returns true if this loop is nested inside given loop.
  bool IsIn(LoopInfo* loop) const;

  // Returns true if this loop contains given block.
  bool Contains(BlockEntryInstr* block) const;

  // Returns the nesting depth of this loop.
  intptr_t NestingDepth() const;

  // Resets induction.
  void ResetInduction();

  // Assigns induction to a definition.
  void AddInduction(Definition* def, InductionVar* induc);

  // Looks up induction.
  InductionVar* LookupInduction(Definition* def) const;

  // Tests if index stays in [0,length) range in this loop at given position.
  bool IsInRange(Instruction* pos, Value* index, Value* length);

  // Getters.
  intptr_t id() const { return id_; }
  BlockEntryInstr* header() const { return header_; }
  BitVector* blocks() const { return blocks_; }
  const GrowableArray<BlockEntryInstr*>& back_edges() { return back_edges_; }
  ConstraintInstr* limit() const { return limit_; }
  InductionVar* control() const { return control_; }
  LoopInfo* outer() const { return outer_; }
  LoopInfo* inner() const { return inner_; }
  LoopInfo* next() const { return next_; }

  // For debugging.
  void PrintTo(BaseTextBuffer* f) const;
  const char* ToCString() const;

 private:
  friend class InductionVar;
  friend class InductionVarAnalysis;
  friend class LoopHierarchy;

  // Mapping from definition to induction.
  typedef RawPointerKeyValueTrait<Definition, InductionVar*> InductionKV;

  // Mapping from induction to mapping from instruction to induction pair.
  class MemoVal : public ZoneAllocated {
   public:
    typedef RawPointerKeyValueTrait<Instruction,
                                    std::pair<InductionVar*, InductionVar*>>
        PosKV;
    MemoVal() : memo_() {}
    DirectChainedHashMap<PosKV> memo_;
  };
  typedef RawPointerKeyValueTrait<InductionVar, MemoVal*> MemoKV;

  // Unique id of loop. We use its index in the
  // loop header array for this.
  const intptr_t id_;

  // Header of loop.
  BlockEntryInstr* header_;

  // Compact representation of every block in the loop,
  // indexed by its "preorder_number".
  BitVector* blocks_;

  // Back edges of loop (usually one).
  GrowableArray<BlockEntryInstr*> back_edges_;

  // Map definition -> induction for this loop.
  DirectChainedHashMap<InductionKV> induction_;

  // A small, per-loop memoization cache, to avoid costly
  // recomputations while traversing very deeply nested loops.
  DirectChainedHashMap<MemoKV> memo_cache_;

  // Constraint on a header phi.
  // TODO(ajcbik): very specific to smi range analysis,
  //               should we really store it here?
  ConstraintInstr* limit_;

  // Control induction.
  InductionVar* control_;

  // Loop hierarchy.
  LoopInfo* outer_;
  LoopInfo* inner_;
  LoopInfo* next_;

  DISALLOW_COPY_AND_ASSIGN(LoopInfo);
};

// Information on the loop hierarchy in the flow graph.
class LoopHierarchy : public ZoneAllocated {
 public:
  LoopHierarchy(ZoneGrowableArray<BlockEntryInstr*>* headers,
                const GrowableArray<BlockEntryInstr*>& preorder,
                bool print_traces);

  // Getters.
  const ZoneGrowableArray<BlockEntryInstr*>& headers() const {
    return *headers_;
  }
  LoopInfo* top() const { return top_; }

  // Returns total number of loops in the hierarchy.
  intptr_t num_loops() const { return headers_->length(); }

  // Performs induction variable analysis on all loops.
  void ComputeInduction() const;

 private:
  void Build();
  void Print(LoopInfo* loop) const;

  ZoneGrowableArray<BlockEntryInstr*>* headers_;
  const GrowableArray<BlockEntryInstr*>& preorder_;
  LoopInfo* top_;
  const bool print_traces_;

  DISALLOW_COPY_AND_ASSIGN(LoopHierarchy);
};

}  // namespace dart

#endif  // RUNTIME_VM_COMPILER_BACKEND_LOOPS_H_
