OLD | NEW |
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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/flow_graph.h" | 5 #include "vm/flow_graph.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/flow_graph_builder.h" | 8 #include "vm/flow_graph_builder.h" |
9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
10 #include "vm/longjump.h" | 10 #include "vm/longjump.h" |
(...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 continue; | 411 continue; |
412 } | 412 } |
413 | 413 |
414 // Iterate backwards starting at the last instruction. | 414 // Iterate backwards starting at the last instruction. |
415 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { | 415 for (BackwardInstructionIterator it(block); !it.Done(); it.Advance()) { |
416 Instruction* current = it.Current(); | 416 Instruction* current = it.Current(); |
417 | 417 |
418 LoadLocalInstr* load = current->AsLoadLocal(); | 418 LoadLocalInstr* load = current->AsLoadLocal(); |
419 if (load != NULL) { | 419 if (load != NULL) { |
420 const intptr_t index = load->local().BitIndexIn(num_non_copied_params_); | 420 const intptr_t index = load->local().BitIndexIn(num_non_copied_params_); |
| 421 if (index >= live_in->length()) continue; // Skip tmp_locals. |
421 live_in->Add(index); | 422 live_in->Add(index); |
422 if (!last_loads->Contains(index)) { | 423 if (!last_loads->Contains(index)) { |
423 last_loads->Add(index); | 424 last_loads->Add(index); |
424 load->mark_last(); | 425 load->mark_last(); |
425 } | 426 } |
426 continue; | 427 continue; |
427 } | 428 } |
428 | 429 |
429 StoreLocalInstr* store = current->AsStoreLocal(); | 430 StoreLocalInstr* store = current->AsStoreLocal(); |
430 if (store != NULL) { | 431 if (store != NULL) { |
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 // the renamed value. | 768 // the renamed value. |
768 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { | 769 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { |
769 Value* v = current->InputAt(i); | 770 Value* v = current->InputAt(i); |
770 // Update expression stack. | 771 // Update expression stack. |
771 ASSERT(env->length() > variable_count()); | 772 ASSERT(env->length() > variable_count()); |
772 | 773 |
773 Definition* reaching_defn = env->RemoveLast(); | 774 Definition* reaching_defn = env->RemoveLast(); |
774 Definition* input_defn = v->definition(); | 775 Definition* input_defn = v->definition(); |
775 if (input_defn->IsLoadLocal() || | 776 if (input_defn->IsLoadLocal() || |
776 input_defn->IsStoreLocal() || | 777 input_defn->IsStoreLocal() || |
| 778 input_defn->IsPushTemp() || |
| 779 input_defn->IsDropTemps() || |
777 input_defn->IsConstant()) { | 780 input_defn->IsConstant()) { |
778 // Remove the load/store from the graph. | 781 // Remove the load/store from the graph. |
779 input_defn->RemoveFromGraph(); | 782 input_defn->RemoveFromGraph(); |
780 // Assert we are not referencing nulls in the initial environment. | 783 // Assert we are not referencing nulls in the initial environment. |
781 ASSERT(reaching_defn->ssa_temp_index() != -1); | 784 ASSERT(reaching_defn->ssa_temp_index() != -1); |
782 v->set_definition(reaching_defn); | 785 v->set_definition(reaching_defn); |
783 input_defn = reaching_defn; | 786 input_defn = reaching_defn; |
784 } | 787 } |
785 input_defn->AddInputUse(v); | 788 input_defn->AddInputUse(v); |
786 } | 789 } |
787 | 790 |
788 // Drop pushed arguments for calls. | 791 // Drop pushed arguments for calls. |
789 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { | 792 for (intptr_t j = 0; j < current->ArgumentCount(); j++) { |
790 env->RemoveLast(); | 793 env->RemoveLast(); |
791 } | 794 } |
792 | 795 |
793 // 2b. Handle LoadLocal, StoreLocal, and Constant. | 796 // 2b. Handle LoadLocal, StoreLocal, and Constant. |
794 Definition* definition = current->AsDefinition(); | 797 Definition* definition = current->AsDefinition(); |
795 if (definition != NULL) { | 798 if (definition != NULL) { |
796 LoadLocalInstr* load = definition->AsLoadLocal(); | 799 LoadLocalInstr* load = definition->AsLoadLocal(); |
797 StoreLocalInstr* store = definition->AsStoreLocal(); | 800 StoreLocalInstr* store = definition->AsStoreLocal(); |
| 801 PushTempInstr* push = definition->AsPushTemp(); |
| 802 DropTempsInstr* drop = definition->AsDropTemps(); |
798 ConstantInstr* constant = definition->AsConstant(); | 803 ConstantInstr* constant = definition->AsConstant(); |
799 if ((load != NULL) || (store != NULL) || (constant != NULL)) { | 804 if ((load != NULL) || |
| 805 (store != NULL) || |
| 806 (push != NULL) || |
| 807 (drop != NULL) || |
| 808 (constant != NULL)) { |
800 intptr_t index; | 809 intptr_t index; |
801 Definition* result; | 810 Definition* result; |
802 if (store != NULL) { | 811 if (store != NULL) { |
803 // Update renaming environment. | 812 // Update renaming environment. |
804 index = store->local().BitIndexIn(num_non_copied_params_); | 813 index = store->local().BitIndexIn(num_non_copied_params_); |
805 result = store->value()->definition(); | 814 result = store->value()->definition(); |
806 | 815 |
807 if (variable_liveness->IsStoreAlive(block_entry, store)) { | 816 if (variable_liveness->IsStoreAlive(block_entry, store)) { |
808 (*env)[index] = result; | 817 (*env)[index] = result; |
809 } else { | 818 } else { |
810 (*env)[index] = constant_null(); | 819 (*env)[index] = constant_null(); |
811 } | 820 } |
812 } else if (load != NULL) { | 821 } else if (load != NULL) { |
813 // The graph construction ensures we do not have an unused LoadLocal | 822 // The graph construction ensures we do not have an unused LoadLocal |
814 // computation. | 823 // computation. |
815 ASSERT(definition->is_used()); | 824 ASSERT(definition->is_used()); |
816 index = load->local().BitIndexIn(num_non_copied_params_); | 825 index = load->local().BitIndexIn(num_non_copied_params_); |
817 result = (*env)[index]; | 826 result = (*env)[index]; |
818 | 827 |
819 PhiInstr* phi = result->AsPhi(); | 828 PhiInstr* phi = result->AsPhi(); |
820 if ((phi != NULL) && !phi->is_alive()) { | 829 if ((phi != NULL) && !phi->is_alive()) { |
821 phi->mark_alive(); | 830 phi->mark_alive(); |
822 live_phis->Add(phi); | 831 live_phis->Add(phi); |
823 } | 832 } |
824 | 833 |
825 if (variable_liveness->IsLastLoad(block_entry, load)) { | 834 if (variable_liveness->IsLastLoad(block_entry, load)) { |
826 (*env)[index] = constant_null(); | 835 (*env)[index] = constant_null(); |
827 } | 836 } |
| 837 } else if (push != NULL) { |
| 838 result = push->value()->definition(); |
| 839 env->Add(result); |
| 840 it.RemoveCurrentFromGraph(); |
| 841 continue; |
| 842 } else if (drop != NULL) { |
| 843 // Drop temps from the environment. |
| 844 for (intptr_t j = 0; j < drop->num_temps(); j++) { |
| 845 env->RemoveLast(); |
| 846 } |
| 847 result = drop->value()->definition(); |
828 } else { | 848 } else { |
829 ASSERT(definition->is_used()); | 849 ASSERT(definition->is_used()); |
830 result = GetConstant(constant->value()); | 850 result = GetConstant(constant->value()); |
831 } | 851 } |
832 // Update expression stack or remove from graph. | 852 // Update expression stack or remove from graph. |
833 if (definition->is_used()) { | 853 if (definition->is_used()) { |
834 ASSERT(result != NULL); | 854 ASSERT(result != NULL); |
835 env->Add(result); | 855 env->Add(result); |
836 // We remove load/store/constant instructions when we find their | 856 // We remove load/store/constant instructions when we find their |
837 // use in 2a. | 857 // use in 2a. |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1115 } | 1135 } |
1116 | 1136 |
1117 | 1137 |
1118 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1138 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
1119 BlockEntryInstr* to) const { | 1139 BlockEntryInstr* to) const { |
1120 return available_at_[to->postorder_number()]->Contains( | 1140 return available_at_[to->postorder_number()]->Contains( |
1121 from->postorder_number()); | 1141 from->postorder_number()); |
1122 } | 1142 } |
1123 | 1143 |
1124 } // namespace dart | 1144 } // namespace dart |
OLD | NEW |