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

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

Issue 10837165: Lattice-based representation inference, powered by left/right specific type feedback for BinaryOps … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 27 matching lines...) Expand all
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698