| Index: src/types.cc
|
| diff --git a/src/types.cc b/src/types.cc
|
| index e269582ca0293b73b68009c39ed129ec0e7a6c81..0598a6353fab1c692bc7030e65348469f3950fa0 100644
|
| --- a/src/types.cc
|
| +++ b/src/types.cc
|
| @@ -436,28 +436,31 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Union(
|
| }
|
|
|
| // Slow case: may need to produce a Unioned object.
|
| - int size = type1->IsBitset() || type2->IsBitset() ? 1 : 0;
|
| + int bitset = type1->GlbBitset() | type2->GlbBitset();
|
| + int allocated_size = bitset != kNone ? 1 : 0;
|
| if (!type1->IsBitset()) {
|
| - size += (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 1);
|
| + allocated_size += type1->IsUnion() ? Config::union_length(type1->AsUnion())
|
| + : 1;
|
| }
|
| if (!type2->IsBitset()) {
|
| - size += (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1);
|
| + allocated_size += type2->IsUnion() ? Config::union_length(type2->AsUnion())
|
| + : 1;
|
| }
|
| - ASSERT(size >= 2);
|
| - UnionedHandle unioned = Config::union_create(size, region);
|
| - size = 0;
|
| + UnionedHandle unioned = Config::union_create(allocated_size, region);
|
| + int used_size = 0;
|
|
|
| - int bitset = type1->GlbBitset() | type2->GlbBitset();
|
| if (bitset != kNone) {
|
| - Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
|
| + Config::union_set(unioned, used_size++,
|
| + Config::from_bitset(bitset, region));
|
| }
|
| - size = ExtendUnion(unioned, type1, size);
|
| - size = ExtendUnion(unioned, type2, size);
|
| + used_size = ExtendUnion(unioned, type1, used_size);
|
| + used_size = ExtendUnion(unioned, type2, used_size);
|
| + ASSERT(used_size <= allocated_size);
|
|
|
| - if (size == 1) {
|
| + if (used_size == 1) {
|
| return Config::union_get(unioned, 0);
|
| } else {
|
| - Config::union_shrink(unioned, size);
|
| + Config::union_shrink(unioned, used_size);
|
| return Config::from_union(unioned);
|
| }
|
| }
|
| @@ -512,31 +515,34 @@ typename TypeImpl<Config>::TypeHandle TypeImpl<Config>::Intersect(
|
| }
|
|
|
| // Slow case: may need to produce a Unioned object.
|
| - int size = 0;
|
| + int allocated_size = 0;
|
| if (!type1->IsBitset()) {
|
| - size = (type1->IsUnion() ? Config::union_length(type1->AsUnion()) : 2);
|
| + allocated_size = type1->IsUnion() ? Config::union_length(type1->AsUnion())
|
| + : 1;
|
| }
|
| if (!type2->IsBitset()) {
|
| - int size2 = (type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 2);
|
| - size = (size == 0 ? size2 : Min(size, size2));
|
| + int size2 = type2->IsUnion() ? Config::union_length(type2->AsUnion()) : 1;
|
| + allocated_size = allocated_size == 0 ? size2 : Min(allocated_size, size2);
|
| }
|
| - ASSERT(size >= 2);
|
| - UnionedHandle unioned = Config::union_create(size, region);
|
| - size = 0;
|
| -
|
| int bitset = type1->GlbBitset() & type2->GlbBitset();
|
| + if (bitset != kNone) allocated_size++;
|
| + UnionedHandle unioned = Config::union_create(allocated_size, region);
|
| + int used_size = 0;
|
| +
|
| if (bitset != kNone) {
|
| - Config::union_set(unioned, size++, Config::from_bitset(bitset, region));
|
| + Config::union_set(unioned, used_size++,
|
| + Config::from_bitset(bitset, region));
|
| }
|
| - size = ExtendIntersection(unioned, type1, type2, size);
|
| - size = ExtendIntersection(unioned, type2, type1, size);
|
| + used_size = ExtendIntersection(unioned, type1, type2, used_size);
|
| + used_size = ExtendIntersection(unioned, type2, type1, used_size);
|
| + ASSERT(used_size <= allocated_size);
|
|
|
| - if (size == 0) {
|
| + if (used_size == 0) {
|
| return None(region);
|
| - } else if (size == 1) {
|
| + } else if (used_size == 1) {
|
| return Config::union_get(unioned, 0);
|
| } else {
|
| - Config::union_shrink(unioned, size);
|
| + Config::union_shrink(unioned, used_size);
|
| return Config::from_union(unioned);
|
| }
|
| }
|
| @@ -645,7 +651,7 @@ void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
|
| switch (dim) {
|
| case BOTH_DIMS:
|
| BitsetTypePrint(out, bitset & kSemantic);
|
| - PrintF("/");
|
| + PrintF(out, "/");
|
| BitsetTypePrint(out, bitset & kRepresentation);
|
| break;
|
| case SEMANTIC_DIM:
|
| @@ -658,18 +664,18 @@ void TypeImpl<Config>::TypePrint(FILE* out, PrintDimension dim) {
|
| } else if (this->IsConstant()) {
|
| PrintF(out, "Constant(%p : ", static_cast<void*>(*this->AsConstant()));
|
| Config::from_bitset(this->LubBitset())->TypePrint(out);
|
| - PrintF(")");
|
| + PrintF(out, ")");
|
| } else if (this->IsClass()) {
|
| PrintF(out, "Class(%p < ", static_cast<void*>(*this->AsClass()));
|
| Config::from_bitset(this->LubBitset())->TypePrint(out);
|
| - PrintF(")");
|
| + PrintF(out, ")");
|
| } else if (this->IsUnion()) {
|
| PrintF(out, "(");
|
| UnionedHandle unioned = this->AsUnion();
|
| for (int i = 0; i < Config::union_length(unioned); ++i) {
|
| TypeHandle type_i = Config::union_get(unioned, i);
|
| if (i > 0) PrintF(out, " | ");
|
| - type_i->TypePrint(out);
|
| + type_i->TypePrint(out, dim);
|
| }
|
| PrintF(out, ")");
|
| }
|
|
|