/*
 * Copyright (C) 2015 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef ART_COMPILER_OPTIMIZING_INDUCTION_VAR_ANALYSIS_H_
#define ART_COMPILER_OPTIMIZING_INDUCTION_VAR_ANALYSIS_H_

#include <string>

#include "base/arena_containers.h"
#include "base/array_ref.h"
#include "base/scoped_arena_containers.h"
#include "nodes.h"
#include "optimization.h"

namespace art {

/**
 * Induction variable analysis. This class does not have a direct public API.
 * Instead, the results of induction variable analysis can be queried through
 * friend classes, such as InductionVarRange.
 *
 * The analysis implementation is based on the paper by M. Gerlek et al.
 * "Beyond Induction Variables: Detecting and Classifying Sequences Using a Demand-Driven SSA Form"
 * (ACM Transactions on Programming Languages and Systems, Volume 17 Issue 1, Jan. 1995).
 */
class HInductionVarAnalysis : public HOptimization {
 public:
  explicit HInductionVarAnalysis(HGraph* graph, const char* name = kInductionPassName);

  bool Run() override;

  static constexpr const char* kInductionPassName = "induction_var_analysis";

 private:
  struct NodeInfo;
  struct StackEntry;

  enum InductionClass {
    kInvariant,
    kLinear,
    kPolynomial,
    kGeometric,
    kWrapAround,
    kPeriodic
  };

  enum InductionOp {
    // Operations.
    kNop,
    kAdd,
    kSub,
    kNeg,
    kMul,
    kDiv,
    kRem,
    kXor,
    kFetch,
    // Trip-counts.
    kTripCountInLoop,        // valid in full loop; loop is finite
    kTripCountInBody,        // valid in body only; loop is finite
    kTripCountInLoopUnsafe,  // valid in full loop; loop may be infinite
    kTripCountInBodyUnsafe,  // valid in body only; loop may be infinite
    // Comparisons for trip-count tests.
    kLT,
    kLE,
    kGT,
    kGE
  };

  /**
   * Defines a detected induction as:
   *   (1) invariant:
   *         op: a + b, a - b, -b, a * b, a / b, a % b, a ^ b, fetch
   *   (2) linear:
   *         nop: a * i + b
   *   (3) polynomial:
   *         nop: sum_lt(a) + b, for linear a
   *   (4) geometric:
   *         op: a * fetch^i + b, a * fetch^-i + b
   *   (5) wrap-around
   *         nop: a, then defined by b
   *   (6) periodic
   *         nop: a, then defined by b (repeated when exhausted)
   *   (7) trip-count:
   *         tc: defined by a, taken-test in b
   */
  struct InductionInfo : public ArenaObject<kArenaAllocInductionVarAnalysis> {
    InductionInfo(InductionClass ic,
                  InductionOp op,
                  InductionInfo* a,
                  InductionInfo* b,
                  HInstruction* f,
                  DataType::Type t)
        : induction_class(ic),
          operation(op),
          op_a(a),
          op_b(b),
          fetch(f),
          type(t) {}
    InductionClass induction_class;
    InductionOp operation;
    InductionInfo* op_a;
    InductionInfo* op_b;
    HInstruction* fetch;
    DataType::Type type;  // precision of operation
  };


  InductionInfo* CreateInvariantOp(const HBasicBlock* context,
                                   const HLoopInformation* loop,
                                   InductionOp op,
                                   InductionInfo* a,
                                   InductionInfo* b) {
    DCHECK(((op != kNeg && a != nullptr) || (op == kNeg && a == nullptr)) && b != nullptr);
    return CreateSimplifiedInvariant(context, loop, op, a, b);
  }

  InductionInfo* CreateInvariantFetch(HInstruction* f) {
    DCHECK(f != nullptr);
    return new (graph_->GetAllocator())
        InductionInfo(kInvariant, kFetch, nullptr, nullptr, f, f->GetType());
  }

  InductionInfo* CreateTripCount(InductionOp op,
                                 InductionInfo* a,
                                 InductionInfo* b,
                                 DataType::Type type) {
    DCHECK(a != nullptr && b != nullptr);
    return new (graph_->GetAllocator()) InductionInfo(kInvariant, op, a, b, nullptr, type);
  }

  InductionInfo* CreateInduction(InductionClass ic,
                                 InductionOp op,
                                 InductionInfo* a,
                                 InductionInfo* b,
                                 HInstruction* f,
                                 DataType::Type type) {
    DCHECK(a != nullptr && b != nullptr);
    return new (graph_->GetAllocator()) InductionInfo(ic, op, a, b, f, type);
  }

  // Methods for analysis.
  void VisitLoop(const HLoopInformation* loop);
  size_t TryVisitNodes(const HLoopInformation* loop,
                       HInstruction* start_instruction,
                       size_t global_depth,
                       /*inout*/ ScopedArenaSafeMap<HInstruction*, NodeInfo>* visited_instructions);
  void ExtractScc(ArrayRef<const StackEntry> stack_tail, ScopedArenaVector<HInstruction*>* scc);
  void ClassifyTrivial(const HLoopInformation* loop, HInstruction* instruction);
  void ClassifyNonTrivial(const HLoopInformation* loop, ArrayRef<const StackEntry> stack_tail);
  InductionInfo* RotatePeriodicInduction(InductionInfo* induction,
                                         InductionInfo* last,
                                         DataType::Type type);

  // Transfer operations.
  InductionInfo* TransferPhi(const HLoopInformation* loop,
                             HInstruction* phi,
                             size_t input_index,
                             size_t adjust_input_size);
  InductionInfo* TransferAddSub(const HBasicBlock* context,
                                const HLoopInformation* loop,
                                InductionInfo* a,
                                InductionInfo* b,
                                InductionOp op,
                                DataType::Type type);
  InductionInfo* TransferNeg(const HBasicBlock* context,
                             const HLoopInformation* loop,
                             InductionInfo* a,
                             DataType::Type type);
  InductionInfo* TransferMul(const HBasicBlock* context,
                             const HLoopInformation* loop,
                             InductionInfo* a,
                             InductionInfo* b,
                             DataType::Type type);
  InductionInfo* TransferConversion(InductionInfo* a, DataType::Type from, DataType::Type to);

  // Solvers.
  InductionInfo* SolvePhi(HInstruction* phi,
                          size_t input_index,
                          size_t adjust_input_size,
                          const ScopedArenaSafeMap<HInstruction*, InductionInfo*>& cycle);
  InductionInfo* SolvePhiAllInputs(const HLoopInformation* loop,
                                   HInstruction* entry_phi,
                                   HInstruction* phi,
                                   const ScopedArenaSafeMap<HInstruction*, InductionInfo*>& cycle,
                                   DataType::Type type);
  InductionInfo* SolveAddSub(const HLoopInformation* loop,
                             HInstruction* entry_phi,
                             HInstruction* instruction,
                             HInstruction* x,
                             HInstruction* y,
                             InductionOp op,
                             const ScopedArenaSafeMap<HInstruction*, InductionInfo*>& cycle,
                             DataType::Type type);
  InductionInfo* SolveOp(const HLoopInformation* loop,
                         HInstruction* entry_phi,
                         HInstruction* instruction,
                         HInstruction* x,
                         HInstruction* y,
                         InductionOp op,
                         DataType::Type type);
  InductionInfo* SolveTest(const HLoopInformation* loop,
                           HInstruction* entry_phi,
                           HInstruction* instruction,
                           int64_t opposite_value,
                           DataType::Type type);
  InductionInfo* SolveConversion(const HLoopInformation* loop,
                                 HInstruction* entry_phi,
                                 HTypeConversion* conversion,
                                 const ScopedArenaSafeMap<HInstruction*, InductionInfo*>& cycle,
                                 /*inout*/ DataType::Type* type);

  //
  // Loop trip count analysis methods.
  //

  // Trip count information.
  void VisitControl(const HLoopInformation* loop);
  void VisitCondition(const HBasicBlock* context,
                      const HLoopInformation* loop,
                      HBasicBlock* body,
                      InductionInfo* a,
                      InductionInfo* b,
                      DataType::Type type,
                      IfCondition cmp);
  void VisitTripCount(const HBasicBlock* context,
                      const HLoopInformation* loop,
                      InductionInfo* lower_expr,
                      InductionInfo* upper_expr,
                      InductionInfo* stride,
                      int64_t stride_value,
                      DataType::Type type,
                      IfCondition cmp);
  bool IsTaken(const HBasicBlock* context,
               const HLoopInformation* loop,
               InductionInfo* lower_expr,
               InductionInfo* upper_expr,
               IfCondition cmp);
  bool IsFinite(const HBasicBlock* context,
                const HLoopInformation* loop,
                InductionInfo* upper_expr,
                int64_t stride_value,
                DataType::Type type,
                IfCondition cmp);
  bool FitsNarrowerControl(const HBasicBlock* context,
                           const HLoopInformation* loop,
                           InductionInfo* lower_expr,
                           InductionInfo* upper_expr,
                           int64_t stride_value,
                           DataType::Type type,
                           IfCondition cmp);
  bool RewriteBreakLoop(const HBasicBlock* context,
                        const HLoopInformation* loop,
                        HBasicBlock* body,
                        int64_t stride_value,
                        DataType::Type type);

  //
  // Helper methods.
  //

  // Assign and lookup.
  void AssignInfo(const HLoopInformation* loop, HInstruction* instruction, InductionInfo* info);
  InductionInfo* LookupInfo(const HLoopInformation* loop, HInstruction* instruction);
  InductionInfo* CreateConstant(int64_t value, DataType::Type type);
  InductionInfo* CreateSimplifiedInvariant(const HBasicBlock* context,
                                           const HLoopInformation* loop,
                                           InductionOp op,
                                           InductionInfo* a,
                                           InductionInfo* b);
  HInstruction* GetShiftConstant(const HLoopInformation* loop,
                                 HInstruction* instruction,
                                 InductionInfo* initial);
  void AssignCycle(HPhi* phi, ArrayRef<HInstruction* const> scc);
  ArenaSet<HInstruction*>* LookupCycle(HPhi* phi);

  // Constants.
  bool IsExact(const HBasicBlock* context,
               const HLoopInformation* loop,
               InductionInfo* info,
               /*out*/int64_t* value);
  bool IsAtMost(const HBasicBlock* context,
                const HLoopInformation* loop,
                InductionInfo* info,
                /*out*/int64_t* value);
  bool IsAtLeast(const HBasicBlock* context,
                 const HLoopInformation* loop,
                 InductionInfo* info,
                 /*out*/int64_t* value);

  // Helpers.
  static bool IsNarrowingLinear(InductionInfo* info);
  static bool InductionEqual(InductionInfo* info1, InductionInfo* info2);
  static std::string FetchToString(HInstruction* fetch);
  static std::string InductionToString(InductionInfo* info);

  /**
   * Maintains the results of the analysis as a mapping from loops to a mapping from instructions
   * to the induction information for that instruction in that loop.
   */
  ArenaSafeMap<const HLoopInformation*, ArenaSafeMap<HInstruction*, InductionInfo*>> induction_;

  /**
   * Preserves induction cycle information for each loop-phi.
   */
  ArenaSafeMap<HPhi*, ArenaSet<HInstruction*>> cycles_;

  friend class InductionVarAnalysisTest;
  friend class InductionVarRange;
  friend class InductionVarRangeTest;

  DISALLOW_COPY_AND_ASSIGN(HInductionVarAnalysis);
};

}  // namespace art

#endif  // ART_COMPILER_OPTIMIZING_INDUCTION_VAR_ANALYSIS_H_
