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

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

Issue 784223006: Adjust environments we attach to the block entries. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years 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
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/bit_vector.h" 9 #include "vm/bit_vector.h"
10 #include "vm/class_finalizer.h" 10 #include "vm/class_finalizer.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 double scale_factor = static_cast<double>(call_->CallCount()) 286 double scale_factor = static_cast<double>(call_->CallCount())
287 / static_cast<double>(caller_graph_->graph_entry()->entry_count()); 287 / static_cast<double>(caller_graph_->graph_entry()->entry_count());
288 for (BlockIterator block_it = callee_graph->postorder_iterator(); 288 for (BlockIterator block_it = callee_graph->postorder_iterator();
289 !block_it.Done(); 289 !block_it.Done();
290 block_it.Advance()) { 290 block_it.Advance()) {
291 BlockEntryInstr* block = block_it.Current(); 291 BlockEntryInstr* block = block_it.Current();
292 if (block->IsTargetEntry()) { 292 if (block->IsTargetEntry()) {
293 block->AsTargetEntry()->adjust_edge_weight(scale_factor); 293 block->AsTargetEntry()->adjust_edge_weight(scale_factor);
294 } 294 }
295 Instruction* instr = block; 295 Instruction* instr = block;
296 if (block->env() != NULL) {
297 call_->env()->DeepCopyToOuter(callee_graph->isolate(), block);
298 }
296 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 299 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
297 instr = it.Current(); 300 instr = it.Current();
298 // TODO(zerny): Avoid creating unnecessary environments. Note that some 301 // TODO(zerny): Avoid creating unnecessary environments. Note that some
299 // optimizations need deoptimization info for non-deoptable instructions, 302 // optimizations need deoptimization info for non-deoptable instructions,
300 // eg, LICM on GOTOs. 303 // eg, LICM on GOTOs.
301 if (instr->env() != NULL) { 304 if (instr->env() != NULL) {
302 call_->env()->DeepCopyToOuter(callee_graph->isolate(), instr); 305 call_->env()->DeepCopyToOuter(callee_graph->isolate(), instr);
303 } 306 }
304 } 307 }
305 if (instr->IsGoto()) { 308 if (instr->IsGoto()) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 *exit_block = ExitBlockAt(0); 354 *exit_block = ExitBlockAt(0);
352 *last_instruction = LastInstructionAt(0); 355 *last_instruction = LastInstructionAt(0);
353 return call_->HasUses() ? ValueAt(0)->definition() : NULL; 356 return call_->HasUses() ? ValueAt(0)->definition() : NULL;
354 } else { 357 } else {
355 ASSERT(num_exits > 1); 358 ASSERT(num_exits > 1);
356 // Create a join of the returns. 359 // Create a join of the returns.
357 intptr_t join_id = caller_graph_->max_block_id() + 1; 360 intptr_t join_id = caller_graph_->max_block_id() + 1;
358 caller_graph_->set_max_block_id(join_id); 361 caller_graph_->set_max_block_id(join_id);
359 JoinEntryInstr* join = 362 JoinEntryInstr* join =
360 new(I) JoinEntryInstr(join_id, try_index); 363 new(I) JoinEntryInstr(join_id, try_index);
361 join->InheritDeoptTargetAfter(isolate(), call_);
362 364
363 // The dominator set of the join is the intersection of the dominator 365 // The dominator set of the join is the intersection of the dominator
364 // sets of all the predecessors. If we keep the dominator sets ordered 366 // sets of all the predecessors. If we keep the dominator sets ordered
365 // by height in the dominator tree, we can also get the immediate 367 // by height in the dominator tree, we can also get the immediate
366 // dominator of the join node from the intersection. 368 // dominator of the join node from the intersection.
367 // 369 //
368 // block_dominators is the dominator set for each block, ordered from 370 // block_dominators is the dominator set for each block, ordered from
369 // the immediate dominator to the root of the dominator tree. This is 371 // the immediate dominator to the root of the dominator tree. This is
370 // the order we collect them in (adding at the end). 372 // the order we collect them in (adding at the end).
371 // 373 //
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 if (call_->HasUses()) { 425 if (call_->HasUses()) {
424 // Add a phi of the return values. 426 // Add a phi of the return values.
425 PhiInstr* phi = new(I) PhiInstr(join, num_exits); 427 PhiInstr* phi = new(I) PhiInstr(join, num_exits);
426 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index()); 428 phi->set_ssa_temp_index(caller_graph_->alloc_ssa_temp_index());
427 phi->mark_alive(); 429 phi->mark_alive();
428 for (intptr_t i = 0; i < num_exits; ++i) { 430 for (intptr_t i = 0; i < num_exits; ++i) {
429 ReturnAt(i)->RemoveEnvironment(); 431 ReturnAt(i)->RemoveEnvironment();
430 phi->SetInputAt(i, ValueAt(i)); 432 phi->SetInputAt(i, ValueAt(i));
431 } 433 }
432 join->InsertPhi(phi); 434 join->InsertPhi(phi);
435 join->InheritDeoptTargetAfter(caller_graph_, call_, phi);
433 return phi; 436 return phi;
434 } else { 437 } else {
435 // In the case that the result is unused, remove the return value uses 438 // In the case that the result is unused, remove the return value uses
436 // from their definition's use list. 439 // from their definition's use list.
437 for (intptr_t i = 0; i < num_exits; ++i) { 440 for (intptr_t i = 0; i < num_exits; ++i) {
438 ReturnAt(i)->UnuseAllInputs(); 441 ReturnAt(i)->UnuseAllInputs();
439 } 442 }
443 join->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
440 return NULL; 444 return NULL;
441 } 445 }
442 } 446 }
443 } 447 }
444 448
445 449
446 void InlineExitCollector::ReplaceCall(TargetEntryInstr* callee_entry) { 450 void InlineExitCollector::ReplaceCall(TargetEntryInstr* callee_entry) {
447 ASSERT(call_->previous() != NULL); 451 ASSERT(call_->previous() != NULL);
448 ASSERT(call_->next() != NULL); 452 ASSERT(call_->next() != NULL);
449 BlockEntryInstr* call_block = call_->GetBlock(); 453 BlockEntryInstr* call_block = call_->GetBlock();
450 454
451 // Insert the callee graph into the caller graph. 455 // Insert the callee graph into the caller graph.
452 BlockEntryInstr* callee_exit = NULL; 456 BlockEntryInstr* callee_exit = NULL;
453 Instruction* callee_last_instruction = NULL; 457 Instruction* callee_last_instruction = NULL;
454 458
455 if (exits_.length() == 0) { 459 if (exits_.length() == 0) {
456 // Handle the case when there are no normal return exits from the callee 460 // Handle the case when there are no normal return exits from the callee
457 // (i.e. the callee unconditionally throws) by inserting an artificial 461 // (i.e. the callee unconditionally throws) by inserting an artificial
458 // branch (true === true). 462 // branch (true === true).
459 // The true successor is the inlined body, the false successor 463 // The true successor is the inlined body, the false successor
460 // goes to the rest of the caller graph. It is removed as unreachable code 464 // goes to the rest of the caller graph. It is removed as unreachable code
461 // by the constant propagation. 465 // by the constant propagation.
462 TargetEntryInstr* false_block = 466 TargetEntryInstr* false_block =
463 new(I) TargetEntryInstr(caller_graph_->allocate_block_id(), 467 new(I) TargetEntryInstr(caller_graph_->allocate_block_id(),
464 call_block->try_index()); 468 call_block->try_index());
465 false_block->InheritDeoptTargetAfter(isolate(), call_); 469 false_block->InheritDeoptTargetAfter(caller_graph_, call_, NULL);
466 false_block->LinkTo(call_->next()); 470 false_block->LinkTo(call_->next());
467 call_block->ReplaceAsPredecessorWith(false_block); 471 call_block->ReplaceAsPredecessorWith(false_block);
468 472
469 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True()); 473 ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
470 BranchInstr* branch = 474 BranchInstr* branch =
471 new(I) BranchInstr( 475 new(I) BranchInstr(
472 new(I) StrictCompareInstr(call_block->start_pos(), 476 new(I) StrictCompareInstr(call_block->start_pos(),
473 Token::kEQ_STRICT, 477 Token::kEQ_STRICT,
474 new(I) Value(true_const), 478 new(I) Value(true_const),
475 new(I) Value(true_const), 479 new(I) Value(true_const),
(...skipping 3827 matching lines...) Expand 10 before | Expand all | Expand 10 after
4303 Report::MessageF(Report::kBailout, 4307 Report::MessageF(Report::kBailout,
4304 Script::Handle(function.script()), 4308 Script::Handle(function.script()),
4305 function.token_pos(), 4309 function.token_pos(),
4306 "FlowGraphBuilder Bailout: %s %s", 4310 "FlowGraphBuilder Bailout: %s %s",
4307 String::Handle(function.name()).ToCString(), 4311 String::Handle(function.name()).ToCString(),
4308 reason); 4312 reason);
4309 UNREACHABLE(); 4313 UNREACHABLE();
4310 } 4314 }
4311 4315
4312 } // namespace dart 4316 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_inliner.cc » ('j') | runtime/vm/flow_graph_range_analysis.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698