buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2013 The Android Open Source Project |
| 3 | * |
| 4 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | * you may not use this file except in compliance with the License. |
| 6 | * You may obtain a copy of the License at |
| 7 | * |
| 8 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | * |
| 10 | * Unless required by applicable law or agreed to in writing, software |
| 11 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. |
| 15 | */ |
| 16 | |
Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 17 | #ifndef ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_ |
| 18 | #define ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_ |
buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 19 | |
| 20 | #include "compiler_ir.h" |
| 21 | #include "mir_graph.h" |
| 22 | |
| 23 | namespace art { |
| 24 | |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 25 | /* |
| 26 | * This class supports iterating over lists of basic blocks in various |
| 27 | * interesting orders. Note that for efficiency, the visit orders have been pre-computed. |
| 28 | * The order itself will not change during the iteration. However, for some uses, |
| 29 | * auxiliary data associated with the basic blocks may be changed during the iteration, |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 30 | * necessitating another pass over the list. If this behavior is required, use the |
| 31 | * "Repeating" variant. For the repeating variant, the caller must tell the iterator |
| 32 | * whether a change has been made that necessitates another pass. Note that calling Next(true) |
| 33 | * does not affect the iteration order or short-circuit the current pass - it simply tells |
| 34 | * the iterator that once it has finished walking through the block list it should reset and |
| 35 | * do another full pass through the list. |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 36 | */ |
buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 37 | class DataflowIterator { |
| 38 | public: |
Brian Carlstrom | 2ce745c | 2013-07-17 17:44:30 -0700 | [diff] [blame] | 39 | virtual ~DataflowIterator() {} |
buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 40 | |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 41 | protected: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 42 | DataflowIterator(MIRGraph* mir_graph, int start_idx, int end_idx) |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 43 | : mir_graph_(mir_graph), |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 44 | start_idx_(start_idx), |
| 45 | end_idx_(end_idx), |
Ian Rogers | e7a5b7d | 2013-04-18 20:09:02 -0700 | [diff] [blame] | 46 | block_id_list_(NULL), |
| 47 | idx_(0), |
| 48 | changed_(false) {} |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 49 | |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 50 | virtual BasicBlock* ForwardSingleNext() ALWAYS_INLINE; |
| 51 | virtual BasicBlock* ReverseSingleNext() ALWAYS_INLINE; |
| 52 | virtual BasicBlock* ForwardRepeatNext(bool had_change) ALWAYS_INLINE; |
| 53 | virtual BasicBlock* ReverseRepeatNext(bool had_change) ALWAYS_INLINE; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 54 | |
| 55 | MIRGraph* const mir_graph_; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 56 | const int start_idx_; |
| 57 | const int end_idx_; |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 58 | GrowableArray<int>* block_id_list_; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 59 | int idx_; |
| 60 | bool changed_; |
Brian Carlstrom | 7934ac2 | 2013-07-26 10:54:15 -0700 | [diff] [blame] | 61 | }; // DataflowIterator |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 62 | |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 63 | class PreOrderDfsIterator : public DataflowIterator { |
| 64 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 65 | explicit PreOrderDfsIterator(MIRGraph* mir_graph) |
| 66 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 67 | idx_ = start_idx_; |
| 68 | block_id_list_ = mir_graph->GetDfsOrder(); |
| 69 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 70 | |
| 71 | BasicBlock* Next() { |
| 72 | return ForwardSingleNext(); |
| 73 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 74 | }; |
| 75 | |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 76 | class RepeatingPreOrderDfsIterator : public DataflowIterator { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 77 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 78 | explicit RepeatingPreOrderDfsIterator(MIRGraph* mir_graph) |
| 79 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
| 80 | idx_ = start_idx_; |
| 81 | block_id_list_ = mir_graph->GetDfsOrder(); |
| 82 | } |
| 83 | |
| 84 | BasicBlock* Next(bool had_change) { |
| 85 | return ForwardRepeatNext(had_change); |
| 86 | } |
| 87 | }; |
| 88 | |
| 89 | class RepeatingPostOrderDfsIterator : public DataflowIterator { |
| 90 | public: |
| 91 | explicit RepeatingPostOrderDfsIterator(MIRGraph* mir_graph) |
| 92 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 93 | idx_ = start_idx_; |
| 94 | block_id_list_ = mir_graph->GetDfsPostOrder(); |
| 95 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 96 | |
| 97 | BasicBlock* Next(bool had_change) { |
| 98 | return ForwardRepeatNext(had_change); |
| 99 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 100 | }; |
| 101 | |
| 102 | class ReversePostOrderDfsIterator : public DataflowIterator { |
| 103 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 104 | explicit ReversePostOrderDfsIterator(MIRGraph* mir_graph) |
| 105 | : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 106 | idx_ = start_idx_; |
| 107 | block_id_list_ = mir_graph->GetDfsPostOrder(); |
| 108 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 109 | |
| 110 | BasicBlock* Next() { |
| 111 | return ReverseSingleNext(); |
| 112 | } |
| 113 | }; |
| 114 | |
| 115 | class RepeatingReversePostOrderDfsIterator : public DataflowIterator { |
| 116 | public: |
| 117 | explicit RepeatingReversePostOrderDfsIterator(MIRGraph* mir_graph) |
| 118 | : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) { |
| 119 | idx_ = start_idx_; |
| 120 | block_id_list_ = mir_graph->GetDfsPostOrder(); |
| 121 | } |
| 122 | |
| 123 | BasicBlock* Next(bool had_change) { |
| 124 | return ReverseRepeatNext(had_change); |
| 125 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 126 | }; |
| 127 | |
| 128 | class PostOrderDOMIterator : public DataflowIterator { |
| 129 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 130 | explicit PostOrderDOMIterator(MIRGraph* mir_graph) |
| 131 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 132 | idx_ = start_idx_; |
| 133 | block_id_list_ = mir_graph->GetDomPostOrder(); |
| 134 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 135 | |
| 136 | BasicBlock* Next() { |
| 137 | return ForwardSingleNext(); |
| 138 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 139 | }; |
| 140 | |
| 141 | class AllNodesIterator : public DataflowIterator { |
| 142 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 143 | explicit AllNodesIterator(MIRGraph* mir_graph) |
| 144 | : DataflowIterator(mir_graph, 0, 0) { |
| 145 | all_nodes_iterator_ = new |
| 146 | (mir_graph->GetArena()) GrowableArray<BasicBlock*>::Iterator(mir_graph->GetBlockList()); |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 147 | } |
| 148 | |
Ian Rogers | 8d3a117 | 2013-06-04 01:13:28 -0700 | [diff] [blame] | 149 | void Reset() { |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 150 | all_nodes_iterator_->Reset(); |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 151 | } |
| 152 | |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 153 | BasicBlock* Next() ALWAYS_INLINE; |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 154 | |
| 155 | private: |
| 156 | GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 157 | }; |
| 158 | |
buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 159 | } // namespace art |
| 160 | |
Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 161 | #endif // ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_ |