| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 } | 585 } |
| 586 } | 586 } |
| 587 } | 587 } |
| 588 | 588 |
| 589 | 589 |
| 590 void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() { | 590 void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() { |
| 591 TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n", | 591 TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n", |
| 592 graph()->use_optimistic_licm() ? "yes" : "no"); | 592 graph()->use_optimistic_licm() ? "yes" : "no"); |
| 593 for (int i = graph()->blocks()->length() - 1; i >= 0; --i) { | 593 for (int i = graph()->blocks()->length() - 1; i >= 0; --i) { |
| 594 HBasicBlock* block = graph()->blocks()->at(i); | 594 HBasicBlock* block = graph()->blocks()->at(i); |
| 595 if (block->IsLoopHeader()) { | 595 if (block->IsLoopHeader() && |
| 596 block->IsReachable() && |
| 597 !block->IsDeoptimizing()) { |
| 596 SideEffects side_effects = loop_side_effects_[block->block_id()]; | 598 SideEffects side_effects = loop_side_effects_[block->block_id()]; |
| 597 if (FLAG_trace_gvn) { | 599 if (FLAG_trace_gvn) { |
| 598 HeapStringAllocator allocator; | 600 HeapStringAllocator allocator; |
| 599 StringStream stream(&allocator); | 601 StringStream stream(&allocator); |
| 600 stream.Add("Try loop invariant motion for block B%d changes ", | 602 stream.Add("Try loop invariant motion for block B%d changes ", |
| 601 block->block_id()); | 603 block->block_id()); |
| 602 side_effects_tracker_.PrintSideEffectsTo(&stream, side_effects); | 604 side_effects_tracker_.PrintSideEffectsTo(&stream, side_effects); |
| 603 stream.Add("\n"); | 605 stream.Add("\n"); |
| 604 stream.OutputToStdOut(); | 606 stream.OutputToStdOut(); |
| 605 } | 607 } |
| 606 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); | 608 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); |
| 607 for (int j = block->block_id(); j <= last->block_id(); ++j) { | 609 for (int j = block->block_id(); j <= last->block_id(); ++j) { |
| 608 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); | 610 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); |
| 609 } | 611 } |
| 610 } | 612 } |
| 611 } | 613 } |
| 612 } | 614 } |
| 613 | 615 |
| 614 | 616 |
| 615 void HGlobalValueNumberingPhase::ProcessLoopBlock( | 617 void HGlobalValueNumberingPhase::ProcessLoopBlock( |
| 616 HBasicBlock* block, | 618 HBasicBlock* block, |
| 617 HBasicBlock* loop_header, | 619 HBasicBlock* loop_header, |
| 618 SideEffects loop_kills) { | 620 SideEffects loop_kills) { |
| 621 if (!block->IsReachable() || block->IsDeoptimizing()) return; |
| 619 HBasicBlock* pre_header = loop_header->predecessors()->at(0); | 622 HBasicBlock* pre_header = loop_header->predecessors()->at(0); |
| 620 if (FLAG_trace_gvn) { | 623 if (FLAG_trace_gvn) { |
| 621 HeapStringAllocator allocator; | 624 HeapStringAllocator allocator; |
| 622 StringStream stream(&allocator); | 625 StringStream stream(&allocator); |
| 623 stream.Add("Loop invariant code motion for B%d depends on ", | 626 stream.Add("Loop invariant code motion for B%d depends on ", |
| 624 block->block_id()); | 627 block->block_id()); |
| 625 side_effects_tracker_.PrintSideEffectsTo(&stream, loop_kills); | 628 side_effects_tracker_.PrintSideEffectsTo(&stream, loop_kills); |
| 626 stream.Add("\n"); | 629 stream.Add("\n"); |
| 627 stream.OutputToStdOut(); | 630 stream.OutputToStdOut(); |
| 628 } | 631 } |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 673 } | 676 } |
| 674 | 677 |
| 675 | 678 |
| 676 bool HGlobalValueNumberingPhase::AllowCodeMotion() { | 679 bool HGlobalValueNumberingPhase::AllowCodeMotion() { |
| 677 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; | 680 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; |
| 678 } | 681 } |
| 679 | 682 |
| 680 | 683 |
| 681 bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr, | 684 bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr, |
| 682 HBasicBlock* loop_header) { | 685 HBasicBlock* loop_header) { |
| 683 // If we've disabled code motion or we're in a block that unconditionally | 686 // If we've disabled code motion, don't move any instructions. |
| 684 // deoptimizes, don't move any instructions. | 687 return AllowCodeMotion(); |
| 685 return AllowCodeMotion() && !instr->block()->IsDeoptimizing() && | |
| 686 instr->block()->IsReachable(); | |
| 687 } | 688 } |
| 688 | 689 |
| 689 | 690 |
| 690 SideEffects | 691 SideEffects |
| 691 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock( | 692 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock( |
| 692 HBasicBlock* dominator, HBasicBlock* dominated) { | 693 HBasicBlock* dominator, HBasicBlock* dominated) { |
| 693 SideEffects side_effects; | 694 SideEffects side_effects; |
| 694 for (int i = 0; i < dominated->predecessors()->length(); ++i) { | 695 for (int i = 0; i < dominated->predecessors()->length(); ++i) { |
| 695 HBasicBlock* block = dominated->predecessors()->at(i); | 696 HBasicBlock* block = dominated->predecessors()->at(i); |
| 696 if (dominator->block_id() < block->block_id() && | 697 if (dominator->block_id() < block->block_id() && |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 769 GvnBasicBlockState(GvnBasicBlockState* previous, | 770 GvnBasicBlockState(GvnBasicBlockState* previous, |
| 770 HBasicBlock* block, | 771 HBasicBlock* block, |
| 771 HInstructionMap* map, | 772 HInstructionMap* map, |
| 772 HSideEffectMap* dominators, | 773 HSideEffectMap* dominators, |
| 773 Zone* zone) | 774 Zone* zone) |
| 774 : previous_(previous), next_(NULL) { | 775 : previous_(previous), next_(NULL) { |
| 775 Initialize(block, map, dominators, true, zone); | 776 Initialize(block, map, dominators, true, zone); |
| 776 } | 777 } |
| 777 | 778 |
| 778 GvnBasicBlockState* next_dominated(Zone* zone) { | 779 GvnBasicBlockState* next_dominated(Zone* zone) { |
| 779 dominated_index_++; | 780 while (++dominated_index_ < length_) { |
| 780 if (dominated_index_ == length_ - 1) { | 781 HBasicBlock* block = block_->dominated_blocks()->at(dominated_index_); |
| 781 // No need to copy the map for the last child in the dominator tree. | 782 if (block->IsReachable()) { |
| 782 Initialize(block_->dominated_blocks()->at(dominated_index_), | 783 if (dominated_index_ == length_ - 1) { |
| 783 map(), | 784 // No need to copy the map for the last child in the dominator tree. |
| 784 dominators(), | 785 Initialize(block, map(), dominators(), false, zone); |
| 785 false, | 786 return this; |
| 786 zone); | 787 } |
| 787 return this; | 788 return push(zone, block); |
| 788 } else if (dominated_index_ < length_) { | 789 } |
| 789 return push(zone, block_->dominated_blocks()->at(dominated_index_)); | |
| 790 } else { | |
| 791 return NULL; | |
| 792 } | 790 } |
| 791 return NULL; |
| 793 } | 792 } |
| 794 | 793 |
| 795 GvnBasicBlockState* push(Zone* zone, HBasicBlock* block) { | 794 GvnBasicBlockState* push(Zone* zone, HBasicBlock* block) { |
| 796 if (next_ == NULL) { | 795 if (next_ == NULL) { |
| 797 next_ = | 796 next_ = |
| 798 new(zone) GvnBasicBlockState(this, block, map(), dominators(), zone); | 797 new(zone) GvnBasicBlockState(this, block, map(), dominators(), zone); |
| 799 } else { | 798 } else { |
| 800 next_->Initialize(block, map(), dominators(), true, zone); | 799 next_->Initialize(block, map(), dominators(), true, zone); |
| 801 } | 800 } |
| 802 return next_; | 801 return next_; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 927 dominated); | 926 dominated); |
| 928 successor_map->Kill(side_effects_on_all_paths); | 927 successor_map->Kill(side_effects_on_all_paths); |
| 929 successor_dominators->Kill(side_effects_on_all_paths); | 928 successor_dominators->Kill(side_effects_on_all_paths); |
| 930 } | 929 } |
| 931 } | 930 } |
| 932 current = next; | 931 current = next; |
| 933 } | 932 } |
| 934 } | 933 } |
| 935 | 934 |
| 936 } } // namespace v8::internal | 935 } } // namespace v8::internal |
| OLD | NEW |