| 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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 ConstantInstr* FlowGraph::GetConstant(const Object& object) { | 80 ConstantInstr* FlowGraph::GetConstant(const Object& object) { |
| 81 // Check if the constant is already in the pool. | 81 // Check if the constant is already in the pool. |
| 82 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); | 82 GrowableArray<Definition*>* pool = graph_entry_->initial_definitions(); |
| 83 for (intptr_t i = 0; i < pool->length(); ++i) { | 83 for (intptr_t i = 0; i < pool->length(); ++i) { |
| 84 ConstantInstr* constant = (*pool)[i]->AsConstant(); | 84 ConstantInstr* constant = (*pool)[i]->AsConstant(); |
| 85 if ((constant != NULL) && (constant->value().raw() == object.raw())) { | 85 if ((constant != NULL) && (constant->value().raw() == object.raw())) { |
| 86 return constant; | 86 return constant; |
| 87 } | 87 } |
| 88 } | 88 } |
| 89 // Otherwise, allocate and add it to the pool. | 89 // Otherwise, allocate and add it to the pool. |
| 90 ConstantInstr* constant = new ConstantInstr(object); | 90 ConstantInstr* constant = new(isolate()) ConstantInstr(object); |
| 91 constant->set_ssa_temp_index(alloc_ssa_temp_index()); | 91 constant->set_ssa_temp_index(alloc_ssa_temp_index()); |
| 92 AddToInitialDefinitions(constant); | 92 AddToInitialDefinitions(constant); |
| 93 return constant; | 93 return constant; |
| 94 } | 94 } |
| 95 | 95 |
| 96 | 96 |
| 97 void FlowGraph::AddToInitialDefinitions(Definition* defn) { | 97 void FlowGraph::AddToInitialDefinitions(Definition* defn) { |
| 98 // TODO(zerny): Set previous to the graph entry so it is accessible by | 98 // TODO(zerny): Set previous to the graph entry so it is accessible by |
| 99 // GetBlock. Remove this once there is a direct pointer to the block. | 99 // GetBlock. Remove this once there is a direct pointer to the block. |
| 100 defn->set_previous(graph_entry_); | 100 defn->set_previous(graph_entry_); |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 264 } |
| 265 } | 265 } |
| 266 return true; // Return true so we can ASSERT validation. | 266 return true; // Return true so we can ASSERT validation. |
| 267 } | 267 } |
| 268 #endif // DEBUG | 268 #endif // DEBUG |
| 269 | 269 |
| 270 | 270 |
| 271 LivenessAnalysis::LivenessAnalysis( | 271 LivenessAnalysis::LivenessAnalysis( |
| 272 intptr_t variable_count, | 272 intptr_t variable_count, |
| 273 const GrowableArray<BlockEntryInstr*>& postorder) | 273 const GrowableArray<BlockEntryInstr*>& postorder) |
| 274 : variable_count_(variable_count), | 274 : isolate_(Isolate::Current()), |
| 275 variable_count_(variable_count), |
| 275 postorder_(postorder), | 276 postorder_(postorder), |
| 276 live_out_(postorder.length()), | 277 live_out_(postorder.length()), |
| 277 kill_(postorder.length()), | 278 kill_(postorder.length()), |
| 278 live_in_(postorder.length()) { | 279 live_in_(postorder.length()) { |
| 279 } | 280 } |
| 280 | 281 |
| 281 | 282 |
| 282 bool LivenessAnalysis::UpdateLiveOut(const BlockEntryInstr& block) { | 283 bool LivenessAnalysis::UpdateLiveOut(const BlockEntryInstr& block) { |
| 283 BitVector* live_out = live_out_[block.postorder_number()]; | 284 BitVector* live_out = live_out_[block.postorder_number()]; |
| 284 bool changed = false; | 285 bool changed = false; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 320 changed = true; | 321 changed = true; |
| 321 } | 322 } |
| 322 } | 323 } |
| 323 } while (changed); | 324 } while (changed); |
| 324 } | 325 } |
| 325 | 326 |
| 326 | 327 |
| 327 void LivenessAnalysis::Analyze() { | 328 void LivenessAnalysis::Analyze() { |
| 328 const intptr_t block_count = postorder_.length(); | 329 const intptr_t block_count = postorder_.length(); |
| 329 for (intptr_t i = 0; i < block_count; i++) { | 330 for (intptr_t i = 0; i < block_count; i++) { |
| 330 live_out_.Add(new BitVector(variable_count_)); | 331 live_out_.Add(new(isolate()) BitVector(variable_count_)); |
| 331 kill_.Add(new BitVector(variable_count_)); | 332 kill_.Add(new(isolate()) BitVector(variable_count_)); |
| 332 live_in_.Add(new BitVector(variable_count_)); | 333 live_in_.Add(new(isolate()) BitVector(variable_count_)); |
| 333 } | 334 } |
| 334 | 335 |
| 335 ComputeInitialSets(); | 336 ComputeInitialSets(); |
| 336 ComputeLiveInAndLiveOutSets(); | 337 ComputeLiveInAndLiveOutSets(); |
| 337 } | 338 } |
| 338 | 339 |
| 339 | 340 |
| 340 static void PrintBitVector(const char* tag, BitVector* v) { | 341 static void PrintBitVector(const char* tag, BitVector* v) { |
| 341 OS::Print("%s:", tag); | 342 OS::Print("%s:", tag); |
| 342 for (BitVector::Iterator it(v); !it.Done(); it.Advance()) { | 343 for (BitVector::Iterator it(v); !it.Done(); it.Advance()) { |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 433 | 434 |
| 434 const FlowGraph* flow_graph_; | 435 const FlowGraph* flow_graph_; |
| 435 const intptr_t num_non_copied_params_; | 436 const intptr_t num_non_copied_params_; |
| 436 GrowableArray<BitVector*> assigned_vars_; | 437 GrowableArray<BitVector*> assigned_vars_; |
| 437 }; | 438 }; |
| 438 | 439 |
| 439 | 440 |
| 440 void VariableLivenessAnalysis::ComputeInitialSets() { | 441 void VariableLivenessAnalysis::ComputeInitialSets() { |
| 441 const intptr_t block_count = postorder_.length(); | 442 const intptr_t block_count = postorder_.length(); |
| 442 | 443 |
| 443 BitVector* last_loads = new BitVector(variable_count_); | 444 BitVector* last_loads = new(isolate()) BitVector(variable_count_); |
| 444 for (intptr_t i = 0; i < block_count; i++) { | 445 for (intptr_t i = 0; i < block_count; i++) { |
| 445 BlockEntryInstr* block = postorder_[i]; | 446 BlockEntryInstr* block = postorder_[i]; |
| 446 | 447 |
| 447 BitVector* kill = kill_[i]; | 448 BitVector* kill = kill_[i]; |
| 448 BitVector* live_in = live_in_[i]; | 449 BitVector* live_in = live_in_[i]; |
| 449 last_loads->Clear(); | 450 last_loads->Clear(); |
| 450 | 451 |
| 451 // There is an implicit use (load-local) of every local variable at each | 452 // There is an implicit use (load-local) of every local variable at each |
| 452 // call inside a try{} block and every call has an implicit control-flow | 453 // call inside a try{} block and every call has an implicit control-flow |
| 453 // to the catch entry. As an approximation we mark all locals as live | 454 // to the catch entry. As an approximation we mark all locals as live |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 557 // Use a link-eval data structure with path compression. Implement path | 558 // Use a link-eval data structure with path compression. Implement path |
| 558 // compression in place by mutating the parent array. Each block has a | 559 // compression in place by mutating the parent array. Each block has a |
| 559 // label, which is the minimum block number on the compressed path. | 560 // label, which is the minimum block number on the compressed path. |
| 560 | 561 |
| 561 // Initialize idom, semi, and label used by SEMI-NCA. Initialize the | 562 // Initialize idom, semi, and label used by SEMI-NCA. Initialize the |
| 562 // dominance frontier output array. | 563 // dominance frontier output array. |
| 563 for (intptr_t i = 0; i < size; ++i) { | 564 for (intptr_t i = 0; i < size; ++i) { |
| 564 idom.Add(parent_[i]); | 565 idom.Add(parent_[i]); |
| 565 semi.Add(i); | 566 semi.Add(i); |
| 566 label.Add(i); | 567 label.Add(i); |
| 567 dominance_frontier->Add(new BitVector(size)); | 568 dominance_frontier->Add(new(isolate()) BitVector(size)); |
| 568 } | 569 } |
| 569 | 570 |
| 570 // Loop over the blocks in reverse preorder (not including the graph | 571 // Loop over the blocks in reverse preorder (not including the graph |
| 571 // entry). Clear the dominated blocks in the graph entry in case | 572 // entry). Clear the dominated blocks in the graph entry in case |
| 572 // ComputeDominators is used to recompute them. | 573 // ComputeDominators is used to recompute them. |
| 573 preorder_[0]->ClearDominatedBlocks(); | 574 preorder_[0]->ClearDominatedBlocks(); |
| 574 for (intptr_t block_index = size - 1; block_index >= 1; --block_index) { | 575 for (intptr_t block_index = size - 1; block_index >= 1; --block_index) { |
| 575 // Loop over the predecessors. | 576 // Loop over the predecessors. |
| 576 BlockEntryInstr* block = preorder_[block_index]; | 577 BlockEntryInstr* block = preorder_[block_index]; |
| 577 // Clear the immediately dominated blocks in case ComputeDominators is | 578 // Clear the immediately dominated blocks in case ComputeDominators is |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 720 Definition* defn = (*inlining_parameters)[i]; | 721 Definition* defn = (*inlining_parameters)[i]; |
| 721 AllocateSSAIndexes(defn); | 722 AllocateSSAIndexes(defn); |
| 722 AddToInitialDefinitions(defn); | 723 AddToInitialDefinitions(defn); |
| 723 env.Add(defn); | 724 env.Add(defn); |
| 724 } | 725 } |
| 725 } else { | 726 } else { |
| 726 // Create new parameters. For functions compiled for OSR, the locals | 727 // Create new parameters. For functions compiled for OSR, the locals |
| 727 // are unknown and so treated like parameters. | 728 // are unknown and so treated like parameters. |
| 728 intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count(); | 729 intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count(); |
| 729 for (intptr_t i = 0; i < count; ++i) { | 730 for (intptr_t i = 0; i < count; ++i) { |
| 730 ParameterInstr* param = new ParameterInstr(i, entry); | 731 ParameterInstr* param = new(isolate()) ParameterInstr(i, entry); |
| 731 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 732 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 732 AddToInitialDefinitions(param); | 733 AddToInitialDefinitions(param); |
| 733 env.Add(param); | 734 env.Add(param); |
| 734 } | 735 } |
| 735 } | 736 } |
| 736 | 737 |
| 737 // Initialize all locals with #null in the renaming environment. For OSR, | 738 // Initialize all locals with #null in the renaming environment. For OSR, |
| 738 // the locals have already been handled as parameters. | 739 // the locals have already been handled as parameters. |
| 739 if (!IsCompiledForOsr()) { | 740 if (!IsCompiledForOsr()) { |
| 740 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { | 741 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 // more redundant phis. | 802 // more redundant phis. |
| 802 phi->mark_alive(); | 803 phi->mark_alive(); |
| 803 live_phis->Add(phi); | 804 live_phis->Add(phi); |
| 804 } | 805 } |
| 805 } | 806 } |
| 806 } | 807 } |
| 807 } | 808 } |
| 808 } else if (block_entry->IsCatchBlockEntry()) { | 809 } else if (block_entry->IsCatchBlockEntry()) { |
| 809 // Add real definitions for all locals and parameters. | 810 // Add real definitions for all locals and parameters. |
| 810 for (intptr_t i = 0; i < env->length(); ++i) { | 811 for (intptr_t i = 0; i < env->length(); ++i) { |
| 811 ParameterInstr* param = new ParameterInstr(i, block_entry); | 812 ParameterInstr* param = new(isolate()) ParameterInstr(i, block_entry); |
| 812 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. | 813 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. |
| 813 (*env)[i] = param; | 814 (*env)[i] = param; |
| 814 block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param); | 815 block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param); |
| 815 } | 816 } |
| 816 } | 817 } |
| 817 | 818 |
| 818 // Prune non-live variables at block entry by replacing their environment | 819 // Prune non-live variables at block entry by replacing their environment |
| 819 // slots with null. | 820 // slots with null. |
| 820 BitVector* live_in = variable_liveness->GetLiveInSet(block_entry); | 821 BitVector* live_in = variable_liveness->GetLiveInSet(block_entry); |
| 821 for (intptr_t i = 0; i < variable_count(); i++) { | 822 for (intptr_t i = 0; i < variable_count(); i++) { |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 966 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { | 967 block_entry->last_instruction()->SuccessorAt(0)->IsJoinEntry()) { |
| 967 JoinEntryInstr* successor = | 968 JoinEntryInstr* successor = |
| 968 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); | 969 block_entry->last_instruction()->SuccessorAt(0)->AsJoinEntry(); |
| 969 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); | 970 intptr_t pred_index = successor->IndexOfPredecessor(block_entry); |
| 970 ASSERT(pred_index >= 0); | 971 ASSERT(pred_index >= 0); |
| 971 if (successor->phis() != NULL) { | 972 if (successor->phis() != NULL) { |
| 972 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { | 973 for (intptr_t i = 0; i < successor->phis()->length(); ++i) { |
| 973 PhiInstr* phi = (*successor->phis())[i]; | 974 PhiInstr* phi = (*successor->phis())[i]; |
| 974 if (phi != NULL) { | 975 if (phi != NULL) { |
| 975 // Rename input operand. | 976 // Rename input operand. |
| 976 Value* use = new Value((*env)[i]); | 977 Value* use = new(isolate()) Value((*env)[i]); |
| 977 phi->SetInputAt(pred_index, use); | 978 phi->SetInputAt(pred_index, use); |
| 978 } | 979 } |
| 979 } | 980 } |
| 980 } | 981 } |
| 981 } | 982 } |
| 982 } | 983 } |
| 983 | 984 |
| 984 | 985 |
| 985 void FlowGraph::RemoveDeadPhis(GrowableArray<PhiInstr*>* live_phis) { | 986 void FlowGraph::RemoveDeadPhis(GrowableArray<PhiInstr*>* live_phis) { |
| 986 while (!live_phis->is_empty()) { | 987 while (!live_phis->is_empty()) { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1022 } | 1023 } |
| 1023 } | 1024 } |
| 1024 } | 1025 } |
| 1025 | 1026 |
| 1026 | 1027 |
| 1027 // Find the natural loop for the back edge m->n and attach loop information | 1028 // Find the natural loop for the back edge m->n and attach loop information |
| 1028 // to block n (loop header). The algorithm is described in "Advanced Compiler | 1029 // to block n (loop header). The algorithm is described in "Advanced Compiler |
| 1029 // Design & Implementation" (Muchnick) p192. | 1030 // Design & Implementation" (Muchnick) p192. |
| 1030 BitVector* FlowGraph::FindLoop(BlockEntryInstr* m, BlockEntryInstr* n) { | 1031 BitVector* FlowGraph::FindLoop(BlockEntryInstr* m, BlockEntryInstr* n) { |
| 1031 GrowableArray<BlockEntryInstr*> stack; | 1032 GrowableArray<BlockEntryInstr*> stack; |
| 1032 BitVector* loop = new BitVector(preorder_.length()); | 1033 BitVector* loop = new(isolate()) BitVector(preorder_.length()); |
| 1033 | 1034 |
| 1034 loop->Add(n->preorder_number()); | 1035 loop->Add(n->preorder_number()); |
| 1035 if (n != m) { | 1036 if (n != m) { |
| 1036 loop->Add(m->preorder_number()); | 1037 loop->Add(m->preorder_number()); |
| 1037 stack.Add(m); | 1038 stack.Add(m); |
| 1038 } | 1039 } |
| 1039 | 1040 |
| 1040 while (!stack.is_empty()) { | 1041 while (!stack.is_empty()) { |
| 1041 BlockEntryInstr* p = stack.RemoveLast(); | 1042 BlockEntryInstr* p = stack.RemoveLast(); |
| 1042 for (intptr_t i = 0; i < p->PredecessorCount(); ++i) { | 1043 for (intptr_t i = 0; i < p->PredecessorCount(); ++i) { |
| 1043 BlockEntryInstr* q = p->PredecessorAt(i); | 1044 BlockEntryInstr* q = p->PredecessorAt(i); |
| 1044 if (!loop->Contains(q->preorder_number())) { | 1045 if (!loop->Contains(q->preorder_number())) { |
| 1045 loop->Add(q->preorder_number()); | 1046 loop->Add(q->preorder_number()); |
| 1046 stack.Add(q); | 1047 stack.Add(q); |
| 1047 } | 1048 } |
| 1048 } | 1049 } |
| 1049 } | 1050 } |
| 1050 return loop; | 1051 return loop; |
| 1051 } | 1052 } |
| 1052 | 1053 |
| 1053 | 1054 |
| 1054 ZoneGrowableArray<BlockEntryInstr*>* FlowGraph::ComputeLoops() { | 1055 ZoneGrowableArray<BlockEntryInstr*>* FlowGraph::ComputeLoops() { |
| 1055 ZoneGrowableArray<BlockEntryInstr*>* loop_headers = | 1056 ZoneGrowableArray<BlockEntryInstr*>* loop_headers = |
| 1056 new ZoneGrowableArray<BlockEntryInstr*>(); | 1057 new(isolate()) ZoneGrowableArray<BlockEntryInstr*>(); |
| 1057 | 1058 |
| 1058 for (BlockIterator it = postorder_iterator(); | 1059 for (BlockIterator it = postorder_iterator(); |
| 1059 !it.Done(); | 1060 !it.Done(); |
| 1060 it.Advance()) { | 1061 it.Advance()) { |
| 1061 BlockEntryInstr* block = it.Current(); | 1062 BlockEntryInstr* block = it.Current(); |
| 1062 for (intptr_t i = 0; i < block->PredecessorCount(); ++i) { | 1063 for (intptr_t i = 0; i < block->PredecessorCount(); ++i) { |
| 1063 BlockEntryInstr* pred = block->PredecessorAt(i); | 1064 BlockEntryInstr* pred = block->PredecessorAt(i); |
| 1064 if (block->Dominates(pred)) { | 1065 if (block->Dominates(pred)) { |
| 1065 if (FLAG_trace_optimization) { | 1066 if (FLAG_trace_optimization) { |
| 1066 OS::Print("Back edge B%" Pd " -> B%" Pd "\n", pred->block_id(), | 1067 OS::Print("Back edge B%" Pd " -> B%" Pd "\n", pred->block_id(), |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 !it.Done(); | 1123 !it.Done(); |
| 1123 it.Advance()) { | 1124 it.Advance()) { |
| 1124 ++size; | 1125 ++size; |
| 1125 } | 1126 } |
| 1126 } | 1127 } |
| 1127 return size; | 1128 return size; |
| 1128 } | 1129 } |
| 1129 | 1130 |
| 1130 | 1131 |
| 1131 void FlowGraph::ComputeBlockEffects() { | 1132 void FlowGraph::ComputeBlockEffects() { |
| 1132 block_effects_ = new BlockEffects(this); | 1133 block_effects_ = new(isolate()) BlockEffects(this); |
| 1133 } | 1134 } |
| 1134 | 1135 |
| 1135 | 1136 |
| 1136 BlockEffects::BlockEffects(FlowGraph* flow_graph) | 1137 BlockEffects::BlockEffects(FlowGraph* flow_graph) |
| 1137 : available_at_(flow_graph->postorder().length()) { | 1138 : available_at_(flow_graph->postorder().length()) { |
| 1138 // We are tracking a single effect. | 1139 // We are tracking a single effect. |
| 1139 ASSERT(EffectSet::kLastEffect == 1); | 1140 ASSERT(EffectSet::kLastEffect == 1); |
| 1140 | 1141 Isolate* isolate = flow_graph->isolate(); |
| 1141 const intptr_t block_count = flow_graph->postorder().length(); | 1142 const intptr_t block_count = flow_graph->postorder().length(); |
| 1142 | 1143 |
| 1143 // Set of blocks that contain side-effects. | 1144 // Set of blocks that contain side-effects. |
| 1144 BitVector* kill = new BitVector(block_count); | 1145 BitVector* kill = new(isolate) BitVector(block_count); |
| 1145 | 1146 |
| 1146 // Per block available-after sets. Block A is available after the block B if | 1147 // Per block available-after sets. Block A is available after the block B if |
| 1147 // and only if A is either equal to B or A is available at B and B contains no | 1148 // and only if A is either equal to B or A is available at B and B contains no |
| 1148 // side-effects. Initially we consider all blocks available after all other | 1149 // side-effects. Initially we consider all blocks available after all other |
| 1149 // blocks. | 1150 // blocks. |
| 1150 GrowableArray<BitVector*> available_after(block_count); | 1151 GrowableArray<BitVector*> available_after(block_count); |
| 1151 | 1152 |
| 1152 // Discover all blocks with side-effects. | 1153 // Discover all blocks with side-effects. |
| 1153 for (BlockIterator it = flow_graph->postorder_iterator(); | 1154 for (BlockIterator it = flow_graph->postorder_iterator(); |
| 1154 !it.Done(); | 1155 !it.Done(); |
| 1155 it.Advance()) { | 1156 it.Advance()) { |
| 1156 available_at_.Add(NULL); | 1157 available_at_.Add(NULL); |
| 1157 available_after.Add(NULL); | 1158 available_after.Add(NULL); |
| 1158 | 1159 |
| 1159 BlockEntryInstr* block = it.Current(); | 1160 BlockEntryInstr* block = it.Current(); |
| 1160 for (ForwardInstructionIterator it(block); | 1161 for (ForwardInstructionIterator it(block); |
| 1161 !it.Done(); | 1162 !it.Done(); |
| 1162 it.Advance()) { | 1163 it.Advance()) { |
| 1163 if (!it.Current()->Effects().IsNone()) { | 1164 if (!it.Current()->Effects().IsNone()) { |
| 1164 kill->Add(block->postorder_number()); | 1165 kill->Add(block->postorder_number()); |
| 1165 break; | 1166 break; |
| 1166 } | 1167 } |
| 1167 } | 1168 } |
| 1168 } | 1169 } |
| 1169 | 1170 |
| 1170 BitVector* temp = new BitVector(block_count); | 1171 BitVector* temp = new(isolate) BitVector(block_count); |
| 1171 | 1172 |
| 1172 // Recompute available-at based on predecessors' available-after until the fix | 1173 // Recompute available-at based on predecessors' available-after until the fix |
| 1173 // point is reached. | 1174 // point is reached. |
| 1174 bool changed; | 1175 bool changed; |
| 1175 do { | 1176 do { |
| 1176 changed = false; | 1177 changed = false; |
| 1177 | 1178 |
| 1178 for (BlockIterator it = flow_graph->reverse_postorder_iterator(); | 1179 for (BlockIterator it = flow_graph->reverse_postorder_iterator(); |
| 1179 !it.Done(); | 1180 !it.Done(); |
| 1180 it.Advance()) { | 1181 it.Advance()) { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1192 if (available_after[pred] != NULL) { | 1193 if (available_after[pred] != NULL) { |
| 1193 temp->Intersect(available_after[pred]); | 1194 temp->Intersect(available_after[pred]); |
| 1194 } | 1195 } |
| 1195 } | 1196 } |
| 1196 } | 1197 } |
| 1197 | 1198 |
| 1198 BitVector* current = available_at_[block_num]; | 1199 BitVector* current = available_at_[block_num]; |
| 1199 if ((current == NULL) || !current->Equals(*temp)) { | 1200 if ((current == NULL) || !current->Equals(*temp)) { |
| 1200 // Available-at changed: update it and recompute available-after. | 1201 // Available-at changed: update it and recompute available-after. |
| 1201 if (available_at_[block_num] == NULL) { | 1202 if (available_at_[block_num] == NULL) { |
| 1202 current = available_at_[block_num] = new BitVector(block_count); | 1203 current = available_at_[block_num] = |
| 1203 available_after[block_num] = new BitVector(block_count); | 1204 new(isolate) BitVector(block_count); |
| 1205 available_after[block_num] = |
| 1206 new(isolate) BitVector(block_count); |
| 1204 // Block is always available after itself. | 1207 // Block is always available after itself. |
| 1205 available_after[block_num]->Add(block_num); | 1208 available_after[block_num]->Add(block_num); |
| 1206 } | 1209 } |
| 1207 current->CopyFrom(temp); | 1210 current->CopyFrom(temp); |
| 1208 if (!kill->Contains(block_num)) { | 1211 if (!kill->Contains(block_num)) { |
| 1209 available_after[block_num]->CopyFrom(temp); | 1212 available_after[block_num]->CopyFrom(temp); |
| 1210 // Block is always available after itself. | 1213 // Block is always available after itself. |
| 1211 available_after[block_num]->Add(block_num); | 1214 available_after[block_num]->Add(block_num); |
| 1212 } | 1215 } |
| 1213 changed = true; | 1216 changed = true; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1231 } | 1234 } |
| 1232 | 1235 |
| 1233 | 1236 |
| 1234 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, | 1237 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, |
| 1235 BlockEntryInstr* to) const { | 1238 BlockEntryInstr* to) const { |
| 1236 return available_at_[to->postorder_number()]->Contains( | 1239 return available_at_[to->postorder_number()]->Contains( |
| 1237 from->postorder_number()); | 1240 from->postorder_number()); |
| 1238 } | 1241 } |
| 1239 | 1242 |
| 1240 } // namespace dart | 1243 } // namespace dart |
| OLD | NEW |