OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/address-map.h" | 9 #include "src/address-map.h" |
10 #include "src/base/bits.h" | 10 #include "src/base/bits.h" |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 234 |
235 MachineRepresentation representation() const { return representation_; } | 235 MachineRepresentation representation() const { return representation_; } |
236 | 236 |
237 // Helpers for feedback typing. | 237 // Helpers for feedback typing. |
238 void set_feedback_type(Type* type) { feedback_type_ = type; } | 238 void set_feedback_type(Type* type) { feedback_type_ = type; } |
239 Type* feedback_type() const { return feedback_type_; } | 239 Type* feedback_type() const { return feedback_type_; } |
240 void set_weakened() { weakened_ = true; } | 240 void set_weakened() { weakened_ = true; } |
241 bool weakened() const { return weakened_; } | 241 bool weakened() const { return weakened_; } |
242 void set_restriction_type(Type* type) { restriction_type_ = type; } | 242 void set_restriction_type(Type* type) { restriction_type_ = type; } |
243 Type* restriction_type() const { return restriction_type_; } | 243 Type* restriction_type() const { return restriction_type_; } |
| 244 void set_unrestricted_feedback_type(Type* type) { |
| 245 unrestricted_feedback_type_ = type; |
| 246 } |
| 247 Type* unrestricted_feedback_type() const { |
| 248 return unrestricted_feedback_type_; |
| 249 } |
244 | 250 |
245 private: | 251 private: |
246 enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued }; | 252 enum State : uint8_t { kUnvisited, kPushed, kVisited, kQueued }; |
247 State state_ = kUnvisited; | 253 State state_ = kUnvisited; |
248 MachineRepresentation representation_ = | 254 MachineRepresentation representation_ = |
249 MachineRepresentation::kNone; // Output representation. | 255 MachineRepresentation::kNone; // Output representation. |
250 Truncation truncation_ = Truncation::None(); // Information about uses. | 256 Truncation truncation_ = Truncation::None(); // Information about uses. |
251 | 257 |
252 Type* restriction_type_ = Type::Any(); | 258 Type* restriction_type_ = Type::Any(); |
253 Type* feedback_type_ = nullptr; | 259 Type* feedback_type_ = nullptr; |
| 260 Type* unrestricted_feedback_type_ = nullptr; |
254 bool weakened_ = false; | 261 bool weakened_ = false; |
255 }; | 262 }; |
256 | 263 |
257 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 264 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
258 RepresentationChanger* changer, | 265 RepresentationChanger* changer, |
259 SourcePositionTable* source_positions) | 266 SourcePositionTable* source_positions) |
260 : jsgraph_(jsgraph), | 267 : jsgraph_(jsgraph), |
261 zone_(zone), | 268 zone_(zone), |
262 count_(jsgraph->graph()->NodeCount()), | 269 count_(jsgraph->graph()->NodeCount()), |
263 info_(count_, zone), | 270 info_(count_, zone), |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
357 Type* TypeOf(Node* node) { | 364 Type* TypeOf(Node* node) { |
358 Type* type = GetInfo(node)->feedback_type(); | 365 Type* type = GetInfo(node)->feedback_type(); |
359 return type == nullptr ? NodeProperties::GetType(node) : type; | 366 return type == nullptr ? NodeProperties::GetType(node) : type; |
360 } | 367 } |
361 | 368 |
362 Type* FeedbackTypeOf(Node* node) { | 369 Type* FeedbackTypeOf(Node* node) { |
363 Type* type = GetInfo(node)->feedback_type(); | 370 Type* type = GetInfo(node)->feedback_type(); |
364 return type == nullptr ? Type::None() : type; | 371 return type == nullptr ? Type::None() : type; |
365 } | 372 } |
366 | 373 |
| 374 Type* UnrestrictedFeedbackTypeOf(Node* node) { |
| 375 Type* type = GetInfo(node)->unrestricted_feedback_type(); |
| 376 return type == nullptr ? NodeProperties::GetType(node) : type; |
| 377 } |
| 378 |
367 Type* TypePhi(Node* node) { | 379 Type* TypePhi(Node* node) { |
368 int arity = node->op()->ValueInputCount(); | 380 int arity = node->op()->ValueInputCount(); |
369 Type* type = FeedbackTypeOf(node->InputAt(0)); | 381 Type* type = FeedbackTypeOf(node->InputAt(0)); |
370 for (int i = 1; i < arity; ++i) { | 382 for (int i = 1; i < arity; ++i) { |
371 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i))); | 383 type = op_typer_.Merge(type, FeedbackTypeOf(node->InputAt(i))); |
372 } | 384 } |
373 return type; | 385 return type; |
374 } | 386 } |
375 | 387 |
376 Type* TypeSelect(Node* node) { | 388 Type* TypeSelect(Node* node) { |
(...skipping 22 matching lines...) Expand all Loading... |
399 switch (node->opcode()) { | 411 switch (node->opcode()) { |
400 #define DECLARE_CASE(Name) \ | 412 #define DECLARE_CASE(Name) \ |
401 case IrOpcode::k##Name: { \ | 413 case IrOpcode::k##Name: { \ |
402 new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \ | 414 new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \ |
403 FeedbackTypeOf(node->InputAt(1))); \ | 415 FeedbackTypeOf(node->InputAt(1))); \ |
404 break; \ | 416 break; \ |
405 } | 417 } |
406 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE) | 418 SIMPLIFIED_NUMBER_BINOP_LIST(DECLARE_CASE) |
407 #undef DECLARE_CASE | 419 #undef DECLARE_CASE |
408 | 420 |
409 #define DECLARE_CASE(Name) \ | 421 #define DECLARE_CASE(Name) \ |
410 case IrOpcode::k##Name: { \ | 422 case IrOpcode::k##Name: { \ |
411 new_type = \ | 423 new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \ |
412 Type::Intersect(op_typer_.Name(FeedbackTypeOf(node->InputAt(0)), \ | 424 FeedbackTypeOf(node->InputAt(1))); \ |
413 FeedbackTypeOf(node->InputAt(1))), \ | 425 break; \ |
414 info->restriction_type(), graph_zone()); \ | |
415 break; \ | |
416 } | 426 } |
417 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE) | 427 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(DECLARE_CASE) |
418 #undef DECLARE_CASE | 428 #undef DECLARE_CASE |
419 | 429 |
420 #define DECLARE_CASE(Name) \ | 430 #define DECLARE_CASE(Name) \ |
421 case IrOpcode::k##Name: { \ | 431 case IrOpcode::k##Name: { \ |
422 new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0))); \ | 432 new_type = op_typer_.Name(FeedbackTypeOf(node->InputAt(0))); \ |
423 break; \ | 433 break; \ |
424 } | 434 } |
425 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE) | 435 SIMPLIFIED_NUMBER_UNOP_LIST(DECLARE_CASE) |
(...skipping 18 matching lines...) Expand all Loading... |
444 } | 454 } |
445 | 455 |
446 case IrOpcode::kSelect: { | 456 case IrOpcode::kSelect: { |
447 new_type = TypeSelect(node); | 457 new_type = TypeSelect(node); |
448 break; | 458 break; |
449 } | 459 } |
450 | 460 |
451 default: | 461 default: |
452 // Shortcut for operations that we do not handle. | 462 // Shortcut for operations that we do not handle. |
453 if (type == nullptr) { | 463 if (type == nullptr) { |
454 GetInfo(node)->set_feedback_type(NodeProperties::GetType(node)); | 464 type = GetUpperBound(node); |
| 465 info->set_unrestricted_feedback_type(type); |
| 466 info->set_feedback_type( |
| 467 Type::Intersect(type, info->restriction_type(), graph_zone())); |
455 return true; | 468 return true; |
456 } | 469 } |
457 return false; | 470 return false; |
458 } | 471 } |
| 472 Type* unrestricted_feedback_type = new_type; |
| 473 new_type = |
| 474 Type::Intersect(new_type, info->restriction_type(), graph_zone()); |
459 // We need to guarantee that the feedback type is a subtype of the upper | 475 // We need to guarantee that the feedback type is a subtype of the upper |
460 // bound. Naively that should hold, but weakening can actually produce | 476 // bound. Naively that should hold, but weakening can actually produce |
461 // a bigger type if we are unlucky with ordering of phi typing. To be | 477 // a bigger type if we are unlucky with ordering of phi typing. To be |
462 // really sure, just intersect the upper bound with the feedback type. | 478 // really sure, just intersect the upper bound with the feedback type. |
463 new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone()); | 479 new_type = Type::Intersect(GetUpperBound(node), new_type, graph_zone()); |
464 | 480 |
465 if (type != nullptr && new_type->Is(type)) return false; | 481 if (type != nullptr && new_type->Is(type)) return false; |
466 GetInfo(node)->set_feedback_type(new_type); | 482 info->set_unrestricted_feedback_type(unrestricted_feedback_type); |
| 483 info->set_feedback_type(new_type); |
467 if (FLAG_trace_representation) { | 484 if (FLAG_trace_representation) { |
468 PrintNodeFeedbackType(node); | 485 PrintNodeFeedbackType(node); |
469 } | 486 } |
470 return true; | 487 return true; |
471 } | 488 } |
472 | 489 |
473 void PrintNodeFeedbackType(Node* n) { | 490 void PrintNodeFeedbackType(Node* n) { |
474 OFStream os(stdout); | 491 OFStream os(stdout); |
475 os << "#" << n->id() << ":" << *n->op() << "("; | 492 os << "#" << n->id() << ":" << *n->op() << "("; |
476 int j = 0; | 493 int j = 0; |
(...skipping 622 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1099 return WriteBarrierKindFor(base_taggedness, field_representation, | 1116 return WriteBarrierKindFor(base_taggedness, field_representation, |
1100 field_type, value_representation, value); | 1117 field_type, value_representation, value); |
1101 } | 1118 } |
1102 | 1119 |
1103 Graph* graph() const { return jsgraph_->graph(); } | 1120 Graph* graph() const { return jsgraph_->graph(); } |
1104 CommonOperatorBuilder* common() const { return jsgraph_->common(); } | 1121 CommonOperatorBuilder* common() const { return jsgraph_->common(); } |
1105 SimplifiedOperatorBuilder* simplified() const { | 1122 SimplifiedOperatorBuilder* simplified() const { |
1106 return jsgraph_->simplified(); | 1123 return jsgraph_->simplified(); |
1107 } | 1124 } |
1108 | 1125 |
1109 void LowerToCheckedInt32Mul(Node* node, Truncation truncation, | |
1110 Type* input0_type, Type* input1_type) { | |
1111 // If one of the inputs is positive and/or truncation is being applied, | |
1112 // there is no need to return -0. | |
1113 CheckForMinusZeroMode mz_mode = | |
1114 truncation.IsUsedAsWord32() || | |
1115 (input0_type->Is(Type::OrderedNumber()) && | |
1116 input0_type->Min() > 0) || | |
1117 (input1_type->Is(Type::OrderedNumber()) && | |
1118 input1_type->Min() > 0) | |
1119 ? CheckForMinusZeroMode::kDontCheckForMinusZero | |
1120 : CheckForMinusZeroMode::kCheckForMinusZero; | |
1121 | |
1122 NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode)); | |
1123 } | |
1124 | |
1125 void ChangeToInt32OverflowOp(Node* node) { | 1126 void ChangeToInt32OverflowOp(Node* node) { |
1126 NodeProperties::ChangeOp(node, Int32OverflowOp(node)); | 1127 NodeProperties::ChangeOp(node, Int32OverflowOp(node)); |
1127 } | 1128 } |
1128 | 1129 |
1129 void ChangeToUint32OverflowOp(Node* node) { | 1130 void ChangeToUint32OverflowOp(Node* node) { |
1130 NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); | 1131 NodeProperties::ChangeOp(node, Uint32OverflowOp(node)); |
1131 } | 1132 } |
1132 | 1133 |
1133 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, | 1134 void VisitSpeculativeAdditiveOp(Node* node, Truncation truncation, |
1134 SimplifiedLowering* lowering) { | 1135 SimplifiedLowering* lowering) { |
1135 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can | 1136 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we can |
1136 // only eliminate an unused speculative number operation if we know that | 1137 // only eliminate an unused speculative number operation if we know that |
1137 // the inputs are PlainPrimitive, which excludes everything that's might | 1138 // the inputs are PlainPrimitive, which excludes everything that's might |
1138 // have side effects or throws during a ToNumber conversion. | 1139 // have side effects or throws during a ToNumber conversion. |
1139 if (BothInputsAre(node, Type::PlainPrimitive())) { | 1140 if (BothInputsAre(node, Type::PlainPrimitive())) { |
1140 if (truncation.IsUnused()) return VisitUnused(node); | 1141 if (truncation.IsUnused()) return VisitUnused(node); |
1141 } | 1142 } |
1142 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && | 1143 if (BothInputsAre(node, type_cache_.kAdditiveSafeIntegerOrMinusZero) && |
1143 (GetUpperBound(node)->Is(Type::Signed32()) || | 1144 (GetUpperBound(node)->Is(Type::Signed32()) || |
1144 GetUpperBound(node)->Is(Type::Unsigned32()) || | 1145 GetUpperBound(node)->Is(Type::Unsigned32()) || |
1145 truncation.IsUsedAsWord32())) { | 1146 truncation.IsUsedAsWord32())) { |
1146 // => Int32Add/Sub | 1147 // => Int32Add/Sub |
1147 VisitWord32TruncatingBinop(node); | 1148 VisitWord32TruncatingBinop(node); |
1148 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1149 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
1149 return; | 1150 return; |
1150 } | 1151 } |
1151 | 1152 |
1152 // Try to use type feedback. | 1153 // We always take SignedSmall/Signed32 feedback otherwise. |
1153 NumberOperationHint hint = NumberOperationHintOf(node->op()); | 1154 NumberOperationHint const hint = NumberOperationHintOf(node->op()); |
1154 | 1155 if (hint == NumberOperationHint::kSignedSmall || |
1155 // Handle the case when no int32 checks on inputs are necessary | 1156 hint == NumberOperationHint::kSigned32) { |
1156 // (but an overflow check is needed on the output). | 1157 // Check if we can guarantee truncations for the inputs. |
1157 if (BothInputsAre(node, Type::Signed32()) || | 1158 if (BothInputsAre(node, Type::Signed32()) || |
1158 (BothInputsAre(node, Type::Signed32OrMinusZero()) && | 1159 (BothInputsAre(node, Type::Signed32OrMinusZero()) && |
1159 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { | 1160 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))) { |
1160 // If both the inputs the feedback are int32, use the overflow op. | |
1161 if (hint == NumberOperationHint::kSignedSmall || | |
1162 hint == NumberOperationHint::kSigned32) { | |
1163 VisitBinop(node, UseInfo::TruncatingWord32(), | 1161 VisitBinop(node, UseInfo::TruncatingWord32(), |
1164 MachineRepresentation::kWord32, Type::Signed32()); | 1162 MachineRepresentation::kWord32, Type::Signed32()); |
1165 if (lower()) ChangeToInt32OverflowOp(node); | 1163 } else { |
1166 return; | 1164 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), |
| 1165 MachineRepresentation::kWord32, Type::Signed32()); |
1167 } | 1166 } |
1168 } | 1167 if (lower()) { |
1169 | 1168 // Avoid overflow checks if the unrestricted feedback type of {node} |
1170 if (hint == NumberOperationHint::kSignedSmall || | 1169 // suggests that the result will fit into Signed32/Unsigned32 range. |
1171 hint == NumberOperationHint::kSigned32) { | 1170 Type* const type = UnrestrictedFeedbackTypeOf(node); |
1172 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | 1171 if (type->Is(Type::Unsigned32())) { |
1173 MachineRepresentation::kWord32, Type::Signed32()); | 1172 ChangeToPureOp(node, Uint32Op(node)); |
1174 if (lower()) ChangeToInt32OverflowOp(node); | 1173 } else if (type->Is(Type::Signed32())) { |
| 1174 ChangeToPureOp(node, Int32Op(node)); |
| 1175 } else { |
| 1176 ChangeToInt32OverflowOp(node); |
| 1177 } |
| 1178 } |
1175 return; | 1179 return; |
1176 } | 1180 } |
1177 | 1181 |
1178 // default case => Float64Add/Sub | 1182 // default case => Float64Add/Sub |
1179 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 1183 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), |
1180 MachineRepresentation::kFloat64, Type::Number()); | 1184 MachineRepresentation::kFloat64, Type::Number()); |
1181 if (lower()) { | 1185 if (lower()) { |
1182 ChangeToPureOp(node, Float64Op(node)); | 1186 ChangeToPureOp(node, Float64Op(node)); |
1183 } | 1187 } |
1184 return; | |
1185 } | 1188 } |
1186 | 1189 |
1187 void VisitSpeculativeNumberModulus(Node* node, Truncation truncation, | 1190 void VisitSpeculativeNumberModulus(Node* node, Truncation truncation, |
1188 SimplifiedLowering* lowering) { | 1191 SimplifiedLowering* lowering) { |
1189 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we | 1192 // ToNumber(x) can throw if x is either a Receiver or a Symbol, so we |
1190 // can only eliminate an unused speculative number operation if we know | 1193 // can only eliminate an unused speculative number operation if we know |
1191 // that the inputs are PlainPrimitive, which excludes everything that's | 1194 // that the inputs are PlainPrimitive, which excludes everything that's |
1192 // might have side effects or throws during a ToNumber conversion. | 1195 // might have side effects or throws during a ToNumber conversion. |
1193 if (BothInputsAre(node, Type::PlainPrimitive())) { | 1196 if (BothInputsAre(node, Type::PlainPrimitive())) { |
1194 if (truncation.IsUnused()) return VisitUnused(node); | 1197 if (truncation.IsUnused()) return VisitUnused(node); |
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1516 type_cache_.kSafeIntegerOrMinusZero)))) { | 1519 type_cache_.kSafeIntegerOrMinusZero)))) { |
1517 // Multiply reduces to Int32Mul if the inputs are integers, and | 1520 // Multiply reduces to Int32Mul if the inputs are integers, and |
1518 // (a) the output is either known to be Signed32, or | 1521 // (a) the output is either known to be Signed32, or |
1519 // (b) the output is known to be Unsigned32, or | 1522 // (b) the output is known to be Unsigned32, or |
1520 // (c) the uses are truncating and the result is in the safe | 1523 // (c) the uses are truncating and the result is in the safe |
1521 // integer range. | 1524 // integer range. |
1522 VisitWord32TruncatingBinop(node); | 1525 VisitWord32TruncatingBinop(node); |
1523 if (lower()) ChangeToPureOp(node, Int32Op(node)); | 1526 if (lower()) ChangeToPureOp(node, Int32Op(node)); |
1524 return; | 1527 return; |
1525 } | 1528 } |
1526 // Try to use type feedback. | |
1527 NumberOperationHint hint = NumberOperationHintOf(node->op()); | |
1528 Type* input0_type = TypeOf(node->InputAt(0)); | |
1529 Type* input1_type = TypeOf(node->InputAt(1)); | |
1530 | 1529 |
1531 // Handle the case when no int32 checks on inputs are necessary | 1530 // We always take SignedSmall/Signed32 feedback otherwise. |
1532 // (but an overflow check is needed on the output). | 1531 NumberOperationHint const hint = NumberOperationHintOf(node->op()); |
1533 if (BothInputsAre(node, Type::Signed32())) { | 1532 if (hint == NumberOperationHint::kSignedSmall || |
1534 // If both the inputs the feedback are int32, use the overflow op. | 1533 hint == NumberOperationHint::kSigned32) { |
1535 if (hint == NumberOperationHint::kSignedSmall || | 1534 // Handle the case when no int32 checks on inputs are necessary |
1536 hint == NumberOperationHint::kSigned32) { | 1535 // (but an overflow check is needed on the output). |
| 1536 if (BothInputsAre(node, Type::Signed32())) { |
| 1537 // If both the inputs the feedback are int32, use the overflow op. |
1537 VisitBinop(node, UseInfo::TruncatingWord32(), | 1538 VisitBinop(node, UseInfo::TruncatingWord32(), |
1538 MachineRepresentation::kWord32, Type::Signed32()); | 1539 MachineRepresentation::kWord32, Type::Signed32()); |
1539 if (lower()) { | 1540 } else { |
1540 LowerToCheckedInt32Mul(node, truncation, input0_type, | 1541 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), |
1541 input1_type); | 1542 MachineRepresentation::kWord32, Type::Signed32()); |
| 1543 } |
| 1544 if (lower()) { |
| 1545 // Avoid overflow checks if the unrestricted feedback type of {node} |
| 1546 // suggests that the result will fit into Signed32/Unsigned32 range, |
| 1547 // or at least try to avoid the expensive minus zero checks. |
| 1548 Type* const type = UnrestrictedFeedbackTypeOf(node); |
| 1549 if (type->Is(Type::Unsigned32())) { |
| 1550 ChangeToPureOp(node, Uint32Op(node)); |
| 1551 } else if (type->Is(Type::Signed32())) { |
| 1552 ChangeToPureOp(node, Int32Op(node)); |
| 1553 } else { |
| 1554 CheckForMinusZeroMode const mode = |
| 1555 (truncation.IdentifiesMinusZeroAndZero() || |
| 1556 !type->Maybe(Type::MinusZero())) |
| 1557 ? CheckForMinusZeroMode::kDontCheckForMinusZero |
| 1558 : CheckForMinusZeroMode::kCheckForMinusZero; |
| 1559 NodeProperties::ChangeOp(node, |
| 1560 simplified()->CheckedInt32Mul(mode)); |
1542 } | 1561 } |
1543 return; | |
1544 } | |
1545 } | |
1546 | |
1547 if (hint == NumberOperationHint::kSignedSmall || | |
1548 hint == NumberOperationHint::kSigned32) { | |
1549 VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint), | |
1550 MachineRepresentation::kWord32, Type::Signed32()); | |
1551 if (lower()) { | |
1552 LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type); | |
1553 } | 1562 } |
1554 return; | 1563 return; |
1555 } | 1564 } |
1556 | 1565 |
1557 // Checked float64 x float64 => float64 | 1566 // Checked float64 x float64 => float64 |
1558 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), | 1567 VisitBinop(node, UseInfo::CheckedNumberOrOddballAsFloat64(), |
1559 MachineRepresentation::kFloat64, Type::Number()); | 1568 MachineRepresentation::kFloat64, Type::Number()); |
1560 if (lower()) ChangeToPureOp(node, Float64Op(node)); | 1569 if (lower()) ChangeToPureOp(node, Float64Op(node)); |
1561 return; | 1570 return; |
1562 } | 1571 } |
(...skipping 1640 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3203 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3212 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3204 Operator::kNoProperties); | 3213 Operator::kNoProperties); |
3205 to_number_operator_.set(common()->Call(desc)); | 3214 to_number_operator_.set(common()->Call(desc)); |
3206 } | 3215 } |
3207 return to_number_operator_.get(); | 3216 return to_number_operator_.get(); |
3208 } | 3217 } |
3209 | 3218 |
3210 } // namespace compiler | 3219 } // namespace compiler |
3211 } // namespace internal | 3220 } // namespace internal |
3212 } // namespace v8 | 3221 } // namespace v8 |
OLD | NEW |