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 "src/base/bits.h" | 7 #include "src/base/bits.h" |
8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
9 #include "src/compiler/common-operator.h" | 9 #include "src/compiler/common-operator.h" |
10 #include "src/compiler/graph-inl.h" | 10 #include "src/compiler/graph-inl.h" |
11 #include "src/compiler/node-matchers.h" | |
11 #include "src/compiler/node-properties-inl.h" | 12 #include "src/compiler/node-properties-inl.h" |
12 #include "src/compiler/representation-change.h" | 13 #include "src/compiler/representation-change.h" |
13 #include "src/compiler/simplified-lowering.h" | 14 #include "src/compiler/simplified-lowering.h" |
14 #include "src/compiler/simplified-operator.h" | 15 #include "src/compiler/simplified-operator.h" |
15 #include "src/objects.h" | 16 #include "src/objects.h" |
16 | 17 |
17 namespace v8 { | 18 namespace v8 { |
18 namespace internal { | 19 namespace internal { |
19 namespace compiler { | 20 namespace compiler { |
20 | 21 |
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
344 } | 345 } |
345 | 346 |
346 const Operator* Uint32Op(Node* node) { | 347 const Operator* Uint32Op(Node* node) { |
347 return changer_->Uint32OperatorFor(node->opcode()); | 348 return changer_->Uint32OperatorFor(node->opcode()); |
348 } | 349 } |
349 | 350 |
350 const Operator* Float64Op(Node* node) { | 351 const Operator* Float64Op(Node* node) { |
351 return changer_->Float64OperatorFor(node->opcode()); | 352 return changer_->Float64OperatorFor(node->opcode()); |
352 } | 353 } |
353 | 354 |
355 bool CanBeInt32Binop(Node* node, MachineTypeUnion use) { | |
Michael Starzinger
2014/10/01 21:11:32
I find the "CanBe" prefix confusing in this settin
Michael Starzinger
2014/10/01 21:15:57
Alternatively "CanBecome" would also work for me.
| |
356 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); | |
357 } | |
358 | |
359 bool CanBeUint32Binop(Node* node, MachineTypeUnion use) { | |
Michael Starzinger
2014/10/01 21:11:32
Likewise.
| |
360 return BothInputsAre(node, Type::Unsigned32()) && !CanObserveNonUint32(use); | |
361 } | |
362 | |
363 bool CanObserveNonInt32(MachineTypeUnion use) { | |
364 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; | |
365 } | |
366 | |
367 bool CanObserveNonUint32(MachineTypeUnion use) { | |
368 return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0; | |
369 } | |
370 | |
354 // Dispatching routine for visiting the node {node} with the usage {use}. | 371 // Dispatching routine for visiting the node {node} with the usage {use}. |
355 // Depending on the operator, propagate new usage info to the inputs. | 372 // Depending on the operator, propagate new usage info to the inputs. |
356 void VisitNode(Node* node, MachineTypeUnion use, | 373 void VisitNode(Node* node, MachineTypeUnion use, |
357 SimplifiedLowering* lowering) { | 374 SimplifiedLowering* lowering) { |
358 switch (node->opcode()) { | 375 switch (node->opcode()) { |
359 //------------------------------------------------------------------ | 376 //------------------------------------------------------------------ |
360 // Common operators. | 377 // Common operators. |
361 //------------------------------------------------------------------ | 378 //------------------------------------------------------------------ |
362 case IrOpcode::kStart: | 379 case IrOpcode::kStart: |
363 case IrOpcode::kDead: | 380 case IrOpcode::kDead: |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
468 // => Float64Cmp | 485 // => Float64Cmp |
469 VisitFloat64Cmp(node); | 486 VisitFloat64Cmp(node); |
470 if (lower()) node->set_op(Float64Op(node)); | 487 if (lower()) node->set_op(Float64Op(node)); |
471 } | 488 } |
472 break; | 489 break; |
473 } | 490 } |
474 case IrOpcode::kNumberAdd: | 491 case IrOpcode::kNumberAdd: |
475 case IrOpcode::kNumberSubtract: { | 492 case IrOpcode::kNumberSubtract: { |
476 // Add and subtract reduce to Int32Add/Sub if the inputs | 493 // Add and subtract reduce to Int32Add/Sub if the inputs |
477 // are already integers and all uses are truncating. | 494 // are already integers and all uses are truncating. |
478 if (BothInputsAre(node, Type::Signed32()) && | 495 if (CanBeInt32Binop(node, use)) { |
479 (use & (kTypeUint32 | kTypeNumber | kTypeAny)) == 0) { | |
480 // => signed Int32Add/Sub | 496 // => signed Int32Add/Sub |
481 VisitInt32Binop(node); | 497 VisitInt32Binop(node); |
482 if (lower()) node->set_op(Int32Op(node)); | 498 if (lower()) node->set_op(Int32Op(node)); |
483 } else if (BothInputsAre(node, Type::Unsigned32()) && | 499 } else if (CanBeUint32Binop(node, use)) { |
484 (use & (kTypeInt32 | kTypeNumber | kTypeAny)) == 0) { | |
485 // => unsigned Int32Add/Sub | 500 // => unsigned Int32Add/Sub |
486 VisitUint32Binop(node); | 501 VisitUint32Binop(node); |
487 if (lower()) node->set_op(Uint32Op(node)); | 502 if (lower()) node->set_op(Uint32Op(node)); |
488 } else { | 503 } else { |
489 // => Float64Add/Sub | 504 // => Float64Add/Sub |
490 VisitFloat64Binop(node); | 505 VisitFloat64Binop(node); |
491 if (lower()) node->set_op(Float64Op(node)); | 506 if (lower()) node->set_op(Float64Op(node)); |
492 } | 507 } |
493 break; | 508 break; |
494 } | 509 } |
495 case IrOpcode::kNumberMultiply: | 510 case IrOpcode::kNumberMultiply: { |
496 case IrOpcode::kNumberDivide: | 511 NumberMatcher right(node->InputAt(1)); |
497 case IrOpcode::kNumberModulus: { | 512 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. |
498 // Float64Mul/Div/Mod | 513 if (CanBeInt32Binop(node, use)) { |
514 // => signed Int32Mul | |
515 VisitInt32Binop(node); | |
516 if (lower()) node->set_op(Int32Op(node)); | |
517 break; | |
518 } | |
519 } | |
520 // => Float64Mul | |
499 VisitFloat64Binop(node); | 521 VisitFloat64Binop(node); |
500 if (lower()) node->set_op(Float64Op(node)); | 522 if (lower()) node->set_op(Float64Op(node)); |
501 break; | 523 break; |
524 } | |
525 case IrOpcode::kNumberDivide: { | |
526 NumberMatcher right(node->InputAt(1)); | |
527 if (right.HasValue() && !right.Is(0) && !right.Is(-1)) { | |
528 if (CanBeInt32Binop(node, use)) { | |
529 // => signed Int32Div | |
530 VisitInt32Binop(node); | |
531 if (lower()) node->set_op(Int32Op(node)); | |
532 break; | |
533 } else if (CanBeUint32Binop(node, use)) { | |
534 // => unsigned Uint32Div | |
535 VisitUint32Binop(node); | |
536 if (lower()) node->set_op(Uint32Op(node)); | |
537 break; | |
538 } | |
539 } | |
540 // => Float64Div | |
541 VisitFloat64Binop(node); | |
542 if (lower()) node->set_op(Float64Op(node)); | |
543 break; | |
544 } | |
545 case IrOpcode::kNumberModulus: { | |
546 NumberMatcher right(node->InputAt(1)); | |
547 if (right.HasValue() && !right.Is(0) && !right.Is(-1)) { | |
548 if (BothInputsAre(node, Type::Signed32())) { | |
549 // => signed Int32Mod | |
550 VisitInt32Binop(node); | |
551 if (lower()) node->set_op(Int32Op(node)); | |
552 break; | |
553 } else if (BothInputsAre(node, Type::Unsigned32())) { | |
554 // => unsigned Uint32Mod | |
555 VisitUint32Binop(node); | |
556 if (lower()) node->set_op(Uint32Op(node)); | |
557 break; | |
558 } | |
559 } | |
560 // => Float64Mod | |
561 VisitFloat64Binop(node); | |
562 if (lower()) node->set_op(Float64Op(node)); | |
563 break; | |
502 } | 564 } |
503 case IrOpcode::kNumberToInt32: { | 565 case IrOpcode::kNumberToInt32: { |
504 MachineTypeUnion use_rep = use & kRepMask; | 566 MachineTypeUnion use_rep = use & kRepMask; |
505 if (lower()) { | 567 if (lower()) { |
506 MachineTypeUnion in = GetInfo(node->InputAt(0))->output; | 568 MachineTypeUnion in = GetInfo(node->InputAt(0))->output; |
507 if ((in & kTypeMask) == kTypeInt32 || (in & kRepMask) == kRepWord32) { | 569 if ((in & kTypeMask) == kTypeInt32 || (in & kRepMask) == kRepWord32) { |
508 // If the input has type int32, or is already a word32, just change | 570 // If the input has type int32, or is already a word32, just change |
509 // representation if necessary. | 571 // representation if necessary. |
510 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); | 572 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); |
511 DeferReplacement(node, node->InputAt(0)); | 573 DeferReplacement(node, node->InputAt(0)); |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
968 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { | 1030 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { |
969 node->set_op(machine()->IntLessThanOrEqual()); | 1031 node->set_op(machine()->IntLessThanOrEqual()); |
970 node->ReplaceInput(0, StringComparison(node, true)); | 1032 node->ReplaceInput(0, StringComparison(node, true)); |
971 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1033 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
972 } | 1034 } |
973 | 1035 |
974 | 1036 |
975 } // namespace compiler | 1037 } // namespace compiler |
976 } // namespace internal | 1038 } // namespace internal |
977 } // namespace v8 | 1039 } // namespace v8 |
OLD | NEW |