Index: src/compiler/representation-change.cc |
diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc |
index 5427bdb1cd83bcd8589cfaf860df8004e6c498f7..95db495a69eff906c1c9daa004fc2115778f39e6 100644 |
--- a/src/compiler/representation-change.cc |
+++ b/src/compiler/representation-change.cc |
@@ -142,7 +142,11 @@ Node* RepresentationChanger::GetRepresentationFor( |
switch (use_info.representation()) { |
case MachineRepresentation::kTaggedSigned: |
+ DCHECK(use_info.type_check() == TypeCheckKind::kNone); |
+ return GetTaggedSignedRepresentationFor(node, output_rep, output_type); |
case MachineRepresentation::kTaggedPointer: |
+ DCHECK(use_info.type_check() == TypeCheckKind::kNone); |
+ return GetTaggedPointerRepresentationFor(node, output_rep, output_type); |
case MachineRepresentation::kTagged: |
DCHECK(use_info.type_check() == TypeCheckKind::kNone); |
return GetTaggedRepresentationFor(node, output_rep, output_type); |
@@ -174,6 +178,129 @@ Node* RepresentationChanger::GetRepresentationFor( |
return nullptr; |
} |
+Node* RepresentationChanger::GetTaggedSignedRepresentationFor( |
+ Node* node, MachineRepresentation output_rep, Type* output_type) { |
+ // Eagerly fold representation changes for constants. |
+ switch (node->opcode()) { |
+ case IrOpcode::kNumberConstant: { |
+ int32_t value = OpParameter<int32_t>(node); |
+ if (Smi::IsValid(value)) { |
+ return jsgraph()->Constant(value); |
+ } |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ } |
+ case IrOpcode::kHeapConstant: |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ case IrOpcode::kInt32Constant: |
+ if (output_type->Is(Type::SignedSmall())) { |
+ int32_t value = OpParameter<int32_t>(node); |
+ return jsgraph()->Constant(value); |
+ } else if (output_type->Is(Type::Unsigned32())) { |
+ uint32_t value = static_cast<uint32_t>(OpParameter<int32_t>(node)); |
+ if (Smi::IsValid(value)) { |
+ return jsgraph()->Constant(static_cast<double>(value)); |
Jarin
2016/08/25 05:52:05
Actually, do we ever get here? I would think that
mvstanton
2016/08/29 12:02:10
Done.
|
+ } else { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ } |
+ } else { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ } |
+ case IrOpcode::kFloat64Constant: |
+ case IrOpcode::kFloat32Constant: |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ default: |
+ break; |
+ } |
+ // Select the correct X -> Tagged operator. |
+ const Operator* op; |
+ if (output_rep == MachineRepresentation::kNone) { |
+ // We should only asisgn this representation if the type is empty. |
+ CHECK(!output_type->IsInhabited()); |
+ // consider producing a smi 0 here instead of all the impossible to whatever |
+ // boilerplate. |
+ op = machine()->ImpossibleToTaggedSigned(); |
+ } else if (IsWord(output_rep)) { |
+ if (output_type->Is(Type::Signed31())) { |
+ op = simplified()->ChangeInt31ToTaggedSigned(); |
+ } else if (machine()->Is64() && output_type->Is(Type::Signed32())) { |
+ op = simplified()->ChangeInt32ToTagged(); |
+ } else { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ } |
+ } else { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ } |
+ return jsgraph()->graph()->NewNode(op, node); |
+} |
+ |
+Node* RepresentationChanger::GetTaggedPointerRepresentationFor( |
+ Node* node, MachineRepresentation output_rep, Type* output_type) { |
+ // Eagerly fold representation changes for constants. |
+ switch (node->opcode()) { |
+ case IrOpcode::kHeapConstant: |
+ return node; // No change necessary. |
+ case IrOpcode::kInt32Constant: |
+ if (output_type->Is(Type::Boolean())) { |
+ return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant() |
+ : jsgraph()->TrueConstant(); |
+ } else { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedPointer); |
+ } |
+ case IrOpcode::kFloat64Constant: |
+ return jsgraph()->Constant(OpParameter<double>(node)); |
Jarin
2016/08/25 05:52:05
I do not think this guarantees non-smi. Can't we j
mvstanton
2016/08/29 12:02:10
Good point, this and kFloat32Constant now would pr
|
+ case IrOpcode::kFloat32Constant: |
+ return jsgraph()->Constant(OpParameter<float>(node)); |
+ default: |
+ break; |
+ } |
+ if (output_rep == MachineRepresentation::kTagged) { |
Jarin
2016/08/25 05:52:05
Out of curiosity, do we ever get here?
mvstanton
2016/08/29 12:02:10
Nope, I've removed it, thanks for the general thru
|
+ // It's a no-op as long as the output_type is not in smi range. |
+ // True, we could convert the smi to a heap number, but let's be |
+ // conservative. |
+ if (output_type->Maybe(Type::SignedSmall())) { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedPointer); |
+ } |
+ return node; |
+ } |
+ // Select the correct X -> Tagged operator. |
+ const Operator* op; |
+ if (output_rep == MachineRepresentation::kNone) { |
+ // We should only asisgn this representation if the type is empty. |
+ CHECK(!output_type->IsInhabited()); |
+ op = machine()->ImpossibleToTaggedPointer(); |
+ } else if (output_rep == MachineRepresentation::kBit) { |
Jarin
2016/08/25 05:52:05
Do we ever get here?
mvstanton
2016/08/29 12:02:10
No, I've removed the case.
|
+ if (output_type->Is(Type::Boolean())) { |
+ op = simplified()->ChangeBitToTagged(); |
+ } else { |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedPointer); |
+ } |
+ } else if (IsWord(output_rep)) { |
+ // These are all about optimizing to smi types, and we want a pointer. |
+ // Let's be very conservative at first here and declare this to be a |
+ // type error. |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedPointer); |
+ } else { |
+ // TODO(mvstanton): Consider introducing a ChangeFloat64ToTaggedPointer |
+ // operator, but for now all kFloat to kTaggedPointer conversions seem |
+ // suspicious. Really, if we want a TaggedPointer representation we |
+ // should have come from a TaggedPointer type. |
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedPointer); |
+ } |
+ return jsgraph()->graph()->NewNode(op, node); |
+} |
+ |
Node* RepresentationChanger::GetTaggedRepresentationFor( |
Node* node, MachineRepresentation output_rep, Type* output_type) { |
// Eagerly fold representation changes for constants. |
@@ -202,6 +329,11 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( |
default: |
break; |
} |
+ if (output_rep == MachineRepresentation::kTaggedSigned || |
+ output_rep == MachineRepresentation::kTaggedPointer) { |
+ // this is a no-op. |
+ return node; |
+ } |
// Select the correct X -> Tagged operator. |
const Operator* op; |
if (output_rep == MachineRepresentation::kNone) { |
@@ -303,7 +435,8 @@ Node* RepresentationChanger::GetFloat32RepresentationFor( |
node = jsgraph()->graph()->NewNode(op, node); |
op = machine()->TruncateFloat64ToFloat32(); |
} |
- } else if (output_rep == MachineRepresentation::kTagged) { |
+ } else if (output_rep == MachineRepresentation::kTagged || |
+ output_rep == MachineRepresentation::kTaggedPointer) { |
if (output_type->Is(Type::NumberOrOddball())) { |
// tagged -> float64 -> float32 |
if (output_type->Is(Type::Number())) { |
@@ -367,7 +500,9 @@ Node* RepresentationChanger::GetFloat64RepresentationFor( |
} |
} else if (output_rep == MachineRepresentation::kBit) { |
op = machine()->ChangeUint32ToFloat64(); |
- } else if (output_rep == MachineRepresentation::kTagged) { |
+ } else if (output_rep == MachineRepresentation::kTagged || |
+ output_rep == MachineRepresentation::kTaggedSigned || |
+ output_rep == MachineRepresentation::kTaggedPointer) { |
if (output_type->Is(Type::Undefined())) { |
return jsgraph()->Float64Constant( |
std::numeric_limits<double>::quiet_NaN()); |
@@ -470,10 +605,28 @@ Node* RepresentationChanger::GetWord32RepresentationFor( |
? CheckForMinusZeroMode::kCheckForMinusZero |
: CheckForMinusZeroMode::kDontCheckForMinusZero); |
} |
- } else if (output_rep == MachineRepresentation::kTagged) { |
- if (output_type->Is(Type::TaggedSigned())) { |
+ } else if (output_rep == MachineRepresentation::kTaggedSigned) { |
+ if (output_type->Is(Type::Unsigned32())) { |
+ op = simplified()->ChangeTaggedToUint32(); |
Jarin
2016/08/25 05:52:05
I am thinking we do not need the Unsigned case her
mvstanton
2016/08/29 12:02:10
Done.
|
+ } else if (output_type->Is(Type::Signed32())) { |
op = simplified()->ChangeTaggedSignedToInt32(); |
- } else if (output_type->Is(Type::Unsigned32())) { |
+ } else if (use_info.truncation().IsUsedAsWord32()) { |
+ if (use_info.type_check() != TypeCheckKind::kNone) { |
+ op = simplified()->CheckedTruncateTaggedToWord32(); |
+ } else { |
+ op = simplified()->TruncateTaggedToWord32(); |
+ } |
+ } else if (use_info.type_check() == TypeCheckKind::kSignedSmall) { |
Jarin
2016/08/25 05:52:05
We already have a Smi, so we should not even get h
mvstanton
2016/08/29 12:02:10
Done.
|
+ op = simplified()->CheckedTaggedSignedToInt32(); |
+ } else if (use_info.type_check() == TypeCheckKind::kSigned32) { |
+ op = simplified()->CheckedTaggedToInt32( |
+ output_type->Maybe(Type::MinusZero()) |
+ ? CheckForMinusZeroMode::kCheckForMinusZero |
+ : CheckForMinusZeroMode::kDontCheckForMinusZero); |
+ } |
+ } else if (output_rep == MachineRepresentation::kTagged || |
+ output_rep == MachineRepresentation::kTaggedPointer) { |
+ if (output_type->Is(Type::Unsigned32())) { |
op = simplified()->ChangeTaggedToUint32(); |
} else if (output_type->Is(Type::Signed32())) { |
op = simplified()->ChangeTaggedToInt32(); |
@@ -555,7 +708,9 @@ Node* RepresentationChanger::GetBitRepresentationFor( |
// We should only use kNone representation if the type is empty. |
CHECK(!output_type->IsInhabited()); |
op = machine()->ImpossibleToBit(); |
- } else if (output_rep == MachineRepresentation::kTagged) { |
+ } else if (output_rep == MachineRepresentation::kTagged || |
+ output_rep == MachineRepresentation::kTaggedSigned || |
+ output_rep == MachineRepresentation::kTaggedPointer) { |
op = simplified()->ChangeTaggedToBit(); |
} else { |
return TypeError(node, output_rep, output_type, |