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 |