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 |