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..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, |