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

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

Issue 12457034: Ensure that all goto instructions have deoptimization target. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Delete UNREACHABLE Created 7 years, 8 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_builder.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 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 curr = curr->next_use(); 163 curr = curr->next_use();
164 } 164 }
165 165
166 prev = NULL; 166 prev = NULL;
167 curr = defn->env_use_list(); 167 curr = defn->env_use_list();
168 while (curr != NULL) { 168 while (curr != NULL) {
169 ASSERT(prev == curr->previous_use()); 169 ASSERT(prev == curr->previous_use());
170 ASSERT(defn == curr->definition()); 170 ASSERT(defn == curr->definition());
171 Instruction* instr = curr->instruction(); 171 Instruction* instr = curr->instruction();
172 ASSERT(curr == instr->env()->ValueAtUseIndex(curr->use_index())); 172 ASSERT(curr == instr->env()->ValueAtUseIndex(curr->use_index()));
173 ASSERT((instr->IsPhi() && instr->AsPhi()->is_alive()) || 173 // BlockEntry instructions have environments attached to them but
174 // have no reliable way to verify if they are still in the graph.
175 // Thus we just assume they are.
176 ASSERT(instr->IsBlockEntry() ||
177 (instr->IsPhi() && instr->AsPhi()->is_alive()) ||
174 (instr->previous() != NULL)); 178 (instr->previous() != NULL));
175 prev = curr; 179 prev = curr;
176 curr = curr->next_use(); 180 curr = curr->next_use();
177 } 181 }
178 } 182 }
179 } 183 }
180 184
181 185
182 bool FlowGraph::VerifyUseLists() { 186 bool FlowGraph::VerifyUseLists() {
183 // Verify the initial definitions. 187 // Verify the initial definitions.
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after
434 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { 438 for (intptr_t i = parameter_count(); i < variable_count(); ++i) {
435 env.Add(constant_null()); 439 env.Add(constant_null());
436 } 440 }
437 441
438 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0); 442 BlockEntryInstr* normal_entry = graph_entry_->SuccessorAt(0);
439 ASSERT(normal_entry != NULL); // Must have entry. 443 ASSERT(normal_entry != NULL); // Must have entry.
440 RenameRecursive(normal_entry, &env, live_phis); 444 RenameRecursive(normal_entry, &env, live_phis);
441 } 445 }
442 446
443 447
448 void FlowGraph::AttachEnvironment(Instruction* instr,
449 GrowableArray<Definition*>* env) {
450 Environment* deopt_env =
451 Environment::From(*env,
452 num_non_copied_params_,
453 parsed_function_.function());
454 instr->SetEnvironment(deopt_env);
455 for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) {
456 Value* use = it.CurrentValue();
457 use->definition()->AddEnvUse(use);
458 }
459 if (instr->CanDeoptimize()) {
460 instr->env()->set_deopt_id(instr->deopt_id());
461 }
462 }
463
464
444 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, 465 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry,
445 GrowableArray<Definition*>* env, 466 GrowableArray<Definition*>* env,
446 GrowableArray<PhiInstr*>* live_phis) { 467 GrowableArray<PhiInstr*>* live_phis) {
447 // 1. Process phis first. 468 // 1. Process phis first.
448 if (block_entry->IsJoinEntry()) { 469 if (block_entry->IsJoinEntry()) {
449 JoinEntryInstr* join = block_entry->AsJoinEntry(); 470 JoinEntryInstr* join = block_entry->AsJoinEntry();
450 if (join->phis() != NULL) { 471 if (join->phis() != NULL) {
451 for (intptr_t i = 0; i < join->phis()->length(); ++i) { 472 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
452 PhiInstr* phi = (*join->phis())[i]; 473 PhiInstr* phi = (*join->phis())[i];
453 if (phi != NULL) { 474 if (phi != NULL) {
454 (*env)[i] = phi; 475 (*env)[i] = phi;
455 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 476 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
456 } 477 }
457 } 478 }
458 } 479 }
459 } 480 }
460 481
482 // Attach environment to the block entry.
483 AttachEnvironment(block_entry, env);
484
461 // 2. Process normal instructions. 485 // 2. Process normal instructions.
486
462 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { 487 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) {
463 Instruction* current = it.Current(); 488 Instruction* current = it.Current();
464 // Attach current environment to the instructions that can deoptimize and 489
465 // at goto instructions. Optimizations like LICM expect an environment at 490 // Attach current environment to the instructions that need it.
466 // gotos. 491 if (current->NeedsEnvironment()) {
467 if (current->CanDeoptimize() || current->IsGoto()) { 492 AttachEnvironment(current, env);
468 Environment* deopt_env =
469 Environment::From(*env,
470 num_non_copied_params_,
471 parsed_function_.function());
472 current->SetEnvironment(deopt_env);
473 for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) {
474 Value* use = it.CurrentValue();
475 use->definition()->AddEnvUse(use);
476 }
477 }
478 if (current->CanDeoptimize()) {
479 current->env()->set_deopt_id(current->deopt_id());
480 } 493 }
481 494
482 // 2a. Handle uses: 495 // 2a. Handle uses:
483 // Update expression stack environment for each use. 496 // Update expression stack environment for each use.
484 // For each use of a LoadLocal or StoreLocal: Replace it with the value 497 // For each use of a LoadLocal or StoreLocal: Replace it with the value
485 // from the environment. 498 // from the environment.
486 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) { 499 for (intptr_t i = current->InputCount() - 1; i >= 0; --i) {
487 Value* v = current->InputAt(i); 500 Value* v = current->InputAt(i);
488 // Update expression stack. 501 // Update expression stack.
489 ASSERT(env->length() > variable_count()); 502 ASSERT(env->length() > variable_count());
(...skipping 235 matching lines...) Expand 10 before | Expand all | Expand 10 after
725 if (!found) { 738 if (!found) {
726 result->Add(field); 739 result->Add(field);
727 } 740 }
728 } 741 }
729 } 742 }
730 743
731 return result; 744 return result;
732 } 745 }
733 746
734 } // namespace dart 747 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph.h ('k') | runtime/vm/flow_graph_builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698