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

Side by Side Diff: src/types.cc

Issue 904863002: [turbofan] Separate representation type operations from the semantic types. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fixes Created 5 years, 10 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
« no previous file with comments | « src/types.h ('k') | test/cctest/cctest.gyp » ('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 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/types.h" 7 #include "src/types.h"
8 8
9 #include "src/ostreams.h" 9 #include "src/ostreams.h"
10 #include "src/types-inl.h" 10 #include "src/types-inl.h"
(...skipping 10 matching lines...) Expand all
21 // Range-related helper functions. 21 // Range-related helper functions.
22 22
23 // The result may be invalid (max < min). 23 // The result may be invalid (max < min).
24 template<class Config> 24 template<class Config>
25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect( 25 typename TypeImpl<Config>::Limits TypeImpl<Config>::Intersect(
26 Limits lhs, Limits rhs) { 26 Limits lhs, Limits rhs) {
27 DisallowHeapAllocation no_allocation; 27 DisallowHeapAllocation no_allocation;
28 Limits result(lhs); 28 Limits result(lhs);
29 if (lhs.min < rhs.min) result.min = rhs.min; 29 if (lhs.min < rhs.min) result.min = rhs.min;
30 if (lhs.max > rhs.max) result.max = rhs.max; 30 if (lhs.max > rhs.max) result.max = rhs.max;
31 result.representation = lhs.representation & rhs.representation;
32 return result; 31 return result;
33 } 32 }
34 33
35 34
36 template <class Config> 35 template <class Config>
37 bool TypeImpl<Config>::IsEmpty(Limits lim) { 36 bool TypeImpl<Config>::IsEmpty(Limits lim) {
38 return lim.min > lim.max; 37 return lim.min > lim.max;
39 } 38 }
40 39
41 40
42 template <class Config> 41 template <class Config>
43 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs, 42 typename TypeImpl<Config>::Limits TypeImpl<Config>::Union(Limits lhs,
44 Limits rhs) { 43 Limits rhs) {
45 DisallowHeapAllocation no_allocation; 44 DisallowHeapAllocation no_allocation;
45 if (IsEmpty(lhs)) return rhs;
46 if (IsEmpty(rhs)) return lhs;
46 Limits result(lhs); 47 Limits result(lhs);
47 if (lhs.min > rhs.min) result.min = rhs.min; 48 if (lhs.min > rhs.min) result.min = rhs.min;
48 if (lhs.max < rhs.max) result.max = rhs.max; 49 if (lhs.max < rhs.max) result.max = rhs.max;
49 result.representation = lhs.representation | rhs.representation;
50 return result; 50 return result;
51 } 51 }
52 52
53 53
54 template<class Config> 54 template<class Config>
55 bool TypeImpl<Config>::Overlap( 55 bool TypeImpl<Config>::Overlap(
56 typename TypeImpl<Config>::RangeType* lhs, 56 typename TypeImpl<Config>::RangeType* lhs,
57 typename TypeImpl<Config>::RangeType* rhs) { 57 typename TypeImpl<Config>::RangeType* rhs) {
58 DisallowHeapAllocation no_allocation; 58 DisallowHeapAllocation no_allocation;
59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs)); 59 typename TypeImpl<Config>::Limits lim = Intersect(Limits(lhs), Limits(rhs));
60 return lim.min <= lim.max; 60 return lim.min <= lim.max;
61 } 61 }
62 62
63 63
64 template<class Config> 64 template<class Config>
65 bool TypeImpl<Config>::Contains( 65 bool TypeImpl<Config>::Contains(
66 typename TypeImpl<Config>::RangeType* lhs, 66 typename TypeImpl<Config>::RangeType* lhs,
67 typename TypeImpl<Config>::RangeType* rhs) { 67 typename TypeImpl<Config>::RangeType* rhs) {
68 DisallowHeapAllocation no_allocation; 68 DisallowHeapAllocation no_allocation;
69 return BitsetType::Is(rhs->Bound(), lhs->Bound()) && 69 return lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
70 lhs->Min() <= rhs->Min() && rhs->Max() <= lhs->Max();
71 } 70 }
72 71
73 72
74 template <class Config> 73 template <class Config>
75 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs, 74 bool TypeImpl<Config>::Contains(typename TypeImpl<Config>::RangeType* lhs,
76 typename TypeImpl<Config>::ConstantType* rhs) { 75 typename TypeImpl<Config>::ConstantType* rhs) {
77 DisallowHeapAllocation no_allocation; 76 DisallowHeapAllocation no_allocation;
78 return IsInteger(*rhs->Value()) && 77 return IsInteger(*rhs->Value()) &&
79 BitsetType::Is(rhs->Bound()->AsBitset(), lhs->Bound()) &&
80 lhs->Min() <= rhs->Value()->Number() && 78 lhs->Min() <= rhs->Value()->Number() &&
81 rhs->Value()->Number() <= lhs->Max(); 79 rhs->Value()->Number() <= lhs->Max();
82 } 80 }
83 81
84 82
85 template<class Config> 83 template<class Config>
86 bool TypeImpl<Config>::Contains( 84 bool TypeImpl<Config>::Contains(
87 typename TypeImpl<Config>::RangeType* range, i::Object* val) { 85 typename TypeImpl<Config>::RangeType* range, i::Object* val) {
88 DisallowHeapAllocation no_allocation; 86 DisallowHeapAllocation no_allocation;
89 return IsInteger(val) && 87 return IsInteger(val) &&
90 BitsetType::Is(BitsetType::Lub(val), range->Bound()) &&
91 range->Min() <= val->Number() && val->Number() <= range->Max(); 88 range->Min() <= val->Number() && val->Number() <= range->Max();
92 } 89 }
93 90
94 91
95 // ----------------------------------------------------------------------------- 92 // -----------------------------------------------------------------------------
96 // Min and Max computation. 93 // Min and Max computation.
97 94
98 template<class Config> 95 template<class Config>
99 double TypeImpl<Config>::Min() { 96 double TypeImpl<Config>::Min() {
100 DCHECK(this->Is(Number())); 97 DCHECK(this->SemanticIs(Number()));
101 if (this->IsBitset()) return BitsetType::Min(this->AsBitset()); 98 if (this->IsBitset()) return BitsetType::Min(this->AsBitset());
102 if (this->IsUnion()) { 99 if (this->IsUnion()) {
103 double min = +V8_INFINITY; 100 double min = +V8_INFINITY;
104 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 101 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
105 min = std::min(min, this->AsUnion()->Get(i)->Min()); 102 min = std::min(min, this->AsUnion()->Get(i)->Min());
106 } 103 }
107 return min; 104 return min;
108 } 105 }
109 if (this->IsRange()) return this->AsRange()->Min(); 106 if (this->IsRange()) return this->AsRange()->Min();
110 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); 107 if (this->IsConstant()) return this->AsConstant()->Value()->Number();
111 UNREACHABLE(); 108 UNREACHABLE();
112 return 0; 109 return 0;
113 } 110 }
114 111
115 112
116 template<class Config> 113 template<class Config>
117 double TypeImpl<Config>::Max() { 114 double TypeImpl<Config>::Max() {
118 DCHECK(this->Is(Number())); 115 DCHECK(this->SemanticIs(Number()));
119 if (this->IsBitset()) return BitsetType::Max(this->AsBitset()); 116 if (this->IsBitset()) return BitsetType::Max(this->AsBitset());
120 if (this->IsUnion()) { 117 if (this->IsUnion()) {
121 double max = -V8_INFINITY; 118 double max = -V8_INFINITY;
122 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 119 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
123 max = std::max(max, this->AsUnion()->Get(i)->Max()); 120 max = std::max(max, this->AsUnion()->Get(i)->Max());
124 } 121 }
125 return max; 122 return max;
126 } 123 }
127 if (this->IsRange()) return this->AsRange()->Max(); 124 if (this->IsRange()) return this->AsRange()->Max();
128 if (this->IsConstant()) return this->AsConstant()->Value()->Number(); 125 if (this->IsConstant()) return this->AsConstant()->Value()->Number();
129 UNREACHABLE(); 126 UNREACHABLE();
130 return 0; 127 return 0;
131 } 128 }
132 129
133 130
134 // ----------------------------------------------------------------------------- 131 // -----------------------------------------------------------------------------
135 // Glb and lub computation. 132 // Glb and lub computation.
136 133
137 134
138 // The largest bitset subsumed by this type. 135 // The largest bitset subsumed by this type.
139 template<class Config> 136 template<class Config>
140 typename TypeImpl<Config>::bitset 137 typename TypeImpl<Config>::bitset
141 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) { 138 TypeImpl<Config>::BitsetType::Glb(TypeImpl* type) {
142 DisallowHeapAllocation no_allocation; 139 DisallowHeapAllocation no_allocation;
140 // Fast case.
143 if (type->IsBitset()) { 141 if (type->IsBitset()) {
144 return type->AsBitset(); 142 return type->AsBitset();
145 } else if (type->IsUnion()) { 143 } else if (type->IsUnion()) {
146 SLOW_DCHECK(type->AsUnion()->Wellformed()); 144 SLOW_DCHECK(type->AsUnion()->Wellformed());
147 return type->AsUnion()->Get(0)->BitsetGlb() | 145 return type->AsUnion()->Get(0)->BitsetGlb() |
148 type->AsUnion()->Get(1)->BitsetGlb(); // Shortcut. 146 SEMANTIC(type->AsUnion()->Get(1)->BitsetGlb()); // Shortcut.
149 } else if (type->IsRange()) { 147 } else if (type->IsRange()) {
150 bitset glb = SEMANTIC( 148 bitset glb = SEMANTIC(
151 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max())); 149 BitsetType::Glb(type->AsRange()->Min(), type->AsRange()->Max()));
152 if (glb == 0) { 150 return glb | REPRESENTATION(type->BitsetLub());
153 return kNone;
154 } else {
155 return glb | REPRESENTATION(type->BitsetLub());
156 }
157 } else { 151 } else {
158 // (The remaining BitsetGlb's are None anyway). 152 return type->Representation();
159 return kNone;
160 } 153 }
161 } 154 }
162 155
163 156
164 // The smallest bitset subsuming this type. 157 // The smallest bitset subsuming this type.
165 template<class Config> 158 template<class Config>
166 typename TypeImpl<Config>::bitset 159 typename TypeImpl<Config>::bitset
167 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) { 160 TypeImpl<Config>::BitsetType::Lub(TypeImpl* type) {
168 DisallowHeapAllocation no_allocation; 161 DisallowHeapAllocation no_allocation;
169 if (type->IsBitset()) return type->AsBitset(); 162 if (type->IsBitset()) return type->AsBitset();
170 if (type->IsUnion()) { 163 if (type->IsUnion()) {
171 int bitset = kNone; 164 // Take the representation from the first element, which is always
165 // a bitset.
166 int bitset = type->AsUnion()->Get(0)->BitsetLub();
172 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { 167 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
173 bitset |= type->AsUnion()->Get(i)->BitsetLub(); 168 // Other elements only contribute their semantic part.
169 bitset |= SEMANTIC(type->AsUnion()->Get(i)->BitsetLub());
174 } 170 }
175 return bitset; 171 return bitset;
176 } 172 }
177 if (type->IsClass()) { 173 if (type->IsClass()) {
178 // Little hack to avoid the need for a region for handlification here... 174 // Little hack to avoid the need for a region for handlification here...
179 return Config::is_class(type) ? Lub(*Config::as_class(type)) : 175 return Config::is_class(type) ? Lub(*Config::as_class(type)) :
180 type->AsClass()->Bound(NULL)->AsBitset(); 176 type->AsClass()->Bound(NULL)->AsBitset();
181 } 177 }
182 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset(); 178 if (type->IsConstant()) return type->AsConstant()->Bound()->AsBitset();
183 if (type->IsRange()) return type->AsRange()->Bound(); 179 if (type->IsRange()) return type->AsRange()->Bound();
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 // in the greatest lower bound. (There is also the small trouble 396 // in the greatest lower bound. (There is also the small trouble
401 // of kOtherNumber having a range hole, which we can conveniently 397 // of kOtherNumber having a range hole, which we can conveniently
402 // ignore here.) 398 // ignore here.)
403 return glb & ~(SEMANTIC(kOtherNumber)); 399 return glb & ~(SEMANTIC(kOtherNumber));
404 } 400 }
405 401
406 402
407 template <class Config> 403 template <class Config>
408 double TypeImpl<Config>::BitsetType::Min(bitset bits) { 404 double TypeImpl<Config>::BitsetType::Min(bitset bits) {
409 DisallowHeapAllocation no_allocation; 405 DisallowHeapAllocation no_allocation;
410 DCHECK(Is(bits, kNumber)); 406 DCHECK(Is(SEMANTIC(bits), kNumber));
411 const Boundary* mins = Boundaries(); 407 const Boundary* mins = Boundaries();
412 bool mz = SEMANTIC(bits & kMinusZero); 408 bool mz = SEMANTIC(bits & kMinusZero);
413 for (size_t i = 0; i < BoundariesSize(); ++i) { 409 for (size_t i = 0; i < BoundariesSize(); ++i) {
414 if (Is(SEMANTIC(mins[i].bits), bits)) { 410 if (Is(SEMANTIC(mins[i].bits), bits)) {
415 return mz ? std::min(0.0, mins[i].min) : mins[i].min; 411 return mz ? std::min(0.0, mins[i].min) : mins[i].min;
416 } 412 }
417 } 413 }
418 if (mz) return 0; 414 if (mz) return 0;
419 return std::numeric_limits<double>::quiet_NaN(); 415 return std::numeric_limits<double>::quiet_NaN();
420 } 416 }
421 417
422 418
423 template<class Config> 419 template<class Config>
424 double TypeImpl<Config>::BitsetType::Max(bitset bits) { 420 double TypeImpl<Config>::BitsetType::Max(bitset bits) {
425 DisallowHeapAllocation no_allocation; 421 DisallowHeapAllocation no_allocation;
426 DCHECK(Is(bits, kNumber)); 422 DCHECK(Is(SEMANTIC(bits), kNumber));
427 const Boundary* mins = Boundaries(); 423 const Boundary* mins = Boundaries();
428 bool mz = SEMANTIC(bits & kMinusZero); 424 bool mz = SEMANTIC(bits & kMinusZero);
429 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) { 425 if (BitsetType::Is(SEMANTIC(mins[BoundariesSize() - 1].bits), bits)) {
430 return +V8_INFINITY; 426 return +V8_INFINITY;
431 } 427 }
432 for (size_t i = BoundariesSize() - 1; i-- > 0;) { 428 for (size_t i = BoundariesSize() - 1; i-- > 0;) {
433 if (Is(SEMANTIC(mins[i].bits), bits)) { 429 if (Is(SEMANTIC(mins[i].bits), bits)) {
434 return mz ? 430 return mz ?
435 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1; 431 std::max(0.0, mins[i+1].min - 1) : mins[i+1].min - 1;
436 } 432 }
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
475 for (int i = 0, n = this_fun->Arity(); i < n; ++i) { 471 for (int i = 0, n = this_fun->Arity(); i < n; ++i) {
476 if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false; 472 if (!this_fun->Parameter(i)->Equals(that_fun->Parameter(i))) return false;
477 } 473 }
478 return true; 474 return true;
479 } 475 }
480 UNREACHABLE(); 476 UNREACHABLE();
481 return false; 477 return false;
482 } 478 }
483 479
484 480
481 template <class Config>
482 typename TypeImpl<Config>::bitset TypeImpl<Config>::Representation() {
483 return REPRESENTATION(this->BitsetLub());
484 }
485
486
485 // Check if [this] <= [that]. 487 // Check if [this] <= [that].
486 template<class Config> 488 template<class Config>
487 bool TypeImpl<Config>::SlowIs(TypeImpl* that) { 489 bool TypeImpl<Config>::SlowIs(TypeImpl* that) {
488 DisallowHeapAllocation no_allocation; 490 DisallowHeapAllocation no_allocation;
489 491
492 // Fast bitset cases
490 if (that->IsBitset()) { 493 if (that->IsBitset()) {
491 return BitsetType::Is(this->BitsetLub(), that->AsBitset()); 494 return BitsetType::Is(this->BitsetLub(), that->AsBitset());
492 } 495 }
496
493 if (this->IsBitset()) { 497 if (this->IsBitset()) {
494 return BitsetType::Is(this->AsBitset(), that->BitsetGlb()); 498 return BitsetType::Is(this->AsBitset(), that->BitsetGlb());
495 } 499 }
496 500
501 // Check the representations.
502 if (!BitsetType::Is(Representation(), that->Representation())) {
503 return false;
504 }
505
506 // Check the semantic part.
507 return SemanticIs(that);
508 }
509
510
511 // Check if SEMANTIC([this]) <= SEMANTIC([that]). The result of the method
512 // should be independent of the representation axis of the types.
513 template <class Config>
514 bool TypeImpl<Config>::SemanticIs(TypeImpl* that) {
515 DisallowHeapAllocation no_allocation;
516
517 if (this == that) return true;
518
519 if (that->IsBitset()) {
520 return BitsetType::Is(SEMANTIC(this->BitsetLub()), that->AsBitset());
521 }
522 if (this->IsBitset()) {
523 return BitsetType::Is(SEMANTIC(this->AsBitset()), that->BitsetGlb());
524 }
525
497 // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T) 526 // (T1 \/ ... \/ Tn) <= T if (T1 <= T) /\ ... /\ (Tn <= T)
498 if (this->IsUnion()) { 527 if (this->IsUnion()) {
499 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 528 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
500 if (!this->AsUnion()->Get(i)->Is(that)) return false; 529 if (!this->AsUnion()->Get(i)->SemanticIs(that)) return false;
501 } 530 }
502 return true; 531 return true;
503 } 532 }
504 533
505 // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn) 534 // T <= (T1 \/ ... \/ Tn) if (T <= T1) \/ ... \/ (T <= Tn)
506 if (that->IsUnion()) { 535 if (that->IsUnion()) {
507 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { 536 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
508 if (this->Is(that->AsUnion()->Get(i))) return true; 537 if (this->SemanticIs(that->AsUnion()->Get(i)->unhandle())) return true;
509 if (i > 1 && this->IsRange()) return false; // Shortcut. 538 if (i > 1 && this->IsRange()) return false; // Shortcut.
510 } 539 }
511 return false; 540 return false;
512 } 541 }
513 542
514 if (that->IsRange()) { 543 if (that->IsRange()) {
515 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) || 544 return (this->IsRange() && Contains(that->AsRange(), this->AsRange())) ||
516 (this->IsConstant() && 545 (this->IsConstant() &&
517 Contains(that->AsRange(), this->AsConstant())); 546 Contains(that->AsRange(), this->AsConstant()));
518 } 547 }
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
551 } 580 }
552 return true; 581 return true;
553 } 582 }
554 583
555 584
556 // Check if [this] and [that] overlap. 585 // Check if [this] and [that] overlap.
557 template<class Config> 586 template<class Config>
558 bool TypeImpl<Config>::Maybe(TypeImpl* that) { 587 bool TypeImpl<Config>::Maybe(TypeImpl* that) {
559 DisallowHeapAllocation no_allocation; 588 DisallowHeapAllocation no_allocation;
560 589
590 // Take care of the representation part (and also approximate
591 // the semantic part).
592 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub()))
593 return false;
594
595 return SemanticMaybe(that);
596 }
597
598 template <class Config>
599 bool TypeImpl<Config>::SemanticMaybe(TypeImpl* that) {
600 DisallowHeapAllocation no_allocation;
601
561 // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T) 602 // (T1 \/ ... \/ Tn) overlaps T if (T1 overlaps T) \/ ... \/ (Tn overlaps T)
562 if (this->IsUnion()) { 603 if (this->IsUnion()) {
563 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 604 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
564 if (this->AsUnion()->Get(i)->Maybe(that)) return true; 605 if (this->AsUnion()->Get(i)->SemanticMaybe(that)) return true;
565 } 606 }
566 return false; 607 return false;
567 } 608 }
568 609
569 // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn) 610 // T overlaps (T1 \/ ... \/ Tn) if (T overlaps T1) \/ ... \/ (T overlaps Tn)
570 if (that->IsUnion()) { 611 if (that->IsUnion()) {
571 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) { 612 for (int i = 0, n = that->AsUnion()->Length(); i < n; ++i) {
572 if (this->Maybe(that->AsUnion()->Get(i))) return true; 613 if (this->SemanticMaybe(that->AsUnion()->Get(i)->unhandle())) return true;
573 } 614 }
574 return false; 615 return false;
575 } 616 }
576 617
577 if (!BitsetType::IsInhabited(this->BitsetLub() & that->BitsetLub())) 618 if (!BitsetType::SemanticIsInhabited(this->BitsetLub() & that->BitsetLub()))
578 return false; 619 return false;
579 620
580 if (this->IsBitset() && that->IsBitset()) return true; 621 if (this->IsBitset() && that->IsBitset()) return true;
581 622
582 if (this->IsClass() != that->IsClass()) return true; 623 if (this->IsClass() != that->IsClass()) return true;
583 624
584 if (this->IsRange()) { 625 if (this->IsRange()) {
585 if (that->IsConstant()) { 626 if (that->IsConstant()) {
586 return Contains(this->AsRange(), that->AsConstant()); 627 return Contains(this->AsRange(), that->AsConstant());
587 } 628 }
588 if (that->IsRange()) { 629 if (that->IsRange()) {
589 return Overlap(this->AsRange(), that->AsRange()); 630 return Overlap(this->AsRange(), that->AsRange());
590 } 631 }
591 if (that->IsBitset()) { 632 if (that->IsBitset()) {
592 bitset number_bits = BitsetType::NumberBits(that->AsBitset()); 633 bitset number_bits = BitsetType::NumberBits(that->AsBitset());
593 if (number_bits == BitsetType::kNone) { 634 if (number_bits == BitsetType::kNone) {
594 return false; 635 return false;
595 } 636 }
596 double min = std::max(BitsetType::Min(number_bits), this->Min()); 637 double min = std::max(BitsetType::Min(number_bits), this->Min());
597 double max = std::min(BitsetType::Max(number_bits), this->Max()); 638 double max = std::min(BitsetType::Max(number_bits), this->Max());
598 return min <= max; 639 return min <= max;
599 } 640 }
600 } 641 }
601 if (that->IsRange()) { 642 if (that->IsRange()) {
602 return that->Maybe(this); // This case is handled above. 643 return that->SemanticMaybe(this); // This case is handled above.
603 } 644 }
604 645
605 if (this->IsBitset() || that->IsBitset()) return true; 646 if (this->IsBitset() || that->IsBitset()) return true;
606 647
607 return this->SimplyEquals(that); 648 return this->SimplyEquals(that);
608 } 649 }
609 650
610 651
611 // Return the range in [this], or [NULL]. 652 // Return the range in [this], or [NULL].
612 template<class Config> 653 template<class Config>
(...skipping 19 matching lines...) Expand all
632 } 673 }
633 return BitsetType::New(BitsetType::Lub(value))->Is(this); 674 return BitsetType::New(BitsetType::Lub(value))->Is(this);
634 } 675 }
635 676
636 677
637 template<class Config> 678 template<class Config>
638 bool TypeImpl<Config>::UnionType::Wellformed() { 679 bool TypeImpl<Config>::UnionType::Wellformed() {
639 DisallowHeapAllocation no_allocation; 680 DisallowHeapAllocation no_allocation;
640 // This checks the invariants of the union representation: 681 // This checks the invariants of the union representation:
641 // 1. There are at least two elements. 682 // 1. There are at least two elements.
642 // 2. At most one element is a bitset, and it must be the first one. 683 // 2. The first element is a bitset, no other element is a bitset.
643 // 3. At most one element is a range, and it must be the second one 684 // 3. At most one element is a range, and it must be the second one.
644 // (even when the first element is not a bitset).
645 // 4. No element is itself a union. 685 // 4. No element is itself a union.
646 // 5. No element is a subtype of any other. 686 // 5. No element (except the bitset) is a subtype of any other.
647 // 6. If there is a range, then the bitset type does not contain 687 // 6. If there is a range, then the bitset type does not contain
648 // plain number bits. 688 // plain number bits.
649 DCHECK(this->Length() >= 2); // (1) 689 DCHECK(this->Length() >= 2); // (1)
650 690 DCHECK(this->Get(0)->IsBitset()); // (2a)
651 bitset number_bits = this->Get(0)->IsBitset()
652 ? BitsetType::NumberBits(this->Get(0)->AsBitset()) : 0;
653 USE(number_bits);
654 691
655 for (int i = 0; i < this->Length(); ++i) { 692 for (int i = 0; i < this->Length(); ++i) {
656 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2) 693 if (i != 0) DCHECK(!this->Get(i)->IsBitset()); // (2b)
657 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3) 694 if (i != 1) DCHECK(!this->Get(i)->IsRange()); // (3)
658 DCHECK(!this->Get(i)->IsUnion()); // (4) 695 DCHECK(!this->Get(i)->IsUnion()); // (4)
659 for (int j = 0; j < this->Length(); ++j) { 696 for (int j = 0; j < this->Length(); ++j) {
660 if (i != j) DCHECK(!this->Get(i)->Is(this->Get(j))); // (5) 697 if (i != j && i != 0)
698 DCHECK(!this->Get(i)->SemanticIs(this->Get(j)->unhandle())); // (5)
661 } 699 }
662 } 700 }
663 DCHECK(!this->Get(1)->IsRange() || (number_bits == 0)); // (6) 701 DCHECK(!this->Get(1)->IsRange() ||
702 (BitsetType::NumberBits(this->Get(0)->AsBitset()) ==
703 BitsetType::kNone)); // (6)
664 return true; 704 return true;
665 } 705 }
666 706
667 707
668 // ----------------------------------------------------------------------------- 708 // -----------------------------------------------------------------------------
669 // Union and intersection 709 // Union and intersection
670 710
671 711
672 static bool AddIsSafe(int x, int y) { 712 static bool AddIsSafe(int x, int y) {
673 return x >= 0 ? 713 return x >= 0 ?
674 y <= std::numeric_limits<int>::max() - x : 714 y <= std::numeric_limits<int>::max() - x :
675 y >= std::numeric_limits<int>::min() - x; 715 y >= std::numeric_limits<int>::min() - x;
676 } 716 }
677 717
678 718
679 template<class Config> 719 template<class Config>
680 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect( 720 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
681 TypeHandle type1, TypeHandle type2, Region* region) { 721 TypeHandle type1, TypeHandle type2, Region* region) {
682 bitset bits = type1->BitsetGlb() & type2->BitsetGlb();
683 if (!BitsetType::IsInhabited(bits)) bits = BitsetType::kNone;
684 722
685 // Fast case: bit sets. 723 // Fast case: bit sets.
686 if (type1->IsBitset() && type2->IsBitset()) { 724 if (type1->IsBitset() && type2->IsBitset()) {
687 return BitsetType::New(bits, region); 725 return BitsetType::New(type1->AsBitset() & type2->AsBitset(), region);
688 } 726 }
689 727
690 // Fast case: top or bottom types. 728 // Fast case: top or bottom types.
691 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut. 729 if (type1->IsNone() || type2->IsAny()) return type1; // Shortcut.
692 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut. 730 if (type2->IsNone() || type1->IsAny()) return type2; // Shortcut.
693 731
694 // Semi-fast case. 732 // Semi-fast case.
695 if (type1->Is(type2)) return type1; 733 if (type1->Is(type2)) return type1;
696 if (type2->Is(type1)) return type2; 734 if (type2->Is(type1)) return type2;
697 735
698 // Slow case: create union. 736 // Slow case: create union.
737
738 // Figure out the representation of the result first.
739 // The rest of the method should not change this representation and
740 // it should not make any decisions based on representations (i.e.,
741 // it should only use the semantic part of types).
742 const bitset representation =
743 type1->Representation() & type2->Representation();
744
745 // Semantic subtyping check - this is needed for consistency with the
746 // semi-fast case above - we should behave the same way regardless of
747 // representations. Intersection with a universal bitset should only update
748 // the representations.
749 if (type1->SemanticIs(type2->unhandle())) {
750 type2 = Any(region);
751 } else if (type2->SemanticIs(type1->unhandle())) {
752 type1 = Any(region);
753 }
754
755 bitset bits =
756 SEMANTIC(type1->BitsetGlb() & type2->BitsetGlb()) | representation;
699 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; 757 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
700 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; 758 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
701 if (!AddIsSafe(size1, size2)) return Any(region); 759 if (!AddIsSafe(size1, size2)) return Any(region);
702 int size = size1 + size2; 760 int size = size1 + size2;
703 if (!AddIsSafe(size, 2)) return Any(region); 761 if (!AddIsSafe(size, 2)) return Any(region);
704 size += 2; 762 size += 2;
705 UnionHandle result = UnionType::New(size, region); 763 UnionHandle result = UnionType::New(size, region);
706 size = 0; 764 size = 0;
707 765
708 // Deal with bitsets. 766 // Deal with bitsets.
709 result->Set(size++, BitsetType::New(bits, region)); 767 result->Set(size++, BitsetType::New(bits, region));
710 // Insert a placeholder for the range.
711 result->Set(size++, None(region));
712 768
713 Limits lims = Limits::Empty(region); 769 Limits lims = Limits::Empty(region);
714 size = IntersectAux(type1, type2, result, size, &lims, region); 770 size = IntersectAux(type1, type2, result, size, &lims, region);
715 771
716 // If the range is not empty, then insert it into the union and 772 // If the range is not empty, then insert it into the union and
717 // remove the number bits from the bitset. 773 // remove the number bits from the bitset.
718 if (!IsEmpty(lims)) { 774 if (!IsEmpty(lims)) {
719 size = UpdateRange(RangeType::New(lims, region), result, size, region); 775 size = UpdateRange(RangeType::New(lims, representation, region), result,
776 size, region);
720 777
721 // Remove the number bits. 778 // Remove the number bits.
722 bitset number_bits = BitsetType::NumberBits(bits); 779 bitset number_bits = BitsetType::NumberBits(bits);
723 bits &= ~number_bits; 780 bits &= ~number_bits;
724 if (SEMANTIC(bits) == BitsetType::kNone) {
725 bits = BitsetType::kNone;
726 }
727 result->Set(0, BitsetType::New(bits, region)); 781 result->Set(0, BitsetType::New(bits, region));
728 } 782 }
729 return NormalizeUnion(result, size); 783 return NormalizeUnion(result, size);
730 } 784 }
731 785
732 786
733 template<class Config> 787 template<class Config>
734 int TypeImpl<Config>::UpdateRange( 788 int TypeImpl<Config>::UpdateRange(
735 RangeHandle range, UnionHandle result, int size, Region* region) { 789 RangeHandle range, UnionHandle result, int size, Region* region) {
736 TypeHandle old_range = result->Get(1); 790 if (size == 1) {
737 DCHECK(old_range->IsRange() || old_range->IsNone()); 791 result->Set(size++, range);
738 if (range->Is(old_range)) return size; 792 } else {
739 if (!old_range->Is(range->unhandle())) { 793 // Make space for the range.
740 range = RangeType::New( 794 result->Set(size++, result->Get(1));
741 Union(Limits(range->AsRange()), Limits(old_range->AsRange())), region); 795 result->Set(1, range);
742 } 796 }
743 result->Set(1, range);
744 797
745 // Remove any components that just got subsumed. 798 // Remove any components that just got subsumed.
746 for (int i = 2; i < size; ) { 799 for (int i = 2; i < size; ) {
747 if (result->Get(i)->Is(range->unhandle())) { 800 if (result->Get(i)->SemanticIs(range->unhandle())) {
748 result->Set(i, result->Get(--size)); 801 result->Set(i, result->Get(--size));
749 } else { 802 } else {
750 ++i; 803 ++i;
751 } 804 }
752 } 805 }
753 return size; 806 return size;
754 } 807 }
755 808
756 809
757 template <class Config> 810 template <class Config>
758 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits, 811 typename TypeImpl<Config>::Limits TypeImpl<Config>::ToLimits(bitset bits,
759 Region* region) { 812 Region* region) {
760 bitset representation = REPRESENTATION(bits);
761 bitset number_bits = BitsetType::NumberBits(bits); 813 bitset number_bits = BitsetType::NumberBits(bits);
762 814
763 if (representation == BitsetType::kNone && number_bits == BitsetType::kNone) { 815 if (number_bits == BitsetType::kNone) {
764 return Limits::Empty(region); 816 return Limits::Empty(region);
765 } 817 }
766 818
767 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits), 819 return Limits(BitsetType::Min(number_bits), BitsetType::Max(number_bits));
768 representation);
769 } 820 }
770 821
771 822
772 template <class Config> 823 template <class Config>
773 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset( 824 typename TypeImpl<Config>::Limits TypeImpl<Config>::IntersectRangeAndBitset(
774 TypeHandle range, TypeHandle bitset, Region* region) { 825 TypeHandle range, TypeHandle bitset, Region* region) {
775 Limits range_lims(range->AsRange()); 826 Limits range_lims(range->AsRange());
776 Limits bitset_lims = ToLimits(bitset->AsBitset(), region); 827 Limits bitset_lims = ToLimits(bitset->AsBitset(), region);
777 return Intersect(range_lims, bitset_lims); 828 return Intersect(range_lims, bitset_lims);
778 } 829 }
(...skipping 11 matching lines...) Expand all
790 return size; 841 return size;
791 } 842 }
792 if (rhs->IsUnion()) { 843 if (rhs->IsUnion()) {
793 for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) { 844 for (int i = 0, n = rhs->AsUnion()->Length(); i < n; ++i) {
794 size = 845 size =
795 IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region); 846 IntersectAux(lhs, rhs->AsUnion()->Get(i), result, size, lims, region);
796 } 847 }
797 return size; 848 return size;
798 } 849 }
799 850
800 if (!BitsetType::IsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) { 851 if (!BitsetType::SemanticIsInhabited(lhs->BitsetLub() & rhs->BitsetLub())) {
801 return size; 852 return size;
802 } 853 }
803 854
804 if (lhs->IsRange()) { 855 if (lhs->IsRange()) {
805 if (rhs->IsBitset()) { 856 if (rhs->IsBitset()) {
806 Limits lim = IntersectRangeAndBitset(lhs, rhs, region); 857 Limits lim = IntersectRangeAndBitset(lhs, rhs, region);
807 858
808 if (!IsEmpty(lim)) { 859 if (!IsEmpty(lim)) {
809 *lims = Union(lim, *lims); 860 *lims = Union(lim, *lims);
810 } 861 }
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
850 RangeHandle range, bitset* bits, Region* region) { 901 RangeHandle range, bitset* bits, Region* region) {
851 // Fast path: If the bitset does not mention numbers, we can just keep the 902 // Fast path: If the bitset does not mention numbers, we can just keep the
852 // range. 903 // range.
853 bitset number_bits = BitsetType::NumberBits(*bits); 904 bitset number_bits = BitsetType::NumberBits(*bits);
854 if (number_bits == 0) { 905 if (number_bits == 0) {
855 return range; 906 return range;
856 } 907 }
857 908
858 // If the range is contained within the bitset, return an empty range 909 // If the range is contained within the bitset, return an empty range
859 // (but make sure we take the representation). 910 // (but make sure we take the representation).
860 bitset range_lub = range->BitsetLub(); 911 bitset range_lub = SEMANTIC(range->BitsetLub());
861 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) { 912 if (BitsetType::Is(BitsetType::NumberBits(range_lub), *bits)) {
862 *bits |= range_lub;
863 return None(region); 913 return None(region);
864 } 914 }
865 915
866 // Slow path: reconcile the bitset range and the range. 916 // Slow path: reconcile the bitset range and the range.
867 double bitset_min = BitsetType::Min(number_bits); 917 double bitset_min = BitsetType::Min(number_bits);
868 double bitset_max = BitsetType::Max(number_bits); 918 double bitset_max = BitsetType::Max(number_bits);
869 919
870 double range_min = range->Min(); 920 double range_min = range->Min();
871 double range_max = range->Max(); 921 double range_max = range->Max();
872 922
873 bitset range_representation = REPRESENTATION(range->BitsetLub());
874 bitset bits_representation = REPRESENTATION(*bits);
875 bitset representation =
876 (bits_representation | range_representation) & BitsetType::kNumber;
877
878 // Remove the number bits from the bitset, they would just confuse us now. 923 // Remove the number bits from the bitset, they would just confuse us now.
879 *bits &= ~number_bits; 924 *bits &= ~number_bits;
880 if (bits_representation == *bits) {
881 *bits = BitsetType::kNone;
882 }
883 925
884 if (representation == range_representation && range_min <= bitset_min && 926 if (range_min <= bitset_min && range_max >= bitset_max) {
885 range_max >= bitset_max) {
886 // Bitset is contained within the range, just return the range. 927 // Bitset is contained within the range, just return the range.
887 return range; 928 return range;
888 } 929 }
889 930
890 if (bitset_min < range_min) { 931 if (bitset_min < range_min) {
891 range_min = bitset_min; 932 range_min = bitset_min;
892 } 933 }
893 if (bitset_max > range_max) { 934 if (bitset_max > range_max) {
894 range_max = bitset_max; 935 range_max = bitset_max;
895 } 936 }
896 return RangeType::New(range_min, range_max, 937 return RangeType::New(range_min, range_max,
897 BitsetType::New(representation, region), region); 938 BitsetType::New(BitsetType::kNone, region), region);
898 } 939 }
899 940
900 941
901 template<class Config> 942 template<class Config>
902 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union( 943 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
903 TypeHandle type1, TypeHandle type2, Region* region) { 944 TypeHandle type1, TypeHandle type2, Region* region) {
904
905 // Fast case: bit sets. 945 // Fast case: bit sets.
906 if (type1->IsBitset() && type2->IsBitset()) { 946 if (type1->IsBitset() && type2->IsBitset()) {
907 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region); 947 return BitsetType::New(type1->AsBitset() | type2->AsBitset(), region);
908 } 948 }
909 949
910 // Fast case: top or bottom types. 950 // Fast case: top or bottom types.
911 if (type1->IsAny() || type2->IsNone()) return type1; 951 if (type1->IsAny() || type2->IsNone()) return type1;
912 if (type2->IsAny() || type1->IsNone()) return type2; 952 if (type2->IsAny() || type1->IsNone()) return type2;
913 953
914 // Semi-fast case. 954 // Semi-fast case.
915 if (type1->Is(type2)) return type2; 955 if (type1->Is(type2)) return type2;
916 if (type2->Is(type1)) return type1; 956 if (type2->Is(type1)) return type1;
917 957
958 // Figure out the representation of the result.
959 // The rest of the method should not change this representation and
960 // it should make any decisions based on representations (i.e.,
961 // it should only use the semantic part of types).
962 const bitset representation =
963 type1->Representation() | type2->Representation();
964
918 // Slow case: create union. 965 // Slow case: create union.
919 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1; 966 int size1 = type1->IsUnion() ? type1->AsUnion()->Length() : 1;
920 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1; 967 int size2 = type2->IsUnion() ? type2->AsUnion()->Length() : 1;
921 if (!AddIsSafe(size1, size2)) return Any(region); 968 if (!AddIsSafe(size1, size2)) return Any(region);
922 int size = size1 + size2; 969 int size = size1 + size2;
923 if (!AddIsSafe(size, 2)) return Any(region); 970 if (!AddIsSafe(size, 2)) return Any(region);
924 size += 2; 971 size += 2;
925 UnionHandle result = UnionType::New(size, region); 972 UnionHandle result = UnionType::New(size, region);
926 size = 0; 973 size = 0;
927 974
928 // Compute the new bitset. 975 // Compute the new bitset.
929 bitset new_bitset = type1->BitsetGlb() | type2->BitsetGlb(); 976 bitset new_bitset = SEMANTIC(type1->BitsetGlb() | type2->BitsetGlb());
930 977
931 // Deal with ranges. 978 // Deal with ranges.
932 TypeHandle range = None(region); 979 TypeHandle range = None(region);
933 RangeType* range1 = type1->GetRange(); 980 RangeType* range1 = type1->GetRange();
934 RangeType* range2 = type2->GetRange(); 981 RangeType* range2 = type2->GetRange();
935 if (range1 != NULL && range2 != NULL) { 982 if (range1 != NULL && range2 != NULL) {
936 Limits lims = Union(Limits(range1), Limits(range2)); 983 Limits lims = Union(Limits(range1), Limits(range2));
937 RangeHandle union_range = RangeType::New(lims, region); 984 RangeHandle union_range = RangeType::New(lims, representation, region);
938 range = NormalizeRangeAndBitset(union_range, &new_bitset, region); 985 range = NormalizeRangeAndBitset(union_range, &new_bitset, region);
939 } else if (range1 != NULL) { 986 } else if (range1 != NULL) {
940 range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region); 987 range = NormalizeRangeAndBitset(handle(range1), &new_bitset, region);
941 } else if (range2 != NULL) { 988 } else if (range2 != NULL) {
942 range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region); 989 range = NormalizeRangeAndBitset(handle(range2), &new_bitset, region);
943 } 990 }
991 new_bitset = SEMANTIC(new_bitset) | representation;
944 TypeHandle bits = BitsetType::New(new_bitset, region); 992 TypeHandle bits = BitsetType::New(new_bitset, region);
945 result->Set(size++, bits); 993 result->Set(size++, bits);
946 result->Set(size++, range); 994 if (!range->IsNone()) result->Set(size++, range);
947 995
948 size = AddToUnion(type1, result, size, region); 996 size = AddToUnion(type1, result, size, region);
949 size = AddToUnion(type2, result, size, region); 997 size = AddToUnion(type2, result, size, region);
950 return NormalizeUnion(result, size); 998 return NormalizeUnion(result, size);
951 } 999 }
952 1000
953 1001
954 // Add [type] to [result] unless [type] is bitset, range, or already subsumed. 1002 // Add [type] to [result] unless [type] is bitset, range, or already subsumed.
955 // Return new size of [result]. 1003 // Return new size of [result].
956 template<class Config> 1004 template<class Config>
957 int TypeImpl<Config>::AddToUnion( 1005 int TypeImpl<Config>::AddToUnion(
958 TypeHandle type, UnionHandle result, int size, Region* region) { 1006 TypeHandle type, UnionHandle result, int size, Region* region) {
959 if (type->IsBitset() || type->IsRange()) return size; 1007 if (type->IsBitset() || type->IsRange()) return size;
960 if (type->IsUnion()) { 1008 if (type->IsUnion()) {
961 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) { 1009 for (int i = 0, n = type->AsUnion()->Length(); i < n; ++i) {
962 size = AddToUnion(type->AsUnion()->Get(i), result, size, region); 1010 size = AddToUnion(type->AsUnion()->Get(i), result, size, region);
963 } 1011 }
964 return size; 1012 return size;
965 } 1013 }
966 for (int i = 0; i < size; ++i) { 1014 for (int i = 0; i < size; ++i) {
967 if (type->Is(result->Get(i))) return size; 1015 if (type->SemanticIs(result->Get(i)->unhandle())) return size;
968 } 1016 }
969 result->Set(size++, type); 1017 result->Set(size++, type);
970 return size; 1018 return size;
971 } 1019 }
972 1020
973 1021
974 template<class Config> 1022 template<class Config>
975 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion( 1023 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::NormalizeUnion(
976 UnionHandle unioned, int size) { 1024 UnionHandle unioned, int size) {
977 DCHECK(size >= 2); 1025 DCHECK(size >= 1);
978 // If range is subsumed by bitset, use its place for a different type. 1026 DCHECK(unioned->Get(0)->IsBitset());
979 if (unioned->Get(1)->Is(unioned->Get(0))) { 1027 // If the union has just one element, return it.
980 unioned->Set(1, unioned->Get(--size)); 1028 if (size == 1) {
1029 return unioned->Get(0);
981 } 1030 }
982 // If bitset is None, use its place for a different type. 1031 bitset bits = unioned->Get(0)->AsBitset();
983 if (size >= 2 && unioned->Get(0)->IsNone()) { 1032 // If the union only consists of a range, we can get rid of the union.
984 unioned->Set(0, unioned->Get(--size)); 1033 if (size == 2 && SEMANTIC(bits) == BitsetType::kNone) {
1034 bitset representation = REPRESENTATION(bits);
1035 if (representation == unioned->Get(1)->Representation()) {
1036 return unioned->Get(1);
1037 }
1038 // TODO(jarin) If the element at 1 is range of constant, slap
1039 // the representation on it and return that.
985 } 1040 }
986 if (size == 1) return unioned->Get(0);
987 unioned->Shrink(size); 1041 unioned->Shrink(size);
988 SLOW_DCHECK(unioned->Wellformed()); 1042 SLOW_DCHECK(unioned->Wellformed());
989 return unioned; 1043 return unioned;
990 } 1044 }
991 1045
992 1046
993 // ----------------------------------------------------------------------------- 1047 // -----------------------------------------------------------------------------
1048 // Component extraction
1049
1050 // static
1051 template <class Config>
1052 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Representation(
1053 TypeHandle t, Region* region) {
1054 return BitsetType::New(t->Representation(), region);
1055 }
1056
1057
1058 // static
1059 template <class Config>
1060 typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Semantic(
1061 TypeHandle t, Region* region) {
1062 return Intersect(t, BitsetType::New(BitsetType::kSemantic, region), region);
1063 }
1064
1065
1066 // -----------------------------------------------------------------------------
994 // Iteration. 1067 // Iteration.
995 1068
996 template<class Config> 1069 template<class Config>
997 int TypeImpl<Config>::NumClasses() { 1070 int TypeImpl<Config>::NumClasses() {
998 DisallowHeapAllocation no_allocation; 1071 DisallowHeapAllocation no_allocation;
999 if (this->IsClass()) { 1072 if (this->IsClass()) {
1000 return 1; 1073 return 1;
1001 } else if (this->IsUnion()) { 1074 } else if (this->IsUnion()) {
1002 int result = 0; 1075 int result = 0;
1003 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) { 1076 for (int i = 0, n = this->AsUnion()->Length(); i < n; ++i) {
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>; 1360 template class TypeImpl<HeapTypeConfig>::Iterator<i::Object>;
1288 1361
1289 template TypeImpl<ZoneTypeConfig>::TypeHandle 1362 template TypeImpl<ZoneTypeConfig>::TypeHandle
1290 TypeImpl<ZoneTypeConfig>::Convert<HeapType>( 1363 TypeImpl<ZoneTypeConfig>::Convert<HeapType>(
1291 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*); 1364 TypeImpl<HeapTypeConfig>::TypeHandle, TypeImpl<ZoneTypeConfig>::Region*);
1292 template TypeImpl<HeapTypeConfig>::TypeHandle 1365 template TypeImpl<HeapTypeConfig>::TypeHandle
1293 TypeImpl<HeapTypeConfig>::Convert<Type>( 1366 TypeImpl<HeapTypeConfig>::Convert<Type>(
1294 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*); 1367 TypeImpl<ZoneTypeConfig>::TypeHandle, TypeImpl<HeapTypeConfig>::Region*);
1295 1368
1296 } } // namespace v8::internal 1369 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/types.h ('k') | test/cctest/cctest.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698