Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: runtime/vm/flow_graph.cc

Issue 11262008: Remove push arguments and replace constants in FlowGraph::InlineCall. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Srdjan's DBCs from previous CL Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/flow_graph_inliner.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698