blob: a0c1c123e7f87e0c6e3796326701f0bb61c75089 [file] [log] [blame]
buzbee311ca162013-02-28 15:56:43 -08001/*
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 Carlstromfc0e3212013-07-17 14:40:12 -070017#ifndef ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_
18#define ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_
buzbee311ca162013-02-28 15:56:43 -080019
20#include "compiler_ir.h"
21#include "mir_graph.h"
22
23namespace art {
24
buzbee0665fe02013-03-21 12:32:21 -070025 /*
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,
buzbee56c71782013-09-05 17:13:19 -070030 * 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.
buzbee0665fe02013-03-21 12:32:21 -070036 */
buzbee311ca162013-02-28 15:56:43 -080037 class DataflowIterator {
38 public:
Brian Carlstrom2ce745c2013-07-17 17:44:30 -070039 virtual ~DataflowIterator() {}
buzbee1da1e2f2013-11-15 13:37:01 -080040 int32_t GetRepeatCount() { return repeats_; }
buzbee311ca162013-02-28 15:56:43 -080041
buzbee0665fe02013-03-21 12:32:21 -070042 protected:
buzbee0d829482013-10-11 15:24:55 -070043 DataflowIterator(MIRGraph* mir_graph, int32_t start_idx, int32_t end_idx)
buzbee0665fe02013-03-21 12:32:21 -070044 : mir_graph_(mir_graph),
buzbee0665fe02013-03-21 12:32:21 -070045 start_idx_(start_idx),
46 end_idx_(end_idx),
Ian Rogerse7a5b7d2013-04-18 20:09:02 -070047 block_id_list_(NULL),
48 idx_(0),
buzbee1da1e2f2013-11-15 13:37:01 -080049 repeats_(0),
Ian Rogerse7a5b7d2013-04-18 20:09:02 -070050 changed_(false) {}
buzbee0665fe02013-03-21 12:32:21 -070051
buzbee56c71782013-09-05 17:13:19 -070052 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;
buzbee0665fe02013-03-21 12:32:21 -070056
buzbee1da1e2f2013-11-15 13:37:01 -080057
buzbee0665fe02013-03-21 12:32:21 -070058 MIRGraph* const mir_graph_;
buzbee0d829482013-10-11 15:24:55 -070059 const int32_t start_idx_;
60 const int32_t end_idx_;
61 GrowableArray<BasicBlockId>* block_id_list_;
62 int32_t idx_;
buzbee1da1e2f2013-11-15 13:37:01 -080063 int32_t repeats_;
buzbee0665fe02013-03-21 12:32:21 -070064 bool changed_;
Brian Carlstrom7934ac22013-07-26 10:54:15 -070065 }; // DataflowIterator
buzbee0665fe02013-03-21 12:32:21 -070066
buzbee0665fe02013-03-21 12:32:21 -070067 class PreOrderDfsIterator : public DataflowIterator {
68 public:
buzbee56c71782013-09-05 17:13:19 -070069 explicit PreOrderDfsIterator(MIRGraph* mir_graph)
70 : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
buzbee0665fe02013-03-21 12:32:21 -070071 idx_ = start_idx_;
72 block_id_list_ = mir_graph->GetDfsOrder();
73 }
buzbee56c71782013-09-05 17:13:19 -070074
75 BasicBlock* Next() {
76 return ForwardSingleNext();
77 }
buzbee0665fe02013-03-21 12:32:21 -070078 };
79
buzbee56c71782013-09-05 17:13:19 -070080 class RepeatingPreOrderDfsIterator : public DataflowIterator {
buzbee0665fe02013-03-21 12:32:21 -070081 public:
buzbee56c71782013-09-05 17:13:19 -070082 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()) {
buzbee0665fe02013-03-21 12:32:21 -070097 idx_ = start_idx_;
98 block_id_list_ = mir_graph->GetDfsPostOrder();
99 }
buzbee56c71782013-09-05 17:13:19 -0700100
101 BasicBlock* Next(bool had_change) {
102 return ForwardRepeatNext(had_change);
103 }
buzbee0665fe02013-03-21 12:32:21 -0700104 };
105
106 class ReversePostOrderDfsIterator : public DataflowIterator {
107 public:
buzbee56c71782013-09-05 17:13:19 -0700108 explicit ReversePostOrderDfsIterator(MIRGraph* mir_graph)
109 : DataflowIterator(mir_graph, mir_graph->GetNumReachableBlocks() -1, 0) {
buzbee0665fe02013-03-21 12:32:21 -0700110 idx_ = start_idx_;
111 block_id_list_ = mir_graph->GetDfsPostOrder();
112 }
buzbee56c71782013-09-05 17:13:19 -0700113
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 }
buzbee0665fe02013-03-21 12:32:21 -0700130 };
131
132 class PostOrderDOMIterator : public DataflowIterator {
133 public:
buzbee56c71782013-09-05 17:13:19 -0700134 explicit PostOrderDOMIterator(MIRGraph* mir_graph)
135 : DataflowIterator(mir_graph, 0, mir_graph->GetNumReachableBlocks()) {
buzbee0665fe02013-03-21 12:32:21 -0700136 idx_ = start_idx_;
137 block_id_list_ = mir_graph->GetDomPostOrder();
138 }
buzbee56c71782013-09-05 17:13:19 -0700139
140 BasicBlock* Next() {
141 return ForwardSingleNext();
142 }
buzbee0665fe02013-03-21 12:32:21 -0700143 };
144
145 class AllNodesIterator : public DataflowIterator {
146 public:
buzbee56c71782013-09-05 17:13:19 -0700147 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());
buzbee862a7602013-04-05 10:58:54 -0700151 }
152
Ian Rogers8d3a1172013-06-04 01:13:28 -0700153 void Reset() {
buzbee862a7602013-04-05 10:58:54 -0700154 all_nodes_iterator_->Reset();
buzbee0665fe02013-03-21 12:32:21 -0700155 }
156
buzbee56c71782013-09-05 17:13:19 -0700157 BasicBlock* Next() ALWAYS_INLINE;
buzbee862a7602013-04-05 10:58:54 -0700158
159 private:
160 GrowableArray<BasicBlock*>::Iterator* all_nodes_iterator_;
buzbee0665fe02013-03-21 12:32:21 -0700161 };
162
buzbee311ca162013-02-28 15:56:43 -0800163} // namespace art
164
Brian Carlstromfc0e3212013-07-17 14:40:12 -0700165#endif // ART_COMPILER_DEX_DATAFLOW_ITERATOR_H_