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 27 matching lines...) Expand all Loading... | |
38 #include "v8conversions.h" | 38 #include "v8conversions.h" |
39 #include "v8utils.h" | 39 #include "v8utils.h" |
40 #include "zone.h" | 40 #include "zone.h" |
41 | 41 |
42 namespace v8 { | 42 namespace v8 { |
43 namespace internal { | 43 namespace internal { |
44 | 44 |
45 // Forward declarations. | 45 // Forward declarations. |
46 class HBasicBlock; | 46 class HBasicBlock; |
47 class HEnvironment; | 47 class HEnvironment; |
48 class HInferRepresentation; | |
48 class HInstruction; | 49 class HInstruction; |
49 class HLoopInformation; | 50 class HLoopInformation; |
50 class HValue; | 51 class HValue; |
51 class LInstruction; | 52 class LInstruction; |
52 class LChunkBuilder; | 53 class LChunkBuilder; |
53 | 54 |
54 | 55 |
55 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \ | 56 #define HYDROGEN_ABSTRACT_INSTRUCTION_LIST(V) \ |
56 V(BinaryOperation) \ | 57 V(BinaryOperation) \ |
57 V(BitwiseBinaryOperation) \ | 58 V(BitwiseBinaryOperation) \ |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 int32_t upper_; | 301 int32_t upper_; |
301 Range* next_; | 302 Range* next_; |
302 bool can_be_minus_zero_; | 303 bool can_be_minus_zero_; |
303 }; | 304 }; |
304 | 305 |
305 | 306 |
306 class Representation { | 307 class Representation { |
307 public: | 308 public: |
308 enum Kind { | 309 enum Kind { |
309 kNone, | 310 kNone, |
311 kInteger32, | |
312 kDouble, | |
310 kTagged, | 313 kTagged, |
311 kDouble, | |
312 kInteger32, | |
313 kExternal, | 314 kExternal, |
314 kNumRepresentations | 315 kNumRepresentations |
315 }; | 316 }; |
316 | 317 |
317 Representation() : kind_(kNone) { } | 318 Representation() : kind_(kNone) { } |
318 | 319 |
319 static Representation None() { return Representation(kNone); } | 320 static Representation None() { return Representation(kNone); } |
320 static Representation Tagged() { return Representation(kTagged); } | 321 static Representation Tagged() { return Representation(kTagged); } |
321 static Representation Integer32() { return Representation(kInteger32); } | 322 static Representation Integer32() { return Representation(kInteger32); } |
322 static Representation Double() { return Representation(kDouble); } | 323 static Representation Double() { return Representation(kDouble); } |
323 static Representation External() { return Representation(kExternal); } | 324 static Representation External() { return Representation(kExternal); } |
324 | 325 |
325 bool Equals(const Representation& other) { | 326 bool Equals(const Representation& other) { |
326 return kind_ == other.kind_; | 327 return kind_ == other.kind_; |
327 } | 328 } |
328 | 329 |
330 bool is_more_general_than(const Representation& other) { | |
331 ASSERT(kind_ != kExternal); | |
332 ASSERT(other.kind_ != kExternal); | |
333 return kind_ > other.kind_; | |
334 } | |
335 | |
329 Kind kind() const { return static_cast<Kind>(kind_); } | 336 Kind kind() const { return static_cast<Kind>(kind_); } |
330 bool IsNone() const { return kind_ == kNone; } | 337 bool IsNone() const { return kind_ == kNone; } |
331 bool IsTagged() const { return kind_ == kTagged; } | 338 bool IsTagged() const { return kind_ == kTagged; } |
332 bool IsInteger32() const { return kind_ == kInteger32; } | 339 bool IsInteger32() const { return kind_ == kInteger32; } |
333 bool IsDouble() const { return kind_ == kDouble; } | 340 bool IsDouble() const { return kind_ == kDouble; } |
334 bool IsExternal() const { return kind_ == kExternal; } | 341 bool IsExternal() const { return kind_ == kExternal; } |
335 bool IsSpecialization() const { | 342 bool IsSpecialization() const { |
336 return kind_ == kInteger32 || kind_ == kDouble; | 343 return kind_ == kInteger32 || kind_ == kDouble; |
337 } | 344 } |
338 const char* Mnemonic() const; | 345 const char* Mnemonic() const; |
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
621 int LoopWeight() const; | 628 int LoopWeight() const; |
622 | 629 |
623 int id() const { return id_; } | 630 int id() const { return id_; } |
624 void set_id(int id) { id_ = id; } | 631 void set_id(int id) { id_ = id; } |
625 | 632 |
626 HUseIterator uses() const { return HUseIterator(use_list_); } | 633 HUseIterator uses() const { return HUseIterator(use_list_); } |
627 | 634 |
628 virtual bool EmitAtUses() { return false; } | 635 virtual bool EmitAtUses() { return false; } |
629 Representation representation() const { return representation_; } | 636 Representation representation() const { return representation_; } |
630 void ChangeRepresentation(Representation r) { | 637 void ChangeRepresentation(Representation r) { |
631 // Representation was already set and is allowed to be changed. | |
632 ASSERT(!r.IsNone()); | |
633 ASSERT(CheckFlag(kFlexibleRepresentation)); | 638 ASSERT(CheckFlag(kFlexibleRepresentation)); |
634 RepresentationChanged(r); | 639 RepresentationChanged(r); |
635 representation_ = r; | 640 representation_ = r; |
641 if (r.IsTagged()) { | |
642 // Tagged is the bottom of the lattice, don't go any further. | |
643 ClearFlag(kFlexibleRepresentation); | |
644 } | |
636 } | 645 } |
637 void AssumeRepresentation(Representation r); | 646 virtual void AssumeRepresentation(Representation r); |
638 | 647 |
639 virtual bool IsConvertibleToInteger() const { return true; } | 648 virtual bool IsConvertibleToInteger() const { return true; } |
640 | 649 |
641 HType type() const { return type_; } | 650 HType type() const { return type_; } |
642 void set_type(HType new_type) { | 651 void set_type(HType new_type) { |
643 ASSERT(new_type.IsSubtypeOf(type_)); | 652 ASSERT(new_type.IsSubtypeOf(type_)); |
644 type_ = new_type; | 653 type_ = new_type; |
645 } | 654 } |
646 | 655 |
647 // An operation needs to override this function iff: | 656 // An operation needs to override this function iff: |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
725 return result; | 734 return result; |
726 } | 735 } |
727 | 736 |
728 Range* range() const { return range_; } | 737 Range* range() const { return range_; } |
729 bool HasRange() const { return range_ != NULL; } | 738 bool HasRange() const { return range_ != NULL; } |
730 void AddNewRange(Range* r, Zone* zone); | 739 void AddNewRange(Range* r, Zone* zone); |
731 void RemoveLastAddedRange(); | 740 void RemoveLastAddedRange(); |
732 void ComputeInitialRange(Zone* zone); | 741 void ComputeInitialRange(Zone* zone); |
733 | 742 |
734 // Representation helpers. | 743 // Representation helpers. |
744 virtual Representation observed_input_representation(int index) { | |
745 return Representation::None(); | |
746 } | |
735 virtual Representation RequiredInputRepresentation(int index) = 0; | 747 virtual Representation RequiredInputRepresentation(int index) = 0; |
736 | 748 virtual void InferRepresentation(HInferRepresentation* h_infer); |
737 virtual Representation InferredRepresentation() { | |
738 return representation(); | |
739 } | |
740 | |
741 // Type feedback access. | |
742 virtual Representation ObservedInputRepresentation(int index) { | |
743 return RequiredInputRepresentation(index); | |
744 } | |
745 | 749 |
746 // This gives the instruction an opportunity to replace itself with an | 750 // This gives the instruction an opportunity to replace itself with an |
747 // instruction that does the same in some better way. To replace an | 751 // instruction that does the same in some better way. To replace an |
748 // instruction with a new one, first add the new instruction to the graph, | 752 // instruction with a new one, first add the new instruction to the graph, |
749 // then return it. Return NULL to have the instruction deleted. | 753 // then return it. Return NULL to have the instruction deleted. |
750 virtual HValue* Canonicalize() { return this; } | 754 virtual HValue* Canonicalize() { return this; } |
751 | 755 |
752 bool Equals(HValue* other); | 756 bool Equals(HValue* other); |
753 virtual intptr_t Hashcode(); | 757 virtual intptr_t Hashcode(); |
754 | 758 |
(...skipping 27 matching lines...) Expand all Loading... | |
782 virtual void Verify() = 0; | 786 virtual void Verify() = 0; |
783 #endif | 787 #endif |
784 | 788 |
785 protected: | 789 protected: |
786 // This function must be overridden for instructions with flag kUseGVN, to | 790 // This function must be overridden for instructions with flag kUseGVN, to |
787 // compare the non-Operand parts of the instruction. | 791 // compare the non-Operand parts of the instruction. |
788 virtual bool DataEquals(HValue* other) { | 792 virtual bool DataEquals(HValue* other) { |
789 UNREACHABLE(); | 793 UNREACHABLE(); |
790 return false; | 794 return false; |
791 } | 795 } |
796 | |
797 virtual Representation RepresentationFromInputs() { | |
798 return representation(); | |
799 } | |
800 Representation RepresentationFromUses(); | |
801 virtual void UpdateRepresentation(Representation new_rep, | |
802 HInferRepresentation* h_infer, | |
803 const char* reason); | |
804 void AddDependantsToWorklist(HInferRepresentation* h_infer); | |
805 | |
792 virtual void RepresentationChanged(Representation to) { } | 806 virtual void RepresentationChanged(Representation to) { } |
807 | |
793 virtual Range* InferRange(Zone* zone); | 808 virtual Range* InferRange(Zone* zone); |
794 virtual void DeleteFromGraph() = 0; | 809 virtual void DeleteFromGraph() = 0; |
795 virtual void InternalSetOperandAt(int index, HValue* value) = 0; | 810 virtual void InternalSetOperandAt(int index, HValue* value) = 0; |
796 void clear_block() { | 811 void clear_block() { |
797 ASSERT(block_ != NULL); | 812 ASSERT(block_ != NULL); |
798 block_ = NULL; | 813 block_ = NULL; |
799 } | 814 } |
800 | 815 |
801 void set_representation(Representation r) { | 816 void set_representation(Representation r) { |
802 // Representation is set-once. | |
803 ASSERT(representation_.IsNone() && !r.IsNone()); | 817 ASSERT(representation_.IsNone() && !r.IsNone()); |
804 representation_ = r; | 818 representation_ = r; |
805 } | 819 } |
806 | 820 |
807 static GVNFlagSet AllDependsOnFlagSet() { | 821 static GVNFlagSet AllDependsOnFlagSet() { |
808 GVNFlagSet result; | 822 GVNFlagSet result; |
809 // Create changes mask. | 823 // Create changes mask. |
810 #define ADD_FLAG(type) result.Add(kDependsOn##type); | 824 #define ADD_FLAG(type) result.Add(kDependsOn##type); |
811 GVN_TRACKED_FLAG_LIST(ADD_FLAG) | 825 GVN_TRACKED_FLAG_LIST(ADD_FLAG) |
812 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) | 826 GVN_UNTRACKED_FLAG_LIST(ADD_FLAG) |
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1105 expected_input_types_(expected_input_types) { | 1119 expected_input_types_(expected_input_types) { |
1106 ASSERT(true_target != NULL && false_target != NULL); | 1120 ASSERT(true_target != NULL && false_target != NULL); |
1107 } | 1121 } |
1108 explicit HBranch(HValue* value) | 1122 explicit HBranch(HValue* value) |
1109 : HUnaryControlInstruction(value, NULL, NULL) { } | 1123 : HUnaryControlInstruction(value, NULL, NULL) { } |
1110 | 1124 |
1111 | 1125 |
1112 virtual Representation RequiredInputRepresentation(int index) { | 1126 virtual Representation RequiredInputRepresentation(int index) { |
1113 return Representation::None(); | 1127 return Representation::None(); |
1114 } | 1128 } |
1129 virtual Representation observed_input_representation(int index); | |
1115 | 1130 |
1116 ToBooleanStub::Types expected_input_types() const { | 1131 ToBooleanStub::Types expected_input_types() const { |
1117 return expected_input_types_; | 1132 return expected_input_types_; |
1118 } | 1133 } |
1119 | 1134 |
1120 DECLARE_CONCRETE_INSTRUCTION(Branch) | 1135 DECLARE_CONCRETE_INSTRUCTION(Branch) |
1121 | 1136 |
1122 private: | 1137 private: |
1123 ToBooleanStub::Types expected_input_types_; | 1138 ToBooleanStub::Types expected_input_types_; |
1124 }; | 1139 }; |
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1309 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) | 1324 DECLARE_CONCRETE_INSTRUCTION(ClampToUint8) |
1310 | 1325 |
1311 protected: | 1326 protected: |
1312 virtual bool DataEquals(HValue* other) { return true; } | 1327 virtual bool DataEquals(HValue* other) { return true; } |
1313 | 1328 |
1314 private: | 1329 private: |
1315 virtual bool IsDeletable() const { return true; } | 1330 virtual bool IsDeletable() const { return true; } |
1316 }; | 1331 }; |
1317 | 1332 |
1318 | 1333 |
1334 enum RemovableSimulate { | |
1335 REMOVABLE, | |
danno
2012/11/14 10:38:22
make this REMOVABLE_SIMULATE?
Jakob Kummerow
2012/11/14 15:53:23
Done.
| |
1336 FIXED | |
1337 }; | |
1338 | |
1339 | |
1319 class HSimulate: public HInstruction { | 1340 class HSimulate: public HInstruction { |
1320 public: | 1341 public: |
1321 HSimulate(BailoutId ast_id, int pop_count, Zone* zone) | 1342 HSimulate(BailoutId ast_id, |
1343 int pop_count, | |
1344 Zone* zone, | |
1345 RemovableSimulate removable) | |
1322 : ast_id_(ast_id), | 1346 : ast_id_(ast_id), |
1323 pop_count_(pop_count), | 1347 pop_count_(pop_count), |
1324 values_(2, zone), | 1348 values_(2, zone), |
1325 assigned_indexes_(2, zone), | 1349 assigned_indexes_(2, zone), |
1326 zone_(zone) {} | 1350 zone_(zone), |
1351 removable_(removable) {} | |
1327 virtual ~HSimulate() {} | 1352 virtual ~HSimulate() {} |
1328 | 1353 |
1329 virtual void PrintDataTo(StringStream* stream); | 1354 virtual void PrintDataTo(StringStream* stream); |
1330 | 1355 |
1331 bool HasAstId() const { return !ast_id_.IsNone(); } | 1356 bool HasAstId() const { return !ast_id_.IsNone(); } |
1332 BailoutId ast_id() const { return ast_id_; } | 1357 BailoutId ast_id() const { return ast_id_; } |
1333 void set_ast_id(BailoutId id) { | 1358 void set_ast_id(BailoutId id) { |
1334 ASSERT(!HasAstId()); | 1359 ASSERT(!HasAstId()); |
1335 ast_id_ = id; | 1360 ast_id_ = id; |
1336 } | 1361 } |
(...skipping 13 matching lines...) Expand all Loading... | |
1350 void AddPushedValue(HValue* value) { | 1375 void AddPushedValue(HValue* value) { |
1351 AddValue(kNoIndex, value); | 1376 AddValue(kNoIndex, value); |
1352 } | 1377 } |
1353 virtual int OperandCount() { return values_.length(); } | 1378 virtual int OperandCount() { return values_.length(); } |
1354 virtual HValue* OperandAt(int index) const { return values_[index]; } | 1379 virtual HValue* OperandAt(int index) const { return values_[index]; } |
1355 | 1380 |
1356 virtual Representation RequiredInputRepresentation(int index) { | 1381 virtual Representation RequiredInputRepresentation(int index) { |
1357 return Representation::None(); | 1382 return Representation::None(); |
1358 } | 1383 } |
1359 | 1384 |
1385 void MergeInto(HSimulate* other); | |
1386 bool is_candidate_for_removal() { return removable_ == REMOVABLE; } | |
1387 | |
1360 DECLARE_CONCRETE_INSTRUCTION(Simulate) | 1388 DECLARE_CONCRETE_INSTRUCTION(Simulate) |
1361 | 1389 |
1362 #ifdef DEBUG | 1390 #ifdef DEBUG |
1363 virtual void Verify(); | 1391 virtual void Verify(); |
1364 #endif | 1392 #endif |
1365 | 1393 |
1366 protected: | 1394 protected: |
1367 virtual void InternalSetOperandAt(int index, HValue* value) { | 1395 virtual void InternalSetOperandAt(int index, HValue* value) { |
1368 values_[index] = value; | 1396 values_[index] = value; |
1369 } | 1397 } |
1370 | 1398 |
1371 private: | 1399 private: |
1372 static const int kNoIndex = -1; | 1400 static const int kNoIndex = -1; |
1373 void AddValue(int index, HValue* value) { | 1401 void AddValue(int index, HValue* value) { |
1374 assigned_indexes_.Add(index, zone_); | 1402 assigned_indexes_.Add(index, zone_); |
1375 // Resize the list of pushed values. | 1403 // Resize the list of pushed values. |
1376 values_.Add(NULL, zone_); | 1404 values_.Add(NULL, zone_); |
1377 // Set the operand through the base method in HValue to make sure that the | 1405 // Set the operand through the base method in HValue to make sure that the |
1378 // use lists are correctly updated. | 1406 // use lists are correctly updated. |
1379 SetOperandAt(values_.length() - 1, value); | 1407 SetOperandAt(values_.length() - 1, value); |
1380 } | 1408 } |
1381 BailoutId ast_id_; | 1409 BailoutId ast_id_; |
1382 int pop_count_; | 1410 int pop_count_; |
1383 ZoneList<HValue*> values_; | 1411 ZoneList<HValue*> values_; |
1384 ZoneList<int> assigned_indexes_; | 1412 ZoneList<int> assigned_indexes_; |
1385 Zone* zone_; | 1413 Zone* zone_; |
1414 RemovableSimulate removable_; | |
1386 }; | 1415 }; |
1387 | 1416 |
1388 | 1417 |
1389 class HStackCheck: public HTemplateInstruction<1> { | 1418 class HStackCheck: public HTemplateInstruction<1> { |
1390 public: | 1419 public: |
1391 enum Type { | 1420 enum Type { |
1392 kFunctionEntry, | 1421 kFunctionEntry, |
1393 kBackwardsBranch | 1422 kBackwardsBranch |
1394 }; | 1423 }; |
1395 | 1424 |
(...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2002 public: | 2031 public: |
2003 explicit HBitNot(HValue* value) : HUnaryOperation(value) { | 2032 explicit HBitNot(HValue* value) : HUnaryOperation(value) { |
2004 set_representation(Representation::Integer32()); | 2033 set_representation(Representation::Integer32()); |
2005 SetFlag(kUseGVN); | 2034 SetFlag(kUseGVN); |
2006 SetFlag(kTruncatingToInt32); | 2035 SetFlag(kTruncatingToInt32); |
2007 } | 2036 } |
2008 | 2037 |
2009 virtual Representation RequiredInputRepresentation(int index) { | 2038 virtual Representation RequiredInputRepresentation(int index) { |
2010 return Representation::Integer32(); | 2039 return Representation::Integer32(); |
2011 } | 2040 } |
2041 virtual Representation observed_input_representation(int index) { | |
2042 return Representation::Integer32(); | |
2043 } | |
2012 virtual HType CalculateInferredType(); | 2044 virtual HType CalculateInferredType(); |
2013 | 2045 |
2014 virtual HValue* Canonicalize(); | 2046 virtual HValue* Canonicalize(); |
2015 | 2047 |
2016 DECLARE_CONCRETE_INSTRUCTION(BitNot) | 2048 DECLARE_CONCRETE_INSTRUCTION(BitNot) |
2017 | 2049 |
2018 protected: | 2050 protected: |
2019 virtual bool DataEquals(HValue* other) { return true; } | 2051 virtual bool DataEquals(HValue* other) { return true; } |
2020 | 2052 |
2021 private: | 2053 private: |
2022 virtual bool IsDeletable() const { return true; } | 2054 virtual bool IsDeletable() const { return true; } |
2023 }; | 2055 }; |
2024 | 2056 |
2025 | 2057 |
2026 class HUnaryMathOperation: public HTemplateInstruction<2> { | 2058 class HUnaryMathOperation: public HTemplateInstruction<2> { |
2027 public: | 2059 public: |
2028 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) | 2060 HUnaryMathOperation(HValue* context, HValue* value, BuiltinFunctionId op) |
2029 : op_(op) { | 2061 : op_(op) { |
2030 SetOperandAt(0, context); | 2062 SetOperandAt(0, context); |
2031 SetOperandAt(1, value); | 2063 SetOperandAt(1, value); |
2032 switch (op) { | 2064 switch (op) { |
2033 case kMathFloor: | 2065 case kMathFloor: |
2034 case kMathRound: | 2066 case kMathRound: |
2035 case kMathCeil: | 2067 case kMathCeil: |
2036 set_representation(Representation::Integer32()); | 2068 set_representation(Representation::Integer32()); |
2037 break; | 2069 break; |
2038 case kMathAbs: | 2070 case kMathAbs: |
2039 set_representation(Representation::Tagged()); | 2071 // Not setting representation here: it is None intentionally. |
2040 SetFlag(kFlexibleRepresentation); | 2072 SetFlag(kFlexibleRepresentation); |
2041 SetGVNFlag(kChangesNewSpacePromotion); | 2073 SetGVNFlag(kChangesNewSpacePromotion); |
2042 break; | 2074 break; |
2043 case kMathSqrt: | 2075 case kMathSqrt: |
2044 case kMathPowHalf: | 2076 case kMathPowHalf: |
2045 case kMathLog: | 2077 case kMathLog: |
2046 case kMathSin: | 2078 case kMathSin: |
2047 case kMathCos: | 2079 case kMathCos: |
2048 case kMathTan: | 2080 case kMathTan: |
2049 set_representation(Representation::Double()); | 2081 set_representation(Representation::Double()); |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2209 map_set->Add(Handle<Map>(transitioned_map), zone); | 2241 map_set->Add(Handle<Map>(transitioned_map), zone); |
2210 } | 2242 } |
2211 }; | 2243 }; |
2212 map_set->Sort(); | 2244 map_set->Sort(); |
2213 return check_map; | 2245 return check_map; |
2214 } | 2246 } |
2215 | 2247 |
2216 virtual Representation RequiredInputRepresentation(int index) { | 2248 virtual Representation RequiredInputRepresentation(int index) { |
2217 return Representation::Tagged(); | 2249 return Representation::Tagged(); |
2218 } | 2250 } |
2251 | |
2219 virtual void PrintDataTo(StringStream* stream); | 2252 virtual void PrintDataTo(StringStream* stream); |
2220 virtual HType CalculateInferredType(); | 2253 virtual HType CalculateInferredType(); |
2221 | 2254 |
2222 HValue* value() { return OperandAt(0); } | 2255 HValue* value() { return OperandAt(0); } |
2223 SmallMapList* map_set() { return &map_set_; } | 2256 SmallMapList* map_set() { return &map_set_; } |
2224 | 2257 |
2225 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) | 2258 DECLARE_CONCRETE_INSTRUCTION(CheckMaps) |
2226 | 2259 |
2227 protected: | 2260 protected: |
2228 virtual bool DataEquals(HValue* other) { | 2261 virtual bool DataEquals(HValue* other) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2436 : inputs_(2, zone), | 2469 : inputs_(2, zone), |
2437 merged_index_(merged_index), | 2470 merged_index_(merged_index), |
2438 phi_id_(-1), | 2471 phi_id_(-1), |
2439 is_live_(false), | 2472 is_live_(false), |
2440 is_convertible_to_integer_(true) { | 2473 is_convertible_to_integer_(true) { |
2441 for (int i = 0; i < Representation::kNumRepresentations; i++) { | 2474 for (int i = 0; i < Representation::kNumRepresentations; i++) { |
2442 non_phi_uses_[i] = 0; | 2475 non_phi_uses_[i] = 0; |
2443 indirect_uses_[i] = 0; | 2476 indirect_uses_[i] = 0; |
2444 } | 2477 } |
2445 ASSERT(merged_index >= 0); | 2478 ASSERT(merged_index >= 0); |
2446 set_representation(Representation::Tagged()); | |
2447 SetFlag(kFlexibleRepresentation); | 2479 SetFlag(kFlexibleRepresentation); |
2448 } | 2480 } |
2449 | 2481 |
2450 virtual Representation InferredRepresentation(); | 2482 virtual Representation RepresentationFromInputs(); |
2451 | 2483 |
2452 virtual Range* InferRange(Zone* zone); | 2484 virtual Range* InferRange(Zone* zone); |
2485 virtual void InferRepresentation(HInferRepresentation* h_infer); | |
2486 Representation RepresentationFromUseRequirements(); | |
2453 virtual Representation RequiredInputRepresentation(int index) { | 2487 virtual Representation RequiredInputRepresentation(int index) { |
2454 return representation(); | 2488 return representation(); |
2455 } | 2489 } |
2456 virtual HType CalculateInferredType(); | 2490 virtual HType CalculateInferredType(); |
2457 virtual int OperandCount() { return inputs_.length(); } | 2491 virtual int OperandCount() { return inputs_.length(); } |
2458 virtual HValue* OperandAt(int index) const { return inputs_[index]; } | 2492 virtual HValue* OperandAt(int index) const { return inputs_[index]; } |
2459 HValue* GetRedundantReplacement(); | 2493 HValue* GetRedundantReplacement(); |
2460 void AddInput(HValue* value); | 2494 void AddInput(HValue* value); |
2461 bool HasRealUses(); | 2495 bool HasRealUses(); |
2462 | 2496 |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2506 return is_convertible_to_integer_; | 2540 return is_convertible_to_integer_; |
2507 } | 2541 } |
2508 | 2542 |
2509 void set_is_convertible_to_integer(bool b) { | 2543 void set_is_convertible_to_integer(bool b) { |
2510 is_convertible_to_integer_ = b; | 2544 is_convertible_to_integer_ = b; |
2511 } | 2545 } |
2512 | 2546 |
2513 bool AllOperandsConvertibleToInteger() { | 2547 bool AllOperandsConvertibleToInteger() { |
2514 for (int i = 0; i < OperandCount(); ++i) { | 2548 for (int i = 0; i < OperandCount(); ++i) { |
2515 if (!OperandAt(i)->IsConvertibleToInteger()) { | 2549 if (!OperandAt(i)->IsConvertibleToInteger()) { |
2550 if (FLAG_trace_representation) { | |
2551 HValue* input = OperandAt(i); | |
2552 PrintF("#%d %s: Input #%d %s at %d is NCTI\n", | |
2553 id(), Mnemonic(), input->id(), input->Mnemonic(), i); | |
2554 } | |
2516 return false; | 2555 return false; |
2517 } | 2556 } |
2518 } | 2557 } |
2519 return true; | 2558 return true; |
2520 } | 2559 } |
2521 | 2560 |
2522 void ResetInteger32Uses(); | |
2523 | |
2524 protected: | 2561 protected: |
2525 virtual void DeleteFromGraph(); | 2562 virtual void DeleteFromGraph(); |
2526 virtual void InternalSetOperandAt(int index, HValue* value) { | 2563 virtual void InternalSetOperandAt(int index, HValue* value) { |
2527 inputs_[index] = value; | 2564 inputs_[index] = value; |
2528 } | 2565 } |
2529 | 2566 |
2530 private: | 2567 private: |
2531 ZoneList<HValue*> inputs_; | 2568 ZoneList<HValue*> inputs_; |
2532 int merged_index_; | 2569 int merged_index_; |
2533 | 2570 |
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2697 // not the converse. | 2734 // not the converse. |
2698 bool has_int32_value_ : 1; | 2735 bool has_int32_value_ : 1; |
2699 bool has_double_value_ : 1; | 2736 bool has_double_value_ : 1; |
2700 int32_t int32_value_; | 2737 int32_t int32_value_; |
2701 double double_value_; | 2738 double double_value_; |
2702 }; | 2739 }; |
2703 | 2740 |
2704 | 2741 |
2705 class HBinaryOperation: public HTemplateInstruction<3> { | 2742 class HBinaryOperation: public HTemplateInstruction<3> { |
2706 public: | 2743 public: |
2707 HBinaryOperation(HValue* context, HValue* left, HValue* right) { | 2744 HBinaryOperation(HValue* context, HValue* left, HValue* right) |
2745 : observed_output_representation_(Representation::None()) { | |
2708 ASSERT(left != NULL && right != NULL); | 2746 ASSERT(left != NULL && right != NULL); |
2709 SetOperandAt(0, context); | 2747 SetOperandAt(0, context); |
2710 SetOperandAt(1, left); | 2748 SetOperandAt(1, left); |
2711 SetOperandAt(2, right); | 2749 SetOperandAt(2, right); |
2750 observed_input_representation_[0] = Representation::None(); | |
2751 observed_input_representation_[1] = Representation::None(); | |
2712 } | 2752 } |
2713 | 2753 |
2714 HValue* context() { return OperandAt(0); } | 2754 HValue* context() { return OperandAt(0); } |
2715 HValue* left() { return OperandAt(1); } | 2755 HValue* left() { return OperandAt(1); } |
2716 HValue* right() { return OperandAt(2); } | 2756 HValue* right() { return OperandAt(2); } |
2717 | 2757 |
2718 // TODO(kasperl): Move these helpers to the IA-32 Lithium | 2758 // TODO(kasperl): Move these helpers to the IA-32 Lithium |
2719 // instruction sequence builder. | 2759 // instruction sequence builder. |
2720 HValue* LeastConstantOperand() { | 2760 HValue* LeastConstantOperand() { |
2721 if (IsCommutative() && left()->IsConstant()) return right(); | 2761 if (IsCommutative() && left()->IsConstant()) return right(); |
2722 return left(); | 2762 return left(); |
2723 } | 2763 } |
2724 | 2764 |
2725 HValue* MostConstantOperand() { | 2765 HValue* MostConstantOperand() { |
2726 if (IsCommutative() && left()->IsConstant()) return left(); | 2766 if (IsCommutative() && left()->IsConstant()) return left(); |
2727 return right(); | 2767 return right(); |
2728 } | 2768 } |
2729 | 2769 |
2770 void set_observed_input_representation(Representation left, | |
2771 Representation right) { | |
2772 observed_input_representation_[0] = left; | |
2773 observed_input_representation_[1] = right; | |
2774 } | |
2775 | |
2776 virtual void initialize_output_representation(Representation observed) { | |
2777 observed_output_representation_ = observed; | |
2778 } | |
2779 | |
2780 virtual Representation observed_input_representation(int index) { | |
2781 if (index == 0) return Representation::Tagged(); | |
2782 return observed_input_representation_[index - 1]; | |
2783 } | |
2784 | |
2785 virtual Representation RepresentationFromInputs(); | |
2786 virtual void AssumeRepresentation(Representation r); | |
2787 | |
2730 virtual bool IsCommutative() const { return false; } | 2788 virtual bool IsCommutative() const { return false; } |
2731 | 2789 |
2732 virtual void PrintDataTo(StringStream* stream); | 2790 virtual void PrintDataTo(StringStream* stream); |
2733 | 2791 |
2734 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) | 2792 DECLARE_ABSTRACT_INSTRUCTION(BinaryOperation) |
2793 | |
2794 private: | |
2795 Representation observed_input_representation_[2]; | |
2796 Representation observed_output_representation_; | |
2735 }; | 2797 }; |
2736 | 2798 |
2737 | 2799 |
2738 class HWrapReceiver: public HTemplateInstruction<2> { | 2800 class HWrapReceiver: public HTemplateInstruction<2> { |
2739 public: | 2801 public: |
2740 HWrapReceiver(HValue* receiver, HValue* function) { | 2802 HWrapReceiver(HValue* receiver, HValue* function) { |
2741 set_representation(Representation::Tagged()); | 2803 set_representation(Representation::Tagged()); |
2742 SetOperandAt(0, receiver); | 2804 SetOperandAt(0, receiver); |
2743 SetOperandAt(1, function); | 2805 SetOperandAt(1, function); |
2744 } | 2806 } |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2894 } | 2956 } |
2895 // Also allow the length to be tagged if the index is constant, because | 2957 // Also allow the length to be tagged if the index is constant, because |
2896 // it can be tagged to allow direct comparison. | 2958 // it can be tagged to allow direct comparison. |
2897 if (index()->IsConstant() && | 2959 if (index()->IsConstant() && |
2898 index()->representation().IsInteger32() && | 2960 index()->representation().IsInteger32() && |
2899 arg_index == 1) { | 2961 arg_index == 1) { |
2900 return Representation::Tagged(); | 2962 return Representation::Tagged(); |
2901 } | 2963 } |
2902 return Representation::Integer32(); | 2964 return Representation::Integer32(); |
2903 } | 2965 } |
2966 virtual Representation observed_input_representation(int index) { | |
2967 return Representation::Integer32(); | |
2968 } | |
2904 | 2969 |
2905 virtual void PrintDataTo(StringStream* stream); | 2970 virtual void PrintDataTo(StringStream* stream); |
2906 | 2971 |
2907 HValue* index() { return OperandAt(0); } | 2972 HValue* index() { return OperandAt(0); } |
2908 HValue* length() { return OperandAt(1); } | 2973 HValue* length() { return OperandAt(1); } |
2909 | 2974 |
2910 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) | 2975 DECLARE_CONCRETE_INSTRUCTION(BoundsCheck) |
2911 | 2976 |
2912 protected: | 2977 protected: |
2913 virtual bool DataEquals(HValue* other) { return true; } | 2978 virtual bool DataEquals(HValue* other) { return true; } |
2914 BoundsCheckKeyMode key_mode_; | 2979 BoundsCheckKeyMode key_mode_; |
2915 }; | 2980 }; |
2916 | 2981 |
2917 | 2982 |
2918 class HBitwiseBinaryOperation: public HBinaryOperation { | 2983 class HBitwiseBinaryOperation: public HBinaryOperation { |
2919 public: | 2984 public: |
2920 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) | 2985 HBitwiseBinaryOperation(HValue* context, HValue* left, HValue* right) |
2921 : HBinaryOperation(context, left, right) { | 2986 : HBinaryOperation(context, left, right) { |
2922 set_representation(Representation::Tagged()); | |
2923 SetFlag(kFlexibleRepresentation); | 2987 SetFlag(kFlexibleRepresentation); |
2988 SetFlag(kTruncatingToInt32); | |
2924 SetAllSideEffects(); | 2989 SetAllSideEffects(); |
2925 observed_input_representation_[0] = Representation::Tagged(); | |
2926 observed_input_representation_[1] = Representation::None(); | |
2927 observed_input_representation_[2] = Representation::None(); | |
2928 } | 2990 } |
2929 | 2991 |
2930 virtual Representation RequiredInputRepresentation(int index) { | 2992 virtual Representation RequiredInputRepresentation(int index) { |
2931 return index == 0 | 2993 return index == 0 |
2932 ? Representation::Tagged() | 2994 ? Representation::Tagged() |
2933 : representation(); | 2995 : representation(); |
2934 } | 2996 } |
2935 | 2997 |
2936 virtual void RepresentationChanged(Representation to) { | 2998 virtual void RepresentationChanged(Representation to) { |
2937 if (!to.IsTagged()) { | 2999 if (!to.IsTagged()) { |
2938 ASSERT(to.IsInteger32()); | 3000 ASSERT(to.IsInteger32()); |
2939 ClearAllSideEffects(); | 3001 ClearAllSideEffects(); |
2940 SetFlag(kTruncatingToInt32); | |
2941 SetFlag(kUseGVN); | 3002 SetFlag(kUseGVN); |
3003 } else { | |
3004 SetAllSideEffects(); | |
3005 ClearFlag(kUseGVN); | |
2942 } | 3006 } |
2943 } | 3007 } |
2944 | 3008 |
2945 virtual HType CalculateInferredType(); | 3009 virtual void UpdateRepresentation(Representation new_rep, |
2946 | 3010 HInferRepresentation* h_infer, |
2947 virtual Representation ObservedInputRepresentation(int index) { | 3011 const char* reason) { |
2948 return observed_input_representation_[index]; | 3012 // We only generate either int32 or generic tagged bitwise operations. |
3013 if (new_rep.IsDouble()) new_rep = Representation::Integer32(); | |
3014 HValue::UpdateRepresentation(new_rep, h_infer, reason); | |
2949 } | 3015 } |
2950 | 3016 |
2951 void InitializeObservedInputRepresentation(Representation r) { | 3017 virtual void initialize_output_representation(Representation observed) { |
2952 observed_input_representation_[1] = r; | 3018 if (observed.IsDouble()) observed = Representation::Integer32(); |
2953 observed_input_representation_[2] = r; | 3019 HBinaryOperation::initialize_output_representation(observed); |
2954 } | 3020 } |
2955 | 3021 |
3022 virtual HType CalculateInferredType(); | |
3023 | |
2956 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) | 3024 DECLARE_ABSTRACT_INSTRUCTION(BitwiseBinaryOperation) |
2957 | 3025 |
2958 private: | 3026 private: |
2959 virtual bool IsDeletable() const { return true; } | 3027 virtual bool IsDeletable() const { return true; } |
2960 | |
2961 Representation observed_input_representation_[3]; | |
2962 }; | 3028 }; |
2963 | 3029 |
2964 | 3030 |
2965 class HMathFloorOfDiv: public HBinaryOperation { | 3031 class HMathFloorOfDiv: public HBinaryOperation { |
2966 public: | 3032 public: |
2967 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) | 3033 HMathFloorOfDiv(HValue* context, HValue* left, HValue* right) |
2968 : HBinaryOperation(context, left, right) { | 3034 : HBinaryOperation(context, left, right) { |
2969 set_representation(Representation::Integer32()); | 3035 set_representation(Representation::Integer32()); |
2970 SetFlag(kUseGVN); | 3036 SetFlag(kUseGVN); |
2971 SetFlag(kCanOverflow); | 3037 SetFlag(kCanOverflow); |
(...skipping 12 matching lines...) Expand all Loading... | |
2984 | 3050 |
2985 private: | 3051 private: |
2986 virtual bool IsDeletable() const { return true; } | 3052 virtual bool IsDeletable() const { return true; } |
2987 }; | 3053 }; |
2988 | 3054 |
2989 | 3055 |
2990 class HArithmeticBinaryOperation: public HBinaryOperation { | 3056 class HArithmeticBinaryOperation: public HBinaryOperation { |
2991 public: | 3057 public: |
2992 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) | 3058 HArithmeticBinaryOperation(HValue* context, HValue* left, HValue* right) |
2993 : HBinaryOperation(context, left, right) { | 3059 : HBinaryOperation(context, left, right) { |
2994 set_representation(Representation::Tagged()); | 3060 SetAllSideEffects(); |
2995 SetFlag(kFlexibleRepresentation); | 3061 SetFlag(kFlexibleRepresentation); |
2996 SetAllSideEffects(); | |
2997 } | 3062 } |
2998 | 3063 |
2999 virtual void RepresentationChanged(Representation to) { | 3064 virtual void RepresentationChanged(Representation to) { |
3000 if (!to.IsTagged()) { | 3065 if (to.IsTagged()) { |
3066 SetAllSideEffects(); | |
3067 ClearFlag(kUseGVN); | |
3068 } else { | |
3001 ClearAllSideEffects(); | 3069 ClearAllSideEffects(); |
3002 SetFlag(kUseGVN); | 3070 SetFlag(kUseGVN); |
3003 } | 3071 } |
3004 } | 3072 } |
3005 | 3073 |
3006 virtual HType CalculateInferredType(); | 3074 virtual HType CalculateInferredType(); |
3007 virtual Representation RequiredInputRepresentation(int index) { | 3075 virtual Representation RequiredInputRepresentation(int index) { |
3008 return index == 0 | 3076 return index == 0 |
3009 ? Representation::Tagged() | 3077 ? Representation::Tagged() |
3010 : representation(); | 3078 : representation(); |
3011 } | 3079 } |
3012 | 3080 |
3013 virtual Representation InferredRepresentation() { | |
3014 if (left()->representation().Equals(right()->representation())) { | |
3015 return left()->representation(); | |
3016 } | |
3017 return HValue::InferredRepresentation(); | |
3018 } | |
3019 | |
3020 private: | 3081 private: |
3021 virtual bool IsDeletable() const { return true; } | 3082 virtual bool IsDeletable() const { return true; } |
3022 }; | 3083 }; |
3023 | 3084 |
3024 | 3085 |
3025 class HCompareGeneric: public HBinaryOperation { | 3086 class HCompareGeneric: public HBinaryOperation { |
3026 public: | 3087 public: |
3027 HCompareGeneric(HValue* context, | 3088 HCompareGeneric(HValue* context, |
3028 HValue* left, | 3089 HValue* left, |
3029 HValue* right, | 3090 HValue* right, |
3030 Token::Value token) | 3091 Token::Value token) |
3031 : HBinaryOperation(context, left, right), token_(token) { | 3092 : HBinaryOperation(context, left, right), token_(token) { |
3032 ASSERT(Token::IsCompareOp(token)); | 3093 ASSERT(Token::IsCompareOp(token)); |
3033 set_representation(Representation::Tagged()); | 3094 set_representation(Representation::Tagged()); |
3034 SetAllSideEffects(); | 3095 SetAllSideEffects(); |
3035 } | 3096 } |
3036 | 3097 |
3037 virtual Representation RequiredInputRepresentation(int index) { | 3098 virtual Representation RequiredInputRepresentation(int index) { |
3038 return Representation::Tagged(); | 3099 return index == 0 |
3039 } | 3100 ? Representation::Tagged() |
3040 | 3101 : representation(); |
3041 Representation GetInputRepresentation() const { | |
3042 return Representation::Tagged(); | |
3043 } | 3102 } |
3044 | 3103 |
3045 Token::Value token() const { return token_; } | 3104 Token::Value token() const { return token_; } |
3046 virtual void PrintDataTo(StringStream* stream); | 3105 virtual void PrintDataTo(StringStream* stream); |
3047 | 3106 |
3048 virtual HType CalculateInferredType(); | 3107 virtual HType CalculateInferredType(); |
3049 | 3108 |
3050 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) | 3109 DECLARE_CONCRETE_INSTRUCTION(CompareGeneric) |
3051 | 3110 |
3052 private: | 3111 private: |
3053 Token::Value token_; | 3112 Token::Value token_; |
3054 }; | 3113 }; |
3055 | 3114 |
3056 | 3115 |
3057 class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> { | 3116 class HCompareIDAndBranch: public HTemplateControlInstruction<2, 2> { |
3058 public: | 3117 public: |
3059 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token) | 3118 HCompareIDAndBranch(HValue* left, HValue* right, Token::Value token) |
3060 : token_(token) { | 3119 : token_(token) { |
3120 SetFlag(kFlexibleRepresentation); | |
3061 ASSERT(Token::IsCompareOp(token)); | 3121 ASSERT(Token::IsCompareOp(token)); |
3062 SetOperandAt(0, left); | 3122 SetOperandAt(0, left); |
3063 SetOperandAt(1, right); | 3123 SetOperandAt(1, right); |
3064 } | 3124 } |
3065 | 3125 |
3066 HValue* left() { return OperandAt(0); } | 3126 HValue* left() { return OperandAt(0); } |
3067 HValue* right() { return OperandAt(1); } | 3127 HValue* right() { return OperandAt(1); } |
3068 Token::Value token() const { return token_; } | 3128 Token::Value token() const { return token_; } |
3069 | 3129 |
3070 void SetInputRepresentation(Representation r); | 3130 void set_observed_input_representation(Representation left, |
3071 Representation GetInputRepresentation() const { | 3131 Representation right) { |
3072 return input_representation_; | 3132 observed_input_representation_[0] = left; |
3133 observed_input_representation_[1] = right; | |
3073 } | 3134 } |
3074 | 3135 |
3136 virtual void InferRepresentation(HInferRepresentation* h_infer); | |
3137 | |
3075 virtual Representation RequiredInputRepresentation(int index) { | 3138 virtual Representation RequiredInputRepresentation(int index) { |
3076 return input_representation_; | 3139 return representation(); |
3140 } | |
3141 virtual Representation observed_input_representation(int index) { | |
3142 return observed_input_representation_[index]; | |
3077 } | 3143 } |
3078 virtual void PrintDataTo(StringStream* stream); | 3144 virtual void PrintDataTo(StringStream* stream); |
3079 | 3145 |
3080 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) | 3146 DECLARE_CONCRETE_INSTRUCTION(CompareIDAndBranch) |
3081 | 3147 |
3082 private: | 3148 private: |
3083 Representation input_representation_; | 3149 Representation observed_input_representation_[2]; |
3084 Token::Value token_; | 3150 Token::Value token_; |
3085 }; | 3151 }; |
3086 | 3152 |
3087 | 3153 |
3088 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { | 3154 class HCompareObjectEqAndBranch: public HTemplateControlInstruction<2, 2> { |
3089 public: | 3155 public: |
3090 HCompareObjectEqAndBranch(HValue* left, HValue* right) { | 3156 HCompareObjectEqAndBranch(HValue* left, HValue* right) { |
3091 SetOperandAt(0, left); | 3157 SetOperandAt(0, left); |
3092 SetOperandAt(1, right); | 3158 SetOperandAt(1, right); |
3093 } | 3159 } |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3134 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { } | 3200 : HUnaryControlInstruction(value, NULL, NULL), kind_(kind), nil_(nil) { } |
3135 | 3201 |
3136 EqualityKind kind() const { return kind_; } | 3202 EqualityKind kind() const { return kind_; } |
3137 NilValue nil() const { return nil_; } | 3203 NilValue nil() const { return nil_; } |
3138 | 3204 |
3139 virtual void PrintDataTo(StringStream* stream); | 3205 virtual void PrintDataTo(StringStream* stream); |
3140 | 3206 |
3141 virtual Representation RequiredInputRepresentation(int index) { | 3207 virtual Representation RequiredInputRepresentation(int index) { |
3142 return Representation::Tagged(); | 3208 return Representation::Tagged(); |
3143 } | 3209 } |
3210 virtual Representation observed_input_representation(int index) { | |
3211 return Representation::Tagged(); | |
3212 } | |
3144 | 3213 |
3145 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch) | 3214 DECLARE_CONCRETE_INSTRUCTION(IsNilAndBranch) |
3146 | 3215 |
3147 private: | 3216 private: |
3148 EqualityKind kind_; | 3217 EqualityKind kind_; |
3149 NilValue nil_; | 3218 NilValue nil_; |
3150 }; | 3219 }; |
3151 | 3220 |
3152 | 3221 |
3153 class HIsObjectAndBranch: public HUnaryControlInstruction { | 3222 class HIsObjectAndBranch: public HUnaryControlInstruction { |
(...skipping 257 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3411 } | 3480 } |
3412 | 3481 |
3413 HValue* left() { return OperandAt(0); } | 3482 HValue* left() { return OperandAt(0); } |
3414 HValue* right() const { return OperandAt(1); } | 3483 HValue* right() const { return OperandAt(1); } |
3415 | 3484 |
3416 virtual Representation RequiredInputRepresentation(int index) { | 3485 virtual Representation RequiredInputRepresentation(int index) { |
3417 return index == 0 | 3486 return index == 0 |
3418 ? Representation::Double() | 3487 ? Representation::Double() |
3419 : Representation::None(); | 3488 : Representation::None(); |
3420 } | 3489 } |
3490 virtual Representation observed_input_representation(int index) { | |
3491 return RequiredInputRepresentation(index); | |
3492 } | |
3421 | 3493 |
3422 DECLARE_CONCRETE_INSTRUCTION(Power) | 3494 DECLARE_CONCRETE_INSTRUCTION(Power) |
3423 | 3495 |
3424 protected: | 3496 protected: |
3425 virtual bool DataEquals(HValue* other) { return true; } | 3497 virtual bool DataEquals(HValue* other) { return true; } |
3426 | 3498 |
3427 private: | 3499 private: |
3428 virtual bool IsDeletable() const { | 3500 virtual bool IsDeletable() const { |
3429 return !right()->representation().IsTagged(); | 3501 return !right()->representation().IsTagged(); |
3430 } | 3502 } |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3596 | 3668 |
3597 class HMathMinMax: public HArithmeticBinaryOperation { | 3669 class HMathMinMax: public HArithmeticBinaryOperation { |
3598 public: | 3670 public: |
3599 enum Operation { kMathMin, kMathMax }; | 3671 enum Operation { kMathMin, kMathMax }; |
3600 | 3672 |
3601 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op) | 3673 HMathMinMax(HValue* context, HValue* left, HValue* right, Operation op) |
3602 : HArithmeticBinaryOperation(context, left, right), | 3674 : HArithmeticBinaryOperation(context, left, right), |
3603 operation_(op) { } | 3675 operation_(op) { } |
3604 | 3676 |
3605 virtual Representation RequiredInputRepresentation(int index) { | 3677 virtual Representation RequiredInputRepresentation(int index) { |
3606 return index == 0 | 3678 return index == 0 ? Representation::Tagged() |
3607 ? Representation::Tagged() | 3679 : representation(); |
3608 : representation(); | 3680 } |
3609 } | |
3610 | 3681 |
3611 virtual Representation InferredRepresentation() { | 3682 virtual Representation observed_input_representation(int index) { |
3612 if (left()->representation().IsInteger32() && | 3683 return RequiredInputRepresentation(index); |
3613 right()->representation().IsInteger32()) { | 3684 } |
3685 | |
3686 virtual Representation RepresentationFromInputs() { | |
3687 Representation left_rep = left()->representation(); | |
3688 Representation right_rep = right()->representation(); | |
3689 if ((left_rep.IsNone() || left_rep.IsInteger32()) && | |
3690 (right_rep.IsNone() || right_rep.IsInteger32())) { | |
3614 return Representation::Integer32(); | 3691 return Representation::Integer32(); |
3615 } | 3692 } |
3616 return Representation::Double(); | 3693 return Representation::Double(); |
3617 } | 3694 } |
3618 | 3695 |
3619 virtual bool IsCommutative() const { return true; } | 3696 virtual bool IsCommutative() const { return true; } |
3620 | 3697 |
3621 Operation operation() { return operation_; } | 3698 Operation operation() { return operation_; } |
3622 | 3699 |
3623 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) | 3700 DECLARE_CONCRETE_INSTRUCTION(MathMinMax) |
(...skipping 686 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4310 // kind_double: tagged[int32] (none) | 4387 // kind_double: tagged[int32] (none) |
4311 // kind_external: external[int32] (none) | 4388 // kind_external: external[int32] (none) |
4312 if (index == 0) { | 4389 if (index == 0) { |
4313 return is_external() ? Representation::External() | 4390 return is_external() ? Representation::External() |
4314 : Representation::Tagged(); | 4391 : Representation::Tagged(); |
4315 } | 4392 } |
4316 if (index == 1) return Representation::Integer32(); | 4393 if (index == 1) return Representation::Integer32(); |
4317 return Representation::None(); | 4394 return Representation::None(); |
4318 } | 4395 } |
4319 | 4396 |
4397 virtual Representation observed_input_representation(int index) { | |
4398 return RequiredInputRepresentation(index); | |
4399 } | |
4400 | |
4320 virtual void PrintDataTo(StringStream* stream); | 4401 virtual void PrintDataTo(StringStream* stream); |
4321 | 4402 |
4322 bool RequiresHoleCheck() const; | 4403 bool RequiresHoleCheck() const; |
4323 | 4404 |
4324 virtual Range* InferRange(Zone* zone); | 4405 virtual Range* InferRange(Zone* zone); |
4325 | 4406 |
4326 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) | 4407 DECLARE_CONCRETE_INSTRUCTION(LoadKeyed) |
4327 | 4408 |
4328 protected: | 4409 protected: |
4329 virtual bool DataEquals(HValue* other) { | 4410 virtual bool DataEquals(HValue* other) { |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4501 SetOperandAt(2, val); | 4582 SetOperandAt(2, val); |
4502 | 4583 |
4503 if (is_external()) { | 4584 if (is_external()) { |
4504 SetGVNFlag(kChangesSpecializedArrayElements); | 4585 SetGVNFlag(kChangesSpecializedArrayElements); |
4505 } else if (IsFastDoubleElementsKind(elements_kind)) { | 4586 } else if (IsFastDoubleElementsKind(elements_kind)) { |
4506 SetGVNFlag(kChangesDoubleArrayElements); | 4587 SetGVNFlag(kChangesDoubleArrayElements); |
4507 SetFlag(kDeoptimizeOnUndefined); | 4588 SetFlag(kDeoptimizeOnUndefined); |
4508 } else { | 4589 } else { |
4509 SetGVNFlag(kChangesArrayElements); | 4590 SetGVNFlag(kChangesArrayElements); |
4510 } | 4591 } |
4592 | |
4593 // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating. | |
4594 if (elements_kind >= EXTERNAL_BYTE_ELEMENTS && | |
4595 elements_kind <= EXTERNAL_UNSIGNED_INT_ELEMENTS) { | |
4596 SetFlag(kTruncatingToInt32); | |
4597 } | |
4511 } | 4598 } |
4512 | 4599 |
4513 virtual Representation RequiredInputRepresentation(int index) { | 4600 virtual Representation RequiredInputRepresentation(int index) { |
4514 // kind_fast: tagged[int32] = tagged | 4601 // kind_fast: tagged[int32] = tagged |
4515 // kind_double: tagged[int32] = double | 4602 // kind_double: tagged[int32] = double |
4516 // kind_external: external[int32] = (double | int32) | 4603 // kind_external: external[int32] = (double | int32) |
4517 if (index == 0) { | 4604 if (index == 0) { |
4518 return is_external() ? Representation::External() | 4605 return is_external() ? Representation::External() |
4519 : Representation::Tagged(); | 4606 : Representation::Tagged(); |
4520 } else if (index == 1) { | 4607 } else if (index == 1) { |
4521 return Representation::Integer32(); | 4608 return Representation::Integer32(); |
4522 } | 4609 } |
4523 | 4610 |
4524 ASSERT_EQ(index, 2); | 4611 ASSERT_EQ(index, 2); |
4525 if (IsDoubleOrFloatElementsKind(elements_kind())) { | 4612 if (IsDoubleOrFloatElementsKind(elements_kind())) { |
4526 return Representation::Double(); | 4613 return Representation::Double(); |
4527 } | 4614 } |
4528 | 4615 |
4529 return is_external() ? Representation::Integer32() | 4616 return is_external() ? Representation::Integer32() |
4530 : Representation::Tagged(); | 4617 : Representation::Tagged(); |
4531 } | 4618 } |
4532 | 4619 |
4533 bool is_external() const { | 4620 bool is_external() const { |
4534 return IsExternalArrayElementsKind(elements_kind()); | 4621 return IsExternalArrayElementsKind(elements_kind()); |
4535 } | 4622 } |
4623 | |
4624 virtual Representation observed_input_representation(int index) { | |
4625 if (index < 2) return RequiredInputRepresentation(index); | |
4626 if (IsDoubleOrFloatElementsKind(elements_kind())) { | |
4627 return Representation::Double(); | |
4628 } | |
4629 if (is_external()) { | |
4630 return Representation::Integer32(); | |
4631 } | |
4632 // For fast object elements kinds, don't assume anything. | |
4633 return Representation::None(); | |
4634 } | |
4635 | |
4536 HValue* elements() { return OperandAt(0); } | 4636 HValue* elements() { return OperandAt(0); } |
4537 HValue* key() { return OperandAt(1); } | 4637 HValue* key() { return OperandAt(1); } |
4538 HValue* value() { return OperandAt(2); } | 4638 HValue* value() { return OperandAt(2); } |
4539 bool value_is_smi() const { | 4639 bool value_is_smi() const { |
4540 return IsFastSmiElementsKind(elements_kind_); | 4640 return IsFastSmiElementsKind(elements_kind_); |
4541 } | 4641 } |
4542 ElementsKind elements_kind() const { return elements_kind_; } | 4642 ElementsKind elements_kind() const { return elements_kind_; } |
4543 uint32_t index_offset() { return index_offset_; } | 4643 uint32_t index_offset() { return index_offset_; } |
4544 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } | 4644 void SetIndexOffset(uint32_t index_offset) { index_offset_ = index_offset; } |
4545 HValue* GetKey() { return key(); } | 4645 HValue* GetKey() { return key(); } |
(...skipping 718 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5264 virtual bool IsDeletable() const { return true; } | 5364 virtual bool IsDeletable() const { return true; } |
5265 }; | 5365 }; |
5266 | 5366 |
5267 | 5367 |
5268 #undef DECLARE_INSTRUCTION | 5368 #undef DECLARE_INSTRUCTION |
5269 #undef DECLARE_CONCRETE_INSTRUCTION | 5369 #undef DECLARE_CONCRETE_INSTRUCTION |
5270 | 5370 |
5271 } } // namespace v8::internal | 5371 } } // namespace v8::internal |
5272 | 5372 |
5273 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ | 5373 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ |
OLD | NEW |