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/access-builder.h" | 5 #include "src/compiler/access-builder.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/js-typed-lowering.h" | 7 #include "src/compiler/js-typed-lowering.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/operator-properties.h" | 10 #include "src/compiler/operator-properties.h" |
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 } | 519 } |
520 if (r.BothInputsAre(Type::Number())) { | 520 if (r.BothInputsAre(Type::Number())) { |
521 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 521 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
522 } | 522 } |
523 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) | 523 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) |
524 return NoChange(); | 524 return NoChange(); |
525 } | 525 } |
526 | 526 |
527 | 527 |
528 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { | 528 Reduction JSTypedLowering::ReduceJSUnaryNot(Node* node) { |
529 Node* input = node->InputAt(0); | 529 Node* const input = node->InputAt(0); |
530 Type* input_type = NodeProperties::GetBounds(input).upper; | 530 Type* const input_type = NodeProperties::GetBounds(input).upper; |
531 if (input_type->Is(Type::Boolean())) { | 531 if (input_type->Is(Type::Boolean())) { |
532 // JSUnaryNot(x:boolean,context) => BooleanNot(x) | 532 // JSUnaryNot(x:boolean) => BooleanNot(x) |
533 node->set_op(simplified()->BooleanNot()); | 533 node->set_op(simplified()->BooleanNot()); |
534 node->TrimInputCount(1); | 534 node->TrimInputCount(1); |
535 return Changed(node); | 535 return Changed(node); |
536 } else if (input_type->Is(Type::OrderedNumber())) { | 536 } else if (input_type->Is(Type::OrderedNumber())) { |
537 // JSUnaryNot(x:number,context) => NumberEqual(x,#0) | 537 // JSUnaryNot(x:number) => NumberEqual(x,#0) |
538 node->set_op(simplified()->NumberEqual()); | 538 node->set_op(simplified()->NumberEqual()); |
539 node->ReplaceInput(1, jsgraph()->ZeroConstant()); | 539 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
540 DCHECK_EQ(2, node->InputCount()); | 540 node->TrimInputCount(2); |
| 541 return Changed(node); |
| 542 } else if (input_type->Is(Type::String())) { |
| 543 // JSUnaryNot(x:string) => NumberEqual(x.length,#0) |
| 544 FieldAccess const access = AccessBuilder::ForStringLength(); |
| 545 // It is safe for the load to be effect-free (i.e. not linked into effect |
| 546 // chain) because we assume String::length to be immutable. |
| 547 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
| 548 graph()->start(), graph()->start()); |
| 549 node->set_op(simplified()->NumberEqual()); |
| 550 node->ReplaceInput(0, length); |
| 551 node->ReplaceInput(1, jsgraph()->ZeroConstant()); |
| 552 node->TrimInputCount(2); |
| 553 NodeProperties::ReplaceWithValue(node, node, length); |
541 return Changed(node); | 554 return Changed(node); |
542 } | 555 } |
543 // JSUnaryNot(x,context) => BooleanNot(AnyToBoolean(x)) | 556 return NoChange(); |
544 node->set_op(simplified()->BooleanNot()); | |
545 node->ReplaceInput(0, graph()->NewNode(simplified()->AnyToBoolean(), input)); | |
546 node->TrimInputCount(1); | |
547 return Changed(node); | |
548 } | 557 } |
549 | 558 |
550 | 559 |
551 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 560 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
552 Node* input = node->InputAt(0); | 561 Node* const input = node->InputAt(0); |
553 Type* input_type = NodeProperties::GetBounds(input).upper; | 562 Type* const input_type = NodeProperties::GetBounds(input).upper; |
554 if (input_type->Is(Type::Boolean())) { | 563 if (input_type->Is(Type::Boolean())) { |
555 // JSToBoolean(x:boolean,context) => x | 564 // JSToBoolean(x:boolean) => x |
556 return Replace(input); | 565 return Replace(input); |
| 566 } else if (input_type->Is(Type::OrderedNumber())) { |
| 567 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) |
| 568 node->set_op(simplified()->BooleanNot()); |
| 569 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, |
| 570 jsgraph()->ZeroConstant())); |
| 571 node->TrimInputCount(1); |
| 572 return Changed(node); |
| 573 } else if (input_type->Is(Type::String())) { |
| 574 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) |
| 575 FieldAccess const access = AccessBuilder::ForStringLength(); |
| 576 // It is safe for the load to be effect-free (i.e. not linked into effect |
| 577 // chain) because we assume String::length to be immutable. |
| 578 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
| 579 graph()->start(), graph()->start()); |
| 580 node->set_op(simplified()->NumberLessThan()); |
| 581 node->ReplaceInput(0, jsgraph()->ZeroConstant()); |
| 582 node->ReplaceInput(1, length); |
| 583 node->TrimInputCount(2); |
| 584 return Changed(node); |
557 } | 585 } |
558 // JSToBoolean(x,context) => AnyToBoolean(x) | 586 return NoChange(); |
559 node->set_op(simplified()->AnyToBoolean()); | |
560 node->TrimInputCount(1); | |
561 return Changed(node); | |
562 } | 587 } |
563 | 588 |
564 | 589 |
565 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { | 590 Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) { |
566 if (input->opcode() == IrOpcode::kJSToNumber) { | 591 if (input->opcode() == IrOpcode::kJSToNumber) { |
567 // Recursively try to reduce the input first. | 592 // Recursively try to reduce the input first. |
568 Reduction result = ReduceJSToNumber(input); | 593 Reduction result = ReduceJSToNumber(input); |
569 if (result.Changed()) return result; | 594 if (result.Changed()) return result; |
570 return Changed(input); // JSToNumber(JSToNumber(x)) => JSToNumber(x) | 595 return Changed(input); // JSToNumber(JSToNumber(x)) => JSToNumber(x) |
571 } | 596 } |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1052 } | 1077 } |
1053 | 1078 |
1054 | 1079 |
1055 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1080 MachineOperatorBuilder* JSTypedLowering::machine() const { |
1056 return jsgraph()->machine(); | 1081 return jsgraph()->machine(); |
1057 } | 1082 } |
1058 | 1083 |
1059 } // namespace compiler | 1084 } // namespace compiler |
1060 } // namespace internal | 1085 } // namespace internal |
1061 } // namespace v8 | 1086 } // namespace v8 |
OLD | NEW |