| 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_builder.h" | 5 #include "vm/flow_graph_builder.h" |
| 6 | 6 |
| 7 #include "vm/ast_printer.h" | 7 #include "vm/ast_printer.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/code_descriptors.h" | 9 #include "vm/code_descriptors.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 2279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2290 TargetEntryInstr* normal_entry = new TargetEntryInstr(); | 2290 TargetEntryInstr* normal_entry = new TargetEntryInstr(); |
| 2291 graph_entry_ = new GraphEntryInstr(normal_entry); | 2291 graph_entry_ = new GraphEntryInstr(normal_entry); |
| 2292 EffectGraphVisitor for_effect(this, 0); | 2292 EffectGraphVisitor for_effect(this, 0); |
| 2293 parsed_function().node_sequence()->Visit(&for_effect); | 2293 parsed_function().node_sequence()->Visit(&for_effect); |
| 2294 AppendFragment(normal_entry, for_effect); | 2294 AppendFragment(normal_entry, for_effect); |
| 2295 // Check that the graph is properly terminated. | 2295 // Check that the graph is properly terminated. |
| 2296 ASSERT(!for_effect.is_open()); | 2296 ASSERT(!for_effect.is_open()); |
| 2297 GrowableArray<intptr_t> parent; | 2297 GrowableArray<intptr_t> parent; |
| 2298 GrowableArray<BitVector*> assigned_vars; | 2298 GrowableArray<BitVector*> assigned_vars; |
| 2299 | 2299 |
| 2300 const intptr_t fixed_parameter_count = | 2300 // Either all parameters are fixed (none are named) or they are all copied. |
| 2301 parsed_function_.function().num_fixed_parameters(); | 2301 // This could change, so we keep fixed/copied counts separate. |
| 2302 const intptr_t variable_count = fixed_parameter_count + | 2302 intptr_t fixed_parameter_count; // This is really the "non-copied" count. |
| 2303 parsed_function_.copied_parameter_count() + | 2303 intptr_t copied_parameter_count; |
| 2304 parsed_function_.stack_local_count(); | 2304 if (parsed_function_.copied_parameter_count() > 0) { |
| 2305 fixed_parameter_count = 0; |
| 2306 copied_parameter_count = parsed_function_.copied_parameter_count(); |
| 2307 } else { |
| 2308 fixed_parameter_count = parsed_function_.function().num_fixed_parameters(); |
| 2309 copied_parameter_count = 0; |
| 2310 } |
| 2311 const intptr_t stack_local_count = parsed_function_.stack_local_count(); |
| 2312 const intptr_t variable_count = |
| 2313 stack_local_count + fixed_parameter_count + copied_parameter_count; |
| 2314 |
| 2305 // Perform a depth-first traversal of the graph to build preorder and | 2315 // Perform a depth-first traversal of the graph to build preorder and |
| 2306 // postorder block orders. | 2316 // postorder block orders. |
| 2307 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. | 2317 graph_entry_->DiscoverBlocks(NULL, // Entry block predecessor. |
| 2308 &preorder_block_entries_, | 2318 &preorder_block_entries_, |
| 2309 &postorder_block_entries_, | 2319 &postorder_block_entries_, |
| 2310 &parent, | 2320 &parent, |
| 2311 &assigned_vars, | 2321 &assigned_vars, |
| 2312 variable_count, | 2322 variable_count, |
| 2313 fixed_parameter_count); | 2323 fixed_parameter_count); |
| 2314 // Number blocks in reverse postorder. | 2324 // Number blocks in reverse postorder. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 2330 } | 2340 } |
| 2331 } | 2341 } |
| 2332 | 2342 |
| 2333 if (for_optimized && use_ssa) { | 2343 if (for_optimized && use_ssa) { |
| 2334 GrowableArray<BitVector*> dominance_frontier; | 2344 GrowableArray<BitVector*> dominance_frontier; |
| 2335 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); | 2345 ComputeDominators(&preorder_block_entries_, &parent, &dominance_frontier); |
| 2336 InsertPhis(preorder_block_entries_, | 2346 InsertPhis(preorder_block_entries_, |
| 2337 assigned_vars, | 2347 assigned_vars, |
| 2338 variable_count, | 2348 variable_count, |
| 2339 dominance_frontier); | 2349 dominance_frontier); |
| 2340 Rename(variable_count); | 2350 Rename(stack_local_count, fixed_parameter_count, copied_parameter_count); |
| 2341 } | 2351 } |
| 2342 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { | 2352 if (FLAG_print_flow_graph || (Dart::flow_graph_writer() != NULL)) { |
| 2343 intptr_t length = postorder_block_entries_.length(); | 2353 intptr_t length = postorder_block_entries_.length(); |
| 2344 GrowableArray<BlockEntryInstr*> reverse_postorder(length); | 2354 GrowableArray<BlockEntryInstr*> reverse_postorder(length); |
| 2345 for (intptr_t i = length - 1; i >= 0; --i) { | 2355 for (intptr_t i = length - 1; i >= 0; --i) { |
| 2346 reverse_postorder.Add(postorder_block_entries_[i]); | 2356 reverse_postorder.Add(postorder_block_entries_[i]); |
| 2347 } | 2357 } |
| 2348 if (FLAG_print_flow_graph) { | 2358 if (FLAG_print_flow_graph) { |
| 2349 // Print flow graph to stdout. | 2359 // Print flow graph to stdout. |
| 2350 FlowGraphPrinter printer(function, reverse_postorder); | 2360 FlowGraphPrinter printer(function, reverse_postorder); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2532 work[index] = var_index; | 2542 work[index] = var_index; |
| 2533 worklist.Add(block); | 2543 worklist.Add(block); |
| 2534 } | 2544 } |
| 2535 } | 2545 } |
| 2536 } | 2546 } |
| 2537 } | 2547 } |
| 2538 } | 2548 } |
| 2539 } | 2549 } |
| 2540 | 2550 |
| 2541 | 2551 |
| 2542 void FlowGraphBuilder::Rename(intptr_t var_count) { | 2552 void FlowGraphBuilder::Rename(intptr_t stack_local_count, |
| 2543 // TODO(fschneider): Store var_count in the FlowGraphBuilder instead of | 2553 intptr_t fixed_parameter_count, |
| 2554 intptr_t copied_parameter_count) { |
| 2555 // TODO(fschneider): Store counts in the FlowGraphBuilder instead of |
| 2544 // passing it around. | 2556 // passing it around. |
| 2545 // TODO(fschneider): Support catch-entry. | 2557 // TODO(fschneider): Support catch-entry. |
| 2546 if (graph_entry_->SuccessorCount() > 1) { | 2558 if (graph_entry_->SuccessorCount() > 1) { |
| 2547 Bailout("Catch-entry support in SSA."); | 2559 Bailout("Catch-entry support in SSA."); |
| 2548 } | 2560 } |
| 2549 // TODO(fschneider): Support copied parameters. | 2561 |
| 2550 if (parsed_function().copied_parameter_count() != 0) { | 2562 const intptr_t parameter_count = |
| 2551 Bailout("Copied parameter support in SSA"); | 2563 fixed_parameter_count + copied_parameter_count; |
| 2552 } | 2564 const intptr_t variable_count = parameter_count + stack_local_count; |
| 2553 ASSERT(var_count == (parsed_function().stack_local_count() + | |
| 2554 parsed_function().function().num_fixed_parameters())); | |
| 2555 | 2565 |
| 2556 // Initialize start environment. | 2566 // Initialize start environment. |
| 2557 GrowableArray<Value*> start_env(var_count); | 2567 GrowableArray<Value*> start_env(variable_count); |
| 2558 intptr_t i = 0; | 2568 intptr_t i = 0; |
| 2559 const intptr_t fixed_parameter_count = | 2569 for (; i < parameter_count; ++i) { |
| 2560 parsed_function().function().num_fixed_parameters(); | |
| 2561 for (; i < fixed_parameter_count; ++i) { | |
| 2562 ParameterInstr* param = new ParameterInstr(i); | 2570 ParameterInstr* param = new ParameterInstr(i); |
| 2563 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 2571 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 2564 start_env.Add(new UseVal(param)); | 2572 start_env.Add(new UseVal(param)); |
| 2565 } | 2573 } |
| 2566 | 2574 |
| 2567 // All locals are initialized with #null. | 2575 // All locals are initialized with #null. |
| 2568 Value* null_value = new ConstantVal(Object::ZoneHandle()); | 2576 Value* null_value = new ConstantVal(Object::ZoneHandle()); |
| 2569 for (; i < var_count; i++) { | 2577 for (; i < variable_count; i++) { |
| 2570 start_env.Add(null_value); | 2578 start_env.Add(null_value); |
| 2571 } | 2579 } |
| 2572 graph_entry_->set_start_env( | 2580 graph_entry_->set_start_env( |
| 2573 new Environment(start_env, fixed_parameter_count)); | 2581 new Environment(start_env, fixed_parameter_count)); |
| 2574 | 2582 |
| 2575 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); | 2583 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); |
| 2576 ASSERT(normal_entry != NULL); // Must have entry. | 2584 ASSERT(normal_entry != NULL); // Must have entry. |
| 2577 GrowableArray<Value*> env(var_count); | 2585 GrowableArray<Value*> env(variable_count); |
| 2578 env.AddArray(start_env); | 2586 env.AddArray(start_env); |
| 2579 RenameRecursive(normal_entry, &env, var_count, fixed_parameter_count); | 2587 RenameRecursive(normal_entry, &env, variable_count, fixed_parameter_count); |
| 2580 } | 2588 } |
| 2581 | 2589 |
| 2582 | 2590 |
| 2583 // Helper to a copy a value iff it is a UseVal. | 2591 // Helper to a copy a value iff it is a UseVal. |
| 2584 static Value* CopyValue(Value* value) { | 2592 static Value* CopyValue(Value* value) { |
| 2585 return value->IsUse() | 2593 return value->IsUse() |
| 2586 ? new UseVal(value->AsUse()->definition()) | 2594 ? new UseVal(value->AsUse()->definition()) |
| 2587 : value; | 2595 : value; |
| 2588 } | 2596 } |
| 2589 | 2597 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2725 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 2733 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 2726 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 2734 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 2727 OS::SNPrint(chars, len, kFormat, function_name, reason); | 2735 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 2728 const Error& error = Error::Handle( | 2736 const Error& error = Error::Handle( |
| 2729 LanguageError::New(String::Handle(String::New(chars)))); | 2737 LanguageError::New(String::Handle(String::New(chars)))); |
| 2730 Isolate::Current()->long_jump_base()->Jump(1, error); | 2738 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 2731 } | 2739 } |
| 2732 | 2740 |
| 2733 | 2741 |
| 2734 } // namespace dart | 2742 } // namespace dart |
| OLD | NEW |