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 464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 475 case kArray: | 475 case kArray: |
| 476 case kGrowableObjectArray: | 476 case kGrowableObjectArray: |
| 477 comp->set_receiver_type(static_cast<ObjectKind>(class_id)); | 477 comp->set_receiver_type(static_cast<ObjectKind>(class_id)); |
| 478 } | 478 } |
| 479 } | 479 } |
| 480 | 480 |
| 481 | 481 |
| 482 static void TryFuseComparisonWithBranch(ComparisonComp* comp) { | 482 static void TryFuseComparisonWithBranch(ComparisonComp* comp) { |
| 483 Instruction* instr = comp->instr(); | 483 Instruction* instr = comp->instr(); |
| 484 Instruction* next_instr = instr->StraightLineSuccessor(); | 484 Instruction* next_instr = instr->StraightLineSuccessor(); |
| 485 if (next_instr != NULL && next_instr->IsBranch()) { | 485 if ((next_instr != NULL) && next_instr->IsBranch()) { |
| 486 BranchInstr* branch = next_instr->AsBranch(); | 486 BranchInstr* branch = next_instr->AsBranch(); |
| 487 UseVal* use = branch->value()->AsUse(); | 487 UseVal* use = branch->value()->AsUse(); |
| 488 if (instr == use->definition()) { | 488 if (instr == use->definition()) { |
| 489 comp->MarkFusedWithBranch(branch); | 489 comp->MarkFusedWithBranch(branch); |
| 490 branch->MarkFusedWithComparison(); | 490 branch->MarkFusedWithComparison(); |
| 491 return; | |
| 492 } | |
| 493 } | |
| 494 if ((next_instr != NULL) && next_instr->IsBind()) { | |
| 495 Computation* next_comp = next_instr->AsBind()->computation(); | |
| 496 if (next_comp->IsBooleanNegate()) { | |
| 497 Instruction* next_next_instr = next_instr->StraightLineSuccessor(); | |
| 498 if ((next_next_instr != NULL) && next_next_instr->IsBranch()) { | |
| 499 BooleanNegateComp* negate = next_comp->AsBooleanNegate(); | |
| 500 BranchInstr* branch = next_next_instr->AsBranch(); | |
| 501 if ((branch->value()->AsUse()->definition() == negate->instr()) && | |
| 502 (negate->value()->AsUse()->definition() == instr)) { | |
| 503 comp->MarkFusedWithBranch(branch); | |
| 504 branch->MarkFusedWithComparison(); | |
| 505 branch->set_is_negated(true); | |
| 506 instr->SetSuccessor(next_next_instr); | |
| 507 return; | |
| 508 } | |
| 509 } | |
| 491 } | 510 } |
| 492 } | 511 } |
| 493 } | 512 } |
| 494 | 513 |
| 495 | 514 |
| 496 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpComp* comp) { | 515 void FlowGraphOptimizer::VisitRelationalOp(RelationalOpComp* comp) { |
| 497 if (!comp->HasICData()) return; | 516 if (!comp->HasICData()) return; |
| 498 | 517 |
| 499 const ICData& ic_data = *comp->ic_data(); | 518 const ICData& ic_data = *comp->ic_data(); |
| 500 if (ic_data.NumberOfChecks() == 0) return; | 519 if (ic_data.NumberOfChecks() == 0) return; |
| 501 // TODO(srdjan): Add multiple receiver type support. | 520 // TODO(srdjan): Add multiple receiver type support. |
| 502 if (ic_data.NumberOfChecks() != 1) return; | 521 if (ic_data.NumberOfChecks() != 1) return; |
| 503 ASSERT(HasOneTarget(ic_data)); | 522 ASSERT(HasOneTarget(ic_data)); |
| 504 | 523 |
| 505 if (HasTwoSmi(ic_data)) { | 524 if (HasTwoSmi(ic_data)) { |
| 506 comp->set_operands_class_id(kSmi); | 525 comp->set_operands_class_id(kSmi); |
| 507 } else if (HasTwoDouble(ic_data)) { | 526 } else if (HasTwoDouble(ic_data)) { |
| 508 comp->set_operands_class_id(kDouble); | 527 comp->set_operands_class_id(kDouble); |
| 509 } else { | 528 } else { |
| 510 return; | 529 return; |
| 511 } | 530 } |
| 512 | 531 |
| 513 // For smi and double comparisons if the next instruction is a conditional | 532 // For smi and double comparisons if the next instruction is a conditional |
| 514 // branch that uses the value of this comparison mark them as fused together | 533 // branch that uses the value of this comparison mark them as fused together |
| 515 // to avoid materializing a boolean value. | 534 // to avoid materializing a boolean value. |
| 516 // TODO(vegorov): recognize the pattern with BooleanNegate between comparsion | |
| 517 // and a branch. | |
| 518 TryFuseComparisonWithBranch(comp); | 535 TryFuseComparisonWithBranch(comp); |
|
Vyacheslav Egorov (Google)
2012/06/20 12:17:40
there is a special NaN branch inside the Double re
srdjan
2012/06/20 16:16:07
Thanks for catching it. Added following code in in
| |
| 519 } | 536 } |
| 520 | 537 |
| 521 | 538 |
| 522 void FlowGraphOptimizer::VisitStrictCompareComp(StrictCompareComp* comp) { | 539 void FlowGraphOptimizer::VisitStrictCompareComp(StrictCompareComp* comp) { |
| 523 // TODO(vegorov): recognize the pattern with BooleanNegate between comparsion | |
| 524 // and a branch. | |
| 525 TryFuseComparisonWithBranch(comp); | 540 TryFuseComparisonWithBranch(comp); |
| 526 } | 541 } |
| 527 | 542 |
| 528 | 543 |
| 529 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp) { | 544 void FlowGraphOptimizer::VisitEqualityCompare(EqualityCompareComp* comp) { |
| 530 const intptr_t kMaxChecks = 4; | 545 const intptr_t kMaxChecks = 4; |
| 531 if (comp->HasICData() && (comp->ic_data()->num_args_tested() <= kMaxChecks)) { | 546 if (comp->HasICData() && (comp->ic_data()->num_args_tested() <= kMaxChecks)) { |
| 532 // Replace binary checks with unary ones. | 547 // Replace binary checks with unary ones. |
| 533 ICData& unary_checks = | 548 ICData& unary_checks = |
| 534 ICData::Handle(ToUnaryClassChecks(*comp->ic_data())); | 549 ICData::Handle(ToUnaryClassChecks(*comp->ic_data())); |
| 535 comp->set_ic_data(&unary_checks); | 550 comp->set_ic_data(&unary_checks); |
| 536 } | 551 } |
| 537 | 552 |
| 538 // TODO(vegorov): recognize the pattern with BooleanNegate between comparsion | |
| 539 // and a branch. | |
| 540 TryFuseComparisonWithBranch(comp); | 553 TryFuseComparisonWithBranch(comp); |
| 541 } | 554 } |
| 542 | 555 |
| 543 | 556 |
| 544 void FlowGraphOptimizer::VisitDo(DoInstr* instr) { | 557 void FlowGraphOptimizer::VisitDo(DoInstr* instr) { |
| 545 instr->computation()->Accept(this); | 558 instr->computation()->Accept(this); |
| 546 } | 559 } |
| 547 | 560 |
| 548 | 561 |
| 549 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { | 562 void FlowGraphOptimizer::VisitBind(BindInstr* instr) { |
| 550 instr->computation()->Accept(this); | 563 instr->computation()->Accept(this); |
| 551 } | 564 } |
| 552 | 565 |
| 553 | 566 |
| 554 } // namespace dart | 567 } // namespace dart |
| OLD | NEW |