/*
 * Copyright (C) 2013 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_DEX_DATAFLOW_ITERATOR_H_
#define ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_

#include "base/logging.h"
#include "mir_graph.h"

namespace art {

  /*
   * This class supports iterating over lists of basic blocks in various
   * interesting orders.  Note that for efficiency, the visit orders have been pre-computed.
   * The order itself will not change during the iteration.  However, for some uses,
   * auxiliary data associated with the basic blocks may be changed during the iteration,
   * necessitating another pass over the list.  If this behavior is required, use the
   * "Repeating" variant.  For the repeating variant, the caller must tell the iterator
   * whether a change has been made that necessitates another pass.  Note that calling Next(true)
   * does not affect the iteration order or short-circuit the current pass - it simply tells
   * the iterator that once it has finished walking through the block list it should reset and
   * do another full pass through the list.
   */
  /**
   * @class DataflowIterator
   * @brief The main iterator class, all other iterators derive of this one to define an iteration order.
   */
  class DataflowIterator {
    public:
      virtual ~DataflowIterator() {}

      /**
       * @brief How many times have we repeated the iterator across the BasicBlocks?
       * @return the number of iteration repetitions.
       */
      int32_t GetRepeatCount() { return repeats_; }

      /**
       * @brief Has the user of the iterator reported a change yet?
       * @details Does not mean there was or not a change, it is only whether the user passed a true to the Next function call.
       * @return whether the user of the iterator reported a change yet.
       */
      int32_t GetChanged() { return changed_; }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) = 0;

    protected:
      /**
       * @param mir_graph the MIRGraph we are interested in.
       * @param start_idx the first index we want to iterate across.
       * @param end_idx the last index we want to iterate (not included).
       */
      DataflowIterator(MIRGraph* mir_graph, int32_t start_idx, int32_t end_idx)
          : mir_graph_(mir_graph),
            start_idx_(start_idx),
            end_idx_(end_idx),
            block_id_list_(NULL),
            idx_(0),
            repeats_(0),
            changed_(false) {}

      /**
       * @brief Get the next BasicBlock iterating forward.
       * @return the next BasicBlock iterating forward.
       */
      virtual BasicBlock* ForwardSingleNext() ALWAYS_INLINE;

      /**
       * @brief Get the next BasicBlock iterating backward.
       * @return the next BasicBlock iterating backward.
       */
      virtual BasicBlock* ReverseSingleNext() ALWAYS_INLINE;

      /**
       * @brief Get the next BasicBlock iterating forward, restart if a BasicBlock was reported changed during the last iteration.
       * @return the next BasicBlock iterating forward, with chance of repeating the iteration.
       */
      virtual BasicBlock* ForwardRepeatNext() ALWAYS_INLINE;

      /**
       * @brief Get the next BasicBlock iterating backward, restart if a BasicBlock was reported changed during the last iteration.
       * @return the next BasicBlock iterating backward, with chance of repeating the iteration.
       */
      virtual BasicBlock* ReverseRepeatNext() ALWAYS_INLINE;

      MIRGraph* const mir_graph_;                       /**< @brief the MIRGraph */
      const int32_t start_idx_;                         /**< @brief the start index for the iteration */
      const int32_t end_idx_;                           /**< @brief the last index for the iteration */
      const ArenaVector<BasicBlockId>* block_id_list_;  /**< @brief the list of BasicBlocks we want to iterate on */
      int32_t idx_;                                     /**< @brief Current index for the iterator */
      int32_t repeats_;                                 /**< @brief Number of repeats over the iteration */
      bool changed_;                                    /**< @brief Has something changed during the current iteration? */
  };  // DataflowIterator

  /**
   * @class PreOrderDfsIterator
   * @brief Used to perform a Pre-order Depth-First-Search Iteration of a MIRGraph.
   */
  class PreOrderDfsIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit PreOrderDfsIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
        // Extra setup for the PreOrderDfsIterator.
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetDfsOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) {
        // Update changed: if had_changed is true, we remember it for the whole iteration.
        changed_ |= had_change;

        return ForwardSingleNext();
      }
  };

  /**
   * @class RepeatingPreOrderDfsIterator
   * @brief Used to perform a Repeating Pre-order Depth-First-Search Iteration of a MIRGraph.
   * @details If there is a change during an iteration, the iteration starts over at the end of the iteration.
   */
  class RepeatingPreOrderDfsIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit RepeatingPreOrderDfsIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
        // Extra setup for the RepeatingPreOrderDfsIterator.
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetDfsOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) {
        // Update changed: if had_changed is true, we remember it for the whole iteration.
        changed_ |= had_change;

        return ForwardRepeatNext();
      }
  };

  /**
   * @class RepeatingPostOrderDfsIterator
   * @brief Used to perform a Repeating Post-order Depth-First-Search Iteration of a MIRGraph.
   * @details If there is a change during an iteration, the iteration starts over at the end of the iteration.
   */
  class RepeatingPostOrderDfsIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit RepeatingPostOrderDfsIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
        // Extra setup for the RepeatingPostOrderDfsIterator.
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetDfsPostOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) {
        // Update changed: if had_changed is true, we remember it for the whole iteration.
        changed_ |= had_change;

        return ForwardRepeatNext();
      }
  };

  /**
   * @class ReversePostOrderDfsIterator
   * @brief Used to perform a Reverse Post-order Depth-First-Search Iteration of a MIRGraph.
   */
  class ReversePostOrderDfsIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit ReversePostOrderDfsIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) {
        // Extra setup for the ReversePostOrderDfsIterator.
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetDfsPostOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) {
        // Update changed: if had_changed is true, we remember it for the whole iteration.
        changed_ |= had_change;

        return ReverseSingleNext();
      }
  };

  /**
   * @class ReversePostOrderDfsIterator
   * @brief Used to perform a Repeating Reverse Post-order Depth-First-Search Iteration of a MIRGraph.
   * @details If there is a change during an iteration, the iteration starts over at the end of the iteration.
   */
  class RepeatingReversePostOrderDfsIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit RepeatingReversePostOrderDfsIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) {
        // Extra setup for the RepeatingReversePostOrderDfsIterator
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetDfsPostOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) {
        // Update changed: if had_changed is true, we remember it for the whole iteration.
        changed_ |= had_change;

        return ReverseRepeatNext();
      }
  };

  /**
   * @class PostOrderDOMIterator
   * @brief Used to perform a Post-order Domination Iteration of a MIRGraph.
   */
  class PostOrderDOMIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit PostOrderDOMIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
        // Extra setup for thePostOrderDOMIterator.
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetDomPostOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) {
        // Update changed: if had_changed is true, we remember it for the whole iteration.
        changed_ |= had_change;

        return ForwardSingleNext();
      }
  };

  /**
   * @class AllNodesIterator
   * @brief Used to perform an iteration on all the BasicBlocks a MIRGraph.
   */
  class AllNodesIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit AllNodesIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, 0, mir_graph->GetBlockList().size()) {
      }

      /**
       * @brief Resetting the iterator.
       */
      void Reset() {
        idx_ = 0;
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) ALWAYS_INLINE;
  };

  /**
   * @class TopologicalSortIterator
   * @brief Used to perform a Topological Sort Iteration of a MIRGraph.
   */
  class TopologicalSortIterator : public DataflowIterator {
    public:
      /**
       * @brief The constructor, using all of the reachable blocks of the MIRGraph.
       * @param mir_graph The MIRGraph considered.
       */
      explicit TopologicalSortIterator(MIRGraph* mir_graph)
          : DataflowIterator(mir_graph, 0, mir_graph->GetTopologicalSortOrder().size()),
            loop_ends_(&mir_graph->GetTopologicalSortOrderLoopEnds()),
            loop_head_stack_(mir_graph_->GetTopologicalSortOrderLoopHeadStack()) {
        // Extra setup for TopologicalSortIterator.
        idx_ = start_idx_;
        block_id_list_ = &mir_graph->GetTopologicalSortOrder();
      }

      /**
       * @brief Get the next BasicBlock depending on iteration order.
       * @param had_change did the user of the iteration change the previous BasicBlock.
       * @return the next BasicBlock following the iteration order, 0 if finished.
       */
      virtual BasicBlock* Next(bool had_change = false) OVERRIDE;

    private:
     const ArenaVector<BasicBlockId>* const loop_ends_;
     ArenaVector<std::pair<uint16_t, bool>>* const loop_head_stack_;
  };

  /**
   * @class LoopRepeatingTopologicalSortIterator
   * @brief Used to perform a Topological Sort Iteration of a MIRGraph, repeating loops as needed.
   * @details The iterator uses the visited flags to keep track of the blocks that need
   * recalculation and keeps a stack of loop heads in the MIRGraph. At the end of the loop
   * it returns back to the loop head if it needs to be recalculated. Due to the use of
   * the visited flags and the loop head stack in the MIRGraph, it's not possible to use
   * two iterators at the same time or modify this data during iteration (though inspection
   * of this data is allowed and sometimes even expected).
   *
   * NOTE: This iterator is not suitable for passes that need to propagate changes to
   * predecessors, such as type inferrence.
   */
  class LoopRepeatingTopologicalSortIterator : public DataflowIterator {
    public:
     /**
      * @brief The constructor, using all of the reachable blocks of the MIRGraph.
      * @param mir_graph The MIRGraph considered.
      */
     explicit LoopRepeatingTopologicalSortIterator(MIRGraph* mir_graph)
         : DataflowIterator(mir_graph, 0, mir_graph->GetTopologicalSortOrder().size()),
           loop_ends_(&mir_graph->GetTopologicalSortOrderLoopEnds()),
           loop_head_stack_(mir_graph_->GetTopologicalSortOrderLoopHeadStack()) {
       // Extra setup for RepeatingTopologicalSortIterator.
       idx_ = start_idx_;
       block_id_list_ = &mir_graph->GetTopologicalSortOrder();
       // Clear visited flags and check that the loop head stack is empty.
       mir_graph->ClearAllVisitedFlags();
       DCHECK_EQ(loop_head_stack_->size(), 0u);
     }

     ~LoopRepeatingTopologicalSortIterator() {
       DCHECK_EQ(loop_head_stack_->size(), 0u);
     }

     /**
      * @brief Get the next BasicBlock depending on iteration order.
      * @param had_change did the user of the iteration change the previous BasicBlock.
      * @return the next BasicBlock following the iteration order, 0 if finished.
      */
     virtual BasicBlock* Next(bool had_change = false) OVERRIDE;

    private:
     const ArenaVector<BasicBlockId>* const loop_ends_;
     ArenaVector<std::pair<uint16_t, bool>>* const loop_head_stack_;
  };

}  // namespace art

#endif  // ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_
