5 #include "src/compiler/simplified-lowering.h" 9 #include "src/address-map.h" 10 #include "src/base/bits.h" 11 #include "src/code-factory.h" 12 #include "src/compiler/access-builder.h" 13 #include "src/compiler/common-operator.h" 14 #include "src/compiler/compiler-source-position-table.h" 15 #include "src/compiler/diamond.h" 16 #include "src/compiler/linkage.h" 17 #include "src/compiler/node-matchers.h" 18 #include "src/compiler/node-origin-table.h" 19 #include "src/compiler/node-properties.h" 20 #include "src/compiler/operation-typer.h" 21 #include "src/compiler/operator-properties.h" 22 #include "src/compiler/representation-change.h" 23 #include "src/compiler/simplified-operator.h" 24 #include "src/compiler/type-cache.h" 25 #include "src/conversions-inl.h" 26 #include "src/objects.h" 35 if (FLAG_trace_representation) PrintF(__VA_ARGS__); \ 69 MachineRepresentation MachineRepresentationFromArrayType(
70 ExternalArrayType array_type) {
72 case kExternalUint8Array:
73 case kExternalUint8ClampedArray:
74 case kExternalInt8Array:
75 return MachineRepresentation::kWord8;
76 case kExternalUint16Array:
77 case kExternalInt16Array:
78 return MachineRepresentation::kWord16;
79 case kExternalUint32Array:
80 case kExternalInt32Array:
81 return MachineRepresentation::kWord32;
82 case kExternalFloat32Array:
83 return MachineRepresentation::kFloat32;
84 case kExternalFloat64Array:
85 return MachineRepresentation::kFloat64;
86 case kExternalBigInt64Array:
87 case kExternalBigUint64Array:
93 UseInfo CheckedUseInfoAsWord32FromHint(
94 NumberOperationHint hint,
const VectorSlotPair& feedback = VectorSlotPair(),
95 IdentifyZeros identify_zeros = kDistinguishZeros) {
97 case NumberOperationHint::kSignedSmall:
98 case NumberOperationHint::kSignedSmallInputs:
99 return UseInfo::CheckedSignedSmallAsWord32(identify_zeros, feedback);
100 case NumberOperationHint::kSigned32:
101 return UseInfo::CheckedSigned32AsWord32(identify_zeros, feedback);
102 case NumberOperationHint::kNumber:
103 return UseInfo::CheckedNumberAsWord32(feedback);
104 case NumberOperationHint::kNumberOrOddball:
105 return UseInfo::CheckedNumberOrOddballAsWord32(feedback);
110 UseInfo CheckedUseInfoAsFloat64FromHint(
111 NumberOperationHint hint,
const VectorSlotPair& feedback,
112 IdentifyZeros identify_zeros = kDistinguishZeros) {
114 case NumberOperationHint::kSignedSmall:
115 case NumberOperationHint::kSignedSmallInputs:
116 case NumberOperationHint::kSigned32:
120 case NumberOperationHint::kNumber:
121 return UseInfo::CheckedNumberAsFloat64(identify_zeros, feedback);
122 case NumberOperationHint::kNumberOrOddball:
123 return UseInfo::CheckedNumberOrOddballAsFloat64(identify_zeros, feedback);
128 UseInfo TruncatingUseInfoFromRepresentation(MachineRepresentation rep) {
130 case MachineRepresentation::kTaggedSigned:
131 return UseInfo::TaggedSigned();
132 case MachineRepresentation::kTaggedPointer:
133 case MachineRepresentation::kTagged:
134 return UseInfo::AnyTagged();
135 case MachineRepresentation::kFloat64:
136 return UseInfo::TruncatingFloat64();
137 case MachineRepresentation::kFloat32:
138 return UseInfo::Float32();
139 case MachineRepresentation::kWord8:
140 case MachineRepresentation::kWord16:
141 case MachineRepresentation::kWord32:
142 return UseInfo::TruncatingWord32();
143 case MachineRepresentation::kWord64:
144 return UseInfo::Word64();
145 case MachineRepresentation::kBit:
146 return UseInfo::Bool();
147 case MachineRepresentation::kSimd128:
148 case MachineRepresentation::kNone:
154 UseInfo UseInfoForBasePointer(
const FieldAccess& access) {
155 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
158 UseInfo UseInfoForBasePointer(
const ElementAccess& access) {
159 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::Word();
162 void ReplaceEffectControlUses(Node* node, Node* effect, Node* control) {
163 for (Edge edge : node->use_edges()) {
164 if (NodeProperties::IsControlEdge(edge)) {
165 edge.UpdateTo(control);
166 }
else if (NodeProperties::IsEffectEdge(edge)) {
167 edge.UpdateTo(effect);
169 DCHECK(NodeProperties::IsValueEdge(edge) ||
170 NodeProperties::IsContextEdge(edge));
175 void ChangeToPureOp(Node* node,
const Operator* new_op) {
176 DCHECK(new_op->HasProperty(Operator::kPure));
177 if (node->op()->EffectInputCount() > 0) {
178 DCHECK_LT(0, node->op()->ControlInputCount());
180 Node* control = NodeProperties::GetControlInput(node);
181 Node* effect = NodeProperties::GetEffectInput(node);
182 ReplaceEffectControlUses(node, effect, control);
183 node->TrimInputCount(new_op->ValueInputCount());
185 DCHECK_EQ(0, node->op()->ControlInputCount());
187 NodeProperties::ChangeOp(node, new_op);
190 bool CanOverflowSigned32(
const Operator* op,
Type left,
Type right,
195 left = Type::Intersect(left, Type::Signed32(), type_zone);
196 right = Type::Intersect(right, Type::Signed32(), type_zone);
197 if (left.IsNone() || right.IsNone())
return false;
198 switch (op->opcode()) {
199 case IrOpcode::kSpeculativeSafeIntegerAdd:
200 return (left.Max() + right.Max() > kMaxInt) ||
201 (left.Min() + right.Min() < kMinInt);
203 case IrOpcode::kSpeculativeSafeIntegerSubtract:
204 return (left.Max() - right.Min() > kMaxInt) ||
205 (left.Min() - right.Max() < kMinInt);
213 bool IsSomePositiveOrderedNumber(
Type type) {
214 return type.Is(Type::OrderedNumber()) && !type.IsNone() && type.Min() > 0;
221 class InputUseInfos {
223 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {}
225 void SetAndCheckInput(Node* node,
int index, UseInfo use_info) {
226 if (input_use_infos_.empty()) {
227 input_use_infos_.resize(node->InputCount(), UseInfo::None());
231 DCHECK(IsUseLessGeneral(input_use_infos_[index], use_info));
232 input_use_infos_[index] = use_info;
236 ZoneVector<UseInfo> input_use_infos_;
238 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) {
239 return use1.truncation().IsLessGeneralThan(use2.truncation());
254 truncation_ = Truncation::Generalize(truncation_, info.truncation());
255 return truncation_ != old_truncation;
258 void set_queued() { state_ = kQueued; }
259 void set_visited() { state_ = kVisited; }
260 void set_pushed() { state_ = kPushed; }
261 void reset_state() { state_ = kUnvisited; }
262 bool visited()
const {
return state_ == kVisited; }
263 bool queued()
const {
return state_ == kQueued; }
264 bool unvisited()
const {
return state_ == kUnvisited; }
265 Truncation truncation()
const {
return truncation_; }
266 void set_output(MachineRepresentation output) { representation_ = output; }
268 MachineRepresentation representation()
const {
return representation_; }
271 void set_feedback_type(
Type type) { feedback_type_ =
type; }
272 Type feedback_type()
const {
return feedback_type_; }
273 void set_weakened() { weakened_ =
true; }
274 bool weakened()
const {
return weakened_; }
275 void set_restriction_type(
Type type) { restriction_type_ =
type; }
276 Type restriction_type()
const {
return restriction_type_; }
279 enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued };
280 State state_ = kUnvisited;
281 MachineRepresentation representation_ =
282 MachineRepresentation::kNone;
285 Type restriction_type_ = Type::Any();
287 bool weakened_ =
false;
296 count_(jsgraph->graph()->NodeCount()),
299 node_input_use_infos_(count_, InputUseInfos(zone), zone),
307 source_positions_(source_positions),
308 node_origins_(node_origins),
310 op_typer_(broker, graph_zone()) {
314 void RunTypePropagationPhase() {
316 TRACE(
"--{Type propagation phase}--\n");
318 ResetNodeInfoState();
320 DCHECK(typing_stack_.empty());
321 typing_stack_.push({graph()->end(), 0});
322 GetInfo(graph()->end())->set_pushed();
323 while (!typing_stack_.empty()) {
324 NodeState& current = typing_stack_.top();
327 bool pushed_unvisited =
false;
328 while (current.input_index < current.node->InputCount()) {
329 Node* input = current.node->InputAt(current.input_index);
330 NodeInfo* input_info = GetInfo(input);
331 current.input_index++;
332 if (input_info->unvisited()) {
333 input_info->set_pushed();
334 typing_stack_.push({input, 0});
335 pushed_unvisited =
true;
339 if (pushed_unvisited)
continue;
342 Node* node = current.node;
344 NodeInfo* info = GetInfo(node);
346 bool updated = UpdateFeedbackType(node);
347 TRACE(
" visit #%d: %s\n", node->id(), node->op()->mnemonic());
348 VisitNode(node, info->truncation(),
nullptr);
349 TRACE(
" ==> output ");
350 PrintOutputInfo(info);
353 for (Node*
const user : node->uses()) {
354 if (GetInfo(user)->visited()) {
355 GetInfo(user)->set_queued();
363 while (!queue_.empty()) {
364 Node* node = queue_.front();
366 NodeInfo* info = GetInfo(node);
368 bool updated = UpdateFeedbackType(node);
369 TRACE(
" visit #%d: %s\n", node->id(), node->op()->mnemonic());
370 VisitNode(node, info->truncation(),
nullptr);
371 TRACE(
" ==> output ");
372 PrintOutputInfo(info);
375 for (Node*
const user : node->uses()) {
376 if (GetInfo(user)->visited()) {
377 GetInfo(user)->set_queued();
385 void ResetNodeInfoState() {
387 for (NodeInfo& info : info_) {
392 Type TypeOf(Node* node) {
393 Type type = GetInfo(node)->feedback_type();
394 return type.IsInvalid() ? NodeProperties::GetType(node) : type;
397 Type FeedbackTypeOf(Node* node) {
398 Type type = GetInfo(node)->feedback_type();
399 return type.IsInvalid() ? Type::None() : type;
402 Type TypePhi(Node* node) {
403 int arity = node->op()->ValueInputCount();
404 Type type = FeedbackTypeOf(node->InputAt(0));
405 for (
int i = 1;
i < arity; ++
i) {
406 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(
i)));
411 Type TypeSelect(Node* node) {
412 return op_typer_.Merge(FeedbackTypeOf(node->InputAt(1)),
413 FeedbackTypeOf(node->InputAt(2)));
416 bool UpdateFeedbackType(Node* node) {
417 if (node->op()->ValueOutputCount() == 0)
return false;
419 NodeInfo* info = GetInfo(node);
420 Type type = info->feedback_type();
421 Type new_type = type;
426 if (node->opcode() != IrOpcode::kPhi) {
427 for (
int i = 0;
i < node->op()->ValueInputCount();
i++) {
428 if (GetInfo(node->InputAt(
i))->feedback_type().IsInvalid()) {
437 if (node->InputCount() > 0) input0_type = FeedbackTypeOf(node->InputAt(0));
439 if (node->InputCount() > 1) input1_type = FeedbackTypeOf(node->InputAt(1));
441 switch (node->opcode()) {
442 #define DECLARE_CASE(Name) \ 443 case IrOpcode::k##Name: { \ 444 new_type = op_typer_.Name(input0_type, input1_type); \ 447 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE)
448 DECLARE_CASE(SameValue)
451 #define DECLARE_CASE(Name) \ 452 case IrOpcode::k##Name: { \ 453 new_type = Type::Intersect(op_typer_.Name(input0_type, input1_type), \ 454 info->restriction_type(), graph_zone()); \ 457 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE)
460 #define DECLARE_CASE(Name) \ 461 case IrOpcode::k##Name: { \ 462 new_type = op_typer_.Name(input0_type); \ 465 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE)
468 #define DECLARE_CASE(Name) \ 469 case IrOpcode::k##Name: { \ 470 new_type = Type::Intersect(op_typer_.Name(input0_type), \ 471 info->restriction_type(), graph_zone()); \ 474 SIMPLIFIED_SPECULATIVE_NUMBER_UNOP_LIST(DECLARE_CASE)
477 case IrOpcode::kConvertReceiver:
478 new_type = op_typer_.ConvertReceiver(input0_type);
481 case IrOpcode::kPlainPrimitiveToNumber:
482 new_type = op_typer_.ToNumber(input0_type);
485 case IrOpcode::kCheckBounds:
487 Type::Intersect(op_typer_.CheckBounds(input0_type, input1_type),
488 info->restriction_type(), graph_zone());
491 case IrOpcode::kCheckFloat64Hole:
492 new_type = Type::Intersect(op_typer_.CheckFloat64Hole(input0_type),
493 info->restriction_type(), graph_zone());
496 case IrOpcode::kCheckNumber:
497 new_type = Type::Intersect(op_typer_.CheckNumber(input0_type),
498 info->restriction_type(), graph_zone());
501 case IrOpcode::kPhi: {
502 new_type = TypePhi(node);
503 if (!type.IsInvalid()) {
504 new_type = Weaken(node, type, new_type);
509 case IrOpcode::kConvertTaggedHoleToUndefined:
510 new_type = op_typer_.ConvertTaggedHoleToUndefined(
511 FeedbackTypeOf(node->InputAt(0)));
514 case IrOpcode::kTypeGuard: {
515 new_type = op_typer_.TypeTypeGuard(node->op(),
516 FeedbackTypeOf(node->InputAt(0)));
520 case IrOpcode::kSelect: {
521 new_type = TypeSelect(node);
527 if (type.IsInvalid()) {
528 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node));
537 new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone());
539 if (!type.IsInvalid() && new_type.Is(type))
return false;
540 GetInfo(node)->set_feedback_type(new_type);
541 if (FLAG_trace_representation) {
542 PrintNodeFeedbackType(node);
547 void PrintNodeFeedbackType(Node* n) {
549 os <<
"#" << n->id() <<
":" << *n->op() <<
"(";
551 for (Node*
const i : n->inputs()) {
552 if (j++ > 0) os <<
", ";
553 os <<
"#" <<
i->id() <<
":" <<
i->op()->mnemonic();
556 if (NodeProperties::IsTyped(n)) {
557 Type static_type = NodeProperties::GetType(n);
558 os <<
" [Static type: " << static_type;
559 Type feedback_type = GetInfo(n)->feedback_type();
560 if (!feedback_type.IsInvalid() && feedback_type != static_type) {
561 os <<
", Feedback type: " << feedback_type;
568 Type Weaken(Node* node,
Type previous_type,
Type current_type) {
570 Type const integer = type_cache_.kInteger;
571 if (!previous_type.Maybe(integer)) {
574 DCHECK(current_type.Maybe(integer));
576 Type current_integer = Type::Intersect(current_type, integer, graph_zone());
577 DCHECK(!current_integer.IsNone());
578 Type previous_integer =
579 Type::Intersect(previous_type, integer, graph_zone());
580 DCHECK(!previous_integer.IsNone());
583 if (!GetInfo(node)->weakened()) {
587 Type previous = previous_integer.GetRange();
588 Type current = current_integer.GetRange();
589 if (current.IsInvalid() || previous.IsInvalid()) {
593 GetInfo(node)->set_weakened();
596 return Type::Union(current_type,
597 op_typer_.WeakenRange(previous_integer, current_integer),
602 void RunTruncationPropagationPhase() {
604 TRACE(
"--{Propagation phase}--\n");
606 EnqueueInitial(jsgraph_->graph()->end());
608 while (!queue_.empty()) {
609 Node* node = queue_.front();
610 NodeInfo* info = GetInfo(node);
613 TRACE(
" visit #%d: %s (trunc: %s)\n", node->id(), node->op()->mnemonic(),
614 info->truncation().description());
615 VisitNode(node, info->truncation(),
nullptr);
619 void Run(SimplifiedLowering* lowering) {
620 RunTruncationPropagationPhase();
622 RunTypePropagationPhase();
625 TRACE(
"--{Simplified lowering phase}--\n");
628 for (NodeVector::iterator
i = nodes_.begin();
i != nodes_.end(); ++
i) {
630 NodeInfo* info = GetInfo(node);
631 TRACE(
" visit #%d: %s\n", node->id(), node->op()->mnemonic());
633 SourcePositionTable::Scope scope(
634 source_positions_, source_positions_->GetSourcePosition(node));
635 NodeOriginTable::Scope origin_scope(node_origins_,
"simplified lowering",
637 VisitNode(node, info->truncation(), lowering);
641 for (NodeVector::iterator
i = replacements_.begin();
642 i != replacements_.end(); ++
i) {
644 Node* replacement = *(++
i);
645 node->ReplaceUses(replacement);
648 for (NodeVector::iterator j =
i + 1; j != replacements_.end(); ++j) {
650 if (*j == node) *j = replacement;
655 void EnqueueInitial(Node* node) {
656 NodeInfo* info = GetInfo(node);
658 nodes_.push_back(node);
665 void EnqueueInput(Node* use_node,
int index,
666 UseInfo use_info = UseInfo::None()) {
667 Node* node = use_node->InputAt(index);
668 if (phase_ != PROPAGATE)
return;
669 NodeInfo* info = GetInfo(node);
672 node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index,
675 if (info->unvisited()) {
678 nodes_.push_back(node);
680 TRACE(
" initial #%i: ", node->id());
681 info->AddUse(use_info);
682 PrintTruncation(info->truncation());
685 TRACE(
" queue #%i?: ", node->id());
686 PrintTruncation(info->truncation());
687 if (info->AddUse(use_info)) {
689 if (!info->queued()) {
696 PrintTruncation(info->truncation());
700 bool lower()
const {
return phase_ == LOWER; }
701 bool retype()
const {
return phase_ == RETYPE; }
702 bool propagate()
const {
return phase_ == PROPAGATE; }
704 void SetOutput(Node* node, MachineRepresentation representation,
705 Type restriction_type = Type::Any()) {
706 NodeInfo*
const info = GetInfo(node);
709 info->set_restriction_type(restriction_type);
712 DCHECK(info->restriction_type().Is(restriction_type));
713 DCHECK(restriction_type.Is(info->restriction_type()));
714 info->set_output(representation);
717 DCHECK_EQ(info->representation(), representation);
718 DCHECK(info->restriction_type().Is(restriction_type));
719 DCHECK(restriction_type.Is(info->restriction_type()));
724 Type GetUpperBound(Node* node) {
return NodeProperties::GetType(node); }
726 bool InputCannotBe(Node* node,
Type type) {
727 DCHECK_EQ(1, node->op()->ValueInputCount());
728 return !GetUpperBound(node->InputAt(0)).Maybe(type);
731 bool InputIs(Node* node,
Type type) {
732 DCHECK_EQ(1, node->op()->ValueInputCount());
733 return GetUpperBound(node->InputAt(0)).Is(type);
736 bool BothInputsAreSigned32(Node* node) {
737 return BothInputsAre(node, Type::Signed32());
740 bool BothInputsAreUnsigned32(Node* node) {
741 return BothInputsAre(node, Type::Unsigned32());
744 bool BothInputsAre(Node* node,
Type type) {
745 DCHECK_EQ(2, node->op()->ValueInputCount());
746 return GetUpperBound(node->InputAt(0)).Is(type) &&
747 GetUpperBound(node->InputAt(1)).Is(type);
750 bool IsNodeRepresentationTagged(Node* node) {
751 MachineRepresentation representation = GetInfo(node)->representation();
752 return IsAnyTagged(representation);
755 bool OneInputCannotBe(Node* node,
Type type) {
756 DCHECK_EQ(2, node->op()->ValueInputCount());
757 return !GetUpperBound(node->InputAt(0)).Maybe(type) ||
758 !GetUpperBound(node->InputAt(1)).Maybe(type);
764 void ConvertInput(Node* node,
int index, UseInfo use,
765 Type input_type = Type::Invalid()) {
766 Node* input = node->InputAt(index);
768 if (use.representation() == MachineRepresentation::kNone)
770 DCHECK_NOT_NULL(input);
771 NodeInfo* input_info = GetInfo(input);
772 MachineRepresentation input_rep = input_info->representation();
773 if (input_rep != use.representation() ||
774 use.type_check() != TypeCheckKind::kNone) {
776 TRACE(
" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
777 index, input->id(), input->op()->mnemonic());
779 PrintOutputInfo(input_info);
783 if (input_type.IsInvalid()) {
784 input_type = TypeOf(input);
786 Node* n = changer_->GetRepresentationFor(
787 input, input_info->representation(), input_type, node, use);
788 node->ReplaceInput(index, n);
792 void ProcessInput(Node* node,
int index, UseInfo use) {
795 EnqueueInput(node, index, use);
800 ConvertInput(node, index, use);
805 void ProcessRemainingInputs(Node* node,
int index) {
806 DCHECK_GE(index, NodeProperties::PastValueIndex(node));
807 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
808 for (
int i = std::max(index, NodeProperties::FirstEffectIndex(node));
809 i < NodeProperties::PastEffectIndex(node); ++
i) {
810 EnqueueInput(node,
i);
812 for (
int i = std::max(index, NodeProperties::FirstControlIndex(node));
813 i < NodeProperties::PastControlIndex(node); ++
i) {
814 EnqueueInput(node,
i);
822 void VisitInputs(Node* node) {
823 int tagged_count = node->op()->ValueInputCount() +
824 OperatorProperties::GetContextInputCount(node->op()) +
825 OperatorProperties::GetFrameStateInputCount(node->op());
827 for (
int i = 0;
i < tagged_count;
i++) {
828 ProcessInput(node,
i, UseInfo::AnyTagged());
831 for (
int i = tagged_count;
i < node->InputCount();
i++) {
832 EnqueueInput(node,
i);
836 void VisitReturn(Node* node) {
837 int tagged_limit = node->op()->ValueInputCount() +
838 OperatorProperties::GetContextInputCount(node->op()) +
839 OperatorProperties::GetFrameStateInputCount(node->op());
841 ProcessInput(node, 0, UseInfo::TruncatingWord32());
844 for (
int i = 1;
i < tagged_limit;
i++) {
845 ProcessInput(node,
i, UseInfo::AnyTagged());
848 for (
int i = tagged_limit;
i < node->InputCount();
i++) {
849 EnqueueInput(node,
i);
854 void VisitUnused(Node* node) {
855 int value_count = node->op()->ValueInputCount() +
856 OperatorProperties::GetContextInputCount(node->op()) +
857 OperatorProperties::GetFrameStateInputCount(node->op());
858 for (
int i = 0;
i < value_count;
i++) {
859 ProcessInput(node,
i, UseInfo::None());
861 ProcessRemainingInputs(node, value_count);
862 if (lower()) Kill(node);
866 void VisitNoop(Node* node, Truncation truncation) {
867 if (truncation.IsUnused())
return VisitUnused(node);
868 MachineRepresentation representation =
869 GetOutputInfoForPhi(node, TypeOf(node), truncation);
870 VisitUnop(node, UseInfo(representation, truncation), representation);
871 if (lower()) DeferReplacement(node, node->InputAt(0));
875 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
876 MachineRepresentation output,
877 Type restriction_type = Type::Any()) {
878 DCHECK_EQ(2, node->op()->ValueInputCount());
879 ProcessInput(node, 0, left_use);
880 ProcessInput(node, 1, right_use);
881 for (
int i = 2;
i < node->InputCount();
i++) {
882 EnqueueInput(node,
i);
884 SetOutput(node, output, restriction_type);
888 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output,
889 Type restriction_type = Type::Any()) {
890 VisitBinop(node, input_use, input_use, output, restriction_type);
893 void VisitSpeculativeInt32Binop(Node* node) {
894 DCHECK_EQ(2, node->op()->ValueInputCount());
895 if (BothInputsAre(node, Type::NumberOrOddball())) {
896 return VisitBinop(node, UseInfo::TruncatingWord32(),
897 MachineRepresentation::kWord32);
899 NumberOperationHint hint = NumberOperationHintOf(node->op());
900 return VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
901 MachineRepresentation::kWord32);
905 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output,
906 Type restriction_type = Type::Any()) {
907 DCHECK_EQ(1, node->op()->ValueInputCount());
908 ProcessInput(node, 0, input_use);
909 ProcessRemainingInputs(node, 1);
910 SetOutput(node, output, restriction_type);
914 void VisitLeaf(Node* node, MachineRepresentation output) {
915 DCHECK_EQ(0, node->InputCount());
916 SetOutput(node, output);
920 void VisitFloat64Binop(Node* node) {
921 VisitBinop(node, UseInfo::TruncatingFloat64(),
922 MachineRepresentation::kFloat64);
924 void VisitInt64Binop(Node* node) {
925 VisitBinop(node, UseInfo::Word64(), MachineRepresentation::kWord64);
927 void VisitWord32TruncatingBinop(Node* node) {
928 VisitBinop(node, UseInfo::TruncatingWord32(),
929 MachineRepresentation::kWord32);
936 MachineRepresentation GetOutputInfoForPhi(Node* node,
Type type,
939 if (type.Is(Type::None())) {
940 return MachineRepresentation::kNone;
941 }
else if (type.Is(Type::Signed32()) || type.Is(Type::Unsigned32())) {
942 return MachineRepresentation::kWord32;
943 }
else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsWord32()) {
944 return MachineRepresentation::kWord32;
945 }
else if (type.Is(Type::Boolean())) {
946 return MachineRepresentation::kBit;
947 }
else if (type.Is(Type::NumberOrOddball()) && use.IsUsedAsFloat64()) {
948 return MachineRepresentation::kFloat64;
949 }
else if (type.Is(Type::Union(Type::SignedSmall(), Type::NaN(), zone()))) {
954 return MachineRepresentation::kTagged;
955 }
else if (type.Is(Type::Number())) {
956 return MachineRepresentation::kFloat64;
957 }
else if (type.Is(Type::ExternalPointer())) {
958 return MachineType::PointerRepresentation();
960 return MachineRepresentation::kTagged;
964 void VisitSelect(Node* node, Truncation truncation,
965 SimplifiedLowering* lowering) {
966 DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
967 ProcessInput(node, 0, UseInfo::Bool());
969 MachineRepresentation output =
970 GetOutputInfoForPhi(node, TypeOf(node), truncation);
971 SetOutput(node, output);
975 SelectParameters p = SelectParametersOf(node->op());
976 if (output != p.representation()) {
977 NodeProperties::ChangeOp(node,
978 lowering->common()->Select(output, p.hint()));
983 UseInfo input_use(output, truncation);
984 ProcessInput(node, 1, input_use);
985 ProcessInput(node, 2, input_use);
989 void VisitPhi(Node* node, Truncation truncation,
990 SimplifiedLowering* lowering) {
991 MachineRepresentation output =
992 GetOutputInfoForPhi(node, TypeOf(node), truncation);
995 SetOutput(node, output);
997 int values = node->op()->ValueInputCount();
1000 if (output != PhiRepresentationOf(node->op())) {
1001 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values));
1007 UseInfo input_use(output, truncation);
1008 for (
int i = 0;
i < node->InputCount();
i++) {
1009 ProcessInput(node,
i,
i < values ? input_use : UseInfo::None());
1013 void VisitObjectIs(Node* node,
Type type, SimplifiedLowering* lowering) {
1014 Type const input_type = TypeOf(node->InputAt(0));
1015 if (input_type.Is(type)) {
1016 VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
1018 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
1021 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
1022 if (lower() && !input_type.Maybe(type)) {
1023 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
1028 void VisitCheck(Node* node,
Type type, SimplifiedLowering* lowering) {
1029 if (InputIs(node, type)) {
1030 VisitUnop(node, UseInfo::AnyTagged(),
1031 MachineRepresentation::kTaggedPointer);
1032 if (lower()) DeferReplacement(node, node->InputAt(0));
1034 VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
1035 MachineRepresentation::kTaggedPointer);
1039 void VisitCall(Node* node, SimplifiedLowering* lowering) {
1040 auto call_descriptor = CallDescriptorOf(node->op());
1041 int params =
static_cast<int>(call_descriptor->ParameterCount());
1042 int value_input_count = node->op()->ValueInputCount();
1044 for (
int i = 0;
i < value_input_count;
i++) {
1047 ProcessInput(node,
i, UseInfo::Any());
1048 }
else if ((
i - 1) < params) {
1049 ProcessInput(node,
i,
1050 TruncatingUseInfoFromRepresentation(
1051 call_descriptor->GetInputType(
i).representation()));
1053 ProcessInput(node,
i, UseInfo::AnyTagged());
1056 ProcessRemainingInputs(node, value_input_count);
1058 if (call_descriptor->ReturnCount() > 0) {
1059 SetOutput(node, call_descriptor->GetReturnType(0).representation());
1061 SetOutput(node, MachineRepresentation::kTagged);
1065 static MachineSemantic DeoptValueSemanticOf(
Type type) {
1067 if (type.Is(Type::Signed32())) {
1068 return MachineSemantic::kInt32;
1069 }
else if (type.Is(Type::Unsigned32())) {
1070 return MachineSemantic::kUint32;
1072 return MachineSemantic::kAny;
1076 static MachineType DeoptMachineTypeOf(MachineRepresentation rep,
Type type) {
1077 if (type.IsNone()) {
1078 return MachineType::None();
1081 if (IsAnyTagged(rep)) {
1082 return MachineType::AnyTagged();
1085 if (rep == MachineRepresentation::kWord64) {
1086 DCHECK(type.Is(TypeCache::Get().kSafeInteger));
1087 return MachineType(rep, MachineSemantic::kInt64);
1089 MachineType machine_type(rep, DeoptValueSemanticOf(type));
1090 DCHECK(machine_type.representation() != MachineRepresentation::kWord32 ||
1091 machine_type.semantic() == MachineSemantic::kInt32 ||
1092 machine_type.semantic() == MachineSemantic::kUint32);
1093 DCHECK(machine_type.representation() != MachineRepresentation::kBit ||
1094 type.Is(Type::Boolean()));
1095 return machine_type;
1098 void VisitStateValues(Node* node) {
1100 for (
int i = 0;
i < node->InputCount();
i++) {
1101 EnqueueInput(node,
i, UseInfo::Any());
1103 }
else if (lower()) {
1104 Zone* zone = jsgraph_->zone();
1105 ZoneVector<MachineType>* types =
1106 new (zone->New(
sizeof(ZoneVector<MachineType>)))
1107 ZoneVector<MachineType>(node->InputCount(), zone);
1108 for (
int i = 0;
i < node->InputCount();
i++) {
1109 Node* input = node->InputAt(
i);
1111 DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
1113 SparseInputMask mask = SparseInputMaskOf(node->op());
1114 NodeProperties::ChangeOp(
1115 node, jsgraph_->common()->TypedStateValues(types, mask));
1117 SetOutput(node, MachineRepresentation::kTagged);
1120 void VisitFrameState(Node* node) {
1121 DCHECK_EQ(5, node->op()->ValueInputCount());
1122 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
1124 ProcessInput(node, 0, UseInfo::AnyTagged());
1125 ProcessInput(node, 1, UseInfo::AnyTagged());
1131 EnqueueInput(node, 2, UseInfo::Any());
1132 }
else if (lower()) {
1133 Zone* zone = jsgraph_->zone();
1134 Node* accumulator = node->InputAt(2);
1135 if (accumulator == jsgraph_->OptimizedOutConstant()) {
1136 node->ReplaceInput(2, jsgraph_->SingleDeadTypedStateValues());
1138 ZoneVector<MachineType>* types =
1139 new (zone->New(
sizeof(ZoneVector<MachineType>)))
1140 ZoneVector<MachineType>(1, zone);
1141 (*types)[0] = DeoptMachineTypeOf(GetInfo(accumulator)->representation(),
1142 TypeOf(accumulator));
1145 2, jsgraph_->graph()->NewNode(jsgraph_->common()->TypedStateValues(
1146 types, SparseInputMask::Dense()),
1151 ProcessInput(node, 3, UseInfo::AnyTagged());
1152 ProcessInput(node, 4, UseInfo::AnyTagged());
1153 ProcessInput(node, 5, UseInfo::AnyTagged());
1154 return SetOutput(node, MachineRepresentation::kTagged);
1157 void VisitObjectState(Node* node) {
1159 for (
int i = 0;
i < node->InputCount();
i++) {
1160 EnqueueInput(node,
i, UseInfo::Any());
1162 }
else if (lower()) {
1163 Zone* zone = jsgraph_->zone();
1164 ZoneVector<MachineType>* types =
1165 new (zone->New(
sizeof(ZoneVector<MachineType>)))
1166 ZoneVector<MachineType>(node->InputCount(), zone);
1167 for (
int i = 0;
i < node->InputCount();
i++) {
1168 Node* input = node->InputAt(
i);
1170 DeoptMachineTypeOf(GetInfo(input)->representation(), TypeOf(input));
1172 NodeProperties::ChangeOp(node, jsgraph_->common()->TypedObjectState(
1173 ObjectIdOf(node->op()), types));
1175 SetOutput(node, MachineRepresentation::kTagged);
1178 const Operator* Int32Op(Node* node) {
1179 return changer_->Int32OperatorFor(node->opcode());
1182 const Operator* Int32OverflowOp(Node* node) {
1183 return changer_->Int32OverflowOperatorFor(node->opcode());
1186 const Operator* Int64Op(Node* node) {
1187 return changer_->Int64OperatorFor(node->opcode());
1190 const Operator* Uint32Op(Node* node) {
1191 return changer_->Uint32OperatorFor(node->opcode());
1194 const Operator* Uint32OverflowOp(Node* node) {
1195 return changer_->Uint32OverflowOperatorFor(node->opcode());
1198 const Operator* Float64Op(Node* node) {
1199 return changer_->Float64OperatorFor(node->opcode());
1202 WriteBarrierKind WriteBarrierKindFor(
1203 BaseTaggedness base_taggedness,
1204 MachineRepresentation field_representation,
Type field_type,
1205 MachineRepresentation value_representation, Node* value) {
1206 if (base_taggedness == kTaggedBase &&
1207 CanBeTaggedPointer(field_representation)) {
1208 Type value_type = NodeProperties::GetType(value);
1209 if (field_representation == MachineRepresentation::kTaggedSigned ||
1210 value_representation == MachineRepresentation::kTaggedSigned) {
1212 return kNoWriteBarrier;
1214 if (field_type.Is(Type::BooleanOrNullOrUndefined()) ||
1215 value_type.Is(Type::BooleanOrNullOrUndefined())) {
1218 return kNoWriteBarrier;
1220 if (value_type.IsHeapConstant()) {
1221 RootIndex root_index;
1222 const RootsTable& roots_table = jsgraph_->isolate()->roots_table();
1223 if (roots_table.IsRootHandle(value_type.AsHeapConstant()->Value(),
1225 if (RootsTable::IsImmortalImmovable(root_index)) {
1227 return kNoWriteBarrier;
1231 if (field_representation == MachineRepresentation::kTaggedPointer ||
1232 value_representation == MachineRepresentation::kTaggedPointer) {
1234 return kPointerWriteBarrier;
1236 NumberMatcher m(value);
1238 if (IsSmiDouble(m.Value())) {
1240 return kNoWriteBarrier;
1243 return kPointerWriteBarrier;
1245 return kFullWriteBarrier;
1247 return kNoWriteBarrier;
1250 WriteBarrierKind WriteBarrierKindFor(
1251 BaseTaggedness base_taggedness,
1252 MachineRepresentation field_representation,
int field_offset,
1253 Type field_type, MachineRepresentation value_representation,
1255 WriteBarrierKind write_barrier_kind =
1256 WriteBarrierKindFor(base_taggedness, field_representation, field_type,
1257 value_representation, value);
1258 if (write_barrier_kind != kNoWriteBarrier) {
1259 if (base_taggedness == kTaggedBase &&
1260 field_offset == HeapObject::kMapOffset) {
1261 write_barrier_kind = kMapWriteBarrier;
1264 return write_barrier_kind;
1267 Graph* graph()
const {
return jsgraph_->graph(); }
1268 CommonOperatorBuilder* common()
const {
return jsgraph_->common(); }
1269 SimplifiedOperatorBuilder* simplified()
const {
1270 return jsgraph_->simplified();
1273 void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
1274 Type input0_type,
Type input1_type) {
1277 CheckForMinusZeroMode mz_mode =
1278 truncation.IdentifiesZeroAndMinusZero() ||
1279 IsSomePositiveOrderedNumber(input0_type) ||
1280 IsSomePositiveOrderedNumber(input1_type)
1281 ? CheckForMinusZeroMode::kDontCheckForMinusZero
1282 : CheckForMinusZeroMode::kCheckForMinusZero;
1284 NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
1287 void ChangeToInt32OverflowOp(Node* node) {
1288 NodeProperties::ChangeOp(node, Int32OverflowOp(node));
1291 void ChangeToUint32OverflowOp(Node* node) {
1292 NodeProperties::ChangeOp(node, Uint32OverflowOp(node));
1295 void VisitSpeculativeIntegerAdditiveOp(Node* node, Truncation truncation,
1296 SimplifiedLowering* lowering) {
1297 Type left_upper = GetUpperBound(node->InputAt(0));
1298 Type right_upper = GetUpperBound(node->InputAt(1));
1300 if (left_upper.Is(type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
1301 right_upper.Is(type_cache_.kAdditiveSafeIntegerOrMinusZero)) {
1304 if (truncation.IsUnused())
return VisitUnused(node);
1309 if (GetUpperBound(node).Is(Type::Signed32()) ||
1310 GetUpperBound(node).Is(Type::Unsigned32()) ||
1311 truncation.IsUsedAsWord32()) {
1313 VisitWord32TruncatingBinop(node);
1314 if (lower()) ChangeToPureOp(node, Int32Op(node));
1320 NumberOperationHint hint = NumberOperationHintOf(node->op());
1321 DCHECK(hint == NumberOperationHint::kSignedSmall ||
1322 hint == NumberOperationHint::kSigned32);
1324 Type left_feedback_type = TypeOf(node->InputAt(0));
1325 Type right_feedback_type = TypeOf(node->InputAt(1));
1331 Type left_constraint_type =
1332 node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd
1333 ? Type::Signed32OrMinusZero()
1335 if (left_upper.Is(left_constraint_type) &&
1336 right_upper.Is(Type::Signed32OrMinusZero()) &&
1337 (left_upper.Is(Type::Signed32()) || right_upper.Is(Type::Signed32()))) {
1338 VisitBinop(node, UseInfo::TruncatingWord32(),
1339 MachineRepresentation::kWord32, Type::Signed32());
1345 IdentifyZeros left_identify_zeros = truncation.identify_zeros();
1346 if (node->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd &&
1347 !right_feedback_type.Maybe(Type::MinusZero())) {
1348 left_identify_zeros = kIdentifyZeros;
1350 UseInfo left_use = CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
1351 left_identify_zeros);
1356 UseInfo right_use = CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
1358 VisitBinop(node, left_use, right_use, MachineRepresentation::kWord32,
1362 if (truncation.IsUsedAsWord32() ||
1363 !CanOverflowSigned32(node->op(), left_feedback_type,
1364 right_feedback_type, graph_zone())) {
1365 ChangeToPureOp(node, Int32Op(node));
1368 ChangeToInt32OverflowOp(node);
1374 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation,
1375 SimplifiedLowering* lowering) {
1376 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
1377 (GetUpperBound(node).Is(Type::Signed32()) ||
1378 GetUpperBound(node).Is(Type::Unsigned32()) ||
1379 truncation.IsUsedAsWord32())) {
1381 VisitWord32TruncatingBinop(node);
1382 if (lower()) ChangeToPureOp(node, Int32Op(node));
1388 UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
1390 MachineRepresentation::kFloat64, Type::Number());
1392 ChangeToPureOp(node, Float64Op(node));
1397 void VisitSpeculativeNumberModulus(Node* node, Truncation truncation,
1398 SimplifiedLowering* lowering) {
1399 if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN()) &&
1400 (truncation.IsUsedAsWord32() ||
1401 NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
1403 VisitWord32TruncatingBinop(node);
1404 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1407 if (BothInputsAre(node, Type::Signed32OrMinusZeroOrNaN()) &&
1408 (truncation.IsUsedAsWord32() ||
1409 NodeProperties::GetType(node).Is(Type::Signed32()))) {
1411 VisitWord32TruncatingBinop(node);
1412 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1417 NumberOperationHint hint = NumberOperationHintOf(node->op());
1421 if (BothInputsAreUnsigned32(node)) {
1422 if (hint == NumberOperationHint::kSignedSmall ||
1423 hint == NumberOperationHint::kSigned32) {
1424 VisitBinop(node, UseInfo::TruncatingWord32(),
1425 MachineRepresentation::kWord32, Type::Unsigned32());
1426 if (lower()) ChangeToUint32OverflowOp(node);
1433 if (BothInputsAre(node, Type::Signed32())) {
1435 if (hint == NumberOperationHint::kSignedSmall ||
1436 hint == NumberOperationHint::kSigned32) {
1437 VisitBinop(node, UseInfo::TruncatingWord32(),
1438 MachineRepresentation::kWord32, Type::Signed32());
1439 if (lower()) ChangeToInt32OverflowOp(node);
1444 if (hint == NumberOperationHint::kSignedSmall ||
1445 hint == NumberOperationHint::kSigned32) {
1451 UseInfo
const lhs_use = CheckedUseInfoAsWord32FromHint(
1452 hint, VectorSlotPair(), truncation.identify_zeros());
1453 UseInfo
const rhs_use = CheckedUseInfoAsWord32FromHint(
1454 hint, VectorSlotPair(), kIdentifyZeros);
1455 if (truncation.IsUsedAsWord32()) {
1456 VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32);
1457 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1458 }
else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
1459 VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
1460 Type::Unsigned32());
1461 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1463 VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kWord32,
1465 if (lower()) ChangeToInt32OverflowOp(node);
1470 if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
1471 TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
1472 (truncation.IsUsedAsWord32() ||
1473 NodeProperties::GetType(node).Is(Type::Unsigned32()))) {
1474 VisitBinop(node, UseInfo::TruncatingWord32(),
1475 MachineRepresentation::kWord32, Type::Number());
1476 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1479 if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
1480 TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
1481 (truncation.IsUsedAsWord32() ||
1482 NodeProperties::GetType(node).Is(Type::Signed32()))) {
1483 VisitBinop(node, UseInfo::TruncatingWord32(),
1484 MachineRepresentation::kWord32, Type::Number());
1485 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1494 UseInfo
const lhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
1495 truncation.identify_zeros(), VectorSlotPair());
1496 UseInfo
const rhs_use = UseInfo::CheckedNumberOrOddballAsFloat64(
1497 kIdentifyZeros, VectorSlotPair());
1498 VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kFloat64,
1500 if (lower()) ChangeToPureOp(node, Float64Op(node));
1504 void InsertUnreachableIfNecessary(Node* node) {
1508 if (node->op()->ValueOutputCount() > 0 &&
1509 node->op()->EffectOutputCount() > 0 &&
1510 node->opcode() != IrOpcode::kUnreachable && TypeOf(node).IsNone()) {
1511 Node* control = node->op()->ControlOutputCount() > 0
1513 : NodeProperties::GetControlInput(node, 0);
1516 graph()->NewNode(common()->Unreachable(), node, control);
1520 for (Edge edge : node->use_edges()) {
1521 if (NodeProperties::IsEffectEdge(edge) && edge.from() != unreachable) {
1522 edge.UpdateTo(unreachable);
1528 void VisitCheckBounds(Node* node, SimplifiedLowering* lowering) {
1529 CheckParameters
const& p = CheckParametersOf(node->op());
1530 Type const index_type = TypeOf(node->InputAt(0));
1531 Type const length_type = TypeOf(node->InputAt(1));
1532 if (length_type.Is(Type::Unsigned31())) {
1533 if (index_type.Is(Type::Integral32OrMinusZero())) {
1537 VisitBinop(node, UseInfo::TruncatingWord32(),
1538 MachineRepresentation::kWord32);
1540 if (lowering->poisoning_level_ ==
1541 PoisoningMitigationLevel::kDontPoison &&
1542 (index_type.IsNone() || length_type.IsNone() ||
1543 (index_type.Min() >= 0.0 &&
1544 index_type.Max() < length_type.Min()))) {
1547 DeferReplacement(node, node->InputAt(0));
1549 NodeProperties::ChangeOp(
1550 node, simplified()->CheckedUint32Bounds(p.feedback()));
1556 UseInfo::CheckedSigned32AsWord32(kIdentifyZeros, p.feedback()),
1557 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
1559 NodeProperties::ChangeOp(
1560 node, simplified()->CheckedUint32Bounds(p.feedback()));
1564 DCHECK(length_type.Is(type_cache_.kPositiveSafeInteger));
1566 UseInfo::CheckedSigned64AsWord64(kIdentifyZeros, p.feedback()),
1567 UseInfo::Word64(), MachineRepresentation::kWord64);
1569 NodeProperties::ChangeOp(
1570 node, simplified()->CheckedUint64Bounds(p.feedback()));
1577 void VisitNode(Node* node, Truncation truncation,
1578 SimplifiedLowering* lowering) {
1588 if (node->op()->ValueInputCount() > 0 &&
1589 node->op()->HasProperty(Operator::kPure) && truncation.IsUnused()) {
1590 return VisitUnused(node);
1593 if (lower()) InsertUnreachableIfNecessary(node);
1595 switch (node->opcode()) {
1599 case IrOpcode::kStart:
1603 return VisitLeaf(node, MachineRepresentation::kTagged);
1604 case IrOpcode::kParameter:
1606 return VisitUnop(node, UseInfo::None(), MachineRepresentation::kTagged);
1607 case IrOpcode::kInt32Constant:
1608 return VisitLeaf(node, MachineRepresentation::kWord32);
1609 case IrOpcode::kInt64Constant:
1610 return VisitLeaf(node, MachineRepresentation::kWord64);
1611 case IrOpcode::kExternalConstant:
1612 return VisitLeaf(node, MachineType::PointerRepresentation());
1613 case IrOpcode::kNumberConstant: {
1614 double const value = OpParameter<double>(node->op());
1616 if (DoubleToSmiInteger(value, &value_as_int)) {
1617 VisitLeaf(node, MachineRepresentation::kTaggedSigned);
1619 intptr_t smi = bit_cast<intptr_t>(Smi::FromInt(value_as_int));
1620 DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(smi));
1624 VisitLeaf(node, MachineRepresentation::kTagged);
1627 case IrOpcode::kHeapConstant:
1628 case IrOpcode::kDelayedStringConstant:
1629 return VisitLeaf(node, MachineRepresentation::kTaggedPointer);
1630 case IrOpcode::kPointerConstant: {
1631 VisitLeaf(node, MachineType::PointerRepresentation());
1633 intptr_t
const value = OpParameter<intptr_t>(node->op());
1634 DeferReplacement(node, lowering->jsgraph()->IntPtrConstant(value));
1639 case IrOpcode::kBranch: {
1640 DCHECK(TypeOf(node->InputAt(0)).Is(Type::Boolean()));
1641 ProcessInput(node, 0, UseInfo::Bool());
1642 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
1645 case IrOpcode::kSwitch:
1646 ProcessInput(node, 0, UseInfo::TruncatingWord32());
1647 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
1649 case IrOpcode::kSelect:
1650 return VisitSelect(node, truncation, lowering);
1651 case IrOpcode::kPhi:
1652 return VisitPhi(node, truncation, lowering);
1653 case IrOpcode::kCall:
1654 return VisitCall(node, lowering);
1659 case IrOpcode::kToBoolean: {
1660 if (truncation.IsUsedAsBool()) {
1661 ProcessInput(node, 0, UseInfo::Bool());
1662 SetOutput(node, MachineRepresentation::kBit);
1663 if (lower()) DeferReplacement(node, node->InputAt(0));
1666 SetOutput(node, MachineRepresentation::kTaggedPointer);
1670 case IrOpcode::kJSToNumber:
1671 case IrOpcode::kJSToNumberConvertBigInt:
1672 case IrOpcode::kJSToNumeric: {
1675 if (truncation.IsUsedAsWord32()) {
1676 SetOutput(node, MachineRepresentation::kWord32);
1678 lowering->DoJSToNumberOrNumericTruncatesToWord32(node,
this);
1679 }
else if (truncation.IsUsedAsFloat64()) {
1680 SetOutput(node, MachineRepresentation::kFloat64);
1682 lowering->DoJSToNumberOrNumericTruncatesToFloat64(node,
this);
1684 SetOutput(node, MachineRepresentation::kTagged);
1692 case IrOpcode::kBooleanNot: {
1694 NodeInfo* input_info = GetInfo(node->InputAt(0));
1695 if (input_info->representation() == MachineRepresentation::kBit) {
1697 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
1698 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
1699 }
else if (CanBeTaggedPointer(input_info->representation())) {
1701 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
1702 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
1704 DCHECK(TypeOf(node->InputAt(0)).IsNone());
1705 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
1709 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
1710 SetOutput(node, MachineRepresentation::kBit);
1714 case IrOpcode::kNumberEqual: {
1715 Type const lhs_type = TypeOf(node->InputAt(0));
1716 Type const rhs_type = TypeOf(node->InputAt(1));
1722 if ((lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
1723 rhs_type.Is(Type::Unsigned32OrMinusZero())) ||
1724 (lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
1725 rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
1726 OneInputCannotBe(node, type_cache_.kZeroish))) {
1728 VisitBinop(node, UseInfo::TruncatingWord32(),
1729 MachineRepresentation::kBit);
1730 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
1733 if ((lhs_type.Is(Type::Signed32OrMinusZero()) &&
1734 rhs_type.Is(Type::Signed32OrMinusZero())) ||
1735 (lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
1736 rhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
1737 OneInputCannotBe(node, type_cache_.kZeroish))) {
1739 VisitBinop(node, UseInfo::TruncatingWord32(),
1740 MachineRepresentation::kBit);
1741 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
1745 VisitBinop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
1746 MachineRepresentation::kBit);
1747 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1750 case IrOpcode::kNumberLessThan:
1751 case IrOpcode::kNumberLessThanOrEqual: {
1752 Type const lhs_type = TypeOf(node->InputAt(0));
1753 Type const rhs_type = TypeOf(node->InputAt(1));
1757 if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
1758 rhs_type.Is(Type::Unsigned32OrMinusZero())) {
1760 VisitBinop(node, UseInfo::TruncatingWord32(),
1761 MachineRepresentation::kBit);
1762 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
1763 }
else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
1764 rhs_type.Is(Type::Signed32OrMinusZero())) {
1766 VisitBinop(node, UseInfo::TruncatingWord32(),
1767 MachineRepresentation::kBit);
1768 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
1771 VisitBinop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
1772 MachineRepresentation::kBit);
1773 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1778 case IrOpcode::kSpeculativeSafeIntegerAdd:
1779 case IrOpcode::kSpeculativeSafeIntegerSubtract:
1780 return VisitSpeculativeIntegerAdditiveOp(node, truncation, lowering);
1782 case IrOpcode::kSpeculativeNumberAdd:
1783 case IrOpcode::kSpeculativeNumberSubtract:
1784 return VisitSpeculativeAdditiveOp(node, truncation, lowering);
1786 case IrOpcode::kSpeculativeNumberLessThan:
1787 case IrOpcode::kSpeculativeNumberLessThanOrEqual:
1788 case IrOpcode::kSpeculativeNumberEqual: {
1789 Type const lhs_type = TypeOf(node->InputAt(0));
1790 Type const rhs_type = TypeOf(node->InputAt(1));
1794 if (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
1795 rhs_type.Is(Type::Unsigned32OrMinusZero())) {
1797 VisitBinop(node, UseInfo::TruncatingWord32(),
1798 MachineRepresentation::kBit);
1799 if (lower()) ChangeToPureOp(node, Uint32Op(node));
1801 }
else if (lhs_type.Is(Type::Signed32OrMinusZero()) &&
1802 rhs_type.Is(Type::Signed32OrMinusZero())) {
1804 VisitBinop(node, UseInfo::TruncatingWord32(),
1805 MachineRepresentation::kBit);
1806 if (lower()) ChangeToPureOp(node, Int32Op(node));
1810 NumberOperationHint hint = NumberOperationHintOf(node->op());
1812 case NumberOperationHint::kSigned32:
1813 case NumberOperationHint::kSignedSmall:
1816 CheckedUseInfoAsWord32FromHint(hint, VectorSlotPair(),
1818 MachineRepresentation::kBit);
1819 }
else if (retype()) {
1820 SetOutput(node, MachineRepresentation::kBit, Type::Any());
1823 Node* lhs = node->InputAt(0);
1824 Node* rhs = node->InputAt(1);
1825 if (IsNodeRepresentationTagged(lhs) &&
1826 IsNodeRepresentationTagged(rhs)) {
1828 UseInfo::CheckedSignedSmallAsTaggedSigned(
1829 VectorSlotPair(), kIdentifyZeros),
1830 MachineRepresentation::kBit);
1832 node, changer_->TaggedSignedOperatorFor(node->opcode()));
1836 CheckedUseInfoAsWord32FromHint(
1837 hint, VectorSlotPair(), kIdentifyZeros),
1838 MachineRepresentation::kBit);
1839 ChangeToPureOp(node, Int32Op(node));
1843 case NumberOperationHint::kSignedSmallInputs:
1846 case NumberOperationHint::kNumberOrOddball:
1850 DCHECK_NE(IrOpcode::kSpeculativeNumberEqual, node->opcode());
1852 case NumberOperationHint::kNumber:
1854 CheckedUseInfoAsFloat64FromHint(hint, VectorSlotPair(),
1856 MachineRepresentation::kBit);
1857 if (lower()) ChangeToPureOp(node, Float64Op(node));
1864 case IrOpcode::kNumberAdd:
1865 case IrOpcode::kNumberSubtract: {
1866 if (TypeOf(node->InputAt(0))
1867 .Is(type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
1868 TypeOf(node->InputAt(1))
1869 .Is(type_cache_.kAdditiveSafeIntegerOrMinusZero) &&
1870 (TypeOf(node).Is(Type::Signed32()) ||
1871 TypeOf(node).Is(Type::Unsigned32()) ||
1872 truncation.IsUsedAsWord32())) {
1874 VisitWord32TruncatingBinop(node);
1875 if (lower()) ChangeToPureOp(node, Int32Op(node));
1876 }
else if (jsgraph_->machine()->Is64() &&
1877 BothInputsAre(node, type_cache_.kSafeInteger) &&
1878 GetUpperBound(node).Is(type_cache_.kSafeInteger)) {
1880 VisitInt64Binop(node);
1881 if (lower()) ChangeToPureOp(node, Int64Op(node));
1884 VisitFloat64Binop(node);
1885 if (lower()) ChangeToPureOp(node, Float64Op(node));
1889 case IrOpcode::kSpeculativeNumberMultiply: {
1890 if (BothInputsAre(node, Type::Integral32()) &&
1891 (NodeProperties::GetType(node).Is(Type::Signed32()) ||
1892 NodeProperties::GetType(node).Is(Type::Unsigned32()) ||
1893 (truncation.IsUsedAsWord32() &&
1894 NodeProperties::GetType(node).Is(
1895 type_cache_.kSafeIntegerOrMinusZero)))) {
1901 VisitWord32TruncatingBinop(node);
1902 if (lower()) ChangeToPureOp(node, Int32Op(node));
1906 NumberOperationHint hint = NumberOperationHintOf(node->op());
1907 Type input0_type = TypeOf(node->InputAt(0));
1908 Type input1_type = TypeOf(node->InputAt(1));
1912 if (BothInputsAre(node, Type::Signed32())) {
1914 if (hint == NumberOperationHint::kSignedSmall ||
1915 hint == NumberOperationHint::kSigned32) {
1916 VisitBinop(node, UseInfo::TruncatingWord32(),
1917 MachineRepresentation::kWord32, Type::Signed32());
1919 LowerToCheckedInt32Mul(node, truncation, input0_type,
1926 if (hint == NumberOperationHint::kSignedSmall ||
1927 hint == NumberOperationHint::kSigned32) {
1928 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
1929 MachineRepresentation::kWord32, Type::Signed32());
1931 LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
1938 UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
1940 MachineRepresentation::kFloat64, Type::Number());
1941 if (lower()) ChangeToPureOp(node, Float64Op(node));
1944 case IrOpcode::kNumberMultiply: {
1945 if (TypeOf(node->InputAt(0)).Is(Type::Integral32()) &&
1946 TypeOf(node->InputAt(1)).Is(Type::Integral32()) &&
1947 (TypeOf(node).Is(Type::Signed32()) ||
1948 TypeOf(node).Is(Type::Unsigned32()) ||
1949 (truncation.IsUsedAsWord32() &&
1950 TypeOf(node).Is(type_cache_.kSafeIntegerOrMinusZero)))) {
1956 VisitWord32TruncatingBinop(node);
1957 if (lower()) ChangeToPureOp(node, Int32Op(node));
1961 VisitFloat64Binop(node);
1962 if (lower()) ChangeToPureOp(node, Float64Op(node));
1965 case IrOpcode::kSpeculativeNumberDivide: {
1966 if (BothInputsAreUnsigned32(node) && truncation.IsUsedAsWord32()) {
1968 VisitWord32TruncatingBinop(node);
1969 if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
1972 if (BothInputsAreSigned32(node)) {
1973 if (NodeProperties::GetType(node).Is(Type::Signed32())) {
1975 VisitWord32TruncatingBinop(node);
1976 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
1979 if (truncation.IsUsedAsWord32()) {
1981 VisitWord32TruncatingBinop(node);
1982 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
1988 NumberOperationHint hint = NumberOperationHintOf(node->op());
1992 if (BothInputsAreUnsigned32(node)) {
1993 if (hint == NumberOperationHint::kSignedSmall ||
1994 hint == NumberOperationHint::kSigned32) {
1995 VisitBinop(node, UseInfo::TruncatingWord32(),
1996 MachineRepresentation::kWord32, Type::Unsigned32());
1997 if (lower()) ChangeToUint32OverflowOp(node);
2004 if (BothInputsAreSigned32(node)) {
2006 if (hint == NumberOperationHint::kSignedSmall ||
2007 hint == NumberOperationHint::kSigned32) {
2008 VisitBinop(node, UseInfo::TruncatingWord32(),
2009 MachineRepresentation::kWord32, Type::Signed32());
2010 if (lower()) ChangeToInt32OverflowOp(node);
2015 if (hint == NumberOperationHint::kSigned32 ||
2016 hint == NumberOperationHint::kSignedSmall ||
2017 hint == NumberOperationHint::kSignedSmallInputs) {
2019 if (truncation.IsUsedAsWord32()) {
2020 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
2021 MachineRepresentation::kWord32);
2022 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
2024 }
else if (hint != NumberOperationHint::kSignedSmallInputs) {
2025 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
2026 MachineRepresentation::kWord32, Type::Signed32());
2027 if (lower()) ChangeToInt32OverflowOp(node);
2034 UseInfo::CheckedNumberOrOddballAsFloat64(kDistinguishZeros,
2036 MachineRepresentation::kFloat64, Type::Number());
2037 if (lower()) ChangeToPureOp(node, Float64Op(node));
2040 case IrOpcode::kNumberDivide: {
2041 if (TypeOf(node->InputAt(0)).Is(Type::Unsigned32()) &&
2042 TypeOf(node->InputAt(1)).Is(Type::Unsigned32()) &&
2043 (truncation.IsUsedAsWord32() ||
2044 TypeOf(node).Is(Type::Unsigned32()))) {
2046 VisitWord32TruncatingBinop(node);
2047 if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
2050 if (TypeOf(node->InputAt(0)).Is(Type::Signed32()) &&
2051 TypeOf(node->InputAt(1)).Is(Type::Signed32()) &&
2052 (truncation.IsUsedAsWord32() ||
2053 TypeOf(node).Is(Type::Signed32()))) {
2055 VisitWord32TruncatingBinop(node);
2056 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
2060 VisitFloat64Binop(node);
2061 if (lower()) ChangeToPureOp(node, Float64Op(node));
2064 case IrOpcode::kSpeculativeNumberModulus:
2065 return VisitSpeculativeNumberModulus(node, truncation, lowering);
2066 case IrOpcode::kNumberModulus: {
2067 Type const lhs_type = TypeOf(node->InputAt(0));
2068 Type const rhs_type = TypeOf(node->InputAt(1));
2069 if ((lhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN()) &&
2070 rhs_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) &&
2071 (truncation.IsUsedAsWord32() ||
2072 TypeOf(node).Is(Type::Unsigned32()))) {
2074 VisitWord32TruncatingBinop(node);
2075 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
2078 if ((lhs_type.Is(Type::Signed32OrMinusZeroOrNaN()) &&
2079 rhs_type.Is(Type::Signed32OrMinusZeroOrNaN())) &&
2080 (truncation.IsUsedAsWord32() || TypeOf(node).Is(Type::Signed32()) ||
2081 (truncation.IdentifiesZeroAndMinusZero() &&
2082 TypeOf(node).Is(Type::Signed32OrMinusZero())))) {
2084 VisitWord32TruncatingBinop(node);
2085 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
2093 UseInfo
const lhs_use =
2094 UseInfo::TruncatingFloat64(truncation.identify_zeros());
2095 UseInfo
const rhs_use = UseInfo::TruncatingFloat64(kIdentifyZeros);
2096 VisitBinop(node, lhs_use, rhs_use, MachineRepresentation::kFloat64);
2097 if (lower()) ChangeToPureOp(node, Float64Op(node));
2100 case IrOpcode::kNumberBitwiseOr:
2101 case IrOpcode::kNumberBitwiseXor:
2102 case IrOpcode::kNumberBitwiseAnd: {
2103 VisitWord32TruncatingBinop(node);
2104 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
2107 case IrOpcode::kSpeculativeNumberBitwiseOr:
2108 case IrOpcode::kSpeculativeNumberBitwiseXor:
2109 case IrOpcode::kSpeculativeNumberBitwiseAnd:
2110 VisitSpeculativeInt32Binop(node);
2112 ChangeToPureOp(node, Int32Op(node));
2115 case IrOpcode::kNumberShiftLeft: {
2116 Type rhs_type = GetUpperBound(node->InputAt(1));
2117 VisitBinop(node, UseInfo::TruncatingWord32(),
2118 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
2120 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
2124 case IrOpcode::kSpeculativeNumberShiftLeft: {
2125 if (BothInputsAre(node, Type::NumberOrOddball())) {
2126 Type rhs_type = GetUpperBound(node->InputAt(1));
2127 VisitBinop(node, UseInfo::TruncatingWord32(),
2128 UseInfo::TruncatingWord32(),
2129 MachineRepresentation::kWord32);
2131 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
2135 NumberOperationHint hint = NumberOperationHintOf(node->op());
2136 Type rhs_type = GetUpperBound(node->InputAt(1));
2137 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
2138 MachineRepresentation::kWord32, Type::Signed32());
2140 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
2144 case IrOpcode::kNumberShiftRight: {
2145 Type rhs_type = GetUpperBound(node->InputAt(1));
2146 VisitBinop(node, UseInfo::TruncatingWord32(),
2147 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
2149 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
2153 case IrOpcode::kSpeculativeNumberShiftRight: {
2154 if (BothInputsAre(node, Type::NumberOrOddball())) {
2155 Type rhs_type = GetUpperBound(node->InputAt(1));
2156 VisitBinop(node, UseInfo::TruncatingWord32(),
2157 UseInfo::TruncatingWord32(),
2158 MachineRepresentation::kWord32);
2160 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
2164 NumberOperationHint hint = NumberOperationHintOf(node->op());
2165 Type rhs_type = GetUpperBound(node->InputAt(1));
2166 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
2167 MachineRepresentation::kWord32, Type::Signed32());
2169 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
2173 case IrOpcode::kNumberShiftRightLogical: {
2174 Type rhs_type = GetUpperBound(node->InputAt(1));
2175 VisitBinop(node, UseInfo::TruncatingWord32(),
2176 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
2178 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
2182 case IrOpcode::kSpeculativeNumberShiftRightLogical: {
2183 NumberOperationHint hint = NumberOperationHintOf(node->op());
2184 Type rhs_type = GetUpperBound(node->InputAt(1));
2185 if (rhs_type.Is(type_cache_.kZeroish) &&
2186 (hint == NumberOperationHint::kSignedSmall ||
2187 hint == NumberOperationHint::kSigned32) &&
2188 !truncation.IsUsedAsWord32()) {
2193 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
2194 MachineRepresentation::kWord32, Type::Unsigned31());
2196 node->RemoveInput(1);
2197 NodeProperties::ChangeOp(
2198 node, simplified()->CheckedUint32ToInt32(VectorSlotPair()));
2202 if (BothInputsAre(node, Type::NumberOrOddball())) {
2203 VisitBinop(node, UseInfo::TruncatingWord32(),
2204 UseInfo::TruncatingWord32(),
2205 MachineRepresentation::kWord32);
2207 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
2211 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
2212 MachineRepresentation::kWord32, Type::Unsigned32());
2214 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
2218 case IrOpcode::kNumberAbs: {
2222 Type const input_type = TypeOf(node->InputAt(0));
2223 if (input_type.Is(Type::Unsigned32OrMinusZero())) {
2224 VisitUnop(node, UseInfo::TruncatingWord32(),
2225 MachineRepresentation::kWord32);
2226 if (lower()) DeferReplacement(node, node->InputAt(0));
2227 }
else if (input_type.Is(Type::Signed32OrMinusZero())) {
2228 VisitUnop(node, UseInfo::TruncatingWord32(),
2229 MachineRepresentation::kWord32);
2230 if (lower()) DeferReplacement(node, lowering->Int32Abs(node));
2231 }
else if (input_type.Is(type_cache_.kPositiveIntegerOrNaN)) {
2232 VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2233 MachineRepresentation::kFloat64);
2234 if (lower()) DeferReplacement(node, node->InputAt(0));
2236 VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2237 MachineRepresentation::kFloat64);
2238 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
2242 case IrOpcode::kNumberClz32: {
2243 VisitUnop(node, UseInfo::TruncatingWord32(),
2244 MachineRepresentation::kWord32);
2245 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
2248 case IrOpcode::kNumberImul: {
2249 VisitBinop(node, UseInfo::TruncatingWord32(),
2250 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
2251 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
2254 case IrOpcode::kNumberFround: {
2255 VisitUnop(node, UseInfo::TruncatingFloat64(),
2256 MachineRepresentation::kFloat32);
2257 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
2260 case IrOpcode::kNumberMax: {
2267 Type const lhs_type = TypeOf(node->InputAt(0));
2268 Type const rhs_type = TypeOf(node->InputAt(1));
2269 if ((lhs_type.Is(Type::Unsigned32()) &&
2270 rhs_type.Is(Type::Unsigned32())) ||
2271 (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
2272 rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
2273 truncation.IdentifiesZeroAndMinusZero())) {
2274 VisitWord32TruncatingBinop(node);
2276 lowering->DoMax(node, lowering->machine()->Uint32LessThan(),
2277 MachineRepresentation::kWord32);
2279 }
else if ((lhs_type.Is(Type::Signed32()) &&
2280 rhs_type.Is(Type::Signed32())) ||
2281 (lhs_type.Is(Type::Signed32OrMinusZero()) &&
2282 rhs_type.Is(Type::Signed32OrMinusZero()) &&
2283 truncation.IdentifiesZeroAndMinusZero())) {
2284 VisitWord32TruncatingBinop(node);
2286 lowering->DoMax(node, lowering->machine()->Int32LessThan(),
2287 MachineRepresentation::kWord32);
2289 }
else if (jsgraph_->machine()->Is64() &&
2290 lhs_type.Is(type_cache_.kSafeInteger) &&
2291 rhs_type.Is(type_cache_.kSafeInteger)) {
2292 VisitInt64Binop(node);
2294 lowering->DoMax(node, lowering->machine()->Int64LessThan(),
2295 MachineRepresentation::kWord64);
2299 UseInfo::TruncatingFloat64(truncation.identify_zeros()),
2300 MachineRepresentation::kFloat64);
2305 if (lhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
2306 ? Type::OrderedNumber()
2307 :
Type::PlainNumber()) &&
2308 rhs_type.Is(
Type::OrderedNumber())) {
2309 lowering->DoMax(node, lowering->machine()->Float64LessThan(),
2310 MachineRepresentation::kFloat64);
2312 NodeProperties::ChangeOp(node, Float64Op(node));
2318 case IrOpcode::kNumberMin: {
2325 Type const lhs_type = TypeOf(node->InputAt(0));
2326 Type const rhs_type = TypeOf(node->InputAt(1));
2327 if ((lhs_type.Is(Type::Unsigned32()) &&
2328 rhs_type.Is(Type::Unsigned32())) ||
2329 (lhs_type.Is(Type::Unsigned32OrMinusZero()) &&
2330 rhs_type.Is(Type::Unsigned32OrMinusZero()) &&
2331 truncation.IdentifiesZeroAndMinusZero())) {
2332 VisitWord32TruncatingBinop(node);
2334 lowering->DoMin(node, lowering->machine()->Uint32LessThan(),
2335 MachineRepresentation::kWord32);
2337 }
else if ((lhs_type.Is(Type::Signed32()) &&
2338 rhs_type.Is(Type::Signed32())) ||
2339 (lhs_type.Is(Type::Signed32OrMinusZero()) &&
2340 rhs_type.Is(Type::Signed32OrMinusZero()) &&
2341 truncation.IdentifiesZeroAndMinusZero())) {
2342 VisitWord32TruncatingBinop(node);
2344 lowering->DoMin(node, lowering->machine()->Int32LessThan(),
2345 MachineRepresentation::kWord32);
2347 }
else if (jsgraph_->machine()->Is64() &&
2348 lhs_type.Is(type_cache_.kSafeInteger) &&
2349 rhs_type.Is(type_cache_.kSafeInteger)) {
2350 VisitInt64Binop(node);
2352 lowering->DoMin(node, lowering->machine()->Int64LessThan(),
2353 MachineRepresentation::kWord64);
2357 UseInfo::TruncatingFloat64(truncation.identify_zeros()),
2358 MachineRepresentation::kFloat64);
2363 if (lhs_type.Is(Type::OrderedNumber()) &&
2364 rhs_type.Is(truncation.IdentifiesZeroAndMinusZero()
2365 ? Type::OrderedNumber()
2366 :
Type::PlainNumber())) {
2367 lowering->DoMin(node,
2368 lowering->machine()->Float64LessThanOrEqual(),
2369 MachineRepresentation::kFloat64);
2371 NodeProperties::ChangeOp(node, Float64Op(node));
2377 case IrOpcode::kNumberAtan2:
2378 case IrOpcode::kNumberPow: {
2379 VisitBinop(node, UseInfo::TruncatingFloat64(),
2380 MachineRepresentation::kFloat64);
2381 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
2384 case IrOpcode::kNumberCeil:
2385 case IrOpcode::kNumberFloor:
2386 case IrOpcode::kNumberRound:
2387 case IrOpcode::kNumberTrunc: {
2392 Type const input_type = TypeOf(node->InputAt(0));
2393 VisitUnop(node, UseInfo::TruncatingFloat64(truncation.identify_zeros()),
2394 MachineRepresentation::kFloat64);
2396 if (input_type.Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
2397 DeferReplacement(node, node->InputAt(0));
2398 }
else if (node->opcode() == IrOpcode::kNumberRound) {
2399 DeferReplacement(node, lowering->Float64Round(node));
2401 NodeProperties::ChangeOp(node, Float64Op(node));
2406 case IrOpcode::kNumberAcos:
2407 case IrOpcode::kNumberAcosh:
2408 case IrOpcode::kNumberAsin:
2409 case IrOpcode::kNumberAsinh:
2410 case IrOpcode::kNumberAtan:
2411 case IrOpcode::kNumberAtanh:
2412 case IrOpcode::kNumberCos:
2413 case IrOpcode::kNumberCosh:
2414 case IrOpcode::kNumberExp:
2415 case IrOpcode::kNumberExpm1:
2416 case IrOpcode::kNumberLog:
2417 case IrOpcode::kNumberLog1p:
2418 case IrOpcode::kNumberLog2:
2419 case IrOpcode::kNumberLog10:
2420 case IrOpcode::kNumberCbrt:
2421 case IrOpcode::kNumberSin:
2422 case IrOpcode::kNumberSinh:
2423 case IrOpcode::kNumberTan:
2424 case IrOpcode::kNumberTanh: {
2425 VisitUnop(node, UseInfo::TruncatingFloat64(),
2426 MachineRepresentation::kFloat64);
2427 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
2430 case IrOpcode::kNumberSign: {
2431 if (InputIs(node, Type::Signed32())) {
2432 VisitUnop(node, UseInfo::TruncatingWord32(),
2433 MachineRepresentation::kWord32);
2434 if (lower()) DeferReplacement(node, lowering->Int32Sign(node));
2436 VisitUnop(node, UseInfo::TruncatingFloat64(),
2437 MachineRepresentation::kFloat64);
2438 if (lower()) DeferReplacement(node, lowering->Float64Sign(node));
2442 case IrOpcode::kNumberSilenceNaN: {
2443 Type const input_type = TypeOf(node->InputAt(0));
2444 if (input_type.Is(Type::OrderedNumber())) {
2446 VisitUnop(node, UseInfo::TruncatingFloat64(),
2447 MachineRepresentation::kFloat64);
2448 if (lower()) DeferReplacement(node, node->InputAt(0));
2450 VisitUnop(node, UseInfo::TruncatingFloat64(),
2451 MachineRepresentation::kFloat64);
2452 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
2456 case IrOpcode::kNumberSqrt: {
2457 VisitUnop(node, UseInfo::TruncatingFloat64(),
2458 MachineRepresentation::kFloat64);
2459 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
2462 case IrOpcode::kNumberToBoolean: {
2466 Type const input_type = TypeOf(node->InputAt(0));
2467 if (input_type.Is(Type::Integral32OrMinusZeroOrNaN())) {
2470 VisitUnop(node, UseInfo::TruncatingWord32(),
2471 MachineRepresentation::kBit);
2472 if (lower()) lowering->DoIntegral32ToBit(node);
2473 }
else if (input_type.Is(Type::OrderedNumber())) {
2474 VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2475 MachineRepresentation::kBit);
2476 if (lower()) lowering->DoOrderedNumberToBit(node);
2478 VisitUnop(node, UseInfo::TruncatingFloat64(kIdentifyZeros),
2479 MachineRepresentation::kBit);
2480 if (lower()) lowering->DoNumberToBit(node);
2484 case IrOpcode::kNumberToInt32: {
2486 VisitUnop(node, UseInfo::TruncatingWord32(),
2487 MachineRepresentation::kWord32);
2488 if (lower()) DeferReplacement(node, node->InputAt(0));
2491 case IrOpcode::kNumberToString: {
2492 VisitUnop(node, UseInfo::AnyTagged(),
2493 MachineRepresentation::kTaggedPointer);
2496 case IrOpcode::kNumberToUint32: {
2498 VisitUnop(node, UseInfo::TruncatingWord32(),
2499 MachineRepresentation::kWord32);
2500 if (lower()) DeferReplacement(node, node->InputAt(0));
2503 case IrOpcode::kNumberToUint8Clamped: {
2504 Type const input_type = TypeOf(node->InputAt(0));
2505 if (input_type.Is(type_cache_.kUint8OrMinusZeroOrNaN)) {
2506 VisitUnop(node, UseInfo::TruncatingWord32(),
2507 MachineRepresentation::kWord32);
2508 if (lower()) DeferReplacement(node, node->InputAt(0));
2509 }
else if (input_type.Is(Type::Unsigned32OrMinusZeroOrNaN())) {
2510 VisitUnop(node, UseInfo::TruncatingWord32(),
2511 MachineRepresentation::kWord32);
2512 if (lower()) lowering->DoUnsigned32ToUint8Clamped(node);
2513 }
else if (input_type.Is(Type::Signed32OrMinusZeroOrNaN())) {
2514 VisitUnop(node, UseInfo::TruncatingWord32(),
2515 MachineRepresentation::kWord32);
2516 if (lower()) lowering->DoSigned32ToUint8Clamped(node);
2517 }
else if (input_type.Is(type_cache_.kIntegerOrMinusZeroOrNaN)) {
2518 VisitUnop(node, UseInfo::TruncatingFloat64(),
2519 MachineRepresentation::kFloat64);
2520 if (lower()) lowering->DoIntegerToUint8Clamped(node);
2522 VisitUnop(node, UseInfo::TruncatingFloat64(),
2523 MachineRepresentation::kFloat64);
2524 if (lower()) lowering->DoNumberToUint8Clamped(node);
2528 case IrOpcode::kReferenceEqual: {
2529 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
2531 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
2535 case IrOpcode::kSameValue: {
2536 if (truncation.IsUnused())
return VisitUnused(node);
2537 VisitBinop(node, UseInfo::AnyTagged(),
2538 MachineRepresentation::kTaggedPointer);
2541 case IrOpcode::kTypeOf: {
2542 return VisitUnop(node, UseInfo::AnyTagged(),
2543 MachineRepresentation::kTaggedPointer);
2545 case IrOpcode::kNewConsString: {
2546 ProcessInput(node, 0, UseInfo::TruncatingWord32());
2547 ProcessInput(node, 1, UseInfo::AnyTagged());
2548 ProcessInput(node, 2, UseInfo::AnyTagged());
2549 SetOutput(node, MachineRepresentation::kTaggedPointer);
2552 case IrOpcode::kStringConcat: {
2558 ProcessInput(node, 0, UseInfo::TaggedSigned());
2559 ProcessInput(node, 1, UseInfo::AnyTagged());
2560 ProcessInput(node, 2, UseInfo::AnyTagged());
2561 SetOutput(node, MachineRepresentation::kTaggedPointer);
2564 case IrOpcode::kStringEqual:
2565 case IrOpcode::kStringLessThan:
2566 case IrOpcode::kStringLessThanOrEqual: {
2567 return VisitBinop(node, UseInfo::AnyTagged(),
2568 MachineRepresentation::kTaggedPointer);
2570 case IrOpcode::kStringCharCodeAt: {
2571 return VisitBinop(node, UseInfo::AnyTagged(), UseInfo::Word(),
2572 MachineRepresentation::kWord32);
2574 case IrOpcode::kStringCodePointAt: {
2575 return VisitBinop(node, UseInfo::AnyTagged(), UseInfo::Word(),
2576 MachineRepresentation::kTaggedSigned);
2578 case IrOpcode::kStringFromSingleCharCode: {
2579 VisitUnop(node, UseInfo::TruncatingWord32(),
2580 MachineRepresentation::kTaggedPointer);
2583 case IrOpcode::kStringFromSingleCodePoint: {
2584 VisitUnop(node, UseInfo::TruncatingWord32(),
2585 MachineRepresentation::kTaggedPointer);
2588 case IrOpcode::kStringIndexOf: {
2589 ProcessInput(node, 0, UseInfo::AnyTagged());
2590 ProcessInput(node, 1, UseInfo::AnyTagged());
2591 ProcessInput(node, 2, UseInfo::TaggedSigned());
2592 SetOutput(node, MachineRepresentation::kTaggedSigned);
2595 case IrOpcode::kStringLength: {
2599 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kWord32);
2602 case IrOpcode::kStringSubstring: {
2603 ProcessInput(node, 0, UseInfo::AnyTagged());
2604 ProcessInput(node, 1, UseInfo::TruncatingWord32());
2605 ProcessInput(node, 2, UseInfo::TruncatingWord32());
2606 ProcessRemainingInputs(node, 3);
2607 SetOutput(node, MachineRepresentation::kTaggedPointer);
2610 case IrOpcode::kStringToLowerCaseIntl:
2611 case IrOpcode::kStringToUpperCaseIntl: {
2612 VisitUnop(node, UseInfo::AnyTagged(),
2613 MachineRepresentation::kTaggedPointer);
2616 case IrOpcode::kCheckBounds:
2617 return VisitCheckBounds(node, lowering);
2618 case IrOpcode::kPoisonIndex: {
2619 VisitUnop(node, UseInfo::TruncatingWord32(),
2620 MachineRepresentation::kWord32);
2623 case IrOpcode::kCheckHeapObject: {
2624 if (InputCannotBe(node, Type::SignedSmall())) {
2625 VisitUnop(node, UseInfo::AnyTagged(),
2626 MachineRepresentation::kTaggedPointer);
2628 VisitUnop(node, UseInfo::CheckedHeapObjectAsTaggedPointer(),
2629 MachineRepresentation::kTaggedPointer);
2631 if (lower()) DeferReplacement(node, node->InputAt(0));
2634 case IrOpcode::kCheckIf: {
2635 ProcessInput(node, 0, UseInfo::Bool());
2636 ProcessRemainingInputs(node, 1);
2637 SetOutput(node, MachineRepresentation::kNone);
2640 case IrOpcode::kCheckInternalizedString: {
2641 VisitCheck(node, Type::InternalizedString(), lowering);
2644 case IrOpcode::kCheckNumber: {
2645 Type const input_type = TypeOf(node->InputAt(0));
2646 if (input_type.Is(Type::Number())) {
2647 VisitNoop(node, truncation);
2649 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
2653 case IrOpcode::kCheckReceiver: {
2654 VisitCheck(node, Type::Receiver(), lowering);
2657 case IrOpcode::kCheckReceiverOrNullOrUndefined: {
2658 VisitCheck(node, Type::ReceiverOrNullOrUndefined(), lowering);
2661 case IrOpcode::kCheckSmi: {
2662 const CheckParameters& params = CheckParametersOf(node->op());
2663 if (SmiValuesAre32Bits() && truncation.IsUsedAsWord32()) {
2665 UseInfo::CheckedSignedSmallAsWord32(kDistinguishZeros,
2667 MachineRepresentation::kWord32);
2671 UseInfo::CheckedSignedSmallAsTaggedSigned(params.feedback()),
2672 MachineRepresentation::kTaggedSigned);
2674 if (lower()) DeferReplacement(node, node->InputAt(0));
2677 case IrOpcode::kCheckString: {
2678 VisitCheck(node, Type::String(), lowering);
2681 case IrOpcode::kCheckSymbol: {
2682 VisitCheck(node, Type::Symbol(), lowering);
2686 case IrOpcode::kAllocate: {
2687 ProcessInput(node, 0, UseInfo::Word());
2688 ProcessRemainingInputs(node, 1);
2689 SetOutput(node, MachineRepresentation::kTaggedPointer);
2692 case IrOpcode::kLoadFieldByIndex: {
2693 if (truncation.IsUnused())
return VisitUnused(node);
2694 VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
2695 MachineRepresentation::kTagged);
2698 case IrOpcode::kLoadField: {
2699 if (truncation.IsUnused())
return VisitUnused(node);
2700 FieldAccess access = FieldAccessOf(node->op());
2701 MachineRepresentation
const representation =
2702 access.machine_type.representation();
2703 VisitUnop(node, UseInfoForBasePointer(access), representation);
2706 case IrOpcode::kStoreField: {
2707 FieldAccess access = FieldAccessOf(node->op());
2708 Node* value_node = node->InputAt(1);
2709 NodeInfo* input_info = GetInfo(value_node);
2710 MachineRepresentation field_representation =
2711 access.machine_type.representation();
2714 if (field_representation == MachineRepresentation::kTagged &&
2715 TypeOf(value_node).Is(Type::SignedSmall())) {
2716 field_representation = MachineRepresentation::kTaggedSigned;
2718 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
2719 access.base_is_tagged, field_representation, access.offset,
2720 access.type, input_info->representation(), value_node);
2722 ProcessInput(node, 0, UseInfoForBasePointer(access));
2723 ProcessInput(node, 1,
2724 TruncatingUseInfoFromRepresentation(field_representation));
2725 ProcessRemainingInputs(node, 2);
2726 SetOutput(node, MachineRepresentation::kNone);
2728 if (write_barrier_kind < access.write_barrier_kind) {
2729 access.write_barrier_kind = write_barrier_kind;
2730 NodeProperties::ChangeOp(
2731 node, jsgraph_->simplified()->StoreField(access));
2736 case IrOpcode::kLoadElement: {
2737 if (truncation.IsUnused())
return VisitUnused(node);
2738 ElementAccess access = ElementAccessOf(node->op());
2739 VisitBinop(node, UseInfoForBasePointer(access), UseInfo::Word(),
2740 access.machine_type.representation());
2743 case IrOpcode::kStoreElement: {
2744 ElementAccess access = ElementAccessOf(node->op());
2745 Node* value_node = node->InputAt(2);
2746 NodeInfo* input_info = GetInfo(value_node);
2747 MachineRepresentation element_representation =
2748 access.machine_type.representation();
2751 if (element_representation == MachineRepresentation::kTagged &&
2752 TypeOf(value_node).Is(Type::SignedSmall())) {
2753 element_representation = MachineRepresentation::kTaggedSigned;
2755 WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
2756 access.base_is_tagged, element_representation, access.type,
2757 input_info->representation(), value_node);
2758 ProcessInput(node, 0, UseInfoForBasePointer(access));
2759 ProcessInput(node, 1, UseInfo::Word());
2760 ProcessInput(node, 2,
2761 TruncatingUseInfoFromRepresentation(
2762 element_representation));
2763 ProcessRemainingInputs(node, 3);
2764 SetOutput(node, MachineRepresentation::kNone);
2766 if (write_barrier_kind < access.write_barrier_kind) {
2767 access.write_barrier_kind = write_barrier_kind;
2768 NodeProperties::ChangeOp(
2769 node, jsgraph_->simplified()->StoreElement(access));
2774 case IrOpcode::kNumberIsFloat64Hole: {
2775 VisitUnop(node, UseInfo::TruncatingFloat64(),
2776 MachineRepresentation::kBit);
2779 case IrOpcode::kTransitionAndStoreElement: {
2780 Type value_type = TypeOf(node->InputAt(2));
2782 ProcessInput(node, 0, UseInfo::AnyTagged());
2783 ProcessInput(node, 1, UseInfo::Word());
2785 if (value_type.Is(Type::SignedSmall())) {
2786 ProcessInput(node, 2, UseInfo::TruncatingWord32());
2788 NodeProperties::ChangeOp(node,
2789 simplified()->StoreSignedSmallElement());
2791 }
else if (value_type.Is(Type::Number())) {
2792 ProcessInput(node, 2, UseInfo::TruncatingFloat64());
2794 Handle<Map> double_map = DoubleMapParameterOf(node->op());
2795 NodeProperties::ChangeOp(
2797 simplified()->TransitionAndStoreNumberElement(double_map));
2799 }
else if (value_type.Is(Type::NonNumber())) {
2800 ProcessInput(node, 2, UseInfo::AnyTagged());
2802 Handle<Map> fast_map = FastMapParameterOf(node->op());
2803 NodeProperties::ChangeOp(
2804 node, simplified()->TransitionAndStoreNonNumberElement(
2805 fast_map, value_type));
2808 ProcessInput(node, 2, UseInfo::AnyTagged());
2811 ProcessRemainingInputs(node, 3);
2812 SetOutput(node, MachineRepresentation::kNone);
2815 case IrOpcode::kLoadTypedElement: {
2816 MachineRepresentation
const rep =
2817 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
2818 ProcessInput(node, 0, UseInfo::AnyTagged());
2819 ProcessInput(node, 1, UseInfo::AnyTagged());
2820 ProcessInput(node, 2, UseInfo::Word());
2821 ProcessInput(node, 3, UseInfo::Word());
2822 ProcessRemainingInputs(node, 4);
2823 SetOutput(node, rep);
2826 case IrOpcode::kLoadDataViewElement: {
2827 MachineRepresentation
const rep =
2828 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
2829 ProcessInput(node, 0, UseInfo::AnyTagged());
2830 ProcessInput(node, 1, UseInfo::Word());
2831 ProcessInput(node, 2, UseInfo::Word());
2832 ProcessInput(node, 3, UseInfo::Word());
2833 ProcessInput(node, 4, UseInfo::Bool());
2834 ProcessRemainingInputs(node, 5);
2835 SetOutput(node, rep);
2838 case IrOpcode::kStoreTypedElement: {
2839 MachineRepresentation
const rep =
2840 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
2841 ProcessInput(node, 0, UseInfo::AnyTagged());
2842 ProcessInput(node, 1, UseInfo::AnyTagged());
2843 ProcessInput(node, 2, UseInfo::Word());
2844 ProcessInput(node, 3, UseInfo::Word());
2845 ProcessInput(node, 4,
2846 TruncatingUseInfoFromRepresentation(rep));
2847 ProcessRemainingInputs(node, 5);
2848 SetOutput(node, MachineRepresentation::kNone);
2851 case IrOpcode::kStoreDataViewElement: {
2852 MachineRepresentation
const rep =
2853 MachineRepresentationFromArrayType(ExternalArrayTypeOf(node->op()));
2854 ProcessInput(node, 0, UseInfo::AnyTagged());
2855 ProcessInput(node, 1, UseInfo::Word());
2856 ProcessInput(node, 2, UseInfo::Word());
2857 ProcessInput(node, 3, UseInfo::Word());
2858 ProcessInput(node, 4,
2859 TruncatingUseInfoFromRepresentation(rep));
2860 ProcessInput(node, 5, UseInfo::Bool());
2861 ProcessRemainingInputs(node, 6);
2862 SetOutput(node, MachineRepresentation::kNone);
2865 case IrOpcode::kConvertReceiver: {
2866 Type input_type = TypeOf(node->InputAt(0));
2867 VisitBinop(node, UseInfo::AnyTagged(),
2868 MachineRepresentation::kTaggedPointer);
2871 if (input_type.Is(Type::Receiver())) {
2872 DeferReplacement(node, node->InputAt(0));
2873 }
else if (input_type.Is(Type::NullOrUndefined())) {
2874 DeferReplacement(node, node->InputAt(1));
2875 }
else if (!input_type.Maybe(Type::NullOrUndefined())) {
2876 NodeProperties::ChangeOp(
2877 node, lowering->simplified()->ConvertReceiver(
2878 ConvertReceiverMode::kNotNullOrUndefined));
2883 case IrOpcode::kPlainPrimitiveToNumber: {
2884 if (InputIs(node, Type::Boolean())) {
2885 VisitUnop(node, UseInfo::Bool(), MachineRepresentation::kWord32);
2886 if (lower()) DeferReplacement(node, node->InputAt(0));
2887 }
else if (InputIs(node, Type::String())) {
2888 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
2890 NodeProperties::ChangeOp(node, simplified()->StringToNumber());
2892 }
else if (truncation.IsUsedAsWord32()) {
2893 if (InputIs(node, Type::NumberOrOddball())) {
2894 VisitUnop(node, UseInfo::TruncatingWord32(),
2895 MachineRepresentation::kWord32);
2896 if (lower()) DeferReplacement(node, node->InputAt(0));
2898 VisitUnop(node, UseInfo::AnyTagged(),
2899 MachineRepresentation::kWord32);
2901 NodeProperties::ChangeOp(node,
2902 simplified()->PlainPrimitiveToWord32());
2905 }
else if (truncation.IsUsedAsFloat64()) {
2906 if (InputIs(node, Type::NumberOrOddball())) {
2907 VisitUnop(node, UseInfo::TruncatingFloat64(),
2908 MachineRepresentation::kFloat64);
2909 if (lower()) DeferReplacement(node, node->InputAt(0));
2911 VisitUnop(node, UseInfo::AnyTagged(),
2912 MachineRepresentation::kFloat64);
2914 NodeProperties::ChangeOp(node,
2915 simplified()->PlainPrimitiveToFloat64());
2919 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
2923 case IrOpcode::kSpeculativeToNumber: {
2924 NumberOperationParameters
const& p =
2925 NumberOperationParametersOf(node->op());
2927 case NumberOperationHint::kSigned32:
2928 case NumberOperationHint::kSignedSmall:
2929 case NumberOperationHint::kSignedSmallInputs:
2931 CheckedUseInfoAsWord32FromHint(p.hint(), p.feedback()),
2932 MachineRepresentation::kWord32, Type::Signed32());
2934 case NumberOperationHint::kNumber:
2935 case NumberOperationHint::kNumberOrOddball:
2937 CheckedUseInfoAsFloat64FromHint(p.hint(), p.feedback()),
2938 MachineRepresentation::kFloat64);
2941 if (lower()) DeferReplacement(node, node->InputAt(0));
2944 case IrOpcode::kObjectIsArrayBufferView: {
2946 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
2949 case IrOpcode::kObjectIsBigInt: {
2950 VisitObjectIs(node, Type::BigInt(), lowering);
2953 case IrOpcode::kObjectIsCallable: {
2954 VisitObjectIs(node, Type::Callable(), lowering);
2957 case IrOpcode::kObjectIsConstructor: {
2959 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
2962 case IrOpcode::kObjectIsDetectableCallable: {
2963 VisitObjectIs(node, Type::DetectableCallable(), lowering);
2966 case IrOpcode::kObjectIsFiniteNumber: {
2967 Type const input_type = GetUpperBound(node->InputAt(0));
2968 if (input_type.Is(type_cache_.kSafeInteger)) {
2969 VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
2971 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
2973 }
else if (!input_type.Maybe(Type::Number())) {
2974 VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
2976 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
2978 }
else if (input_type.Is(Type::Number())) {
2979 VisitUnop(node, UseInfo::TruncatingFloat64(),
2980 MachineRepresentation::kBit);
2982 NodeProperties::ChangeOp(node,
2983 lowering->simplified()->NumberIsFinite());
2986 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
2990 case IrOpcode::kNumberIsFinite: {
2991 VisitUnop(node, UseInfo::TruncatingFloat64(),
2992 MachineRepresentation::kBit);
2995 case IrOpcode::kObjectIsSafeInteger: {
2996 Type const input_type = GetUpperBound(node->InputAt(0));
2997 if (input_type.Is(type_cache_.kSafeInteger)) {
2998 VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
3000 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3002 }
else if (!input_type.Maybe(Type::Number())) {
3003 VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
3005 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3007 }
else if (input_type.Is(Type::Number())) {
3008 VisitUnop(node, UseInfo::TruncatingFloat64(),
3009 MachineRepresentation::kBit);
3011 NodeProperties::ChangeOp(
3012 node, lowering->simplified()->NumberIsSafeInteger());
3015 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3019 case IrOpcode::kNumberIsSafeInteger: {
3022 case IrOpcode::kObjectIsInteger: {
3023 Type const input_type = GetUpperBound(node->InputAt(0));
3024 if (input_type.Is(type_cache_.kSafeInteger)) {
3025 VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
3027 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3029 }
else if (!input_type.Maybe(Type::Number())) {
3030 VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
3032 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3034 }
else if (input_type.Is(Type::Number())) {
3035 VisitUnop(node, UseInfo::TruncatingFloat64(),
3036 MachineRepresentation::kBit);
3038 NodeProperties::ChangeOp(node,
3039 lowering->simplified()->NumberIsInteger());
3042 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3046 case IrOpcode::kNumberIsInteger: {
3047 VisitUnop(node, UseInfo::TruncatingFloat64(),
3048 MachineRepresentation::kBit);
3051 case IrOpcode::kObjectIsMinusZero: {
3052 Type const input_type = GetUpperBound(node->InputAt(0));
3053 if (input_type.Is(Type::MinusZero())) {
3054 VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
3056 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3058 }
else if (!input_type.Maybe(Type::MinusZero())) {
3059 VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
3061 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3063 }
else if (input_type.Is(Type::Number())) {
3064 VisitUnop(node, UseInfo::TruncatingFloat64(),
3065 MachineRepresentation::kBit);
3067 NodeProperties::ChangeOp(node, simplified()->NumberIsMinusZero());
3070 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3074 case IrOpcode::kObjectIsNaN: {
3075 Type const input_type = GetUpperBound(node->InputAt(0));
3076 if (input_type.Is(Type::NaN())) {
3077 VisitUnop(node, UseInfo::None(), MachineRepresentation::kBit);
3079 DeferReplacement(node, lowering->jsgraph()->Int32Constant(1));
3081 }
else if (!input_type.Maybe(Type::NaN())) {
3082 VisitUnop(node, UseInfo::Any(), MachineRepresentation::kBit);
3084 DeferReplacement(node, lowering->jsgraph()->Int32Constant(0));
3086 }
else if (input_type.Is(Type::Number())) {
3087 VisitUnop(node, UseInfo::TruncatingFloat64(),
3088 MachineRepresentation::kBit);
3090 NodeProperties::ChangeOp(node, simplified()->NumberIsNaN());
3093 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3097 case IrOpcode::kNumberIsNaN: {
3098 VisitUnop(node, UseInfo::TruncatingFloat64(),
3099 MachineRepresentation::kBit);
3102 case IrOpcode::kObjectIsNonCallable: {
3103 VisitObjectIs(node, Type::NonCallable(), lowering);
3106 case IrOpcode::kObjectIsNumber: {
3107 VisitObjectIs(node, Type::Number(), lowering);
3110 case IrOpcode::kObjectIsReceiver: {
3111 VisitObjectIs(node, Type::Receiver(), lowering);
3114 case IrOpcode::kObjectIsSmi: {
3116 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
3119 case IrOpcode::kObjectIsString: {
3120 VisitObjectIs(node, Type::String(), lowering);
3123 case IrOpcode::kObjectIsSymbol: {
3124 VisitObjectIs(node, Type::Symbol(), lowering);
3127 case IrOpcode::kObjectIsUndetectable: {
3128 VisitObjectIs(node, Type::Undetectable(), lowering);
3131 case IrOpcode::kArgumentsFrame: {
3132 SetOutput(node, MachineType::PointerRepresentation());
3135 case IrOpcode::kArgumentsLength: {
3136 VisitUnop(node, UseInfo::Word(), MachineRepresentation::kTaggedSigned);
3139 case IrOpcode::kNewDoubleElements:
3140 case IrOpcode::kNewSmiOrObjectElements: {
3141 VisitUnop(node, UseInfo::TruncatingWord32(),
3142 MachineRepresentation::kTaggedPointer);
3145 case IrOpcode::kNewArgumentsElements: {
3146 VisitBinop(node, UseInfo::Word(), UseInfo::TaggedSigned(),
3147 MachineRepresentation::kTaggedPointer);
3150 case IrOpcode::kCheckFloat64Hole: {
3151 Type const input_type = TypeOf(node->InputAt(0));
3152 CheckFloat64HoleMode mode =
3153 CheckFloat64HoleParametersOf(node->op()).mode();
3154 if (mode == CheckFloat64HoleMode::kAllowReturnHole) {
3158 if (truncation.IsUnused())
return VisitUnused(node);
3159 if (truncation.IsUsedAsFloat64()) {
3160 VisitUnop(node, UseInfo::TruncatingFloat64(),
3161 MachineRepresentation::kFloat64);
3162 if (lower()) DeferReplacement(node, node->InputAt(0));
3167 UseInfo(MachineRepresentation::kFloat64, Truncation::Any()),
3168 MachineRepresentation::kFloat64, Type::Number());
3169 if (lower() && input_type.Is(Type::Number())) {
3170 DeferReplacement(node, node->InputAt(0));
3174 case IrOpcode::kCheckNotTaggedHole: {
3175 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
3178 case IrOpcode::kConvertTaggedHoleToUndefined: {
3179 if (InputIs(node, Type::NumberOrOddball()) &&
3180 truncation.IsUsedAsWord32()) {
3182 VisitUnop(node, UseInfo::TruncatingWord32(),
3183 MachineRepresentation::kWord32);
3184 if (lower()) DeferReplacement(node, node->InputAt(0));
3185 }
else if (InputIs(node, Type::NumberOrOddball()) &&
3186 truncation.IsUsedAsFloat64()) {
3188 VisitUnop(node, UseInfo::TruncatingFloat64(),
3189 MachineRepresentation::kFloat64);
3190 if (lower()) DeferReplacement(node, node->InputAt(0));
3191 }
else if (InputIs(node, Type::NonInternal())) {
3192 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
3193 if (lower()) DeferReplacement(node, node->InputAt(0));
3197 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged);
3201 case IrOpcode::kCheckEqualsSymbol:
3202 case IrOpcode::kCheckEqualsInternalizedString:
3203 return VisitBinop(node, UseInfo::AnyTagged(),
3204 MachineRepresentation::kNone);
3205 case IrOpcode::kMapGuard:
3207 return VisitUnused(node);
3208 case IrOpcode::kCheckMaps:
3209 case IrOpcode::kTransitionElementsKind: {
3211 return SetOutput(node, MachineRepresentation::kNone);
3213 case IrOpcode::kCompareMaps:
3214 return VisitUnop(node, UseInfo::AnyTagged(),
3215 MachineRepresentation::kBit);
3216 case IrOpcode::kEnsureWritableFastElements:
3217 return VisitBinop(node, UseInfo::AnyTagged(),
3218 MachineRepresentation::kTaggedPointer);
3219 case IrOpcode::kMaybeGrowFastElements: {
3220 Type const index_type = TypeOf(node->InputAt(2));
3221 Type const length_type = TypeOf(node->InputAt(3));
3222 ProcessInput(node, 0, UseInfo::AnyTagged());
3223 ProcessInput(node, 1, UseInfo::AnyTagged());
3224 ProcessInput(node, 2, UseInfo::TruncatingWord32());
3225 ProcessInput(node, 3, UseInfo::TruncatingWord32());
3226 ProcessRemainingInputs(node, 4);
3227 SetOutput(node, MachineRepresentation::kTaggedPointer);
3234 if (index_type.IsNone() || length_type.IsNone() ||
3235 index_type.Max() < length_type.Min()) {
3236 DeferReplacement(node, node->InputAt(1));
3242 case IrOpcode::kDateNow:
3244 return SetOutput(node, MachineRepresentation::kTaggedPointer);
3245 case IrOpcode::kFrameState:
3246 return VisitFrameState(node);
3247 case IrOpcode::kStateValues:
3248 return VisitStateValues(node);
3249 case IrOpcode::kObjectState:
3250 return VisitObjectState(node);
3251 case IrOpcode::kObjectId:
3252 return SetOutput(node, MachineRepresentation::kTaggedPointer);
3253 case IrOpcode::kTypeGuard: {
3256 Type type = TypeOf(node);
3257 MachineRepresentation representation =
3258 GetOutputInfoForPhi(node, type, truncation);
3262 UseInfo use(representation, truncation);
3264 EnqueueInput(node, 0, use);
3265 }
else if (lower()) {
3266 ConvertInput(node, 0, use, type);
3268 ProcessRemainingInputs(node, 1);
3269 SetOutput(node, representation);
3273 case IrOpcode::kFinishRegion:
3276 return SetOutput(node, MachineRepresentation::kTaggedPointer);
3278 case IrOpcode::kReturn:
3281 return SetOutput(node, MachineRepresentation::kTagged);
3283 case IrOpcode::kFindOrderedHashMapEntry: {
3284 Type const key_type = TypeOf(node->InputAt(1));
3285 if (key_type.Is(Type::Signed32OrMinusZero())) {
3286 VisitBinop(node, UseInfo::AnyTagged(), UseInfo::TruncatingWord32(),
3287 MachineType::PointerRepresentation());
3289 NodeProperties::ChangeOp(
3291 lowering->simplified()->FindOrderedHashMapEntryForInt32Key());
3294 VisitBinop(node, UseInfo::AnyTagged(),
3295 MachineRepresentation::kTaggedSigned);
3302 case IrOpcode::kEnd:
3303 case IrOpcode::kIfSuccess:
3304 case IrOpcode::kIfException:
3305 case IrOpcode::kIfTrue:
3306 case IrOpcode::kIfFalse:
3307 case IrOpcode::kIfValue:
3308 case IrOpcode::kIfDefault:
3309 case IrOpcode::kDeoptimize:
3310 case IrOpcode::kEffectPhi:
3311 case IrOpcode::kTerminate:
3312 case IrOpcode::kCheckpoint:
3313 case IrOpcode::kLoop:
3314 case IrOpcode::kMerge:
3315 case IrOpcode::kThrow:
3316 case IrOpcode::kBeginRegion:
3317 case IrOpcode::kProjection:
3318 case IrOpcode::kOsrValue:
3319 case IrOpcode::kArgumentsElementsState:
3320 case IrOpcode::kArgumentsLengthState:
3321 case IrOpcode::kUnreachable:
3322 case IrOpcode::kRuntimeAbort:
3324 #define OPCODE_CASE(name) case IrOpcode::k##name: 3325 JS_SIMPLE_BINOP_LIST(OPCODE_CASE)
3326 JS_OBJECT_OP_LIST(OPCODE_CASE)
3327 JS_CONTEXT_OP_LIST(OPCODE_CASE)
3328 JS_OTHER_OP_LIST(OPCODE_CASE)
3330 case IrOpcode::kJSBitwiseNot:
3331 case IrOpcode::kJSDecrement:
3332 case IrOpcode::kJSIncrement:
3333 case IrOpcode::kJSNegate:
3334 case IrOpcode::kJSToLength:
3335 case IrOpcode::kJSToName:
3336 case IrOpcode::kJSToObject:
3337 case IrOpcode::kJSToString:
3338 case IrOpcode::kJSParseInt:
3341 return SetOutput(node, MachineRepresentation::kTagged);
3342 case IrOpcode::kDeadValue:
3343 ProcessInput(node, 0, UseInfo::Any());
3344 return SetOutput(node, MachineRepresentation::kNone);
3347 "Representation inference: unsupported opcode %i (%s), node #%i\n.",
3348 node->opcode(), node->op()->mnemonic(), node->id());
3354 void DeferReplacement(Node* node, Node* replacement) {
3355 TRACE(
"defer replacement #%d:%s with #%d:%s\n", node->id(),
3356 node->op()->mnemonic(), replacement->id(),
3357 replacement->op()->mnemonic());
3360 if (node->op()->EffectInputCount() > 0) {
3361 DCHECK_LT(0, node->op()->ControlInputCount());
3363 Node* control = NodeProperties::GetControlInput(node);
3364 Node* effect = NodeProperties::GetEffectInput(node);
3365 ReplaceEffectControlUses(node, effect, control);
3368 replacements_.push_back(node);
3369 replacements_.push_back(replacement);
3371 node->NullAllInputs();
3374 void Kill(Node* node) {
3375 TRACE(
"killing #%d:%s\n", node->id(), node->op()->mnemonic());
3377 if (node->op()->EffectInputCount() == 1) {
3378 DCHECK_LT(0, node->op()->ControlInputCount());
3380 Node* control = NodeProperties::GetControlInput(node);
3381 Node* effect = NodeProperties::GetEffectInput(node);
3382 ReplaceEffectControlUses(node, effect, control);
3384 DCHECK_EQ(0, node->op()->EffectInputCount());
3385 DCHECK_EQ(0, node->op()->ControlOutputCount());
3386 DCHECK_EQ(0, node->op()->EffectOutputCount());
3389 node->ReplaceUses(jsgraph_->Dead());
3391 node->NullAllInputs();
3394 void PrintOutputInfo(NodeInfo* info) {
3395 if (FLAG_trace_representation) {
3396 StdoutStream{} << info->representation();
3400 void PrintRepresentation(MachineRepresentation rep) {
3401 if (FLAG_trace_representation) {
3402 StdoutStream{} << rep;
3406 void PrintTruncation(Truncation truncation) {
3407 if (FLAG_trace_representation) {
3408 StdoutStream{} << truncation.description() << std::endl;
3412 void PrintUseInfo(UseInfo info) {
3413 if (FLAG_trace_representation) {
3414 StdoutStream{} << info.representation() <<
":" 3415 << info.truncation().description();
3422 size_t const count_;
3423 ZoneVector<NodeInfo> info_;
3425 ZoneVector<InputUseInfos> node_input_use_infos_;
3429 NodeVector replacements_;
3431 RepresentationChanger* changer_;
3432 ZoneQueue<Node*> queue_;
3438 ZoneStack<NodeState> typing_stack_;
3444 SourcePositionTable* source_positions_;
3445 NodeOriginTable* node_origins_;
3446 TypeCache
const& type_cache_;
3447 OperationTyper op_typer_;
3449 NodeInfo* GetInfo(Node* node) {
3450 DCHECK(node->id() < count_);
3451 return &info_[node->id()];
3453 Zone* zone() {
return zone_; }
3454 Zone* graph_zone() {
return jsgraph_->zone(); }
3457 SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, JSHeapBroker* broker,
3459 SourcePositionTable* source_positions,
3460 NodeOriginTable* node_origins,
3461 PoisoningMitigationLevel poisoning_level)
3462 : jsgraph_(jsgraph),
3465 type_cache_(TypeCache::Get()),
3466 source_positions_(source_positions),
3467 node_origins_(node_origins),
3468 poisoning_level_(poisoning_level) {}
3470 void SimplifiedLowering::LowerAllNodes() {
3471 RepresentationChanger changer(jsgraph(), jsgraph()->isolate());
3472 RepresentationSelector selector(jsgraph(), broker_, zone_, &changer,
3473 source_positions_, node_origins_);
3477 void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToFloat64(
3478 Node* node, RepresentationSelector* selector) {
3479 DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
3480 node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
3481 node->opcode() == IrOpcode::kJSToNumeric);
3482 Node* value = node->InputAt(0);
3483 Node* context = node->InputAt(1);
3484 Node* frame_state = node->InputAt(2);
3485 Node* effect = node->InputAt(3);
3486 Node* control = node->InputAt(4);
3488 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
3490 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3492 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3493 Node* etrue0 = effect;
3496 vtrue0 = graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
3497 vtrue0 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue0);
3500 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3501 Node* efalse0 = effect;
3504 Operator
const* op =
3505 node->opcode() == IrOpcode::kJSToNumber
3506 ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
3507 ? ToNumberConvertBigIntOperator()
3508 : ToNumberOperator())
3509 : ToNumericOperator();
3510 Node* code = node->opcode() == IrOpcode::kJSToNumber
3512 : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
3513 ? ToNumberConvertBigIntCode()
3515 vfalse0 = efalse0 = if_false0 = graph()->NewNode(
3516 op, code, value, context, frame_state, efalse0, if_false0);
3520 Node* on_exception =
nullptr;
3521 if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
3522 NodeProperties::ReplaceControlInput(on_exception, vfalse0);
3523 NodeProperties::ReplaceEffectInput(on_exception, efalse0);
3524 if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
3527 Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
3528 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
3530 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3531 Node* etrue1 = efalse0;
3535 graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
3536 vtrue1 = graph()->NewNode(machine()->ChangeInt32ToFloat64(), vtrue1);
3539 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3540 Node* efalse1 = efalse0;
3543 vfalse1 = efalse1 = graph()->NewNode(
3544 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
3545 efalse1, if_false1);
3548 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3550 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
3552 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3553 vtrue1, vfalse1, if_false0);
3556 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3557 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
3558 value = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
3559 vtrue0, vfalse0, control);
3562 for (Edge edge : node->use_edges()) {
3563 if (NodeProperties::IsControlEdge(edge)) {
3564 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
3565 edge.from()->ReplaceUses(control);
3566 edge.from()->Kill();
3568 DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
3569 edge.UpdateTo(control);
3571 }
else if (NodeProperties::IsEffectEdge(edge)) {
3572 edge.UpdateTo(effect);
3576 selector->DeferReplacement(node, value);
3579 void SimplifiedLowering::DoJSToNumberOrNumericTruncatesToWord32(
3580 Node* node, RepresentationSelector* selector) {
3581 DCHECK(node->opcode() == IrOpcode::kJSToNumber ||
3582 node->opcode() == IrOpcode::kJSToNumberConvertBigInt ||
3583 node->opcode() == IrOpcode::kJSToNumeric);
3584 Node* value = node->InputAt(0);
3585 Node* context = node->InputAt(1);
3586 Node* frame_state = node->InputAt(2);
3587 Node* effect = node->InputAt(3);
3588 Node* control = node->InputAt(4);
3590 Node* check0 = graph()->NewNode(simplified()->ObjectIsSmi(), value);
3592 graph()->NewNode(common()->Branch(BranchHint::kTrue), check0, control);
3594 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3595 Node* etrue0 = effect;
3597 graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), value);
3599 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3600 Node* efalse0 = effect;
3603 Operator
const* op =
3604 node->opcode() == IrOpcode::kJSToNumber
3605 ? (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
3606 ? ToNumberConvertBigIntOperator()
3607 : ToNumberOperator())
3608 : ToNumericOperator();
3609 Node* code = node->opcode() == IrOpcode::kJSToNumber
3611 : (node->opcode() == IrOpcode::kJSToNumberConvertBigInt
3612 ? ToNumberConvertBigIntCode()
3614 vfalse0 = efalse0 = if_false0 = graph()->NewNode(
3615 op, code, value, context, frame_state, efalse0, if_false0);
3619 Node* on_exception =
nullptr;
3620 if (NodeProperties::IsExceptionalCall(node, &on_exception)) {
3621 NodeProperties::ReplaceControlInput(on_exception, vfalse0);
3622 NodeProperties::ReplaceEffectInput(on_exception, efalse0);
3623 if_false0 = graph()->NewNode(common()->IfSuccess(), vfalse0);
3626 Node* check1 = graph()->NewNode(simplified()->ObjectIsSmi(), vfalse0);
3627 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
3629 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3630 Node* etrue1 = efalse0;
3632 graph()->NewNode(simplified()->ChangeTaggedSignedToInt32(), vfalse0);
3634 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3635 Node* efalse1 = efalse0;
3638 vfalse1 = efalse1 = graph()->NewNode(
3639 simplified()->LoadField(AccessBuilder::ForHeapNumberValue()), efalse0,
3640 efalse1, if_false1);
3641 vfalse1 = graph()->NewNode(machine()->TruncateFloat64ToWord32(), vfalse1);
3644 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
3646 graph()->NewNode(common()->EffectPhi(2), etrue1, efalse1, if_false0);
3647 vfalse0 = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
3648 vtrue1, vfalse1, if_false0);
3651 control = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
3652 effect = graph()->NewNode(common()->EffectPhi(2), etrue0, efalse0, control);
3653 value = graph()->NewNode(common()->Phi(MachineRepresentation::kWord32, 2),
3654 vtrue0, vfalse0, control);
3657 for (Edge edge : node->use_edges()) {
3658 if (NodeProperties::IsControlEdge(edge)) {
3659 if (edge.from()->opcode() == IrOpcode::kIfSuccess) {
3660 edge.from()->ReplaceUses(control);
3661 edge.from()->Kill();
3663 DCHECK_NE(IrOpcode::kIfException, edge.from()->opcode());
3664 edge.UpdateTo(control);
3666 }
else if (NodeProperties::IsEffectEdge(edge)) {
3667 edge.UpdateTo(effect);
3671 selector->DeferReplacement(node, value);
3674 Node* SimplifiedLowering::Float64Round(Node*
const node) {
3675 Node*
const one = jsgraph()->Float64Constant(1.0);
3676 Node*
const one_half = jsgraph()->Float64Constant(0.5);
3677 Node*
const input = node->InputAt(0);
3680 Node* result = graph()->NewNode(machine()->Float64RoundUp().placeholder(),
3682 return graph()->NewNode(
3683 common()->Select(MachineRepresentation::kFloat64),
3685 machine()->Float64LessThanOrEqual(),
3686 graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
3687 result, graph()->NewNode(machine()->Float64Sub(), result, one));
3690 Node* SimplifiedLowering::Float64Sign(Node*
const node) {
3691 Node*
const minus_one = jsgraph()->Float64Constant(-1.0);
3692 Node*
const zero = jsgraph()->Float64Constant(0.0);
3693 Node*
const one = jsgraph()->Float64Constant(1.0);
3695 Node*
const input = node->InputAt(0);
3697 return graph()->NewNode(
3698 common()->Select(MachineRepresentation::kFloat64),
3699 graph()->NewNode(machine()->Float64LessThan(), input, zero), minus_one,
3701 common()->Select(MachineRepresentation::kFloat64),
3702 graph()->NewNode(machine()->Float64LessThan(), zero, input), one,
3706 Node* SimplifiedLowering::Int32Abs(Node*
const node) {
3707 Node*
const input = node->InputAt(0);
3714 Node* sign = graph()->NewNode(machine()->Word32Sar(), input,
3715 jsgraph()->Int32Constant(31));
3716 return graph()->NewNode(machine()->Int32Sub(),
3717 graph()->NewNode(machine()->Word32Xor(), input, sign),
3721 Node* SimplifiedLowering::Int32Div(Node*
const node) {
3722 Int32BinopMatcher m(node);
3723 Node*
const zero = jsgraph()->Int32Constant(0);
3724 Node*
const minus_one = jsgraph()->Int32Constant(-1);
3725 Node*
const lhs = m.left().node();
3726 Node*
const rhs = m.right().node();
3728 if (m.right().Is(-1)) {
3729 return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
3730 }
else if (m.right().Is(0)) {
3732 }
else if (machine()->Int32DivIsSafe() || m.right().HasValue()) {
3733 return graph()->NewNode(machine()->Int32Div(), lhs, rhs, graph()->start());
3750 const Operator*
const merge_op = common()->Merge(2);
3751 const Operator*
const phi_op =
3752 common()->Phi(MachineRepresentation::kWord32, 2);
3754 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
3755 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
3758 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3759 Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
3761 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3764 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
3765 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
3767 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3768 Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
3770 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3773 Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
3774 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
3776 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3779 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3780 Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
3782 if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
3783 false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
3786 if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
3787 false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
3790 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
3791 return graph()->NewNode(phi_op, true0, false0, merge0);
3794 Node* SimplifiedLowering::Int32Mod(Node*
const node) {
3795 Int32BinopMatcher m(node);
3796 Node*
const zero = jsgraph()->Int32Constant(0);
3797 Node*
const minus_one = jsgraph()->Int32Constant(-1);
3798 Node*
const lhs = m.left().node();
3799 Node*
const rhs = m.right().node();
3801 if (m.right().Is(-1) || m.right().Is(0)) {
3803 }
else if (m.right().HasValue()) {
3804 return graph()->NewNode(machine()->Int32Mod(), lhs, rhs, graph()->start());
3827 const Operator*
const merge_op = common()->Merge(2);
3828 const Operator*
const phi_op =
3829 common()->Phi(MachineRepresentation::kWord32, 2);
3831 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
3832 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
3835 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3838 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
3840 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
3841 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
3843 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3844 Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
3846 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3849 Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
3850 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
3853 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
3854 Node* true2 = graph()->NewNode(
3855 machine()->Int32Sub(), zero,
3856 graph()->NewNode(machine()->Word32And(),
3857 graph()->NewNode(machine()->Int32Sub(), zero, lhs),
3860 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
3861 Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
3863 if_false1 = graph()->NewNode(merge_op, if_true2, if_false2);
3864 false1 = graph()->NewNode(phi_op, true2, false2, if_false1);
3867 if_true0 = graph()->NewNode(merge_op, if_true1, if_false1);
3868 true0 = graph()->NewNode(phi_op, true1, false1, if_true0);
3871 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3874 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
3875 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
3878 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3879 Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
3881 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3882 Node* false1 = zero;
3884 if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
3885 false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
3888 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
3889 return graph()->NewNode(phi_op, true0, false0, merge0);
3892 Node* SimplifiedLowering::Int32Sign(Node*
const node) {
3893 Node*
const minus_one = jsgraph()->Int32Constant(-1);
3894 Node*
const zero = jsgraph()->Int32Constant(0);
3895 Node*
const one = jsgraph()->Int32Constant(1);
3897 Node*
const input = node->InputAt(0);
3899 return graph()->NewNode(
3900 common()->Select(MachineRepresentation::kWord32),
3901 graph()->NewNode(machine()->Int32LessThan(), input, zero), minus_one,
3903 common()->Select(MachineRepresentation::kWord32),
3904 graph()->NewNode(machine()->Int32LessThan(), zero, input), one,
3908 Node* SimplifiedLowering::Uint32Div(Node*
const node) {
3909 Uint32BinopMatcher m(node);
3910 Node*
const zero = jsgraph()->Uint32Constant(0);
3911 Node*
const lhs = m.left().node();
3912 Node*
const rhs = m.right().node();
3914 if (m.right().Is(0)) {
3916 }
else if (machine()->Uint32DivIsSafe() || m.right().HasValue()) {
3917 return graph()->NewNode(machine()->Uint32Div(), lhs, rhs, graph()->start());
3920 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
3921 Diamond d(graph(), common(), check, BranchHint::kFalse);
3922 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
3923 return d.Phi(MachineRepresentation::kWord32, zero, div);
3926 Node* SimplifiedLowering::Uint32Mod(Node*
const node) {
3927 Uint32BinopMatcher m(node);
3928 Node*
const minus_one = jsgraph()->Int32Constant(-1);
3929 Node*
const zero = jsgraph()->Uint32Constant(0);
3930 Node*
const lhs = m.left().node();
3931 Node*
const rhs = m.right().node();
3933 if (m.right().Is(0)) {
3935 }
else if (m.right().HasValue()) {
3936 return graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, graph()->start());
3953 const Operator*
const merge_op = common()->Merge(2);
3954 const Operator*
const phi_op =
3955 common()->Phi(MachineRepresentation::kWord32, 2);
3957 Node* check0 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
3958 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kFalse), check0,
3961 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
3964 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
3967 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
3969 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
3970 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_false0);
3972 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
3973 Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
3975 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
3976 Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
3978 if_false0 = graph()->NewNode(merge_op, if_true1, if_false1);
3979 false0 = graph()->NewNode(phi_op, true1, false1, if_false0);
3982 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
3983 return graph()->NewNode(phi_op, true0, false0, merge0);
3986 void SimplifiedLowering::DoMax(Node* node, Operator
const* op,
3987 MachineRepresentation rep) {
3988 Node*
const lhs = node->InputAt(0);
3989 Node*
const rhs = node->InputAt(1);
3991 node->ReplaceInput(0, graph()->NewNode(op, lhs, rhs));
3992 DCHECK_EQ(rhs, node->InputAt(1));
3993 node->AppendInput(graph()->zone(), lhs);
3994 NodeProperties::ChangeOp(node, common()->Select(rep));
3997 void SimplifiedLowering::DoMin(Node* node, Operator
const* op,
3998 MachineRepresentation rep) {
3999 Node*
const lhs = node->InputAt(0);
4000 Node*
const rhs = node->InputAt(1);
4002 node->InsertInput(graph()->zone(), 0, graph()->NewNode(op, lhs, rhs));
4003 DCHECK_EQ(lhs, node->InputAt(1));
4004 DCHECK_EQ(rhs, node->InputAt(2));
4005 NodeProperties::ChangeOp(node, common()->Select(rep));
4008 void SimplifiedLowering::DoShift(Node* node, Operator
const* op,
4010 if (!rhs_type.Is(type_cache_.kZeroToThirtyOne)) {
4011 Node*
const rhs = NodeProperties::GetValueInput(node, 1);
4012 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
4013 jsgraph()->Int32Constant(0x1F)));
4015 ChangeToPureOp(node, op);
4018 void SimplifiedLowering::DoIntegral32ToBit(Node* node) {
4019 Node*
const input = node->InputAt(0);
4020 Node*
const zero = jsgraph()->Int32Constant(0);
4021 Operator
const*
const op = machine()->Word32Equal();
4023 node->ReplaceInput(0, graph()->NewNode(op, input, zero));
4024 node->AppendInput(graph()->zone(), zero);
4025 NodeProperties::ChangeOp(node, op);
4028 void SimplifiedLowering::DoOrderedNumberToBit(Node* node) {
4029 Node*
const input = node->InputAt(0);
4031 node->ReplaceInput(0, graph()->NewNode(machine()->Float64Equal(), input,
4032 jsgraph()->Float64Constant(0.0)));
4033 node->AppendInput(graph()->zone(), jsgraph()->Int32Constant(0));
4034 NodeProperties::ChangeOp(node, machine()->Word32Equal());
4037 void SimplifiedLowering::DoNumberToBit(Node* node) {
4038 Node*
const input = node->InputAt(0);
4040 node->ReplaceInput(0, jsgraph()->Float64Constant(0.0));
4041 node->AppendInput(graph()->zone(),
4042 graph()->NewNode(machine()->Float64Abs(), input));
4043 NodeProperties::ChangeOp(node, machine()->Float64LessThan());
4046 void SimplifiedLowering::DoIntegerToUint8Clamped(Node* node) {
4047 Node*
const input = node->InputAt(0);
4048 Node*
const min = jsgraph()->Float64Constant(0.0);
4049 Node*
const max = jsgraph()->Float64Constant(255.0);
4052 0, graph()->NewNode(machine()->Float64LessThan(), min, input));
4056 common()->Select(MachineRepresentation::kFloat64),
4057 graph()->NewNode(machine()->Float64LessThan(), input, max), input,
4059 node->AppendInput(graph()->zone(), min);
4060 NodeProperties::ChangeOp(node,
4061 common()->Select(MachineRepresentation::kFloat64));
4064 void SimplifiedLowering::DoNumberToUint8Clamped(Node* node) {
4065 Node*
const input = node->InputAt(0);
4066 Node*
const min = jsgraph()->Float64Constant(0.0);
4067 Node*
const max = jsgraph()->Float64Constant(255.0);
4070 0, graph()->NewNode(
4071 common()->Select(MachineRepresentation::kFloat64),
4072 graph()->NewNode(machine()->Float64LessThan(), min, input),
4074 common()->Select(MachineRepresentation::kFloat64),
4075 graph()->NewNode(machine()->Float64LessThan(), input, max),
4078 NodeProperties::ChangeOp(node,
4079 machine()->Float64RoundTiesEven().placeholder());
4082 void SimplifiedLowering::DoSigned32ToUint8Clamped(Node* node) {
4083 Node*
const input = node->InputAt(0);
4084 Node*
const min = jsgraph()->Int32Constant(0);
4085 Node*
const max = jsgraph()->Int32Constant(255);
4088 0, graph()->NewNode(machine()->Int32LessThanOrEqual(), input, max));
4091 graph()->NewNode(common()->Select(MachineRepresentation::kWord32),
4092 graph()->NewNode(machine()->Int32LessThan(), input, min),
4094 node->AppendInput(graph()->zone(), max);
4095 NodeProperties::ChangeOp(node,
4096 common()->Select(MachineRepresentation::kWord32));
4099 void SimplifiedLowering::DoUnsigned32ToUint8Clamped(Node* node) {
4100 Node*
const input = node->InputAt(0);
4101 Node*
const max = jsgraph()->Uint32Constant(255u);
4104 0, graph()->NewNode(machine()->Uint32LessThanOrEqual(), input, max));
4105 node->AppendInput(graph()->zone(), input);
4106 node->AppendInput(graph()->zone(), max);
4107 NodeProperties::ChangeOp(node,
4108 common()->Select(MachineRepresentation::kWord32));
4111 Node* SimplifiedLowering::ToNumberCode() {
4112 if (!to_number_code_.is_set()) {
4113 Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
4114 to_number_code_.set(jsgraph()->HeapConstant(callable.code()));
4116 return to_number_code_.get();
4119 Node* SimplifiedLowering::ToNumberConvertBigIntCode() {
4120 if (!to_number_convert_big_int_code_.is_set()) {
4122 Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
4123 to_number_convert_big_int_code_.set(
4124 jsgraph()->HeapConstant(callable.code()));
4126 return to_number_convert_big_int_code_.get();
4129 Node* SimplifiedLowering::ToNumericCode() {
4130 if (!to_numeric_code_.is_set()) {
4131 Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
4132 to_numeric_code_.set(jsgraph()->HeapConstant(callable.code()));
4134 return to_numeric_code_.get();
4137 Operator
const* SimplifiedLowering::ToNumberOperator() {
4138 if (!to_number_operator_.is_set()) {
4139 Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumber);
4140 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
4141 auto call_descriptor = Linkage::GetStubCallDescriptor(
4142 graph()->zone(), callable.descriptor(),
4143 callable.descriptor().GetStackParameterCount(), flags,
4144 Operator::kNoProperties);
4145 to_number_operator_.set(common()->Call(call_descriptor));
4147 return to_number_operator_.get();
4150 Operator
const* SimplifiedLowering::ToNumberConvertBigIntOperator() {
4151 if (!to_number_convert_big_int_operator_.is_set()) {
4153 Builtins::CallableFor(isolate(), Builtins::kToNumberConvertBigInt);
4154 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
4155 auto call_descriptor = Linkage::GetStubCallDescriptor(
4156 graph()->zone(), callable.descriptor(),
4157 callable.descriptor().GetStackParameterCount(), flags,
4158 Operator::kNoProperties);
4159 to_number_convert_big_int_operator_.set(common()->Call(call_descriptor));
4161 return to_number_convert_big_int_operator_.get();
4164 Operator
const* SimplifiedLowering::ToNumericOperator() {
4165 if (!to_numeric_operator_.is_set()) {
4166 Callable callable = Builtins::CallableFor(isolate(), Builtins::kToNumeric);
4167 CallDescriptor::Flags flags = CallDescriptor::kNeedsFrameState;
4168 auto call_descriptor = Linkage::GetStubCallDescriptor(
4169 graph()->zone(), callable.descriptor(),
4170 callable.descriptor().GetStackParameterCount(), flags,
4171 Operator::kNoProperties);
4172 to_numeric_operator_.set(common()->Call(call_descriptor));
4174 return to_numeric_operator_.get();