Commit c9cc3d16 authored by mvstanton's avatar mvstanton Committed by Commit bot

[turbofan] Remove the representation dimension from Type.

Adding this back in because it's not part of the stability issue.

BUG=chromium:649967
TBR=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2365373004
Cr-Commit-Position: refs/heads/master@{#39761}
parent 8fea7757
......@@ -196,7 +196,7 @@ Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
}
// Select the correct X -> Tagged operator.
const Operator* op;
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Constant(0);
......@@ -293,7 +293,7 @@ Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
break;
}
// Select the correct X -> Tagged operator.
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->TheHoleConstant();
......@@ -338,7 +338,7 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
}
// Select the correct X -> Tagged operator.
const Operator* op;
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->TheHoleConstant();
......@@ -420,7 +420,7 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
}
// Select the correct X -> Float32 operator.
const Operator* op = nullptr;
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Float32Constant(0.0f);
......@@ -490,7 +490,7 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
}
// Select the correct X -> Float64 operator.
const Operator* op = nullptr;
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Float64Constant(0.0);
......@@ -576,7 +576,7 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
// Select the correct X -> Word32 operator.
const Operator* op = nullptr;
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int32Constant(0);
......@@ -698,7 +698,7 @@ Node* RepresentationChanger::GetBitRepresentationFor(
}
// Select the correct X -> Bit operator.
const Operator* op;
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int32Constant(0);
......@@ -737,7 +737,7 @@ Node* RepresentationChanger::GetBitRepresentationFor(
Node* RepresentationChanger::GetWord64RepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) {
if (Type::Semantic(output_type, jsgraph()->zone())->Is(Type::None())) {
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int64Constant(0);
......@@ -958,7 +958,7 @@ Node* RepresentationChanger::TypeError(Node* node,
if (!testing_type_errors_) {
std::ostringstream out_str;
out_str << output_rep << " (";
output_type->PrintTo(out_str, Type::SEMANTIC_DIM);
output_type->PrintTo(out_str);
out_str << ")";
std::ostringstream use_str;
......
This diff is collapsed.
......@@ -22,13 +22,7 @@ namespace compiler {
// can express class types (a.k.a. specific maps) and singleton types (i.e.,
// concrete constants).
//
// Types consist of two dimensions: semantic (value range) and representation.
// Both are related through subtyping.
//
//
// SEMANTIC DIMENSION
//
// The following equations and inequations hold for the semantic axis:
// The following equations and inequations hold:
//
// None <= T
// T <= Any
......@@ -40,41 +34,12 @@ namespace compiler {
// InternalizedString < String
//
// Receiver = Object \/ Proxy
// RegExp < Object
// OtherUndetectable < Object
// DetectableReceiver = Receiver - OtherUndetectable
//
// Constant(x) < T iff instance_type(map(x)) < T
//
//
// REPRESENTATIONAL DIMENSION
//
// For the representation axis, the following holds:
//
// None <= R
// R <= Any
//
// UntaggedInt = UntaggedInt1 \/ UntaggedInt8 \/
// UntaggedInt16 \/ UntaggedInt32
// UntaggedFloat = UntaggedFloat32 \/ UntaggedFloat64
// UntaggedNumber = UntaggedInt \/ UntaggedFloat
// Untagged = UntaggedNumber \/ UntaggedPtr
// Tagged = TaggedInt \/ TaggedPtr
//
// Subtyping relates the two dimensions, for example:
//
// Number <= Tagged \/ UntaggedNumber
// Object <= TaggedPtr \/ UntaggedPtr
//
// That holds because the semantic type constructors defined by the API create
// types that allow for all possible representations, and dually, the ones for
// representation types initially include all semantic ranges. Representations
// can then e.g. be narrowed for a given semantic type using intersection:
//
// SignedSmall /\ TaggedInt (a 'smi')
// Number /\ TaggedPtr (a heap number)
//
//
// RANGE TYPES
//
// A range type represents a continuous integer interval by its minimum and
......@@ -125,64 +90,37 @@ namespace compiler {
// Internally, all 'primitive' types, and their unions, are represented as
// bitsets. Bit 0 is reserved for tagging. Only structured types require
// allocation.
// Note that the bitset representation is closed under both Union and Intersect.
// -----------------------------------------------------------------------------
// Values for bitset types
// clang-format off
#define MASK_BITSET_TYPE_LIST(V) \
V(Representation, 0xffc00000u) \
V(Semantic, 0x003ffffeu)
#define REPRESENTATION(k) ((k) & BitsetType::kRepresentation)
#define SEMANTIC(k) ((k) & BitsetType::kSemantic)
#define REPRESENTATION_BITSET_TYPE_LIST(V) \
V(None, 0) \
V(UntaggedBit, 1u << 22 | kSemantic) \
V(UntaggedIntegral8, 1u << 23 | kSemantic) \
V(UntaggedIntegral16, 1u << 24 | kSemantic) \
V(UntaggedIntegral32, 1u << 25 | kSemantic) \
V(UntaggedFloat32, 1u << 26 | kSemantic) \
V(UntaggedFloat64, 1u << 27 | kSemantic) \
V(UntaggedSimd128, 1u << 28 | kSemantic) \
V(UntaggedPointer, 1u << 29 | kSemantic) \
V(TaggedSigned, 1u << 30 | kSemantic) \
V(TaggedPointer, 1u << 31 | kSemantic) \
\
V(UntaggedIntegral, kUntaggedBit | kUntaggedIntegral8 | \
kUntaggedIntegral16 | kUntaggedIntegral32) \
V(UntaggedFloat, kUntaggedFloat32 | kUntaggedFloat64) \
V(UntaggedNumber, kUntaggedIntegral | kUntaggedFloat) \
V(Untagged, kUntaggedNumber | kUntaggedPointer) \
V(Tagged, kTaggedSigned | kTaggedPointer)
#define INTERNAL_BITSET_TYPE_LIST(V) \
V(OtherUnsigned31, 1u << 1 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherUnsigned32, 1u << 2 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherSigned32, 1u << 3 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(OtherNumber, 1u << 4 | REPRESENTATION(kTagged | kUntaggedNumber))
#define SEMANTIC_BITSET_TYPE_LIST(V) \
V(Negative31, 1u << 5 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(Null, 1u << 6 | REPRESENTATION(kTaggedPointer)) \
V(Undefined, 1u << 7 | REPRESENTATION(kTaggedPointer)) \
V(Boolean, 1u << 8 | REPRESENTATION(kTaggedPointer)) \
V(Unsigned30, 1u << 9 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(MinusZero, 1u << 10 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(NaN, 1u << 11 | REPRESENTATION(kTagged | kUntaggedNumber)) \
V(Symbol, 1u << 12 | REPRESENTATION(kTaggedPointer)) \
V(InternalizedString, 1u << 13 | REPRESENTATION(kTaggedPointer)) \
V(OtherString, 1u << 14 | REPRESENTATION(kTaggedPointer)) \
V(Simd, 1u << 15 | REPRESENTATION(kTaggedPointer)) \
V(OtherObject, 1u << 17 | REPRESENTATION(kTaggedPointer)) \
V(OtherUndetectable, 1u << 16 | REPRESENTATION(kTaggedPointer)) \
V(Proxy, 1u << 18 | REPRESENTATION(kTaggedPointer)) \
V(Function, 1u << 19 | REPRESENTATION(kTaggedPointer)) \
V(Hole, 1u << 20 | REPRESENTATION(kTaggedPointer)) \
V(OtherInternal, 1u << 21 | REPRESENTATION(kTagged | kUntagged)) \
V(OtherUnsigned31, 1u << 1) \
V(OtherUnsigned32, 1u << 2) \
V(OtherSigned32, 1u << 3) \
V(OtherNumber, 1u << 4) \
#define PROPER_BITSET_TYPE_LIST(V) \
V(None, 0u) \
V(Negative31, 1u << 5) \
V(Null, 1u << 6) \
V(Undefined, 1u << 7) \
V(Boolean, 1u << 8) \
V(Unsigned30, 1u << 9) \
V(MinusZero, 1u << 10) \
V(NaN, 1u << 11) \
V(Symbol, 1u << 12) \
V(InternalizedString, 1u << 13) \
V(OtherString, 1u << 14) \
V(Simd, 1u << 15) \
V(OtherObject, 1u << 17) \
V(OtherUndetectable, 1u << 16) \
V(Proxy, 1u << 18) \
V(Function, 1u << 19) \
V(Hole, 1u << 20) \
V(OtherInternal, 1u << 21) \
\
V(Signed31, kUnsigned30 | kNegative31) \
V(Signed32, kSigned31 | kOtherUnsigned31 | kOtherSigned32) \
......@@ -243,15 +181,9 @@ namespace compiler {
* occur as part of PlainNumber.
*/
#define PROPER_BITSET_TYPE_LIST(V) \
REPRESENTATION_BITSET_TYPE_LIST(V) \
SEMANTIC_BITSET_TYPE_LIST(V)
#define BITSET_TYPE_LIST(V) \
MASK_BITSET_TYPE_LIST(V) \
REPRESENTATION_BITSET_TYPE_LIST(V) \
INTERNAL_BITSET_TYPE_LIST(V) \
SEMANTIC_BITSET_TYPE_LIST(V)
PROPER_BITSET_TYPE_LIST(V)
class Type;
......@@ -276,13 +208,7 @@ class BitsetType {
return static_cast<bitset>(reinterpret_cast<uintptr_t>(this) ^ 1u);
}
static bool IsInhabited(bitset bits) {
return SEMANTIC(bits) != kNone && REPRESENTATION(bits) != kNone;
}
static bool SemanticIsInhabited(bitset bits) {
return SEMANTIC(bits) != kNone;
}
static bool IsInhabited(bitset bits) { return bits != kNone; }
static bool Is(bitset bits1, bitset bits2) {
return (bits1 | bits2) == bits2;
......@@ -389,7 +315,6 @@ class ConstantType : public TypeBase {
Handle<i::Object> object_;
};
// TODO(neis): Also cache value if numerical.
// TODO(neis): Allow restricting the representation.
// -----------------------------------------------------------------------------
// Range types.
......@@ -415,21 +340,18 @@ class RangeType : public TypeBase {
friend class BitsetType;
friend class UnionType;
static Type* New(double min, double max, BitsetType::bitset representation,
Zone* zone) {
return New(Limits(min, max), representation, zone);
static Type* New(double min, double max, Zone* zone) {
return New(Limits(min, max), zone);
}
static bool IsInteger(double x) {
return nearbyint(x) == x && !i::IsMinusZero(x); // Allows for infinities.
}
static Type* New(Limits lim, BitsetType::bitset representation, Zone* zone) {
static Type* New(Limits lim, Zone* zone) {
DCHECK(IsInteger(lim.min) && IsInteger(lim.max));
DCHECK(lim.min <= lim.max);
DCHECK(REPRESENTATION(representation) == representation);
BitsetType::bitset bits =
SEMANTIC(BitsetType::Lub(lim.min, lim.max)) | representation;
BitsetType::bitset bits = BitsetType::Lub(lim.min, lim.max);
return AsType(new (zone->New(sizeof(RangeType))) RangeType(bits, lim));
}
......@@ -556,9 +478,7 @@ class Type {
return ConstantType::New(value, zone);
}
static Type* Range(double min, double max, Zone* zone) {
return RangeType::New(min, max, REPRESENTATION(BitsetType::kTagged |
BitsetType::kUntaggedNumber),
zone);
return RangeType::New(min, max, zone);
}
static Type* Tuple(Type* first, Type* second, Type* third, Zone* zone) {
Type* tuple = TupleType::New(3, zone);
......@@ -586,10 +506,6 @@ class Type {
}
static Type* For(i::Handle<i::Map> map) { return For(*map); }
// Extraction of components.
static Type* Representation(Type* t, Zone* zone);
static Type* Semantic(Type* t, Zone* zone);
// Predicates.
bool IsInhabited() { return BitsetType::IsInhabited(this->BitsetLub()); }
......@@ -655,9 +571,7 @@ class Type {
// Printing.
enum PrintDimension { BOTH_DIMS, SEMANTIC_DIM, REPRESENTATION_DIM };
void PrintTo(std::ostream& os, PrintDimension dim = BOTH_DIMS); // NOLINT
void PrintTo(std::ostream& os);
#ifdef DEBUG
void Print();
......@@ -690,16 +604,10 @@ class Type {
}
UnionType* AsUnion() { return UnionType::cast(this); }
bitset Representation();
// Auxiliary functions.
bool SemanticMaybe(Type* that);
bitset BitsetGlb() { return BitsetType::Glb(this); }
bitset BitsetLub() { return BitsetType::Lub(this); }
bool SlowIs(Type* that);
bool SemanticIs(Type* that);
static bool Overlap(RangeType* lhs, RangeType* rhs);
static bool Contains(RangeType* lhs, RangeType* rhs);
......
......@@ -187,72 +187,6 @@ struct Tests {
}
}
void PointwiseRepresentation() {
// Check we can decompose type into semantics and representation and
// then compose it back to get an equivalent type.
int counter = 0;
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
counter++;
Type* type1 = *it1;
Type* representation = T.Representation(type1);
Type* semantic = T.Semantic(type1);
Type* composed = T.Union(representation, semantic);
CHECK(type1->Equals(composed));
}
// Pointwiseness of Union.
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
Type* type1 = *it1;
Type* type2 = *it2;
Type* representation1 = T.Representation(type1);
Type* semantic1 = T.Semantic(type1);
Type* representation2 = T.Representation(type2);
Type* semantic2 = T.Semantic(type2);
Type* direct_union = T.Union(type1, type2);
Type* representation_union = T.Union(representation1, representation2);
Type* semantic_union = T.Union(semantic1, semantic2);
Type* composed_union = T.Union(representation_union, semantic_union);
CHECK(direct_union->Equals(composed_union));
}
}
// Pointwiseness of Intersect.
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
Type* type1 = *it1;
Type* type2 = *it2;
Type* representation1 = T.Representation(type1);
Type* semantic1 = T.Semantic(type1);
Type* representation2 = T.Representation(type2);
Type* semantic2 = T.Semantic(type2);
Type* direct_intersection = T.Intersect(type1, type2);
Type* representation_intersection =
T.Intersect(representation1, representation2);
Type* semantic_intersection = T.Intersect(semantic1, semantic2);
Type* composed_intersection =
T.Union(representation_intersection, semantic_intersection);
CHECK(direct_intersection->Equals(composed_intersection));
}
}
// Pointwiseness of Is.
for (TypeIterator it1 = T.types.begin(); it1 != T.types.end(); ++it1) {
for (TypeIterator it2 = T.types.begin(); it2 != T.types.end(); ++it2) {
Type* type1 = *it1;
Type* type2 = *it2;
Type* representation1 = T.Representation(type1);
Type* semantic1 = T.Semantic(type1);
Type* representation2 = T.Representation(type2);
Type* semantic2 = T.Semantic(type2);
bool representation_is = representation1->Is(representation2);
bool semantic_is = semantic1->Is(semantic2);
bool direct_is = type1->Is(type2);
CHECK(direct_is == (semantic_is && representation_is));
}
}
}
void Constant() {
// Constructor
for (ValueIterator vt = T.values.begin(); vt != T.values.end(); ++vt) {
......@@ -1153,8 +1087,6 @@ struct Tests {
TEST(IsSomeType) { Tests().IsSomeType(); }
TEST(PointwiseRepresentation) { Tests().PointwiseRepresentation(); }
TEST(BitsetType) { Tests().Bitset(); }
TEST(ConstantType) { Tests().Constant(); }
......
......@@ -108,9 +108,6 @@ class Types {
PROPER_BITSET_TYPE_LIST(DECLARE_TYPE)
#undef DECLARE_TYPE
#define DECLARE_TYPE(name, value) Type* Mask##name##ForTesting;
MASK_BITSET_TYPE_LIST(DECLARE_TYPE)
#undef DECLARE_TYPE
Type* SignedSmall;
Type* UnsignedSmall;
......@@ -142,10 +139,6 @@ class Types {
Type* Intersect(Type* t1, Type* t2) { return Type::Intersect(t1, t2, zone_); }
Type* Representation(Type* t) { return Type::Representation(t, zone_); }
Type* Semantic(Type* t) { return Type::Semantic(t, zone_); }
Type* Random() {
return types[rng_->NextInt(static_cast<int>(types.size()))];
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment