OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/flow_graph_builder.h" | 5 #include "vm/flow_graph_builder.h" |
6 | 6 |
7 #include "lib/invocation_mirror.h" | 7 #include "lib/invocation_mirror.h" |
8 #include "vm/ast_printer.h" | 8 #include "vm/ast_printer.h" |
9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 } | 90 } |
91 } | 91 } |
92 | 92 |
93 | 93 |
94 void InlineExitCollector::AddExit(ReturnInstr* exit) { | 94 void InlineExitCollector::AddExit(ReturnInstr* exit) { |
95 Data data = { NULL, exit }; | 95 Data data = { NULL, exit }; |
96 exits_.Add(data); | 96 exits_.Add(data); |
97 } | 97 } |
98 | 98 |
99 | 99 |
| 100 void InlineExitCollector::Union(const InlineExitCollector* other) { |
| 101 // It doesn't make sense to combine different calls or calls from |
| 102 // different graphs. |
| 103 ASSERT(caller_graph_ == other->caller_graph_); |
| 104 ASSERT(call_ == other->call_); |
| 105 exits_.AddArray(other->exits_); |
| 106 } |
| 107 |
| 108 |
100 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) { | 109 int InlineExitCollector::LowestBlockIdFirst(const Data* a, const Data* b) { |
101 return (a->exit_block->block_id() - b->exit_block->block_id()); | 110 return (a->exit_block->block_id() - b->exit_block->block_id()); |
102 } | 111 } |
103 | 112 |
104 | 113 |
105 void InlineExitCollector::SortExits() { | 114 void InlineExitCollector::SortExits() { |
106 // Assign block entries here because we did not necessarily know them when | 115 // Assign block entries here because we did not necessarily know them when |
107 // the return exit was added to the array. | 116 // the return exit was added to the array. |
108 for (int i = 0; i < exits_.length(); ++i) { | 117 for (int i = 0; i < exits_.length(); ++i) { |
109 exits_[i].exit_block = exits_[i].exit_return->GetBlock(); | 118 exits_[i].exit_block = exits_[i].exit_return->GetBlock(); |
(...skipping 16 matching lines...) Expand all Loading... |
126 ReturnAt(0)->UnuseAllInputs(); | 135 ReturnAt(0)->UnuseAllInputs(); |
127 *exit_block = ExitBlockAt(0); | 136 *exit_block = ExitBlockAt(0); |
128 *last_instruction = LastInstructionAt(0); | 137 *last_instruction = LastInstructionAt(0); |
129 return call_->HasUses() ? ValueAt(0)->definition() : NULL; | 138 return call_->HasUses() ? ValueAt(0)->definition() : NULL; |
130 } else { | 139 } else { |
131 // Create a join of the returns. | 140 // Create a join of the returns. |
132 intptr_t join_id = caller_graph_->max_block_id() + 1; | 141 intptr_t join_id = caller_graph_->max_block_id() + 1; |
133 caller_graph_->set_max_block_id(join_id); | 142 caller_graph_->set_max_block_id(join_id); |
134 JoinEntryInstr* join = | 143 JoinEntryInstr* join = |
135 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); | 144 new JoinEntryInstr(join_id, CatchClauseNode::kInvalidTryIndex); |
136 join->InheritDeoptTarget(call_); | 145 join->InheritDeoptTargetAfter(call_); |
137 | 146 |
138 // The dominator set of the join is the intersection of the dominator | 147 // The dominator set of the join is the intersection of the dominator |
139 // sets of all the predecessors. If we keep the dominator sets ordered | 148 // sets of all the predecessors. If we keep the dominator sets ordered |
140 // by height in the dominator tree, we can also get the immediate | 149 // by height in the dominator tree, we can also get the immediate |
141 // dominator of the join node from the intersection. | 150 // dominator of the join node from the intersection. |
142 // | 151 // |
143 // block_dominators is the dominator set for each block, ordered from | 152 // block_dominators is the dominator set for each block, ordered from |
144 // the immediate dominator to the root of the dominator tree. This is | 153 // the immediate dominator to the root of the dominator tree. This is |
145 // the order we collect them in (adding at the end). | 154 // the order we collect them in (adding at the end). |
146 // | 155 // |
(...skipping 26 matching lines...) Expand all Loading... |
173 } | 182 } |
174 } else { | 183 } else { |
175 // Intersect the block's dominators with the join's dominators so far. | 184 // Intersect the block's dominators with the join's dominators so far. |
176 intptr_t last = block_dominators.length() - 1; | 185 intptr_t last = block_dominators.length() - 1; |
177 for (intptr_t j = 0; j < join_dominators.length(); ++j) { | 186 for (intptr_t j = 0; j < join_dominators.length(); ++j) { |
178 intptr_t k = last - j; // Corresponding index in block_dominators. | 187 intptr_t k = last - j; // Corresponding index in block_dominators. |
179 if ((k < 0) || (join_dominators[j] != block_dominators[k])) { | 188 if ((k < 0) || (join_dominators[j] != block_dominators[k])) { |
180 // We either exhausted the dominators for this block before | 189 // We either exhausted the dominators for this block before |
181 // exhausting the current intersection, or else we found a block | 190 // exhausting the current intersection, or else we found a block |
182 // on the path from the root of the tree that is not in common. | 191 // on the path from the root of the tree that is not in common. |
183 ASSERT(j >= 2); | 192 // I.e., there cannot be an empty set of dominators. |
| 193 ASSERT(j > 0); |
184 join_dominators.TruncateTo(j); | 194 join_dominators.TruncateTo(j); |
185 break; | 195 break; |
186 } | 196 } |
187 } | 197 } |
188 } | 198 } |
189 } | 199 } |
190 // The immediate dominator of the join is the last one in the ordered | 200 // The immediate dominator of the join is the last one in the ordered |
191 // intersection. | 201 // intersection. |
192 join->set_dominator(join_dominators.Last()); | |
193 join_dominators.Last()->AddDominatedBlock(join); | 202 join_dominators.Last()->AddDominatedBlock(join); |
194 *exit_block = join; | 203 *exit_block = join; |
195 *last_instruction = join; | 204 *last_instruction = join; |
196 | 205 |
197 // If the call has uses, create a phi of the returns. | 206 // If the call has uses, create a phi of the returns. |
198 if (call_->HasUses()) { | 207 if (call_->HasUses()) { |
199 // Add a phi of the return values. | 208 // Add a phi of the return values. |
200 PhiInstr* phi = new PhiInstr(join, num_exits); | 209 PhiInstr* phi = new PhiInstr(join, num_exits); |
201 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); | 210 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); |
202 phi->mark_alive(); | 211 phi->mark_alive(); |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
266 call_block->ReplaceAsPredecessorWith(callee_exit); | 275 call_block->ReplaceAsPredecessorWith(callee_exit); |
267 // For successors of 'inlined_head', the callee entry (Bi) is replaced | 276 // For successors of 'inlined_head', the callee entry (Bi) is replaced |
268 // as a predecessor by the call block (Bc). | 277 // as a predecessor by the call block (Bc). |
269 callee_entry->ReplaceAsPredecessorWith(call_block); | 278 callee_entry->ReplaceAsPredecessorWith(call_block); |
270 | 279 |
271 // The callee exit is now the immediate dominator of blocks whose | 280 // The callee exit is now the immediate dominator of blocks whose |
272 // immediate dominator was the call block. | 281 // immediate dominator was the call block. |
273 ASSERT(callee_exit->dominated_blocks().is_empty()); | 282 ASSERT(callee_exit->dominated_blocks().is_empty()); |
274 for (intptr_t i = 0; i < call_block->dominated_blocks().length(); ++i) { | 283 for (intptr_t i = 0; i < call_block->dominated_blocks().length(); ++i) { |
275 BlockEntryInstr* block = call_block->dominated_blocks()[i]; | 284 BlockEntryInstr* block = call_block->dominated_blocks()[i]; |
276 block->set_dominator(callee_exit); | |
277 callee_exit->AddDominatedBlock(block); | 285 callee_exit->AddDominatedBlock(block); |
278 } | 286 } |
279 // The call block is now the immediate dominator of blocks whose | 287 // The call block is now the immediate dominator of blocks whose |
280 // immediate dominator was the callee entry. | 288 // immediate dominator was the callee entry. |
281 call_block->ClearDominatedBlocks(); | 289 call_block->ClearDominatedBlocks(); |
282 for (intptr_t i = 0; i < callee_entry->dominated_blocks().length(); ++i) { | 290 for (intptr_t i = 0; i < callee_entry->dominated_blocks().length(); ++i) { |
283 BlockEntryInstr* block = callee_entry->dominated_blocks()[i]; | 291 BlockEntryInstr* block = callee_entry->dominated_blocks()[i]; |
284 block->set_dominator(call_block); | |
285 call_block->AddDominatedBlock(block); | 292 call_block->AddDominatedBlock(block); |
286 } | 293 } |
287 } | 294 } |
288 } | 295 } |
289 | 296 |
290 | 297 |
291 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { | 298 void EffectGraphVisitor::Append(const EffectGraphVisitor& other_fragment) { |
292 ASSERT(is_open()); | 299 ASSERT(is_open()); |
293 if (other_fragment.is_empty()) return; | 300 if (other_fragment.is_empty()) return; |
294 if (is_empty()) { | 301 if (is_empty()) { |
(...skipping 3080 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3375 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 3382 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
3376 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 3383 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
3377 OS::SNPrint(chars, len, kFormat, function_name, reason); | 3384 OS::SNPrint(chars, len, kFormat, function_name, reason); |
3378 const Error& error = Error::Handle( | 3385 const Error& error = Error::Handle( |
3379 LanguageError::New(String::Handle(String::New(chars)))); | 3386 LanguageError::New(String::Handle(String::New(chars)))); |
3380 Isolate::Current()->long_jump_base()->Jump(1, error); | 3387 Isolate::Current()->long_jump_base()->Jump(1, error); |
3381 } | 3388 } |
3382 | 3389 |
3383 | 3390 |
3384 } // namespace dart | 3391 } // namespace dart |
OLD | NEW |