Index: src/compiler/representation-change.h |
diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h |
index bd5fb5f79349b7abf95233f7bcf7d0111b98267a..9bdccfc67d213543913cef9c08dc45d7bfb11ff0 100644 |
--- a/src/compiler/representation-change.h |
+++ b/src/compiler/representation-change.h |
@@ -14,50 +14,6 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-// The types and representations tracked during representation inference |
-// and change insertion. |
-// TODO(titzer): First, merge MachineType and RepType. |
-// TODO(titzer): Second, Use the real type system instead of RepType. |
-enum RepType { |
- // Representations. |
- rBit = 1 << 0, |
- rWord32 = 1 << 1, |
- rWord64 = 1 << 2, |
- rFloat64 = 1 << 3, |
- rTagged = 1 << 4, |
- |
- // Types. |
- tBool = 1 << 5, |
- tInt32 = 1 << 6, |
- tUint32 = 1 << 7, |
- tInt64 = 1 << 8, |
- tUint64 = 1 << 9, |
- tNumber = 1 << 10, |
- tAny = 1 << 11 |
-}; |
- |
-#define REP_TYPE_STRLEN 24 |
- |
-typedef uint16_t RepTypeUnion; |
- |
- |
-inline void RenderRepTypeUnion(char* buf, RepTypeUnion info) { |
- base::OS::SNPrintF(buf, REP_TYPE_STRLEN, "{%s%s%s%s%s %s%s%s%s%s%s%s}", |
- (info & rBit) ? "k" : " ", (info & rWord32) ? "w" : " ", |
- (info & rWord64) ? "q" : " ", |
- (info & rFloat64) ? "f" : " ", |
- (info & rTagged) ? "t" : " ", (info & tBool) ? "Z" : " ", |
- (info & tInt32) ? "I" : " ", (info & tUint32) ? "U" : " ", |
- (info & tInt64) ? "L" : " ", (info & tUint64) ? "J" : " ", |
- (info & tNumber) ? "N" : " ", (info & tAny) ? "*" : " "); |
-} |
- |
- |
-const RepTypeUnion rMask = rBit | rWord32 | rWord64 | rFloat64 | rTagged; |
-const RepTypeUnion tMask = |
- tBool | tInt32 | tUint32 | tInt64 | tUint64 | tNumber | tAny; |
-const RepType rPtr = kPointerSize == 4 ? rWord32 : rWord64; |
- |
// Contains logic related to changing the representation of values for constants |
// and other nodes, as well as lowering Simplified->Machine operators. |
// Eagerly folds any representation changes for constants. |
@@ -72,9 +28,11 @@ class RepresentationChanger { |
testing_type_errors_(false), |
type_error_(false) {} |
+ // TODO(titzer): should Word64 also be implicitly convertable to others? |
+ static const MachineTypeUnion rWord = rBit | rWord8 | rWord16 | rWord32; |
- Node* GetRepresentationFor(Node* node, RepTypeUnion output_type, |
- RepTypeUnion use_type) { |
+ Node* GetRepresentationFor(Node* node, MachineTypeUnion output_type, |
+ MachineTypeUnion use_type) { |
if (!IsPowerOf2(output_type & rMask)) { |
// There should be only one output representation. |
return TypeError(node, output_type, use_type); |
@@ -83,14 +41,21 @@ class RepresentationChanger { |
// Representations are the same. That's a no-op. |
return node; |
} |
+ if ((use_type & rWord) && (output_type & rWord)) { |
+ // Both are words less than or equal to 32-bits. |
+ // Since loads of integers from memory implicitly sign or zero extend the |
+ // value to the full machine word size and stores implicitly truncate, |
+ // no representation change is necessary. |
+ return node; |
+ } |
if (use_type & rTagged) { |
return GetTaggedRepresentationFor(node, output_type); |
} else if (use_type & rFloat64) { |
return GetFloat64RepresentationFor(node, output_type); |
- } else if (use_type & rWord32) { |
- return GetWord32RepresentationFor(node, output_type, use_type & tUint32); |
} else if (use_type & rBit) { |
return GetBitRepresentationFor(node, output_type); |
+ } else if (use_type & rWord) { |
+ return GetWord32RepresentationFor(node, output_type, use_type & tUint32); |
} else if (use_type & rWord64) { |
return GetWord64RepresentationFor(node, output_type); |
} else { |
@@ -98,7 +63,7 @@ class RepresentationChanger { |
} |
} |
- Node* GetTaggedRepresentationFor(Node* node, RepTypeUnion output_type) { |
+ Node* GetTaggedRepresentationFor(Node* node, MachineTypeUnion output_type) { |
// Eagerly fold representation changes for constants. |
switch (node->opcode()) { |
case IrOpcode::kNumberConstant: |
@@ -126,7 +91,7 @@ class RepresentationChanger { |
Operator* op; |
if (output_type & rBit) { |
op = simplified()->ChangeBitToBool(); |
- } else if (output_type & rWord32) { |
+ } else if (output_type & rWord) { |
if (output_type & tUint32) { |
op = simplified()->ChangeUint32ToTagged(); |
} else if (output_type & tInt32) { |
@@ -142,7 +107,7 @@ class RepresentationChanger { |
return jsgraph()->graph()->NewNode(op, node); |
} |
- Node* GetFloat64RepresentationFor(Node* node, RepTypeUnion output_type) { |
+ Node* GetFloat64RepresentationFor(Node* node, MachineTypeUnion output_type) { |
// Eagerly fold representation changes for constants. |
switch (node->opcode()) { |
case IrOpcode::kNumberConstant: |
@@ -162,7 +127,9 @@ class RepresentationChanger { |
} |
// Select the correct X -> Float64 operator. |
Operator* op; |
- if (output_type & rWord32) { |
+ if (output_type & rBit) { |
+ return TypeError(node, output_type, rFloat64); |
+ } else if (output_type & rWord) { |
if (output_type & tUint32) { |
op = machine()->ChangeUint32ToFloat64(); |
} else { |
@@ -176,7 +143,7 @@ class RepresentationChanger { |
return jsgraph()->graph()->NewNode(op, node); |
} |
- Node* GetWord32RepresentationFor(Node* node, RepTypeUnion output_type, |
+ Node* GetWord32RepresentationFor(Node* node, MachineTypeUnion output_type, |
bool use_unsigned) { |
// Eagerly fold representation changes for constants. |
switch (node->opcode()) { |
@@ -212,15 +179,13 @@ class RepresentationChanger { |
} else { |
op = simplified()->ChangeTaggedToInt32(); |
} |
- } else if (output_type & rBit) { |
- return node; // Sloppy comparison -> word32. |
} else { |
return TypeError(node, output_type, rWord32); |
} |
return jsgraph()->graph()->NewNode(op, node); |
} |
- Node* GetBitRepresentationFor(Node* node, RepTypeUnion output_type) { |
+ Node* GetBitRepresentationFor(Node* node, MachineTypeUnion output_type) { |
// Eagerly fold representation changes for constants. |
switch (node->opcode()) { |
case IrOpcode::kInt32Constant: { |
@@ -240,7 +205,7 @@ class RepresentationChanger { |
} |
// Select the correct X -> Bit operator. |
Operator* op; |
- if (output_type & rWord32) { |
+ if (output_type & rWord) { |
return node; // No change necessary. |
} else if (output_type & rWord64) { |
return node; // TODO(titzer): No change necessary, on 64-bit. |
@@ -252,7 +217,7 @@ class RepresentationChanger { |
return jsgraph()->graph()->NewNode(op, node); |
} |
- Node* GetWord64RepresentationFor(Node* node, RepTypeUnion output_type) { |
+ Node* GetWord64RepresentationFor(Node* node, MachineTypeUnion output_type) { |
if (output_type & rBit) { |
return node; // Sloppy comparison -> word64 |
} |
@@ -260,27 +225,6 @@ class RepresentationChanger { |
return TypeError(node, output_type, rWord64); |
} |
- static RepType TypeForMachineType(MachineType rep) { |
- // TODO(titzer): merge MachineType and RepType. |
- switch (rep) { |
- case kMachineWord8: |
- return rWord32; |
- case kMachineWord16: |
- return rWord32; |
- case kMachineWord32: |
- return rWord32; |
- case kMachineWord64: |
- return rWord64; |
- case kMachineFloat64: |
- return rFloat64; |
- case kMachineTagged: |
- return rTagged; |
- default: |
- UNREACHABLE(); |
- return static_cast<RepType>(0); |
- } |
- } |
- |
Operator* Int32OperatorFor(IrOpcode::Value opcode) { |
switch (opcode) { |
case IrOpcode::kNumberAdd: |
@@ -341,29 +285,15 @@ class RepresentationChanger { |
} |
} |
- RepType TypeForField(const FieldAccess& access) { |
- RepType tElement = static_cast<RepType>(0); // TODO(titzer) |
- RepType rElement = TypeForMachineType(access.representation); |
- return static_cast<RepType>(tElement | rElement); |
+ MachineType TypeForBasePointer(const FieldAccess& access) { |
+ return access.tag() != 0 ? mAnyTagged : mPtr; |
} |
- RepType TypeForElement(const ElementAccess& access) { |
- RepType tElement = static_cast<RepType>(0); // TODO(titzer) |
- RepType rElement = TypeForMachineType(access.representation); |
- return static_cast<RepType>(tElement | rElement); |
+ MachineType TypeForBasePointer(const ElementAccess& access) { |
+ return access.tag() != 0 ? mAnyTagged : mPtr; |
} |
- RepType TypeForBasePointer(const FieldAccess& access) { |
- if (access.tag() != 0) return static_cast<RepType>(tAny | rTagged); |
- return kPointerSize == 8 ? rWord64 : rWord32; |
- } |
- |
- RepType TypeForBasePointer(const ElementAccess& access) { |
- if (access.tag() != 0) return static_cast<RepType>(tAny | rTagged); |
- return kPointerSize == 8 ? rWord64 : rWord32; |
- } |
- |
- RepType TypeFromUpperBound(Type* type) { |
+ MachineType TypeFromUpperBound(Type* type) { |
if (type->Is(Type::None())) |
return tAny; // TODO(titzer): should be an error |
if (type->Is(Type::Signed32())) return tInt32; |
@@ -384,17 +314,21 @@ class RepresentationChanger { |
bool testing_type_errors_; // If {true}, don't abort on a type error. |
bool type_error_; // Set when a type error is detected. |
- Node* TypeError(Node* node, RepTypeUnion output_type, RepTypeUnion use) { |
+ Node* TypeError(Node* node, MachineTypeUnion output_type, |
+ MachineTypeUnion use) { |
type_error_ = true; |
if (!testing_type_errors_) { |
- char buf1[REP_TYPE_STRLEN]; |
- char buf2[REP_TYPE_STRLEN]; |
- RenderRepTypeUnion(buf1, output_type); |
- RenderRepTypeUnion(buf2, use); |
+ OStringStream out_str; |
+ PrintMachineTypeUnionTo(out_str, output_type); |
+ |
+ OStringStream use_str; |
+ PrintMachineTypeUnionTo(use_str, use); |
+ |
V8_Fatal(__FILE__, __LINE__, |
- "RepresentationChangerError: node #%d:%s of rep" |
- "%s cannot be changed to rep%s", |
- node->id(), node->op()->mnemonic(), buf1, buf2); |
+ "RepresentationChangerError: node #%d:%s of " |
+ "%s cannot be changed to %s", |
+ node->id(), node->op()->mnemonic(), out_str.c_str(), |
+ use_str.c_str()); |
} |
return node; |
} |