Commit 65951323 authored by Andreas Haas's avatar Andreas Haas Committed by Commit Bot

[arm64] Remove arm64-specific CountTrailingZeros function

The {CountTrailingZeros} function is at least on one hot code path,
and there it causes significant overhead. With this CL I just call the
base::bit:: version of {CountTrailingZeros} directly. This allows the
compiler to compile it to a single hardware instruction.

R=v8-arm-ports@googlegroups.com

Bug: v8:9396
Change-Id: I81eccc5fce9b9856d41c503bd1e4a07287eb6e1e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1803648
Commit-Queue: Andreas Haas <ahaas@chromium.org>
Reviewed-by: 's avatarMartyn Capewell <martyn.capewell@arm.com>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63831}
parent 0eb4b90f
...@@ -67,7 +67,7 @@ CPURegister CPURegList::PopLowestIndex() { ...@@ -67,7 +67,7 @@ CPURegister CPURegList::PopLowestIndex() {
if (IsEmpty()) { if (IsEmpty()) {
return NoCPUReg; return NoCPUReg;
} }
int index = CountTrailingZeros(list_, kRegListSizeInBits); int index = base::bits::CountTrailingZeros(list_);
DCHECK((1LL << index) & list_); DCHECK((1LL << index) & list_);
Remove(index); Remove(index);
return CPURegister::Create(index, size_, type_); return CPURegister::Create(index, size_, type_);
......
...@@ -1083,7 +1083,7 @@ void TurboAssembler::Claim(const Register& count, uint64_t unit_size) { ...@@ -1083,7 +1083,7 @@ void TurboAssembler::Claim(const Register& count, uint64_t unit_size) {
if (unit_size == 0) return; if (unit_size == 0) return;
DCHECK(base::bits::IsPowerOfTwo(unit_size)); DCHECK(base::bits::IsPowerOfTwo(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); const int shift = base::bits::CountTrailingZeros(unit_size);
const Operand size(count, LSL, shift); const Operand size(count, LSL, shift);
if (size.IsZero()) { if (size.IsZero()) {
...@@ -1136,7 +1136,7 @@ void TurboAssembler::Drop(const Register& count, uint64_t unit_size) { ...@@ -1136,7 +1136,7 @@ void TurboAssembler::Drop(const Register& count, uint64_t unit_size) {
if (unit_size == 0) return; if (unit_size == 0) return;
DCHECK(base::bits::IsPowerOfTwo(unit_size)); DCHECK(base::bits::IsPowerOfTwo(unit_size));
const int shift = CountTrailingZeros(unit_size, kXRegSizeInBits); const int shift = base::bits::CountTrailingZeros(unit_size);
const Operand size(count, LSL, shift); const Operand size(count, LSL, shift);
if (size.IsZero()) { if (size.IsZero()) {
......
...@@ -650,7 +650,14 @@ Operand TurboAssembler::MoveImmediateForShiftedOp(const Register& dst, ...@@ -650,7 +650,14 @@ Operand TurboAssembler::MoveImmediateForShiftedOp(const Register& dst,
// The move was successful; nothing to do here. // The move was successful; nothing to do here.
} else { } else {
// Pre-shift the immediate to the least-significant bits of the register. // Pre-shift the immediate to the least-significant bits of the register.
int shift_low = CountTrailingZeros(imm, reg_size); int shift_low;
if (reg_size == 64) {
shift_low = base::bits::CountTrailingZeros(imm);
} else {
DCHECK_EQ(reg_size, 32);
shift_low = base::bits::CountTrailingZeros(static_cast<uint32_t>(imm));
}
if (mode == kLimitShiftForSP) { if (mode == kLimitShiftForSP) {
// When applied to the stack pointer, the subsequent arithmetic operation // When applied to the stack pointer, the subsequent arithmetic operation
// can use the extend form to shift left by a maximum of four bits. Right // can use the extend form to shift left by a maximum of four bits. Right
......
...@@ -89,15 +89,6 @@ int CountLeadingSignBits(int64_t value, int width) { ...@@ -89,15 +89,6 @@ int CountLeadingSignBits(int64_t value, int width) {
} }
} }
int CountTrailingZeros(uint64_t value, int width) {
DCHECK((width == 32) || (width == 64));
if (width == 64) {
return static_cast<int>(base::bits::CountTrailingZeros64(value));
}
return static_cast<int>(base::bits::CountTrailingZeros32(
static_cast<uint32_t>(value & 0xFFFFFFFFF)));
}
int CountSetBits(uint64_t value, int width) { int CountSetBits(uint64_t value, int width) {
DCHECK((width == 32) || (width == 64)); DCHECK((width == 32) || (width == 64));
if (width == 64) { if (width == 64) {
...@@ -109,7 +100,7 @@ int CountSetBits(uint64_t value, int width) { ...@@ -109,7 +100,7 @@ int CountSetBits(uint64_t value, int width) {
int LowestSetBitPosition(uint64_t value) { int LowestSetBitPosition(uint64_t value) {
DCHECK_NE(value, 0U); DCHECK_NE(value, 0U);
return CountTrailingZeros(value, 64) + 1; return base::bits::CountTrailingZeros(value) + 1;
} }
int HighestSetBitPosition(uint64_t value) { int HighestSetBitPosition(uint64_t value) {
...@@ -125,7 +116,7 @@ uint64_t LargestPowerOf2Divisor(uint64_t value) { ...@@ -125,7 +116,7 @@ uint64_t LargestPowerOf2Divisor(uint64_t value) {
int MaskToBit(uint64_t mask) { int MaskToBit(uint64_t mask) {
DCHECK_EQ(CountSetBits(mask, 64), 1); DCHECK_EQ(CountSetBits(mask, 64), 1);
return CountTrailingZeros(mask, 64); return base::bits::CountTrailingZeros(mask);
} }
#undef __ #undef __
......
...@@ -33,7 +33,6 @@ int float16classify(float16 value); ...@@ -33,7 +33,6 @@ int float16classify(float16 value);
// Bit counting. // Bit counting.
int CountLeadingZeros(uint64_t value, int width); int CountLeadingZeros(uint64_t value, int width);
int CountLeadingSignBits(int64_t value, int width); int CountLeadingSignBits(int64_t value, int width);
V8_EXPORT_PRIVATE int CountTrailingZeros(uint64_t value, int width);
V8_EXPORT_PRIVATE int CountSetBits(uint64_t value, int width); V8_EXPORT_PRIVATE int CountSetBits(uint64_t value, int width);
int LowestSetBitPosition(uint64_t value); int LowestSetBitPosition(uint64_t value);
int HighestSetBitPosition(uint64_t value); int HighestSetBitPosition(uint64_t value);
......
...@@ -3960,7 +3960,7 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr, ...@@ -3960,7 +3960,7 @@ int DisassemblingDecoder::SubstituteImmediateField(Instruction* instr,
unsigned rd_index, rn_index; unsigned rd_index, rn_index;
unsigned imm5 = instr->ImmNEON5(); unsigned imm5 = instr->ImmNEON5();
unsigned imm4 = instr->ImmNEON4(); unsigned imm4 = instr->ImmNEON4();
int tz = CountTrailingZeros(imm5, 32); int tz = base::bits::CountTrailingZeros(imm5);
if (tz <= 3) { // Defined for 0 <= tz <= 3 only. if (tz <= 3) { // Defined for 0 <= tz <= 3 only.
rd_index = imm5 >> (tz + 1); rd_index = imm5 >> (tz + 1);
rn_index = imm4 >> tz; rn_index = imm4 >> tz;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment