| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/hydrogen.h" | 5 #include "src/hydrogen.h" |
| 6 #include "src/hydrogen-gvn.h" | 6 #include "src/hydrogen-gvn.h" |
| 7 #include "src/v8.h" | 7 #include "src/v8.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 } else { | 393 } else { |
| 394 for (index = 0; index < kNumberOfInobjectFields; ++index) { | 394 for (index = 0; index < kNumberOfInobjectFields; ++index) { |
| 395 result.AddSpecial(InobjectField(index)); | 395 result.AddSpecial(InobjectField(index)); |
| 396 } | 396 } |
| 397 } | 397 } |
| 398 } | 398 } |
| 399 return result; | 399 return result; |
| 400 } | 400 } |
| 401 | 401 |
| 402 | 402 |
| 403 OStream& operator<<(OStream& os, const TrackedEffects& te) { | 403 std::ostream& operator<<(std::ostream& os, const TrackedEffects& te) { |
| 404 SideEffectsTracker* t = te.tracker; | 404 SideEffectsTracker* t = te.tracker; |
| 405 const char* separator = ""; | 405 const char* separator = ""; |
| 406 os << "["; | 406 os << "["; |
| 407 for (int bit = 0; bit < kNumberOfFlags; ++bit) { | 407 for (int bit = 0; bit < kNumberOfFlags; ++bit) { |
| 408 GVNFlag flag = GVNFlagFromInt(bit); | 408 GVNFlag flag = GVNFlagFromInt(bit); |
| 409 if (te.effects.ContainsFlag(flag)) { | 409 if (te.effects.ContainsFlag(flag)) { |
| 410 os << separator; | 410 os << separator; |
| 411 separator = ", "; | 411 separator = ", "; |
| 412 switch (flag) { | 412 switch (flag) { |
| 413 #define DECLARE_FLAG(Type) \ | 413 #define DECLARE_FLAG(Type) \ |
| (...skipping 29 matching lines...) Expand all Loading... |
| 443 for (int i = 0; i < num_global_vars_; ++i) { | 443 for (int i = 0; i < num_global_vars_; ++i) { |
| 444 if (cell == global_vars_[i]) { | 444 if (cell == global_vars_[i]) { |
| 445 *index = i; | 445 *index = i; |
| 446 return true; | 446 return true; |
| 447 } | 447 } |
| 448 } | 448 } |
| 449 if (num_global_vars_ < kNumberOfGlobalVars) { | 449 if (num_global_vars_ < kNumberOfGlobalVars) { |
| 450 if (FLAG_trace_gvn) { | 450 if (FLAG_trace_gvn) { |
| 451 OFStream os(stdout); | 451 OFStream os(stdout); |
| 452 os << "Tracking global var [" << *cell.handle() << "] " | 452 os << "Tracking global var [" << *cell.handle() << "] " |
| 453 << "(mapped to index " << num_global_vars_ << ")" << endl; | 453 << "(mapped to index " << num_global_vars_ << ")" << std::endl; |
| 454 } | 454 } |
| 455 *index = num_global_vars_; | 455 *index = num_global_vars_; |
| 456 global_vars_[num_global_vars_++] = cell; | 456 global_vars_[num_global_vars_++] = cell; |
| 457 return true; | 457 return true; |
| 458 } | 458 } |
| 459 return false; | 459 return false; |
| 460 } | 460 } |
| 461 | 461 |
| 462 | 462 |
| 463 bool SideEffectsTracker::ComputeInobjectField(HObjectAccess access, | 463 bool SideEffectsTracker::ComputeInobjectField(HObjectAccess access, |
| 464 int* index) { | 464 int* index) { |
| 465 for (int i = 0; i < num_inobject_fields_; ++i) { | 465 for (int i = 0; i < num_inobject_fields_; ++i) { |
| 466 if (access.Equals(inobject_fields_[i])) { | 466 if (access.Equals(inobject_fields_[i])) { |
| 467 *index = i; | 467 *index = i; |
| 468 return true; | 468 return true; |
| 469 } | 469 } |
| 470 } | 470 } |
| 471 if (num_inobject_fields_ < kNumberOfInobjectFields) { | 471 if (num_inobject_fields_ < kNumberOfInobjectFields) { |
| 472 if (FLAG_trace_gvn) { | 472 if (FLAG_trace_gvn) { |
| 473 OFStream os(stdout); | 473 OFStream os(stdout); |
| 474 os << "Tracking inobject field access " << access << " (mapped to index " | 474 os << "Tracking inobject field access " << access << " (mapped to index " |
| 475 << num_inobject_fields_ << ")" << endl; | 475 << num_inobject_fields_ << ")" << std::endl; |
| 476 } | 476 } |
| 477 *index = num_inobject_fields_; | 477 *index = num_inobject_fields_; |
| 478 inobject_fields_[num_inobject_fields_++] = access; | 478 inobject_fields_[num_inobject_fields_++] = access; |
| 479 return true; | 479 return true; |
| 480 } | 480 } |
| 481 return false; | 481 return false; |
| 482 } | 482 } |
| 483 | 483 |
| 484 | 484 |
| 485 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph) | 485 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph) |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 560 void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() { | 560 void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() { |
| 561 TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n", | 561 TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n", |
| 562 graph()->use_optimistic_licm() ? "yes" : "no"); | 562 graph()->use_optimistic_licm() ? "yes" : "no"); |
| 563 for (int i = graph()->blocks()->length() - 1; i >= 0; --i) { | 563 for (int i = graph()->blocks()->length() - 1; i >= 0; --i) { |
| 564 HBasicBlock* block = graph()->blocks()->at(i); | 564 HBasicBlock* block = graph()->blocks()->at(i); |
| 565 if (block->IsLoopHeader()) { | 565 if (block->IsLoopHeader()) { |
| 566 SideEffects side_effects = loop_side_effects_[block->block_id()]; | 566 SideEffects side_effects = loop_side_effects_[block->block_id()]; |
| 567 if (FLAG_trace_gvn) { | 567 if (FLAG_trace_gvn) { |
| 568 OFStream os(stdout); | 568 OFStream os(stdout); |
| 569 os << "Try loop invariant motion for " << *block << " changes " | 569 os << "Try loop invariant motion for " << *block << " changes " |
| 570 << Print(side_effects) << endl; | 570 << Print(side_effects) << std::endl; |
| 571 } | 571 } |
| 572 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); | 572 HBasicBlock* last = block->loop_information()->GetLastBackEdge(); |
| 573 for (int j = block->block_id(); j <= last->block_id(); ++j) { | 573 for (int j = block->block_id(); j <= last->block_id(); ++j) { |
| 574 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); | 574 ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects); |
| 575 } | 575 } |
| 576 } | 576 } |
| 577 } | 577 } |
| 578 } | 578 } |
| 579 | 579 |
| 580 | 580 |
| 581 void HGlobalValueNumberingPhase::ProcessLoopBlock( | 581 void HGlobalValueNumberingPhase::ProcessLoopBlock( |
| 582 HBasicBlock* block, | 582 HBasicBlock* block, |
| 583 HBasicBlock* loop_header, | 583 HBasicBlock* loop_header, |
| 584 SideEffects loop_kills) { | 584 SideEffects loop_kills) { |
| 585 HBasicBlock* pre_header = loop_header->predecessors()->at(0); | 585 HBasicBlock* pre_header = loop_header->predecessors()->at(0); |
| 586 if (FLAG_trace_gvn) { | 586 if (FLAG_trace_gvn) { |
| 587 OFStream os(stdout); | 587 OFStream os(stdout); |
| 588 os << "Loop invariant code motion for " << *block << " depends on " | 588 os << "Loop invariant code motion for " << *block << " depends on " |
| 589 << Print(loop_kills) << endl; | 589 << Print(loop_kills) << std::endl; |
| 590 } | 590 } |
| 591 HInstruction* instr = block->first(); | 591 HInstruction* instr = block->first(); |
| 592 while (instr != NULL) { | 592 while (instr != NULL) { |
| 593 HInstruction* next = instr->next(); | 593 HInstruction* next = instr->next(); |
| 594 if (instr->CheckFlag(HValue::kUseGVN)) { | 594 if (instr->CheckFlag(HValue::kUseGVN)) { |
| 595 SideEffects changes = side_effects_tracker_.ComputeChanges(instr); | 595 SideEffects changes = side_effects_tracker_.ComputeChanges(instr); |
| 596 SideEffects depends_on = side_effects_tracker_.ComputeDependsOn(instr); | 596 SideEffects depends_on = side_effects_tracker_.ComputeDependsOn(instr); |
| 597 if (FLAG_trace_gvn) { | 597 if (FLAG_trace_gvn) { |
| 598 OFStream os(stdout); | 598 OFStream os(stdout); |
| 599 os << "Checking instruction i" << instr->id() << " (" | 599 os << "Checking instruction i" << instr->id() << " (" |
| 600 << instr->Mnemonic() << ") changes " << Print(changes) | 600 << instr->Mnemonic() << ") changes " << Print(changes) |
| 601 << ", depends on " << Print(depends_on) << ". Loop changes " | 601 << ", depends on " << Print(depends_on) << ". Loop changes " |
| 602 << Print(loop_kills) << endl; | 602 << Print(loop_kills) << std::endl; |
| 603 } | 603 } |
| 604 bool can_hoist = !depends_on.ContainsAnyOf(loop_kills); | 604 bool can_hoist = !depends_on.ContainsAnyOf(loop_kills); |
| 605 if (can_hoist && !graph()->use_optimistic_licm()) { | 605 if (can_hoist && !graph()->use_optimistic_licm()) { |
| 606 can_hoist = block->IsLoopSuccessorDominator(); | 606 can_hoist = block->IsLoopSuccessorDominator(); |
| 607 } | 607 } |
| 608 | 608 |
| 609 if (can_hoist) { | 609 if (can_hoist) { |
| 610 bool inputs_loop_invariant = true; | 610 bool inputs_loop_invariant = true; |
| 611 for (int i = 0; i < instr->OperandCount(); ++i) { | 611 for (int i = 0; i < instr->OperandCount(); ++i) { |
| 612 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { | 612 if (instr->OperandAt(i)->IsDefinedAfter(pre_header)) { |
| (...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 829 | 829 |
| 830 SideEffects changes = side_effects_tracker_.ComputeChanges(instr); | 830 SideEffects changes = side_effects_tracker_.ComputeChanges(instr); |
| 831 if (!changes.IsEmpty()) { | 831 if (!changes.IsEmpty()) { |
| 832 // Clear all instructions in the map that are affected by side effects. | 832 // Clear all instructions in the map that are affected by side effects. |
| 833 // Store instruction as the dominating one for tracked side effects. | 833 // Store instruction as the dominating one for tracked side effects. |
| 834 map->Kill(changes); | 834 map->Kill(changes); |
| 835 dominators->Store(changes, instr); | 835 dominators->Store(changes, instr); |
| 836 if (FLAG_trace_gvn) { | 836 if (FLAG_trace_gvn) { |
| 837 OFStream os(stdout); | 837 OFStream os(stdout); |
| 838 os << "Instruction i" << instr->id() << " changes " << Print(changes) | 838 os << "Instruction i" << instr->id() << " changes " << Print(changes) |
| 839 << endl; | 839 << std::endl; |
| 840 } | 840 } |
| 841 } | 841 } |
| 842 if (instr->CheckFlag(HValue::kUseGVN) && | 842 if (instr->CheckFlag(HValue::kUseGVN) && |
| 843 !instr->CheckFlag(HValue::kCantBeReplaced)) { | 843 !instr->CheckFlag(HValue::kCantBeReplaced)) { |
| 844 DCHECK(!instr->HasObservableSideEffects()); | 844 DCHECK(!instr->HasObservableSideEffects()); |
| 845 HInstruction* other = map->Lookup(instr); | 845 HInstruction* other = map->Lookup(instr); |
| 846 if (other != NULL) { | 846 if (other != NULL) { |
| 847 DCHECK(instr->Equals(other) && other->Equals(instr)); | 847 DCHECK(instr->Equals(other) && other->Equals(instr)); |
| 848 TRACE_GVN_4("Replacing instruction i%d (%s) with i%d (%s)\n", | 848 TRACE_GVN_4("Replacing instruction i%d (%s) with i%d (%s)\n", |
| 849 instr->id(), | 849 instr->id(), |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 881 dominated); | 881 dominated); |
| 882 successor_map->Kill(side_effects_on_all_paths); | 882 successor_map->Kill(side_effects_on_all_paths); |
| 883 successor_dominators->Kill(side_effects_on_all_paths); | 883 successor_dominators->Kill(side_effects_on_all_paths); |
| 884 } | 884 } |
| 885 } | 885 } |
| 886 current = next; | 886 current = next; |
| 887 } | 887 } |
| 888 } | 888 } |
| 889 | 889 |
| 890 } } // namespace v8::internal | 890 } } // namespace v8::internal |
| OLD | NEW |