Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(398)

Side by Side Diff: src/compiler/machine-operator-reducer.cc

Issue 1366753003: [turbofan] Make Node::set_op safer via wrapper. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments. Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-typed-lowering.cc ('k') | src/compiler/node.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/machine-operator-reducer.h" 5 #include "src/compiler/machine-operator-reducer.h"
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/division-by-constant.h" 8 #include "src/base/division-by-constant.h"
9 #include "src/codegen.h" 9 #include "src/codegen.h"
10 #include "src/compiler/diamond.h" 10 #include "src/compiler/diamond.h"
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 case IrOpcode::kInt32Sub: 206 case IrOpcode::kInt32Sub:
207 return ReduceInt32Sub(node); 207 return ReduceInt32Sub(node);
208 case IrOpcode::kInt32Mul: { 208 case IrOpcode::kInt32Mul: {
209 Int32BinopMatcher m(node); 209 Int32BinopMatcher m(node);
210 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0 210 if (m.right().Is(0)) return Replace(m.right().node()); // x * 0 => 0
211 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x 211 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1 => x
212 if (m.IsFoldable()) { // K * K => K 212 if (m.IsFoldable()) { // K * K => K
213 return ReplaceInt32(m.left().Value() * m.right().Value()); 213 return ReplaceInt32(m.left().Value() * m.right().Value());
214 } 214 }
215 if (m.right().Is(-1)) { // x * -1 => 0 - x 215 if (m.right().Is(-1)) { // x * -1 => 0 - x
216 node->set_op(machine()->Int32Sub());
217 node->ReplaceInput(0, Int32Constant(0)); 216 node->ReplaceInput(0, Int32Constant(0));
218 node->ReplaceInput(1, m.left().node()); 217 node->ReplaceInput(1, m.left().node());
218 NodeProperties::ChangeOp(node, machine()->Int32Sub());
219 return Changed(node); 219 return Changed(node);
220 } 220 }
221 if (m.right().IsPowerOf2()) { // x * 2^n => x << n 221 if (m.right().IsPowerOf2()) { // x * 2^n => x << n
222 node->set_op(machine()->Word32Shl());
223 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value()))); 222 node->ReplaceInput(1, Int32Constant(WhichPowerOf2(m.right().Value())));
223 NodeProperties::ChangeOp(node, machine()->Word32Shl());
224 Reduction reduction = ReduceWord32Shl(node); 224 Reduction reduction = ReduceWord32Shl(node);
225 return reduction.Changed() ? reduction : Changed(node); 225 return reduction.Changed() ? reduction : Changed(node);
226 } 226 }
227 break; 227 break;
228 } 228 }
229 case IrOpcode::kInt32Div: 229 case IrOpcode::kInt32Div:
230 return ReduceInt32Div(node); 230 return ReduceInt32Div(node);
231 case IrOpcode::kUint32Div: 231 case IrOpcode::kUint32Div:
232 return ReduceUint32Div(node); 232 return ReduceUint32Div(node);
233 case IrOpcode::kInt32Mod: 233 case IrOpcode::kInt32Mod:
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
331 return Replace(m.left().node()); 331 return Replace(m.left().node());
332 } 332 }
333 if (m.IsFoldable()) { // K - K => K 333 if (m.IsFoldable()) { // K - K => K
334 return ReplaceFloat64(m.left().Value() - m.right().Value()); 334 return ReplaceFloat64(m.left().Value() - m.right().Value());
335 } 335 }
336 break; 336 break;
337 } 337 }
338 case IrOpcode::kFloat64Mul: { 338 case IrOpcode::kFloat64Mul: {
339 Float64BinopMatcher m(node); 339 Float64BinopMatcher m(node);
340 if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x 340 if (m.right().Is(-1)) { // x * -1.0 => -0.0 - x
341 node->set_op(machine()->Float64Sub());
342 node->ReplaceInput(0, Float64Constant(-0.0)); 341 node->ReplaceInput(0, Float64Constant(-0.0));
343 node->ReplaceInput(1, m.left().node()); 342 node->ReplaceInput(1, m.left().node());
343 NodeProperties::ChangeOp(node, machine()->Float64Sub());
344 return Changed(node); 344 return Changed(node);
345 } 345 }
346 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1.0 => x 346 if (m.right().Is(1)) return Replace(m.left().node()); // x * 1.0 => x
347 if (m.right().IsNaN()) { // x * NaN => NaN 347 if (m.right().IsNaN()) { // x * NaN => NaN
348 return Replace(m.right().node()); 348 return Replace(m.right().node());
349 } 349 }
350 if (m.IsFoldable()) { // K * K => K 350 if (m.IsFoldable()) { // K * K => K
351 return ReplaceFloat64(m.left().Value() * m.right().Value()); 351 return ReplaceFloat64(m.left().Value() * m.right().Value());
352 } 352 }
353 break; 353 break;
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 DCHECK_EQ(IrOpcode::kInt32Add, node->opcode()); 454 DCHECK_EQ(IrOpcode::kInt32Add, node->opcode());
455 Int32BinopMatcher m(node); 455 Int32BinopMatcher m(node);
456 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x 456 if (m.right().Is(0)) return Replace(m.left().node()); // x + 0 => x
457 if (m.IsFoldable()) { // K + K => K 457 if (m.IsFoldable()) { // K + K => K
458 return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) + 458 return ReplaceUint32(bit_cast<uint32_t>(m.left().Value()) +
459 bit_cast<uint32_t>(m.right().Value())); 459 bit_cast<uint32_t>(m.right().Value()));
460 } 460 }
461 if (m.left().IsInt32Sub()) { 461 if (m.left().IsInt32Sub()) {
462 Int32BinopMatcher mleft(m.left().node()); 462 Int32BinopMatcher mleft(m.left().node());
463 if (mleft.left().Is(0)) { // (0 - x) + y => y - x 463 if (mleft.left().Is(0)) { // (0 - x) + y => y - x
464 node->set_op(machine()->Int32Sub());
465 node->ReplaceInput(0, m.right().node()); 464 node->ReplaceInput(0, m.right().node());
466 node->ReplaceInput(1, mleft.right().node()); 465 node->ReplaceInput(1, mleft.right().node());
466 NodeProperties::ChangeOp(node, machine()->Int32Sub());
467 Reduction const reduction = ReduceInt32Sub(node); 467 Reduction const reduction = ReduceInt32Sub(node);
468 return reduction.Changed() ? reduction : Changed(node); 468 return reduction.Changed() ? reduction : Changed(node);
469 } 469 }
470 } 470 }
471 if (m.right().IsInt32Sub()) { 471 if (m.right().IsInt32Sub()) {
472 Int32BinopMatcher mright(m.right().node()); 472 Int32BinopMatcher mright(m.right().node());
473 if (mright.left().Is(0)) { // y + (0 - x) => y - x 473 if (mright.left().Is(0)) { // y + (0 - x) => y - x
474 node->set_op(machine()->Int32Sub());
475 node->ReplaceInput(1, mright.right().node()); 474 node->ReplaceInput(1, mright.right().node());
475 NodeProperties::ChangeOp(node, machine()->Int32Sub());
476 Reduction const reduction = ReduceInt32Sub(node); 476 Reduction const reduction = ReduceInt32Sub(node);
477 return reduction.Changed() ? reduction : Changed(node); 477 return reduction.Changed() ? reduction : Changed(node);
478 } 478 }
479 } 479 }
480 return NoChange(); 480 return NoChange();
481 } 481 }
482 482
483 483
484 Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) { 484 Reduction MachineOperatorReducer::ReduceInt32Sub(Node* node) {
485 DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode()); 485 DCHECK_EQ(IrOpcode::kInt32Sub, node->opcode());
486 Int32BinopMatcher m(node); 486 Int32BinopMatcher m(node);
487 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x 487 if (m.right().Is(0)) return Replace(m.left().node()); // x - 0 => x
488 if (m.IsFoldable()) { // K - K => K 488 if (m.IsFoldable()) { // K - K => K
489 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) - 489 return ReplaceInt32(static_cast<uint32_t>(m.left().Value()) -
490 static_cast<uint32_t>(m.right().Value())); 490 static_cast<uint32_t>(m.right().Value()));
491 } 491 }
492 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0 492 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x - x => 0
493 if (m.right().HasValue()) { // x - K => x + -K 493 if (m.right().HasValue()) { // x - K => x + -K
494 node->set_op(machine()->Int32Add());
495 node->ReplaceInput(1, Int32Constant(-m.right().Value())); 494 node->ReplaceInput(1, Int32Constant(-m.right().Value()));
495 NodeProperties::ChangeOp(node, machine()->Int32Add());
496 Reduction const reduction = ReduceInt32Add(node); 496 Reduction const reduction = ReduceInt32Add(node);
497 return reduction.Changed() ? reduction : Changed(node); 497 return reduction.Changed() ? reduction : Changed(node);
498 } 498 }
499 return NoChange(); 499 return NoChange();
500 } 500 }
501 501
502 502
503 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) { 503 Reduction MachineOperatorReducer::ReduceInt32Div(Node* node) {
504 Int32BinopMatcher m(node); 504 Int32BinopMatcher m(node);
505 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 505 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
506 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 506 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0
507 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x 507 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
508 if (m.IsFoldable()) { // K / K => K 508 if (m.IsFoldable()) { // K / K => K
509 return ReplaceInt32( 509 return ReplaceInt32(
510 base::bits::SignedDiv32(m.left().Value(), m.right().Value())); 510 base::bits::SignedDiv32(m.left().Value(), m.right().Value()));
511 } 511 }
512 if (m.LeftEqualsRight()) { // x / x => x != 0 512 if (m.LeftEqualsRight()) { // x / x => x != 0
513 Node* const zero = Int32Constant(0); 513 Node* const zero = Int32Constant(0);
514 return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero)); 514 return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
515 } 515 }
516 if (m.right().Is(-1)) { // x / -1 => 0 - x 516 if (m.right().Is(-1)) { // x / -1 => 0 - x
517 node->set_op(machine()->Int32Sub());
518 node->ReplaceInput(0, Int32Constant(0)); 517 node->ReplaceInput(0, Int32Constant(0));
519 node->ReplaceInput(1, m.left().node()); 518 node->ReplaceInput(1, m.left().node());
520 node->TrimInputCount(2); 519 node->TrimInputCount(2);
520 NodeProperties::ChangeOp(node, machine()->Int32Sub());
521 return Changed(node); 521 return Changed(node);
522 } 522 }
523 if (m.right().HasValue()) { 523 if (m.right().HasValue()) {
524 int32_t const divisor = m.right().Value(); 524 int32_t const divisor = m.right().Value();
525 Node* const dividend = m.left().node(); 525 Node* const dividend = m.left().node();
526 Node* quotient = dividend; 526 Node* quotient = dividend;
527 if (base::bits::IsPowerOfTwo32(Abs(divisor))) { 527 if (base::bits::IsPowerOfTwo32(Abs(divisor))) {
528 uint32_t const shift = WhichPowerOf2Abs(divisor); 528 uint32_t const shift = WhichPowerOf2Abs(divisor);
529 DCHECK_NE(0u, shift); 529 DCHECK_NE(0u, shift);
530 if (shift > 1) { 530 if (shift > 1) {
531 quotient = Word32Sar(quotient, 31); 531 quotient = Word32Sar(quotient, 31);
532 } 532 }
533 quotient = Int32Add(Word32Shr(quotient, 32u - shift), dividend); 533 quotient = Int32Add(Word32Shr(quotient, 32u - shift), dividend);
534 quotient = Word32Sar(quotient, shift); 534 quotient = Word32Sar(quotient, shift);
535 } else { 535 } else {
536 quotient = Int32Div(quotient, Abs(divisor)); 536 quotient = Int32Div(quotient, Abs(divisor));
537 } 537 }
538 if (divisor < 0) { 538 if (divisor < 0) {
539 node->set_op(machine()->Int32Sub());
540 node->ReplaceInput(0, Int32Constant(0)); 539 node->ReplaceInput(0, Int32Constant(0));
541 node->ReplaceInput(1, quotient); 540 node->ReplaceInput(1, quotient);
542 node->TrimInputCount(2); 541 node->TrimInputCount(2);
542 NodeProperties::ChangeOp(node, machine()->Int32Sub());
543 return Changed(node); 543 return Changed(node);
544 } 544 }
545 return Replace(quotient); 545 return Replace(quotient);
546 } 546 }
547 return NoChange(); 547 return NoChange();
548 } 548 }
549 549
550 550
551 Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) { 551 Reduction MachineOperatorReducer::ReduceUint32Div(Node* node) {
552 Uint32BinopMatcher m(node); 552 Uint32BinopMatcher m(node);
553 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0 553 if (m.left().Is(0)) return Replace(m.left().node()); // 0 / x => 0
554 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0 554 if (m.right().Is(0)) return Replace(m.right().node()); // x / 0 => 0
555 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x 555 if (m.right().Is(1)) return Replace(m.left().node()); // x / 1 => x
556 if (m.IsFoldable()) { // K / K => K 556 if (m.IsFoldable()) { // K / K => K
557 return ReplaceUint32( 557 return ReplaceUint32(
558 base::bits::UnsignedDiv32(m.left().Value(), m.right().Value())); 558 base::bits::UnsignedDiv32(m.left().Value(), m.right().Value()));
559 } 559 }
560 if (m.LeftEqualsRight()) { // x / x => x != 0 560 if (m.LeftEqualsRight()) { // x / x => x != 0
561 Node* const zero = Int32Constant(0); 561 Node* const zero = Int32Constant(0);
562 return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero)); 562 return Replace(Word32Equal(Word32Equal(m.left().node(), zero), zero));
563 } 563 }
564 if (m.right().HasValue()) { 564 if (m.right().HasValue()) {
565 Node* const dividend = m.left().node(); 565 Node* const dividend = m.left().node();
566 uint32_t const divisor = m.right().Value(); 566 uint32_t const divisor = m.right().Value();
567 if (base::bits::IsPowerOfTwo32(divisor)) { // x / 2^n => x >> n 567 if (base::bits::IsPowerOfTwo32(divisor)) { // x / 2^n => x >> n
568 node->set_op(machine()->Word32Shr());
569 node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value()))); 568 node->ReplaceInput(1, Uint32Constant(WhichPowerOf2(m.right().Value())));
570 node->TrimInputCount(2); 569 node->TrimInputCount(2);
570 NodeProperties::ChangeOp(node, machine()->Word32Shr());
571 return Changed(node); 571 return Changed(node);
572 } else { 572 } else {
573 return Replace(Uint32Div(dividend, divisor)); 573 return Replace(Uint32Div(dividend, divisor));
574 } 574 }
575 } 575 }
576 return NoChange(); 576 return NoChange();
577 } 577 }
578 578
579 579
580 Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) { 580 Reduction MachineOperatorReducer::ReduceInt32Mod(Node* node) {
581 Int32BinopMatcher m(node); 581 Int32BinopMatcher m(node);
582 if (m.left().Is(0)) return Replace(m.left().node()); // 0 % x => 0 582 if (m.left().Is(0)) return Replace(m.left().node()); // 0 % x => 0
583 if (m.right().Is(0)) return Replace(m.right().node()); // x % 0 => 0 583 if (m.right().Is(0)) return Replace(m.right().node()); // x % 0 => 0
584 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0 584 if (m.right().Is(1)) return ReplaceInt32(0); // x % 1 => 0
585 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0 585 if (m.right().Is(-1)) return ReplaceInt32(0); // x % -1 => 0
586 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x % x => 0 586 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x % x => 0
587 if (m.IsFoldable()) { // K % K => K 587 if (m.IsFoldable()) { // K % K => K
588 return ReplaceInt32( 588 return ReplaceInt32(
589 base::bits::SignedMod32(m.left().Value(), m.right().Value())); 589 base::bits::SignedMod32(m.left().Value(), m.right().Value()));
590 } 590 }
591 if (m.right().HasValue()) { 591 if (m.right().HasValue()) {
592 Node* const dividend = m.left().node(); 592 Node* const dividend = m.left().node();
593 int32_t const divisor = Abs(m.right().Value()); 593 int32_t const divisor = Abs(m.right().Value());
594 if (base::bits::IsPowerOfTwo32(divisor)) { 594 if (base::bits::IsPowerOfTwo32(divisor)) {
595 uint32_t const mask = divisor - 1; 595 uint32_t const mask = divisor - 1;
596 Node* const zero = Int32Constant(0); 596 Node* const zero = Int32Constant(0);
597 node->set_op(common()->Select(kMachInt32, BranchHint::kFalse));
598 node->ReplaceInput( 597 node->ReplaceInput(
599 0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero)); 598 0, graph()->NewNode(machine()->Int32LessThan(), dividend, zero));
600 node->ReplaceInput( 599 node->ReplaceInput(
601 1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask))); 600 1, Int32Sub(zero, Word32And(Int32Sub(zero, dividend), mask)));
602 node->ReplaceInput(2, Word32And(dividend, mask)); 601 node->ReplaceInput(2, Word32And(dividend, mask));
602 NodeProperties::ChangeOp(
603 node, common()->Select(kMachInt32, BranchHint::kFalse));
603 } else { 604 } else {
604 Node* quotient = Int32Div(dividend, divisor); 605 Node* quotient = Int32Div(dividend, divisor);
605 node->set_op(machine()->Int32Sub());
606 DCHECK_EQ(dividend, node->InputAt(0)); 606 DCHECK_EQ(dividend, node->InputAt(0));
607 node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor))); 607 node->ReplaceInput(1, Int32Mul(quotient, Int32Constant(divisor)));
608 node->TrimInputCount(2); 608 node->TrimInputCount(2);
609 NodeProperties::ChangeOp(node, machine()->Int32Sub());
609 } 610 }
610 return Changed(node); 611 return Changed(node);
611 } 612 }
612 return NoChange(); 613 return NoChange();
613 } 614 }
614 615
615 616
616 Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) { 617 Reduction MachineOperatorReducer::ReduceUint32Mod(Node* node) {
617 Uint32BinopMatcher m(node); 618 Uint32BinopMatcher m(node);
618 if (m.left().Is(0)) return Replace(m.left().node()); // 0 % x => 0 619 if (m.left().Is(0)) return Replace(m.left().node()); // 0 % x => 0
619 if (m.right().Is(0)) return Replace(m.right().node()); // x % 0 => 0 620 if (m.right().Is(0)) return Replace(m.right().node()); // x % 0 => 0
620 if (m.right().Is(1)) return ReplaceUint32(0); // x % 1 => 0 621 if (m.right().Is(1)) return ReplaceUint32(0); // x % 1 => 0
621 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x % x => 0 622 if (m.LeftEqualsRight()) return ReplaceInt32(0); // x % x => 0
622 if (m.IsFoldable()) { // K % K => K 623 if (m.IsFoldable()) { // K % K => K
623 return ReplaceUint32( 624 return ReplaceUint32(
624 base::bits::UnsignedMod32(m.left().Value(), m.right().Value())); 625 base::bits::UnsignedMod32(m.left().Value(), m.right().Value()));
625 } 626 }
626 if (m.right().HasValue()) { 627 if (m.right().HasValue()) {
627 Node* const dividend = m.left().node(); 628 Node* const dividend = m.left().node();
628 uint32_t const divisor = m.right().Value(); 629 uint32_t const divisor = m.right().Value();
629 if (base::bits::IsPowerOfTwo32(divisor)) { // x % 2^n => x & 2^n-1 630 if (base::bits::IsPowerOfTwo32(divisor)) { // x % 2^n => x & 2^n-1
630 node->set_op(machine()->Word32And());
631 node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1)); 631 node->ReplaceInput(1, Uint32Constant(m.right().Value() - 1));
632 node->TrimInputCount(2);
633 NodeProperties::ChangeOp(node, machine()->Word32And());
632 } else { 634 } else {
633 Node* quotient = Uint32Div(dividend, divisor); 635 Node* quotient = Uint32Div(dividend, divisor);
634 node->set_op(machine()->Int32Sub());
635 DCHECK_EQ(dividend, node->InputAt(0)); 636 DCHECK_EQ(dividend, node->InputAt(0));
636 node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor))); 637 node->ReplaceInput(1, Int32Mul(quotient, Uint32Constant(divisor)));
638 node->TrimInputCount(2);
639 NodeProperties::ChangeOp(node, machine()->Int32Sub());
637 } 640 }
638 node->TrimInputCount(2);
639 return Changed(node); 641 return Changed(node);
640 } 642 }
641 return NoChange(); 643 return NoChange();
642 } 644 }
643 645
644 646
645 Reduction MachineOperatorReducer::ReduceTruncateFloat64ToInt32(Node* node) { 647 Reduction MachineOperatorReducer::ReduceTruncateFloat64ToInt32(Node* node) {
646 Float64Matcher m(node->InputAt(0)); 648 Float64Matcher m(node->InputAt(0));
647 if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value())); 649 if (m.HasValue()) return ReplaceInt32(DoubleToInt32(m.Value()));
648 if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0)); 650 if (m.IsChangeInt32ToFloat64()) return Replace(m.node()->InputAt(0));
649 if (m.IsPhi()) { 651 if (m.IsPhi()) {
650 Node* const phi = m.node(); 652 Node* const phi = m.node();
651 DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi))); 653 DCHECK_EQ(kRepFloat64, RepresentationOf(OpParameter<MachineType>(phi)));
652 if (phi->OwnedBy(node)) { 654 if (phi->OwnedBy(node)) {
653 // TruncateFloat64ToInt32[mode](Phi[Float64](x1,...,xn)) 655 // TruncateFloat64ToInt32[mode](Phi[Float64](x1,...,xn))
654 // => Phi[Int32](TruncateFloat64ToInt32[mode](x1), 656 // => Phi[Int32](TruncateFloat64ToInt32[mode](x1),
655 // ..., 657 // ...,
656 // TruncateFloat64ToInt32[mode](xn)) 658 // TruncateFloat64ToInt32[mode](xn))
657 const int value_input_count = phi->InputCount() - 1; 659 const int value_input_count = phi->InputCount() - 1;
658 for (int i = 0; i < value_input_count; ++i) { 660 for (int i = 0; i < value_input_count; ++i) {
659 Node* input = graph()->NewNode(node->op(), phi->InputAt(i)); 661 Node* input = graph()->NewNode(node->op(), phi->InputAt(i));
660 // TODO(bmeurer): Reschedule input for reduction once we have Revisit() 662 // TODO(bmeurer): Reschedule input for reduction once we have Revisit()
661 // instead of recursing into ReduceTruncateFloat64ToInt32() here. 663 // instead of recursing into ReduceTruncateFloat64ToInt32() here.
662 Reduction reduction = ReduceTruncateFloat64ToInt32(input); 664 Reduction reduction = ReduceTruncateFloat64ToInt32(input);
663 if (reduction.Changed()) input = reduction.replacement(); 665 if (reduction.Changed()) input = reduction.replacement();
664 phi->ReplaceInput(i, input); 666 phi->ReplaceInput(i, input);
665 } 667 }
666 phi->set_op(common()->Phi(kMachInt32, value_input_count)); 668 NodeProperties::ChangeOp(phi,
669 common()->Phi(kMachInt32, value_input_count));
667 return Replace(phi); 670 return Replace(phi);
668 } 671 }
669 } 672 }
670 return NoChange(); 673 return NoChange();
671 } 674 }
672 675
673 676
674 Reduction MachineOperatorReducer::ReduceStore(Node* node) { 677 Reduction MachineOperatorReducer::ReduceStore(Node* node) {
675 MachineType const rep = 678 MachineType const rep =
676 RepresentationOf(StoreRepresentationOf(node->op()).machine_type()); 679 RepresentationOf(StoreRepresentationOf(node->op()).machine_type());
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
769 if (m.right().Is(0)) return Replace(m.left().node()); // x << 0 => x 772 if (m.right().Is(0)) return Replace(m.left().node()); // x << 0 => x
770 if (m.IsFoldable()) { // K << K => K 773 if (m.IsFoldable()) { // K << K => K
771 return ReplaceInt32(m.left().Value() << m.right().Value()); 774 return ReplaceInt32(m.left().Value() << m.right().Value());
772 } 775 }
773 if (m.right().IsInRange(1, 31)) { 776 if (m.right().IsInRange(1, 31)) {
774 // (x >>> K) << K => x & ~(2^K - 1) 777 // (x >>> K) << K => x & ~(2^K - 1)
775 // (x >> K) << K => x & ~(2^K - 1) 778 // (x >> K) << K => x & ~(2^K - 1)
776 if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) { 779 if (m.left().IsWord32Sar() || m.left().IsWord32Shr()) {
777 Int32BinopMatcher mleft(m.left().node()); 780 Int32BinopMatcher mleft(m.left().node());
778 if (mleft.right().Is(m.right().Value())) { 781 if (mleft.right().Is(m.right().Value())) {
779 node->set_op(machine()->Word32And());
780 node->ReplaceInput(0, mleft.left().node()); 782 node->ReplaceInput(0, mleft.left().node());
781 node->ReplaceInput(1, 783 node->ReplaceInput(1,
782 Uint32Constant(~((1U << m.right().Value()) - 1U))); 784 Uint32Constant(~((1U << m.right().Value()) - 1U)));
785 NodeProperties::ChangeOp(node, machine()->Word32And());
783 Reduction reduction = ReduceWord32And(node); 786 Reduction reduction = ReduceWord32And(node);
784 return reduction.Changed() ? reduction : Changed(node); 787 return reduction.Changed() ? reduction : Changed(node);
785 } 788 }
786 } 789 }
787 } 790 }
788 return ReduceWord32Shifts(node); 791 return ReduceWord32Shifts(node);
789 } 792 }
790 793
791 794
792 Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) { 795 Reduction MachineOperatorReducer::ReduceWord32Sar(Node* node) {
793 Int32BinopMatcher m(node); 796 Int32BinopMatcher m(node);
794 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x 797 if (m.right().Is(0)) return Replace(m.left().node()); // x >> 0 => x
795 if (m.IsFoldable()) { // K >> K => K 798 if (m.IsFoldable()) { // K >> K => K
796 return ReplaceInt32(m.left().Value() >> m.right().Value()); 799 return ReplaceInt32(m.left().Value() >> m.right().Value());
797 } 800 }
798 if (m.left().IsWord32Shl()) { 801 if (m.left().IsWord32Shl()) {
799 Int32BinopMatcher mleft(m.left().node()); 802 Int32BinopMatcher mleft(m.left().node());
800 if (mleft.left().IsComparison()) { 803 if (mleft.left().IsComparison()) {
801 if (m.right().Is(31) && mleft.right().Is(31)) { 804 if (m.right().Is(31) && mleft.right().Is(31)) {
802 // Comparison << 31 >> 31 => 0 - Comparison 805 // Comparison << 31 >> 31 => 0 - Comparison
803 node->set_op(machine()->Int32Sub());
804 node->ReplaceInput(0, Int32Constant(0)); 806 node->ReplaceInput(0, Int32Constant(0));
805 node->ReplaceInput(1, mleft.left().node()); 807 node->ReplaceInput(1, mleft.left().node());
808 NodeProperties::ChangeOp(node, machine()->Int32Sub());
806 Reduction const reduction = ReduceInt32Sub(node); 809 Reduction const reduction = ReduceInt32Sub(node);
807 return reduction.Changed() ? reduction : Changed(node); 810 return reduction.Changed() ? reduction : Changed(node);
808 } 811 }
809 } else if (mleft.left().IsLoad()) { 812 } else if (mleft.left().IsLoad()) {
810 LoadRepresentation const rep = 813 LoadRepresentation const rep =
811 OpParameter<LoadRepresentation>(mleft.left().node()); 814 OpParameter<LoadRepresentation>(mleft.left().node());
812 if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) { 815 if (m.right().Is(24) && mleft.right().Is(24) && rep == kMachInt8) {
813 // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8] 816 // Load[kMachInt8] << 24 >> 24 => Load[kMachInt8]
814 return Replace(mleft.left().node()); 817 return Replace(mleft.left().node());
815 } 818 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 if (mleft.right().HasValue() && 855 if (mleft.right().HasValue() &&
853 mleft.right().Value() >= base::bits::CountTrailingZeros32(mask)) { 856 mleft.right().Value() >= base::bits::CountTrailingZeros32(mask)) {
854 // (x << L) & (-1 << K) => x << L iff K >= L 857 // (x << L) & (-1 << K) => x << L iff K >= L
855 return Replace(mleft.node()); 858 return Replace(mleft.node());
856 } 859 }
857 } else if (m.left().IsInt32Add()) { 860 } else if (m.left().IsInt32Add()) {
858 Int32BinopMatcher mleft(m.left().node()); 861 Int32BinopMatcher mleft(m.left().node());
859 if (mleft.right().HasValue() && 862 if (mleft.right().HasValue() &&
860 (mleft.right().Value() & mask) == mleft.right().Value()) { 863 (mleft.right().Value() & mask) == mleft.right().Value()) {
861 // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L) 864 // (x + (K << L)) & (-1 << L) => (x & (-1 << L)) + (K << L)
862 node->set_op(machine()->Int32Add());
863 node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node())); 865 node->ReplaceInput(0, Word32And(mleft.left().node(), m.right().node()));
864 node->ReplaceInput(1, mleft.right().node()); 866 node->ReplaceInput(1, mleft.right().node());
867 NodeProperties::ChangeOp(node, machine()->Int32Add());
865 Reduction const reduction = ReduceInt32Add(node); 868 Reduction const reduction = ReduceInt32Add(node);
866 return reduction.Changed() ? reduction : Changed(node); 869 return reduction.Changed() ? reduction : Changed(node);
867 } 870 }
868 if (mleft.left().IsInt32Mul()) { 871 if (mleft.left().IsInt32Mul()) {
869 Int32BinopMatcher mleftleft(mleft.left().node()); 872 Int32BinopMatcher mleftleft(mleft.left().node());
870 if (mleftleft.right().IsMultipleOf(-mask)) { 873 if (mleftleft.right().IsMultipleOf(-mask)) {
871 // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L) 874 // (y * (K << L) + x) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
872 node->set_op(machine()->Int32Add());
873 node->ReplaceInput(0, 875 node->ReplaceInput(0,
874 Word32And(mleft.right().node(), m.right().node())); 876 Word32And(mleft.right().node(), m.right().node()));
875 node->ReplaceInput(1, mleftleft.node()); 877 node->ReplaceInput(1, mleftleft.node());
878 NodeProperties::ChangeOp(node, machine()->Int32Add());
876 Reduction const reduction = ReduceInt32Add(node); 879 Reduction const reduction = ReduceInt32Add(node);
877 return reduction.Changed() ? reduction : Changed(node); 880 return reduction.Changed() ? reduction : Changed(node);
878 } 881 }
879 } 882 }
880 if (mleft.right().IsInt32Mul()) { 883 if (mleft.right().IsInt32Mul()) {
881 Int32BinopMatcher mleftright(mleft.right().node()); 884 Int32BinopMatcher mleftright(mleft.right().node());
882 if (mleftright.right().IsMultipleOf(-mask)) { 885 if (mleftright.right().IsMultipleOf(-mask)) {
883 // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L) 886 // (x + y * (K << L)) & (-1 << L) => (x & (-1 << L)) + y * (K << L)
884 node->set_op(machine()->Int32Add());
885 node->ReplaceInput(0, 887 node->ReplaceInput(0,
886 Word32And(mleft.left().node(), m.right().node())); 888 Word32And(mleft.left().node(), m.right().node()));
887 node->ReplaceInput(1, mleftright.node()); 889 node->ReplaceInput(1, mleftright.node());
890 NodeProperties::ChangeOp(node, machine()->Int32Add());
888 Reduction const reduction = ReduceInt32Add(node); 891 Reduction const reduction = ReduceInt32Add(node);
889 return reduction.Changed() ? reduction : Changed(node); 892 return reduction.Changed() ? reduction : Changed(node);
890 } 893 }
891 } 894 }
892 if (mleft.left().IsWord32Shl()) { 895 if (mleft.left().IsWord32Shl()) {
893 Int32BinopMatcher mleftleft(mleft.left().node()); 896 Int32BinopMatcher mleftleft(mleft.left().node());
894 if (mleftleft.right().Is(base::bits::CountTrailingZeros32(mask))) { 897 if (mleftleft.right().Is(base::bits::CountTrailingZeros32(mask))) {
895 // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L 898 // (y << L + x) & (-1 << L) => (x & (-1 << L)) + y << L
896 node->set_op(machine()->Int32Add());
897 node->ReplaceInput(0, 899 node->ReplaceInput(0,
898 Word32And(mleft.right().node(), m.right().node())); 900 Word32And(mleft.right().node(), m.right().node()));
899 node->ReplaceInput(1, mleftleft.node()); 901 node->ReplaceInput(1, mleftleft.node());
902 NodeProperties::ChangeOp(node, machine()->Int32Add());
900 Reduction const reduction = ReduceInt32Add(node); 903 Reduction const reduction = ReduceInt32Add(node);
901 return reduction.Changed() ? reduction : Changed(node); 904 return reduction.Changed() ? reduction : Changed(node);
902 } 905 }
903 } 906 }
904 if (mleft.right().IsWord32Shl()) { 907 if (mleft.right().IsWord32Shl()) {
905 Int32BinopMatcher mleftright(mleft.right().node()); 908 Int32BinopMatcher mleftright(mleft.right().node());
906 if (mleftright.right().Is(base::bits::CountTrailingZeros32(mask))) { 909 if (mleftright.right().Is(base::bits::CountTrailingZeros32(mask))) {
907 // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L 910 // (x + y << L) & (-1 << L) => (x & (-1 << L)) + y << L
908 node->set_op(machine()->Int32Add());
909 node->ReplaceInput(0, 911 node->ReplaceInput(0,
910 Word32And(mleft.left().node(), m.right().node())); 912 Word32And(mleft.left().node(), m.right().node()));
911 node->ReplaceInput(1, mleftright.node()); 913 node->ReplaceInput(1, mleftright.node());
914 NodeProperties::ChangeOp(node, machine()->Int32Add());
912 Reduction const reduction = ReduceInt32Add(node); 915 Reduction const reduction = ReduceInt32Add(node);
913 return reduction.Changed() ? reduction : Changed(node); 916 return reduction.Changed() ? reduction : Changed(node);
914 } 917 }
915 } 918 }
916 } else if (m.left().IsInt32Mul()) { 919 } else if (m.left().IsInt32Mul()) {
917 Int32BinopMatcher mleft(m.left().node()); 920 Int32BinopMatcher mleft(m.left().node());
918 if (mleft.right().IsMultipleOf(-mask)) { 921 if (mleft.right().IsMultipleOf(-mask)) {
919 // (x * (K << L)) & (-1 << L) => x * (K << L) 922 // (x * (K << L)) & (-1 << L) => x * (K << L)
920 return Replace(mleft.node()); 923 return Replace(mleft.node());
921 } 924 }
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
968 sub = mshr.right().node(); 971 sub = mshr.right().node();
969 y = mshl.right().node(); 972 y = mshl.right().node();
970 } else { 973 } else {
971 return NoChange(); 974 return NoChange();
972 } 975 }
973 976
974 Int32BinopMatcher msub(sub); 977 Int32BinopMatcher msub(sub);
975 if (!msub.left().Is(32) || msub.right().node() != y) return NoChange(); 978 if (!msub.left().Is(32) || msub.right().node() != y) return NoChange();
976 } 979 }
977 980
978 node->set_op(machine()->Word32Ror());
979 node->ReplaceInput(0, mshl.left().node()); 981 node->ReplaceInput(0, mshl.left().node());
980 node->ReplaceInput(1, mshr.right().node()); 982 node->ReplaceInput(1, mshr.right().node());
983 NodeProperties::ChangeOp(node, machine()->Word32Ror());
981 return Changed(node); 984 return Changed(node);
982 } 985 }
983 986
984 987
985 Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) { 988 Reduction MachineOperatorReducer::ReduceFloat64InsertLowWord32(Node* node) {
986 DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode()); 989 DCHECK_EQ(IrOpcode::kFloat64InsertLowWord32, node->opcode());
987 Float64Matcher mlhs(node->InputAt(0)); 990 Float64Matcher mlhs(node->InputAt(0));
988 Uint32Matcher mrhs(node->InputAt(1)); 991 Uint32Matcher mrhs(node->InputAt(1));
989 if (mlhs.HasValue() && mrhs.HasValue()) { 992 if (mlhs.HasValue() && mrhs.HasValue()) {
990 return ReplaceFloat64(bit_cast<double>( 993 return ReplaceFloat64(bit_cast<double>(
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
1033 // represented exactly as Float32. 1036 // represented exactly as Float32.
1034 Float64BinopMatcher m(node); 1037 Float64BinopMatcher m(node);
1035 if ((m.left().IsChangeFloat32ToFloat64() && 1038 if ((m.left().IsChangeFloat32ToFloat64() &&
1036 m.right().IsChangeFloat32ToFloat64()) || 1039 m.right().IsChangeFloat32ToFloat64()) ||
1037 (m.left().IsChangeFloat32ToFloat64() && 1040 (m.left().IsChangeFloat32ToFloat64() &&
1038 IsFloat64RepresentableAsFloat32(m.right())) || 1041 IsFloat64RepresentableAsFloat32(m.right())) ||
1039 (IsFloat64RepresentableAsFloat32(m.left()) && 1042 (IsFloat64RepresentableAsFloat32(m.left()) &&
1040 m.right().IsChangeFloat32ToFloat64())) { 1043 m.right().IsChangeFloat32ToFloat64())) {
1041 switch (node->opcode()) { 1044 switch (node->opcode()) {
1042 case IrOpcode::kFloat64Equal: 1045 case IrOpcode::kFloat64Equal:
1043 node->set_op(machine()->Float32Equal()); 1046 NodeProperties::ChangeOp(node, machine()->Float32Equal());
1044 break; 1047 break;
1045 case IrOpcode::kFloat64LessThan: 1048 case IrOpcode::kFloat64LessThan:
1046 node->set_op(machine()->Float32LessThan()); 1049 NodeProperties::ChangeOp(node, machine()->Float32LessThan());
1047 break; 1050 break;
1048 case IrOpcode::kFloat64LessThanOrEqual: 1051 case IrOpcode::kFloat64LessThanOrEqual:
1049 node->set_op(machine()->Float32LessThanOrEqual()); 1052 NodeProperties::ChangeOp(node, machine()->Float32LessThanOrEqual());
1050 break; 1053 break;
1051 default: 1054 default:
1052 return NoChange(); 1055 return NoChange();
1053 } 1056 }
1054 node->ReplaceInput( 1057 node->ReplaceInput(
1055 0, m.left().HasValue() 1058 0, m.left().HasValue()
1056 ? Float32Constant(static_cast<float>(m.left().Value())) 1059 ? Float32Constant(static_cast<float>(m.left().Value()))
1057 : m.left().InputAt(0)); 1060 : m.left().InputAt(0));
1058 node->ReplaceInput( 1061 node->ReplaceInput(
1059 1, m.right().HasValue() 1062 1, m.right().HasValue()
(...skipping 13 matching lines...) Expand all
1073 MachineOperatorBuilder* MachineOperatorReducer::machine() const { 1076 MachineOperatorBuilder* MachineOperatorReducer::machine() const {
1074 return jsgraph()->machine(); 1077 return jsgraph()->machine();
1075 } 1078 }
1076 1079
1077 1080
1078 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); } 1081 Graph* MachineOperatorReducer::graph() const { return jsgraph()->graph(); }
1079 1082
1080 } // namespace compiler 1083 } // namespace compiler
1081 } // namespace internal 1084 } // namespace internal
1082 } // namespace v8 1085 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.cc ('k') | src/compiler/node.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698