| 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 |