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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
(...skipping 21 matching lines...) Expand all Loading... |
32 !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) { | 32 !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) { |
33 return BinaryOperationHints::kAny; | 33 return BinaryOperationHints::kAny; |
34 } | 34 } |
35 DCHECK_NE(0, node_->op()->ControlOutputCount()); | 35 DCHECK_NE(0, node_->op()->ControlOutputCount()); |
36 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 36 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
37 DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op())); | 37 DCHECK_LE(1, OperatorProperties::GetFrameStateInputCount(node_->op())); |
38 BinaryOperationHints hints = BinaryOperationHintsOf(node_->op()); | 38 BinaryOperationHints hints = BinaryOperationHintsOf(node_->op()); |
39 BinaryOperationHints::Hint combined = hints.combined(); | 39 BinaryOperationHints::Hint combined = hints.combined(); |
40 if (combined == BinaryOperationHints::kSignedSmall || | 40 if (combined == BinaryOperationHints::kSignedSmall || |
41 combined == BinaryOperationHints::kSigned32 || | 41 combined == BinaryOperationHints::kSigned32 || |
42 combined == BinaryOperationHints::kNumberOrUndefined) { | 42 combined == BinaryOperationHints::kNumberOrOddball) { |
43 return combined; | 43 return combined; |
44 } | 44 } |
45 return BinaryOperationHints::kAny; | 45 return BinaryOperationHints::kAny; |
46 } | 46 } |
47 | 47 |
48 CompareOperationHints::Hint GetNumberCompareOperationFeedback() { | 48 CompareOperationHints::Hint GetNumberCompareOperationFeedback() { |
49 if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) || | 49 if (!(lowering_->flags() & JSTypedLowering::kDeoptimizationEnabled) || |
50 !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) { | 50 !(lowering_->flags() & JSTypedLowering::kTypeFeedbackEnabled)) { |
51 return CompareOperationHints::kAny; | 51 return CompareOperationHints::kAny; |
52 } | 52 } |
53 DCHECK_NE(0, node_->op()->ControlOutputCount()); | 53 DCHECK_NE(0, node_->op()->ControlOutputCount()); |
54 DCHECK_EQ(1, node_->op()->EffectOutputCount()); | 54 DCHECK_EQ(1, node_->op()->EffectOutputCount()); |
55 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op())); | 55 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node_->op())); |
56 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); | 56 CompareOperationHints hints = CompareOperationHintsOf(node_->op()); |
57 CompareOperationHints::Hint combined = hints.combined(); | 57 CompareOperationHints::Hint combined = hints.combined(); |
58 if (combined == CompareOperationHints::kSignedSmall || | 58 if (combined == CompareOperationHints::kSignedSmall || |
59 combined == CompareOperationHints::kNumber) { | 59 combined == CompareOperationHints::kNumberOrOddball) { |
60 return combined; | 60 return combined; |
61 } | 61 } |
62 return CompareOperationHints::kAny; | 62 return CompareOperationHints::kAny; |
63 } | 63 } |
64 | 64 |
65 void ConvertInputsToNumber() { | 65 void ConvertInputsToNumber() { |
66 // To convert the inputs to numbers, we have to provide frame states | 66 // To convert the inputs to numbers, we have to provide frame states |
67 // for lazy bailouts in the ToNumber conversions. | 67 // for lazy bailouts in the ToNumber conversions. |
68 // We use a little hack here: we take the frame state before the binary | 68 // We use a little hack here: we take the frame state before the binary |
69 // operation and use it to construct the frame states for the conversion | 69 // operation and use it to construct the frame states for the conversion |
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
428 double min = kMinInt / (1 << k); | 428 double min = kMinInt / (1 << k); |
429 double max = kMaxInt / (1 << k); | 429 double max = kMaxInt / (1 << k); |
430 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 430 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
431 } | 431 } |
432 } | 432 } |
433 | 433 |
434 | 434 |
435 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { | 435 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { |
436 JSBinopReduction r(this, node); | 436 JSBinopReduction r(this, node); |
437 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 437 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
438 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 438 if (feedback == BinaryOperationHints::kNumberOrOddball && |
439 r.BothInputsAre(Type::PlainPrimitive()) && | 439 r.BothInputsAre(Type::PlainPrimitive()) && |
440 r.NeitherInputCanBe(Type::StringOrReceiver())) { | 440 r.NeitherInputCanBe(Type::StringOrReceiver())) { |
441 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 441 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
442 r.ConvertInputsToNumber(); | 442 r.ConvertInputsToNumber(); |
443 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 443 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
444 } | 444 } |
445 if (feedback != BinaryOperationHints::kAny) { | 445 if (feedback != BinaryOperationHints::kAny) { |
446 // Lower to the optimistic number binop. | 446 // Lower to the optimistic number binop. |
447 return r.ChangeToSpeculativeOperator( | 447 return r.ChangeToSpeculativeOperator( |
448 simplified()->SpeculativeNumberAdd(feedback), Type::Number()); | 448 simplified()->SpeculativeNumberAdd(feedback), Type::Number()); |
(...skipping 30 matching lines...) Expand all Loading... |
479 NodeProperties::ChangeOp(node, common()->Call(desc)); | 479 NodeProperties::ChangeOp(node, common()->Call(desc)); |
480 return Changed(node); | 480 return Changed(node); |
481 } | 481 } |
482 return NoChange(); | 482 return NoChange(); |
483 } | 483 } |
484 | 484 |
485 | 485 |
486 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) { | 486 Reduction JSTypedLowering::ReduceJSSubtract(Node* node) { |
487 JSBinopReduction r(this, node); | 487 JSBinopReduction r(this, node); |
488 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 488 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
489 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 489 if (feedback == BinaryOperationHints::kNumberOrOddball && |
490 r.BothInputsAre(Type::PlainPrimitive())) { | 490 r.BothInputsAre(Type::PlainPrimitive())) { |
491 // JSSubtract(x:plain-primitive, y:plain-primitive) | 491 // JSSubtract(x:plain-primitive, y:plain-primitive) |
492 // => NumberSubtract(ToNumber(x), ToNumber(y)) | 492 // => NumberSubtract(ToNumber(x), ToNumber(y)) |
493 r.ConvertInputsToNumber(); | 493 r.ConvertInputsToNumber(); |
494 return r.ChangeToPureOperator(simplified()->NumberSubtract(), | 494 return r.ChangeToPureOperator(simplified()->NumberSubtract(), |
495 Type::Number()); | 495 Type::Number()); |
496 } | 496 } |
497 if (feedback != BinaryOperationHints::kAny) { | 497 if (feedback != BinaryOperationHints::kAny) { |
498 // Lower to the optimistic number binop. | 498 // Lower to the optimistic number binop. |
499 return r.ChangeToSpeculativeOperator( | 499 return r.ChangeToSpeculativeOperator( |
(...skipping 26 matching lines...) Expand all Loading... |
526 return r.ChangeToPureOperator(simplified()->NumberMultiply(), | 526 return r.ChangeToPureOperator(simplified()->NumberMultiply(), |
527 Type::Number()); | 527 Type::Number()); |
528 } | 528 } |
529 | 529 |
530 return NoChange(); | 530 return NoChange(); |
531 } | 531 } |
532 | 532 |
533 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { | 533 Reduction JSTypedLowering::ReduceJSDivide(Node* node) { |
534 JSBinopReduction r(this, node); | 534 JSBinopReduction r(this, node); |
535 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 535 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
536 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 536 if (feedback == BinaryOperationHints::kNumberOrOddball && |
537 r.BothInputsAre(Type::PlainPrimitive())) { | 537 r.BothInputsAre(Type::PlainPrimitive())) { |
538 // JSDivide(x:plain-primitive, | 538 // JSDivide(x:plain-primitive, |
539 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) | 539 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) |
540 r.ConvertInputsToNumber(); | 540 r.ConvertInputsToNumber(); |
541 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); | 541 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); |
542 } | 542 } |
543 if (feedback != BinaryOperationHints::kAny) { | 543 if (feedback != BinaryOperationHints::kAny) { |
544 return r.ChangeToSpeculativeOperator( | 544 return r.ChangeToSpeculativeOperator( |
545 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); | 545 simplified()->SpeculativeNumberDivide(feedback), Type::Number()); |
546 } | 546 } |
547 if (r.BothInputsAre(Type::PlainPrimitive())) { | 547 if (r.BothInputsAre(Type::PlainPrimitive())) { |
548 // JSDivide(x:plain-primitive, | 548 // JSDivide(x:plain-primitive, |
549 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) | 549 // y:plain-primitive) => NumberDivide(ToNumber(x), ToNumber(y)) |
550 r.ConvertInputsToNumber(); | 550 r.ConvertInputsToNumber(); |
551 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); | 551 return r.ChangeToPureOperator(simplified()->NumberDivide(), Type::Number()); |
552 } | 552 } |
553 return NoChange(); | 553 return NoChange(); |
554 } | 554 } |
555 | 555 |
556 Reduction JSTypedLowering::ReduceJSModulus(Node* node) { | 556 Reduction JSTypedLowering::ReduceJSModulus(Node* node) { |
557 JSBinopReduction r(this, node); | 557 JSBinopReduction r(this, node); |
558 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); | 558 BinaryOperationHints::Hint feedback = r.GetNumberBinaryOperationFeedback(); |
559 if (feedback == BinaryOperationHints::kNumberOrUndefined && | 559 if (feedback == BinaryOperationHints::kNumberOrOddball && |
560 r.BothInputsAre(Type::PlainPrimitive())) { | 560 r.BothInputsAre(Type::PlainPrimitive())) { |
561 // JSModulus(x:plain-primitive, | 561 // JSModulus(x:plain-primitive, |
562 // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y)) | 562 // y:plain-primitive) => NumberModulus(ToNumber(x), ToNumber(y)) |
563 r.ConvertInputsToNumber(); | 563 r.ConvertInputsToNumber(); |
564 return r.ChangeToPureOperator(simplified()->NumberModulus(), | 564 return r.ChangeToPureOperator(simplified()->NumberModulus(), |
565 Type::Number()); | 565 Type::Number()); |
566 } | 566 } |
567 if (feedback != BinaryOperationHints::kAny) { | 567 if (feedback != BinaryOperationHints::kAny) { |
568 return r.ChangeToSpeculativeOperator( | 568 return r.ChangeToSpeculativeOperator( |
569 simplified()->SpeculativeNumberModulus(feedback), Type::Number()); | 569 simplified()->SpeculativeNumberModulus(feedback), Type::Number()); |
(...skipping 1489 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 } | 2059 } |
2060 | 2060 |
2061 | 2061 |
2062 CompilationDependencies* JSTypedLowering::dependencies() const { | 2062 CompilationDependencies* JSTypedLowering::dependencies() const { |
2063 return dependencies_; | 2063 return dependencies_; |
2064 } | 2064 } |
2065 | 2065 |
2066 } // namespace compiler | 2066 } // namespace compiler |
2067 } // namespace internal | 2067 } // namespace internal |
2068 } // namespace v8 | 2068 } // namespace v8 |
OLD | NEW |