Reland "[vm] Recognize int.trailingZeroBitCount/oneBitCount as graph-inlinable"
The previous attempt was reverted because it broke unoptimized JIT
on ARM 32. This reland force-optimizes the two getters.
Stacks on top of the int.{trailingZeroBitCount,oneBitCount} API CL
(commit 754239b077). Both getters route through OTHER_RECOGNIZED_LIST
when a hardware fast path is available; otherwise the newly added
Dart bodies inline at call sites via vm:prefer-inline. The C++
natives are removed.
Backend codegen
---------------
ARM64: NEON CNT + UADDLV (popcount); RBIT + CLZ (ctz).
ARM: NEON CNT + VPADDL chain (popcount); RBIT + CLZ on the
register pair (ctz).
x64: popcntq when TargetCPUFeatures::popcnt_supported();
LoadImmediate(64) + rep_bsfq for ctz (decodes as tzcnt
on BMI1+, preserves dest on zero otherwise).
RISC-V 64: cpop / ctz when RV_baseline includes Zbb.
Per-arch availability is encapsulated in
UnaryInt64OpInstr::IsSupported(Token::Kind).
Apple M-series ARM64, AOT (us/iter, lower is better):
cardinality.swar 371
cardinality.accelerated 154 (2.4x)
forEachSetBit.swar 19031
forEachSetBit.accelerated 4988 (3.8x)
select.swar 199
select.accelerated 77 (2.6x)
complementCardinality.swar 399
complementCardinality.accel 152 (2.6x)
Work towards https://github.com/dart-lang/sdk/issues/6486 (popcount
and ctz intrinsification).
Work towards https://github.com/dart-lang/sdk/issues/1053 (efficient
BitSet implementation).
Fixes https://github.com/dart-lang/sdk/issues/52673
Fixes https://github.com/dart-lang/sdk/issues/38346
Fixes https://github.com/dart-lang/sdk/issues/63436
Issue https://github.com/dart-lang/sdk/issues/10212
Issue https://github.com/dart-lang/sdk/issues/5798
TEST=tests/corelib/int_bit_count_test
Cq-Include-Trybots: luci.dart.try:vm-linux-release-simarm-try,vm-ffi-qemu-linux-release-arm-try,vm-aot-linux-release-simarm_x64-try,vm-aot-linux-debug-simarm_x64-try,dart-sdk-linux-riscv64-try
Change-Id: Ib812cbaec6e371b9720df7a543411f78e524cac1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506060
Reviewed-by: Martin Kustermann <kustermann@google.com>
Auto-Submit: Modestas Valauskas <valauskasmodestas@gmail.com>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This commit is contained in:
committed by
dart-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
abbd9e33ca
commit
415b040d6f
@@ -163,13 +163,24 @@ abstract final class _IntegerImplementation implements int {
|
||||
@pragma("vm:external-name", "Integer_equalToInteger")
|
||||
external bool _equalToInteger(int other);
|
||||
|
||||
@pragma("vm:recognized", "other")
|
||||
@pragma("vm:prefer-inline")
|
||||
@pragma("vm:exact-result-type", "dart:core#_Smi")
|
||||
@pragma("vm:external-name", "Integer_trailingZeroBitCount")
|
||||
external int get trailingZeroBitCount;
|
||||
int get trailingZeroBitCount {
|
||||
final int v = this;
|
||||
return ((v - 1) & ~v).oneBitCount;
|
||||
}
|
||||
|
||||
@pragma("vm:recognized", "other")
|
||||
@pragma("vm:prefer-inline")
|
||||
@pragma("vm:exact-result-type", "dart:core#_Smi")
|
||||
@pragma("vm:external-name", "Integer_oneBitCount")
|
||||
external int get oneBitCount;
|
||||
int get oneBitCount {
|
||||
int v = this;
|
||||
v = v - ((v >>> 1) & 0x5555555555555555);
|
||||
v = (v & 0x3333333333333333) + ((v >>> 2) & 0x3333333333333333);
|
||||
v = (v + (v >>> 4)) & 0x0F0F0F0F0F0F0F0F;
|
||||
return ((v * 0x0101010101010101) >>> 56);
|
||||
}
|
||||
|
||||
int abs() {
|
||||
return this < 0 ? -this : this;
|
||||
|
||||
Reference in New Issue
Block a user