Index: src/compiler/representation-change.cc |
diff --git a/src/compiler/representation-change.cc b/src/compiler/representation-change.cc |
index 5427bdb1cd83bcd8589cfaf860df8004e6c498f7..ad6eeff67d1c1aa150ffb4501fcde887ccb1f61d 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,142 @@ 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); |
+ break; |
Jarin
2016/08/22 14:23:22
No need for break.
mvstanton
2016/08/24 16:06:28
Done.
|
+ case IrOpcode::kInt32Constant: |
+ if (output_type->Is(Type::SignedSmall())) { |
+ // do it. |
Jarin
2016/08/22 14:23:22
Remove comment.
mvstanton
2016/08/24 16:06:28
Done.
|
+ int32_t value = OpParameter<int32_t>(node); |
+ return jsgraph()->Constant(value); |
+ } |
+ if (machine()->Is64() && output_type->Is(Type::Signed32())) { |
Jarin
2016/08/22 14:23:22
Do you ever get here? If this is a 64-bit platform
mvstanton
2016/08/24 16:06:28
Done.
|
+ 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)); |
+ } 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 (output_rep == MachineRepresentation::kBit) { |
Jarin
2016/08/22 14:23:22
This case is not necessary (since the final else g
mvstanton
2016/08/24 16:06:28
Done.
|
+ return TypeError(node, output_rep, output_type, |
+ MachineRepresentation::kTaggedSigned); |
+ } else if (IsWord(output_rep)) { |
+ if (output_type->Is(Type::Signed31())) { |
+ op = simplified()->ChangeInt31ToTaggedSigned(); |
+ } else if (machine()->Is64() && output_type->Is(Type::Signed32())) { |
+ // TODO(mvstanton): Can I count on this to produce a machine |
+ // representation of |
+ // TaggedSigned? I think so because we are on a 64bit platform. |
Jarin
2016/08/22 14:23:22
Yes, on 64-but platform this produces a Smi.
mvstanton
2016/08/24 16:06:28
Thanks, removed TODO.
|
+ 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::kNumberConstant: |
+ case IrOpcode::kHeapConstant: |
+ return node; // No change necessary. |
Jarin
2016/08/22 14:23:22
Actually, NumberConstant would be wrong because it
mvstanton
2016/08/24 16:06:28
Done.
|
+ 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)); |
+ case IrOpcode::kFloat32Constant: |
+ return jsgraph()->Constant(OpParameter<float>(node)); |
+ default: |
+ break; |
+ } |
+ if (output_rep == MachineRepresentation::kTagged) { |
+ // 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->Is(Type::SignedSmall())) { |
Jarin
2016/08/22 14:23:22
Here you have to ask if it can be a Smi:
if (outp
mvstanton
2016/08/24 16:06:28
Done.
|
+ 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) { |
+ 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 +342,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 +448,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 +513,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,7 +618,29 @@ Node* RepresentationChanger::GetWord32RepresentationFor( |
? CheckForMinusZeroMode::kCheckForMinusZero |
: CheckForMinusZeroMode::kDontCheckForMinusZero); |
} |
- } else if (output_rep == MachineRepresentation::kTagged) { |
+ } else if (output_rep == MachineRepresentation::kTaggedSigned) { |
+ if (output_type->Is(Type::TaggedSigned())) { |
Jarin
2016/08/22 14:23:22
You should not need this case. Maybe you want to a
mvstanton
2016/08/24 16:06:28
Done.
|
+ op = simplified()->ChangeTaggedSignedToInt32(); |
+ } else if (output_type->Is(Type::Unsigned32())) { |
+ op = simplified()->ChangeTaggedToUint32(); |
+ } else if (output_type->Is(Type::Signed32())) { |
+ op = simplified()->ChangeTaggedToInt32(); |
Jarin
2016/08/22 14:23:22
This should be ChangeTaggedSignedToInt32, no?
mvstanton
2016/08/24 16:06:28
Done.
|
+ } 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) { |
+ 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::TaggedSigned())) { |
Jarin
2016/08/22 14:23:22
This case should go away. Maybe a TODO here?
|
op = simplified()->ChangeTaggedSignedToInt32(); |
} else if (output_type->Is(Type::Unsigned32())) { |
@@ -555,7 +725,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, |