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