| 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/object_store.h" | 11 #include "vm/object_store.h" |
| 12 #include "vm/report.h" | 12 #include "vm/report.h" |
| 13 | 13 |
| 14 namespace dart { | 14 namespace dart { |
| 15 | 15 |
| 16 DEFINE_FLAG(bool, prune_dead_locals, true, "optimize dead locals away"); | 16 DEFINE_FLAG(bool, prune_dead_locals, true, "optimize dead locals away"); |
| 17 DECLARE_FLAG(bool, reorder_basic_blocks); | 17 DECLARE_FLAG(bool, reorder_basic_blocks); |
| 18 DECLARE_FLAG(bool, trace_optimization); | 18 DECLARE_FLAG(bool, trace_optimization); |
| 19 DECLARE_FLAG(bool, verify_compiler); | 19 DECLARE_FLAG(bool, verify_compiler); |
| 20 | 20 |
| 21 | 21 |
| 22 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, | 22 FlowGraph::FlowGraph(ParsedFunction* parsed_function, |
| 23 GraphEntryInstr* graph_entry, | 23 GraphEntryInstr* graph_entry, |
| 24 intptr_t max_block_id) | 24 intptr_t max_block_id) |
| 25 : isolate_(Isolate::Current()), | 25 : isolate_(Isolate::Current()), |
| 26 parent_(), | 26 parent_(), |
| 27 current_ssa_temp_index_(0), | 27 current_ssa_temp_index_(0), |
| 28 max_block_id_(max_block_id), | 28 max_block_id_(max_block_id), |
| 29 builder_(builder), | 29 parsed_function_(parsed_function), |
| 30 parsed_function_(*builder.parsed_function()), | 30 num_copied_params_(parsed_function->num_copied_params()), |
| 31 num_copied_params_(builder.num_copied_params()), | 31 num_non_copied_params_(parsed_function->num_non_copied_params()), |
| 32 num_non_copied_params_(builder.num_non_copied_params()), | |
| 33 graph_entry_(graph_entry), | 32 graph_entry_(graph_entry), |
| 34 preorder_(), | 33 preorder_(), |
| 35 postorder_(), | 34 postorder_(), |
| 36 reverse_postorder_(), | 35 reverse_postorder_(), |
| 37 optimized_block_order_(), | 36 optimized_block_order_(), |
| 38 constant_null_(NULL), | 37 constant_null_(NULL), |
| 39 constant_dead_(NULL), | 38 constant_dead_(NULL), |
| 40 constant_empty_context_(NULL), | 39 constant_empty_context_(NULL), |
| 41 block_effects_(NULL), | 40 block_effects_(NULL), |
| 42 licm_allowed_(true), | 41 licm_allowed_(true), |
| 43 loop_headers_(NULL), | 42 loop_headers_(NULL), |
| 44 loop_invariant_loads_(NULL), | 43 loop_invariant_loads_(NULL), |
| 45 guarded_fields_(builder.guarded_fields()), | 44 guarded_fields_(parsed_function->guarded_fields()), |
| 46 deferred_prefixes_(builder.deferred_prefixes()), | 45 deferred_prefixes_(parsed_function->deferred_prefixes()), |
| 47 captured_parameters_( | 46 captured_parameters_( |
| 48 new(isolate_) BitVector(isolate_, variable_count())) { | 47 new(isolate_) BitVector(isolate_, variable_count())) { |
| 49 DiscoverBlocks(); | 48 DiscoverBlocks(); |
| 50 } | 49 } |
| 51 | 50 |
| 52 | 51 |
| 53 void FlowGraph::AddToGuardedFields( | 52 void FlowGraph::AddToGuardedFields( |
| 54 ZoneGrowableArray<const Field*>* array, | 53 ZoneGrowableArray<const Field*>* array, |
| 55 const Field* field) { | 54 const Field* field) { |
| 56 if ((field->guarded_cid() == kDynamicCid) || | 55 if ((field->guarded_cid() == kDynamicCid) || |
| (...skipping 25 matching lines...) Expand all Loading... |
| 82 | 81 |
| 83 | 82 |
| 84 bool FlowGraph::ShouldReorderBlocks(const Function& function, | 83 bool FlowGraph::ShouldReorderBlocks(const Function& function, |
| 85 bool is_optimized) { | 84 bool is_optimized) { |
| 86 return is_optimized && FLAG_reorder_basic_blocks && !function.is_intrinsic(); | 85 return is_optimized && FLAG_reorder_basic_blocks && !function.is_intrinsic(); |
| 87 } | 86 } |
| 88 | 87 |
| 89 | 88 |
| 90 GrowableArray<BlockEntryInstr*>* FlowGraph::CodegenBlockOrder( | 89 GrowableArray<BlockEntryInstr*>* FlowGraph::CodegenBlockOrder( |
| 91 bool is_optimized) { | 90 bool is_optimized) { |
| 92 return ShouldReorderBlocks(parsed_function().function(), is_optimized) | 91 return ShouldReorderBlocks(parsed_function()->function(), is_optimized) |
| 93 ? &optimized_block_order_ | 92 ? &optimized_block_order_ |
| 94 : &reverse_postorder_; | 93 : &reverse_postorder_; |
| 95 } | 94 } |
| 96 | 95 |
| 97 | 96 |
| 98 ConstantInstr* FlowGraph::GetConstant(const Object& object) { | 97 ConstantInstr* FlowGraph::GetConstant(const Object& object) { |
| 99 ConstantInstr* constant = constant_instr_pool_.Lookup(object); | 98 ConstantInstr* constant = constant_instr_pool_.Lookup(object); |
| 100 if (constant == NULL) { | 99 if (constant == NULL) { |
| 101 // Otherwise, allocate and add it to the pool. | 100 // Otherwise, allocate and add it to the pool. |
| 102 constant = new(isolate()) ConstantInstr( | 101 constant = new(isolate()) ConstantInstr( |
| (...skipping 745 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 848 AddToInitialDefinitions(param); | 847 AddToInitialDefinitions(param); |
| 849 env.Add(param); | 848 env.Add(param); |
| 850 } | 849 } |
| 851 } | 850 } |
| 852 | 851 |
| 853 // Initialize all locals in the renaming environment For OSR, the locals have | 852 // Initialize all locals in the renaming environment For OSR, the locals have |
| 854 // already been handled as parameters. | 853 // already been handled as parameters. |
| 855 if (!IsCompiledForOsr()) { | 854 if (!IsCompiledForOsr()) { |
| 856 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { | 855 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { |
| 857 if (i == CurrentContextEnvIndex()) { | 856 if (i == CurrentContextEnvIndex()) { |
| 858 if (parsed_function().function().IsClosureFunction()) { | 857 if (parsed_function()->function().IsClosureFunction()) { |
| 859 CurrentContextInstr* context = new CurrentContextInstr(); | 858 CurrentContextInstr* context = new CurrentContextInstr(); |
| 860 context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 859 context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 861 AddToInitialDefinitions(context); | 860 AddToInitialDefinitions(context); |
| 862 env.Add(context); | 861 env.Add(context); |
| 863 } else { | 862 } else { |
| 864 env.Add(constant_empty_context()); | 863 env.Add(constant_empty_context()); |
| 865 } | 864 } |
| 866 } else { | 865 } else { |
| 867 env.Add(constant_null()); | 866 env.Add(constant_null()); |
| 868 } | 867 } |
| 869 } | 868 } |
| 870 } | 869 } |
| 871 | 870 |
| 872 if (entry->SuccessorCount() > 1) { | 871 if (entry->SuccessorCount() > 1) { |
| 873 // Functions with try-catch have a fixed area of stack slots reserved | 872 // Functions with try-catch have a fixed area of stack slots reserved |
| 874 // so that all local variables are stored at a known location when | 873 // so that all local variables are stored at a known location when |
| 875 // on entry to the catch. | 874 // on entry to the catch. |
| 876 entry->set_fixed_slot_count(num_stack_locals() + num_copied_params()); | 875 entry->set_fixed_slot_count(num_stack_locals() + num_copied_params()); |
| 877 } | 876 } |
| 878 RenameRecursive(entry, &env, live_phis, variable_liveness); | 877 RenameRecursive(entry, &env, live_phis, variable_liveness); |
| 879 } | 878 } |
| 880 | 879 |
| 881 | 880 |
| 882 void FlowGraph::AttachEnvironment(Instruction* instr, | 881 void FlowGraph::AttachEnvironment(Instruction* instr, |
| 883 GrowableArray<Definition*>* env) { | 882 GrowableArray<Definition*>* env) { |
| 884 Environment* deopt_env = | 883 Environment* deopt_env = |
| 885 Environment::From(isolate(), | 884 Environment::From(isolate(), |
| 886 *env, | 885 *env, |
| 887 num_non_copied_params_, | 886 num_non_copied_params_, |
| 888 &parsed_function_); | 887 parsed_function_); |
| 889 if (instr->IsClosureCall()) { | 888 if (instr->IsClosureCall()) { |
| 890 deopt_env = deopt_env->DeepCopy(isolate(), | 889 deopt_env = deopt_env->DeepCopy(isolate(), |
| 891 deopt_env->Length() - instr->InputCount()); | 890 deopt_env->Length() - instr->InputCount()); |
| 892 } | 891 } |
| 893 instr->SetEnvironment(deopt_env); | 892 instr->SetEnvironment(deopt_env); |
| 894 for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) { | 893 for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) { |
| 895 Value* use = it.CurrentValue(); | 894 Value* use = it.CurrentValue(); |
| 896 use->definition()->AddEnvUse(use); | 895 use->definition()->AddEnvUse(use); |
| 897 } | 896 } |
| 898 if (instr->CanDeoptimize()) { | 897 if (instr->CanDeoptimize()) { |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 } | 1381 } |
| 1383 | 1382 |
| 1384 | 1383 |
| 1385 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1384 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1386 BlockEntryInstr* to) const { | 1385 BlockEntryInstr* to) const { |
| 1387 return available_at_[to->postorder_number()]->Contains( | 1386 return available_at_[to->postorder_number()]->Contains( |
| 1388 from->postorder_number()); | 1387 from->postorder_number()); |
| 1389 } | 1388 } |
| 1390 | 1389 |
| 1391 } // namespace dart | 1390 } // namespace dart |
| OLD | NEW |