OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <iomanip> | 5 #include <iomanip> |
6 | 6 |
7 #include "src/compiler/types.h" | 7 #include "src/compiler/types.h" |
8 | 8 |
9 #include "src/handles-inl.h" | 9 #include "src/handles-inl.h" |
10 #include "src/ostreams.h" | 10 #include "src/ostreams.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
65 bool Type::Contains(RangeType* range, i::Object* val) { | 65 bool Type::Contains(RangeType* range, i::Object* val) { |
66 DisallowHeapAllocation no_allocation; | 66 DisallowHeapAllocation no_allocation; |
67 return IsInteger(val) && range->Min() <= val->Number() && | 67 return IsInteger(val) && range->Min() <= val->Number() && |
68 val->Number() <= range->Max(); | 68 val->Number() <= range->Max(); |
69 } | 69 } |
70 | 70 |
71 // ----------------------------------------------------------------------------- | 71 // ----------------------------------------------------------------------------- |
72 // Min and Max computation. | 72 // Min and Max computation. |
73 | 73 |
74 double Type::Min() { | 74 double Type::Min() { |
75 DCHECK(this->SemanticIs(Number())); | 75 DCHECK(this->Is(Number())); |
76 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); | 76 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); |
77 if (this->IsUnion()) { | 77 if (this->IsUnion()) { |
78 double min = +V8_INFINITY; | 78 double min = +V8_INFINITY; |
79 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 79 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
80 min = std::min(min, this->AsUnion()->Get(i)->Min()); | 80 min = std::min(min, this->AsUnion()->Get(i)->Min()); |
81 } | 81 } |
82 return min; | 82 return min; |
83 } | 83 } |
84 if (this->IsRange()) return this->AsRange()->Min(); | 84 if (this->IsRange()) return this->AsRange()->Min(); |
85 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 85 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
86 UNREACHABLE(); | 86 UNREACHABLE(); |
87 return 0; | 87 return 0; |
88 } | 88 } |
89 | 89 |
90 double Type::Max() { | 90 double Type::Max() { |
91 DCHECK(this->SemanticIs(Number())); | 91 DCHECK(this->Is(Number())); |
92 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); | 92 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); |
93 if (this->IsUnion()) { | 93 if (this->IsUnion()) { |
94 double max = -V8_INFINITY; | 94 double max = -V8_INFINITY; |
95 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 95 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
96 max = std::max(max, this->AsUnion()->Get(i)->Max()); | 96 max = std::max(max, this->AsUnion()->Get(i)->Max()); |
97 } | 97 } |
98 return max; | 98 return max; |
99 } | 99 } |
100 if (this->IsRange()) return this->AsRange()->Max(); | 100 if (this->IsRange()) return this->AsRange()->Max(); |
101 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); | 101 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); |
102 UNREACHABLE(); | 102 UNREACHABLE(); |
103 return 0; | 103 return 0; |
104 } | 104 } |
105 | 105 |
106 // ----------------------------------------------------------------------------- | 106 // ----------------------------------------------------------------------------- |
107 // Glb and lub computation. | 107 // Glb and lub computation. |
108 | 108 |
109 // The largest bitset subsumed by this type. | 109 // The largest bitset subsumed by this type. |
110 Type::bitset BitsetType::Glb(Type* type) { | 110 Type::bitset BitsetType::Glb(Type* type) { |
111 DisallowHeapAllocation no_allocation; | 111 DisallowHeapAllocation no_allocation; |
112 // Fast case. | 112 // Fast case. |
113 if (IsBitset(type)) { | 113 if (IsBitset(type)) { |
114 return type->AsBitset(); | 114 return type->AsBitset(); |
115 } else if (type->IsUnion()) { | 115 } else if (type->IsUnion()) { |
116 SLOW_DCHECK(type->AsUnion()->Wellformed()); | 116 SLOW_DCHECK(type->AsUnion()->Wellformed()); |
117 return type->AsUnion()->Get(0)->BitsetGlb() | | 117 return type->AsUnion()->Get(0)->BitsetGlb() | |
118 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut. | 118 type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut. |
119 } else if (type->IsRange()) { | 119 } else if (type->IsRange()) { |
120 bitset glb = SEMANTIC( | 120 bitset glb = |
121 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); | 121 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()); |
122 return glb; | 122 return glb; |
123 } else { | 123 } else { |
124 return kNone; | 124 return kNone; |
125 } | 125 } |
126 } | 126 } |
127 | 127 |
128 // The smallest bitset subsuming this type, possibly not a proper one. | 128 // The smallest bitset subsuming this type, possibly not a proper one. |
129 Type::bitset BitsetType::Lub(Type* type) { | 129 Type::bitset BitsetType::Lub(Type* type) { |
130 DisallowHeapAllocation no_allocation; | 130 DisallowHeapAllocation no_allocation; |
131 if (IsBitset(type)) return type->AsBitset(); | 131 if (IsBitset(type)) return type->AsBitset(); |
132 if (type->IsUnion()) { | 132 if (type->IsUnion()) { |
133 // Take the representation from the first element, which is always | 133 // Take the representation from the first element, which is always |
134 // a bitset. | 134 // a bitset. |
135 int bitset = type->AsUnion()->Get(0)->BitsetLub(); | 135 int bitset = type->AsUnion()->Get(0)->BitsetLub(); |
136 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 136 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
137 // Other elements only contribute their semantic part. | 137 // Other elements only contribute their semantic part. |
138 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub()); | 138 bitset |= type->AsUnion()->Get(i)->BitsetLub(); |
139 } | 139 } |
140 return bitset; | 140 return bitset; |
141 } | 141 } |
142 if (type->IsConstant()) return type->AsConstant()->Lub(); | 142 if (type->IsConstant()) return type->AsConstant()->Lub(); |
143 if (type->IsRange()) return type->AsRange()->Lub(); | 143 if (type->IsRange()) return type->AsRange()->Lub(); |
144 if (type->IsTuple()) return kOtherInternal; | 144 if (type->IsTuple()) return kOtherInternal; |
145 UNREACHABLE(); | 145 UNREACHABLE(); |
146 return kNone; | 146 return kNone; |
147 } | 147 } |
148 | 148 |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; } | 308 const BitsetType::Boundary* BitsetType::Boundaries() { return BoundariesArray; } |
309 | 309 |
310 size_t BitsetType::BoundariesSize() { | 310 size_t BitsetType::BoundariesSize() { |
311 // Windows doesn't like arraysize here. | 311 // Windows doesn't like arraysize here. |
312 // return arraysize(BoundariesArray); | 312 // return arraysize(BoundariesArray); |
313 return 7; | 313 return 7; |
314 } | 314 } |
315 | 315 |
316 Type::bitset BitsetType::ExpandInternals(Type::bitset bits) { | 316 Type::bitset BitsetType::ExpandInternals(Type::bitset bits) { |
317 DisallowHeapAllocation no_allocation; | 317 DisallowHeapAllocation no_allocation; |
318 if (!(bits & SEMANTIC(kPlainNumber))) return bits; // Shortcut. | 318 if (!(bits & kPlainNumber)) return bits; // Shortcut. |
319 const Boundary* boundaries = Boundaries(); | 319 const Boundary* boundaries = Boundaries(); |
320 for (size_t i = 0; i < BoundariesSize(); ++i) { | 320 for (size_t i = 0; i < BoundariesSize(); ++i) { |
321 DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external)); | 321 DCHECK(BitsetType::Is(boundaries[i].internal, boundaries[i].external)); |
322 if (bits & SEMANTIC(boundaries[i].internal)) | 322 if (bits & boundaries[i].internal) bits |= boundaries[i].external; |
323 bits |= SEMANTIC(boundaries[i].external); | |
324 } | 323 } |
325 return bits; | 324 return bits; |
326 } | 325 } |
327 | 326 |
328 Type::bitset BitsetType::Lub(double min, double max) { | 327 Type::bitset BitsetType::Lub(double min, double max) { |
329 DisallowHeapAllocation no_allocation; | 328 DisallowHeapAllocation no_allocation; |
330 int lub = kNone; | 329 int lub = kNone; |
331 const Boundary* mins = Boundaries(); | 330 const Boundary* mins = Boundaries(); |
332 | 331 |
333 for (size_t i = 1; i < BoundariesSize(); ++i) { | 332 for (size_t i = 1; i < BoundariesSize(); ++i) { |
334 if (min < mins[i].min) { | 333 if (min < mins[i].min) { |
335 lub |= mins[i - 1].internal; | 334 lub |= mins[i - 1].internal; |
336 if (max < mins[i].min) return lub; | 335 if (max < mins[i].min) return lub; |
337 } | 336 } |
338 } | 337 } |
339 return lub | mins[BoundariesSize() - 1].internal; | 338 return lub | mins[BoundariesSize() - 1].internal; |
340 } | 339 } |
341 | 340 |
342 Type::bitset BitsetType::NumberBits(bitset bits) { | 341 Type::bitset BitsetType::NumberBits(bitset bits) { return bits & kPlainNumber; } |
343 return SEMANTIC(bits & kPlainNumber); | |
344 } | |
345 | 342 |
346 Type::bitset BitsetType::Glb(double min, double max) { | 343 Type::bitset BitsetType::Glb(double min, double max) { |
347 DisallowHeapAllocation no_allocation; | 344 DisallowHeapAllocation no_allocation; |
348 int glb = kNone; | 345 int glb = kNone; |
349 const Boundary* mins = Boundaries(); | 346 const Boundary* mins = Boundaries(); |
350 | 347 |
351 // If the range does not touch 0, the bound is empty. | 348 // If the range does not touch 0, the bound is empty. |
352 if (max < -1 || min > 0) return glb; | 349 if (max < -1 || min > 0) return glb; |
353 | 350 |
354 for (size_t i = 1; i + 1 < BoundariesSize(); ++i) { | 351 for (size_t i = 1; i + 1 < BoundariesSize(); ++i) { |
355 if (min <= mins[i].min) { | 352 if (min <= mins[i].min) { |
356 if (max + 1 < mins[i + 1].min) break; | 353 if (max + 1 < mins[i + 1].min) break; |
357 glb |= mins[i].external; | 354 glb |= mins[i].external; |
358 } | 355 } |
359 } | 356 } |
360 // OtherNumber also contains float numbers, so it can never be | 357 // OtherNumber also contains float numbers, so it can never be |
361 // in the greatest lower bound. | 358 // in the greatest lower bound. |
362 return glb & ~(SEMANTIC(kOtherNumber)); | 359 return glb & ~(kOtherNumber); |
363 } | 360 } |
364 | 361 |
365 double BitsetType::Min(bitset bits) { | 362 double BitsetType::Min(bitset bits) { |
366 DisallowHeapAllocation no_allocation; | 363 DisallowHeapAllocation no_allocation; |
367 DCHECK(Is(SEMANTIC(bits), kNumber)); | 364 DCHECK(Is(bits, kNumber)); |
368 const Boundary* mins = Boundaries(); | 365 const Boundary* mins = Boundaries(); |
369 bool mz = SEMANTIC(bits & kMinusZero); | 366 bool mz = bits & kMinusZero; |
370 for (size_t i = 0; i < BoundariesSize(); ++i) { | 367 for (size_t i = 0; i < BoundariesSize(); ++i) { |
371 if (Is(SEMANTIC(mins[i].internal), bits)) { | 368 if (Is(mins[i].internal, bits)) { |
372 return mz ? std::min(0.0, mins[i].min) : mins[i].min; | 369 return mz ? std::min(0.0, mins[i].min) : mins[i].min; |
373 } | 370 } |
374 } | 371 } |
375 if (mz) return 0; | 372 if (mz) return 0; |
376 return std::numeric_limits<double>::quiet_NaN(); | 373 return std::numeric_limits<double>::quiet_NaN(); |
377 } | 374 } |
378 | 375 |
379 double BitsetType::Max(bitset bits) { | 376 double BitsetType::Max(bitset bits) { |
380 DisallowHeapAllocation no_allocation; | 377 DisallowHeapAllocation no_allocation; |
381 DCHECK(Is(SEMANTIC(bits), kNumber)); | 378 DCHECK(Is(bits, kNumber)); |
382 const Boundary* mins = Boundaries(); | 379 const Boundary* mins = Boundaries(); |
383 bool mz = SEMANTIC(bits & kMinusZero); | 380 bool mz = bits & kMinusZero; |
384 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].internal), bits)) { | 381 if (BitsetType::Is(mins[BoundariesSize() - 1].internal, bits)) { |
385 return +V8_INFINITY; | 382 return +V8_INFINITY; |
386 } | 383 } |
387 for (size_t i = BoundariesSize() - 1; i-- > 0;) { | 384 for (size_t i = BoundariesSize() - 1; i-- > 0;) { |
388 if (Is(SEMANTIC(mins[i].internal), bits)) { | 385 if (Is(mins[i].internal, bits)) { |
389 return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1; | 386 return mz ? std::max(0.0, mins[i + 1].min - 1) : mins[i + 1].min - 1; |
390 } | 387 } |
391 } | 388 } |
392 if (mz) return 0; | 389 if (mz) return 0; |
393 return std::numeric_limits<double>::quiet_NaN(); | 390 return std::numeric_limits<double>::quiet_NaN(); |
394 } | 391 } |
395 | 392 |
396 // ----------------------------------------------------------------------------- | 393 // ----------------------------------------------------------------------------- |
397 // Predicates. | 394 // Predicates. |
398 | 395 |
(...skipping 25 matching lines...) Expand all Loading... | |
424 | 421 |
425 // Fast bitset cases | 422 // Fast bitset cases |
426 if (that->IsBitset()) { | 423 if (that->IsBitset()) { |
427 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); | 424 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); |
428 } | 425 } |
429 | 426 |
430 if (this->IsBitset()) { | 427 if (this->IsBitset()) { |
431 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); | 428 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); |
432 } | 429 } |
433 | 430 |
434 // Check the semantic part. | |
435 return SemanticIs(that); | |
436 } | |
437 | |
438 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method | |
439 // should be independent of the representation axis of the types. | |
440 bool Type::SemanticIs(Type* that) { | |
441 DisallowHeapAllocation no_allocation; | |
442 | |
443 if (this == that) return true; | |
444 | |
445 if (that->IsBitset()) { | |
446 return BitsetType::Is(SEMANTIC(this->BitsetLub()), that->AsBitset()); | |
447 } | |
448 if (this->IsBitset()) { | |
449 return BitsetType::Is(SEMANTIC(this->AsBitset()), that->BitsetGlb()); | |
450 } | |
451 | |
452 // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T) | 431 // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T) |
453 if (this->IsUnion()) { | 432 if (this->IsUnion()) { |
454 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 433 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
455 if (!this->AsUnion()->Get(i)->SemanticIs(that)) return false; | 434 if (!this->AsUnion()->Get(i)->Is(that)) return false; |
456 } | 435 } |
457 return true; | 436 return true; |
458 } | 437 } |
459 | 438 |
460 // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn) | 439 // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn) |
461 if (that->IsUnion()) { | 440 if (that->IsUnion()) { |
462 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { | 441 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { |
463 if (this->SemanticIs(that->AsUnion()->Get(i))) return true; | 442 if (this->Is(that->AsUnion()->Get(i))) return true; |
464 if (i > 1 && this->IsRange()) return false; // Shortcut. | 443 if (i > 1 && this->IsRange()) return false; // Shortcut. |
465 } | 444 } |
466 return false; | 445 return false; |
467 } | 446 } |
468 | 447 |
469 if (that->IsRange()) { | 448 if (that->IsRange()) { |
470 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || | 449 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || |
471 (this->IsConstant() && | 450 (this->IsConstant() && |
472 Contains(that->AsRange(), this->AsConstant())); | 451 Contains(that->AsRange(), this->AsConstant())); |
473 } | 452 } |
474 if (this->IsRange()) return false; | 453 if (this->IsRange()) return false; |
475 | 454 |
476 return this->SimplyEquals(that); | 455 return this->SimplyEquals(that); |
477 } | 456 } |
478 | 457 |
479 // Check if [this] and [that] overlap. | 458 // Check if [this] and [that] overlap. |
480 bool Type::Maybe(Type* that) { | 459 bool Type::Maybe(Type* that) { |
481 DisallowHeapAllocation no_allocation; | 460 DisallowHeapAllocation no_allocation; |
482 | 461 |
483 // Take care of the representation part (and also approximate | |
484 // the semantic part). | |
485 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) | 462 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) |
486 return false; | 463 return false; |
487 | 464 |
488 return SemanticMaybe(that); | |
489 } | |
490 | |
491 bool Type::SemanticMaybe(Type* that) { | |
492 DisallowHeapAllocation no_allocation; | |
493 | |
494 // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T) | 465 // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T) |
495 if (this->IsUnion()) { | 466 if (this->IsUnion()) { |
496 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 467 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
497 if (this->AsUnion()->Get(i)->SemanticMaybe(that)) return true; | 468 if (this->AsUnion()->Get(i)->Maybe(that)) return true; |
498 } | 469 } |
499 return false; | 470 return false; |
500 } | 471 } |
501 | 472 |
502 // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn) | 473 // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn) |
503 if (that->IsUnion()) { | 474 if (that->IsUnion()) { |
504 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { | 475 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { |
505 if (this->SemanticMaybe(that->AsUnion()->Get(i))) return true; | 476 if (this->Maybe(that->AsUnion()->Get(i))) return true; |
506 } | 477 } |
507 return false; | 478 return false; |
508 } | 479 } |
509 | 480 |
510 if (!BitsetType::SemanticIsInhabited(this->BitsetLub() & that->BitsetLub())) | |
511 return false; | |
512 | |
513 if (this->IsBitset() && that->IsBitset()) return true; | 481 if (this->IsBitset() && that->IsBitset()) return true; |
514 | 482 |
515 if (this->IsRange()) { | 483 if (this->IsRange()) { |
516 if (that->IsConstant()) { | 484 if (that->IsConstant()) { |
517 return Contains(this->AsRange(), that->AsConstant()); | 485 return Contains(this->AsRange(), that->AsConstant()); |
518 } | 486 } |
519 if (that->IsRange()) { | 487 if (that->IsRange()) { |
520 return Overlap(this->AsRange(), that->AsRange()); | 488 return Overlap(this->AsRange(), that->AsRange()); |
521 } | 489 } |
522 if (that->IsBitset()) { | 490 if (that->IsBitset()) { |
523 bitset number_bits = BitsetType::NumberBits(that->AsBitset()); | 491 bitset number_bits = BitsetType::NumberBits(that->AsBitset()); |
524 if (number_bits == BitsetType::kNone) { | 492 if (number_bits == BitsetType::kNone) { |
525 return false; | 493 return false; |
526 } | 494 } |
527 double min = std::max(BitsetType::Min(number_bits), this->Min()); | 495 double min = std::max(BitsetType::Min(number_bits), this->Min()); |
528 double max = std::min(BitsetType::Max(number_bits), this->Max()); | 496 double max = std::min(BitsetType::Max(number_bits), this->Max()); |
529 return min <= max; | 497 return min <= max; |
530 } | 498 } |
531 } | 499 } |
532 if (that->IsRange()) { | 500 if (that->IsRange()) { |
533 return that->SemanticMaybe(this); // This case is handled above. | 501 return that->Maybe(this); // This case is handled above. |
534 } | 502 } |
535 | 503 |
536 if (this->IsBitset() || that->IsBitset()) return true; | 504 if (this->IsBitset() || that->IsBitset()) return true; |
537 | 505 |
538 return this->SimplyEquals(that); | 506 return this->SimplyEquals(that); |
539 } | 507 } |
540 | 508 |
541 // Return the range in [this], or [NULL]. | 509 // Return the range in [this], or [NULL]. |
542 Type* Type::GetRange() { | 510 Type* Type::GetRange() { |
543 DisallowHeapAllocation no_allocation; | 511 DisallowHeapAllocation no_allocation; |
(...skipping 27 matching lines...) Expand all Loading... | |
571 // 6. If there is a range, then the bitset type does not contain | 539 // 6. If there is a range, then the bitset type does not contain |
572 // plain number bits. | 540 // plain number bits. |
573 DCHECK(this->Length() >= 2); // (1) | 541 DCHECK(this->Length() >= 2); // (1) |
574 DCHECK(this->Get(0)->IsBitset()); // (2a) | 542 DCHECK(this->Get(0)->IsBitset()); // (2a) |
575 | 543 |
576 for (int i = 0; i < this->Length(); ++i) { | 544 for (int i = 0; i < this->Length(); ++i) { |
577 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b) | 545 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b) |
578 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) | 546 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) |
579 DCHECK(!this->Get(i)->IsUnion()); // (4) | 547 DCHECK(!this->Get(i)->IsUnion()); // (4) |
580 for (int j = 0; j < this->Length(); ++j) { | 548 for (int j = 0; j < this->Length(); ++j) { |
581 if (i != j && i != 0) | 549 if (i != j && i != 0) DCHECK(!this->Get(i)->Is(this->Get(j))); // (5) |
582 DCHECK(!this->Get(i)->SemanticIs(this->Get(j))); // (5) | |
583 } | 550 } |
584 } | 551 } |
585 DCHECK(!this->Get(1)->IsRange() || | 552 DCHECK(!this->Get(1)->IsRange() || |
586 (BitsetType::NumberBits(this->Get(0)->AsBitset()) == | 553 (BitsetType::NumberBits(this->Get(0)->AsBitset()) == |
587 BitsetType::kNone)); // (6) | 554 BitsetType::kNone)); // (6) |
588 return true; | 555 return true; |
589 } | 556 } |
590 | 557 |
591 // ----------------------------------------------------------------------------- | 558 // ----------------------------------------------------------------------------- |
592 // Union and intersection | 559 // Union and intersection |
(...skipping 14 matching lines...) Expand all Loading... | |
607 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. | 574 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. |
608 | 575 |
609 // Semi-fast case. | 576 // Semi-fast case. |
610 if (type1->Is(type2)) return type1; | 577 if (type1->Is(type2)) return type1; |
611 if (type2->Is(type1)) return type2; | 578 if (type2->Is(type1)) return type2; |
612 | 579 |
613 // Slow case: create union. | 580 // Slow case: create union. |
614 | 581 |
615 // Semantic subtyping check - this is needed for consistency with the | 582 // Semantic subtyping check - this is needed for consistency with the |
616 // semi-fast case above. | 583 // semi-fast case above. |
617 if (type1->SemanticIs(type2)) { | 584 if (type1->Is(type2)) { |
618 type2 = Any(); | 585 type2 = Any(); |
619 } else if (type2->SemanticIs(type1)) { | 586 } else if (type2->Is(type1)) { |
620 type1 = Any(); | 587 type1 = Any(); |
621 } | 588 } |
622 | 589 |
623 bitset bits = SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()); | 590 bitset bits = type1->BitsetGlb() & type2->BitsetGlb(); |
624 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; | 591 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; |
625 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 592 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
626 if (!AddIsSafe(size1, size2)) return Any(); | 593 if (!AddIsSafe(size1, size2)) return Any(); |
627 int size = size1 + size2; | 594 int size = size1 + size2; |
628 if (!AddIsSafe(size, 2)) return Any(); | 595 if (!AddIsSafe(size, 2)) return Any(); |
629 size += 2; | 596 size += 2; |
630 Type* result_type = UnionType::New(size, zone); | 597 Type* result_type = UnionType::New(size, zone); |
631 UnionType* result = result_type->AsUnion(); | 598 UnionType* result = result_type->AsUnion(); |
632 size = 0; | 599 size = 0; |
633 | 600 |
(...skipping 20 matching lines...) Expand all Loading... | |
654 if (size == 1) { | 621 if (size == 1) { |
655 result->Set(size++, range); | 622 result->Set(size++, range); |
656 } else { | 623 } else { |
657 // Make space for the range. | 624 // Make space for the range. |
658 result->Set(size++, result->Get(1)); | 625 result->Set(size++, result->Get(1)); |
659 result->Set(1, range); | 626 result->Set(1, range); |
660 } | 627 } |
661 | 628 |
662 // Remove any components that just got subsumed. | 629 // Remove any components that just got subsumed. |
663 for (int i = 2; i < size;) { | 630 for (int i = 2; i < size;) { |
664 if (result->Get(i)->SemanticIs(range)) { | 631 if (result->Get(i)->Is(range)) { |
665 result->Set(i, result->Get(--size)); | 632 result->Set(i, result->Get(--size)); |
666 } else { | 633 } else { |
667 ++i; | 634 ++i; |
668 } | 635 } |
669 } | 636 } |
670 return size; | 637 return size; |
671 } | 638 } |
672 | 639 |
673 RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) { | 640 RangeType::Limits Type::ToLimits(bitset bits, Zone* zone) { |
674 bitset number_bits = BitsetType::NumberBits(bits); | 641 bitset number_bits = BitsetType::NumberBits(bits); |
(...skipping 23 matching lines...) Expand all Loading... | |
698 return size; | 665 return size; |
699 } | 666 } |
700 if (rhs->IsUnion()) { | 667 if (rhs->IsUnion()) { |
701 for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) { | 668 for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) { |
702 size = | 669 size = |
703 IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone); | 670 IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, zone); |
704 } | 671 } |
705 return size; | 672 return size; |
706 } | 673 } |
707 | 674 |
708 if (!BitsetType::SemanticIsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { | 675 if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { |
709 return size; | 676 return size; |
710 } | 677 } |
711 | 678 |
712 if (lhs->IsRange()) { | 679 if (lhs->IsRange()) { |
713 if (rhs->IsBitset()) { | 680 if (rhs->IsBitset()) { |
714 RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone); | 681 RangeType::Limits lim = IntersectRangeAndBitset(lhs, rhs, zone); |
715 | 682 |
716 if (!lim.IsEmpty()) { | 683 if (!lim.IsEmpty()) { |
717 *lims = RangeType::Limits::Union(lim, *lims); | 684 *lims = RangeType::Limits::Union(lim, *lims); |
718 } | 685 } |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
750 Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) { | 717 Type* Type::NormalizeRangeAndBitset(Type* range, bitset* bits, Zone* zone) { |
751 // Fast path: If the bitset does not mention numbers, we can just keep the | 718 // Fast path: If the bitset does not mention numbers, we can just keep the |
752 // range. | 719 // range. |
753 bitset number_bits = BitsetType::NumberBits(*bits); | 720 bitset number_bits = BitsetType::NumberBits(*bits); |
754 if (number_bits == 0) { | 721 if (number_bits == 0) { |
755 return range; | 722 return range; |
756 } | 723 } |
757 | 724 |
758 // If the range is semantically contained within the bitset, return None and | 725 // If the range is semantically contained within the bitset, return None and |
759 // leave the bitset untouched. | 726 // leave the bitset untouched. |
760 bitset range_lub = SEMANTIC(range->BitsetLub()); | 727 bitset range_lub = range->BitsetLub(); |
761 if (BitsetType::Is(range_lub, *bits)) { | 728 if (BitsetType::Is(range_lub, *bits)) { |
762 return None(); | 729 return None(); |
763 } | 730 } |
764 | 731 |
765 // Slow path: reconcile the bitset range and the range. | 732 // Slow path: reconcile the bitset range and the range. |
766 double bitset_min = BitsetType::Min(number_bits); | 733 double bitset_min = BitsetType::Min(number_bits); |
767 double bitset_max = BitsetType::Max(number_bits); | 734 double bitset_max = BitsetType::Max(number_bits); |
768 | 735 |
769 double range_min = range->Min(); | 736 double range_min = range->Min(); |
770 double range_max = range->Max(); | 737 double range_max = range->Max(); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
807 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; | 774 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; |
808 if (!AddIsSafe(size1, size2)) return Any(); | 775 if (!AddIsSafe(size1, size2)) return Any(); |
809 int size = size1 + size2; | 776 int size = size1 + size2; |
810 if (!AddIsSafe(size, 2)) return Any(); | 777 if (!AddIsSafe(size, 2)) return Any(); |
811 size += 2; | 778 size += 2; |
812 Type* result_type = UnionType::New(size, zone); | 779 Type* result_type = UnionType::New(size, zone); |
813 UnionType* result = result_type->AsUnion(); | 780 UnionType* result = result_type->AsUnion(); |
814 size = 0; | 781 size = 0; |
815 | 782 |
816 // Compute the new bitset. | 783 // Compute the new bitset. |
817 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb()); | 784 bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb(); |
818 | 785 |
819 // Deal with ranges. | 786 // Deal with ranges. |
820 Type* range = None(); | 787 Type* range = None(); |
821 Type* range1 = type1->GetRange(); | 788 Type* range1 = type1->GetRange(); |
822 Type* range2 = type2->GetRange(); | 789 Type* range2 = type2->GetRange(); |
823 if (range1 != NULL && range2 != NULL) { | 790 if (range1 != NULL && range2 != NULL) { |
824 RangeType::Limits lims = | 791 RangeType::Limits lims = |
825 RangeType::Limits::Union(RangeType::Limits(range1->AsRange()), | 792 RangeType::Limits::Union(RangeType::Limits(range1->AsRange()), |
826 RangeType::Limits(range2->AsRange())); | 793 RangeType::Limits(range2->AsRange())); |
827 Type* union_range = RangeType::New(lims, zone); | 794 Type* union_range = RangeType::New(lims, zone); |
828 range = NormalizeRangeAndBitset(union_range, &new_bitset, zone); | 795 range = NormalizeRangeAndBitset(union_range, &new_bitset, zone); |
829 } else if (range1 != NULL) { | 796 } else if (range1 != NULL) { |
830 range = NormalizeRangeAndBitset(range1, &new_bitset, zone); | 797 range = NormalizeRangeAndBitset(range1, &new_bitset, zone); |
831 } else if (range2 != NULL) { | 798 } else if (range2 != NULL) { |
832 range = NormalizeRangeAndBitset(range2, &new_bitset, zone); | 799 range = NormalizeRangeAndBitset(range2, &new_bitset, zone); |
833 } | 800 } |
834 new_bitset = SEMANTIC(new_bitset); | |
835 Type* bits = BitsetType::New(new_bitset); | 801 Type* bits = BitsetType::New(new_bitset); |
836 result->Set(size++, bits); | 802 result->Set(size++, bits); |
837 if (!range->IsNone()) result->Set(size++, range); | 803 if (!range->IsNone()) result->Set(size++, range); |
838 | 804 |
839 size = AddToUnion(type1, result, size, zone); | 805 size = AddToUnion(type1, result, size, zone); |
840 size = AddToUnion(type2, result, size, zone); | 806 size = AddToUnion(type2, result, size, zone); |
841 return NormalizeUnion(result_type, size, zone); | 807 return NormalizeUnion(result_type, size, zone); |
842 } | 808 } |
843 | 809 |
844 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. | 810 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. |
845 // Return new size of [result]. | 811 // Return new size of [result]. |
846 int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) { | 812 int Type::AddToUnion(Type* type, UnionType* result, int size, Zone* zone) { |
847 if (type->IsBitset() || type->IsRange()) return size; | 813 if (type->IsBitset() || type->IsRange()) return size; |
848 if (type->IsUnion()) { | 814 if (type->IsUnion()) { |
849 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { | 815 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { |
850 size = AddToUnion(type->AsUnion()->Get(i), result, size, zone); | 816 size = AddToUnion(type->AsUnion()->Get(i), result, size, zone); |
851 } | 817 } |
852 return size; | 818 return size; |
853 } | 819 } |
854 for (int i = 0; i < size; ++i) { | 820 for (int i = 0; i < size; ++i) { |
855 if (type->SemanticIs(result->Get(i))) return size; | 821 if (type->Is(result->Get(i))) return size; |
856 } | 822 } |
857 result->Set(size++, type); | 823 result->Set(size++, type); |
858 return size; | 824 return size; |
859 } | 825 } |
860 | 826 |
861 Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) { | 827 Type* Type::NormalizeUnion(Type* union_type, int size, Zone* zone) { |
862 UnionType* unioned = union_type->AsUnion(); | 828 UnionType* unioned = union_type->AsUnion(); |
863 DCHECK(size >= 1); | 829 DCHECK(size >= 1); |
864 DCHECK(unioned->Get(0)->IsBitset()); | 830 DCHECK(unioned->Get(0)->IsBitset()); |
865 // If the union has just one element, return it. | 831 // If the union has just one element, return it. |
866 if (size == 1) { | 832 if (size == 1) { |
867 return unioned->Get(0); | 833 return unioned->Get(0); |
868 } | 834 } |
869 bitset bits = unioned->Get(0)->AsBitset(); | 835 bitset bits = unioned->Get(0)->AsBitset(); |
870 // If the union only consists of a range, we can get rid of the union. | 836 // If the union only consists of a range, we can get rid of the union. |
871 if (size == 2 && SEMANTIC(bits) == BitsetType::kNone) { | 837 if (size == 2 && bits == BitsetType::kNone) { |
872 if (unioned->Get(1)->IsRange()) { | 838 if (unioned->Get(1)->IsRange()) { |
873 return RangeType::New(unioned->Get(1)->AsRange()->Min(), | 839 return RangeType::New(unioned->Get(1)->AsRange()->Min(), |
874 unioned->Get(1)->AsRange()->Max(), zone); | 840 unioned->Get(1)->AsRange()->Max(), zone); |
875 } | 841 } |
876 } | 842 } |
877 unioned->Shrink(size); | 843 unioned->Shrink(size); |
878 SLOW_DCHECK(unioned->Wellformed()); | 844 SLOW_DCHECK(unioned->Wellformed()); |
879 return union_type; | 845 return union_type; |
880 } | 846 } |
881 | 847 |
882 // ----------------------------------------------------------------------------- | 848 // ----------------------------------------------------------------------------- |
883 // Component extraction | |
884 | |
885 // static | |
886 Type* Type::Semantic(Type* t, Zone* zone) { | |
887 return Intersect(t, BitsetType::New(BitsetType::kSemantic), zone); | |
888 } | |
889 | |
890 // ----------------------------------------------------------------------------- | |
891 // Iteration. | 849 // Iteration. |
892 | 850 |
893 int Type::NumConstants() { | 851 int Type::NumConstants() { |
894 DisallowHeapAllocation no_allocation; | 852 DisallowHeapAllocation no_allocation; |
895 if (this->IsConstant()) { | 853 if (this->IsConstant()) { |
896 return 1; | 854 return 1; |
897 } else if (this->IsUnion()) { | 855 } else if (this->IsUnion()) { |
898 int result = 0; | 856 int result = 0; |
899 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { | 857 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { |
900 if (this->AsUnion()->Get(i)->IsConstant()) ++result; | 858 if (this->AsUnion()->Get(i)->IsConstant()) ++result; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
949 return; | 907 return; |
950 } | 908 } |
951 index_ = -1; | 909 index_ = -1; |
952 } | 910 } |
953 | 911 |
954 // ----------------------------------------------------------------------------- | 912 // ----------------------------------------------------------------------------- |
955 // Printing. | 913 // Printing. |
956 | 914 |
957 const char* BitsetType::Name(bitset bits) { | 915 const char* BitsetType::Name(bitset bits) { |
958 switch (bits) { | 916 switch (bits) { |
959 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ | 917 #define RETURN_NAMED_SEMANTIC_TYPE(type, value) \ |
Jarin
2016/09/23 09:23:39
RETURN_NAMED_TYPE?
mvstanton
2016/09/23 11:23:57
Done.
| |
960 case SEMANTIC(k##type): \ | 918 case k##type: \ |
961 return #type; | 919 return #type; |
962 SEMANTIC_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 920 NONINTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
963 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) | 921 INTERNAL_BITSET_TYPE_LIST(RETURN_NAMED_SEMANTIC_TYPE) |
964 #undef RETURN_NAMED_SEMANTIC_TYPE | 922 #undef RETURN_NAMED_SEMANTIC_TYPE |
965 | 923 |
966 default: | 924 default: |
967 return NULL; | 925 return NULL; |
968 } | 926 } |
969 } | 927 } |
970 | 928 |
971 void BitsetType::Print(std::ostream& os, // NOLINT | 929 void BitsetType::Print(std::ostream& os, // NOLINT |
972 bitset bits) { | 930 bitset bits) { |
973 DisallowHeapAllocation no_allocation; | 931 DisallowHeapAllocation no_allocation; |
974 const char* name = Name(bits); | 932 const char* name = Name(bits); |
975 if (name != NULL) { | 933 if (name != NULL) { |
976 os << name; | 934 os << name; |
977 return; | 935 return; |
978 } | 936 } |
979 | 937 |
980 // clang-format off | 938 // clang-format off |
981 static const bitset named_bitsets[] = { | 939 static const bitset named_bitsets[] = { |
982 #define BITSET_CONSTANT(type, value) SEMANTIC(k##type), | 940 #define BITSET_CONSTANT(type, value) k##type, |
983 INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) | 941 INTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) |
984 SEMANTIC_BITSET_TYPE_LIST(BITSET_CONSTANT) | 942 NONINTERNAL_BITSET_TYPE_LIST(BITSET_CONSTANT) |
985 #undef BITSET_CONSTANT | 943 #undef BITSET_CONSTANT |
986 }; | 944 }; |
987 // clang-format on | 945 // clang-format on |
988 | 946 |
989 bool is_first = true; | 947 bool is_first = true; |
990 os << "("; | 948 os << "("; |
991 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { | 949 for (int i(arraysize(named_bitsets) - 1); bits != 0 && i >= 0; --i) { |
992 bitset subset = named_bitsets[i]; | 950 bitset subset = named_bitsets[i]; |
993 if ((bits & subset) == subset) { | 951 if ((bits & subset) == subset) { |
994 if (!is_first) os << " | "; | 952 if (!is_first) os << " | "; |
995 is_first = false; | 953 is_first = false; |
996 os << Name(subset); | 954 os << Name(subset); |
997 bits -= subset; | 955 bits -= subset; |
998 } | 956 } |
999 } | 957 } |
1000 DCHECK(bits == 0); | 958 DCHECK(bits == 0); |
1001 os << ")"; | 959 os << ")"; |
1002 } | 960 } |
1003 | 961 |
1004 void Type::PrintTo(std::ostream& os) { | 962 void Type::PrintTo(std::ostream& os) { |
1005 DisallowHeapAllocation no_allocation; | 963 DisallowHeapAllocation no_allocation; |
1006 if (this->IsBitset()) { | 964 if (this->IsBitset()) { |
1007 BitsetType::Print(os, SEMANTIC(this->AsBitset())); | 965 BitsetType::Print(os, this->AsBitset()); |
1008 } else if (this->IsConstant()) { | 966 } else if (this->IsConstant()) { |
1009 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; | 967 os << "Constant(" << Brief(*this->AsConstant()->Value()) << ")"; |
1010 } else if (this->IsRange()) { | 968 } else if (this->IsRange()) { |
1011 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); | 969 std::ostream::fmtflags saved_flags = os.setf(std::ios::fixed); |
1012 std::streamsize saved_precision = os.precision(0); | 970 std::streamsize saved_precision = os.precision(0); |
1013 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() | 971 os << "Range(" << this->AsRange()->Min() << ", " << this->AsRange()->Max() |
1014 << ")"; | 972 << ")"; |
1015 os.flags(saved_flags); | 973 os.flags(saved_flags); |
1016 os.precision(saved_precision); | 974 os.precision(saved_precision); |
1017 } else if (this->IsUnion()) { | 975 } else if (this->IsUnion()) { |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1057 } | 1015 } |
1058 | 1016 |
1059 // ----------------------------------------------------------------------------- | 1017 // ----------------------------------------------------------------------------- |
1060 // Instantiations. | 1018 // Instantiations. |
1061 | 1019 |
1062 template class Type::Iterator<i::Object>; | 1020 template class Type::Iterator<i::Object>; |
1063 | 1021 |
1064 } // namespace compiler | 1022 } // namespace compiler |
1065 } // namespace internal | 1023 } // namespace internal |
1066 } // namespace v8 | 1024 } // namespace v8 |
OLD | NEW |