summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/representation-change.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/representation-change.cc')
-rw-r--r--deps/v8/src/compiler/representation-change.cc192
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