Chromium Code Reviews| 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" |
| 11 #include "vm/growable_array.h" | 11 #include "vm/growable_array.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 DECLARE_FLAG(bool, trace_optimization); | |
| 16 | |
| 15 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, | 17 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, |
| 16 GraphEntryInstr* graph_entry) | 18 GraphEntryInstr* graph_entry) |
| 17 : parent_(), | 19 : parent_(), |
| 18 assigned_vars_(), | 20 assigned_vars_(), |
| 19 current_ssa_temp_index_(0), | 21 current_ssa_temp_index_(0), |
| 20 parsed_function_(builder.parsed_function()), | 22 parsed_function_(builder.parsed_function()), |
| 21 copied_parameter_count_(builder.copied_parameter_count()), | 23 copied_parameter_count_(builder.copied_parameter_count()), |
| 22 non_copied_parameter_count_(builder.non_copied_parameter_count()), | 24 non_copied_parameter_count_(builder.non_copied_parameter_count()), |
| 23 stack_local_count_(builder.stack_local_count()), | 25 stack_local_count_(builder.stack_local_count()), |
| 24 graph_entry_(graph_entry), | 26 graph_entry_(graph_entry), |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 490 if (graph_entry_->SuccessorCount() > 1) { | 492 if (graph_entry_->SuccessorCount() > 1) { |
| 491 Bailout("Catch-entry support in SSA."); | 493 Bailout("Catch-entry support in SSA."); |
| 492 } | 494 } |
| 493 | 495 |
| 494 // Name global constants. | 496 // Name global constants. |
| 495 graph_entry_->constant_null()->set_ssa_temp_index(alloc_ssa_temp_index()); | 497 graph_entry_->constant_null()->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 496 | 498 |
| 497 // Initialize start environment. | 499 // Initialize start environment. |
| 498 GrowableArray<Definition*> start_env(variable_count()); | 500 GrowableArray<Definition*> start_env(variable_count()); |
| 499 for (intptr_t i = 0; i < parameter_count(); ++i) { | 501 for (intptr_t i = 0; i < parameter_count(); ++i) { |
| 500 ParameterInstr* param = new ParameterInstr(i); | 502 ParameterInstr* param = new ParameterInstr(i, graph_entry_); |
| 501 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 503 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 502 start_env.Add(param); | 504 start_env.Add(param); |
| 503 } | 505 } |
| 504 | 506 |
| 505 // All locals are initialized with #null. Use the global definition, uses | 507 // All locals are initialized with #null. Use the global definition, uses |
| 506 // will be created in the Environment constructor. | 508 // will be created in the Environment constructor. |
| 507 while (start_env.length() < variable_count()) { | 509 while (start_env.length() < variable_count()) { |
| 508 start_env.Add(graph_entry_->constant_null()); | 510 start_env.Add(graph_entry_->constant_null()); |
| 509 } | 511 } |
| 510 graph_entry_->set_start_env( | 512 graph_entry_->set_start_env( |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 PhiInstr* used_phi = val->definition()->AsPhi(); | 659 PhiInstr* used_phi = val->definition()->AsPhi(); |
| 658 if ((used_phi != NULL) && !used_phi->is_alive()) { | 660 if ((used_phi != NULL) && !used_phi->is_alive()) { |
| 659 used_phi->mark_alive(); | 661 used_phi->mark_alive(); |
| 660 live_phis->Add(used_phi); | 662 live_phis->Add(used_phi); |
| 661 } | 663 } |
| 662 } | 664 } |
| 663 } | 665 } |
| 664 } | 666 } |
| 665 | 667 |
| 666 | 668 |
| 669 // Find the natural loop for the back edge m->n and attach loop information | |
| 670 // to block n (loop header). The algorithm is described in "Advanced Compiler | |
| 671 // Design & Implementation" (Muchnick) p192. | |
| 672 static void FindLoop(BlockEntryInstr* m, BlockEntryInstr* n) { | |
|
srdjan
2012/09/06 13:44:26
There is also FlowGraphAllocator::DiscoverLoops, h
Florian Schneider
2012/09/06 13:49:30
Good point. I didn't remember that we have such a
| |
| 673 GrowableArray<BlockEntryInstr*> stack; | |
| 674 ZoneGrowableArray<BlockEntryInstr*>* loop = | |
|
Kevin Millikin (Google)
2012/09/06 12:42:42
Consider a bit vector indexed by preorder block nu
Florian Schneider
2012/09/06 13:05:53
Done.
| |
| 675 new ZoneGrowableArray<BlockEntryInstr*>(2); | |
| 676 | |
| 677 loop->Add(n); | |
| 678 if (n != m) { | |
| 679 loop->Add(m); | |
| 680 stack.Add(m); | |
| 681 } | |
| 682 | |
| 683 while (!stack.is_empty()) { | |
| 684 BlockEntryInstr* p = stack.Last(); | |
| 685 stack.RemoveLast(); | |
| 686 for (intptr_t i = 0; i < p->PredecessorCount(); ++i) { | |
| 687 BlockEntryInstr* q = p->PredecessorAt(i); | |
| 688 if (!loop->Contains(q)) { | |
| 689 loop->Add(q); | |
| 690 stack.Add(q); | |
| 691 } | |
| 692 } | |
| 693 } | |
| 694 n->set_loop_info(loop); | |
| 695 if (FLAG_trace_optimization) { | |
| 696 for (intptr_t i = 0; i < loop->length(); i++) { | |
| 697 OS::Print(" B%"Pd"\n", (*loop)[i]->block_id()); | |
| 698 } | |
| 699 } | |
| 700 } | |
| 701 | |
| 702 | |
| 703 void FlowGraph::ComputeLoops(GrowableArray<BlockEntryInstr*>* loop_headers) { | |
| 704 ASSERT(loop_headers->is_empty()); | |
| 705 for (BlockIterator it = postorder_iterator(); | |
| 706 !it.Done(); | |
| 707 it.Advance()) { | |
| 708 BlockEntryInstr* block = it.Current(); | |
| 709 for (intptr_t i = 0; i < block->PredecessorCount(); ++i) { | |
| 710 BlockEntryInstr* pred = block->PredecessorAt(i); | |
| 711 if (block->Dominates(pred)) { | |
| 712 if (FLAG_trace_optimization) { | |
| 713 OS::Print("Back edge B%"Pd" -> B%"Pd"\n", pred->block_id(), | |
| 714 block->block_id()); | |
| 715 } | |
| 716 FindLoop(pred, block); | |
| 717 loop_headers->Add(block); | |
| 718 } | |
| 719 } | |
| 720 } | |
| 721 } | |
| 722 | |
| 723 | |
| 667 void FlowGraph::Bailout(const char* reason) const { | 724 void FlowGraph::Bailout(const char* reason) const { |
| 668 const char* kFormat = "FlowGraph Bailout: %s %s"; | 725 const char* kFormat = "FlowGraph Bailout: %s %s"; |
| 669 const char* function_name = parsed_function_.function().ToCString(); | 726 const char* function_name = parsed_function_.function().ToCString(); |
| 670 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; | 727 intptr_t len = OS::SNPrint(NULL, 0, kFormat, function_name, reason) + 1; |
| 671 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); | 728 char* chars = Isolate::Current()->current_zone()->Alloc<char>(len); |
| 672 OS::SNPrint(chars, len, kFormat, function_name, reason); | 729 OS::SNPrint(chars, len, kFormat, function_name, reason); |
| 673 const Error& error = Error::Handle( | 730 const Error& error = Error::Handle( |
| 674 LanguageError::New(String::Handle(String::New(chars)))); | 731 LanguageError::New(String::Handle(String::New(chars)))); |
| 675 Isolate::Current()->long_jump_base()->Jump(1, error); | 732 Isolate::Current()->long_jump_base()->Jump(1, error); |
| 676 } | 733 } |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 734 // Remove original arguments to the call. | 791 // Remove original arguments to the call. |
| 735 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 792 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 736 PushArgumentInstr* push = call->ArgumentAt(i); | 793 PushArgumentInstr* push = call->ArgumentAt(i); |
| 737 push->ReplaceUsesWith(push->value()->definition()); | 794 push->ReplaceUsesWith(push->value()->definition()); |
| 738 push->RemoveFromGraph(); | 795 push->RemoveFromGraph(); |
| 739 } | 796 } |
| 740 } | 797 } |
| 741 | 798 |
| 742 | 799 |
| 743 } // namespace dart | 800 } // namespace dart |
| OLD | NEW |