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 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 | 520 |
| 521 const intptr_t class_id = ReceiverClassId(comp); | 521 const intptr_t class_id = ReceiverClassId(comp); |
| 522 switch (class_id) { | 522 switch (class_id) { |
| 523 case kArray: | 523 case kArray: |
| 524 case kGrowableObjectArray: | 524 case kGrowableObjectArray: |
| 525 comp->set_receiver_type(static_cast<ObjectKind>(class_id)); | 525 comp->set_receiver_type(static_cast<ObjectKind>(class_id)); |
| 526 } | 526 } |
| 527 } | 527 } |
| 528 | 528 |
| 529 | 529 |
| 530 #if 0 | |
| 531 // TODO(vegorov): land a separate CL to fix the fusion. Now it should remove | |
| 532 // instruction from the graph to avoid confusing register allocator. | |
| 530 static void TryFuseComparisonWithBranch(BindInstr* instr, | 533 static void TryFuseComparisonWithBranch(BindInstr* instr, |
| 531 ComparisonComp* comp) { | 534 ComparisonComp* comp) { |
| 532 Instruction* next_instr = instr->next(); | 535 Instruction* next_instr = instr->next(); |
| 533 if ((next_instr != NULL) && next_instr->IsBranch()) { | 536 if ((next_instr != NULL) && next_instr->IsBranch()) { |
| 534 BranchInstr* branch = next_instr->AsBranch(); | 537 BranchInstr* branch = next_instr->AsBranch(); |
| 535 UseVal* use = branch->value()->AsUse(); | 538 UseVal* use = branch->value()->AsUse(); |
| 536 if (instr == use->definition()) { | 539 if (instr == use->definition()) { |
| 537 comp->MarkFusedWithBranch(branch); | 540 comp->MarkFusedWithBranch(branch); |
| 538 branch->MarkFusedWithComparison(); | 541 branch->MarkFusedWithComparison(); |
| 539 return; | 542 return; |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 551 comp->MarkFusedWithBranch(branch); | 554 comp->MarkFusedWithBranch(branch); |
| 552 branch->MarkFusedWithComparison(); | 555 branch->MarkFusedWithComparison(); |
| 553 branch->set_is_negated(true); | 556 branch->set_is_negated(true); |
| 554 instr->set_next(next_next_instr); | 557 instr->set_next(next_next_instr); |
| 555 return; | 558 return; |
| 556 } | 559 } |
| 557 } | 560 } |
| 558 } | 561 } |
| 559 } | 562 } |
| 560 } | 563 } |
| 564 #endif | |
| 561 | 565 |
| 562 | 566 |
| 563 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpComp* comp, | 567 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpComp* comp, |
| 564 BindInstr* instr) { | 568 BindInstr* instr) { |
| 565 if (!comp->HasICData()) return; | 569 if (!comp->HasICData()) return; |
| 566 | 570 |
| 567 const ICData& ic_data = *comp->ic_data(); | 571 const ICData& ic_data = *comp->ic_data(); |
| 568 if (ic_data.NumberOfChecks() == 0) return; | 572 if (ic_data.NumberOfChecks() == 0) return; |
| 569 // TODO(srdjan): Add multiple receiver type support. | 573 // TODO(srdjan): Add multiple receiver type support. |
| 570 if (ic_data.NumberOfChecks() != 1) return; | 574 if (ic_data.NumberOfChecks() != 1) return; |
| 571 ASSERT(HasOneTarget(ic_data)); | 575 ASSERT(HasOneTarget(ic_data)); |
| 572 | 576 |
| 573 if (HasOnlyTwoSmi(ic_data)) { | 577 if (HasOnlyTwoSmi(ic_data)) { |
| 574 comp->set_operands_class_id(kSmi); | 578 comp->set_operands_class_id(kSmi); |
| 575 } else if (HasOnlyTwoDouble(ic_data)) { | 579 } else if (HasOnlyTwoDouble(ic_data)) { |
| 576 comp->set_operands_class_id(kDouble); | 580 comp->set_operands_class_id(kDouble); |
| 577 } else { | 581 } else { |
| 578 return; | 582 return; |
| 579 } | 583 } |
| 580 | 584 |
| 581 // For smi and double comparisons if the next instruction is a conditional | 585 // For smi and double comparisons if the next instruction is a conditional |
| 582 // branch that uses the value of this comparison mark them as fused together | 586 // branch that uses the value of this comparison mark them as fused together |
| 583 // to avoid materializing a boolean value. | 587 // to avoid materializing a boolean value. |
| 588 #if 0 | |
|
srdjan
2012/07/11 17:22:32
Enable once synced with branch fusion fix
| |
| 584 TryFuseComparisonWithBranch(instr, comp); | 589 TryFuseComparisonWithBranch(instr, comp); |
| 590 #endif | |
| 585 } | 591 } |
| 586 | 592 |
| 587 | 593 |
| 588 void FlowGraphOptimizer::VisitStrictCompare(StrictCompareComp* comp, | 594 void FlowGraphOptimizer::VisitStrictCompare(StrictCompareComp* comp, |
| 589 BindInstr* instr) { | 595 BindInstr* instr) { |
| 596 #if 0 | |
| 590 TryFuseComparisonWithBranch(instr, comp); | 597 TryFuseComparisonWithBranch(instr, comp); |
| 598 #endif | |
| 591 } | 599 } |
| 592 | 600 |
| 593 | 601 |
| 594 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp, | 602 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp, |
| 595 BindInstr* instr) { | 603 BindInstr* instr) { |
| 596 if (comp->HasICData()) { | 604 if (comp->HasICData()) { |
| 597 // Replace binary checks with unary ones since EmitNative expects it. | 605 // Replace binary checks with unary ones since EmitNative expects it. |
| 598 ICData& unary_checks = | 606 ICData& unary_checks = |
| 599 ICData::Handle(ToUnaryClassChecks(*comp->ic_data())); | 607 ICData::Handle(ToUnaryClassChecks(*comp->ic_data())); |
| 600 comp->set_ic_data(&unary_checks); | 608 comp->set_ic_data(&unary_checks); |
| 601 } | 609 } |
| 602 | 610 |
| 611 #if 0 | |
| 603 TryFuseComparisonWithBranch(instr, comp); | 612 TryFuseComparisonWithBranch(instr, comp); |
| 613 #endif | |
| 604 } | 614 } |
| 605 | 615 |
| 606 | 616 |
| 607 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { | 617 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { |
| 608 instr->computation()->Accept(this, instr); | 618 instr->computation()->Accept(this, instr); |
| 609 } | 619 } |
| 610 | 620 |
| 611 | 621 |
| 612 | 622 |
| 613 void FlowGraphAnalyzer::Analyze() { | 623 void FlowGraphAnalyzer::Analyze() { |
| 614 is_leaf_ = true; | 624 is_leaf_ = true; |
| 615 for (intptr_t i = 0; i < blocks_.length(); ++i) { | 625 for (intptr_t i = 0; i < blocks_.length(); ++i) { |
| 616 BlockEntryInstr* entry = blocks_[i]; | 626 BlockEntryInstr* entry = blocks_[i]; |
| 617 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | 627 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { |
| 618 LocationSummary* locs = it.Current()->locs(); | 628 LocationSummary* locs = it.Current()->locs(); |
| 619 if ((locs != NULL) && locs->is_call()) { | 629 if ((locs != NULL) && locs->is_call()) { |
| 620 is_leaf_ = false; | 630 is_leaf_ = false; |
| 621 return; | 631 return; |
| 622 } | 632 } |
| 623 } | 633 } |
| 624 } | 634 } |
| 625 } | 635 } |
| 626 | 636 |
| 627 } // namespace dart | 637 } // namespace dart |
| OLD | NEW |