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

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

Issue 299263005: More reduction of accessing TLS by caching/passing isolate value. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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_compiler.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 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_compiler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698