Chromium Code Reviews| 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_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/flow_graph_builder.h" | 7 #include "vm/flow_graph_builder.h" |
| 8 #include "vm/il_printer.h" | 8 #include "vm/il_printer.h" |
| 9 #include "vm/object_store.h" | 9 #include "vm/object_store.h" |
| 10 | 10 |
| (...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 542 | 542 |
| 543 | 543 |
| 544 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { | 544 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { |
| 545 instr->computation()->Accept(this, instr); | 545 instr->computation()->Accept(this, instr); |
| 546 } | 546 } |
| 547 | 547 |
| 548 | 548 |
| 549 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp, | 549 void FlowGraphTypePropagator::VisitAssertAssignable(AssertAssignableComp* comp, |
| 550 BindInstr* instr) { | 550 BindInstr* instr) { |
| 551 if (FLAG_eliminate_type_checks && | 551 if (FLAG_eliminate_type_checks && |
| 552 !comp->IsEliminated() && | |
| 552 (comp->value() != NULL) && | 553 (comp->value() != NULL) && |
|
srdjan
2012/08/09 22:20:53
When can comp->value() be NULL?
regis
2012/08/09 23:51:37
It cannot. Code reuse error. Removed.
| |
| 553 !comp->dst_type().IsMalformed() && | 554 !comp->dst_type().IsMalformed() && |
| 554 comp->value()->StaticTypeIsMoreSpecificThan(comp->dst_type())) { | 555 comp->value()->CompileTypeIsMoreSpecificThan(comp->dst_type())) { |
| 555 // TODO(regis): Eliminate type check by removing comp node from graph. | 556 comp->Eliminate(); |
| 556 if (FLAG_trace_type_check_elimination) { | 557 if (FLAG_trace_type_check_elimination) { |
| 557 FlowGraphPrinter::PrintTypeCheck(parsed_function(), | 558 FlowGraphPrinter::PrintTypeCheck(parsed_function(), |
| 558 comp->token_pos(), | 559 comp->token_pos(), |
| 559 comp->value(), | 560 comp->value(), |
| 560 comp->dst_type(), | 561 comp->dst_type(), |
| 561 comp->dst_name(), | 562 comp->dst_name(), |
| 562 /*eliminated*/ true); | 563 comp->IsEliminated()); |
| 563 } | 564 } |
| 564 } | 565 } |
| 565 } | 566 } |
| 566 | 567 |
| 567 | 568 |
| 568 void FlowGraphTypePropagator::VisitBind(BindInstr* instr) { | 569 void FlowGraphTypePropagator::VisitGraphEntry(GraphEntryInstr* graph_entry) { |
| 569 instr->computation()->Accept(this, instr); | 570 if (graph_entry->start_env() == NULL) { |
| 571 return; | |
| 572 } | |
| 573 // Visit incoming parameters. | |
| 574 for (intptr_t i = 0; i < graph_entry->start_env()->values().length(); i++) { | |
| 575 Value* val = graph_entry->start_env()->values()[i]; | |
| 576 if (val->IsUse()) { | |
| 577 ParameterInstr* param = val->AsUse()->definition()->AsParameter(); | |
| 578 if (param != NULL) { | |
| 579 VisitParameter(param); | |
| 580 } | |
| 581 } | |
| 582 } | |
| 583 } | |
| 584 | |
| 585 | |
| 586 void FlowGraphTypePropagator::VisitJoinEntry(JoinEntryInstr* join_entry) { | |
| 587 if (join_entry->phis() != NULL) { | |
| 588 for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) { | |
| 589 PhiInstr* phi = (*join_entry->phis())[i]; | |
| 590 if (phi != NULL) { | |
| 591 VisitPhi(phi); | |
| 592 } | |
| 593 } | |
| 594 } | |
| 595 } | |
| 596 | |
| 597 | |
| 598 void FlowGraphTypePropagator::VisitBind(BindInstr* bind) { | |
| 599 // No need to propagate the input types of the bound computation, as long as | |
| 600 // PhiInstr's are handled as part of JoinEntryInstr. | |
| 601 // Cache propagated computation type. | |
| 602 AbstractType& type = AbstractType::Handle(bind->computation()->CompileType()); | |
| 603 bool changed = bind->SetPropagatedType(type); | |
| 604 if (changed) { | |
| 605 still_changing_ = true; | |
| 606 } | |
| 607 } | |
| 608 | |
| 609 | |
| 610 void FlowGraphTypePropagator::VisitPhi(PhiInstr* phi) { | |
| 611 // We could set the propagated type of the phi to the least upper bound of its | |
| 612 // input propagated types. However, keeping all propagated types allows us to | |
| 613 // optimize method dispatch. | |
| 614 // TODO(regis): Support a set of propagated types. For now, we compute the | |
| 615 // least specific of the input propagated types. | |
| 616 AbstractType& type = AbstractType::Handle(phi->LeastSpecificInputType()); | |
| 617 bool changed = phi->SetPropagatedType(type); | |
| 618 if (changed) { | |
| 619 still_changing_ = true; | |
| 620 } | |
| 621 } | |
| 622 | |
| 623 | |
| 624 void FlowGraphTypePropagator::VisitParameter(ParameterInstr* param) { | |
| 625 // TODO(regis): Set propagated type according to type feedback. | |
| 626 bool changed = param->SetPropagatedType(Type::Handle(Type::DynamicType())); | |
| 627 if (changed) { | |
| 628 still_changing_ = true; | |
| 629 } | |
| 630 } | |
| 631 | |
| 632 | |
| 633 void FlowGraphTypePropagator::PropagateTypes() { | |
| 634 do { | |
| 635 still_changing_ = false; | |
| 636 VisitBlocks(); | |
| 637 } while (still_changing_); | |
|
srdjan
2012/08/09 22:20:53
This could be made more efficient by visiting only
regis
2012/08/09 23:51:37
Added TODO.
I think we would need to revisit block
| |
| 570 } | 638 } |
| 571 | 639 |
| 572 | 640 |
| 573 void FlowGraphAnalyzer::Analyze() { | 641 void FlowGraphAnalyzer::Analyze() { |
| 574 is_leaf_ = true; | 642 is_leaf_ = true; |
| 575 for (intptr_t i = 0; i < blocks_.length(); ++i) { | 643 for (intptr_t i = 0; i < blocks_.length(); ++i) { |
| 576 BlockEntryInstr* entry = blocks_[i]; | 644 BlockEntryInstr* entry = blocks_[i]; |
| 577 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 645 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 578 LocationSummary* locs = it.Current()->locs(); | 646 LocationSummary* locs = it.Current()->locs(); |
| 579 if ((locs != NULL) && locs->is_call()) { | 647 if ((locs != NULL) && locs->is_call()) { |
| 580 is_leaf_ = false; | 648 is_leaf_ = false; |
| 581 return; | 649 return; |
| 582 } | 650 } |
| 583 } | 651 } |
| 584 } | 652 } |
| 585 } | 653 } |
| 586 | 654 |
| 587 | |
| 588 void FlowGraphTypePropagator::PropagateTypes() { | |
| 589 VisitBlocks(); | |
| 590 } | |
| 591 | |
| 592 } // namespace dart | 655 } // namespace dart |
| OLD | NEW |