| 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/growable_array.h" | 10 #include "vm/growable_array.h" |
| 11 #include "vm/report.h" | 11 #include "vm/report.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DEFINE_FLAG(bool, prune_dead_locals, true, "optimize dead locals away"); |
| 15 DECLARE_FLAG(bool, reorder_basic_blocks); | 16 DECLARE_FLAG(bool, reorder_basic_blocks); |
| 16 DECLARE_FLAG(bool, trace_optimization); | 17 DECLARE_FLAG(bool, trace_optimization); |
| 17 DECLARE_FLAG(bool, verify_compiler); | 18 DECLARE_FLAG(bool, verify_compiler); |
| 18 | 19 |
| 19 | 20 |
| 20 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, | 21 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, |
| 21 GraphEntryInstr* graph_entry, | 22 GraphEntryInstr* graph_entry, |
| 22 intptr_t max_block_id) | 23 intptr_t max_block_id) |
| 23 : isolate_(Isolate::Current()), | 24 : isolate_(Isolate::Current()), |
| 24 parent_(), | 25 parent_(), |
| (...skipping 840 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 866 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 866 (*env)[i] = param; | 867 (*env)[i] = param; |
| 867 block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param); | 868 block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param); |
| 868 } | 869 } |
| 869 } | 870 } |
| 870 | 871 |
| 871 // Prune non-live variables at block entry by replacing their environment | 872 // Prune non-live variables at block entry by replacing their environment |
| 872 // slots with null. | 873 // slots with null. |
| 873 BitVector* live_in = variable_liveness->GetLiveInSet(block_entry); | 874 BitVector* live_in = variable_liveness->GetLiveInSet(block_entry); |
| 874 for (intptr_t i = 0; i < variable_count(); i++) { | 875 for (intptr_t i = 0; i < variable_count(); i++) { |
| 875 if (!live_in->Contains(i)) { | 876 if (FLAG_prune_dead_locals && !live_in->Contains(i)) { |
| 876 (*env)[i] = constant_dead(); | 877 (*env)[i] = constant_dead(); |
| 877 } | 878 } |
| 878 } | 879 } |
| 879 | 880 |
| 880 // Attach environment to the block entry. | 881 // Attach environment to the block entry. |
| 881 AttachEnvironment(block_entry, env); | 882 AttachEnvironment(block_entry, env); |
| 882 | 883 |
| 883 // 2. Process normal instructions. | 884 // 2. Process normal instructions. |
| 884 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { | 885 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { |
| 885 Instruction* current = it.Current(); | 886 Instruction* current = it.Current(); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 (store != NULL) || | 934 (store != NULL) || |
| 934 (push != NULL) || | 935 (push != NULL) || |
| 935 (drop != NULL) || | 936 (drop != NULL) || |
| 936 (constant != NULL)) { | 937 (constant != NULL)) { |
| 937 Definition* result = NULL; | 938 Definition* result = NULL; |
| 938 if (store != NULL) { | 939 if (store != NULL) { |
| 939 // Update renaming environment. | 940 // Update renaming environment. |
| 940 intptr_t index = store->local().BitIndexIn(num_non_copied_params_); | 941 intptr_t index = store->local().BitIndexIn(num_non_copied_params_); |
| 941 result = store->value()->definition(); | 942 result = store->value()->definition(); |
| 942 | 943 |
| 943 if (variable_liveness->IsStoreAlive(block_entry, store)) { | 944 if (!FLAG_prune_dead_locals || |
| 945 variable_liveness->IsStoreAlive(block_entry, store)) { |
| 944 (*env)[index] = result; | 946 (*env)[index] = result; |
| 945 } else { | 947 } else { |
| 946 (*env)[index] = constant_dead(); | 948 (*env)[index] = constant_dead(); |
| 947 } | 949 } |
| 948 } else if (load != NULL) { | 950 } else if (load != NULL) { |
| 949 // The graph construction ensures we do not have an unused LoadLocal | 951 // The graph construction ensures we do not have an unused LoadLocal |
| 950 // computation. | 952 // computation. |
| 951 ASSERT(definition->HasTemp()); | 953 ASSERT(definition->HasTemp()); |
| 952 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); | 954 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); |
| 953 result = (*env)[index]; | 955 result = (*env)[index]; |
| 954 | 956 |
| 955 PhiInstr* phi = result->AsPhi(); | 957 PhiInstr* phi = result->AsPhi(); |
| 956 if ((phi != NULL) && !phi->is_alive()) { | 958 if ((phi != NULL) && !phi->is_alive()) { |
| 957 phi->mark_alive(); | 959 phi->mark_alive(); |
| 958 live_phis->Add(phi); | 960 live_phis->Add(phi); |
| 959 } | 961 } |
| 960 | 962 |
| 961 if (variable_liveness->IsLastLoad(block_entry, load)) { | 963 if (FLAG_prune_dead_locals && |
| 964 variable_liveness->IsLastLoad(block_entry, load)) { |
| 962 (*env)[index] = constant_dead(); | 965 (*env)[index] = constant_dead(); |
| 963 } | 966 } |
| 964 | 967 |
| 965 // Record captured parameters so that they can be skipped when | 968 // Record captured parameters so that they can be skipped when |
| 966 // emitting sync code inside optimized try-blocks. | 969 // emitting sync code inside optimized try-blocks. |
| 967 if (load->local().is_captured_parameter()) { | 970 if (load->local().is_captured_parameter()) { |
| 968 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); | 971 intptr_t index = load->local().BitIndexIn(num_non_copied_params_); |
| 969 captured_parameters_->Add(index); | 972 captured_parameters_->Add(index); |
| 970 } | 973 } |
| 971 | 974 |
| (...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1308 } | 1311 } |
| 1309 | 1312 |
| 1310 | 1313 |
| 1311 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1314 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1312 BlockEntryInstr* to) const { | 1315 BlockEntryInstr* to) const { |
| 1313 return available_at_[to->postorder_number()]->Contains( | 1316 return available_at_[to->postorder_number()]->Contains( |
| 1314 from->postorder_number()); | 1317 from->postorder_number()); |
| 1315 } | 1318 } |
| 1316 | 1319 |
| 1317 } // namespace dart | 1320 } // namespace dart |
| OLD | NEW |