Lines Matching refs:node
14 #include "src/compiler/node-matchers.h"
15 #include "src/compiler/node-properties.h"
43 // During this phase, the usage information for a node determines the best
62 // The {UseInfo} class is used to describe a use of an input of a node.
66 // 1. During propagation, the use info is used to inform the input node
214 void SetAndCheckInput(Node* node, int index, UseInfo use_info) {
216 input_use_infos_.resize(node->InputCount(), UseInfo::None());
240 // Information for each node tracked during the fixpoint.
308 // Adds new use to the node. Returns true if something has changed
309 // and the node has to be requeued.
360 Node* node = queue_.front();
361 NodeInfo* info = GetInfo(node);
364 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
365 VisitNode(node, info->truncation(), nullptr);
376 Node* node = *i;
377 NodeInfo* info = GetInfo(node);
378 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic());
381 source_positions_, source_positions_->GetSourcePosition(node));
382 VisitNode(node, info->truncation(), lowering);
388 Node* node = *i;
389 Node* replacement = *(++i);
390 node->ReplaceUses(replacement);
391 // We also need to replace the node in the rest of the vector.
394 if (*j == node) *j = replacement;
399 void EnqueueInitial(Node* node) {
400 NodeInfo* info = GetInfo(node);
403 nodes_.push_back(node);
404 queue_.push(node);
408 // for that input node. Add the input to {nodes_} if this is the first time
410 void EnqueueInput(Node* use_node, int index,
412 Node* node = use_node->InputAt(index);
414 NodeInfo* info = GetInfo(node);
421 // First visit of this node.
424 nodes_.push_back(node);
425 queue_.push(node);
434 // New usage information for the node is available.
436 queue_.push(node);
448 void EnqueueUses(Node* node) {
449 for (Edge edge : node->use_edges()) {
451 Node* const user = edge.from();
453 // New type information for the node is available.
455 // Enqueue the node only if we are sure it is reachable from
466 void SetOutputFromMachineType(Node* node, MachineType machine_type) {
496 return SetOutput(node, NodeOutputInfo(machine_type.representation(), type));
499 void SetOutput(Node* node, NodeOutputInfo output_info) {
500 // Every node should have at most one output representation. Note that
504 if (NodeProperties::IsTyped(node)) {
505 output_type = Type::Intersect(NodeProperties::GetType(node),
508 NodeInfo* info = GetInfo(node);
514 EnqueueUses(node);
520 bool BothInputsAreSigned32(Node* node) {
521 DCHECK_EQ(2, node->InputCount());
522 return GetInfo(node->InputAt(0))->output_type()->Is(Type::Signed32()) &&
523 GetInfo(node->InputAt(1))->output_type()->Is(Type::Signed32());
526 bool BothInputsAreUnsigned32(Node* node) {
527 DCHECK_EQ(2, node->InputCount());
528 return GetInfo(node->InputAt(0))->output_type()->Is(Type::Unsigned32()) &&
529 GetInfo(node->InputAt(1))->output_type()->Is(Type::Unsigned32());
532 bool BothInputsAre(Node* node, Type* type) {
533 DCHECK_EQ(2, node->InputCount());
534 return GetInfo(node->InputAt(0))->output_type()->Is(type) &&
535 GetInfo(node->InputAt(1))->output_type()->Is(type);
538 void ConvertInput(Node* node, int index, UseInfo use) {
539 Node* input = node->InputAt(index);
547 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(),
554 Node* n = changer_->GetRepresentationFor(
557 node->ReplaceInput(index, n);
561 void ProcessInput(Node* node, int index, UseInfo use) {
563 EnqueueInput(node, index, use);
565 ConvertInput(node, index, use);
569 void ProcessRemainingInputs(Node* node, int index) {
570 DCHECK_GE(index, NodeProperties::PastValueIndex(node));
571 DCHECK_GE(index, NodeProperties::PastContextIndex(node));
572 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node));
573 i < NodeProperties::PastEffectIndex(node); ++i) {
574 EnqueueInput(node, i); // Effect inputs: just visit
576 for (int i = std::max(index, NodeProperties::FirstControlIndex(node));
577 i < NodeProperties::PastControlIndex(node); ++i) {
578 EnqueueInput(node, i); // Control inputs: just visit
582 // The default, most general visitation case. For {node}, process all value,
586 void VisitInputs(Node* node) {
587 int tagged_count = node->op()->ValueInputCount() +
588 OperatorProperties::GetContextInputCount(node->op());
591 ProcessInput(node, i, UseInfo::AnyTagged());
594 for (int i = tagged_count; i < node->InputCount(); i++) {
595 EnqueueInput(node, i);
600 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use,
602 DCHECK_EQ(2, node->op()->ValueInputCount());
603 ProcessInput(node, 0, left_use);
604 ProcessInput(node, 1, right_use);
605 for (int i = 2; i < node->InputCount(); i++) {
606 EnqueueInput(node, i);
608 SetOutput(node, output);
612 void VisitBinop(Node* node, UseInfo input_use, NodeOutputInfo output) {
613 VisitBinop(node, input_use, input_use, output);
617 void VisitUnop(Node* node, UseInfo input_use, NodeOutputInfo output) {
618 DCHECK_EQ(1, node->InputCount());
619 ProcessInput(node, 0, input_use);
620 SetOutput(node, output);
624 void VisitLeaf(Node* node, NodeOutputInfo output) {
625 DCHECK_EQ(0, node->InputCount());
626 SetOutput(node, output);
630 void VisitFloat64Binop(Node* node) {
631 VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Float64());
633 void VisitInt32Binop(Node* node) {
634 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32());
636 void VisitWord32TruncatingBinop(Node* node) {
637 VisitBinop(node, UseInfo::TruncatingWord32(),
640 void VisitUint32Binop(Node* node) {
641 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32());
643 void VisitInt64Binop(Node* node) {
644 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Int64());
646 void VisitUint64Binop(Node* node) {
647 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Uint64());
649 void VisitFloat64Cmp(Node* node) {
650 VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Bool());
652 void VisitInt32Cmp(Node* node) {
653 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool());
655 void VisitUint32Cmp(Node* node) {
656 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool());
658 void VisitInt64Cmp(Node* node) {
659 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool());
661 void VisitUint64Cmp(Node* node) {
662 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool());
666 NodeOutputInfo GetOutputInfoForPhi(Node* node, Truncation use) {
668 Type* type = GetInfo(node->InputAt(0))->output_type();
669 for (int i = 1; i < node->op()->ValueInputCount(); ++i) {
670 type = Type::Union(type, GetInfo(node->InputAt(i))->output_type(),
692 bool is_word64 = GetInfo(node->InputAt(0))->representation() ==
696 for (int i = 1; i < node->op()->ValueInputCount(); i++) {
697 DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() ==
708 void VisitSelect(Node* node, Truncation truncation,
710 ProcessInput(node, 0, UseInfo::Bool());
712 NodeOutputInfo output = GetOutputInfoForPhi(node, truncation);
713 SetOutput(node, output);
717 SelectParameters p = SelectParametersOf(node->op());
719 NodeProperties::ChangeOp(node, lowering->common()->Select(
726 ProcessInput(node, 1, input_use);
727 ProcessInput(node, 2, input_use);
731 void VisitPhi(Node* node, Truncation truncation,
733 NodeOutputInfo output = GetOutputInfoForPhi(node, truncation);
734 SetOutput(node, output);
736 int values = node->op()->ValueInputCount();
739 if (output.representation() != PhiRepresentationOf(node->op())) {
741 node, lowering->common()->Phi(output.representation(), values));
748 for (int i = 0; i < node->InputCount(); i++) {
749 ProcessInput(node, i, i < values ? input_use : UseInfo::None());
753 void VisitCall(Node* node, SimplifiedLowering* lowering) {
754 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op());
758 for (int i = 0; i < node->InputCount(); i++) {
761 ProcessInput(node, i, UseInfo::None());
763 ProcessInput(node, i, TruncatingUseInfoFromRepresentation(
766 ProcessInput(node, i, UseInfo::None());
771 SetOutputFromMachineType(node, desc->GetMachineSignature()->GetReturn());
773 SetOutput(node, NodeOutputInfo::AnyTagged());
789 void VisitStateValues(Node* node) {
791 for (int i = 0; i < node->InputCount(); i++) {
792 EnqueueInput(node, i, UseInfo::Any());
798 ZoneVector<MachineType>(node->InputCount(), zone);
799 for (int i = 0; i < node->InputCount(); i++) {
800 NodeInfo* input_info = GetInfo(node->InputAt(i));
810 NodeProperties::ChangeOp(node,
813 SetOutput(node, NodeOutputInfo::AnyTagged());
816 const Operator* Int32Op(Node* node) {
817 return changer_->Int32OperatorFor(node->opcode());
820 const Operator* Uint32Op(Node* node) {
821 return changer_->Uint32OperatorFor(node->opcode());
824 const Operator* Float64Op(Node* node) {
825 return changer_->Float64OperatorFor(node->opcode());
828 // Dispatching routine for visiting the node {node} with the usage {use}.
830 void VisitNode(Node* node, Truncation truncation,
832 switch (node->opcode()) {
838 return VisitLeaf(node, NodeOutputInfo::None());
841 Type* type = NodeProperties::GetType(node);
842 ProcessInput(node, 0, UseInfo::None());
843 SetOutput(node, NodeOutputInfo(MachineRepresentation::kTagged, type));
847 return VisitLeaf(node, NodeOutputInfo::Int32());
849 return VisitLeaf(node, NodeOutputInfo::Int64());
851 return VisitLeaf(node, NodeOutputInfo::Float32());
853 return VisitLeaf(node, NodeOutputInfo::Float64());
855 return VisitLeaf(node, NodeOutputInfo::Pointer());
857 return VisitLeaf(node, NodeOutputInfo::NumberTagged());
859 return VisitLeaf(node, NodeOutputInfo::AnyTagged());
862 ProcessInput(node, 0, UseInfo::Bool());
863 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
866 ProcessInput(node, 0, UseInfo::TruncatingWord32());
867 EnqueueInput(node, NodeProperties::FirstControlIndex(node));
870 return VisitSelect(node, truncation, lowering);
872 return VisitPhi(node, truncation, lowering);
874 return VisitCall(node, lowering);
887 VisitInputs(node);
888 return SetOutput(node
895 NodeInfo* input_info = GetInfo(node->InputAt(0));
898 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0));
899 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal());
902 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant());
903 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
907 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
908 SetOutput(node, NodeOutputInfo::Bool());
914 NodeInfo* input_info = GetInfo(node->InputAt(0));
917 DeferReplacement(node, node->InputAt(0));
920 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
921 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
925 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool());
926 SetOutput(node, NodeOutputInfo::Int32());
934 if (BothInputsAreSigned32(node)) {
936 VisitInt32Cmp(node);
937 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
938 } else if (BothInputsAreUnsigned32(node)) {
940 VisitUint32Cmp(node);
941 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node));
944 VisitFloat64Cmp(node);
945 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
951 if (BothInputsAre(node, Type::Signed32()) &&
952 NodeProperties::GetType(node)->Is(Type::Signed32())) {
955 VisitInt32Binop(node);
956 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
957 } else if (BothInputsAre(node, type_cache_.kAdditiveSafeInteger) &&
961 VisitWord32TruncatingBinop(node);
962 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
965 VisitFloat64Binop(node);
966 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
971 if (BothInputsAreSigned32(node)) {
972 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
975 VisitInt32Binop(node);
976 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
980 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger)) {
984 VisitWord32TruncatingBinop(node);
985 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
990 VisitFloat64Binop(node);
991 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
995 if (BothInputsAreSigned32(node)) {
996 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
998 VisitInt32Binop(node);
999 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
1004 VisitWord32TruncatingBinop(node);
1005 if (lower()) DeferReplacement(node, lowering->Int32Div(node));
1009 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
1011 VisitWord32TruncatingBinop(node);
1012 if (lower()) DeferReplacement(node, lowering->Uint32Div(node));
1016 VisitFloat64Binop(node);
1017 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1021 if (BothInputsAreSigned32(node)) {
1022 if (NodeProperties::GetType(node)->Is(Type::Signed32())) {
1024 VisitInt32Binop(node);
1025 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1030 VisitWord32TruncatingBinop(node);
1031 if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
1035 if (BothInputsAreUnsigned32(node) && truncation.TruncatesToWord32()) {
1037 VisitWord32TruncatingBinop(node);
1038 if (lower()) DeferReplacement(node, lowering->Uint32Mod(node));
1042 VisitFloat64Binop(node);
1043 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node));
1049 VisitInt32Binop(node);
1050 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node));
1054 Type* rhs_type = GetInfo(node->InputAt(1))->output_type();
1055 VisitBinop(node, UseInfo::TruncatingWord32(),
1058 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type);
1063 Type* rhs_type = GetInfo(node->InputAt(1))->output_type();
1064 VisitBinop(node, UseInfo::TruncatingWord32(),
1067 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type);
1072 Type* rhs_type = GetInfo(node->InputAt(1))->output_type();
1073 VisitBinop(node, UseInfo::TruncatingWord32(),
1076 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
1082 VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32());
1083 if (lower()) DeferReplacement(node, node->InputAt(0));
1088 VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32());
1089 if (lower()) DeferReplacement(node, node->InputAt(0));
1093 VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Bool());
1097 node->ReplaceInput(0,
1100 node->InputAt(0)));
1101 node->AppendInput(jsgraph_->zone(),
1103 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal());
1108 VisitUnop(node, UseInfo::AnyTagged(), NodeOutputInfo::NumberTagged());
1111 Operator::Properties properties = node->op()->properties();
1117 node->InsertInput(jsgraph_->zone(), 0,
1119 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant());
1120 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc));
1125 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
1127 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual());
1132 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
1133 if (lower()) lowering->DoStringEqual(node);
1137 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
1138 if (lower()) lowering->DoStringLessThan(node);
1142 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool());
1143 if (lower()) lowering->DoStringLessThanOrEqual(node);
1147 ProcessInput(node, 0, UseInfo::AnyTagged());
1148 ProcessRemainingInputs(node, 1);
1149 SetOutput(node, NodeOutputInfo::AnyTagged());
1153 FieldAccess access = FieldAccessOf(node->op());
1154 ProcessInput(node, 0, UseInfoForBasePointer(access));
1155 ProcessRemainingInputs(node, 1);
1156 SetOutputFromMachineType(node, access.machine_type);
1160 FieldAccess access = FieldAccessOf(node->op());
1161 ProcessInput(node, 0, UseInfoForBasePointer(access));
1162 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation(
1164 ProcessRemainingInputs(node, 2);
1165 SetOutput(node, NodeOutputInfo::None());
1169 BufferAccess access = BufferAccessOf(node->op());
1170 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer
1171 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
1172 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
1173 ProcessRemainingInputs(node, 3);
1181 NodeProperties::GetType(node));
1190 NodeProperties::GetType(node));
1200 SetOutput(node, output_info);
1202 lowering->DoLoadBuffer(node, output_info.representation(), changer_);
1206 BufferAccess access = BufferAccessOf(node->op());
1207 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer
1208 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset
1209 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length
1210 ProcessInput(node, 3,
1213 ProcessRemainingInputs(node, 4);
1214 SetOutput(node, NodeOutputInfo::None());
1215 if (lower()) lowering->DoStoreBuffer(node);
1219 ElementAccess access = ElementAccessOf(node->op());
1220 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base
1221 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
1222 ProcessRemainingInputs(node, 2);
1223 SetOutputFromMachineType(node, access.machine_type);
1227 ElementAccess access = ElementAccessOf(node->op());
1228 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base
1229 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index
1230 ProcessInput(node, 2,
1233 ProcessRemainingInputs(node, 3);
1234 SetOutput(node, NodeOutputInfo::None());
1238 ProcessInput(node, 0, UseInfo::AnyTagged());
1239 SetOutput(node, NodeOutputInfo::Bool());
1240 if (lower()) lowering->DoObjectIsNumber(node);
1244 ProcessInput(node, 0, UseInfo::AnyTagged());
1245 SetOutput(node, NodeOutputInfo::Bool());
1246 if (lower()) lowering->DoObjectIsSmi(node);
1256 LoadRepresentation rep = LoadRepresentationOf(node->op());
1257 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer
1258 ProcessInput(node, 1, UseInfo::PointerInt()); // index
1259 ProcessRemainingInputs(node, 2);
1260 SetOutputFromMachineType(node, rep);
1266 StoreRepresentation rep = StoreRepresentationOf(node->op());
1267 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer
1268 node, 1, UseInfo::PointerInt()); // index
1269 ProcessInput(node, 2,
1271 ProcessRemainingInputs(node, 3);
1272 SetOutput(node, NodeOutputInfo::None());
1277 return VisitBinop(node, UseInfo::TruncatingWord32(),
1287 return VisitBinop(node, UseInfo::TruncatingWord32(),
1290 return VisitBinop(node, UseInfo::TruncatingWord32(),
1294 return VisitUnop(node, UseInfo::TruncatingWord32(),
1303 return VisitInt32Binop(node);
1307 return VisitUint32Binop(node);
1310 return VisitInt32Cmp(node);
1314 return VisitUint32Cmp(node);
1321 return VisitInt64Binop(node);
1324 return VisitInt64Cmp(node);
1327 return VisitUint64Cmp(node);
1331 return VisitUint64Binop(node);
1339 return VisitBinop(node, UseInfo::TruncatingWord64(),
1342 return VisitBinop(node, UseInfo::TruncatingWord64(),
1347 node, UseInfo::TruncatingWord32(),
1351 node, UseInfo::TruncatingWord32(),
1354 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float32());
1356 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32());
1359 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(),
1363 return VisitUnop(node, UseInfo::Float32(), NodeOutputInfo::Float64());
1366 node, UseInfo::TruncatingWord32(),
1369 return VisitUnop(node, UseInfo::TruncatingWord32(),
1373 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
1376 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(),
1385 return VisitFloat64Binop(node);
1391 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float64());
1395 return VisitFloat64Cmp(node);
1398 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32());
1401 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(),
1405 return VisitLeaf(node, NodeOutputInfo::Pointer());
1407 VisitStateValues(node);
1410 VisitInputs(node);
1412 SetOutput(node, NodeOutputInfo::AnyTagged());
1417 void DeferReplacement(Node* node, Node* replacement) {
1418 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(),
1419 node->op()->mnemonic(), replacement->id(),
1423 GetInfo(node)->output_type()->Is(GetInfo(replacement)->output_type())) {
1424 // Replace with a previously existing node eagerly only if the type is the
1426 node->ReplaceUses(replacement);
1428 // Otherwise, we are replacing a node with a representation change.
1431 // insertion for uses of the node.
1432 replacements_.push_back(node);
1435 node->NullAllInputs(); // Node is now dead.
1471 ZoneVector<NodeInfo> info_; // node id -> usage information
1480 ZoneQueue<Node*> queue_; // queue for traversing the graph
1489 NodeInfo* GetInfo(Node* node) {
1490 DCHECK(node->id() >= 0);
1491 DCHECK(node->id() < count_);
1492 return &info_[node->id()];
1513 void SimplifiedLowering::DoLoadBuffer(Node* node,
1516 DCHECK_EQ(IrOpcode::kLoadBuffer, node->opcode());
1518 MachineType const access_type = BufferAccessOf(node->op()).machine_type();
1520 Node* const buffer = node->InputAt(0);
1521 Node* const offset = node->InputAt(1);
1522 Node* const length = node->InputAt(2);
1523 Node* const effect = node->InputAt(3);
1524 Node* const control = node->InputAt(4);
1525 Node* const index =
1530 Node* check = graph()->NewNode(machine()->Uint32LessThan(), offset, length);
1531 Node* branch =
1534 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1535 Node* etrue = graph()->NewNode(machine()->Load(access_type), buffer, index,
1537 Node* vtrue = changer->GetRepresentationFor(
1538 etrue, access_type.representation(), NodeProperties::GetType(node),
1541 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1542 Node* efalse = effect;
1543 Node* vfalse;
1556 Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
1557 Node* ephi = graph()->NewNode(common()->EffectPhi(2), etrue, efalse, merge);
1559 // Replace effect uses of {node} with the {ephi}.
1560 NodeProperties::ReplaceUses(node, node, ephi);
1562 // Turn the {node} into a Phi.
1563 node->ReplaceInput(0, vtrue);
1564 node->ReplaceInput(1, vfalse);
1565 node->ReplaceInput(2, merge);
1566 node->TrimInputCount(3);
1567 NodeProperties::ChangeOp(node, common()->Phi(output_rep, 2));
1569 NodeProperties::ChangeOp(node, machine()->CheckedLoad(access_type));
1574 void SimplifiedLowering::DoStoreBuffer(Node* node) {
1575 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
1577 BufferAccessOf(node->op()).machine_type().representation();
1578 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep));
1582 void SimplifiedLowering::DoObjectIsNumber(Node* node) {
1583 Node* input = NodeProperties::GetValueInput(node, 0);
1585 Node* check =
1590 Node* branch = graph()->NewNode(common()->Branch(), check, graph()->start());
1591 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
1592 Node* vtrue = jsgraph()->Int32Constant(1);
1593 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
1594 Node* vfalse = graph()->NewNode(
1601 Node* control = graph()->NewNode(common()->Merge(2), if_true, if_false);
1602 node->ReplaceInput(0, vtrue);
1603 node->AppendInput(graph()->zone(), vfalse);
1604 node->AppendInput(graph()->zone(), control);
1605 NodeProperties::ChangeOp(node, common()->Phi(MachineRepresentation::kBit, 2));
1609 void SimplifiedLowering::DoObjectIsSmi(Node* node) {
1610 node->ReplaceInput(0,
1611 graph()->NewNode(machine()->WordAnd(), node->InputAt(0),
1613 node->AppendInput(graph()->zone(), jsgraph()->IntPtrConstant(kSmiTag));
1614 NodeProperties::ChangeOp(node, machine()->WordEqual());
1618 Node* SimplifiedLowering::StringComparison(Node* node) {
1619 Operator::Properties properties = node->op()->properties();
1626 NodeProperties::GetValueInput(node, 0),
1627 NodeProperties::GetValueInput(node, 1), jsgraph()->NoContextConstant(),
1628 NodeProperties::GetEffectInput(node),
1629 NodeProperties::GetControlInput(node));
1633 Node* SimplifiedLowering::Int32Div(Node* const node) {
1634 Int32BinopMatcher m(node);
1635 Node* const zero = jsgraph()->Int32Constant(0);
1636 Node* const minus_one = jsgraph()->Int32Constant(-1);
1637 Node* const lhs = m.left().node();
1638 Node* const rhs = m.right().node();
1666 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
1667 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
1670 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1671 Node* true0 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true0);
1673 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1674 Node* false0;
1676 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
1677 Node
1679 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1680 Node* true1 = graph()->NewNode(machine()->Int32Div(), lhs, rhs, if_true1);
1682 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1683 Node* false1;
1685 Node* check2 = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1686 Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_false1);
1688 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1689 Node* true2 = zero;
1691 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1692 Node* false2 = graph()->NewNode(machine()->Int32Sub(), zero, lhs);
1702 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
1707 Node* SimplifiedLowering::Int32Mod(Node* const node) {
1708 Int32BinopMatcher m(node);
1709 Node* const zero = jsgraph()->Int32Constant(0);
1710 Node* const minus_one = jsgraph()->Int32Constant(-1);
1711 Node* const lhs = m.left().node();
1712 Node* const rhs = m.right().node();
1744 Node* check0 = graph()->NewNode(machine()->Int32LessThan(), zero, rhs);
1745 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
1748 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1749 Node* true0;
1751 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
1753 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
1754 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
1756 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1757 Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
1759 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1760 Node* false1;
1762 Node* check2 = graph()->NewNode(machine()->Int32LessThan(), lhs, zero);
1763 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1766 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1767 Node* true2 = graph()->NewNode(
1773 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1774 Node* false2 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1784 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1785 Node* false0;
1787 Node* check1 = graph()->NewNode(machine()->Int32LessThan(), rhs, minus_one);
1788 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kTrue),
1791 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1792 Node* true1 = graph()->NewNode(machine()->Int32Mod(), lhs, rhs, if_true1);
1794 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1795 Node* false1 = zero;
1801 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
1806 Node* SimplifiedLowering::Uint32Div(Node* const node) {
1807 Uint32BinopMatcher m(node);
1808 Node* const zero = jsgraph()->Uint32Constant(0);
1809 Node* const lhs = m.left().node();
1810 Node* const rhs = m.right().node();
1818 Node* check = graph()->NewNode(machine()->Word32Equal(), rhs, zero);
1820 Node* div = graph()->NewNode(machine()->Uint32Div(), lhs, rhs, d.if_false);
1825 Node* SimplifiedLowering::Uint32Mod(Node* const node) {
1826 Uint32BinopMatcher m(node);
1827 Node* const minus_one = jsgraph()->Int32Constant(-1);
1828 Node* const zero = jsgraph()->Uint32Constant(0);
1829 Node* const lhs = m.left().node();
1830 Node* const rhs = m.right().node();
1856 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), rhs,
1859 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1860 Node* true0;
1862 Node* msk = graph()->NewNode(machine()->Int32Add(), rhs, minus_one);
1864 Node* check1 = graph()->NewNode(machine()->Word32And(), rhs, msk);
1865 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
1867 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1868 Node* true1 = graph()->NewNode(machine()->Uint32Mod(), lhs, rhs, if_true1);
1870 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1871 Node* false1 = graph()->NewNode(machine()->Word32And(), lhs, msk);
1877 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1878 Node* false0 = zero;
1880 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0);
1885 void SimplifiedLowering::DoShift(Node* node, Operator const* op,
1887 Node* const rhs = NodeProperties::GetValueInput(node, 1);
1889 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
1892 NodeProperties::ChangeOp(node, op);
1898 void ReplaceEffectUses(Node* node, Node* replacement) {
1901 for (Edge edge : node->use_edges()) {
1913 void SimplifiedLowering::DoStringEqual(Node* node) {
1914 Node* comparison = StringComparison(node);
1915 ReplaceEffectUses(node, comparison);
1916 node->ReplaceInput(0, comparison);
1917 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1918 node->TrimInputCount(2);
1919 NodeProperties::ChangeOp(node, machine()->WordEqual());
1923 void SimplifiedLowering::DoStringLessThan(Node* node) {
1924 Node* comparison = StringComparison(node);
1925 ReplaceEffectUses(node, comparison);
1926 node->ReplaceInput(0, comparison);
1927 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1928 node->TrimInputCount(2);
1929 NodeProperties::ChangeOp(node, machine()->IntLessThan());
1933 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
1934 Node* comparison = StringComparison(node);
1935 ReplaceEffectUses(node, comparison);
1936 node->ReplaceInput(0, comparison);
1937 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1938 node->TrimInputCount(2);
1939 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual());