Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(275)

Side by Side Diff: runtime/vm/flow_graph_builder.cc

Issue 14740005: Initial support for polymorphic inlining. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Incorporated review comments. Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.h ('k') | runtime/vm/flow_graph_compiler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698