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

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; fixed tests 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 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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_SIMULATE,
1339 FIXED_SIMULATE
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
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_SIMULATE; }
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
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
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
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 RepresentationObservedByAllNonPhiUses();
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
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
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
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
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
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
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
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
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
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
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_
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