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

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

Issue 6881003: Prevent deopt when assigning double values to typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fixes to make ia32 tests run Created 9 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
251 Range* next_; 251 Range* next_;
252 bool can_be_minus_zero_; 252 bool can_be_minus_zero_;
253 }; 253 };
254 254
255 255
256 class Representation { 256 class Representation {
257 public: 257 public:
258 enum Kind { 258 enum Kind {
259 kNone, 259 kNone,
260 kTagged, 260 kTagged,
261 // Specializations
262 kTruncatedInteger32,
263 kClampedRoundedUInteger8,
264 // Terminal specializations
265 kInteger32,
261 kDouble, 266 kDouble,
262 kInteger32,
263 kExternal, 267 kExternal,
264 kNumRepresentations 268 // Derived
269 kNumRepresentations,
270 kFirstSpecialization = kTruncatedInteger32,
271 kLastSpecialization = kExternal,
272 kNumberOfSpecialization = kLastSpecialization -
273 kFirstSpecialization + 1,
274 kFirstTerminalSpecialization = kInteger32,
275 kLastTerminalSpecialization = kExternal,
276 kNumberOfTerminalSpecialization =
277 kLastTerminalSpecialization - kFirstTerminalSpecialization + 1
265 }; 278 };
266 279
267 Representation() : kind_(kNone) { } 280 Representation() : kind_(kNone) { }
268 281
269 static Representation None() { return Representation(kNone); } 282 static Representation None() { return Representation(kNone); }
270 static Representation Tagged() { return Representation(kTagged); } 283 static Representation Tagged() { return Representation(kTagged); }
284 static Representation Double() { return Representation(kDouble); }
271 static Representation Integer32() { return Representation(kInteger32); } 285 static Representation Integer32() { return Representation(kInteger32); }
272 static Representation Double() { return Representation(kDouble); } 286 static Representation TruncatedInteger32() {
287 return Representation(kTruncatedInteger32);
288 }
289 static Representation ClampedRoundedUInteger8() {
290 return Representation(kClampedRoundedUInteger8);
291 }
273 static Representation External() { return Representation(kExternal); } 292 static Representation External() { return Representation(kExternal); }
274 293
275 bool Equals(const Representation& other) { 294 bool Equals(const Representation& other) {
276 return kind_ == other.kind_; 295 return kind_ == other.kind_;
277 } 296 }
278 297
279 Kind kind() const { return static_cast<Kind>(kind_); } 298 Kind kind() const { return static_cast<Kind>(kind_); }
280 bool IsNone() const { return kind_ == kNone; } 299 bool IsNone() const { return kind_ == kNone; }
281 bool IsTagged() const { return kind_ == kTagged; } 300 bool IsTagged() const { return kind_ == kTagged; }
282 bool IsInteger32() const { return kind_ == kInteger32; } 301 bool IsInteger32X() const { return kind_ == kInteger32; }
302 bool IsTruncatedInteger32() const { return kind_ == kTruncatedInteger32; }
303 bool IsClampedRoundedInteger8() const {
304 return kind_ == kClampedRoundedUInteger8;
305 }
306 bool IsInteger() const { return IsInteger32X() || IsTruncatedInteger32() ||
307 IsClampedRoundedInteger8(); }
283 bool IsDouble() const { return kind_ == kDouble; } 308 bool IsDouble() const { return kind_ == kDouble; }
284 bool IsExternal() const { return kind_ == kExternal; } 309 bool IsExternal() const { return kind_ == kExternal; }
285 bool IsSpecialization() const { 310 bool IsTerminalSpecialization() const {
286 return kind_ == kInteger32 || kind_ == kDouble; 311 return kind_ >= kFirstTerminalSpecialization &&
312 kind_ <= kLastTerminalSpecialization;
287 } 313 }
288 const char* Mnemonic() const; 314 const char* Mnemonic() const;
289 315
290 private: 316 private:
291 explicit Representation(Kind k) : kind_(k) { } 317 explicit Representation(Kind k) : kind_(k) { }
292 318
293 // Make sure kind fits in int8. 319 // Make sure kind fits in int8.
294 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte)); 320 STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
295 321
296 int8_t kind_; 322 int8_t kind_;
297 }; 323 };
298 324
299 325
326 enum ToIRoundingMode {
327 kNoRoundingMode = 0,
328 kTruncatingRoundingMode,
329 k8BitClampedRoundingMode
330 };
331
332
333 inline static ToIRoundingMode RepresentationToRoundingMode(Representation r) {
334 if (r.IsClampedRoundedInteger8()) {
335 return k8BitClampedRoundingMode;
336 } else if (r.IsTruncatedInteger32()) {
337 return kTruncatingRoundingMode;
338 } else {
339 return kNoRoundingMode;
340 }
341 }
342
343
300 class HType { 344 class HType {
301 public: 345 public:
302 HType() : type_(kUninitialized) { } 346 HType() : type_(kUninitialized) { }
303 347
304 static HType Tagged() { return HType(kTagged); } 348 static HType Tagged() { return HType(kTagged); }
305 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); } 349 static HType TaggedPrimitive() { return HType(kTaggedPrimitive); }
306 static HType TaggedNumber() { return HType(kTaggedNumber); } 350 static HType TaggedNumber() { return HType(kTaggedNumber); }
307 static HType Smi() { return HType(kSmi); } 351 static HType Smi() { return HType(kSmi); }
308 static HType HeapNumber() { return HType(kHeapNumber); } 352 static HType HeapNumber() { return HType(kHeapNumber); }
309 static HType String() { return HType(kString); } 353 static HType String() { return HType(kString); }
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
420 // Declare global value numbering flags. 464 // Declare global value numbering flags.
421 #define DECLARE_DO(type) kChanges##type, kDependsOn##type, 465 #define DECLARE_DO(type) kChanges##type, kDependsOn##type,
422 GVN_FLAG_LIST(DECLARE_DO) 466 GVN_FLAG_LIST(DECLARE_DO)
423 #undef DECLARE_DO 467 #undef DECLARE_DO
424 kFlexibleRepresentation, 468 kFlexibleRepresentation,
425 kUseGVN, 469 kUseGVN,
426 kCanOverflow, 470 kCanOverflow,
427 kBailoutOnMinusZero, 471 kBailoutOnMinusZero,
428 kCanBeDivByZero, 472 kCanBeDivByZero,
429 kIsArguments, 473 kIsArguments,
430 kTruncatingToInt32, 474 kLastFlag = kIsArguments
431 kLastFlag = kTruncatingToInt32
432 }; 475 };
433 476
434 STATIC_ASSERT(kLastFlag < kBitsPerInt); 477 STATIC_ASSERT(kLastFlag < kBitsPerInt);
435 478
436 static const int kChangesToDependsFlagsLeftShift = 1; 479 static const int kChangesToDependsFlagsLeftShift = 1;
437 480
438 static int ChangesFlagsMask() { 481 static int ChangesFlagsMask() {
439 int result = 0; 482 int result = 0;
440 // Create changes mask. 483 // Create changes mask.
441 #define DECLARE_DO(type) result |= (1 << kChanges##type); 484 #define DECLARE_DO(type) result |= (1 << kChanges##type);
(...skipping 490 matching lines...) Expand 10 before | Expand all | Expand 10 after
932 } 975 }
933 976
934 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw") 977 DECLARE_CONCRETE_INSTRUCTION(Throw, "throw")
935 }; 978 };
936 979
937 980
938 class HChange: public HUnaryOperation { 981 class HChange: public HUnaryOperation {
939 public: 982 public:
940 HChange(HValue* value, 983 HChange(HValue* value,
941 Representation from, 984 Representation from,
942 Representation to, 985 Representation to)
943 bool is_truncating)
944 : HUnaryOperation(value), from_(from) { 986 : HUnaryOperation(value), from_(from) {
945 ASSERT(!from.IsNone() && !to.IsNone()); 987 ASSERT(!from.IsNone() && !to.IsNone());
946 ASSERT(!from.Equals(to)); 988 ASSERT(!from.Equals(to));
947 set_representation(to); 989 set_representation(to);
948 SetFlag(kUseGVN); 990 SetFlag(kUseGVN);
949 if (is_truncating) SetFlag(kTruncatingToInt32); 991 if (from.IsInteger() && to.IsTagged() && value->range() != NULL &&
950 if (from.IsInteger32() && to.IsTagged() && value->range() != NULL &&
951 value->range()->IsInSmiRange()) { 992 value->range()->IsInSmiRange()) {
952 set_type(HType::Smi()); 993 set_type(HType::Smi());
953 } 994 }
954 } 995 }
955 996
956 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited); 997 virtual HValue* EnsureAndPropagateNotMinusZero(BitVector* visited);
957 998
958 Representation from() const { return from_; } 999 Representation from() const { return from_; }
959 Representation to() const { return representation(); } 1000 Representation to() const { return representation(); }
960 virtual Representation RequiredInputRepresentation(int index) const { 1001 virtual Representation RequiredInputRepresentation(int index) const {
961 return from_; 1002 return from_;
962 } 1003 }
963 1004
964 bool CanTruncateToInt32() const { return CheckFlag(kTruncatingToInt32); }
965
966 virtual void PrintDataTo(StringStream* stream); 1005 virtual void PrintDataTo(StringStream* stream);
967 1006
968 DECLARE_CONCRETE_INSTRUCTION(Change, 1007 DECLARE_CONCRETE_INSTRUCTION(Change,
969 CanTruncateToInt32() ? "truncate" : "change") 1008 representation().IsTruncatedInteger32()
1009 ? "truncate"
1010 : (representation().IsClampedRoundedInteger8()
1011 ? "clamp"
1012 : "change"))
970 1013
971 protected: 1014 protected:
972 virtual bool DataEquals(HValue* other) { 1015 virtual bool DataEquals(HValue* other) {
973 if (!other->IsChange()) return false; 1016 if (!other->IsChange()) return false;
974 HChange* change = HChange::cast(other); 1017 HChange* change = HChange::cast(other);
975 return value() == change->value() 1018 return value() == change->value()
976 && to().Equals(change->to()); 1019 && to().Equals(change->to());
977 } 1020 }
978 1021
979 private: 1022 private:
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
1485 protected: 1528 protected:
1486 virtual bool DataEquals(HValue* other) { return true; } 1529 virtual bool DataEquals(HValue* other) { return true; }
1487 }; 1530 };
1488 1531
1489 1532
1490 class HBitNot: public HUnaryOperation { 1533 class HBitNot: public HUnaryOperation {
1491 public: 1534 public:
1492 explicit HBitNot(HValue* value) : HUnaryOperation(value) { 1535 explicit HBitNot(HValue* value) : HUnaryOperation(value) {
1493 set_representation(Representation::Integer32()); 1536 set_representation(Representation::Integer32());
1494 SetFlag(kUseGVN); 1537 SetFlag(kUseGVN);
1495 SetFlag(kTruncatingToInt32);
1496 } 1538 }
1497 1539
1498 virtual Representation RequiredInputRepresentation(int index) const { 1540 virtual Representation RequiredInputRepresentation(int index) const {
1499 return Representation::Integer32(); 1541 return Representation::TruncatedInteger32();
1500 } 1542 }
1501 virtual HType CalculateInferredType(); 1543 virtual HType CalculateInferredType();
1502 1544
1503 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not") 1545 DECLARE_CONCRETE_INSTRUCTION(BitNot, "bit_not")
1504 1546
1505 protected: 1547 protected:
1506 virtual bool DataEquals(HValue* other) { return true; } 1548 virtual bool DataEquals(HValue* other) { return true; }
1507 }; 1549 };
1508 1550
1509 1551
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 UNREACHABLE(); 1599 UNREACHABLE();
1558 return Representation::None(); 1600 return Representation::None();
1559 } 1601 }
1560 } 1602 }
1561 1603
1562 virtual HValue* Canonicalize() { 1604 virtual HValue* Canonicalize() {
1563 // If the input is integer32 then we replace the floor instruction 1605 // If the input is integer32 then we replace the floor instruction
1564 // with its inputs. This happens before the representation changes are 1606 // with its inputs. This happens before the representation changes are
1565 // introduced. 1607 // introduced.
1566 if (op() == kMathFloor) { 1608 if (op() == kMathFloor) {
1567 if (value()->representation().IsInteger32()) return value(); 1609 if (value()->representation().IsInteger()) return value();
1568 } 1610 }
1569 return this; 1611 return this;
1570 } 1612 }
1571 1613
1572 BuiltinFunctionId op() const { return op_; } 1614 BuiltinFunctionId op() const { return op_; }
1573 const char* OpName() const; 1615 const char* OpName() const;
1574 1616
1575 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation") 1617 DECLARE_CONCRETE_INSTRUCTION(UnaryMathOperation, "unary_math_operation")
1576 1618
1577 protected: 1619 protected:
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
1875 non_phi_uses_[i] = 0; 1917 non_phi_uses_[i] = 0;
1876 indirect_uses_[i] = 0; 1918 indirect_uses_[i] = 0;
1877 } 1919 }
1878 ASSERT(merged_index >= 0); 1920 ASSERT(merged_index >= 0);
1879 set_representation(Representation::Tagged()); 1921 set_representation(Representation::Tagged());
1880 SetFlag(kFlexibleRepresentation); 1922 SetFlag(kFlexibleRepresentation);
1881 } 1923 }
1882 1924
1883 virtual Representation InferredRepresentation() { 1925 virtual Representation InferredRepresentation() {
1884 bool double_occurred = false; 1926 bool double_occurred = false;
1885 bool int32_occurred = false; 1927 bool int_occurred = false;
1928 Representation int_representation(Representation::None());
1886 for (int i = 0; i < OperandCount(); ++i) { 1929 for (int i = 0; i < OperandCount(); ++i) {
1887 HValue* value = OperandAt(i); 1930 HValue* value = OperandAt(i);
1888 if (value->representation().IsDouble()) double_occurred = true; 1931 if (value->representation().IsDouble()) double_occurred = true;
1889 if (value->representation().IsInteger32()) int32_occurred = true; 1932 if (value->representation().IsInteger()) {
1933 int_occurred = true;
1934 if (int_representation.IsNone()) {
1935 int_representation = value->representation();
1936 } else if (!int_representation.Equals(value->representation())) {
1937 int_representation = Representation::Integer32();
1938 } else {
1939 int_representation = value->representation();
1940 }
1941 }
1890 if (value->representation().IsTagged()) return Representation::Tagged(); 1942 if (value->representation().IsTagged()) return Representation::Tagged();
1891 } 1943 }
1892 1944
1893 if (double_occurred) return Representation::Double(); 1945 if (double_occurred) return Representation::Double();
1894 if (int32_occurred) return Representation::Integer32(); 1946 if (!int_representation.IsNone()) {
1947 return int_representation;
1948 }
1895 return Representation::None(); 1949 return Representation::None();
1896 } 1950 }
1897 1951
1898 virtual Range* InferRange(); 1952 virtual Range* InferRange();
1899 virtual Representation RequiredInputRepresentation(int index) const { 1953 virtual Representation RequiredInputRepresentation(int index) const {
1900 return representation(); 1954 return representation();
1901 } 1955 }
1902 virtual HType CalculateInferredType(); 1956 virtual HType CalculateInferredType();
1903 virtual int OperandCount() { return inputs_.length(); } 1957 virtual int OperandCount() { return inputs_.length(); }
1904 virtual HValue* OperandAt(int index) { return inputs_[index]; } 1958 virtual HValue* OperandAt(int index) { return inputs_[index]; }
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 virtual Representation RequiredInputRepresentation(int index) const { 2043 virtual Representation RequiredInputRepresentation(int index) const {
1990 return Representation::None(); 2044 return Representation::None();
1991 } 2045 }
1992 2046
1993 virtual bool EmitAtUses() { return !representation().IsDouble(); } 2047 virtual bool EmitAtUses() { return !representation().IsDouble(); }
1994 virtual void PrintDataTo(StringStream* stream); 2048 virtual void PrintDataTo(StringStream* stream);
1995 virtual HType CalculateInferredType(); 2049 virtual HType CalculateInferredType();
1996 bool IsInteger() const { return handle_->IsSmi(); } 2050 bool IsInteger() const { return handle_->IsSmi(); }
1997 HConstant* CopyToRepresentation(Representation r) const; 2051 HConstant* CopyToRepresentation(Representation r) const;
1998 HConstant* CopyToTruncatedInt32() const; 2052 HConstant* CopyToTruncatedInt32() const;
2053 HConstant* CopyToClampedRoundedUInt8() const;
1999 bool HasInteger32Value() const { return has_int32_value_; } 2054 bool HasInteger32Value() const { return has_int32_value_; }
2000 int32_t Integer32Value() const { 2055 int32_t Integer32Value() const {
2001 ASSERT(HasInteger32Value()); 2056 ASSERT(HasInteger32Value());
2002 return int32_value_; 2057 return int32_value_;
2003 } 2058 }
2004 bool HasDoubleValue() const { return has_double_value_; } 2059 bool HasDoubleValue() const { return has_double_value_; }
2005 double DoubleValue() const { 2060 double DoubleValue() const {
2006 ASSERT(HasDoubleValue()); 2061 ASSERT(HasDoubleValue());
2007 return double_value_; 2062 return double_value_;
2008 } 2063 }
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
2204 SetFlag(kFlexibleRepresentation); 2259 SetFlag(kFlexibleRepresentation);
2205 SetAllSideEffects(); 2260 SetAllSideEffects();
2206 } 2261 }
2207 2262
2208 virtual Representation RequiredInputRepresentation(int index) const { 2263 virtual Representation RequiredInputRepresentation(int index) const {
2209 return representation(); 2264 return representation();
2210 } 2265 }
2211 2266
2212 virtual void RepresentationChanged(Representation to) { 2267 virtual void RepresentationChanged(Representation to) {
2213 if (!to.IsTagged()) { 2268 if (!to.IsTagged()) {
2214 ASSERT(to.IsInteger32()); 2269 ASSERT(to.IsInteger());
2215 ClearAllSideEffects(); 2270 ClearAllSideEffects();
2216 SetFlag(kTruncatingToInt32);
2217 SetFlag(kUseGVN); 2271 SetFlag(kUseGVN);
2218 } 2272 }
2219 } 2273 }
2220 2274
2221 virtual HType CalculateInferredType(); 2275 virtual HType CalculateInferredType();
2222 2276
2223 DECLARE_INSTRUCTION(BitwiseBinaryOperation) 2277 DECLARE_INSTRUCTION(BitwiseBinaryOperation)
2224 }; 2278 };
2225 2279
2226 2280
(...skipping 1159 matching lines...) Expand 10 before | Expand all | Expand 10 after
3386 SetOperandAt(0, external_elements); 3440 SetOperandAt(0, external_elements);
3387 SetOperandAt(1, key); 3441 SetOperandAt(1, key);
3388 SetOperandAt(2, val); 3442 SetOperandAt(2, val);
3389 } 3443 }
3390 3444
3391 virtual void PrintDataTo(StringStream* stream); 3445 virtual void PrintDataTo(StringStream* stream);
3392 3446
3393 virtual Representation RequiredInputRepresentation(int index) const { 3447 virtual Representation RequiredInputRepresentation(int index) const {
3394 if (index == 0) { 3448 if (index == 0) {
3395 return Representation::External(); 3449 return Representation::External();
3450 } else if (index == 2) {
3451 if (array_type_ == kExternalFloatArray) {
3452 return Representation::Double();
3453 } else if (array_type_ == kExternalPixelArray) {
3454 return Representation::ClampedRoundedUInteger8();
3455 } else {
3456 return Representation::TruncatedInteger32();
3457 }
3396 } else { 3458 } else {
3397 if (index == 2 && array_type() == kExternalFloatArray) { 3459 return Representation::Integer32();
3398 return Representation::Double();
3399 } else {
3400 return Representation::Integer32();
3401 }
3402 } 3460 }
3403 } 3461 }
3404 3462
3405 HValue* external_pointer() { return OperandAt(0); } 3463 HValue* external_pointer() { return OperandAt(0); }
3406 HValue* key() { return OperandAt(1); } 3464 HValue* key() { return OperandAt(1); }
3407 HValue* value() { return OperandAt(2); } 3465 HValue* value() { return OperandAt(2); }
3408 ExternalArrayType array_type() const { return array_type_; } 3466 ExternalArrayType array_type() const { return array_type_; }
3409 3467
3410 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement, 3468 DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement,
3411 "store_keyed_specialized_array_element") 3469 "store_keyed_specialized_array_element")
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
3733 HValue* object() { return left(); } 3791 HValue* object() { return left(); }
3734 HValue* key() { return right(); } 3792 HValue* key() { return right(); }
3735 }; 3793 };
3736 3794
3737 #undef DECLARE_INSTRUCTION 3795 #undef DECLARE_INSTRUCTION
3738 #undef DECLARE_CONCRETE_INSTRUCTION 3796 #undef DECLARE_CONCRETE_INSTRUCTION
3739 3797
3740 } } // namespace v8::internal 3798 } } // namespace v8::internal
3741 3799
3742 #endif // V8_HYDROGEN_INSTRUCTIONS_H_ 3800 #endif // V8_HYDROGEN_INSTRUCTIONS_H_
OLDNEW
« src/hydrogen.cc ('K') | « src/hydrogen.cc ('k') | src/hydrogen-instructions.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698