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" |
| (...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 777 // If the successor is a target, update its predecessor. | 777 // If the successor is a target, update its predecessor. |
| 778 TargetEntryInstr* target = last->SuccessorAt(sidx)->AsTargetEntry(); | 778 TargetEntryInstr* target = last->SuccessorAt(sidx)->AsTargetEntry(); |
| 779 if (target != NULL) { | 779 if (target != NULL) { |
| 780 target->predecessor_ = new_block; | 780 target->predecessor_ = new_block; |
| 781 continue; | 781 continue; |
| 782 } | 782 } |
| 783 // If the successor is a join, update each predecessor and the phis. | 783 // If the successor is a join, update each predecessor and the phis. |
| 784 JoinEntryInstr* join = last->SuccessorAt(sidx)->AsJoinEntry(); | 784 JoinEntryInstr* join = last->SuccessorAt(sidx)->AsJoinEntry(); |
| 785 ASSERT(join != NULL); | 785 ASSERT(join != NULL); |
| 786 // Find the old predecessor index. | 786 // Find the old predecessor index. |
| 787 intptr_t old_index = join->IndexOfPredecessor(old_block); | 787 const intptr_t old_index = join->IndexOfPredecessor(old_block); |
| 788 intptr_t pred_count = join->PredecessorCount(); | 788 const intptr_t pred_count = join->PredecessorCount(); |
| 789 ASSERT(old_index >= 0); | 789 ASSERT(old_index >= 0); |
| 790 ASSERT(old_index < pred_count); | 790 ASSERT(old_index < pred_count); |
| 791 // Find the new predecessor index while reordering the predecessors. | 791 // Find the new predecessor index while reordering the predecessors. |
| 792 intptr_t new_id = new_block->block_id(); | 792 const intptr_t new_id = new_block->block_id(); |
| 793 intptr_t new_index = old_index; | 793 intptr_t new_index = old_index; |
| 794 // The predecessors are sorted by block id in ascending order. This is done | |
| 795 // in JoinEntryInstr::AddPredecessor and in InlineCall. | |
| 794 if (old_block->block_id() < new_id) { | 796 if (old_block->block_id() < new_id) { |
| 795 // Search upwards, bubbling down intermediate predecessors. | 797 // Search upwards, bubbling down intermediate predecessors. |
| 796 for (; new_index < pred_count - 1; ++new_index) { | 798 for (; new_index < pred_count - 1; ++new_index) { |
| 799 ASSERT(join->predecessors_[new_index]->block_id() < | |
| 800 join->predecessors_[new_index + 1]->block_id()); | |
|
Kevin Millikin (Google)
2012/11/02 11:35:23
The continuation line should be indented 4 spaces.
zerny-google
2012/11/02 12:37:31
Done.
| |
| 797 if (join->predecessors_[new_index + 1]->block_id() > new_id) break; | 801 if (join->predecessors_[new_index + 1]->block_id() > new_id) break; |
| 798 join->predecessors_[new_index] = join->predecessors_[new_index + 1]; | 802 join->predecessors_[new_index] = join->predecessors_[new_index + 1]; |
| 799 } | 803 } |
| 800 } else { | 804 } else { |
| 801 // Search downwards, bubbling up intermediate predecessors. | 805 // Search downwards, bubbling up intermediate predecessors. |
| 802 for (; new_index > 0; --new_index) { | 806 for (; new_index > 0; --new_index) { |
| 807 ASSERT(join->predecessors_[new_index - 1]->block_id() < | |
|
Kevin Millikin (Google)
2012/11/02 11:35:23
Same.
zerny-google
2012/11/02 12:37:31
Done.
| |
| 808 join->predecessors_[new_index]->block_id()); | |
| 803 if (join->predecessors_[new_index - 1]->block_id() < new_id) break; | 809 if (join->predecessors_[new_index - 1]->block_id() < new_id) break; |
| 804 join->predecessors_[new_index] = join->predecessors_[new_index - 1]; | 810 join->predecessors_[new_index] = join->predecessors_[new_index - 1]; |
| 805 } | 811 } |
| 806 } | 812 } |
| 807 join->predecessors_[new_index] = new_block; | 813 join->predecessors_[new_index] = new_block; |
| 808 // If the new and old predecessor index match there is nothing to update. | 814 // If the new and old predecessor index match there is nothing to update. |
| 809 if ((join->phis() == NULL) || (old_index == new_index)) return; | 815 if ((join->phis() == NULL) || (old_index == new_index)) return; |
| 810 // Otherwise, reorder the predecessor uses in each phi. | 816 // Otherwise, reorder the predecessor uses in each phi. |
| 811 for (intptr_t i = 0; i < join->phis()->length(); ++i) { | 817 for (intptr_t i = 0; i < join->phis()->length(); ++i) { |
| 812 PhiInstr* phi = (*join->phis())[i]; | 818 PhiInstr* phi = (*join->phis())[i]; |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 981 ReplacePredecessor(callee_entry, caller_entry); | 987 ReplacePredecessor(callee_entry, caller_entry); |
| 982 // Update the last instruction pointers on each exit (ie, to the new goto). | 988 // Update the last instruction pointers on each exit (ie, to the new goto). |
| 983 for (intptr_t i = 0; i < exits.length(); ++i) { | 989 for (intptr_t i = 0; i < exits.length(); ++i) { |
| 984 exits[i]->set_last_instruction( | 990 exits[i]->set_last_instruction( |
| 985 exits[i]->last_instruction()->previous()->next()); | 991 exits[i]->last_instruction()->previous()->next()); |
| 986 } | 992 } |
| 987 // Mark that the dominator tree is invalid. | 993 // Mark that the dominator tree is invalid. |
| 988 // TODO(zerny): Compute the dominator frontier locally. | 994 // TODO(zerny): Compute the dominator frontier locally. |
| 989 invalid_dominator_tree_ = true; | 995 invalid_dominator_tree_ = true; |
| 990 } | 996 } |
| 997 | |
| 998 // Remove push arguments of the call. | |
| 999 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | |
| 1000 PushArgumentInstr* push = call->ArgumentAt(i); | |
| 1001 push->ReplaceUsesWith(push->value()->definition()); | |
| 1002 push->RemoveFromGraph(); | |
| 1003 } | |
| 1004 | |
| 1005 // Replace remaining constants with uses by constants in the caller's | |
| 1006 // initial definitions. | |
| 1007 GrowableArray<Definition*>* defns = | |
| 1008 callee_graph->graph_entry()->initial_definitions(); | |
| 1009 for (intptr_t i = 0; i < defns->length(); ++i) { | |
| 1010 ConstantInstr* constant = (*defns)[i]->AsConstant(); | |
| 1011 if (constant == NULL || | |
|
Kevin Millikin (Google)
2012/11/02 11:35:23
I wouldn't use continue to skip a single statement
zerny-google
2012/11/02 12:37:31
That is simpler. Thanks for pointing that out.
| |
| 1012 ((constant->input_use_list() == NULL) && | |
| 1013 (constant->env_use_list() == NULL))) { | |
| 1014 continue; | |
| 1015 } | |
| 1016 constant->ReplaceUsesWith( | |
| 1017 AddConstantToInitialDefinitions(constant->value())); | |
| 1018 } | |
| 991 } | 1019 } |
| 992 | 1020 |
| 993 | 1021 |
| 994 void FlowGraph::RepairGraphAfterInlining() { | 1022 void FlowGraph::RepairGraphAfterInlining() { |
| 995 DiscoverBlocks(); | 1023 DiscoverBlocks(); |
| 996 if (invalid_dominator_tree_) { | 1024 if (invalid_dominator_tree_) { |
| 997 GrowableArray<BitVector*> dominance_frontier; | 1025 GrowableArray<BitVector*> dominance_frontier; |
| 998 ComputeDominators(&dominance_frontier); | 1026 ComputeDominators(&dominance_frontier); |
| 999 } | 1027 } |
| 1000 } | 1028 } |
| 1001 | 1029 |
| 1002 | 1030 |
| 1003 intptr_t FlowGraph::InstructionCount() const { | 1031 intptr_t FlowGraph::InstructionCount() const { |
| 1004 intptr_t size = 0; | 1032 intptr_t size = 0; |
| 1005 // Iterate each block, skipping the graph entry. | 1033 // Iterate each block, skipping the graph entry. |
| 1006 for (intptr_t i = 1; i < preorder_.length(); ++i) { | 1034 for (intptr_t i = 1; i < preorder_.length(); ++i) { |
| 1007 for (ForwardInstructionIterator it(preorder_[i]); | 1035 for (ForwardInstructionIterator it(preorder_[i]); |
| 1008 !it.Done(); | 1036 !it.Done(); |
| 1009 it.Advance()) { | 1037 it.Advance()) { |
| 1010 ++size; | 1038 ++size; |
| 1011 } | 1039 } |
| 1012 } | 1040 } |
| 1013 return size; | 1041 return size; |
| 1014 } | 1042 } |
| 1015 | 1043 |
| 1016 | 1044 |
| 1017 } // namespace dart | 1045 } // namespace dart |
| OLD | NEW |