[turbofan] Move UseInfo to its own file
Change-Id: Idbd61bf934b08c4e9afdfc7e939787f842952f65
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3948786
Auto-Submit: Nico Hartmann <nicohartmann@chromium.org>
Reviewed-by: Darius Mercadier <dmercadier@chromium.org>
Commit-Queue: Darius Mercadier <dmercadier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83660}
diff --git a/BUILD.bazel b/BUILD.bazel
index d0f1f3a..f216a18 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -2913,6 +2913,7 @@
"src/compiler/typer.h",
"src/compiler/types.cc",
"src/compiler/types.h",
+ "src/compiler/use-info.h",
"src/compiler/value-numbering-reducer.cc",
"src/compiler/value-numbering-reducer.h",
"src/compiler/verifier.cc",
diff --git a/BUILD.gn b/BUILD.gn
index bd6252b..29eb0dc 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -2936,6 +2936,7 @@
"src/compiler/typed-optimization.h",
"src/compiler/typer.h",
"src/compiler/types.h",
+ "src/compiler/use-info.h",
"src/compiler/value-numbering-reducer.h",
"src/compiler/verifier.h",
"src/compiler/write-barrier-kind.h",
diff --git a/src/compiler/feedback-source.h b/src/compiler/feedback-source.h
index 29c22cd..afa3e6b 100644
--- a/src/compiler/feedback-source.h
+++ b/src/compiler/feedback-source.h
@@ -43,6 +43,9 @@
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
FeedbackSource const&);
+inline size_t hash_value(const FeedbackSource& value) {
+ return FeedbackSource::Hash()(value);
+}
} // namespace compiler
} // namespace internal
diff --git a/src/compiler/globals.h b/src/compiler/globals.h
index 39fe27c..a20a0044 100644
--- a/src/compiler/globals.h
+++ b/src/compiler/globals.h
@@ -50,6 +50,25 @@
return static_cast<size_t>(kind);
}
+enum class CheckForMinusZeroMode : uint8_t {
+ kCheckForMinusZero,
+ kDontCheckForMinusZero,
+};
+
+inline size_t hash_value(CheckForMinusZeroMode mode) {
+ return static_cast<size_t>(mode);
+}
+
+inline std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) {
+ switch (mode) {
+ case CheckForMinusZeroMode::kCheckForMinusZero:
+ return os << "check-for-minus-zero";
+ case CheckForMinusZeroMode::kDontCheckForMinusZero:
+ return os << "dont-check-for-minus-zero";
+ }
+ UNREACHABLE();
+}
+
// The CallFeedbackRelation provides the meaning of the call feedback for a
// TurboFan JSCall operator
// - kReceiver: The call target was Function.prototype.apply and its receiver
diff --git a/src/compiler/representation-change.h b/src/compiler/representation-change.h
index 8b6ee4c..cbfd893 100644
--- a/src/compiler/representation-change.h
+++ b/src/compiler/representation-change.h
@@ -8,6 +8,7 @@
#include "src/compiler/feedback-source.h"
#include "src/compiler/js-graph.h"
#include "src/compiler/simplified-operator.h"
+#include "src/compiler/use-info.h"
namespace v8 {
namespace internal {
@@ -17,312 +18,6 @@
class SimplifiedLoweringVerifier;
class TypeCache;
-enum IdentifyZeros : uint8_t { kIdentifyZeros, kDistinguishZeros };
-
-class Truncation final {
- public:
- // Constructors.
- static Truncation None() {
- return Truncation(TruncationKind::kNone, kIdentifyZeros);
- }
- static Truncation Bool() {
- return Truncation(TruncationKind::kBool, kIdentifyZeros);
- }
- static Truncation Word32() {
- return Truncation(TruncationKind::kWord32, kIdentifyZeros);
- }
- static Truncation Word64() {
- return Truncation(TruncationKind::kWord64, kIdentifyZeros);
- }
- static Truncation OddballAndBigIntToNumber(
- IdentifyZeros identify_zeros = kDistinguishZeros) {
- return Truncation(TruncationKind::kOddballAndBigIntToNumber,
- identify_zeros);
- }
- static Truncation Any(IdentifyZeros identify_zeros = kDistinguishZeros) {
- return Truncation(TruncationKind::kAny, identify_zeros);
- }
-
- static Truncation Generalize(Truncation t1, Truncation t2) {
- return Truncation(
- Generalize(t1.kind(), t2.kind()),
- GeneralizeIdentifyZeros(t1.identify_zeros(), t2.identify_zeros()));
- }
-
- // Queries.
- bool IsUnused() const { return kind_ == TruncationKind::kNone; }
- bool IsUsedAsBool() const {
- return LessGeneral(kind_, TruncationKind::kBool);
- }
- bool IsUsedAsWord32() const {
- return LessGeneral(kind_, TruncationKind::kWord32);
- }
- bool IsUsedAsWord64() const {
- return LessGeneral(kind_, TruncationKind::kWord64);
- }
- bool TruncatesOddballAndBigIntToNumber() const {
- return LessGeneral(kind_, TruncationKind::kOddballAndBigIntToNumber);
- }
- bool IdentifiesUndefinedAndZero() {
- return LessGeneral(kind_, TruncationKind::kWord32) ||
- LessGeneral(kind_, TruncationKind::kBool);
- }
- bool IdentifiesZeroAndMinusZero() const {
- return identify_zeros() == kIdentifyZeros;
- }
-
- // Operators.
- bool operator==(Truncation other) const {
- return kind() == other.kind() && identify_zeros() == other.identify_zeros();
- }
- bool operator!=(Truncation other) const { return !(*this == other); }
-
- // Debug utilities.
- const char* description() const;
- bool IsLessGeneralThan(Truncation other) const {
- return LessGeneral(kind(), other.kind()) &&
- LessGeneralIdentifyZeros(identify_zeros(), other.identify_zeros());
- }
-
- IdentifyZeros identify_zeros() const { return identify_zeros_; }
-
- private:
- enum class TruncationKind : uint8_t {
- kNone,
- kBool,
- kWord32,
- kWord64,
- kOddballAndBigIntToNumber,
- kAny
- };
-
- explicit Truncation(TruncationKind kind, IdentifyZeros identify_zeros)
- : kind_(kind), identify_zeros_(identify_zeros) {}
-
- TruncationKind kind() const { return kind_; }
-
- friend class SimplifiedLoweringVerifier;
- TruncationKind kind_;
- IdentifyZeros identify_zeros_;
-
- static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
- static IdentifyZeros GeneralizeIdentifyZeros(IdentifyZeros i1,
- IdentifyZeros i2);
- static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
- static bool LessGeneralIdentifyZeros(IdentifyZeros u1, IdentifyZeros u2);
-};
-
-enum class TypeCheckKind : uint8_t {
- kNone,
- kSignedSmall,
- kSigned32,
- kSigned64,
- kNumber,
- kNumberOrBoolean,
- kNumberOrOddball,
- kHeapObject,
- kBigInt,
- kBigInt64,
- kArrayIndex
-};
-
-inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
- switch (type_check) {
- case TypeCheckKind::kNone:
- return os << "None";
- case TypeCheckKind::kSignedSmall:
- return os << "SignedSmall";
- case TypeCheckKind::kSigned32:
- return os << "Signed32";
- case TypeCheckKind::kSigned64:
- return os << "Signed64";
- case TypeCheckKind::kNumber:
- return os << "Number";
- case TypeCheckKind::kNumberOrBoolean:
- return os << "NumberOrBoolean";
- case TypeCheckKind::kNumberOrOddball:
- return os << "NumberOrOddball";
- case TypeCheckKind::kHeapObject:
- return os << "HeapObject";
- case TypeCheckKind::kBigInt:
- return os << "BigInt";
- case TypeCheckKind::kBigInt64:
- return os << "BigInt64";
- case TypeCheckKind::kArrayIndex:
- return os << "ArrayIndex";
- }
- UNREACHABLE();
-}
-
-// The {UseInfo} class is used to describe a use of an input of a node.
-//
-// This information is used in two different ways, based on the phase:
-//
-// 1. During propagation, the use info is used to inform the input node
-// about what part of the input is used (we call this truncation) and what
-// is the preferred representation. For conversions that will require
-// checks, we also keep track of whether a minus zero check is needed.
-//
-// 2. During lowering, the use info is used to properly convert the input
-// to the preferred representation. The preferred representation might be
-// insufficient to do the conversion (e.g. word32->float64 conv), so we also
-// need the signedness information to produce the correct value.
-// Additionally, use info may contain {CheckParameters} which contains
-// information for the deoptimizer such as a CallIC on which speculation
-// should be disallowed if the check fails.
-class UseInfo {
- public:
- UseInfo(MachineRepresentation representation, Truncation truncation,
- TypeCheckKind type_check = TypeCheckKind::kNone,
- const FeedbackSource& feedback = FeedbackSource())
- : representation_(representation),
- truncation_(truncation),
- type_check_(type_check),
- feedback_(feedback) {}
- static UseInfo TruncatingWord32() {
- return UseInfo(MachineRepresentation::kWord32, Truncation::Word32());
- }
- static UseInfo CheckedBigIntTruncatingWord64(const FeedbackSource& feedback) {
- // Note that Trunction::Word64() can safely use kIdentifyZero, because
- // TypeCheckKind::kBigInt will make sure we deopt for anything other than
- // type BigInt anyway.
- return UseInfo(MachineRepresentation::kWord64, Truncation::Word64(),
- TypeCheckKind::kBigInt, feedback);
- }
- static UseInfo CheckedBigInt64AsWord64(const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kWord64, Truncation::Any(),
- TypeCheckKind::kBigInt64, feedback);
- }
- static UseInfo Word64() {
- return UseInfo(MachineRepresentation::kWord64, Truncation::Any());
- }
- static UseInfo Word() {
- return UseInfo(MachineType::PointerRepresentation(), Truncation::Any());
- }
- static UseInfo Bool() {
- return UseInfo(MachineRepresentation::kBit, Truncation::Bool());
- }
- static UseInfo Float32() {
- return UseInfo(MachineRepresentation::kFloat32, Truncation::Any());
- }
- static UseInfo Float64() {
- return UseInfo(MachineRepresentation::kFloat64, Truncation::Any());
- }
- static UseInfo TruncatingFloat64(
- IdentifyZeros identify_zeros = kDistinguishZeros) {
- return UseInfo(MachineRepresentation::kFloat64,
- Truncation::OddballAndBigIntToNumber(identify_zeros));
- }
- static UseInfo AnyTagged() {
- return UseInfo(MachineRepresentation::kTagged, Truncation::Any());
- }
- static UseInfo TaggedSigned() {
- return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any());
- }
- static UseInfo TaggedPointer() {
- return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any());
- }
-
- // Possibly deoptimizing conversions.
- static UseInfo CheckedTaggedAsArrayIndex(const FeedbackSource& feedback) {
- return UseInfo(MachineType::PointerRepresentation(),
- Truncation::Any(kIdentifyZeros), TypeCheckKind::kArrayIndex,
- feedback);
- }
- static UseInfo CheckedHeapObjectAsTaggedPointer(
- const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(),
- TypeCheckKind::kHeapObject, feedback);
- }
-
- static UseInfo CheckedBigIntAsTaggedPointer(const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(),
- TypeCheckKind::kBigInt, feedback);
- }
-
- static UseInfo CheckedSignedSmallAsTaggedSigned(
- const FeedbackSource& feedback,
- IdentifyZeros identify_zeros = kDistinguishZeros) {
- return UseInfo(MachineRepresentation::kTaggedSigned,
- Truncation::Any(identify_zeros), TypeCheckKind::kSignedSmall,
- feedback);
- }
- static UseInfo CheckedSignedSmallAsWord32(IdentifyZeros identify_zeros,
- const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kWord32,
- Truncation::Any(identify_zeros), TypeCheckKind::kSignedSmall,
- feedback);
- }
- static UseInfo CheckedSigned32AsWord32(IdentifyZeros identify_zeros,
- const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kWord32,
- Truncation::Any(identify_zeros), TypeCheckKind::kSigned32,
- feedback);
- }
- static UseInfo CheckedSigned64AsWord64(IdentifyZeros identify_zeros,
- const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kWord64,
- Truncation::Any(identify_zeros), TypeCheckKind::kSigned64,
- feedback);
- }
- static UseInfo CheckedNumberAsFloat64(IdentifyZeros identify_zeros,
- const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kFloat64,
- Truncation::Any(identify_zeros), TypeCheckKind::kNumber,
- feedback);
- }
- static UseInfo CheckedNumberAsWord32(const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kWord32, Truncation::Word32(),
- TypeCheckKind::kNumber, feedback);
- }
- static UseInfo CheckedNumberOrBooleanAsFloat64(
- IdentifyZeros identify_zeros, const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kFloat64,
- Truncation::Any(identify_zeros),
- TypeCheckKind::kNumberOrBoolean, feedback);
- }
- static UseInfo CheckedNumberOrOddballAsFloat64(
- IdentifyZeros identify_zeros, const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kFloat64,
- Truncation::Any(identify_zeros),
- TypeCheckKind::kNumberOrOddball, feedback);
- }
- static UseInfo CheckedNumberOrOddballAsWord32(
- const FeedbackSource& feedback) {
- return UseInfo(MachineRepresentation::kWord32, Truncation::Word32(),
- TypeCheckKind::kNumberOrOddball, feedback);
- }
-
- // Undetermined representation.
- static UseInfo Any() {
- return UseInfo(MachineRepresentation::kNone, Truncation::Any());
- }
- static UseInfo AnyTruncatingToBool() {
- return UseInfo(MachineRepresentation::kNone, Truncation::Bool());
- }
-
- // Value not used.
- static UseInfo None() {
- return UseInfo(MachineRepresentation::kNone, Truncation::None());
- }
-
- MachineRepresentation representation() const { return representation_; }
- Truncation truncation() const { return truncation_; }
- TypeCheckKind type_check() const { return type_check_; }
- CheckForMinusZeroMode minus_zero_check() const {
- return truncation().IdentifiesZeroAndMinusZero()
- ? CheckForMinusZeroMode::kDontCheckForMinusZero
- : CheckForMinusZeroMode::kCheckForMinusZero;
- }
- const FeedbackSource& feedback() const { return feedback_; }
-
- private:
- MachineRepresentation representation_;
- Truncation truncation_;
- TypeCheckKind type_check_;
- FeedbackSource feedback_;
-};
-
// Contains logic related to changing the representation of values for constants
// and other nodes, as well as lowering Simplified->Machine operators.
// Eagerly folds any representation changes for constants.
diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc
index 30f9b43..69cc822 100644
--- a/src/compiler/simplified-operator.cc
+++ b/src/compiler/simplified-operator.cc
@@ -235,20 +235,6 @@
return OpParameter<CheckForMinusZeroMode>(op);
}
-size_t hash_value(CheckForMinusZeroMode mode) {
- return static_cast<size_t>(mode);
-}
-
-std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) {
- switch (mode) {
- case CheckForMinusZeroMode::kCheckForMinusZero:
- return os << "check-for-minus-zero";
- case CheckForMinusZeroMode::kDontCheckForMinusZero:
- return os << "dont-check-for-minus-zero";
- }
- UNREACHABLE();
-}
-
std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) {
if (flags & CheckMapsFlag::kTryMigrateInstance) {
return os << "TryMigrateInstance";
diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h
index 05b9daa..2e3f6e2 100644
--- a/src/compiler/simplified-operator.h
+++ b/src/compiler/simplified-operator.h
@@ -13,6 +13,7 @@
#include "src/common/globals.h"
#include "src/compiler/common-operator.h"
#include "src/compiler/feedback-source.h"
+#include "src/compiler/globals.h"
#include "src/compiler/node-properties.h"
#include "src/compiler/operator.h"
#include "src/compiler/types.h"
@@ -371,16 +372,6 @@
bool operator==(CheckTaggedInputParameters const&,
CheckTaggedInputParameters const&);
-enum class CheckForMinusZeroMode : uint8_t {
- kCheckForMinusZero,
- kDontCheckForMinusZero,
-};
-
-size_t hash_value(CheckForMinusZeroMode);
-
-V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream&,
- CheckForMinusZeroMode);
-
CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator*)
V8_WARN_UNUSED_RESULT;
diff --git a/src/compiler/use-info.h b/src/compiler/use-info.h
new file mode 100644
index 0000000..8a97ef0
--- /dev/null
+++ b/src/compiler/use-info.h
@@ -0,0 +1,352 @@
+// Copyright 2022 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef V8_COMPILER_USE_INFO_H_
+#define V8_COMPILER_USE_INFO_H_
+
+#include "src/base/functional.h"
+#include "src/compiler/feedback-source.h"
+#include "src/compiler/globals.h"
+
+namespace v8::internal::compiler {
+
+enum IdentifyZeros : uint8_t { kIdentifyZeros, kDistinguishZeros };
+
+class Truncation;
+size_t hash_value(const Truncation&);
+
+class Truncation final {
+ public:
+ // Constructors.
+ static Truncation None() {
+ return Truncation(TruncationKind::kNone, kIdentifyZeros);
+ }
+ static Truncation Bool() {
+ return Truncation(TruncationKind::kBool, kIdentifyZeros);
+ }
+ static Truncation Word32() {
+ return Truncation(TruncationKind::kWord32, kIdentifyZeros);
+ }
+ static Truncation Word64() {
+ return Truncation(TruncationKind::kWord64, kIdentifyZeros);
+ }
+ static Truncation OddballAndBigIntToNumber(
+ IdentifyZeros identify_zeros = kDistinguishZeros) {
+ return Truncation(TruncationKind::kOddballAndBigIntToNumber,
+ identify_zeros);
+ }
+ static Truncation Any(IdentifyZeros identify_zeros = kDistinguishZeros) {
+ return Truncation(TruncationKind::kAny, identify_zeros);
+ }
+
+ static Truncation Generalize(Truncation t1, Truncation t2) {
+ return Truncation(
+ Generalize(t1.kind(), t2.kind()),
+ GeneralizeIdentifyZeros(t1.identify_zeros(), t2.identify_zeros()));
+ }
+
+ // Queries.
+ bool IsUnused() const { return kind_ == TruncationKind::kNone; }
+ bool IsUsedAsBool() const {
+ return LessGeneral(kind_, TruncationKind::kBool);
+ }
+ bool IsUsedAsWord32() const {
+ return LessGeneral(kind_, TruncationKind::kWord32);
+ }
+ bool IsUsedAsWord64() const {
+ return LessGeneral(kind_, TruncationKind::kWord64);
+ }
+ bool TruncatesOddballAndBigIntToNumber() const {
+ return LessGeneral(kind_, TruncationKind::kOddballAndBigIntToNumber);
+ }
+ bool IdentifiesUndefinedAndZero() {
+ return LessGeneral(kind_, TruncationKind::kWord32) ||
+ LessGeneral(kind_, TruncationKind::kBool);
+ }
+ bool IdentifiesZeroAndMinusZero() const {
+ return identify_zeros() == kIdentifyZeros;
+ }
+
+ // Operators.
+ bool operator==(Truncation other) const {
+ return kind() == other.kind() && identify_zeros() == other.identify_zeros();
+ }
+ bool operator!=(Truncation other) const { return !(*this == other); }
+
+ // Debug utilities.
+ const char* description() const;
+ bool IsLessGeneralThan(Truncation other) const {
+ return LessGeneral(kind(), other.kind()) &&
+ LessGeneralIdentifyZeros(identify_zeros(), other.identify_zeros());
+ }
+
+ IdentifyZeros identify_zeros() const { return identify_zeros_; }
+
+ private:
+ enum class TruncationKind : uint8_t {
+ kNone,
+ kBool,
+ kWord32,
+ kWord64,
+ kOddballAndBigIntToNumber,
+ kAny
+ };
+
+ explicit Truncation(TruncationKind kind, IdentifyZeros identify_zeros)
+ : kind_(kind), identify_zeros_(identify_zeros) {}
+
+ TruncationKind kind() const { return kind_; }
+
+ friend class SimplifiedLoweringVerifier;
+ friend size_t hash_value(const Truncation&);
+ TruncationKind kind_;
+ IdentifyZeros identify_zeros_;
+
+ static TruncationKind Generalize(TruncationKind rep1, TruncationKind rep2);
+ static IdentifyZeros GeneralizeIdentifyZeros(IdentifyZeros i1,
+ IdentifyZeros i2);
+ static bool LessGeneral(TruncationKind rep1, TruncationKind rep2);
+ static bool LessGeneralIdentifyZeros(IdentifyZeros u1, IdentifyZeros u2);
+};
+
+inline size_t hash_value(const Truncation& truncation) {
+ return base::hash_combine(truncation.kind(), truncation.identify_zeros());
+}
+
+inline std::ostream& operator<<(std::ostream& os,
+ const Truncation& truncation) {
+ return os << truncation.description();
+}
+
+enum class TypeCheckKind : uint8_t {
+ kNone,
+ kSignedSmall,
+ kSigned32,
+ kSigned64,
+ kNumber,
+ kNumberOrBoolean,
+ kNumberOrOddball,
+ kHeapObject,
+ kBigInt,
+ kBigInt64,
+ kArrayIndex
+};
+
+inline std::ostream& operator<<(std::ostream& os, TypeCheckKind type_check) {
+ switch (type_check) {
+ case TypeCheckKind::kNone:
+ return os << "None";
+ case TypeCheckKind::kSignedSmall:
+ return os << "SignedSmall";
+ case TypeCheckKind::kSigned32:
+ return os << "Signed32";
+ case TypeCheckKind::kSigned64:
+ return os << "Signed64";
+ case TypeCheckKind::kNumber:
+ return os << "Number";
+ case TypeCheckKind::kNumberOrBoolean:
+ return os << "NumberOrBoolean";
+ case TypeCheckKind::kNumberOrOddball:
+ return os << "NumberOrOddball";
+ case TypeCheckKind::kHeapObject:
+ return os << "HeapObject";
+ case TypeCheckKind::kBigInt:
+ return os << "BigInt";
+ case TypeCheckKind::kBigInt64:
+ return os << "BigInt64";
+ case TypeCheckKind::kArrayIndex:
+ return os << "ArrayIndex";
+ }
+ UNREACHABLE();
+}
+
+// The {UseInfo} class is used to describe a use of an input of a node.
+//
+// This information is used in two different ways, based on the phase:
+//
+// 1. During propagation, the use info is used to inform the input node
+// about what part of the input is used (we call this truncation) and what
+// is the preferred representation. For conversions that will require
+// checks, we also keep track of whether a minus zero check is needed.
+//
+// 2. During lowering, the use info is used to properly convert the input
+// to the preferred representation. The preferred representation might be
+// insufficient to do the conversion (e.g. word32->float64 conv), so we also
+// need the signedness information to produce the correct value.
+// Additionally, use info may contain {CheckParameters} which contains
+// information for the deoptimizer such as a CallIC on which speculation
+// should be disallowed if the check fails.
+class UseInfo {
+ public:
+ UseInfo(MachineRepresentation representation, Truncation truncation,
+ TypeCheckKind type_check = TypeCheckKind::kNone,
+ const FeedbackSource& feedback = FeedbackSource())
+ : representation_(representation),
+ truncation_(truncation),
+ type_check_(type_check),
+ feedback_(feedback) {}
+ static UseInfo TruncatingWord32() {
+ return UseInfo(MachineRepresentation::kWord32, Truncation::Word32());
+ }
+ static UseInfo CheckedBigIntTruncatingWord64(const FeedbackSource& feedback) {
+ // Note that Trunction::Word64() can safely use kIdentifyZero, because
+ // TypeCheckKind::kBigInt will make sure we deopt for anything other than
+ // type BigInt anyway.
+ return UseInfo(MachineRepresentation::kWord64, Truncation::Word64(),
+ TypeCheckKind::kBigInt, feedback);
+ }
+ static UseInfo CheckedBigInt64AsWord64(const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kWord64, Truncation::Any(),
+ TypeCheckKind::kBigInt64, feedback);
+ }
+ static UseInfo Word64() {
+ return UseInfo(MachineRepresentation::kWord64, Truncation::Any());
+ }
+ static UseInfo Word() {
+ return UseInfo(MachineType::PointerRepresentation(), Truncation::Any());
+ }
+ static UseInfo Bool() {
+ return UseInfo(MachineRepresentation::kBit, Truncation::Bool());
+ }
+ static UseInfo Float32() {
+ return UseInfo(MachineRepresentation::kFloat32, Truncation::Any());
+ }
+ static UseInfo Float64() {
+ return UseInfo(MachineRepresentation::kFloat64, Truncation::Any());
+ }
+ static UseInfo TruncatingFloat64(
+ IdentifyZeros identify_zeros = kDistinguishZeros) {
+ return UseInfo(MachineRepresentation::kFloat64,
+ Truncation::OddballAndBigIntToNumber(identify_zeros));
+ }
+ static UseInfo AnyTagged() {
+ return UseInfo(MachineRepresentation::kTagged, Truncation::Any());
+ }
+ static UseInfo TaggedSigned() {
+ return UseInfo(MachineRepresentation::kTaggedSigned, Truncation::Any());
+ }
+ static UseInfo TaggedPointer() {
+ return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any());
+ }
+
+ // Possibly deoptimizing conversions.
+ static UseInfo CheckedTaggedAsArrayIndex(const FeedbackSource& feedback) {
+ return UseInfo(MachineType::PointerRepresentation(),
+ Truncation::Any(kIdentifyZeros), TypeCheckKind::kArrayIndex,
+ feedback);
+ }
+ static UseInfo CheckedHeapObjectAsTaggedPointer(
+ const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(),
+ TypeCheckKind::kHeapObject, feedback);
+ }
+
+ static UseInfo CheckedBigIntAsTaggedPointer(const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kTaggedPointer, Truncation::Any(),
+ TypeCheckKind::kBigInt, feedback);
+ }
+
+ static UseInfo CheckedSignedSmallAsTaggedSigned(
+ const FeedbackSource& feedback,
+ IdentifyZeros identify_zeros = kDistinguishZeros) {
+ return UseInfo(MachineRepresentation::kTaggedSigned,
+ Truncation::Any(identify_zeros), TypeCheckKind::kSignedSmall,
+ feedback);
+ }
+ static UseInfo CheckedSignedSmallAsWord32(IdentifyZeros identify_zeros,
+ const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kWord32,
+ Truncation::Any(identify_zeros), TypeCheckKind::kSignedSmall,
+ feedback);
+ }
+ static UseInfo CheckedSigned32AsWord32(IdentifyZeros identify_zeros,
+ const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kWord32,
+ Truncation::Any(identify_zeros), TypeCheckKind::kSigned32,
+ feedback);
+ }
+ static UseInfo CheckedSigned64AsWord64(IdentifyZeros identify_zeros,
+ const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kWord64,
+ Truncation::Any(identify_zeros), TypeCheckKind::kSigned64,
+ feedback);
+ }
+ static UseInfo CheckedNumberAsFloat64(IdentifyZeros identify_zeros,
+ const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kFloat64,
+ Truncation::Any(identify_zeros), TypeCheckKind::kNumber,
+ feedback);
+ }
+ static UseInfo CheckedNumberAsWord32(const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kWord32, Truncation::Word32(),
+ TypeCheckKind::kNumber, feedback);
+ }
+ static UseInfo CheckedNumberOrBooleanAsFloat64(
+ IdentifyZeros identify_zeros, const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kFloat64,
+ Truncation::Any(identify_zeros),
+ TypeCheckKind::kNumberOrBoolean, feedback);
+ }
+ static UseInfo CheckedNumberOrOddballAsFloat64(
+ IdentifyZeros identify_zeros, const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kFloat64,
+ Truncation::Any(identify_zeros),
+ TypeCheckKind::kNumberOrOddball, feedback);
+ }
+ static UseInfo CheckedNumberOrOddballAsWord32(
+ const FeedbackSource& feedback) {
+ return UseInfo(MachineRepresentation::kWord32, Truncation::Word32(),
+ TypeCheckKind::kNumberOrOddball, feedback);
+ }
+
+ // Undetermined representation.
+ static UseInfo Any() {
+ return UseInfo(MachineRepresentation::kNone, Truncation::Any());
+ }
+ static UseInfo AnyTruncatingToBool() {
+ return UseInfo(MachineRepresentation::kNone, Truncation::Bool());
+ }
+
+ // Value not used.
+ static UseInfo None() {
+ return UseInfo(MachineRepresentation::kNone, Truncation::None());
+ }
+
+ MachineRepresentation representation() const { return representation_; }
+ Truncation truncation() const { return truncation_; }
+ TypeCheckKind type_check() const { return type_check_; }
+ CheckForMinusZeroMode minus_zero_check() const {
+ return truncation().IdentifiesZeroAndMinusZero()
+ ? CheckForMinusZeroMode::kDontCheckForMinusZero
+ : CheckForMinusZeroMode::kCheckForMinusZero;
+ }
+ const FeedbackSource& feedback() const { return feedback_; }
+
+ private:
+ MachineRepresentation representation_;
+ Truncation truncation_;
+ TypeCheckKind type_check_;
+ FeedbackSource feedback_;
+};
+
+inline bool operator==(const UseInfo& lhs, const UseInfo& rhs) {
+ return lhs.representation() == rhs.representation() &&
+ lhs.truncation() == rhs.truncation() &&
+ lhs.type_check() == rhs.type_check() &&
+ lhs.feedback() == rhs.feedback();
+}
+
+inline size_t hash_value(const UseInfo& use_info) {
+ return base::hash_combine(use_info.representation(), use_info.truncation(),
+ use_info.type_check(), use_info.feedback());
+}
+
+inline std::ostream& operator<<(std::ostream& os, const UseInfo& use_info) {
+ return os << use_info.representation() << ", " << use_info.truncation()
+ << ", " << use_info.type_check() << ", " << use_info.feedback();
+}
+
+} // namespace v8::internal::compiler
+
+#endif // V8_COMPILER_USE_INFO_H_