diff options
Diffstat (limited to 'deps/v8/src/compiler/representation-change.cc')
-rw-r--r-- | deps/v8/src/compiler/representation-change.cc | 192 |
1 files changed, 142 insertions, 50 deletions
diff --git a/deps/v8/src/compiler/representation-change.cc b/deps/v8/src/compiler/representation-change.cc index cebd87e73d..7a4577b799 100644 --- a/deps/v8/src/compiler/representation-change.cc +++ b/deps/v8/src/compiler/representation-change.cc @@ -8,6 +8,7 @@ #include "src/base/bits.h" #include "src/codegen/code-factory.h" +#include "src/compiler/js-heap-broker.h" #include "src/compiler/machine-operator.h" #include "src/compiler/node-matchers.h" #include "src/compiler/type-cache.h" @@ -25,12 +26,14 @@ const char* Truncation::description() const { return "truncate-to-bool"; case TruncationKind::kWord32: return "truncate-to-word32"; - case TruncationKind::kFloat64: + case TruncationKind::kWord64: + return "truncate-to-word64"; + case TruncationKind::kOddballAndBigIntToNumber: switch (identify_zeros()) { case kIdentifyZeros: - return "truncate-to-float64 (identify zeros)"; + return "truncate-oddball&bigint-to-number (identify zeros)"; case kDistinguishZeros: - return "truncate-to-float64 (distinguish zeros)"; + return "truncate-oddball&bigint-to-number (distinguish zeros)"; } case TruncationKind::kAny: switch (identify_zeros()) { @@ -45,22 +48,25 @@ const char* Truncation::description() const { // Partial order for truncations: // -// kAny <-------+ -// ^ | -// | | -// kFloat64 | -// ^ | -// / | -// kWord32 kBool -// ^ ^ -// \ / -// \ / -// \ / -// \ / -// \ / -// kNone +// kAny <-------+ +// ^ | +// | | +// kOddballAndBigIntToNumber | +// ^ | +// / | +// kWord64 | +// ^ | +// | | +// kWord32 kBool +// ^ ^ +// \ / +// \ / +// \ / +// \ / +// \ / +// kNone // -// TODO(jarin) We might consider making kBool < kFloat64. +// TODO(jarin) We might consider making kBool < kOddballAndBigIntToNumber. // static Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1, @@ -68,9 +74,9 @@ Truncation::TruncationKind Truncation::Generalize(TruncationKind rep1, if (LessGeneral(rep1, rep2)) return rep2; if (LessGeneral(rep2, rep1)) return rep1; // Handle the generalization of float64-representable values. - if (LessGeneral(rep1, TruncationKind::kFloat64) && - LessGeneral(rep2, TruncationKind::kFloat64)) { - return TruncationKind::kFloat64; + if (LessGeneral(rep1, TruncationKind::kOddballAndBigIntToNumber) && + LessGeneral(rep2, TruncationKind::kOddballAndBigIntToNumber)) { + return TruncationKind::kOddballAndBigIntToNumber; } // Handle the generalization of any-representable values. if (LessGeneral(rep1, TruncationKind::kAny) && @@ -101,9 +107,16 @@ bool Truncation::LessGeneral(TruncationKind rep1, TruncationKind rep2) { return rep2 == TruncationKind::kBool || rep2 == TruncationKind::kAny; case TruncationKind::kWord32: return rep2 == TruncationKind::kWord32 || - rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny; - case TruncationKind::kFloat64: - return rep2 == TruncationKind::kFloat64 || rep2 == TruncationKind::kAny; + rep2 == TruncationKind::kWord64 || + rep2 == TruncationKind::kOddballAndBigIntToNumber || + rep2 == TruncationKind::kAny; + case TruncationKind::kWord64: + return rep2 == TruncationKind::kWord64 || + rep2 == TruncationKind::kOddballAndBigIntToNumber || + rep2 == TruncationKind::kAny; + case TruncationKind::kOddballAndBigIntToNumber: + return rep2 == TruncationKind::kOddballAndBigIntToNumber || + rep2 == TruncationKind::kAny; case TruncationKind::kAny: return rep2 == TruncationKind::kAny; } @@ -125,10 +138,11 @@ bool IsWord(MachineRepresentation rep) { } // namespace -RepresentationChanger::RepresentationChanger(JSGraph* jsgraph, Isolate* isolate) +RepresentationChanger::RepresentationChanger(JSGraph* jsgraph, + JSHeapBroker* broker) : cache_(TypeCache::Get()), jsgraph_(jsgraph), - isolate_(isolate), + broker_(broker), testing_type_errors_(false), type_error_(false) {} @@ -169,7 +183,8 @@ Node* RepresentationChanger::GetRepresentationFor( use_node, use_info); case MachineRepresentation::kTaggedPointer: DCHECK(use_info.type_check() == TypeCheckKind::kNone || - use_info.type_check() == TypeCheckKind::kHeapObject); + use_info.type_check() == TypeCheckKind::kHeapObject || + use_info.type_check() == TypeCheckKind::kBigInt); return GetTaggedPointerRepresentationFor(node, output_rep, output_type, use_node, use_info); case MachineRepresentation::kTagged: @@ -207,7 +222,8 @@ Node* RepresentationChanger::GetRepresentationFor( use_info); case MachineRepresentation::kWord64: DCHECK(use_info.type_check() == TypeCheckKind::kNone || - use_info.type_check() == TypeCheckKind::kSigned64); + use_info.type_check() == TypeCheckKind::kSigned64 || + use_info.type_check() == TypeCheckKind::kBigInt); return GetWord64RepresentationFor(node, output_rep, output_type, use_node, use_info); case MachineRepresentation::kSimd128: @@ -418,6 +434,8 @@ Node* RepresentationChanger::GetTaggedPointerRepresentationFor( op = machine()->ChangeInt64ToFloat64(); node = jsgraph()->graph()->NewNode(op, node); op = simplified()->ChangeFloat64ToTaggedPointer(); + } else if (output_type.Is(Type::BigInt())) { + op = simplified()->ChangeUint64ToBigInt(); } else { return TypeError(node, output_rep, output_type, MachineRepresentation::kTaggedPointer); @@ -447,16 +465,37 @@ Node* RepresentationChanger::GetTaggedPointerRepresentationFor( // TODO(turbofan): Consider adding a Bailout operator that just deopts // for TaggedSigned output representation. op = simplified()->CheckedTaggedToTaggedPointer(use_info.feedback()); + } else if (IsAnyTagged(output_rep) && + (use_info.type_check() == TypeCheckKind::kBigInt || + output_type.Is(Type::BigInt()))) { + if (output_type.Is(Type::BigInt())) { + return node; + } + op = simplified()->CheckBigInt(use_info.feedback()); } else if (output_rep == MachineRepresentation::kCompressedPointer) { + if (use_info.type_check() == TypeCheckKind::kBigInt && + !output_type.Is(Type::BigInt())) { + node = InsertChangeCompressedToTagged(node); + op = simplified()->CheckBigInt(use_info.feedback()); + } else { + op = machine()->ChangeCompressedPointerToTaggedPointer(); + } + } else if (output_rep == MachineRepresentation::kCompressed && + output_type.Is(Type::BigInt())) { op = machine()->ChangeCompressedPointerToTaggedPointer(); + } else if (output_rep == MachineRepresentation::kCompressed && + use_info.type_check() == TypeCheckKind::kBigInt) { + node = InsertChangeCompressedToTagged(node); + op = simplified()->CheckBigInt(use_info.feedback()); } else if (CanBeCompressedSigned(output_rep) && use_info.type_check() == TypeCheckKind::kHeapObject) { if (!output_type.Maybe(Type::SignedSmall())) { op = machine()->ChangeCompressedPointerToTaggedPointer(); + } else { + // TODO(turbofan): Consider adding a Bailout operator that just deopts + // for CompressedSigned output representation. + op = simplified()->CheckedCompressedToTaggedPointer(use_info.feedback()); } - // TODO(turbofan): Consider adding a Bailout operator that just deopts - // for CompressedSigned output representation. - op = simplified()->CheckedCompressedToTaggedPointer(use_info.feedback()); } else { return TypeError(node, output_rep, output_type, MachineRepresentation::kTaggedPointer); @@ -535,6 +574,9 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( } else if (output_type.Is(cache_->kSafeInteger)) { // int64 -> tagged op = simplified()->ChangeInt64ToTagged(); + } else if (output_type.Is(Type::BigInt())) { + // uint64 -> BigInt + op = simplified()->ChangeUint64ToBigInt(); } else { return TypeError(node, output_rep, output_type, MachineRepresentation::kTagged); @@ -560,7 +602,7 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( op = simplified()->ChangeUint32ToTagged(); } else if (output_type.Is(Type::Number()) || (output_type.Is(Type::NumberOrOddball()) && - truncation.IsUsedAsFloat64())) { + truncation.TruncatesOddballAndBigIntToNumber())) { op = simplified()->ChangeFloat64ToTagged( output_type.Maybe(Type::MinusZero()) ? CheckForMinusZeroMode::kCheckForMinusZero @@ -569,7 +611,11 @@ Node* RepresentationChanger::GetTaggedRepresentationFor( return TypeError(node, output_rep, output_type, MachineRepresentation::kTagged); } - } else if (IsAnyCompressed(output_rep)) { + } else if (output_rep == MachineRepresentation::kCompressedSigned) { + op = machine()->ChangeCompressedSignedToTaggedSigned(); + } else if (output_rep == MachineRepresentation::kCompressedPointer) { + op = machine()->ChangeCompressedPointerToTaggedPointer(); + } else if (output_rep == MachineRepresentation::kCompressed) { op = machine()->ChangeCompressedToTagged(); } else { return TypeError(node, output_rep, output_type, @@ -606,9 +652,20 @@ Node* RepresentationChanger::GetCompressedSignedRepresentationFor( use_node, use_info); op = machine()->ChangeTaggedSignedToCompressedSigned(); } else if (IsWord(output_rep)) { - node = GetTaggedSignedRepresentationFor(node, output_rep, output_type, - use_node, use_info); - op = machine()->ChangeTaggedSignedToCompressedSigned(); + if (output_type.Is(Type::Signed31())) { + op = simplified()->ChangeInt31ToCompressedSigned(); + } else if (output_type.Is(Type::Signed32())) { + if (use_info.type_check() == TypeCheckKind::kSignedSmall) { + op = simplified()->CheckedInt32ToCompressedSigned(use_info.feedback()); + } else { + return TypeError(node, output_rep, output_type, + MachineRepresentation::kCompressedSigned); + } + } else { + node = GetTaggedSignedRepresentationFor(node, output_rep, output_type, + use_node, use_info); + op = machine()->ChangeTaggedSignedToCompressedSigned(); + } } else if (output_rep == MachineRepresentation::kWord64) { node = GetTaggedSignedRepresentationFor(node, output_rep, output_type, use_node, use_info); @@ -645,10 +702,11 @@ Node* RepresentationChanger::GetCompressedPointerRepresentationFor( use_info.type_check() == TypeCheckKind::kHeapObject) { if (!output_type.Maybe(Type::SignedSmall())) { op = machine()->ChangeTaggedPointerToCompressedPointer(); + } else { + // TODO(turbofan): Consider adding a Bailout operator that just deopts + // for TaggedSigned output representation. + op = simplified()->CheckedTaggedToCompressedPointer(use_info.feedback()); } - // TODO(turbofan): Consider adding a Bailout operator that just deopts - // for TaggedSigned output representation. - op = simplified()->CheckedTaggedToCompressedPointer(use_info.feedback()); } else if (output_rep == MachineRepresentation::kBit) { // TODO(v8:8977): specialize here and below node = GetTaggedPointerRepresentationFor(node, output_rep, output_type, @@ -810,11 +868,14 @@ Node* RepresentationChanger::GetFloat64RepresentationFor( Node* use_node, UseInfo use_info) { NumberMatcher m(node); if (m.HasValue()) { + // BigInts are not used as number constants. + DCHECK(use_info.type_check() != TypeCheckKind::kBigInt); switch (use_info.type_check()) { case TypeCheckKind::kNone: case TypeCheckKind::kNumber: case TypeCheckKind::kNumberOrOddball: return jsgraph()->Float64Constant(m.Value()); + case TypeCheckKind::kBigInt: case TypeCheckKind::kHeapObject: case TypeCheckKind::kSigned32: case TypeCheckKind::kSigned64: @@ -843,9 +904,7 @@ Node* RepresentationChanger::GetFloat64RepresentationFor( } } else if (output_rep == MachineRepresentation::kBit) { CHECK(output_type.Is(Type::Boolean())); - // TODO(tebbi): TypeCheckKind::kNumberOrOddball should imply Float64 - // truncation, since this exactly means that we treat Oddballs as Numbers. - if (use_info.truncation().IsUsedAsFloat64() || + if (use_info.truncation().TruncatesOddballAndBigIntToNumber() || use_info.type_check() == TypeCheckKind::kNumberOrOddball) { op = machine()->ChangeUint32ToFloat64(); } else { @@ -867,7 +926,7 @@ Node* RepresentationChanger::GetFloat64RepresentationFor( } else if (output_type.Is(Type::Number())) { op = simplified()->ChangeTaggedToFloat64(); } else if ((output_type.Is(Type::NumberOrOddball()) && - use_info.truncation().IsUsedAsFloat64()) || + use_info.truncation().TruncatesOddballAndBigIntToNumber()) || output_type.Is(Type::NumberOrHole())) { // JavaScript 'null' is an Oddball that results in +0 when truncated to // Number. In a context like -0 == null, which must evaluate to false, @@ -1063,11 +1122,15 @@ Node* RepresentationChanger::GetWord32RepresentationFor( output_type, use_node, use_info); } else if (output_rep == MachineRepresentation::kCompressedSigned) { // TODO(v8:8977): Specialise here - op = machine()->ChangeCompressedSignedToTaggedSigned(); - node = jsgraph()->graph()->NewNode(op, node); - return GetWord32RepresentationFor(node, - MachineRepresentation::kTaggedSigned, - output_type, use_node, use_info); + if (output_type.Is(Type::SignedSmall())) { + op = simplified()->ChangeCompressedSignedToInt32(); + } else { + op = machine()->ChangeCompressedSignedToTaggedSigned(); + node = jsgraph()->graph()->NewNode(op, node); + return GetWord32RepresentationFor(node, + MachineRepresentation::kTaggedSigned, + output_type, use_node, use_info); + } } else if (output_rep == MachineRepresentation::kCompressedPointer) { // TODO(v8:8977): Specialise here op = machine()->ChangeCompressedPointerToTaggedPointer(); @@ -1252,6 +1315,15 @@ Node* RepresentationChanger::GetWord64RepresentationFor( } break; } + case IrOpcode::kHeapConstant: { + HeapObjectMatcher m(node); + if (m.HasValue() && m.Ref(broker_).IsBigInt()) { + auto bigint = m.Ref(broker_).AsBigInt(); + return jsgraph()->Int64Constant( + static_cast<int64_t>(bigint.AsUint64())); + } + break; + } default: break; } @@ -1272,9 +1344,15 @@ Node* RepresentationChanger::GetWord64RepresentationFor( jsgraph()->common()->DeadValue(MachineRepresentation::kWord64), unreachable); } else if (IsWord(output_rep)) { - if (output_type.Is(Type::Unsigned32())) { + if (output_type.Is(Type::Unsigned32OrMinusZero())) { + // uint32 -> uint64 + CHECK_IMPLIES(output_type.Maybe(Type::MinusZero()), + use_info.truncation().IdentifiesZeroAndMinusZero()); op = machine()->ChangeUint32ToUint64(); - } else if (output_type.Is(Type::Signed32())) { + } else if (output_type.Is(Type::Signed32OrMinusZero())) { + // int32 -> int64 + CHECK_IMPLIES(output_type.Maybe(Type::MinusZero()), + use_info.truncation().IdentifiesZeroAndMinusZero()); op = machine()->ChangeInt32ToInt64(); } else { return TypeError(node, output_rep, output_type, @@ -1323,6 +1401,13 @@ Node* RepresentationChanger::GetWord64RepresentationFor( return TypeError(node, output_rep, output_type, MachineRepresentation::kWord64); } + } else if (IsAnyTagged(output_rep) && + use_info.truncation().IsUsedAsWord64() && + (use_info.type_check() == TypeCheckKind::kBigInt || + output_type.Is(Type::BigInt()))) { + node = GetTaggedPointerRepresentationFor(node, output_rep, output_type, + use_node, use_info); + op = simplified()->TruncateBigIntToUint64(); } else if (CanBeTaggedPointer(output_rep)) { if (output_type.Is(cache_->kInt64)) { op = simplified()->ChangeTaggedToInt64(); @@ -1656,6 +1741,13 @@ Node* RepresentationChanger::InsertTruncateInt64ToInt32(Node* node) { return jsgraph()->graph()->NewNode(machine()->TruncateInt64ToInt32(), node); } +Node* RepresentationChanger::InsertChangeCompressedToTagged(Node* node) { + return jsgraph()->graph()->NewNode(machine()->ChangeCompressedToTagged(), + node); +} + +Isolate* RepresentationChanger::isolate() const { return broker_->isolate(); } + } // namespace compiler } // namespace internal } // namespace v8 |