blob: 6a3975ed83967879cc52f1b3bb6b8124f7a16c83 [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
17#include "dataflow_iterator.h"
18
19namespace art {
20
21 DataflowIterator::DataflowIterator(MIRGraph* mir_graph, DataFlowAnalysisMode dfa_mode, bool is_iterative)
22 : mir_graph_(mir_graph),
23 mode_(dfa_mode),
24 is_iterative_(is_iterative),
25 changed_(false) {
26 switch(mode_) {
27 case kAllNodes:
28 GrowableListIteratorInit(mir_graph_->GetBlockList(), &all_nodes_iterator_);
29 break;
30
31 case kReachableNodes:
32 case kPreOrderDFSTraversal:
33 start_idx_ = 0;
34 end_idx_ = mir_graph_->GetNumReachableBlocks();
35 idx_ = start_idx_;
36 block_id_list_ = mir_graph_->GetDfsOrder();
37 reverse_ = false;
38 break;
39
40 case kPostOrderDFSTraversal:
41 start_idx_ = mir_graph_->GetNumReachableBlocks() - 1;
42 end_idx_ = 0;
43 idx_ = start_idx_;
44 block_id_list_ = mir_graph_->GetDfsOrder();
45 reverse_ = true;
46 break;
47
48 case kPostOrderDOMTraversal:
49 start_idx_ = 0;
50 end_idx_ = mir_graph_->GetNumReachableBlocks();
51 idx_ = start_idx_;
52 block_id_list_ = mir_graph_->GetDomPostOrder();
53 reverse_ = false;
54 break;
55
56 case kReversePostOrderTraversal:
57 start_idx_ = mir_graph_->GetNumReachableBlocks() - 1;
58 end_idx_ = 0;
59 idx_ = start_idx_;
60 block_id_list_ = mir_graph_->GetDfsPostOrder();
61 reverse_ = true;
62 break;
63 default:
64 LOG(FATAL) << "Unknown traversal mode: " << dfa_mode;
65 }
66 }
67
68 BasicBlock* DataflowIterator::NextBody(bool had_change)
69 {
70 changed_ |= had_change;
71 BasicBlock* res = NULL;
72 if (mode_ == kAllNodes) {
73 bool keep_looking = true;
74 while (keep_looking) {
75 res = reinterpret_cast<BasicBlock*>(GrowableListIteratorNext(&all_nodes_iterator_));
76 if (is_iterative_ && changed_ && (res == NULL)) {
77 GrowableListIteratorInit(mir_graph_->GetBlockList(), &all_nodes_iterator_);
78 changed_ = false;
79 } else if ((res == NULL) || (!res->hidden)) {
80 keep_looking = false;
81 }
82 }
83 } else if (reverse_) {
84 if (is_iterative_ && changed_ && (idx_ < 0)) {
85 idx_ = start_idx_;
86 changed_ = false;
87 }
88 if (idx_ >= 0) {
89 int bb_id = block_id_list_->elem_list[idx_--];
90 res = mir_graph_->GetBasicBlock(bb_id);
91 }
92 } else {
93 if (is_iterative_ && changed_ && (idx_ >= end_idx_)) {
94 idx_ = start_idx_;
95 changed_ = false;
96 }
97 if (idx_ < end_idx_) {
98 int bb_id = block_id_list_->elem_list[idx_++];
99 res = mir_graph_->GetBasicBlock(bb_id);
100 }
101 }
102 return res;
103 }
104
105 BasicBlock* DataflowIterator::Next(bool had_change)
106 {
107 DCHECK(is_iterative_);
108 return NextBody(had_change);
109 }
110
111 BasicBlock* DataflowIterator::Next()
112 {
113 DCHECK(!is_iterative_);
114 return NextBody(false);
115 }
116
117} // namespace art