Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 kIsArguments, | 572 kIsArguments, |
| 573 kTruncatingToInt32, | 573 kTruncatingToInt32, |
| 574 kIsDead, | 574 kIsDead, |
| 575 // Instructions that are allowed to produce full range unsigned integer | 575 // Instructions that are allowed to produce full range unsigned integer |
| 576 // values are marked with kUint32 flag. If arithmetic shift or a load from | 576 // values are marked with kUint32 flag. If arithmetic shift or a load from |
| 577 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag | 577 // EXTERNAL_UNSIGNED_INT_ELEMENTS array is not marked with this flag |
| 578 // it will deoptimize if result does not fit into signed integer range. | 578 // it will deoptimize if result does not fit into signed integer range. |
| 579 // HGraph::ComputeSafeUint32Operations is responsible for setting this | 579 // HGraph::ComputeSafeUint32Operations is responsible for setting this |
| 580 // flag. | 580 // flag. |
| 581 kUint32, | 581 kUint32, |
| 582 kLastFlag = kUint32 | 582 // This flag is set to true after the SetupInformativeDefinitions() pass |
| 583 // has processed this instruction. | |
| 584 kIDefsProcessingDone, | |
| 585 kLastFlag = kIDefsProcessingDone | |
| 583 }; | 586 }; |
| 584 | 587 |
| 585 STATIC_ASSERT(kLastFlag < kBitsPerInt); | 588 STATIC_ASSERT(kLastFlag < kBitsPerInt); |
| 586 | 589 |
| 587 static const int kChangesToDependsFlagsLeftShift = 1; | 590 static const int kChangesToDependsFlagsLeftShift = 1; |
| 588 | 591 |
| 589 static GVNFlag ChangesFlagFromInt(int x) { | 592 static GVNFlag ChangesFlagFromInt(int x) { |
| 590 return static_cast<GVNFlag>(x * 2); | 593 return static_cast<GVNFlag>(x * 2); |
| 591 } | 594 } |
| 592 static GVNFlag DependsOnFlagFromInt(int x) { | 595 static GVNFlag DependsOnFlagFromInt(int x) { |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 680 // One of the iDef operands is special because it is the value that is | 683 // One of the iDef operands is special because it is the value that is |
| 681 // "transferred" to the output, we call it the "redefined operand". | 684 // "transferred" to the output, we call it the "redefined operand". |
| 682 // If an HValue is an iDef it must override RedefinedOperandIndex() so that | 685 // If an HValue is an iDef it must override RedefinedOperandIndex() so that |
| 683 // it does not return kNoRedefinedOperand; | 686 // it does not return kNoRedefinedOperand; |
| 684 static const int kNoRedefinedOperand = -1; | 687 static const int kNoRedefinedOperand = -1; |
| 685 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } | 688 virtual int RedefinedOperandIndex() { return kNoRedefinedOperand; } |
| 686 bool IsInformativeDefinition() { | 689 bool IsInformativeDefinition() { |
| 687 return RedefinedOperandIndex() != kNoRedefinedOperand; | 690 return RedefinedOperandIndex() != kNoRedefinedOperand; |
| 688 } | 691 } |
| 689 HValue* RedefinedOperand() { | 692 HValue* RedefinedOperand() { |
| 690 ASSERT(IsInformativeDefinition()); | 693 return IsInformativeDefinition() ? OperandAt(RedefinedOperandIndex()) |
| 691 return OperandAt(RedefinedOperandIndex()); | 694 : NULL; |
| 692 } | 695 } |
| 693 | 696 |
| 694 // This method must always return the original HValue SSA definition | 697 // This method must always return the original HValue SSA definition |
| 695 // (regardless of any iDef of this value). | 698 // (regardless of any iDef of this value). |
| 696 HValue* ActualValue() { | 699 HValue* ActualValue() { |
| 697 return IsInformativeDefinition() ? RedefinedOperand()->ActualValue() | 700 return IsInformativeDefinition() ? RedefinedOperand()->ActualValue() |
| 698 : this; | 701 : this; |
| 699 } | 702 } |
| 700 | 703 |
| 704 virtual void AddInformativeDefinitions() {} | |
| 705 | |
| 706 void UpdateRedefinedUsesWhileSettingUpInformativeDefinitions() { | |
| 707 UpdateRedefinedUsesInner<TestDominanceUsingProcessedFlag>(); | |
| 708 } | |
| 709 void UpdateRedefinedUses() { | |
| 710 UpdateRedefinedUsesInner<Dominates>(); | |
| 711 } | |
| 712 | |
| 701 bool IsDefinedAfter(HBasicBlock* other) const; | 713 bool IsDefinedAfter(HBasicBlock* other) const; |
| 702 | 714 |
| 703 // Operands. | 715 // Operands. |
| 704 virtual int OperandCount() = 0; | 716 virtual int OperandCount() = 0; |
| 705 virtual HValue* OperandAt(int index) const = 0; | 717 virtual HValue* OperandAt(int index) const = 0; |
| 706 void SetOperandAt(int index, HValue* value); | 718 void SetOperandAt(int index, HValue* value); |
| 707 | 719 |
| 708 void DeleteAndReplaceWith(HValue* other); | 720 void DeleteAndReplaceWith(HValue* other); |
| 709 void ReplaceAllUsesWith(HValue* other); | 721 void ReplaceAllUsesWith(HValue* other); |
| 710 bool HasNoUses() const { return use_list_ == NULL; } | 722 bool HasNoUses() const { return use_list_ == NULL; } |
| (...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 849 void clear_block() { | 861 void clear_block() { |
| 850 ASSERT(block_ != NULL); | 862 ASSERT(block_ != NULL); |
| 851 block_ = NULL; | 863 block_ = NULL; |
| 852 } | 864 } |
| 853 | 865 |
| 854 void set_representation(Representation r) { | 866 void set_representation(Representation r) { |
| 855 ASSERT(representation_.IsNone() && !r.IsNone()); | 867 ASSERT(representation_.IsNone() && !r.IsNone()); |
| 856 representation_ = r; | 868 representation_ = r; |
| 857 } | 869 } |
| 858 | 870 |
| 871 // Signature of a function testing if a HValue properly dominates another. | |
| 872 typedef bool (*DominanceTest)(HValue*, HValue*); | |
| 873 | |
| 874 // Simple implementation of DominanceTest implemented walking the chain | |
| 875 // of Hinstructions (used in UpdateRedefinedUsesInner). | |
| 876 static bool Dominates(HValue* dominator, HValue* dominated); | |
| 877 | |
| 878 // A fast implementation of DominanceTest that works only for the | |
| 879 // "current" instruction in the SetupInformativeDefinitions() phase. | |
| 880 // During that phase we use a flag to mark processed instructions, and by | |
| 881 // checking the flag we can quickly test if an instruction comes before or | |
| 882 // after the "current" one. | |
| 883 static bool TestDominanceUsingProcessedFlag(HValue* dominator, | |
| 884 HValue* dominated); | |
| 885 | |
| 886 // If we are redefining an operand, update all its dominated uses (the | |
| 887 // function that checks if a use is dominated is the template argument). | |
| 888 template<DominanceTest CheckDominance> | |
|
Jakob Kummerow
2013/02/01 10:08:40
s/Check/Test/ here too, please
| |
| 889 void UpdateRedefinedUsesInner() { | |
| 890 HValue* input = RedefinedOperand(); | |
| 891 if (input != NULL) { | |
| 892 for (HUseIterator uses = input->uses(); !uses.Done(); uses.Advance()) { | |
| 893 HValue* use = uses.value(); | |
| 894 if (CheckDominance(this, use)) { | |
| 895 use->SetOperandAt(uses.index(), this); | |
| 896 } | |
| 897 } | |
| 898 } | |
| 899 } | |
| 900 | |
| 859 static GVNFlagSet AllDependsOnFlagSet() { | 901 static GVNFlagSet AllDependsOnFlagSet() { |
| 860 GVNFlagSet result; | 902 GVNFlagSet result; |
| 861 // Create changes mask. | 903 // Create changes mask. |
| 862 #define ADD_FLAG(type) result.Add(kDependsOn##type); | 904 #define ADD_FLAG(type) result.Add(kDependsOn##type); |
| 863 GVN_TRACKED_FLAG_LIST(ADD_FLAG) | 905 GVN_TRACKED_FLAG_LIST(ADD_FLAG) |
| 864 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) | 906 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) |
| 865 #undef ADD_FLAG | 907 #undef ADD_FLAG |
| 866 return result; | 908 return result; |
| 867 } | 909 } |
| 868 | 910 |
| (...skipping 4698 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5567 virtual bool IsDeletable() const { return true; } | 5609 virtual bool IsDeletable() const { return true; } |
| 5568 }; | 5610 }; |
| 5569 | 5611 |
| 5570 | 5612 |
| 5571 #undef DECLARE_INSTRUCTION | 5613 #undef DECLARE_INSTRUCTION |
| 5572 #undef DECLARE_CONCRETE_INSTRUCTION | 5614 #undef DECLARE_CONCRETE_INSTRUCTION |
| 5573 | 5615 |
| 5574 } } // namespace v8::internal | 5616 } } // namespace v8::internal |
| 5575 | 5617 |
| 5576 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5618 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
| OLD | NEW |