| 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 350 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 361 } | 361 } |
| 362 } | 362 } |
| 363 } | 363 } |
| 364 | 364 |
| 365 | 365 |
| 366 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph) | 366 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph) |
| 367 : HPhase("H_Global value numbering", graph), | 367 : HPhase("H_Global value numbering", graph), |
| 368 removed_side_effects_(false), | 368 removed_side_effects_(false), |
| 369 block_side_effects_(graph->blocks()->length(), zone()), | 369 block_side_effects_(graph->blocks()->length(), zone()), |
| 370 loop_side_effects_(graph->blocks()->length(), zone()), | 370 loop_side_effects_(graph->blocks()->length(), zone()), |
| 371 visited_on_paths_(zone(), graph->blocks()->length()) { | 371 visited_on_paths_(graph->blocks()->length(), zone()) { |
| 372 ASSERT(!AllowHandleAllocation::IsAllowed()); | 372 ASSERT(!AllowHandleAllocation::IsAllowed()); |
| 373 block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), | 373 block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), |
| 374 zone()); | 374 zone()); |
| 375 loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), | 375 loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(), |
| 376 zone()); | 376 zone()); |
| 377 } | 377 } |
| 378 | 378 |
| 379 void HGlobalValueNumberingPhase::Analyze() { | 379 void HGlobalValueNumberingPhase::Analyze() { |
| 380 removed_side_effects_ = false; | 380 removed_side_effects_ = false; |
| 381 ComputeBlockSideEffects(); | 381 ComputeBlockSideEffects(); |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 614 | 614 |
| 615 | 615 |
| 616 GVNFlagSet | 616 GVNFlagSet |
| 617 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock( | 617 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock( |
| 618 HBasicBlock* dominator, HBasicBlock* dominated) { | 618 HBasicBlock* dominator, HBasicBlock* dominated) { |
| 619 GVNFlagSet side_effects; | 619 GVNFlagSet side_effects; |
| 620 for (int i = 0; i < dominated->predecessors()->length(); ++i) { | 620 for (int i = 0; i < dominated->predecessors()->length(); ++i) { |
| 621 HBasicBlock* block = dominated->predecessors()->at(i); | 621 HBasicBlock* block = dominated->predecessors()->at(i); |
| 622 if (dominator->block_id() < block->block_id() && | 622 if (dominator->block_id() < block->block_id() && |
| 623 block->block_id() < dominated->block_id() && | 623 block->block_id() < dominated->block_id() && |
| 624 visited_on_paths_.Add(block->block_id())) { | 624 !visited_on_paths_.Contains(block->block_id())) { |
| 625 visited_on_paths_.Add(block->block_id()); |
| 625 side_effects.Add(block_side_effects_[block->block_id()]); | 626 side_effects.Add(block_side_effects_[block->block_id()]); |
| 626 if (block->IsLoopHeader()) { | 627 if (block->IsLoopHeader()) { |
| 627 side_effects.Add(loop_side_effects_[block->block_id()]); | 628 side_effects.Add(loop_side_effects_[block->block_id()]); |
| 628 } | 629 } |
| 629 side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock( | 630 side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock( |
| 630 dominator, block)); | 631 dominator, block)); |
| 631 } | 632 } |
| 632 } | 633 } |
| 633 return side_effects; | 634 return side_effects; |
| 634 } | 635 } |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 704 dominated_index_++; | 705 dominated_index_++; |
| 705 if (dominated_index_ == length_ - 1) { | 706 if (dominated_index_ == length_ - 1) { |
| 706 // No need to copy the map for the last child in the dominator tree. | 707 // No need to copy the map for the last child in the dominator tree. |
| 707 Initialize(block_->dominated_blocks()->at(dominated_index_), | 708 Initialize(block_->dominated_blocks()->at(dominated_index_), |
| 708 map(), | 709 map(), |
| 709 dominators(), | 710 dominators(), |
| 710 false, | 711 false, |
| 711 zone); | 712 zone); |
| 712 return this; | 713 return this; |
| 713 } else if (dominated_index_ < length_) { | 714 } else if (dominated_index_ < length_) { |
| 714 return push(zone, | 715 return push(zone, block_->dominated_blocks()->at(dominated_index_)); |
| 715 block_->dominated_blocks()->at(dominated_index_), | |
| 716 dominators()); | |
| 717 } else { | 716 } else { |
| 718 return NULL; | 717 return NULL; |
| 719 } | 718 } |
| 720 } | 719 } |
| 721 | 720 |
| 722 GvnBasicBlockState* push(Zone* zone, | 721 GvnBasicBlockState* push(Zone* zone, HBasicBlock* block) { |
| 723 HBasicBlock* block, | |
| 724 HSideEffectMap* dominators) { | |
| 725 if (next_ == NULL) { | 722 if (next_ == NULL) { |
| 726 next_ = | 723 next_ = |
| 727 new(zone) GvnBasicBlockState(this, block, map(), dominators, zone); | 724 new(zone) GvnBasicBlockState(this, block, map(), dominators(), zone); |
| 728 } else { | 725 } else { |
| 729 next_->Initialize(block, map(), dominators, true, zone); | 726 next_->Initialize(block, map(), dominators(), true, zone); |
| 730 } | 727 } |
| 731 return next_; | 728 return next_; |
| 732 } | 729 } |
| 733 GvnBasicBlockState* pop() { | 730 GvnBasicBlockState* pop() { |
| 734 GvnBasicBlockState* result = previous_; | 731 GvnBasicBlockState* result = previous_; |
| 735 while (result != NULL && result->is_done()) { | 732 while (result != NULL && result->is_done()) { |
| 736 TRACE_GVN_2("Backtracking from block B%d to block b%d\n", | 733 TRACE_GVN_2("Backtracking from block B%d to block b%d\n", |
| 737 block()->block_id(), | 734 block()->block_id(), |
| 738 previous_->block()->block_id()) | 735 previous_->block()->block_id()) |
| 739 result = result->previous_; | 736 result = result->previous_; |
| (...skipping 26 matching lines...) Expand all Loading... |
| 766 HValueMap* map = current->map(); | 763 HValueMap* map = current->map(); |
| 767 HSideEffectMap* dominators = current->dominators(); | 764 HSideEffectMap* dominators = current->dominators(); |
| 768 | 765 |
| 769 TRACE_GVN_2("Analyzing block B%d%s\n", | 766 TRACE_GVN_2("Analyzing block B%d%s\n", |
| 770 block->block_id(), | 767 block->block_id(), |
| 771 block->IsLoopHeader() ? " (loop header)" : ""); | 768 block->IsLoopHeader() ? " (loop header)" : ""); |
| 772 | 769 |
| 773 // If this is a loop header kill everything killed by the loop. | 770 // If this is a loop header kill everything killed by the loop. |
| 774 if (block->IsLoopHeader()) { | 771 if (block->IsLoopHeader()) { |
| 775 map->Kill(loop_side_effects_[block->block_id()]); | 772 map->Kill(loop_side_effects_[block->block_id()]); |
| 773 dominators->Kill(loop_side_effects_[block->block_id()]); |
| 776 } | 774 } |
| 777 | 775 |
| 778 // Go through all instructions of the current block. | 776 // Go through all instructions of the current block. |
| 779 HInstruction* instr = block->first(); | 777 for (HInstructionIterator it(block); !it.Done(); it.Advance()) { |
| 780 while (instr != NULL) { | 778 HInstruction* instr = it.Current(); |
| 781 HInstruction* next = instr->next(); | 779 if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) { |
| 780 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { |
| 781 HValue* other = dominators->at(i); |
| 782 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); |
| 783 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); |
| 784 if (instr->DependsOnFlags().Contains(depends_on_flag) && |
| 785 (other != NULL)) { |
| 786 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", |
| 787 i, |
| 788 instr->id(), |
| 789 instr->Mnemonic(), |
| 790 other->id(), |
| 791 other->Mnemonic()); |
| 792 instr->HandleSideEffectDominator(changes_flag, other); |
| 793 } |
| 794 } |
| 795 } |
| 796 // Instruction was unlinked during graph traversal. |
| 797 if (!instr->IsLinked()) continue; |
| 798 |
| 782 GVNFlagSet flags = instr->ChangesFlags(); | 799 GVNFlagSet flags = instr->ChangesFlags(); |
| 783 if (!flags.IsEmpty()) { | 800 if (!flags.IsEmpty()) { |
| 784 // Clear all instructions in the map that are affected by side effects. | 801 // Clear all instructions in the map that are affected by side effects. |
| 785 // Store instruction as the dominating one for tracked side effects. | 802 // Store instruction as the dominating one for tracked side effects. |
| 786 map->Kill(flags); | 803 map->Kill(flags); |
| 787 dominators->Store(flags, instr); | 804 dominators->Store(flags, instr); |
| 788 TRACE_GVN_2("Instruction %d %s\n", instr->id(), | 805 TRACE_GVN_2("Instruction %d %s\n", instr->id(), |
| 789 *GetGVNFlagsString(flags)); | 806 *GetGVNFlagsString(flags)); |
| 790 } | 807 } |
| 791 if (instr->CheckFlag(HValue::kUseGVN)) { | 808 if (instr->CheckFlag(HValue::kUseGVN)) { |
| 792 ASSERT(!instr->HasObservableSideEffects()); | 809 ASSERT(!instr->HasObservableSideEffects()); |
| 793 HValue* other = map->Lookup(instr); | 810 HValue* other = map->Lookup(instr); |
| 794 if (other != NULL) { | 811 if (other != NULL) { |
| 795 ASSERT(instr->Equals(other) && other->Equals(instr)); | 812 ASSERT(instr->Equals(other) && other->Equals(instr)); |
| 796 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", | 813 TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n", |
| 797 instr->id(), | 814 instr->id(), |
| 798 instr->Mnemonic(), | 815 instr->Mnemonic(), |
| 799 other->id(), | 816 other->id(), |
| 800 other->Mnemonic()); | 817 other->Mnemonic()); |
| 801 if (instr->HasSideEffects()) removed_side_effects_ = true; | 818 if (instr->HasSideEffects()) removed_side_effects_ = true; |
| 802 instr->DeleteAndReplaceWith(other); | 819 instr->DeleteAndReplaceWith(other); |
| 803 } else { | 820 } else { |
| 804 map->Add(instr, zone()); | 821 map->Add(instr, zone()); |
| 805 } | 822 } |
| 806 } | 823 } |
| 807 if (instr->IsLinked() && | |
| 808 instr->CheckFlag(HValue::kTrackSideEffectDominators)) { | |
| 809 for (int i = 0; i < kNumberOfTrackedSideEffects; i++) { | |
| 810 HValue* other = dominators->at(i); | |
| 811 GVNFlag changes_flag = HValue::ChangesFlagFromInt(i); | |
| 812 GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i); | |
| 813 if (instr->DependsOnFlags().Contains(depends_on_flag) && | |
| 814 (other != NULL)) { | |
| 815 TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n", | |
| 816 i, | |
| 817 instr->id(), | |
| 818 instr->Mnemonic(), | |
| 819 other->id(), | |
| 820 other->Mnemonic()); | |
| 821 instr->SetSideEffectDominator(changes_flag, other); | |
| 822 } | |
| 823 } | |
| 824 } | |
| 825 instr = next; | |
| 826 } | 824 } |
| 827 | 825 |
| 828 HBasicBlock* dominator_block; | 826 HBasicBlock* dominator_block; |
| 829 GvnBasicBlockState* next = | 827 GvnBasicBlockState* next = |
| 830 current->next_in_dominator_tree_traversal(zone(), | 828 current->next_in_dominator_tree_traversal(zone(), |
| 831 &dominator_block); | 829 &dominator_block); |
| 832 | 830 |
| 833 if (next != NULL) { | 831 if (next != NULL) { |
| 834 HBasicBlock* dominated = next->block(); | 832 HBasicBlock* dominated = next->block(); |
| 835 HValueMap* successor_map = next->map(); | 833 HValueMap* successor_map = next->map(); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 848 dominated); | 846 dominated); |
| 849 successor_map->Kill(side_effects_on_all_paths); | 847 successor_map->Kill(side_effects_on_all_paths); |
| 850 successor_dominators->Kill(side_effects_on_all_paths); | 848 successor_dominators->Kill(side_effects_on_all_paths); |
| 851 } | 849 } |
| 852 } | 850 } |
| 853 current = next; | 851 current = next; |
| 854 } | 852 } |
| 855 } | 853 } |
| 856 | 854 |
| 857 } } // namespace v8::internal | 855 } } // namespace v8::internal |
| OLD | NEW |