[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_