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

Side by Side Diff: src/hydrogen-instructions.h

Issue 11783055: Make the array bounds check elimination phase optional (and set the foundation for introducing SSI … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed review comments. Created 7 years, 11 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
OLDNEW
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 330 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 bool IsNone() const { return kind_ == kNone; } 341 bool IsNone() const { return kind_ == kNone; }
342 bool IsTagged() const { return kind_ == kTagged; } 342 bool IsTagged() const { return kind_ == kTagged; }
343 bool IsInteger32() const { return kind_ == kInteger32; } 343 bool IsInteger32() const { return kind_ == kInteger32; }
344 bool IsDouble() const { return kind_ == kDouble; } 344 bool IsDouble() const { return kind_ == kDouble; }
345 bool IsExternal() const { return kind_ == kExternal; } 345 bool IsExternal() const { return kind_ == kExternal; }
346 bool IsSpecialization() const { 346 bool IsSpecialization() const {
347 return kind_ == kInteger32 || kind_ == kDouble; 347 return kind_ == kInteger32 || kind_ == kDouble;
348 } 348 }
349 const char* Mnemonic() const; 349 const char* Mnemonic() const;
350 350
351 Representation KeyedAccessIndexRequirement() {
Jakob Kummerow 2013/01/10 16:06:47 nit: I'm a bit unhappy about adding instruction-sp
352 return IsInteger32() ? Integer32() : Tagged();
353 }
354
351 private: 355 private:
352 explicit Representation(Kind k) : kind_(k) { } 356 explicit Representation(Kind k) : kind_(k) { }
353 357
354 // Make sure kind fits in int8. 358 // Make sure kind fits in int8.
355 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); 359 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
356 360
357 int8_t kind_; 361 int8_t kind_;
358 }; 362 };
359 363
360 364
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
665 // If the operation also exists in a form that takes int32 and outputs int32 669 // If the operation also exists in a form that takes int32 and outputs int32
666 // then the operation should return its input value so that we can propagate 670 // then the operation should return its input value so that we can propagate
667 // back. There are three operations that need to propagate back to more than 671 // back. There are three operations that need to propagate back to more than
668 // one input. They are phi and binary div and mul. They always return NULL 672 // one input. They are phi and binary div and mul. They always return NULL
669 // and expect the caller to take care of things. 673 // and expect the caller to take care of things.
670 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) { 674 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited) {
671 visited->Add(id()); 675 visited->Add(id());
672 return NULL; 676 return NULL;
673 } 677 }
674 678
679 // There are HInstructions that do not really change a value, they
680 // only add pieces of information to it (like bounds checks, map checks
681 // or SSI definitions after conditional branches).
682 // This method must always return the original HValue SSA definition (the
683 // register allocator relies on this to avoid allocating multiple registers
684 // for the same value).
685 virtual HValue* ActualValue() { return this; }
686
675 bool IsDefinedAfter(HBasicBlock* other) const; 687 bool IsDefinedAfter(HBasicBlock* other) const;
676 688
677 // Operands. 689 // Operands.
678 virtual int OperandCount() = 0; 690 virtual int OperandCount() = 0;
679 virtual HValue* OperandAt(int index) const = 0; 691 virtual HValue* OperandAt(int index) const = 0;
680 void SetOperandAt(int index, HValue* value); 692 void SetOperandAt(int index, HValue* value);
681 693
682 void DeleteAndReplaceWith(HValue* other); 694 void DeleteAndReplaceWith(HValue* other);
683 void ReplaceAllUsesWith(HValue* other); 695 void ReplaceAllUsesWith(HValue* other);
684 bool HasNoUses() const { return use_list_ == NULL; } 696 bool HasNoUses() const { return use_list_ == NULL; }
(...skipping 2263 matching lines...) Expand 10 before | Expand all | Expand 10 after
2948 2960
2949 enum BoundsCheckKeyMode { 2961 enum BoundsCheckKeyMode {
2950 DONT_ALLOW_SMI_KEY, 2962 DONT_ALLOW_SMI_KEY,
2951 ALLOW_SMI_KEY 2963 ALLOW_SMI_KEY
2952 }; 2964 };
2953 2965
2954 2966
2955 class HBoundsCheck: public HTemplateInstruction<2> { 2967 class HBoundsCheck: public HTemplateInstruction<2> {
2956 public: 2968 public:
2957 HBoundsCheck(HValue* index, HValue* length, 2969 HBoundsCheck(HValue* index, HValue* length,
2958 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY) 2970 BoundsCheckKeyMode key_mode = DONT_ALLOW_SMI_KEY,
2971 Representation r = Representation::None())
2959 : key_mode_(key_mode) { 2972 : key_mode_(key_mode) {
2960 SetOperandAt(0, index); 2973 SetOperandAt(0, index);
2961 SetOperandAt(1, length); 2974 SetOperandAt(1, length);
2962 set_representation(Representation::Integer32()); 2975 if (r.IsNone()) {
2976 // In the normal compilation pipeline the representation is flexible
2977 // (see comment to RequiredInputRepresentation).
2978 SetFlag(kFlexibleRepresentation);
2979 } else {
2980 // When compiling stubs we want to set the representation explicitly
2981 // so the compilation pipeline can skip the HInferRepresentation phase.
2982 set_representation(r);
2983 }
2963 SetFlag(kUseGVN); 2984 SetFlag(kUseGVN);
2964 } 2985 }
2965 2986
2966 virtual Representation RequiredInputRepresentation(int arg_index) { 2987 virtual Representation RequiredInputRepresentation(int arg_index) {
2967 if (key_mode_ == DONT_ALLOW_SMI_KEY || 2988 return representation();
2968 !length()->representation().IsTagged()) {
2969 return Representation::Integer32();
2970 }
2971 // If the index is tagged and isn't constant, then allow the length
2972 // to be tagged, since it is usually already tagged from loading it out of
2973 // the length field of a JSArray. This allows for direct comparison without
2974 // untagging.
2975 if (index()->representation().IsTagged() && !index()->IsConstant()) {
2976 return Representation::Tagged();
2977 }
2978 // Also allow the length to be tagged if the index is constant, because
2979 // it can be tagged to allow direct comparison.
2980 if (index()->IsConstant() &&
2981 index()->representation().IsInteger32() &&
2982 arg_index == 1) {
2983 return Representation::Tagged();
2984 }
2985 return Representation::Integer32();
2986 } 2989 }
2987 virtual Representation observed_input_representation(int index) { 2990 virtual Representation observed_input_representation(int index) {
2988 return Representation::Integer32(); 2991 return Representation::Integer32();
2989 } 2992 }
2990 2993
2991 virtual void PrintDataTo(StringStream* stream); 2994 virtual void PrintDataTo(StringStream* stream);
2995 virtual void InferRepresentation(HInferRepresentation* h_infer);
2992 2996
2993 HValue* index() { return OperandAt(0); } 2997 HValue* index() { return OperandAt(0); }
2994 HValue* length() { return OperandAt(1); } 2998 HValue* length() { return OperandAt(1); }
2995 2999
3000 virtual HValue* ActualValue() {
3001 return index();
3002 }
3003
2996 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) 3004 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck)
2997 3005
2998 protected: 3006 protected:
2999 virtual bool DataEquals(HValue* other) { return true; } 3007 virtual bool DataEquals(HValue* other) { return true; }
3000 BoundsCheckKeyMode key_mode_; 3008 BoundsCheckKeyMode key_mode_;
3001 }; 3009 };
3002 3010
3003 3011
3004 class HBitwiseBinaryOperation: public HBinaryOperation { 3012 class HBitwiseBinaryOperation: public HBinaryOperation {
3005 public: 3013 public:
(...skipping 1433 matching lines...) Expand 10 before | Expand all | Expand 10 after
4439 } 4447 }
4440 4448
4441 virtual Representation RequiredInputRepresentation(int index) { 4449 virtual Representation RequiredInputRepresentation(int index) {
4442 // kind_fast: tagged[int32] (none) 4450 // kind_fast: tagged[int32] (none)
4443 // kind_double: tagged[int32] (none) 4451 // kind_double: tagged[int32] (none)
4444 // kind_external: external[int32] (none) 4452 // kind_external: external[int32] (none)
4445 if (index == 0) { 4453 if (index == 0) {
4446 return is_external() ? Representation::External() 4454 return is_external() ? Representation::External()
4447 : Representation::Tagged(); 4455 : Representation::Tagged();
4448 } 4456 }
4449 if (index == 1) return Representation::Integer32(); 4457 if (index == 1) {
4458 return OperandAt(1)->representation().KeyedAccessIndexRequirement();
4459 }
4450 return Representation::None(); 4460 return Representation::None();
4451 } 4461 }
4452 4462
4453 virtual Representation observed_input_representation(int index) { 4463 virtual Representation observed_input_representation(int index) {
4454 return RequiredInputRepresentation(index); 4464 return RequiredInputRepresentation(index);
4455 } 4465 }
4456 4466
4457 virtual void PrintDataTo(StringStream* stream); 4467 virtual void PrintDataTo(StringStream* stream);
4458 4468
4459 bool RequiresHoleCheck() const; 4469 bool RequiresHoleCheck() const;
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after
4654 } 4664 }
4655 4665
4656 virtual Representation RequiredInputRepresentation(int index) { 4666 virtual Representation RequiredInputRepresentation(int index) {
4657 // kind_fast: tagged[int32] = tagged 4667 // kind_fast: tagged[int32] = tagged
4658 // kind_double: tagged[int32] = double 4668 // kind_double: tagged[int32] = double
4659 // kind_external: external[int32] = (double | int32) 4669 // kind_external: external[int32] = (double | int32)
4660 if (index == 0) { 4670 if (index == 0) {
4661 return is_external() ? Representation::External() 4671 return is_external() ? Representation::External()
4662 : Representation::Tagged(); 4672 : Representation::Tagged();
4663 } else if (index == 1) { 4673 } else if (index == 1) {
4664 return Representation::Integer32(); 4674 return OperandAt(1)->representation().KeyedAccessIndexRequirement();
4665 } 4675 }
4666 4676
4667 ASSERT_EQ(index, 2); 4677 ASSERT_EQ(index, 2);
4668 if (IsDoubleOrFloatElementsKind(elements_kind())) { 4678 if (IsDoubleOrFloatElementsKind(elements_kind())) {
4669 return Representation::Double(); 4679 return Representation::Double();
4670 } 4680 }
4671 4681
4672 return is_external() ? Representation::Integer32() 4682 return is_external() ? Representation::Integer32()
4673 : Representation::Tagged(); 4683 : Representation::Tagged();
4674 } 4684 }
(...skipping 771 matching lines...) Expand 10 before | Expand all | Expand 10 after
5446 virtual bool IsDeletable() const { return true; } 5456 virtual bool IsDeletable() const { return true; }
5447 }; 5457 };
5448 5458
5449 5459
5450 #undef DECLARE_INSTRUCTION 5460 #undef DECLARE_INSTRUCTION
5451 #undef DECLARE_CONCRETE_INSTRUCTION 5461 #undef DECLARE_CONCRETE_INSTRUCTION
5452 5462
5453 } } // namespace v8::internal 5463 } } // namespace v8::internal
5454 5464
5455 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 5465 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698