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<CheckDominanceUsingProcessedFlag>(); | |
708 } | |
709 void UpdateRedefinedUses() { | |
710 UpdateRedefinedUsesInner<CheckDominanceFollowingDefinitionList>(); | |
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 // Check if "dominator" properly dominates "dominated" | |
872 // (used in UpdateRedefinedUsesInner). | |
873 static bool CheckDominanceFollowingDefinitionList( | |
Jakob Kummerow
2013/01/31 14:06:43
I'm not too happy with this method's name. "Check"
Massi
2013/01/31 17:16:19
Renamed the methods but, after the offline chat, k
| |
874 HValue* dominator, HValue* dominated); | |
Jakob Kummerow
2013/01/31 14:06:43
nit: for method/function declarations (contrary to
Massi
2013/01/31 17:16:19
Done.
| |
875 | |
876 // When we are setting up informaative definitions we use a flag to mark | |
Jakob Kummerow
2013/01/31 14:06:43
nit: s/informaative/informative/
Massi
2013/01/31 17:16:19
Done.
| |
877 // processed instructions, and by checking the flag we know if an | |
878 // instruction comes before or after the "current" one. | |
879 static bool CheckDominanceUsingProcessedFlag( | |
880 HValue* dominator, HValue* dominated); | |
Jakob Kummerow
2013/01/31 14:06:43
same here
Massi
2013/01/31 17:16:19
Done.
| |
881 | |
882 // If we are redefining an operand, update all its dominated uses (the | |
883 // function that checks if a use is dominated is the template argument). | |
884 template<bool (*CheckDominance)(HValue*, HValue*)> | |
Jakob Kummerow
2013/01/31 14:06:43
Please use a typedef for the function signature de
Massi
2013/01/31 17:16:19
Done.
| |
885 void UpdateRedefinedUsesInner() { | |
886 HValue* input = RedefinedOperand(); | |
887 if (input != NULL) { | |
888 HUseIterator uses = input->uses(); | |
889 while (!uses.Done()) { | |
Jakob Kummerow
2013/01/31 14:06:43
I'm used to seeing for-loops for iterating over us
Massi
2013/01/31 17:16:19
Done.
| |
890 HValue* use = uses.value(); | |
891 int index = uses.index(); | |
892 uses.Advance(); | |
893 // We need to update all dominated uses. | |
894 if (CheckDominance(this, use)) { | |
895 use->SetOperandAt(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 |