-
Notifications
You must be signed in to change notification settings - Fork 13.8k
Optimize checked_ilog
and pow
when base
is a power of two
#147250
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Optimize checked_ilog
and pow
when base
is a power of two
#147250
Conversation
8f19ce6
to
e5ca8cd
Compare
This comment has been minimized.
This comment has been minimized.
does this affect the codegen in practical circumstances? I would expect even a fairly weak optimizer to perform this optimization, making us hand-coding it irrelevant and potentially even harmful because we introduce more conditional logic to chew through. |
checked_ilog
when base
is a power of twochecked_ilog
and pow
when base
is a power of two
It replaces a loop by some bit manipulations. Whether anyone actually calls either function with a compile-time known, power of 2 base is another question. But it can't hurt, since it is guarded by
No, in either function, LLVM is not able to see that the loop is performing a log/pow and apply the identities: https://godbolt.org/z/6vMsxc9Kh
They're guarded by |
e5ca8cd
to
2faa397
Compare
if base == 2 ** k, then log(base, n) == log(2, n) / k
if base == 2 ** k, then (2 ** k) ** n == 2 ** (k * n) == 1 << (k * n)
2faa397
to
abb7f32
Compare
...then I'm kinda surprised! Nice catch. |
if base == 2 { | ||
return self.checked_ilog2(); | ||
} else if base == 10 { | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there's no need for the base == 2
case any more? The is_power_of_two
one would handle it.
if base.is_power_of_two() { | ||
let k = base.ilog2(); | ||
return Some(try_opt!(self.checked_ilog2()) / k); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the a problem because it'll apply for base == 1
, then divide by zero?
Would be good to have codegen tests to demonstrate what this is doing -- especially since that way there's a way for people to try removing the special cases later if they think that LLVM no longer needs them. |
Optimize
checked_ilog
andpow
when the base is a power of two