dataflow_iterator.h revision 0d82948094d9a198e01aa95f64012bdedd5b6fc9
1311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee/*
2311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Copyright (C) 2013 The Android Open Source Project
3311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *
4311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Licensed under the Apache License, Version 2.0 (the "License");
5311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * you may not use this file except in compliance with the License.
6311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * You may obtain a copy of the License at
7311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *
8311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *      http://www.apache.org/licenses/LICENSE-2.0
9311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee *
10311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * Unless required by applicable law or agreed to in writing, software
11311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * distributed under the License is distributed on an "AS IS" BASIS,
12311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * See the License for the specific language governing permissions and
14311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee * limitations under the License.
15311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee */
16311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
17fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#ifndef ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_
18fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#define ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_
19311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
20311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "compiler_ir.h"
21311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee#include "mir_graph.h"
22311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
23311ca169f4727d46a55bdc8dfa0059719fa72b65buzbeenamespace art {
24311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
250665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  /*
260665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee   * This class supports iterating over lists of basic blocks in various
270665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee   * interesting orders.  Note that for efficiency, the visit orders have been pre-computed.
280665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee   * The order itself will not change during the iteration.  However, for some uses,
290665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee   * auxiliary data associated with the basic blocks may be changed during the iteration,
3056c717860df2d71d66fb77aa77f29dd346e559d3buzbee   * necessitating another pass over the list.  If this behavior is required, use the
3156c717860df2d71d66fb77aa77f29dd346e559d3buzbee   * "Repeating" variant.  For the repeating variant, the caller must tell the iterator
3256c717860df2d71d66fb77aa77f29dd346e559d3buzbee   * whether a change has been made that necessitates another pass.  Note that calling Next(true)
3356c717860df2d71d66fb77aa77f29dd346e559d3buzbee   * does not affect the iteration order or short-circuit the current pass - it simply tells
3456c717860df2d71d66fb77aa77f29dd346e559d3buzbee   * the iterator that once it has finished walking through the block list it should reset and
3556c717860df2d71d66fb77aa77f29dd346e559d3buzbee   * do another full pass through the list.
360665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee   */
37311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee  class DataflowIterator {
38311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee    public:
392ce745c06271d5223d57dbf08117b20d5b60694aBrian Carlstrom      virtual ~DataflowIterator() {}
40311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
410665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    protected:
420d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      DataflowIterator(MIRGraph* mir_graph, int32_t start_idx, int32_t end_idx)
430665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee          : mir_graph_(mir_graph),
440665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee            start_idx_(start_idx),
450665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee            end_idx_(end_idx),
46e7a5b7d3fcc3af100fec13af057eecaff1037f2cIan Rogers            block_id_list_(NULL),
47e7a5b7d3fcc3af100fec13af057eecaff1037f2cIan Rogers            idx_(0),
48e7a5b7d3fcc3af100fec13af057eecaff1037f2cIan Rogers            changed_(false) {}
490665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
5056c717860df2d71d66fb77aa77f29dd346e559d3buzbee      virtual BasicBlock* ForwardSingleNext() ALWAYS_INLINE;
5156c717860df2d71d66fb77aa77f29dd346e559d3buzbee      virtual BasicBlock* ReverseSingleNext() ALWAYS_INLINE;
5256c717860df2d71d66fb77aa77f29dd346e559d3buzbee      virtual BasicBlock* ForwardRepeatNext(bool had_change) ALWAYS_INLINE;
5356c717860df2d71d66fb77aa77f29dd346e559d3buzbee      virtual BasicBlock* ReverseRepeatNext(bool had_change) ALWAYS_INLINE;
540665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
550665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      MIRGraph* const mir_graph_;
560d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      const int32_t start_idx_;
570d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      const int32_t end_idx_;
580d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      GrowableArray<BasicBlockId>* block_id_list_;
590d82948094d9a198e01aa95f64012bdedd5b6fc9buzbee      int32_t idx_;
600665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      bool changed_;
617934ac288acfb2552bb0b06ec1f61e5820d924a4Brian Carlstrom  };  // DataflowIterator
620665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
6356c717860df2d71d66fb77aa77f29dd346e559d3buzbee  class PreOrderDfsIterator : public DataflowIterator {
640665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    public:
6556c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit PreOrderDfsIterator(MIRGraph* mir_graph)
6656c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
670665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        idx_ = start_idx_;
680665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        block_id_list_ = mir_graph->GetDfsOrder();
690665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      }
7056c717860df2d71d66fb77aa77f29dd346e559d3buzbee
7156c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next() {
7256c717860df2d71d66fb77aa77f29dd346e559d3buzbee        return ForwardSingleNext();
7356c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
740665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  };
750665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
7656c717860df2d71d66fb77aa77f29dd346e559d3buzbee  class RepeatingPreOrderDfsIterator : public DataflowIterator {
770665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    public:
7856c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit RepeatingPreOrderDfsIterator(MIRGraph* mir_graph)
7956c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
800665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        idx_ = start_idx_;
810665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        block_id_list_ = mir_graph->GetDfsOrder();
820665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      }
8356c717860df2d71d66fb77aa77f29dd346e559d3buzbee
8456c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next(bool had_change) {
8556c717860df2d71d66fb77aa77f29dd346e559d3buzbee        return ForwardRepeatNext(had_change);
8656c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
870665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  };
880665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
8956c717860df2d71d66fb77aa77f29dd346e559d3buzbee  class RepeatingPostOrderDfsIterator : public DataflowIterator {
900665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    public:
9156c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit RepeatingPostOrderDfsIterator(MIRGraph* mir_graph)
9256c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
930665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        idx_ = start_idx_;
940665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        block_id_list_ = mir_graph->GetDfsPostOrder();
950665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      }
9656c717860df2d71d66fb77aa77f29dd346e559d3buzbee
9756c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next(bool had_change) {
9856c717860df2d71d66fb77aa77f29dd346e559d3buzbee        return ForwardRepeatNext(had_change);
9956c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
1000665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  };
1010665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
1020665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  class ReversePostOrderDfsIterator : public DataflowIterator {
1030665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    public:
10456c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit ReversePostOrderDfsIterator(MIRGraph* mir_graph)
10556c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) {
10656c717860df2d71d66fb77aa77f29dd346e559d3buzbee        idx_ = start_idx_;
10756c717860df2d71d66fb77aa77f29dd346e559d3buzbee        block_id_list_ = mir_graph->GetDfsPostOrder();
10856c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
10956c717860df2d71d66fb77aa77f29dd346e559d3buzbee
11056c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next() {
11156c717860df2d71d66fb77aa77f29dd346e559d3buzbee        return ReverseSingleNext();
11256c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
11356c717860df2d71d66fb77aa77f29dd346e559d3buzbee  };
11456c717860df2d71d66fb77aa77f29dd346e559d3buzbee
11556c717860df2d71d66fb77aa77f29dd346e559d3buzbee  class RepeatingReversePostOrderDfsIterator : public DataflowIterator {
11656c717860df2d71d66fb77aa77f29dd346e559d3buzbee    public:
11756c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit RepeatingReversePostOrderDfsIterator(MIRGraph* mir_graph)
11856c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) {
1190665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        idx_ = start_idx_;
1200665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        block_id_list_ = mir_graph->GetDfsPostOrder();
1210665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      }
12256c717860df2d71d66fb77aa77f29dd346e559d3buzbee
12356c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next(bool had_change) {
12456c717860df2d71d66fb77aa77f29dd346e559d3buzbee        return ReverseRepeatNext(had_change);
12556c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
1260665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  };
1270665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
1280665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  class PostOrderDOMIterator : public DataflowIterator {
1290665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    public:
13056c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit PostOrderDOMIterator(MIRGraph* mir_graph)
13156c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
1320665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        idx_ = start_idx_;
1330665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee        block_id_list_ = mir_graph->GetDomPostOrder();
1340665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      }
13556c717860df2d71d66fb77aa77f29dd346e559d3buzbee
13656c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next() {
13756c717860df2d71d66fb77aa77f29dd346e559d3buzbee        return ForwardSingleNext();
13856c717860df2d71d66fb77aa77f29dd346e559d3buzbee      }
1390665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  };
1400665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
1410665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  class AllNodesIterator : public DataflowIterator {
1420665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee    public:
14356c717860df2d71d66fb77aa77f29dd346e559d3buzbee      explicit AllNodesIterator(MIRGraph* mir_graph)
14456c717860df2d71d66fb77aa77f29dd346e559d3buzbee          : DataflowIterator(mir_graph, 0, 0) {
14556c717860df2d71d66fb77aa77f29dd346e559d3buzbee        all_nodes_iterator_ = new
14656c717860df2d71d66fb77aa77f29dd346e559d3buzbee            (mir_graph->GetArena()) GrowableArray<BasicBlock*>::Iterator(mir_graph->GetBlockList());
147862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      }
148862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee
1498d3a117b374352a1853fae9b7306afeaaa9e3b91Ian Rogers      void Reset() {
150862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee        all_nodes_iterator_->Reset();
1510665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee      }
1520665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
15356c717860df2d71d66fb77aa77f29dd346e559d3buzbee      BasicBlock* Next() ALWAYS_INLINE;
154862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee
155862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee    private:
156862a76027076c341c26aa6cd4a30a7cdd6dc2143buzbee      GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_;
1570665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee  };
1580665fe0966d9591c5378a5d598c6eb6cab67e74abuzbee
159311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee}  // namespace art
160311ca169f4727d46a55bdc8dfa0059719fa72b65buzbee
161fc0e3219edc9a5bf81b166e82fd5db2796eb6a0dBrian Carlstrom#endif  // ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_
162