It'd be nice for the compiler to be able to optimize bits.OnesCount(x) == 1
to x&(x-1) != 0 && x != 0
.
This is a bit tricky, because by the time we get to the rewrite rules, there's already a branch to check cpu feature availability.
If we figure this out, there might be other math/bits function result comparisons we want to optimize.
Implementation ideas welcome.
7条答案
按热度按时间xam8gpfp1#
https://golang.org/cl/229127提到了这个问题:
cmd/compile: use cheaper implementation of oneBit
qrjkbowd2#
我猜你不喜欢在编译器达到SSA之前做这件事?可能成本大于收益,并且会干扰早期阶段?
kmb7vmvb3#
成本超过了收益,并且在早期阶段造成了混乱?
没错。
carvr3hs4#
https://golang.org/cl/229197提到了这个问题:
cmd/compile: use cheaper implementation of oneBit
pu82cl6c5#
作为附带说明,至少在
GOAMD64=v2
及以上版本中,没有CPU标志检查,因此我们得到了以下代码:没有调用
math/bits.OnesCount(SB)
。为了完整性,建议的替换模式
x&(x-1) != 0 && x != 0
被编译为:在Go tip上进行了测试(嗯,不是最新的一个,但足够接近:fad67f8)。
gudnpqoy6#
替换后的编译代码中不应该有任何跳转。我们肯定遗漏了一条或三条重写规则。
6mw9ycah7#
好的,抱歉再次提出这个问题,但我正在盯着最初提出的替换方案,它看起来并不完全正确。
也许我计算出了一些错误。
或许它应该像这样?
考虑到这一点,这里是与不同编译器输出的比较。
Clang ( https://godbolt.org/z/o9PzM49TG ):
GCC:
Go ( https://godbolt.org/z/nfKjKe93a ):
看起来Go也应该能够在这里移除一些分支。