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

Side by Side Diff: src/compiler/arm/instruction-selector-arm.cc

Issue 1684073006: Reland of [turbofan] ARM: Improve AND instruction selection (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 10 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 | « no previous file | test/unittests/compiler/arm/instruction-selector-arm-unittest.cc » ('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/base/adapters.h" 5 #include "src/base/adapters.h"
6 #include "src/base/bits.h" 6 #include "src/base/bits.h"
7 #include "src/compiler/instruction-selector-impl.h" 7 #include "src/compiler/instruction-selector-impl.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 10
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) { 544 if (m.right().IsWord32Xor() && CanCover(node, m.right().node())) {
545 Int32BinopMatcher mright(m.right().node()); 545 Int32BinopMatcher mright(m.right().node());
546 if (mright.right().Is(-1)) { 546 if (mright.right().Is(-1)) {
547 EmitBic(this, node, m.left().node(), mright.left().node()); 547 EmitBic(this, node, m.left().node(), mright.left().node());
548 return; 548 return;
549 } 549 }
550 } 550 }
551 if (m.right().HasValue()) { 551 if (m.right().HasValue()) {
552 uint32_t const value = m.right().Value(); 552 uint32_t const value = m.right().Value();
553 uint32_t width = base::bits::CountPopulation32(value); 553 uint32_t width = base::bits::CountPopulation32(value);
554 uint32_t msb = base::bits::CountLeadingZeros32(value); 554 uint32_t leading_zeros = base::bits::CountLeadingZeros32(value);
555 // Try to interpret this AND as UBFX. 555
556 if (IsSupported(ARMv7) && width != 0 && msb + width == 32) { 556 // Try to merge SHR operations on the left hand input into this AND.
557 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value)); 557 if (m.left().IsWord32Shr()) {
558 if (m.left().IsWord32Shr()) { 558 Int32BinopMatcher mshr(m.left().node());
559 Int32BinopMatcher mleft(m.left().node()); 559 if (mshr.right().HasValue()) {
560 if (mleft.right().IsInRange(0, 31)) { 560 uint32_t const shift = mshr.right().Value();
561 // UBFX cannot extract bits past the register size, however since 561
562 // shifting the original value would have introduced some zeros we can 562 if (((shift == 8) || (shift == 16) || (shift == 24)) &&
563 // still use UBFX with a smaller mask and the remaining bits will be 563 ((value == 0xff) || (value == 0xffff))) {
564 // zeros. 564 // Merge SHR into AND by emitting a UXTB or UXTH instruction with a
565 uint32_t const lsb = mleft.right().Value(); 565 // bytewise rotation.
566 return EmitUbfx(this, node, mleft.left().node(), lsb, 566 Emit((value == 0xff) ? kArmUxtb : kArmUxth,
567 std::min(width, 32 - lsb)); 567 g.DefineAsRegister(m.node()), g.UseRegister(mshr.left().node()),
568 g.TempImmediate(mshr.right().Value()));
569 return;
570 } else if (IsSupported(ARMv7) && (width != 0) &&
571 ((leading_zeros + width) == 32)) {
572 // Merge Shr into And by emitting a UBFX instruction.
573 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
574 if ((1 <= shift) && (shift <= 31)) {
575 // UBFX cannot extract bits past the register size, however since
576 // shifting the original value would have introduced some zeros we
577 // can still use UBFX with a smaller mask and the remaining bits
578 // will be zeros.
579 EmitUbfx(this, node, mshr.left().node(), shift,
580 std::min(width, 32 - shift));
581 return;
582 }
568 } 583 }
569 } 584 }
570 return EmitUbfx(this, node, m.left().node(), 0, width); 585 } else if (value == 0xffff) {
586 // Emit UXTH for this AND. We don't bother testing for UXTB, as it's no
587 // better than AND 0xff for this operation.
588 Emit(kArmUxth, g.DefineAsRegister(m.node()),
589 g.UseRegister(m.left().node()), g.TempImmediate(0));
590 return;
571 } 591 }
572 // Try to interpret this AND as BIC.
573 if (g.CanBeImmediate(~value)) { 592 if (g.CanBeImmediate(~value)) {
593 // Emit BIC for this AND by inverting the immediate value first.
574 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I), 594 Emit(kArmBic | AddressingModeField::encode(kMode_Operand2_I),
575 g.DefineAsRegister(node), g.UseRegister(m.left().node()), 595 g.DefineAsRegister(node), g.UseRegister(m.left().node()),
576 g.TempImmediate(~value)); 596 g.TempImmediate(~value));
577 return; 597 return;
578 } 598 }
579 // Try to interpret this AND as UXTH. 599 if (!g.CanBeImmediate(value) && IsSupported(ARMv7)) {
580 if (value == 0xffff) { 600 // If value has 9 to 23 contiguous set bits, and has the lsb set, we can
581 Emit(kArmUxth, g.DefineAsRegister(m.node()), 601 // replace this AND with UBFX. Other contiguous bit patterns have already
582 g.UseRegister(m.left().node()), g.TempImmediate(0)); 602 // been handled by BIC or will be handled by AND.
583 return; 603 if ((width != 0) && ((leading_zeros + width) == 32) &&
584 } 604 (9 <= leading_zeros) && (leading_zeros <= 23)) {
585 // Try to interpret this AND as BFC. 605 DCHECK_EQ(0u, base::bits::CountTrailingZeros32(value));
586 if (IsSupported(ARMv7)) { 606 EmitUbfx(this, node, m.left().node(), 0, width);
607 return;
608 }
609
587 width = 32 - width; 610 width = 32 - width;
588 msb = base::bits::CountLeadingZeros32(~value); 611 leading_zeros = base::bits::CountLeadingZeros32(~value);
589 uint32_t lsb = base::bits::CountTrailingZeros32(~value); 612 uint32_t lsb = base::bits::CountTrailingZeros32(~value);
590 if (msb + width + lsb == 32) { 613 if ((leading_zeros + width + lsb) == 32) {
614 // This AND can be replaced with BFC.
591 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()), 615 Emit(kArmBfc, g.DefineSameAsFirst(node), g.UseRegister(m.left().node()),
592 g.TempImmediate(lsb), g.TempImmediate(width)); 616 g.TempImmediate(lsb), g.TempImmediate(width));
593 return; 617 return;
594 } 618 }
595 } 619 }
596 } 620 }
597 VisitBinop(this, node, kArmAnd, kArmAnd); 621 VisitBinop(this, node, kArmAnd, kArmAnd);
598 } 622 }
599 623
600 624
(...skipping 1020 matching lines...) Expand 10 before | Expand all | Expand 10 after
1621 MachineOperatorBuilder::kFloat64RoundTiesAway | 1645 MachineOperatorBuilder::kFloat64RoundTiesAway |
1622 MachineOperatorBuilder::kFloat32RoundTiesEven | 1646 MachineOperatorBuilder::kFloat32RoundTiesEven |
1623 MachineOperatorBuilder::kFloat64RoundTiesEven; 1647 MachineOperatorBuilder::kFloat64RoundTiesEven;
1624 } 1648 }
1625 return flags; 1649 return flags;
1626 } 1650 }
1627 1651
1628 } // namespace compiler 1652 } // namespace compiler
1629 } // namespace internal 1653 } // namespace internal
1630 } // namespace v8 1654 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/unittests/compiler/arm/instruction-selector-arm-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698