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

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

Issue 14021016: Track side-effect free paths in the graph to allow CSE and LICM for instructions that depend on som… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 months 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 | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_optimizer.h » ('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 10 matching lines...) Expand all
21 : parent_(), 21 : parent_(),
22 current_ssa_temp_index_(0), 22 current_ssa_temp_index_(0),
23 max_block_id_(max_block_id), 23 max_block_id_(max_block_id),
24 parsed_function_(builder.parsed_function()), 24 parsed_function_(builder.parsed_function()),
25 num_copied_params_(builder.num_copied_params()), 25 num_copied_params_(builder.num_copied_params()),
26 num_non_copied_params_(builder.num_non_copied_params()), 26 num_non_copied_params_(builder.num_non_copied_params()),
27 num_stack_locals_(builder.num_stack_locals()), 27 num_stack_locals_(builder.num_stack_locals()),
28 graph_entry_(graph_entry), 28 graph_entry_(graph_entry),
29 preorder_(), 29 preorder_(),
30 postorder_(), 30 postorder_(),
31 reverse_postorder_() { 31 reverse_postorder_(),
32 block_effects_(NULL) {
32 DiscoverBlocks(); 33 DiscoverBlocks();
33 } 34 }
34 35
35 36
36 ConstantInstr* FlowGraph::AddConstantToInitialDefinitions( 37 ConstantInstr* FlowGraph::AddConstantToInitialDefinitions(
37 const Object& object) { 38 const Object& object) {
38 // Check if the constant is already in the pool. 39 // Check if the constant is already in the pool.
39 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) { 40 for (intptr_t i = 0; i < graph_entry_->initial_definitions()->length(); ++i) {
40 ConstantInstr* constant = 41 ConstantInstr* constant =
41 (*graph_entry_->initial_definitions())[i]->AsConstant(); 42 (*graph_entry_->initial_definitions())[i]->AsConstant();
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
92 &preorder_, 93 &preorder_,
93 &postorder_, 94 &postorder_,
94 &parent_, 95 &parent_,
95 variable_count(), 96 variable_count(),
96 num_non_copied_params()); 97 num_non_copied_params());
97 // Create an array of blocks in reverse postorder. 98 // Create an array of blocks in reverse postorder.
98 intptr_t block_count = postorder_.length(); 99 intptr_t block_count = postorder_.length();
99 for (intptr_t i = 0; i < block_count; ++i) { 100 for (intptr_t i = 0; i < block_count; ++i) {
100 reverse_postorder_.Add(postorder_[block_count - i - 1]); 101 reverse_postorder_.Add(postorder_[block_count - i - 1]);
101 } 102 }
103
104 // Block effects are using postorder numbering. Discard computed information.
105 block_effects_ = NULL;
102 } 106 }
103 107
104 108
105 #ifdef DEBUG 109 #ifdef DEBUG
106 // Debugging code to verify the construction of use lists. 110 // Debugging code to verify the construction of use lists.
107 111
108 static intptr_t MembershipCount(Value* use, Value* list) { 112 static intptr_t MembershipCount(Value* use, Value* list) {
109 intptr_t count = 0; 113 intptr_t count = 0;
110 while (list != NULL) { 114 while (list != NULL) {
111 if (list == use) ++count; 115 if (list == use) ++count;
(...skipping 804 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 for (intptr_t i = 1; i < preorder_.length(); ++i) { 920 for (intptr_t i = 1; i < preorder_.length(); ++i) {
917 for (ForwardInstructionIterator it(preorder_[i]); 921 for (ForwardInstructionIterator it(preorder_[i]);
918 !it.Done(); 922 !it.Done();
919 it.Advance()) { 923 it.Advance()) {
920 ++size; 924 ++size;
921 } 925 }
922 } 926 }
923 return size; 927 return size;
924 } 928 }
925 929
930
931 void FlowGraph::ComputeBlockEffects() {
932 block_effects_ = new BlockEffects(this);
933 }
934
935
936 BlockEffects::BlockEffects(FlowGraph* flow_graph)
937 : available_at_(flow_graph->postorder().length()) {
938 // We are tracking a single effect.
939 ASSERT(EffectSet::kLastEffect == 1);
940
941 const intptr_t block_count = flow_graph->postorder().length();
942
943 // Set of blocks that contain side-effects.
944 BitVector* kill = new BitVector(block_count);
945
946 // Per block available-after sets. Block A is available after the block B if
947 // and only if A is either equal to B or A is available at B and B contains no
948 // side-effects. Initially we consider all blocks available after all other
949 // blocks.
950 GrowableArray<BitVector*> available_after(block_count);
951
952 // Discover all blocks with side-effects.
953 for (BlockIterator it = flow_graph->postorder_iterator();
954 !it.Done();
955 it.Advance()) {
956 available_at_.Add(NULL);
957 available_after.Add(NULL);
958
959 BlockEntryInstr* block = it.Current();
960 for (ForwardInstructionIterator it(block);
961 !it.Done();
962 it.Advance()) {
963 if (!it.Current()->Effects().IsNone()) {
964 kill->Add(block->postorder_number());
965 break;
966 }
967 }
968 }
969
970 BitVector* temp = new BitVector(block_count);
971
972 // Recompute available-at based on predecessors' available-after until the fix
973 // point is reached.
974 bool changed;
975 do {
976 changed = false;
977
978 for (BlockIterator it = flow_graph->reverse_postorder_iterator();
979 !it.Done();
980 it.Advance()) {
981 BlockEntryInstr* block = it.Current();
982 const intptr_t block_num = block->postorder_number();
983
984 if (block->IsGraphEntry()) {
985 temp->Clear(); // Nothing is live-in into graph entry.
986 } else {
987 // Available-at is an intersection of all predecessors' available-after
988 // sets.
989 temp->SetAll();
990 for (intptr_t i = 0; i < block->PredecessorCount(); i++) {
991 const intptr_t pred = block->PredecessorAt(i)->postorder_number();
992 if (available_after[pred] != NULL) {
993 temp->Intersect(available_after[pred]);
994 }
995 }
996 }
997
998 BitVector* current = available_at_[block_num];
999 if ((current == NULL) || !current->Equals(*temp)) {
1000 // Available-at changed: update it and recompute available-after.
1001 if (available_at_[block_num] == NULL) {
1002 current = available_at_[block_num] = new BitVector(block_count);
1003 available_after[block_num] = new BitVector(block_count);
1004 // Block is always available after itself.
1005 available_after[block_num]->Add(block_num);
1006 }
1007 current->CopyFrom(temp);
1008 if (!kill->Contains(block_num)) {
1009 available_after[block_num]->CopyFrom(temp);
1010 // Block is always available after itself.
1011 available_after[block_num]->Add(block_num);
1012 }
1013 changed = true;
1014 }
1015 }
1016 } while (changed);
1017 }
1018
1019
1020 bool BlockEffects::IsAvailableAt(Instruction* instr,
1021 BlockEntryInstr* block) const {
1022 return (instr->Dependencies().IsNone()) ||
1023 IsSideEffectFreePath(instr->GetBlock(), block);
1024 }
1025
1026
1027 bool BlockEffects::CanBeMovedTo(Instruction* instr,
1028 BlockEntryInstr* block) const {
1029 return (instr->Dependencies().IsNone()) ||
1030 IsSideEffectFreePath(block, instr->GetBlock());
1031 }
1032
1033
1034 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from,
1035 BlockEntryInstr* to) const {
1036 return available_at_[to->postorder_number()]->Contains(
1037 from->postorder_number());
1038 }
1039
926 } // namespace dart 1040 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698