This patch teaches LICM to hoist guards from the loop if they are guaranteed to execute and
if there are no side effects that could prevent that.
Details
Diff Detail
Event Timeline
Didn't look at the code, but this needs a test case that shows we don't hoist the second guard in
for (;;) { guard(loop_varying); gurad(loop_invariant); }
lib/Transforms/Scalar/LICM.cpp | ||
---|---|---|
461 | Indeed. Thanks for pointing out! |
lib/Transforms/Scalar/LICM.cpp | ||
---|---|---|
523 | Not sure if it's a good idea... What if it changes in the future? Besides, sink can actually return false, and it would be strange to have different signatures for these two. |
Fixed bug in mem-write detection, added tests to exercise guard-after-guard scenarios.
LGTM w/mandatory separate cleanup changes as described.
lib/Transforms/Scalar/LICM.cpp | ||
---|---|---|
520 | Note for anyone reading: This can be trivially extended to llvm.invariant.start w/no uses. I thought about requiring that in this review, but decided a separate patch was better. | |
523 | This was not a suggestion. Please make the change. It can be done post commit, but I want this cleanup done. At the moment, you have control flow in this patch which is never executed and introduces non-trivial reasoning complexity for no value. In general, the person who changes code in the future has to think about the implications of their changes. Future proofing never works and just adds complexity now. |
lib/Transforms/Scalar/LICM.cpp | ||
---|---|---|
523 |
Bug: Can only start true if a) readonly loop or b) header block.