Lines Matching refs:node

22 #include "src/compiler/node-matchers.h"
23 #include "src/compiler/node-observer.h"
24 #include "src/compiler/node-origin-table.h"
61 // During this phase, the usage information for a node determines the best
182 void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
183 for (Edge edge : node->use_edges()) {
236 base::Optional<Type> GetType(Node* node) override {
237 return verifier_->GetType(node);
252 void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
254 input_use_infos_.resize(node->InputCount(), UseInfo::None());
280 static void ChangeOp(Node* node, const Operator* new_op) { UNREACHABLE(); }
284 // Information for each node tracked during the fixpoint.
287 // Adds new use to the node. Returns true if something has changed
288 // and the node has to be requeued.
369 Type TypeOf(Node* node) {
370 Type type = GetInfo(node)->feedback_type();
371 return type.IsInvalid() ? NodeProperties::GetType(node) : type;
374 Type FeedbackTypeOf(Node* node) {
375 Type type = GetInfo(node)->feedback_type();
379 Type TypePhi(Node* node) {
380 int arity = node->op()->ValueInputCount();
381 Type type = FeedbackTypeOf(node->InputAt(0));
383 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i)));
388 Type TypeSelect(Node* node) {
389 return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
390 FeedbackTypeOf(node->InputAt(2)));
393 bool UpdateFeedbackType(Node* node) {
394 if (node->op()->ValueOutputCount() == 0) return false;
396 // For any non-phi node just wait until we get all inputs typed. We only
399 if (node->opcode() != IrOpcode::kPhi) {
400 for (int i = 0; i < node->op()->ValueInputCount(); i++) {
401 if (GetInfo(node->InputAt(i))->feedback_type().IsInvalid()) {
407 NodeInfo* info = GetInfo(node);
409 Type new_type = NodeProperties::GetType(node);
414 if (node->InputCount() > 0) input0_type = FeedbackTypeOf(node->InputAt(0));
416 if (node->InputCount() > 1) input1_type = FeedbackTypeOf(node->InputAt(1));
418 switch (node->opcode()) {
480 new_type = TypePhi(node);
482 new_type = Weaken(node, type, new_type);
489 FeedbackTypeOf(node->InputAt(0)));
493 new_type = op_typer_.TypeTypeGuard(node->op(),
494 FeedbackTypeOf(node->InputAt(0)));
499 new_type = TypeSelect(node);
506 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
515 new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
518 GetInfo(node)->set_feedback_type(new_type);
520 PrintNodeFeedbackType(node);
546 Type Weaken(Node* node, Type previous_type, Type current_type) {
560 // Once we start weakening a node, we should always weaken.
561 if (!GetInfo(node)->weakened()) {
571 GetInfo(node)->set_weakened();
593 Node* node = current.node;
595 // If there is an unvisited input, push it and continue with that node.
597 while (current.input_index < node->InputCount()) {
598 Node* input = node->InputAt(current.input_index);
609 // the current node will be visited in the Retype phase before one of
610 // its inputs. If this happens, the current node might need to be
612 MarkAsPossibleRevisit(node, input);
619 NodeInfo* info = GetInfo(node);
623 traversal_nodes_.push_back(node);
627 void PushNodeToRevisitIfVisited(Node* node) {
628 NodeInfo* info = GetInfo(node);
630 TRACE(" QUEUEING #%d: %s\n", node->id(), node->op()->mnemonic());
632 revisit_queue_.push(node);
636 // Tries to update the feedback type of the node, as well as setting its
639 bool RetypeNode(Node* node) {
640 NodeInfo* info = GetInfo(node);
642 bool updated = UpdateFeedbackType(node);
643 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
644 VisitNode<RETYPE>(node, info->truncation(), nullptr);
649 // Visits the node and marks it as visited. Inside of VisitNode, we might
651 // this). If we change the truncation of an already visited node, we will add
653 void PropagateTruncation(Node* node) {
654 NodeInfo* info = GetInfo(node);
656 TRACE(" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
658 VisitNode<PROPAGATE>(node, info->truncation(), nullptr);
673 Node* node = revisit_queue_.front();
675 PropagateTruncation(node);
688 Node* node = *it;
689 if (!RetypeNode(node)) continue;
691 auto revisit_it = might_need_revisit_.find(node);
705 // a revisited node.
718 Node* node = *it;
719 NodeInfo* info = GetInfo(node);
720 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
723 source_positions_, source_positions_->GetSourcePosition(node));
725 node);
726 VisitNode<LOWER>(node, info->truncation(), lowering);
732 Node* node = *i;
734 node->ReplaceUses(replacement);
735 node->Kill();
736 // We also need to replace the node in the rest of the vector.
739 if (*j == node) *j = replacement;
753 // Set node types to the refined types computed during retyping.
754 for (Node* node : traversal_nodes_) {
755 NodeInfo* info = GetInfo(node);
757 NodeProperties::SetType(node, info->feedback_type());
762 for (Node* node : traversal_nodes_) verifier_->VisitNode(node, op_typer_);
776 for (Node* node : verifier_->inserted_hints()) {
777 Node* input = node->InputAt(0);
778 node->ReplaceUses(input);
779 node->Kill();
819 void SetOutput(Node* node, MachineRepresentation representation,
822 Type GetUpperBound(Node* node) { return NodeProperties::GetType(node); }
824 bool InputCannotBe(Node* node, Type type) {
825 DCHECK_EQ(1, node->op()->ValueInputCount());
826 return !GetUpperBound(node->InputAt(0)).Maybe(type);
829 bool InputIs(Node* node, Type type) {
830 DCHECK_EQ(1, node->op()->ValueInputCount());
831 return GetUpperBound(node->InputAt(0)).Is(type);
834 bool BothInputsAreSigned32(Node* node) {
835 return BothInputsAre(node, Type::Signed32());
838 bool BothInputsAreUnsigned32(Node* node) {
839 return BothInputsAre(node, Type::Unsigned32());
842 bool BothInputsAre(Node* node, Type type) {
843 DCHECK_EQ(2, node->op()->ValueInputCount());
844 return GetUpperBound(node->InputAt(0)).Is(type) &&
845 GetUpperBound(node->InputAt(1)).Is(type);
848 bool IsNodeRepresentationTagged(Node* node) {
849 MachineRepresentation representation = GetInfo(node)->representation();
853 bool OneInputCannotBe(Node* node, Type type) {
854 DCHECK_EQ(2, node->op()->ValueInputCount());
855 return !GetUpperBound(node->InputAt(0)).Maybe(type) ||
856 !GetUpperBound(node->InputAt(1)).Maybe(type);
859 void ChangeToDeadValue(Node* node, Node* effect, Node* control) {
860 DCHECK(TypeOf(node).IsNone());
861 // If the node is unreachable, insert an Unreachable node and mark the
868 common()->DeadValue(GetInfo(node)->representation());
869 node->ReplaceInput(0, unreachable);
870 node->TrimInputCount(dead_value->ValueInputCount());
871 ReplaceEffectControlUses(node, effect, control);
872 ChangeOp(node, dead_value);
876 // replace a node that is part of the effect and control chain by a pure node.
877 void ReplaceWithPureNode(Node* node, Node* pure_node) {
879 if (node->op()->EffectInputCount() > 0) {
880 DCHECK_LT(0, node->op()->ControlInputCount());
881 Node* control = NodeProperties::GetControlInput(node);
882 Node* effect = NodeProperties::GetEffectInput(node);
883 if (TypeOf(node).IsNone()) {
884 ChangeToDeadValue(node, effect, control);
888 ReplaceEffectControlUses(node, effect, control);
890 DCHECK_EQ(0, node->op()->ControlInputCount());
892 DeferReplacement(node, pure_node);
895 void ChangeToPureOp(Node* node, const Operator* new_op) {
897 DCHECK_EQ(new_op->ValueInputCount(), node->op()->ValueInputCount());
898 if (node->op()->EffectInputCount() > 0) {
899 DCHECK_LT(0, node->op()->ControlInputCount());
900 Node* control = NodeProperties::GetControlInput(node);
901 Node* effect = NodeProperties::GetEffectInput(node);
902 if (TypeOf(node).IsNone()) {
903 ChangeToDeadValue(node, effect, control);
907 node->TrimInputCount(new_op->ValueInputCount());
908 ReplaceEffectControlUses(node, effect, control);
910 DCHECK_EQ(0, node->op()->ControlInputCount());
912 ChangeOp(node, new_op);
915 void ChangeUnaryToPureBinaryOp(Node* node, const Operator* new_op,
919 DCHECK_EQ(node->op()->ValueInputCount(), 1);
922 if (node->op()->EffectInputCount() > 0) {
923 DCHECK_LT(0, node->op()->ControlInputCount());
924 Node* control = NodeProperties::GetControlInput(node);
925 Node* effect = NodeProperties::GetEffectInput(node);
926 if (TypeOf(node).IsNone()) {
927 ChangeToDeadValue(node, effect, control);
930 node->TrimInputCount(node->op()->ValueInputCount());
931 ReplaceEffectControlUses(node, effect, control);
933 DCHECK_EQ(0, node->op()->ControlInputCount());
936 node->InsertInput(jsgraph_->zone(), 0, new_input);
939 DCHECK_EQ(node->InputCount(), 1);
940 node->AppendInput(jsgraph_->zone(), new_input);
942 ChangeOp(node, new_op);
945 // Converts input {index} of {node} according to given UseInfo {use},
947 // it takes the input from the input node {TypeOf(node->InputAt(index))}.
948 void ConvertInput(Node* node, int index, UseInfo use,
953 Node* input = node->InputAt(index);
960 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
970 node, use);
971 node->ReplaceInput(index, n);
976 void ProcessInput(Node* node, int index, UseInfo use);
980 void ProcessRemainingInputs(Node* node, int index) {
984 DCHECK_GE(index, NodeProperties::PastValueIndex(node));
985 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
988 // Marks node as a possible revisit since it is a use of input that will be
990 void MarkAsPossibleRevisit(Node* node, Node* input) {
995 it->second.push_back(node);
996 TRACE(" Marking #%d: %s as needing revisit due to #%d: %s\n", node->id(),
997 node->op()->mnemonic(), input->id(), input->op()->mnemonic());
1002 void VisitInputs(Node* node) {
1009 void VisitReturn(Node* node) {
1010 int first_effect_index = NodeProperties::FirstEffectIndex(node);
1012 ProcessInput<T>(node, 0, UseInfo::TruncatingWord32());
1016 ProcessInput<T>(node, i, UseInfo::AnyTagged());
1019 for (int i = first_effect_index; i < node->InputCount(); i++) {
1020 EnqueueInput<T>(node, i);
1024 // Helper for an unused node.
1026 void VisitUnused(Node* node) {
1027 int first_effect_index = NodeProperties::FirstEffectIndex(node);
1029 ProcessInput<T>(node, i, UseInfo::None());
1031 ProcessRemainingInputs<T>(node, first_effect_index);
1034 TRACE("disconnecting unused #%d:%s\n", node->id(),
1035 node->op()->mnemonic());
1036 DisconnectFromEffectAndControl(node);
1037 node->NullAllInputs(); // Node is now dead.
1038 DeferReplacement(node, graph()->NewNode(common()->Plug()));
1042 // Helper for no-op node.
1044 void VisitNoop(Node* node, Truncation truncation) {
1045 if (truncation.IsUnused()) return VisitUnused<T>(node);
1047 GetOutputInfoForPhi(node, TypeOf(node), truncation);
1048 VisitUnop<T>(node, UseInfo(representation, truncation), representation);
1049 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
1054 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
1057 DCHECK_EQ(2, node->op()->ValueInputCount());
1058 ProcessInput<T>(node, 0, left_use);
1059 ProcessInput<T>(node, 1, right_use);
1060 for (int i = 2; i < node->InputCount(); i++) {
1061 EnqueueInput<T>(node, i);
1063 SetOutput<T>(node, output, restriction_type);
1068 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
1070 VisitBinop<T>(node, input_use, input_use, output, restriction_type);
1074 void VisitSpeculativeInt32Binop(Node* node) {
1075 DCHECK_EQ(2, node->op()->ValueInputCount());
1076 if (BothInputsAre(node, Type::NumberOrOddball())) {
1077 return VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1080 NumberOperationHint hint = NumberOperationHintOf(node->op());
1081 return VisitBinop<T>(node,
1088 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
1090 DCHECK_EQ(1, node->op()->ValueInputCount());
1091 ProcessInput<T>(node, 0, input_use);
1092 ProcessRemainingInputs<T>(node, 1);
1093 SetOutput<T>(node, output, restriction_type);
1098 void VisitLeaf(Node* node, MachineRepresentation output) {
1099 DCHECK_EQ(0, node->InputCount());
1100 SetOutput<T>(node, output);
1106 void VisitFloat64Binop(Node* node) {
1107 VisitBinop<T>(node, UseInfo::TruncatingFloat64(),
1112 void VisitInt64Binop(Node* node) {
1113 VisitBinop<T>(node, UseInfo::Word64(), MachineRepresentation::kWord64);
1117 void VisitWord32TruncatingBinop(Node* node) {
1118 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1123 // The {node} parameter is only used to decide on the int64 representation.
1124 // Once the type system supports an external pointer type, the {node}
1126 MachineRepresentation GetOutputInfoForPhi(Node* node, Type type,
1159 void VisitSelect(Node* node, Truncation truncation,
1161 DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
1162 ProcessInput<T>(node, 0, UseInfo::Bool());
1165 GetOutputInfoForPhi(node, TypeOf(node), truncation);
1166 SetOutput<T>(node, output);
1170 SelectParameters p = SelectParametersOf(node->op());
1172 ChangeOp(node, lowering->common()->Select(output, p.hint()));
1178 ProcessInput<T>(node, 1, input_use);
1179 ProcessInput<T>(node, 2, input_use);
1184 void VisitPhi(Node* node, Truncation truncation,
1187 GetOutputInfoForPhi(node, TypeOf(node), truncation);
1190 SetOutput<T>(node, output);
1192 int values = node->op()->ValueInputCount();
1195 if (output != PhiRepresentationOf(node->op())) {
1196 ChangeOp(node, lowering->common()->Phi(output, values));
1203 for (int i = 0; i < node->InputCount(); i++) {
1204 ProcessInput<T>(node, i, i < values ? input_use : UseInfo::None());
1209 void VisitObjectIs(Node* node, Type type, SimplifiedLowering* lowering) {
1210 Type const input_type = TypeOf(node->InputAt(0));
1212 VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
1214 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
1217 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
1219 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
1225 void VisitCheck(Node* node, Type type, SimplifiedLowering* lowering) {
1226 if (InputIs(node, type)) {
1227 VisitUnop<T>(node, UseInfo::AnyTagged(),
1229 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
1231 VisitUnop<T>(node,
1238 void VisitCall(Node* node, SimplifiedLowering* lowering) {
1239 auto call_descriptor = CallDescriptorOf(node->op());
1241 int value_input_count = node->op()->ValueInputCount();
1247 ProcessInput<T>(node, 0, UseInfo::Any());
1252 ProcessInput<T>(node, i,
1259 ProcessInput<T>(node, i, UseInfo::AnyTagged());
1263 ProcessRemainingInputs<T>(node, value_input_count);
1266 SetOutput<T>(node, call_descriptor->GetReturnType(0).representation());
1268 SetOutput<T>(node, MachineRepresentation::kTagged);
1272 void MaskShiftOperand(Node* node, Type rhs_type) {
1274 Node* const rhs = NodeProperties::GetValueInput(node, 1);
1275 node->ReplaceInput(1,
1318 void VisitStateValues(Node* node) {
1320 for (int i = 0; i < node->InputCount(); i++) {
1327 if (TypeOf(node->InputAt(i)).Is(Type::BigInt())) {
1328 EnqueueInput<T>(node, i, UseInfo::AnyTagged());
1330 EnqueueInput<T>(node, i, UseInfo::Any());
1336 zone->New<ZoneVector<MachineType>>(node->InputCount(), zone);
1337 for (int i = 0; i < node->InputCount(); i++) {
1338 Node* input = node->InputAt(i);
1342 ConvertInput(node, i, UseInfo::AnyTagged());
1348 SparseInputMask mask = SparseInputMaskOf(node->op());
1349 ChangeOp(node, common()->TypedStateValues(types, mask));
1351 SetOutput<T>(node, MachineRepresentation::kTagged);
1355 void VisitFrameState(FrameState node) {
1356 DCHECK_EQ(5, node->op()->ValueInputCount());
1357 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1358 DCHECK_EQ(FrameState::kFrameStateInputCount, node->InputCount());
1360 ProcessInput<T>(node, FrameState::kFrameStateParametersInput,
1362 ProcessInput<T>(node, FrameState::kFrameStateLocalsInput,
1366 // a singleton typed-state-values node (as if it was a singleton
1367 // state-values node).
1368 Node* accumulator = node.stack();
1373 EnqueueInput<T>(node, FrameState::kFrameStateStackInput,
1376 EnqueueInput<T>(node, FrameState::kFrameStateStackInput,
1383 ConvertInput(node, FrameState::kFrameStateStackInput,
1388 node->ReplaceInput(FrameState::kFrameStateStackInput,
1396 node->ReplaceInput(
1400 node.stack()));
1404 ProcessInput<T>(node, FrameState::kFrameStateContextInput,
1406 ProcessInput<T>(node, FrameState::kFrameStateFunctionInput,
1408 ProcessInput<T>(node, FrameState::kFrameStateOuterStateInput,
1410 return SetOutput<T>(node, MachineRepresentation::kTagged);
1414 void VisitObjectState(Node* node) {
1416 for (int i = 0; i < node->InputCount(); i++) {
1419 if (TypeOf(node->InputAt(i)).Is(Type::BigInt())) {
1420 EnqueueInput<T>(node, i, UseInfo::AnyTagged());
1422 EnqueueInput<T>(node, i, UseInfo::Any());
1428 zone->New<ZoneVector<MachineType>>(node->InputCount(), zone);
1429 for (int i = 0; i < node->InputCount(); i++) {
1430 Node* input = node->InputAt(i);
1435 if (TypeOf(node->InputAt(i)).Is(Type::BigInt())) {
1436 ConvertInput(node, i, UseInfo::AnyTagged());
1439 ChangeOp(node, common()->TypedObjectState(ObjectIdOf(node->op()), types));
1441 SetOutput<T>(node, MachineRepresentation::kTagged);
1444 const Operator* Int32Op(Node* node) {
1445 return changer_->Int32OperatorFor(node->opcode());
1448 const Operator* Int32OverflowOp(Node* node) {
1449 return changer_->Int32OverflowOperatorFor(node->opcode());
1452 const Operator* Int64Op(Node* node) {
1453 return changer_->Int64OperatorFor(node->opcode());
1456 const Operator* Uint32Op(Node* node) {
1457 return changer_->Uint32OperatorFor(node->opcode());
1460 const Operator* Uint32OverflowOp(Node* node) {
1461 return changer_->Uint32OverflowOperatorFor(node->opcode());
1464 const Operator* Float64Op(Node* node) {
1465 return changer_->Float64OperatorFor(node->opcode());
1539 void VisitForCheckedInt32Mul(Node* node, Truncation truncation,
1542 DCHECK_EQ(node->opcode(), IrOpcode::kSpeculativeNumberMultiply);
1544 DCHECK(BothInputsAre(node, Type::Signed32()) ||
1561 VisitBinop<T>(node, input_use, MachineRepresentation::kWord32, restriction);
1562 if (lower<T>()) ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
1565 void ChangeToInt32OverflowOp(Node* node) {
1566 ChangeOp(node, Int32OverflowOp(node));
1569 void ChangeToUint32OverflowOp(Node* node) {
1570 ChangeOp(node, Uint32OverflowOp(node));
1574 void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
1576 Type left_upper = GetUpperBound(node->InputAt(0));
1577 Type right_upper = GetUpperBound(node->InputAt(1));
1581 // Only eliminate the node if its typing rule can be satisfied, namely
1583 if (truncation.IsUnused()) return VisitUnused<T>(node);
1588 if (GetUpperBound(node).Is(Type::Signed32()) ||
1589 GetUpperBound(node).Is(Type::Unsigned32()) ||
1592 VisitWord32TruncatingBinop<T>(node);
1593 if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
1600 DCHECK_EQ(hint, NumberOperationHintOf(node->op()));
1602 Type left_feedback_type = TypeOf(node->InputAt(0));
1603 Type right_feedback_type = TypeOf(node->InputAt(1));
1622 node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd
1628 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1636 if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
1647 VisitBinop<T>(node, left_use, right_use, MachineRepresentation::kWord32,
1653 !CanOverflowSigned32(node->op(), left_feedback_type,
1656 ChangeToPureOp(node, Int32Op(node));
1658 ChangeToInt32OverflowOp(node);
1665 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
1667 if (BothInputsAre(node, type_cache_->kAdditiveSafeIntegerOrMinusZero) &&
1668 (GetUpperBound(node).Is(Type::Signed32()) ||
1669 GetUpperBound(node).Is(Type::Unsigned32()) ||
1672 VisitWord32TruncatingBinop<T>(node);
1673 if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
1678 VisitBinop<T>(node,
1683 ChangeToPureOp(node, Float64Op(node));
1689 void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
1691 if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
1693 NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
1695 VisitWord32TruncatingBinop<T>(node);
1696 if (lower<T>()) DeferReplacement(node, lowering->Uint32Mod(node));
1699 if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
1701 NodeProperties::GetType(node).Is(Type::Signed32()))) {
1703 VisitWord32TruncatingBinop<T>(node);
1704 if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
1709 NumberOperationHint hint = NumberOperationHintOf(node->op());
1713 if (BothInputsAreUnsigned32(node)) {
1715 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1717 if (lower<T>()) ChangeToUint32OverflowOp(node);
1724 if (BothInputsAre(node, Type::Signed32())) {
1727 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1729 if (lower<T>()) ChangeToInt32OverflowOp(node);
1745 VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kWord32);
1746 if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
1747 } else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
1750 TypeOf(node->InputAt(0)).Maybe(Type::MinusZero())
1753 VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
1755 if (lower<T>()) ChangeToUint32OverflowOp(node);
1759 TypeOf(node->InputAt(0)).Maybe(Type::MinusZero())
1762 VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
1764 if (lower<T>()) ChangeToInt32OverflowOp(node);
1769 if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
1770 TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
1772 NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
1773 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1775 if (lower<T>()) DeferReplacement(node, lowering->Uint32Mod(node));
1778 if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
1779 TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
1781 NodeProperties::GetType(node).Is(Type::Signed32()))) {
1782 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1784 if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
1797 VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kFloat64,
1799 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
1805 void InsertUnreachableIfNecessary(Node* node) {
1812 void VisitCheckBounds(Node* node, SimplifiedLowering* lowering) {
1813 CheckBoundsParameters const& p = CheckBoundsParametersOf(node->op());
1815 Type const index_type = TypeOf(node->InputAt(0));
1816 Type const length_type = TypeOf(node->InputAt(1));
1830 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
1841 ChangeOp(node,
1845 VisitBinop<T>(node, UseInfo::CheckedTaggedAsArrayIndex(feedback),
1849 ChangeOp(node,
1852 ChangeOp(node,
1858 node, UseInfo::CheckedSigned32AsWord32(kDistinguishZeros, feedback),
1861 ChangeOp(node,
1871 VisitBinop<T>(node,
1875 ChangeOp(node, simplified()->CheckedUint64Bounds(feedback, new_flags));
1923 void VisitFastApiCall(Node* node, SimplifiedLowering* lowering) {
1925 FastApiCallParametersOf(node->op());
1935 const int value_input_count = node->op()->ValueInputCount();
1945 ProcessInput<T>(node, i, arg_use_info[i]);
1949 ProcessInput<T>(node, c_arg_count, UseInfo::AnyTagged());
1951 ProcessInput<T>(node, c_arg_count + i,
1956 ProcessInput<T>(node, i, UseInfo::AnyTagged());
1958 ProcessRemainingInputs<T>(node, value_input_count);
1959 SetOutput<T>(node, MachineRepresentation::kTagged);
2001 void VisitJSWasmCall(Node* node, SimplifiedLowering* lowering) {
2006 JSWasmCallNode n(node);
2017 ProcessInput<T>(node, JSWasmCallNode::TargetIndex(), UseInfo::Any());
2018 ProcessInput<T>(node, JSWasmCallNode::ReceiverIndex(), UseInfo::Any());
2026 ProcessInput<T>(node, JSWasmCallNode::ArgumentIndex(i), arg_use_info[i]);
2030 int first_effect_index = NodeProperties::FirstEffectIndex(node);
2035 ProcessInput<T>(node, i, UseInfo::AnyTagged());
2039 ProcessRemainingInputs<T>(node, NodeProperties::FirstEffectIndex(node));
2045 SetOutput<T>(node, MachineRepresentation::kTagged);
2050 node, return_type.representation(),
2055 SetOutput<T>(node, MachineRepresentation::kTagged);
2063 // Dispatching routine for visiting the node {node} with the usage {use}.
2066 void VisitNode(Node* node, Truncation truncation,
2076 if (node->op()->EffectOutputCount() == 0 &&
2077 node->op()->ControlOutputCount() == 0 &&
2078 node->opcode() != IrOpcode::kDeadValue &&
2079 node->opcode() != IrOpcode::kStateValues &&
2080 node->opcode() != IrOpcode::kFrameState &&
2081 node->opcode() != IrOpcode::kPhi) {
2082 for (int i = 0; i < node->op()->ValueInputCount(); i++) {
2083 Node* input = node->InputAt(i);
2085 node->ReplaceInput(0, input);
2086 node->TrimInputCount(1);
2087 ChangeOp(node,
2088 common()->DeadValue(GetInfo(node)->representation()));
2093 InsertUnreachableIfNecessary<T>(node);
2101 // would thus kill the cached {node} during lowering (i.e. replace all
2102 // uses with Dead), but at that point some node lowering might have
2103 // already taken the constant {node} from the cache (while it was not
2105 if (node->op()->ValueInputCount() > 0 &&
2106 node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) {
2107 return VisitUnused<T>(node);
2110 switch (node->opcode()) {
2118 return VisitLeaf<T>(node, MachineRepresentation::kTagged);
2120 return VisitUnop<T>(node, UseInfo::None(),
2122 ->GetParameterType(ParameterIndexOf(node->op()))
2125 return VisitLeaf<T>(node, MachineRepresentation::kWord32);
2127 return VisitLeaf<T>(node, MachineRepresentation::kWord64);
2129 return VisitLeaf<T>(node, MachineType::PointerRepresentation());
2131 double const value = OpParameter<double>(node->op());
2134 VisitLeaf<T>(node, MachineRepresentation::kTaggedSigned);
2138 NodeProperties::GetType(node),
2140 DeferReplacement(node, constant);
2144 VisitLeaf<T>(node, MachineRepresentation::kTagged);
2149 return VisitLeaf<T>(node, MachineRepresentation::kTaggedPointer);
2151 VisitLeaf<T>(node, MachineType::PointerRepresentation());
2153 intptr_t const value = OpParameter<intptr_t>(node->op());
2154 DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
2160 DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
2161 ProcessInput<T>(node, 0, UseInfo::Bool());
2162 EnqueueInput<T>(node, NodeProperties::FirstControlIndex(node));
2166 ProcessInput<T>(node, 0, UseInfo::TruncatingWord32());
2167 EnqueueInput<T>(node, NodeProperties::FirstControlIndex(node));
2170 return VisitSelect<T>(node, truncation, lowering);
2172 return VisitPhi<T>(node, truncation, lowering);
2174 return VisitCall<T>(node, lowering);
2182 DCHECK(NodeProperties::GetType(node).Is(Type::Union(
2184 VisitInputs<T>(node);
2187 SetOutput<T>(node, MachineRepresentation::kWord32);
2189 lowering->DoJSToNumberOrNumericTruncatesToWord32(node, this);
2191 SetOutput<T>(node, MachineRepresentation::kFloat64);
2193 lowering->DoJSToNumberOrNumericTruncatesToFloat64(node, this);
2195 SetOutput<T>(node, MachineRepresentation::kTagged);
2205 ProcessInput<T>(node, 0, UseInfo::Bool());
2206 SetOutput<T>(node, MachineRepresentation::kBit);
2207 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
2209 VisitInputs<T>(node);
2210 SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
2216 NodeInfo* input_info = GetInfo(node->InputAt(0));
2219 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
2220 ChangeOp(node, lowering->machine()->Word32Equal());
2223 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
2224 ChangeOp(node, lowering->machine()->WordEqual());
2226 DCHECK(TypeOf(node->InputAt(0)).IsNone());
2227 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
2231 ProcessInput<T>(node, 0, UseInfo::AnyTruncatingToBool());
2232 SetOutput<T>(node, MachineRepresentation::kBit);
2237 Type const lhs_type = TypeOf(node->InputAt(0));
2238 Type const rhs_type = TypeOf(node->InputAt(1));
2248 OneInputCannotBe(node, type_cache_->kZeroish))) {
2250 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2252 if (lower<T>()) ChangeOp(node, Uint32Op(node));
2259 OneInputCannotBe(node, type_cache_->kZeroish))) {
2261 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2263 if (lower<T>()) ChangeOp(node, Int32Op(node));
2267 VisitBinop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2269 if (lower<T>()) ChangeOp(node, Float64Op(node));
2274 Type const lhs_type = TypeOf(node->InputAt(0));
2275 Type const rhs_type = TypeOf(node->InputAt(1));
2282 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2284 if (lower<T>()) ChangeOp(node, Uint32Op(node));
2288 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2290 if (lower<T>()) ChangeOp(node, Int32Op(node));
2293 VisitBinop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2295 if (lower<T>()) ChangeOp(node, Float64Op(node));
2302 return VisitSpeculativeIntegerAdditiveOp<T>(node, truncation, lowering);
2306 return VisitSpeculativeAdditiveOp<T>(node, truncation, lowering);
2311 Type const lhs_type = TypeOf(node->InputAt(0));
2312 Type const rhs_type = TypeOf(node->InputAt(1));
2319 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2321 if (lower<T>()) ChangeToPureOp(node, Uint32Op(node));
2326 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2328 if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
2332 NumberOperationHint hint = NumberOperationHintOf(node->op());
2337 node, CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
2340 SetOutput<T>(node, MachineRepresentation::kBit, Type::Any());
2343 Node* lhs = node->InputAt(0);
2344 Node* rhs = node->InputAt(1);
2347 VisitBinop<T>(node,
2352 node, changer_->TaggedSignedOperatorFor(node->opcode()));
2356 node, CheckedUseInfoAsWord32FromHint(hint, kIdentifyZeros),
2358 ChangeToPureOp(node, Int32Op(node));
2369 DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
2373 VisitBinop<T>(node,
2377 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2386 if (TypeOf(node->InputAt(0))
2388 TypeOf(node->InputAt(1))
2390 (TypeOf(node).Is(Type::Signed32()) ||
2391 TypeOf(node).Is(Type::Unsigned32()) ||
2394 VisitWord32TruncatingBinop<T>(node);
2395 if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
2397 BothInputsAre(node, type_cache_->kSafeInteger) &&
2398 GetUpperBound(node).Is(type_cache_->kSafeInteger)) {
2400 VisitInt64Binop<T>(node);
2401 if (lower<T>()) ChangeToPureOp(node, Int64Op(node));
2404 VisitFloat64Binop<T>(node);
2405 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2410 if (BothInputsAre(node, Type::Integral32()) &&
2411 (NodeProperties::GetType(node).Is(Type::Signed32()) ||
2412 NodeProperties::GetType(node).Is(Type::Unsigned32()) ||
2414 NodeProperties::GetType(node).Is(
2421 VisitWord32TruncatingBinop<T>(node);
2422 if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
2426 NumberOperationHint hint = NumberOperationHintOf(node->op());
2427 Type input0_type = TypeOf(node->InputAt(0));
2428 Type input1_type = TypeOf(node->InputAt(1));
2432 if (BothInputsAre(node, Type::Signed32())) {
2435 VisitForCheckedInt32Mul<T>(node, truncation, input0_type,
2443 VisitForCheckedInt32Mul<T>(node, truncation, input0_type, input1_type,
2449 VisitBinop<T>(node,
2453 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2457 if (TypeOf(node->InputAt(0)).Is(Type::Integral32()) &&
2458 TypeOf(node->InputAt(1)).Is(Type::Integral32()) &&
2459 (TypeOf(node).Is(Type::Signed32()) ||
2460 TypeOf(node).Is(Type::Unsigned32()) ||
2462 TypeOf(node).Is(type_cache_->kSafeIntegerOrMinusZero)))) {
2468 VisitWord32TruncatingBinop<T>(node);
2469 if (lower<T>()) ChangeToPureOp(node, Int32Op(node));
2473 VisitFloat64Binop<T>(node);
2474 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2478 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
2480 VisitWord32TruncatingBinop<T>(node);
2481 if (lower<T>()) DeferReplacement(node, lowering->Uint32Div(node));
2484 if (BothInputsAreSigned32(node)) {
2485 if (NodeProperties::GetType(node).Is(Type::Signed32())) {
2487 VisitWord32TruncatingBinop<T>(node);
2488 if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
2493 VisitWord32TruncatingBinop<T>(node);
2494 if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
2500 NumberOperationHint hint = NumberOperationHintOf(node->op());
2504 if (BothInputsAreUnsigned32(node)) {
2506 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2508 if (lower<T>()) ChangeToUint32OverflowOp(node);
2515 if (BothInputsAreSigned32(node)) {
2518 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2520 if (lower<T>()) ChangeToInt32OverflowOp(node);
2529 VisitBinop<T>(node, CheckedUseInfoAsWord32FromHint(hint),
2531 if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
2534 VisitBinop<T>(node, CheckedUseInfoAsWord32FromHint(hint),
2536 if (lower<T>()) ChangeToInt32OverflowOp(node);
2542 VisitBinop<T>(node,
2546 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2550 if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
2551 TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
2553 TypeOf(node).Is(Type::Unsigned32()))) {
2555 VisitWord32TruncatingBinop<T>(node);
2556 if (lower<T>()) DeferReplacement(node, lowering->Uint32Div(node));
2559 if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
2560 TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
2562 TypeOf(node).Is(Type::Signed32()))) {
2564 VisitWord32TruncatingBinop<T>(node);
2565 if (lower<T>()) DeferReplacement(node, lowering->Int32Div(node));
2569 VisitFloat64Binop<T>(node);
2570 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2574 return VisitSpeculativeNumberModulus<T>(node, truncation, lowering);
2576 Type const lhs_type = TypeOf(node->InputAt(0));
2577 Type const rhs_type = TypeOf(node->InputAt(1));
2581 TypeOf(node).Is(Type::Unsigned32()))) {
2583 VisitWord32TruncatingBinop<T>(node);
2584 if (lower<T>()) DeferReplacement(node, lowering->Uint32Mod(node));
2589 (truncation.IsUsedAsWord32() || TypeOf(node).Is(Type::Signed32()) ||
2591 TypeOf(node).Is(Type::Signed32OrMinusZero())))) {
2593 VisitWord32TruncatingBinop<T>(node);
2594 if (lower<T>()) DeferReplacement(node, lowering->Int32Mod(node));
2605 VisitBinop<T>(node, lhs_use, rhs_use, MachineRepresentation::kFloat64);
2606 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2612 VisitWord32TruncatingBinop<T>(node);
2613 if (lower<T>()) ChangeOp(node, Int32Op(node));
2619 VisitSpeculativeInt32Binop<T>(node);
2621 ChangeToPureOp(node, Int32Op(node));
2625 Type rhs_type = GetUpperBound(node->InputAt(1));
2626 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2630 MaskShiftOperand(node, rhs_type);
2631 ChangeToPureOp(node, lowering->machine()->Word32Shl());
2636 if (BothInputsAre(node, Type::NumberOrOddball())) {
2637 Type rhs_type = GetUpperBound(node->InputAt(1));
2638 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2642 MaskShiftOperand(node, rhs_type);
2643 ChangeToPureOp(node, lowering->machine()->Word32Shl());
2647 NumberOperationHint hint = NumberOperationHintOf(node->op());
2648 Type rhs_type = GetUpperBound(node->InputAt(1));
2649 VisitBinop<T>(node,
2653 MaskShiftOperand(node, rhs_type);
2654 ChangeToPureOp(node, lowering->machine()->Word32Shl());
2659 Type rhs_type = GetUpperBound(node->InputAt(1));
2660 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2664 MaskShiftOperand(node, rhs_type);
2665 ChangeToPureOp(node, lowering->machine()->Word32Sar());
2670 if (BothInputsAre(node, Type::NumberOrOddball())) {
2671 Type rhs_type = GetUpperBound(node->InputAt(1));
2672 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2676 MaskShiftOperand(node, rhs_type);
2677 ChangeToPureOp(node, lowering->machine()->Word32Sar());
2681 NumberOperationHint hint = NumberOperationHintOf(node->op());
2682 Type rhs_type = GetUpperBound(node->InputAt(1));
2683 VisitBinop<T>(node,
2687 MaskShiftOperand(node, rhs_type);
2688 ChangeToPureOp(node, lowering->machine()->Word32Sar());
2693 Type rhs_type = GetUpperBound(node->InputAt(1));
2694 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2698 MaskShiftOperand(node, rhs_type);
2699 ChangeToPureOp(node, lowering->machine()->Word32Shr());
2704 NumberOperationHint hint = NumberOperationHintOf(node->op());
2705 Type rhs_type = GetUpperBound(node->InputAt(1));
2713 VisitBinop<T>(node,
2717 node->RemoveInput(1);
2718 ChangeOp(node,
2723 if (BothInputsAre(node, Type::NumberOrOddball())) {
2724 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2728 MaskShiftOperand(node, rhs_type);
2729 ChangeToPureOp(node, lowering->machine()->Word32Shr());
2733 VisitBinop<T>(node,
2737 MaskShiftOperand(node, rhs_type);
2738 ChangeToPureOp(node, lowering->machine()->Word32Shr());
2746 Type const input_type = TypeOf(node->InputAt(0));
2748 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
2750 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
2752 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
2754 if (lower<T>()) DeferReplacement(node, lowering->Int32Abs(node));
2756 VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2758 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
2760 VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2762 if (lower<T>()) ChangeOp(node, Float64Op(node));
2767 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
2769 if (lower<T>()) ChangeOp(node, Uint32Op(node));
2773 VisitBinop<T>(node, UseInfo::TruncatingWord32(),
2776 if (lower<T>()) ChangeOp(node, Uint32Op(node));
2780 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
2782 if (lower<T>()) ChangeOp(node, Float64Op(node));
2792 Type const lhs_type = TypeOf(node->InputAt(0));
2793 Type const rhs_type = TypeOf(node->InputAt(1));
2799 VisitWord32TruncatingBinop<T>(node);
2801 lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
2809 VisitWord32TruncatingBinop<T>(node);
2811 lowering->DoMax(node, lowering->machine()->Int32LessThan(),
2817 VisitInt64Binop<T>(node);
2819 lowering->DoMax(node, lowering->machine()->Int64LessThan(),
2823 VisitBinop<T>(node,
2834 lowering->DoMax(node, lowering->machine()->Float64LessThan(),
2837 ChangeOp(node, Float64Op(node));
2850 Type const lhs_type = TypeOf(node->InputAt(0));
2851 Type const rhs_type = TypeOf(node->InputAt(1));
2857 VisitWord32TruncatingBinop<T>(node);
2859 lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
2867 VisitWord32TruncatingBinop<T>(node);
2869 lowering->DoMin(node, lowering->machine()->Int32LessThan(),
2875 VisitInt64Binop<T>(node);
2877 lowering->DoMin(node, lowering->machine()->Int64LessThan(),
2881 VisitBinop<T>(node,
2892 lowering->DoMin(node,
2896 ChangeOp(node, Float64Op(node));
2904 VisitBinop<T>(node,
2908 if (lower<T>()) ChangeToPureOp(node, Float64Op(node));
2913 VisitBinop<T>(node, UseInfo::TruncatingFloat64(),
2915 if (lower<T>()) ChangeOp(node, Float64Op(node));
2926 Type const input_type = TypeOf(node->InputAt(0));
2927 VisitUnop<T>(node,
2932 DeferReplacement(node, node->InputAt(0));
2933 } else if (node->opcode() == IrOpcode::kNumberRound) {
2934 DeferReplacement(node, lowering->Float64Round(node));
2936 ChangeOp(node, Float64Op(node));
2942 if (InputIs(node, Type::BigInt())) {
2943 VisitNoop<T>(node, truncation);
2945 VisitUnop<T>(node, UseInfo::AnyTagged(),
2953 node->opcode() == IrOpcode::kSpeculativeBigIntAsUintN;
2954 const auto p = SpeculativeBigIntAsNParametersOf(node->op());
2958 ProcessInput<T>(node, 0,
2961 node, MachineRepresentation::kWord64,
2966 node, InsertTypeOverrideForVerifier(Type::UnsignedBigInt63(),
2969 DeferReplacement(node, node->InputAt(0));
2973 ChangeUnaryToPureBinaryOp(node, lowering->machine()->Word64And(),
2986 Node* value = node->InputAt(0);
2994 ReplaceWithPureNode(node, unshifted);
3019 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3021 if (lower<T>()) ChangeOp(node, Float64Op(node));
3025 if (InputIs(node, Type::Signed32())) {
3026 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3028 if (lower<T>()) DeferReplacement(node, lowering->Int32Sign(node));
3030 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3032 if (lower<T>()) DeferReplacement(node, lowering->Float64Sign(node));
3037 Type const input_type = TypeOf(node->InputAt(0));
3040 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3042 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3044 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3046 if (lower<T>()) ChangeOp(node, Float64Op(node));
3051 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3053 if (lower<T>()) ChangeOp(node, Float64Op(node));
3060 Type const input_type = TypeOf(node->InputAt(0));
3064 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3066 if (lower<T>()) lowering->DoIntegral32ToBit(node);
3068 VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
3070 if (lower<T>()) lowering->DoOrderedNumberToBit(node);
3072 VisitUnop<T>(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
3074 if (lower<T>()) lowering->DoNumberToBit(node);
3080 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3082 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3086 VisitUnop<T>(node, UseInfo::AnyTagged(),
3092 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3094 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3098 Type const input_type = TypeOf(node->InputAt(0));
3100 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3102 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3104 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3106 if (lower<T>()) lowering->DoUnsigned32ToUint8Clamped(node);
3108 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3110 if (lower<T>()) lowering->DoSigned32ToUint8Clamped(node);
3112 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3114 if (lower<T>()) lowering->DoIntegerToUint8Clamped(node);
3116 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3118 if (lower<T>()) lowering->DoNumberToUint8Clamped(node);
3123 VisitBinop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3126 ChangeOp(node, lowering->machine()->Word32Equal());
3128 ChangeOp(node, lowering->machine()->WordEqual());
3134 VisitBinop<T>(node, UseInfo::AnyTagged(),
3139 if (truncation.IsUnused()) return VisitUnused<T>(node);
3140 if (BothInputsAre(node, Type::Number())) {
3141 VisitBinop<T>(node, UseInfo::TruncatingFloat64(),
3144 ChangeOp(node, lowering->simplified()->NumberSameValue());
3147 VisitBinop<T>(node, UseInfo::AnyTagged(),
3153 return VisitUnop<T>(node, UseInfo::AnyTagged(),
3157 ProcessInput<T>(node, 0, UseInfo::TruncatingWord32()); // length
3158 ProcessInput<T>(node, 1, UseInfo::AnyTagged()); // first
3159 ProcessInput<T>(node, 2, UseInfo::AnyTagged()); // second
3160 SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3171 node, UseInfo::CheckedBigIntTruncatingWord64(FeedbackSource{}),
3174 ChangeToPureOp(node, lowering->machine()->Int64Add());
3177 VisitBinop<T>(node,
3181 ChangeOp(node, lowering->simplified()->BigIntAdd());
3189 node, UseInfo::CheckedBigIntTruncatingWord64(FeedbackSource{}),
3192 ChangeToPureOp(node, lowering->machine()->Int64Sub());
3195 VisitBinop<T>(node,
3199 ChangeOp(node, lowering->simplified()->BigIntSubtract());
3206 VisitUnop<T>(node,
3210 ChangeUnaryToPureBinaryOp(node, lowering->machine()->Int64Sub(), 0,
3214 VisitUnop<T>(node,
3218 ChangeToPureOp(node, lowering->simplified()->BigIntNegate());
3229 ProcessInput<T>(node, 0, UseInfo::TaggedSigned()); // length
3230 ProcessInput<T>(node, 1, UseInfo::AnyTagged()); // first
3231 ProcessInput<T>(node, 2, UseInfo::AnyTagged()); // second
3232 SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3238 return VisitBinop<T>(node, UseInfo::AnyTagged(),
3242 return VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::Word(),
3246 return VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::Word(),
3250 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3255 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3260 return VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::Word(),
3264 ProcessInput<T>(node, 0, UseInfo::AnyTagged());
3265 ProcessInput<T>(node, 1, UseInfo::AnyTagged());
3266 ProcessInput<T>(node, 2, UseInfo::TaggedSigned());
3267 SetOutput<T>(node, MachineRepresentation::kTaggedSigned);
3274 VisitUnop<T>(node, UseInfo::AnyTagged(),
3279 ProcessInput<T>(node, 0, UseInfo::AnyTagged());
3280 ProcessInput<T>(node, 1, UseInfo::TruncatingWord32());
3281 ProcessInput<T>(node, 2, UseInfo::TruncatingWord32());
3282 ProcessRemainingInputs<T>(node, 3);
3283 SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3288 VisitUnop<T>(node, UseInfo::AnyTagged(),
3293 return VisitCheckBounds<T>(node, lowering);
3295 if (InputCannotBe(node, Type::SignedSmall())) {
3296 VisitUnop<T>(node, UseInfo::AnyTagged(),
3300 node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
3303 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3307 ProcessInput<T>(node, 0, UseInfo::Bool());
3308 ProcessRemainingInputs<T>(node, 1);
3309 SetOutput<T>(node, MachineRepresentation::kNone);
3313 VisitCheck<T>(node, Type::InternalizedString(), lowering);
3317 Type const input_type = TypeOf(node->InputAt(0));
3319 VisitNoop<T>(node, truncation);
3321 VisitUnop<T>(node, UseInfo::AnyTagged(),
3327 VisitCheck<T>(node, Type::Receiver(), lowering);
3331 VisitCheck<T>(node, Type::ReceiverOrNullOrUndefined(), lowering);
3335 const CheckParameters& params = CheckParametersOf(node->op());
3337 VisitUnop<T>(node,
3343 node,
3347 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3351 const CheckParameters& params = CheckParametersOf(node->op());
3352 if (InputIs(node, Type::String())) {
3353 VisitUnop<T>(node, UseInfo::AnyTagged(),
3355 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3358 node,
3365 VisitCheck<T>(node, Type::Symbol(), lowering);
3370 ProcessInput<T>(node, 0, UseInfo::Word());
3371 ProcessRemainingInputs<T>(node, 1);
3372 SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3376 SetOutput<T>(node, MachineType::PointerRepresentation());
3380 if (truncation.IsUnused()) return VisitUnused<T>(node);
3381 VisitUnop<T>(node, UseInfo::Word(), MachineRepresentation::kTagged);
3385 ProcessInput<T>(node, 0, UseInfo::Word());
3386 ProcessInput<T>(node, 1, UseInfo::AnyTagged());
3387 ProcessRemainingInputs<T>(node, 2);
3388 SetOutput<T>(node, MachineRepresentation::kNone);
3392 if (truncation.IsUnused()) return VisitUnused<T>(node);
3393 VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
3398 if (truncation.IsUnused()) return VisitUnused<T>(node);
3399 FieldAccess access = FieldAccessOf(node->op());
3402 VisitUnop<T>(node, UseInfoForBasePointer(access), representation);
3406 FieldAccess access = FieldAccessOf(node->op());
3407 Node* value_node = node->InputAt(1);
3421 ProcessInput<T>(node, 0, UseInfoForBasePointer(access));
3423 node, 1, TruncatingUseInfoFromRepresentation(field_representation));
3424 ProcessRemainingInputs<T>(node, 2);
3425 SetOutput<T>(node, MachineRepresentation::kNone);
3429 ChangeOp(node, jsgraph_->simplified()->StoreField(access));
3435 if (truncation.IsUnused()) return VisitUnused<T>(node);
3436 ElementAccess access = ElementAccessOf(node->op());
3437 VisitBinop<T>(node, UseInfoForBasePointer(access), UseInfo::Word(),
3442 if (truncation.IsUnused()) return VisitUnused<T>(node);
3443 VisitBinop<T>(node, UseInfo::Word(), MachineRepresentation::kTagged);
3447 ElementAccess access = ElementAccessOf(node->op());
3448 Node* value_node = node->InputAt(2);
3461 ProcessInput<T>(node, 0, UseInfoForBasePointer(access)); // base
3462 ProcessInput<T>(node, 1, UseInfo::Word()); // index
3463 ProcessInput<T>(node, 2,
3466 ProcessRemainingInputs<T>(node, 3);
3467 SetOutput<T>(node, MachineRepresentation::kNone);
3471 ChangeOp(node, jsgraph_->simplified()->StoreElement(access));
3477 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3482 Type value_type = TypeOf(node->InputAt(2));
3484 ProcessInput<T>(node, 0, UseInfo::AnyTagged()); // array
3485 ProcessInput<T>(node, 1, UseInfo::Word()); // index
3488 ProcessInput<T>(node, 2, UseInfo::TruncatingWord32()); // value
3490 ChangeOp(node, simplified()->StoreSignedSmallElement());
3493 ProcessInput<T>(node, 2, UseInfo::TruncatingFloat64()); // value
3495 Handle<Map> double_map = DoubleMapParameterOf(node->op());
3496 ChangeOp(node,
3500 ProcessInput<T>(node, 2, UseInfo::AnyTagged()); // value
3502 Handle<Map> fast_map = FastMapParameterOf(node->op());
3503 ChangeOp(node, simplified()->TransitionAndStoreNonNumberElement(
3507 ProcessInput<T>(node, 2, UseInfo::AnyTagged()); // value
3510 ProcessRemainingInputs<T>(node, 3);
3511 SetOutput<T>(node, MachineRepresentation::kNone);
3516 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
3517 ProcessInput<T>(node, 0, UseInfo::AnyTagged()); // buffer
3518 ProcessInput<T>(node, 1, UseInfo::AnyTagged()); // base pointer
3519 ProcessInput<T>(node, 2, UseInfo::Word()); // external pointer
3520 ProcessInput<T>(node, 3, UseInfo::Word()); // index
3521 ProcessRemainingInputs<T>(node, 4);
3522 SetOutput<T>(node, rep);
3527 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
3528 ProcessInput<T>(node, 0, UseInfo::AnyTagged()); // object
3529 ProcessInput<T>(node, 1, UseInfo::Word()); // base
3530 ProcessInput<T>(node, 2, UseInfo::Word()); // index
3531 ProcessInput<T>(node, 3, UseInfo::Bool()); // little-endian
3532 ProcessRemainingInputs<T>(node, 4);
3533 SetOutput<T>(node, rep);
3538 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
3539 ProcessInput<T>(node, 0, UseInfo::AnyTagged()); // buffer
3540 ProcessInput<T>(node, 1, UseInfo::AnyTagged()); // base pointer
3541 ProcessInput<T>(node, 2, UseInfo::Word()); // external pointer
3542 ProcessInput<T>(node, 3, UseInfo::Word()); // index
3543 ProcessInput<T>(node, 4,
3545 ProcessRemainingInputs<T>(node, 5);
3546 SetOutput<T>(node, MachineRepresentation::kNone);
3551 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
3552 ProcessInput<T>(node, 0, UseInfo::AnyTagged()); // object
3553 ProcessInput<T>(node, 1, UseInfo::Word()); // base
3554 ProcessInput<T>(node, 2, UseInfo::Word()); // index
3555 ProcessInput<T>(node, 3,
3557 ProcessInput<T>(node, 4, UseInfo::Bool()); // little-endian
3558 ProcessRemainingInputs<T>(node, 5);
3559 SetOutput<T>(node, MachineRepresentation::kNone);
3563 Type input_type = TypeOf(node->InputAt(0));
3564 VisitBinop<T>(node, UseInfo::AnyTagged(),
3567 // Try to optimize the {node} based on the input type.
3569 DeferReplacement(node, node->InputAt(0));
3571 DeferReplacement(node, node->InputAt(1));
3573 ChangeOp(node, lowering->simplified()->ConvertReceiver(
3580 if (InputIs(node, Type::Boolean())) {
3581 VisitUnop<T>(node, UseInfo::Bool(), MachineRepresentation::kWord32);
3583 ChangeToSemanticsHintForVerifier(node, node->op());
3585 } else if (InputIs(node, Type::String())) {
3586 VisitUnop<T>(node, UseInfo::AnyTagged(),
3589 ChangeOp(node, simplified()->StringToNumber());
3592 if (InputIs(node, Type::NumberOrOddball())) {
3593 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3596 ChangeToSemanticsHintForVerifier(node, node->op());
3599 VisitUnop<T>(node, UseInfo::AnyTagged(),
3602 ChangeOp(node, simplified()->PlainPrimitiveToWord32());
3606 if (InputIs(node, Type::NumberOrOddball())) {
3607 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3610 ChangeToSemanticsHintForVerifier(node, node->op());
3613 VisitUnop<T>(node, UseInfo::AnyTagged(),
3616 ChangeOp(node, simplified()->PlainPrimitiveToFloat64());
3620 VisitUnop<T>(node, UseInfo::AnyTagged(),
3627 NumberOperationParametersOf(node->op());
3631 VisitUnop<T>(node,
3640 node, CheckedUseInfoAsFloat64FromHint(p.hint(), p.feedback()),
3644 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3649 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3653 VisitObjectIs<T>(node, Type::BigInt(), lowering);
3657 VisitObjectIs<T>(node, Type::Callable(), lowering);
3662 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3666 VisitObjectIs<T>(node, Type::DetectableCallable(), lowering);
3670 Type const input_type = GetUpperBound(node->InputAt(0));
3672 VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
3674 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3677 VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
3679 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3682 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3685 ChangeOp(node, lowering->simplified()->NumberIsFinite());
3688 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3693 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3698 Type const input_type = GetUpperBound(node->InputAt(0));
3700 VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
3702 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3705 VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
3707 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3710 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3713 ChangeOp(node, lowering->simplified()->NumberIsSafeInteger());
3716 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3724 Type const input_type = GetUpperBound(node->InputAt(0));
3726 VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
3728 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3731 VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
3733 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3736 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3739 ChangeOp(node, lowering->simplified()->NumberIsInteger());
3742 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3747 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3752 Type const input_type = GetUpperBound(node->InputAt(0));
3754 VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
3756 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3759 VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
3761 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3764 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3767 ChangeOp(node, simplified()->NumberIsMinusZero());
3770 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3775 Type const input_type = GetUpperBound(node->InputAt(0));
3777 VisitUnop<T>(node, UseInfo::None(), MachineRepresentation::kBit);
3779 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3782 VisitUnop<T>(node, UseInfo::Any(), MachineRepresentation::kBit);
3784 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3787 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3790 ChangeOp(node, simplified()->NumberIsNaN());
3793 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3798 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3803 VisitObjectIs<T>(node, Type::NonCallable(), lowering);
3807 VisitObjectIs<T>(node, Type::Number(), lowering);
3811 VisitObjectIs<T>(node, Type::Receiver(), lowering);
3816 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3820 VisitObjectIs<T>(node, Type::String(), lowering);
3824 VisitObjectIs<T>(node, Type::Symbol(), lowering);
3828 VisitObjectIs<T>(node, Type::Undetectable(), lowering);
3833 SetOutput<T>(node, MachineRepresentation::kTaggedSigned);
3838 VisitUnop<T>(node, UseInfo::Word(),
3843 VisitUnop<T>(node, UseInfo::TaggedSigned(),
3848 Type const input_type = TypeOf(node->InputAt(0));
3850 CheckFloat64HoleParametersOf(node->op()).mode();
3854 // the {truncation} and completely wipe the {node}.
3855 if (truncation.IsUnused()) return VisitUnused<T>(node);
3857 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3859 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3864 node, UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
3867 DeferReplacement(node, node->InputAt(0));
3872 VisitUnop<T>(node, UseInfo::AnyTagged(),
3878 node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
3883 if (InputIs(node, Type::NumberOrOddball()) &&
3886 VisitUnop<T>(node, UseInfo::TruncatingWord32(),
3888 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3889 } else if (InputIs(node, Type::NumberOrOddball()) &&
3892 VisitUnop<T>(node, UseInfo::TruncatingFloat64(),
3894 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3895 } else if (InputIs(node, Type::NonInternal())) {
3896 VisitUnop<T>(node, UseInfo::AnyTagged(),
3898 if (lower<T>()) DeferReplacement(node, node->InputAt(0));
3902 VisitUnop<T>(node, UseInfo::AnyTagged(),
3909 return VisitBinop<T>(node, UseInfo::AnyTagged(),
3913 return VisitUnused<T>(node);
3915 CheckMapsParameters const& p = CheckMapsParametersOf(node->op());
3917 node, UseInfo::CheckedHeapObjectAsTaggedPointer(p.feedback()),
3922 node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
3927 node, UseInfo::CheckedHeapObjectAsTaggedPointer(FeedbackSource()),
3930 return VisitBinop<T>(node, UseInfo::AnyTagged(),
3933 ProcessInput<T>(node, 0, UseInfo::AnyTagged()); // object
3934 ProcessInput<T>(node, 1, UseInfo::AnyTagged()); // elements
3935 ProcessInput<T>(node, 2, UseInfo::TruncatingWord32()); // index
3936 ProcessInput<T>(node, 3, UseInfo::TruncatingWord32()); // length
3937 ProcessRemainingInputs<T>(node, 4);
3938 SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3943 VisitInputs<T>(node);
3944 return SetOutput<T>(node, MachineRepresentation::kTagged);
3946 return VisitFrameState<T>(FrameState{node});
3948 return VisitStateValues<T>(node);
3950 return VisitObjectState<T>(node);
3952 return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3955 if (truncation.IsUnused()) return VisitUnused<T>(node);
3959 Type type = TypeOf(node);
3961 GetOutputInfoForPhi(node, type, truncation);
3967 EnqueueInput<T>(node, 0, use);
3969 ConvertInput(node, 0, use, type);
3971 ProcessRemainingInputs<T>(node, 1);
3972 SetOutput<T>(node, representation);
3977 VisitInputs<T>(node);
3978 return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3981 VisitInputs<T>(node);
3983 return SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
3986 VisitReturn<T>(node);
3988 return SetOutput<T>(node, MachineRepresentation::kTagged);
3991 Type const key_type = TypeOf(node->InputAt(1));
3993 VisitBinop<T>(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
3997 node,
4001 VisitBinop<T>(node, UseInfo::AnyTagged(),
4008 VisitFastApiCall<T>(node, lowering);
4053 if (node->opcode() == IrOpcode::kJSWasmCall) {
4054 return VisitJSWasmCall<T>(node, lowering);
4057 VisitInputs<T>(node);
4059 return SetOutput<T>(node, MachineRepresentation::kTagged);
4061 ProcessInput<T>(node, 0, UseInfo::Any());
4062 return SetOutput<T>(node, MachineRepresentation::kNone);
4064 DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
4065 return VisitUnop<T>(node, UseInfo::Bool(),
4068 return VisitUnop<T>(node, UseInfo::AnyTagged(),
4071 Type inputType = TypeOf(node->InputAt(0));
4072 VisitUnop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged,
4076 ChangeOp(node, simplified()->AssertType(inputType));
4084 DeferReplacement(node, node->InputAt(0));
4092 "Representation inference: unsupported opcode %i (%s), node #%i\n.",
4093 node->opcode(), node->op()->mnemonic(), node->id());
4099 void DisconnectFromEffectAndControl(Node* node) {
4100 if (node->op()->EffectInputCount() == 1) {
4101 Node* control = NodeProperties::GetControlInput(node);
4102 Node* effect = NodeProperties::GetEffectInput(node);
4103 ReplaceEffectControlUses(node, effect, control);
4105 DCHECK_EQ(0, node->op()->EffectInputCount());
4106 DCHECK_EQ(0, node->op()->ControlOutputCount());
4107 DCHECK_EQ(0, node->op()->EffectOutputCount());
4111 void DeferReplacement(Node* node, Node* replacement) {
4112 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
4113 node->op()->mnemonic(), replacement->id(),
4116 DisconnectFromEffectAndControl(node);
4117 node->NullAllInputs(); // Node is now dead.
4119 replacements_.push_back(node);
4122 NotifyNodeReplaced(node, replacement);
4125 Node* InsertTypeOverrideForVerifier(const Type& type, Node* node) {
4128 node = graph()->NewNode(common()->SLVerifierHint(nullptr, type), node);
4129 verifier_->RecordHint(node);
4131 return node;
4134 void ChangeToSemanticsHintForVerifier(Node* node, const Operator* semantics) {
4135 DCHECK_EQ(node->op()->ValueInputCount(), 1);
4136 DCHECK_EQ(node->op()->EffectInputCount(), 0);
4137 DCHECK_EQ(node->op()->ControlInputCount(), 0);
4139 ChangeOp(node, common()->SLVerifierHint(semantics, base::nullopt));
4140 verifier_->RecordHint(node);
4142 DeferReplacement(node, node->InputAt(0));
4147 void ChangeOp(Node* node, const Operator* new_op) {
4148 compiler::NodeProperties::ChangeOp(node, new_op);
4151 observe_node_manager_->OnNodeChanged(kSimplifiedLoweringReducerName, node,
4152 node);
4155 void NotifyNodeReplaced(Node* node, Node* replacement) {
4157 observe_node_manager_->OnNodeChanged(kSimplifiedLoweringReducerName, node,
4164 // Map from node to its uses that might need to be revisited.
4167 ZoneVector<NodeInfo> info_; // node id -> usage information
4177 Node* node;
4195 NodeInfo* GetInfo(Node* node) {
4196 DCHECK(node->id() < count_);
4197 return &info_[node->id()];
4207 // for that input node.
4211 Node* node = use_node->InputAt(index);
4212 NodeInfo* info = GetInfo(node);
4220 TRACE(" initial #%i: %s\n", node->id(), info->truncation().description());
4223 TRACE(" queue #%i?: %s\n", node->id(), info->truncation().description());
4225 // New usage information for the node is available.
4228 revisit_queue_.push(node);
4239 Node* node, MachineRepresentation representation, Type restriction_type) {
4240 NodeInfo* const info = GetInfo(node);
4246 Node* node, MachineRepresentation representation, Type restriction_type) {
4247 NodeInfo* const info = GetInfo(node);
4254 Node* node, MachineRepresentation representation, Type restriction_type) {
4255 NodeInfo* const info = GetInfo(node);
4262 void RepresentationSelector::ProcessInput<PROPAGATE>(Node* node, int index,
4265 !node->op()->HasProperty(Operator::kNoDeopt) &&
4266 node->op()->EffectInputCount() > 0);
4267 EnqueueInput<PROPAGATE>(node, index, use);
4271 void RepresentationSelector::ProcessInput<RETYPE>(Node* node, int index,
4274 !node->op()->HasProperty(Operator::kNoDeopt) &&
4275 node->op()->EffectInputCount() > 0);
4279 void RepresentationSelector::ProcessInput<LOWER>(Node* node, int index,
4282 !node->op()->HasProperty(Operator::kNoDeopt) &&
4283 node->op()->EffectInputCount() > 0);
4284 ConvertInput(node, index, use);
4288 void RepresentationSelector::ProcessRemainingInputs<PROPAGATE>(Node* node,
4290 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
4293 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
4294 i < node->InputCount(); ++i) {
4295 EnqueueInput<PROPAGATE>(node, i);
4299 // The default, most general visitation case. For {node}, process all value,
4304 void RepresentationSelector::VisitInputs<PROPAGATE>(Node* node) {
4305 int first_effect_index = NodeProperties::FirstEffectIndex(node);
4308 ProcessInput<PROPAGATE>(node, i, UseInfo::AnyTagged());
4311 for (int i = first_effect_index; i < node->InputCount(); i++) {
4312 EnqueueInput<PROPAGATE>(node, i);
4317 void RepresentationSelector::VisitInputs<LOWER>(Node* node) {
4318 int first_effect_index = NodeProperties::FirstEffectIndex(node);
4321 ProcessInput<LOWER>(node, i, UseInfo::AnyTagged());
4326 void RepresentationSelector::InsertUnreachableIfNecessary<LOWER>(Node* node) {
4327 // If the node is effectful and it produces an impossible value, then we
4328 // insert Unreachable node after it.
4329 if (node->op()->ValueOutputCount() > 0 &&
4330 node->op()->EffectOutputCount() > 0 &&
4331 node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
4332 Node* control = (node->op()->ControlOutputCount() == 0)
4333 ? NodeProperties::GetControlInput(node, 0)
4334 : NodeProperties::FindSuccessfulControlProjection(node);
4337 graph()->NewNode(common()->Unreachable(), node, control);
4339 // Insert unreachable node and replace all the effect uses of the {node}
4340 // with the new unreachable node.
4341 for (Edge edge : node->use_edges()) {
4343 // Make sure to not overwrite the unreachable node's input. That would
4348 DCHECK(!node->op()->HasProperty(Operator::kNoThrow));
4349 DCHECK_EQ(NodeProperties::GetControlInput(edge.from()), node);
4387 Node* node, RepresentationSelector* selector) {
4388 DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
4389 node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
4390 node->opcode() == IrOpcode::kJSToNumeric);
4391 Node* value = node->InputAt(0);
4392 Node* context = node->InputAt(1);
4393 Node* frame_state = node->InputAt(2);
4394 Node* effect = node->InputAt(3);
4395 Node* control = node->InputAt(4);
4414 node->opcode() == IrOpcode::kJSToNumber
4415 ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
4419 Node* code = node->opcode() == IrOpcode::kJSToNumber
4421 : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
4427 // Update potential {IfException} uses of {node} to point to the above
4428 // stub call node instead.
4430 if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
4471 for (Edge edge : node->use_edges()) {
4485 selector->DeferReplacement(node, value);
4489 Node* node, RepresentationSelector* selector) {
4490 DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
4491 node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
4492 node->opcode() == IrOpcode::kJSToNumeric);
4493 Node* value = node->InputAt(0);
4494 Node* context = node->InputAt(1);
4495 Node* frame_state = node->InputAt(2);
4496 Node* effect = node->InputAt(3);
4497 Node* control = node->InputAt(4);
4513 node->opcode() == IrOpcode::kJSToNumber
4514 ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
4518 Node* code = node->opcode() == IrOpcode::kJSToNumber
4520 : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
4526 // Update potential {IfException} uses of {node} to point to the above
4527 // stub call node instead.
4529 if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
4566 for (Edge edge : node->use_edges()) {
4580 selector->DeferReplacement(node, value);
4583 Node* SimplifiedLowering::Float64Round(Node* const node) {
4586 Node* const input = node->InputAt(0);
4590 node->InputAt(0));
4599 Node* SimplifiedLowering::Float64Sign(Node* const node) {
4604 Node* const input = node->InputAt(0);
4615 Node* SimplifiedLowering::Int32Abs(Node* const node) {
4616 Node* const input = node->InputAt(0);
4630 Node* SimplifiedLowering::Int32Div(Node* const node) {
4631 Int32BinopMatcher m(node);
4634 Node* const lhs = m.left().node();
4635 Node* const rhs = m.right().node();
4703 Node* SimplifiedLowering::Int32Mod(Node* const node) {
4704 Int32BinopMatcher m(node);
4707 Node* const lhs = m.left().node();
4708 Node* const rhs = m.right().node();
4801 Node* SimplifiedLowering::Int32Sign(Node* const node) {
4806 Node* const input = node->InputAt(0);
4817 Node* SimplifiedLowering::Uint32Div(Node* const node) {
4818 Uint32BinopMatcher m(node);
4820 Node* const lhs = m.left().node();
4821 Node* const rhs = m.right().node();
4835 Node* SimplifiedLowering::Uint32Mod(Node* const node) {
4836 Uint32BinopMatcher m(node);
4839 Node* const lhs = m.left().node();
4840 Node* const rhs = m.right().node();
4895 void SimplifiedLowering::DoMax(Node* node, Operator const* op,
4897 Node* const lhs = node->InputAt(0);
4898 Node* const rhs = node->InputAt(1);
4900 node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
4901 DCHECK_EQ(rhs, node->InputAt(1));
4902 node->AppendInput(graph()->zone(), lhs);
4903 ChangeOp(node, common()->Select(rep));
4906 void SimplifiedLowering::DoMin(Node* node, Operator const* op,
4908 Node* const lhs = node->InputAt(0);
4909 Node* const rhs = node->InputAt(1);
4911 node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
4912 DCHECK_EQ(lhs, node->InputAt(1));
4913 DCHECK_EQ(rhs, node->InputAt(2));
4914 ChangeOp(node, common()->Select(rep));
4917 void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
4918 Node* const input = node->InputAt(0);
4922 node->ReplaceInput(0, graph()->NewNode(op, input, zero));
4923 node->AppendInput(graph()->zone(), zero);
4924 ChangeOp(node, op);
4927 void SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
4928 Node* const input = node->InputAt(0);
4930 node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
4932 node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
4933 ChangeOp(node, machine()->Word32Equal());
4936 void SimplifiedLowering::DoNumberToBit(Node* node) {
4937 Node* const input = node->InputAt(0);
4939 node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
4940 node->AppendInput(graph()->zone(),
4942 ChangeOp(node, machine()->Float64LessThan());
4945 void SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
4946 Node* const input = node->InputAt(0);
4950 node->ReplaceInput(
4952 node->AppendInput(
4958 node->AppendInput(graph()->zone(), min);
4959 ChangeOp(node, common()->Select(MachineRepresentation::kFloat64));
4962 void SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
4963 Node* const input = node->InputAt(0);
4967 node->ReplaceInput(
4976 ChangeOp(node, machine()->Float64RoundTiesEven().placeholder());
4979 void SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
4980 Node* const input = node->InputAt(0);
4984 node->ReplaceInput(
4986 node->AppendInput(
4991 node->AppendInput(graph()->zone(), max);
4992 ChangeOp(node, common()->Select(MachineRepresentation::kWord32));
4995 void SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
4996 Node* const input = node->InputAt(0);
4999 node->ReplaceInput(
5001 node->AppendInput(graph()->zone(), input);
5002 node->AppendInput(graph()->zone(), max);
5003 ChangeOp(node, common()->Select(MachineRepresentation::kWord32));
5072 void SimplifiedLowering::ChangeOp(Node* node, const Operator* new_op) {
5073 compiler::NodeProperties::ChangeOp(node, new_op);
5076 observe_node_manager_->OnNodeChanged(kSimplifiedLoweringReducerName, node,
5077 node);