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; |