| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/dart_entry.h" | 8 #include "vm/dart_entry.h" |
| 9 #include "vm/flow_graph_allocator.h" | 9 #include "vm/flow_graph_allocator.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 821 // block while computing the dominator tree. | 821 // block while computing the dominator tree. |
| 822 ASSERT(other != NULL); | 822 ASSERT(other != NULL); |
| 823 BlockEntryInstr* current = other; | 823 BlockEntryInstr* current = other; |
| 824 while (current != NULL && current != this) { | 824 while (current != NULL && current != this) { |
| 825 current = current->dominator(); | 825 current = current->dominator(); |
| 826 } | 826 } |
| 827 return current == this; | 827 return current == this; |
| 828 } | 828 } |
| 829 | 829 |
| 830 | 830 |
| 831 // Helper to mutate the graph during inlining. This block should be |
| 832 // replaced with new_block as a predecessor of all of this block's |
| 833 // successors. For each successor, the predecessors will be reordered |
| 834 // to preserve block-order sorting of the predecessors as well as the |
| 835 // phis if the successor is a join. |
| 836 void BlockEntryInstr::ReplaceAsPredecessorWith(BlockEntryInstr* new_block) { |
| 837 // Set the last instruction of the new block to that of the old block. |
| 838 Instruction* last = last_instruction(); |
| 839 new_block->set_last_instruction(last); |
| 840 // For each successor, update the predecessors. |
| 841 for (intptr_t sidx = 0; sidx < last->SuccessorCount(); ++sidx) { |
| 842 // If the successor is a target, update its predecessor. |
| 843 TargetEntryInstr* target = last->SuccessorAt(sidx)->AsTargetEntry(); |
| 844 if (target != NULL) { |
| 845 target->predecessor_ = new_block; |
| 846 continue; |
| 847 } |
| 848 // If the successor is a join, update each predecessor and the phis. |
| 849 JoinEntryInstr* join = last->SuccessorAt(sidx)->AsJoinEntry(); |
| 850 ASSERT(join != NULL); |
| 851 // Find the old predecessor index. |
| 852 intptr_t old_index = join->IndexOfPredecessor(this); |
| 853 intptr_t pred_count = join->PredecessorCount(); |
| 854 ASSERT(old_index >= 0); |
| 855 ASSERT(old_index < pred_count); |
| 856 // Find the new predecessor index while reordering the predecessors. |
| 857 intptr_t new_id = new_block->block_id(); |
| 858 intptr_t new_index = old_index; |
| 859 if (block_id() < new_id) { |
| 860 // Search upwards, bubbling down intermediate predecessors. |
| 861 for (; new_index < pred_count - 1; ++new_index) { |
| 862 if (join->predecessors_[new_index + 1]->block_id() > new_id) break; |
| 863 join->predecessors_[new_index] = join->predecessors_[new_index + 1]; |
| 864 } |
| 865 } else { |
| 866 // Search downwards, bubbling up intermediate predecessors. |
| 867 for (; new_index > 0; --new_index) { |
| 868 if (join->predecessors_[new_index - 1]->block_id() < new_id) break; |
| 869 join->predecessors_[new_index] = join->predecessors_[new_index - 1]; |
| 870 } |
| 871 } |
| 872 join->predecessors_[new_index] = new_block; |
| 873 // If the new and old predecessor index match there is nothing to update. |
| 874 if ((join->phis() == NULL) || (old_index == new_index)) return; |
| 875 // Otherwise, reorder the predecessor uses in each phi. |
| 876 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 877 PhiInstr* phi = (*join->phis())[i]; |
| 878 if (phi == NULL) continue; |
| 879 ASSERT(pred_count == phi->InputCount()); |
| 880 // Save the predecessor use. |
| 881 Value* pred_use = phi->InputAt(old_index); |
| 882 // Move uses between old and new. |
| 883 intptr_t step = (old_index < new_index) ? 1 : -1; |
| 884 for (intptr_t use_idx = old_index; |
| 885 use_idx != new_index; |
| 886 use_idx += step) { |
| 887 Value* use = phi->InputAt(use_idx + step); |
| 888 phi->SetInputAt(use_idx, use); |
| 889 use->set_use_index(use_idx); |
| 890 } |
| 891 // Write the predecessor use. |
| 892 phi->SetInputAt(new_index, pred_use); |
| 893 pred_use->set_use_index(new_index); |
| 894 } |
| 895 } |
| 896 } |
| 897 |
| 898 |
| 831 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { | 899 void JoinEntryInstr::InsertPhi(intptr_t var_index, intptr_t var_count) { |
| 832 // Lazily initialize the array of phis. | 900 // Lazily initialize the array of phis. |
| 833 // Currently, phis are stored in a sparse array that holds the phi | 901 // Currently, phis are stored in a sparse array that holds the phi |
| 834 // for variable with index i at position i. | 902 // for variable with index i at position i. |
| 835 // TODO(fschneider): Store phis in a more compact way. | 903 // TODO(fschneider): Store phis in a more compact way. |
| 836 if (phis_ == NULL) { | 904 if (phis_ == NULL) { |
| 837 phis_ = new ZoneGrowableArray<PhiInstr*>(var_count); | 905 phis_ = new ZoneGrowableArray<PhiInstr*>(var_count); |
| 838 for (intptr_t i = 0; i < var_count; i++) { | 906 for (intptr_t i = 0; i < var_count; i++) { |
| 839 phis_->Add(NULL); | 907 phis_->Add(NULL); |
| 840 } | 908 } |
| (...skipping 1846 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2687 default: | 2755 default: |
| 2688 UNREACHABLE(); | 2756 UNREACHABLE(); |
| 2689 } | 2757 } |
| 2690 return kPowRuntimeEntry; | 2758 return kPowRuntimeEntry; |
| 2691 } | 2759 } |
| 2692 | 2760 |
| 2693 | 2761 |
| 2694 #undef __ | 2762 #undef __ |
| 2695 | 2763 |
| 2696 } // namespace dart | 2764 } // namespace dart |
| OLD | NEW |