Chromium Code Reviews| 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, |