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()) { | |
598 SideEffects side_effects = loop_side_effects_[block->block_id()]; | 596 SideEffects side_effects = loop_side_effects_[block->block_id()]; |
599 if (FLAG_trace_gvn) { | 597 if (FLAG_trace_gvn) { |
600 HeapStringAllocator allocator; | 598 HeapStringAllocator allocator; |
601 StringStream stream(&allocator); | 599 StringStream stream(&allocator); |
602 stream.Add("Try loop invariant motion for block B%d changes ", | 600 stream.Add("Try loop invariant motion for block B%d changes ", |
603 block->block_id()); | 601 block->block_id()); |
604 side_effects_tracker_.PrintSideEffectsTo(&stream, side_effects); | 602 side_effects_tracker_.PrintSideEffectsTo(&stream, side_effects); |
605 stream.Add("\n"); | 603 stream.Add("\n"); |
606 stream.OutputToStdOut(); | 604 stream.OutputToStdOut(); |
607 } | 605 } |
608 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); | 606 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); |
609 for (int j = block->block_id(); j <= last->block_id(); ++j) { | 607 for (int j = block->block_id(); j <= last->block_id(); ++j) { |
610 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); | 608 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); |
611 } | 609 } |
612 } | 610 } |
613 } | 611 } |
614 } | 612 } |
615 | 613 |
616 | 614 |
617 void HGlobalValueNumberingPhase::ProcessLoopBlock( | 615 void HGlobalValueNumberingPhase::ProcessLoopBlock( |
618 HBasicBlock* block, | 616 HBasicBlock* block, |
619 HBasicBlock* loop_header, | 617 HBasicBlock* loop_header, |
620 SideEffects loop_kills) { | 618 SideEffects loop_kills) { |
621 if (!block->IsReachable() || block->IsDeoptimizing()) return; | |
622 HBasicBlock* pre_header = loop_header->predecessors()->at(0); | 619 HBasicBlock* pre_header = loop_header->predecessors()->at(0); |
623 if (FLAG_trace_gvn) { | 620 if (FLAG_trace_gvn) { |
624 HeapStringAllocator allocator; | 621 HeapStringAllocator allocator; |
625 StringStream stream(&allocator); | 622 StringStream stream(&allocator); |
626 stream.Add("Loop invariant code motion for B%d depends on ", | 623 stream.Add("Loop invariant code motion for B%d depends on ", |
627 block->block_id()); | 624 block->block_id()); |
628 side_effects_tracker_.PrintSideEffectsTo(&stream, loop_kills); | 625 side_effects_tracker_.PrintSideEffectsTo(&stream, loop_kills); |
629 stream.Add("\n"); | 626 stream.Add("\n"); |
630 stream.OutputToStdOut(); | 627 stream.OutputToStdOut(); |
631 } | 628 } |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
676 } | 673 } |
677 | 674 |
678 | 675 |
679 bool HGlobalValueNumberingPhase::AllowCodeMotion() { | 676 bool HGlobalValueNumberingPhase::AllowCodeMotion() { |
680 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; | 677 return info()->IsStub() || info()->opt_count() + 1 < FLAG_max_opt_count; |
681 } | 678 } |
682 | 679 |
683 | 680 |
684 bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr, | 681 bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr, |
685 HBasicBlock* loop_header) { | 682 HBasicBlock* loop_header) { |
686 // If we've disabled code motion, don't move any instructions. | 683 // If we've disabled code motion or we're in a block that unconditionally |
687 return AllowCodeMotion(); | 684 // deoptimizes, don't move any instructions. |
| 685 return AllowCodeMotion() && !instr->block()->IsDeoptimizing() && |
| 686 instr->block()->IsReachable(); |
688 } | 687 } |
689 | 688 |
690 | 689 |
691 SideEffects | 690 SideEffects |
692 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock( | 691 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock( |
693 HBasicBlock* dominator, HBasicBlock* dominated) { | 692 HBasicBlock* dominator, HBasicBlock* dominated) { |
694 SideEffects side_effects; | 693 SideEffects side_effects; |
695 for (int i = 0; i < dominated->predecessors()->length(); ++i) { | 694 for (int i = 0; i < dominated->predecessors()->length(); ++i) { |
696 HBasicBlock* block = dominated->predecessors()->at(i); | 695 HBasicBlock* block = dominated->predecessors()->at(i); |
697 if (dominator->block_id() < block->block_id() && | 696 if (dominator->block_id() < block->block_id() && |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
770 GvnBasicBlockState(GvnBasicBlockState* previous, | 769 GvnBasicBlockState(GvnBasicBlockState* previous, |
771 HBasicBlock* block, | 770 HBasicBlock* block, |
772 HInstructionMap* map, | 771 HInstructionMap* map, |
773 HSideEffectMap* dominators, | 772 HSideEffectMap* dominators, |
774 Zone* zone) | 773 Zone* zone) |
775 : previous_(previous), next_(NULL) { | 774 : previous_(previous), next_(NULL) { |
776 Initialize(block, map, dominators, true, zone); | 775 Initialize(block, map, dominators, true, zone); |
777 } | 776 } |
778 | 777 |
779 GvnBasicBlockState* next_dominated(Zone* zone) { | 778 GvnBasicBlockState* next_dominated(Zone* zone) { |
780 while (++dominated_index_ < length_) { | 779 dominated_index_++; |
781 HBasicBlock* block = block_->dominated_blocks()->at(dominated_index_); | 780 if (dominated_index_ == length_ - 1) { |
782 if (block->IsReachable()) { | 781 // No need to copy the map for the last child in the dominator tree. |
783 if (dominated_index_ == length_ - 1) { | 782 Initialize(block_->dominated_blocks()->at(dominated_index_), |
784 // No need to copy the map for the last child in the dominator tree. | 783 map(), |
785 Initialize(block, map(), dominators(), false, zone); | 784 dominators(), |
786 return this; | 785 false, |
787 } | 786 zone); |
788 return push(zone, block); | 787 return this; |
789 } | 788 } else if (dominated_index_ < length_) { |
| 789 return push(zone, block_->dominated_blocks()->at(dominated_index_)); |
| 790 } else { |
| 791 return NULL; |
790 } | 792 } |
791 return NULL; | |
792 } | 793 } |
793 | 794 |
794 GvnBasicBlockState* push(Zone* zone, HBasicBlock* block) { | 795 GvnBasicBlockState* push(Zone* zone, HBasicBlock* block) { |
795 if (next_ == NULL) { | 796 if (next_ == NULL) { |
796 next_ = | 797 next_ = |
797 new(zone) GvnBasicBlockState(this, block, map(), dominators(), zone); | 798 new(zone) GvnBasicBlockState(this, block, map(), dominators(), zone); |
798 } else { | 799 } else { |
799 next_->Initialize(block, map(), dominators(), true, zone); | 800 next_->Initialize(block, map(), dominators(), true, zone); |
800 } | 801 } |
801 return next_; | 802 return next_; |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 dominated); | 927 dominated); |
927 successor_map->Kill(side_effects_on_all_paths); | 928 successor_map->Kill(side_effects_on_all_paths); |
928 successor_dominators->Kill(side_effects_on_all_paths); | 929 successor_dominators->Kill(side_effects_on_all_paths); |
929 } | 930 } |
930 } | 931 } |
931 current = next; | 932 current = next; |
932 } | 933 } |
933 } | 934 } |
934 | 935 |
935 } } // namespace v8::internal | 936 } } // namespace v8::internal |
OLD | NEW |