| Index: src/compiler/representation-change.cc
|
| diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc
|
| index bc0850f43af271f68bd2fdfd92eb143bd0ac1701..01ca8d3732f6f13883173e5ce89a2c0035bee343 100644
|
| --- a/src/compiler/representation-change.cc
|
| +++ b/src/compiler/representation-change.cc
|
| @@ -107,23 +107,22 @@ bool IsWord(MachineRepresentation rep) {
|
| } // namespace
|
|
|
|
|
| -// Changes representation from {output_type} to {use_rep}. The {truncation}
|
| +// Changes representation from {output_rep} to {use_rep}. The {truncation}
|
| // parameter is only used for sanity checking - if the changer cannot figure
|
| // out signedness for the word32->float64 conversion, then we check that the
|
| // uses truncate to word32 (so they do not care about signedness).
|
| -Node* RepresentationChanger::GetRepresentationFor(Node* node,
|
| - MachineType output_type,
|
| - MachineRepresentation use_rep,
|
| - Truncation truncation) {
|
| - if (output_type.representation() == MachineRepresentation::kNone) {
|
| +Node* RepresentationChanger::GetRepresentationFor(
|
| + Node* node, MachineRepresentation output_rep, Type* output_type,
|
| + MachineRepresentation use_rep, Truncation truncation) {
|
| + if (output_rep == MachineRepresentation::kNone) {
|
| // The output representation should be set.
|
| - return TypeError(node, output_type, use_rep);
|
| + return TypeError(node, output_rep, output_type, use_rep);
|
| }
|
| - if (use_rep == output_type.representation()) {
|
| + if (use_rep == output_rep) {
|
| // Representations are the same. That's a no-op.
|
| return node;
|
| }
|
| - if (IsWord(use_rep) && IsWord(output_type.representation())) {
|
| + if (IsWord(use_rep) && IsWord(output_rep)) {
|
| // 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,
|
| @@ -132,19 +131,21 @@ Node* RepresentationChanger::GetRepresentationFor(Node* node,
|
| }
|
| switch (use_rep) {
|
| case MachineRepresentation::kTagged:
|
| - return GetTaggedRepresentationFor(node, output_type);
|
| + return GetTaggedRepresentationFor(node, output_rep, output_type);
|
| case MachineRepresentation::kFloat32:
|
| - return GetFloat32RepresentationFor(node, output_type, truncation);
|
| + return GetFloat32RepresentationFor(node, output_rep, output_type,
|
| + truncation);
|
| case MachineRepresentation::kFloat64:
|
| - return GetFloat64RepresentationFor(node, output_type, truncation);
|
| + return GetFloat64RepresentationFor(node, output_rep, output_type,
|
| + truncation);
|
| case MachineRepresentation::kBit:
|
| - return GetBitRepresentationFor(node, output_type);
|
| + return GetBitRepresentationFor(node, output_rep, output_type);
|
| case MachineRepresentation::kWord8:
|
| case MachineRepresentation::kWord16:
|
| case MachineRepresentation::kWord32:
|
| - return GetWord32RepresentationFor(node, output_type);
|
| + return GetWord32RepresentationFor(node, output_rep, output_type);
|
| case MachineRepresentation::kWord64:
|
| - return GetWord64RepresentationFor(node, output_type);
|
| + return GetWord64RepresentationFor(node, output_rep, output_type);
|
| case MachineRepresentation::kNone:
|
| return node;
|
| }
|
| @@ -154,24 +155,25 @@ Node* RepresentationChanger::GetRepresentationFor(Node* node,
|
|
|
|
|
| Node* RepresentationChanger::GetTaggedRepresentationFor(
|
| - Node* node, MachineType output_type) {
|
| + Node* node, MachineRepresentation output_rep, Type* output_type) {
|
| // Eagerly fold representation changes for constants.
|
| switch (node->opcode()) {
|
| case IrOpcode::kNumberConstant:
|
| case IrOpcode::kHeapConstant:
|
| return node; // No change necessary.
|
| case IrOpcode::kInt32Constant:
|
| - if (output_type.semantic() == MachineSemantic::kUint32) {
|
| - uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
|
| - return jsgraph()->Constant(static_cast<double>(value));
|
| - } else if (output_type.semantic() == MachineSemantic::kInt32) {
|
| + if (output_type->Is(Type::Signed32())) {
|
| int32_t value = OpParameter<int32_t>(node);
|
| return jsgraph()->Constant(value);
|
| - } else if (output_type.representation() == MachineRepresentation::kBit) {
|
| + } else if (output_type->Is(Type::Unsigned32())) {
|
| + uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
|
| + return jsgraph()->Constant(static_cast<double>(value));
|
| + } else if (output_rep == MachineRepresentation::kBit) {
|
| return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
|
| : jsgraph()->TrueConstant();
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kTagged);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kTagged);
|
| }
|
| case IrOpcode::kFloat64Constant:
|
| return jsgraph()->Constant(OpParameter<double>(node));
|
| @@ -182,31 +184,34 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
|
| }
|
| // Select the correct X -> Tagged operator.
|
| const Operator* op;
|
| - if (output_type.representation() == MachineRepresentation::kBit) {
|
| + if (output_rep == MachineRepresentation::kBit) {
|
| op = simplified()->ChangeBitToBool();
|
| - } else if (IsWord(output_type.representation())) {
|
| - if (output_type.semantic() == MachineSemantic::kUint32) {
|
| + } else if (IsWord(output_rep)) {
|
| + if (output_type->Is(Type::Unsigned32())) {
|
| op = simplified()->ChangeUint32ToTagged();
|
| - } else if (output_type.semantic() == MachineSemantic::kInt32) {
|
| + } else if (output_type->Is(Type::Signed32())) {
|
| op = simplified()->ChangeInt32ToTagged();
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kTagged);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kTagged);
|
| }
|
| - } else if (output_type.representation() ==
|
| + } else if (output_rep ==
|
| MachineRepresentation::kFloat32) { // float32 -> float64 -> tagged
|
| node = InsertChangeFloat32ToFloat64(node);
|
| op = simplified()->ChangeFloat64ToTagged();
|
| - } else if (output_type.representation() == MachineRepresentation::kFloat64) {
|
| + } else if (output_rep == MachineRepresentation::kFloat64) {
|
| op = simplified()->ChangeFloat64ToTagged();
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kTagged);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kTagged);
|
| }
|
| return jsgraph()->graph()->NewNode(op, node);
|
| }
|
|
|
|
|
| Node* RepresentationChanger::GetFloat32RepresentationFor(
|
| - Node* node, MachineType output_type, Truncation truncation) {
|
| + Node* node, MachineRepresentation output_rep, Type* output_type,
|
| + Truncation truncation) {
|
| // Eagerly fold representation changes for constants.
|
| switch (node->opcode()) {
|
| case IrOpcode::kFloat64Constant:
|
| @@ -214,7 +219,7 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
|
| return jsgraph()->Float32Constant(
|
| DoubleToFloat32(OpParameter<double>(node)));
|
| case IrOpcode::kInt32Constant:
|
| - if (output_type.semantic() == MachineSemantic::kUint32) {
|
| + if (output_type->Is(Type::Unsigned32())) {
|
| uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
|
| return jsgraph()->Float32Constant(static_cast<float>(value));
|
| } else {
|
| @@ -228,47 +233,51 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
|
| }
|
| // Select the correct X -> Float32 operator.
|
| const Operator* op;
|
| - if (output_type.representation() == MachineRepresentation::kBit) {
|
| - return TypeError(node, output_type, MachineRepresentation::kFloat32);
|
| - } else if (IsWord(output_type.representation())) {
|
| - if (output_type.semantic() == MachineSemantic::kUint32) {
|
| - op = machine()->ChangeUint32ToFloat64();
|
| + if (output_rep == MachineRepresentation::kBit) {
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kFloat32);
|
| + } else if (IsWord(output_rep)) {
|
| + if (output_type->Is(Type::Signed32())) {
|
| + op = machine()->ChangeInt32ToFloat64();
|
| } else {
|
| // Either the output is int32 or the uses only care about the
|
| // low 32 bits (so we can pick int32 safely).
|
| - DCHECK(output_type.semantic() == MachineSemantic::kInt32 ||
|
| + DCHECK(output_type->Is(Type::Unsigned32()) ||
|
| truncation.TruncatesToWord32());
|
| - op = machine()->ChangeInt32ToFloat64();
|
| + op = machine()->ChangeUint32ToFloat64();
|
| }
|
| // int32 -> float64 -> float32
|
| node = jsgraph()->graph()->NewNode(op, node);
|
| op = machine()->TruncateFloat64ToFloat32();
|
| - } else if (output_type.representation() == MachineRepresentation::kTagged) {
|
| + } else if (output_rep == MachineRepresentation::kTagged) {
|
| op = simplified()->ChangeTaggedToFloat64(); // tagged -> float64 -> float32
|
| node = jsgraph()->graph()->NewNode(op, node);
|
| op = machine()->TruncateFloat64ToFloat32();
|
| - } else if (output_type.representation() == MachineRepresentation::kFloat64) {
|
| + } else if (output_rep == MachineRepresentation::kFloat64) {
|
| op = machine()->TruncateFloat64ToFloat32();
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kFloat32);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kFloat32);
|
| }
|
| return jsgraph()->graph()->NewNode(op, node);
|
| }
|
|
|
|
|
| Node* RepresentationChanger::GetFloat64RepresentationFor(
|
| - Node* node, MachineType output_type, Truncation truncation) {
|
| + Node* node, MachineRepresentation output_rep, Type* output_type,
|
| + Truncation truncation) {
|
| // Eagerly fold representation changes for constants.
|
| switch (node->opcode()) {
|
| case IrOpcode::kNumberConstant:
|
| return jsgraph()->Float64Constant(OpParameter<double>(node));
|
| case IrOpcode::kInt32Constant:
|
| - if (output_type.semantic() == MachineSemantic::kUint32) {
|
| - uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
|
| - return jsgraph()->Float64Constant(static_cast<double>(value));
|
| - } else {
|
| + if (output_type->Is(Type::Signed32())) {
|
| int32_t value = OpParameter<int32_t>(node);
|
| return jsgraph()->Float64Constant(value);
|
| + } else {
|
| + DCHECK(output_type->Is(Type::Unsigned32()));
|
| + uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node));
|
| + return jsgraph()->Float64Constant(static_cast<double>(value));
|
| }
|
| case IrOpcode::kFloat64Constant:
|
| return node; // No change necessary.
|
| @@ -279,24 +288,26 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
|
| }
|
| // Select the correct X -> Float64 operator.
|
| const Operator* op;
|
| - if (output_type.representation() == MachineRepresentation::kBit) {
|
| - return TypeError(node, output_type, MachineRepresentation::kFloat64);
|
| - } else if (IsWord(output_type.representation())) {
|
| - if (output_type.semantic() == MachineSemantic::kUint32) {
|
| - op = machine()->ChangeUint32ToFloat64();
|
| + if (output_rep == MachineRepresentation::kBit) {
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kFloat64);
|
| + } else if (IsWord(output_rep)) {
|
| + if (output_type->Is(Type::Signed32())) {
|
| + op = machine()->ChangeInt32ToFloat64();
|
| } else {
|
| // Either the output is int32 or the uses only care about the
|
| // low 32 bits (so we can pick int32 safely).
|
| - DCHECK(output_type.semantic() == MachineSemantic::kInt32 ||
|
| + DCHECK(output_type->Is(Type::Unsigned32()) ||
|
| truncation.TruncatesToWord32());
|
| - op = machine()->ChangeInt32ToFloat64();
|
| + op = machine()->ChangeUint32ToFloat64();
|
| }
|
| - } else if (output_type.representation() == MachineRepresentation::kTagged) {
|
| + } else if (output_rep == MachineRepresentation::kTagged) {
|
| op = simplified()->ChangeTaggedToFloat64();
|
| - } else if (output_type.representation() == MachineRepresentation::kFloat32) {
|
| + } else if (output_rep == MachineRepresentation::kFloat32) {
|
| op = machine()->ChangeFloat32ToFloat64();
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kFloat64);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kFloat64);
|
| }
|
| return jsgraph()->graph()->NewNode(op, node);
|
| }
|
| @@ -308,7 +319,7 @@ Node* RepresentationChanger::MakeTruncatedInt32Constant(double value) {
|
|
|
|
|
| Node* RepresentationChanger::GetWord32RepresentationFor(
|
| - Node* node, MachineType output_type) {
|
| + Node* node, MachineRepresentation output_rep, Type* output_type) {
|
| // Eagerly fold representation changes for constants.
|
| switch (node->opcode()) {
|
| case IrOpcode::kInt32Constant:
|
| @@ -325,34 +336,33 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
|
| const Operator* op;
|
| Type* type = NodeProperties::GetType(node);
|
|
|
| - if (output_type.representation() == MachineRepresentation::kBit) {
|
| + if (output_rep == MachineRepresentation::kBit) {
|
| return node; // Sloppy comparison -> word32
|
| - } else if (output_type.representation() == MachineRepresentation::kFloat64) {
|
| - if (output_type.semantic() == MachineSemantic::kUint32 ||
|
| - type->Is(Type::Unsigned32())) {
|
| + } else if (output_rep == MachineRepresentation::kFloat64) {
|
| + // TODO(jarin) Use only output_type here, once we intersect it with the
|
| + // type inferred by the typer.
|
| + if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
|
| op = machine()->ChangeFloat64ToUint32();
|
| - } else if (output_type.semantic() == MachineSemantic::kInt32 ||
|
| + } else if (output_type->Is(Type::Signed32()) ||
|
| type->Is(Type::Signed32())) {
|
| op = machine()->ChangeFloat64ToInt32();
|
| } else {
|
| op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
|
| }
|
| - } else if (output_type.representation() == MachineRepresentation::kFloat32) {
|
| + } else if (output_rep == MachineRepresentation::kFloat32) {
|
| node = InsertChangeFloat32ToFloat64(node); // float32 -> float64 -> int32
|
| - if (output_type.semantic() == MachineSemantic::kUint32 ||
|
| - type->Is(Type::Unsigned32())) {
|
| + if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
|
| op = machine()->ChangeFloat64ToUint32();
|
| - } else if (output_type.semantic() == MachineSemantic::kInt32 ||
|
| + } else if (output_type->Is(Type::Signed32()) ||
|
| type->Is(Type::Signed32())) {
|
| op = machine()->ChangeFloat64ToInt32();
|
| } else {
|
| op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
|
| }
|
| - } else if (output_type.representation() == MachineRepresentation::kTagged) {
|
| - if (output_type.semantic() == MachineSemantic::kUint32 ||
|
| - type->Is(Type::Unsigned32())) {
|
| + } else if (output_rep == MachineRepresentation::kTagged) {
|
| + if (output_type->Is(Type::Unsigned32()) || type->Is(Type::Unsigned32())) {
|
| op = simplified()->ChangeTaggedToUint32();
|
| - } else if (output_type.semantic() == MachineSemantic::kInt32 ||
|
| + } else if (output_type->Is(Type::Signed32()) ||
|
| type->Is(Type::Signed32())) {
|
| op = simplified()->ChangeTaggedToInt32();
|
| } else {
|
| @@ -360,14 +370,15 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
|
| op = machine()->TruncateFloat64ToInt32(TruncationMode::kJavaScript);
|
| }
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kWord32);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kWord32);
|
| }
|
| return jsgraph()->graph()->NewNode(op, node);
|
| }
|
|
|
|
|
| -Node* RepresentationChanger::GetBitRepresentationFor(Node* node,
|
| - MachineType output_type) {
|
| +Node* RepresentationChanger::GetBitRepresentationFor(
|
| + Node* node, MachineRepresentation output_rep, Type* output_type) {
|
| // Eagerly fold representation changes for constants.
|
| switch (node->opcode()) {
|
| case IrOpcode::kHeapConstant: {
|
| @@ -382,22 +393,24 @@ Node* RepresentationChanger::GetBitRepresentationFor(Node* node,
|
| }
|
| // Select the correct X -> Bit operator.
|
| const Operator* op;
|
| - if (output_type.representation() == MachineRepresentation::kTagged) {
|
| + if (output_rep == MachineRepresentation::kTagged) {
|
| op = simplified()->ChangeBoolToBit();
|
| } else {
|
| - return TypeError(node, output_type, MachineRepresentation::kBit);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kBit);
|
| }
|
| return jsgraph()->graph()->NewNode(op, node);
|
| }
|
|
|
|
|
| Node* RepresentationChanger::GetWord64RepresentationFor(
|
| - Node* node, MachineType output_type) {
|
| - if (output_type.representation() == MachineRepresentation::kBit) {
|
| + Node* node, MachineRepresentation output_rep, Type* output_type) {
|
| + if (output_rep == MachineRepresentation::kBit) {
|
| return node; // Sloppy comparison -> word64
|
| }
|
| // Can't really convert Word64 to anything else. Purported to be internal.
|
| - return TypeError(node, output_type, MachineRepresentation::kWord64);
|
| + return TypeError(node, output_rep, output_type,
|
| + MachineRepresentation::kWord64);
|
| }
|
|
|
|
|
| @@ -485,22 +498,16 @@ const Operator* RepresentationChanger::Float64OperatorFor(
|
| }
|
|
|
|
|
| -MachineSemantic RepresentationChanger::TypeFromUpperBound(Type* type) {
|
| - CHECK(!type->Is(Type::None()));
|
| - if (type->Is(Type::Signed32())) return MachineSemantic::kInt32;
|
| - if (type->Is(Type::Unsigned32())) return MachineSemantic::kUint32;
|
| - if (type->Is(Type::Number())) return MachineSemantic::kNumber;
|
| - if (type->Is(Type::Boolean())) return MachineSemantic::kBool;
|
| - return MachineSemantic::kAny;
|
| -}
|
| -
|
| -
|
| -Node* RepresentationChanger::TypeError(Node* node, MachineType output_type,
|
| +Node* RepresentationChanger::TypeError(Node* node,
|
| + MachineRepresentation output_rep,
|
| + Type* output_type,
|
| MachineRepresentation use) {
|
| type_error_ = true;
|
| if (!testing_type_errors_) {
|
| std::ostringstream out_str;
|
| - out_str << output_type;
|
| + out_str << output_rep << " (";
|
| + output_type->PrintTo(out_str, Type::SEMANTIC_DIM);
|
| + out_str << ")";
|
|
|
| std::ostringstream use_str;
|
| use_str << use;
|
|
|