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 | 1da1e2f | 2013-11-15 13:37:01 -0800 | [diff] [blame] | 40 | int32_t GetRepeatCount() { return repeats_; } |
buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 41 | |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 42 | protected: |
buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 43 | DataflowIterator(MIRGraph* mir_graph, int32_t start_idx, int32_t end_idx) |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 44 | : mir_graph_(mir_graph), |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 45 | start_idx_(start_idx), |
| 46 | end_idx_(end_idx), |
Ian Rogers | e7a5b7d | 2013-04-18 20:09:02 -0700 | [diff] [blame] | 47 | block_id_list_(NULL), |
| 48 | idx_(0), |
buzbee | 1da1e2f | 2013-11-15 13:37:01 -0800 | [diff] [blame] | 49 | repeats_(0), |
Ian Rogers | e7a5b7d | 2013-04-18 20:09:02 -0700 | [diff] [blame] | 50 | changed_(false) {} |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 51 | |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 52 | virtual BasicBlock* ForwardSingleNext() ALWAYS_INLINE; |
| 53 | virtual BasicBlock* ReverseSingleNext() ALWAYS_INLINE; |
| 54 | virtual BasicBlock* ForwardRepeatNext(bool had_change) ALWAYS_INLINE; |
| 55 | virtual BasicBlock* ReverseRepeatNext(bool had_change) ALWAYS_INLINE; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 56 | |
buzbee | 1da1e2f | 2013-11-15 13:37:01 -0800 | [diff] [blame] | 57 | |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 58 | MIRGraph* const mir_graph_; |
buzbee | 0d82948 | 2013-10-11 15:24:55 -0700 | [diff] [blame] | 59 | const int32_t start_idx_; |
| 60 | const int32_t end_idx_; |
| 61 | GrowableArray<BasicBlockId>* block_id_list_; |
| 62 | int32_t idx_; |
buzbee | 1da1e2f | 2013-11-15 13:37:01 -0800 | [diff] [blame] | 63 | int32_t repeats_; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 64 | bool changed_; |
Brian Carlstrom | 7934ac2 | 2013-07-26 10:54:15 -0700 | [diff] [blame] | 65 | }; // DataflowIterator |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 66 | |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 67 | class PreOrderDfsIterator : public DataflowIterator { |
| 68 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 69 | explicit PreOrderDfsIterator(MIRGraph* mir_graph) |
| 70 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 71 | idx_ = start_idx_; |
| 72 | block_id_list_ = mir_graph->GetDfsOrder(); |
| 73 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 74 | |
| 75 | BasicBlock* Next() { |
| 76 | return ForwardSingleNext(); |
| 77 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 78 | }; |
| 79 | |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 80 | class RepeatingPreOrderDfsIterator : public DataflowIterator { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 81 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 82 | explicit RepeatingPreOrderDfsIterator(MIRGraph* mir_graph) |
| 83 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
| 84 | idx_ = start_idx_; |
| 85 | block_id_list_ = mir_graph->GetDfsOrder(); |
| 86 | } |
| 87 | |
| 88 | BasicBlock* Next(bool had_change) { |
| 89 | return ForwardRepeatNext(had_change); |
| 90 | } |
| 91 | }; |
| 92 | |
| 93 | class RepeatingPostOrderDfsIterator : public DataflowIterator { |
| 94 | public: |
| 95 | explicit RepeatingPostOrderDfsIterator(MIRGraph* mir_graph) |
| 96 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 97 | idx_ = start_idx_; |
| 98 | block_id_list_ = mir_graph->GetDfsPostOrder(); |
| 99 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 100 | |
| 101 | BasicBlock* Next(bool had_change) { |
| 102 | return ForwardRepeatNext(had_change); |
| 103 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 104 | }; |
| 105 | |
| 106 | class ReversePostOrderDfsIterator : public DataflowIterator { |
| 107 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 108 | explicit ReversePostOrderDfsIterator(MIRGraph* mir_graph) |
| 109 | : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 110 | idx_ = start_idx_; |
| 111 | block_id_list_ = mir_graph->GetDfsPostOrder(); |
| 112 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 113 | |
| 114 | BasicBlock* Next() { |
| 115 | return ReverseSingleNext(); |
| 116 | } |
| 117 | }; |
| 118 | |
| 119 | class RepeatingReversePostOrderDfsIterator : public DataflowIterator { |
| 120 | public: |
| 121 | explicit RepeatingReversePostOrderDfsIterator(MIRGraph* mir_graph) |
| 122 | : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) { |
| 123 | idx_ = start_idx_; |
| 124 | block_id_list_ = mir_graph->GetDfsPostOrder(); |
| 125 | } |
| 126 | |
| 127 | BasicBlock* Next(bool had_change) { |
| 128 | return ReverseRepeatNext(had_change); |
| 129 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 130 | }; |
| 131 | |
| 132 | class PostOrderDOMIterator : public DataflowIterator { |
| 133 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 134 | explicit PostOrderDOMIterator(MIRGraph* mir_graph) |
| 135 | : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) { |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 136 | idx_ = start_idx_; |
| 137 | block_id_list_ = mir_graph->GetDomPostOrder(); |
| 138 | } |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 139 | |
| 140 | BasicBlock* Next() { |
| 141 | return ForwardSingleNext(); |
| 142 | } |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 143 | }; |
| 144 | |
| 145 | class AllNodesIterator : public DataflowIterator { |
| 146 | public: |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 147 | explicit AllNodesIterator(MIRGraph* mir_graph) |
| 148 | : DataflowIterator(mir_graph, 0, 0) { |
| 149 | all_nodes_iterator_ = new |
| 150 | (mir_graph->GetArena()) GrowableArray<BasicBlock*>::Iterator(mir_graph->GetBlockList()); |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 151 | } |
| 152 | |
Ian Rogers | 8d3a117 | 2013-06-04 01:13:28 -0700 | [diff] [blame] | 153 | void Reset() { |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 154 | all_nodes_iterator_->Reset(); |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 155 | } |
| 156 | |
buzbee | 56c7178 | 2013-09-05 17:13:19 -0700 | [diff] [blame] | 157 | BasicBlock* Next() ALWAYS_INLINE; |
buzbee | 862a760 | 2013-04-05 10:58:54 -0700 | [diff] [blame] | 158 | |
| 159 | private: |
| 160 | GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_; |
buzbee | 0665fe0 | 2013-03-21 12:32:21 -0700 | [diff] [blame] | 161 | }; |
| 162 | |
buzbee | 311ca16 | 2013-02-28 15:56:43 -0800 | [diff] [blame] | 163 | } // namespace art |
| 164 | |
Brian Carlstrom | fc0e321 | 2013-07-17 14:40:12 -0700 | [diff] [blame] | 165 | #endif // ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_ |