Disallow loops with preheader or exit block which contains instructions that are not safe to execute speculatively to be considered as guarded loop.
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
I think this restriction needs to be at least documented. But what's the reason for this restriction? Unless I am missing something, even if the instructions between the guard and the loop are not safe to speculate, the guard condition still applies to the loop, right?
Added comments to explain why the preheader and exit block should not contain instructions which are not safe to execute speculatively.
I think this restriction needs to be at least documented. But what's the reason for this restriction? Unless I am missing something, even if the instructions between the guard and the loop are not safe to speculate, the guard condition still applies to the loop, right?
Good point, it should be documented, changed the description in the .h file. Added a comment in the code to explain the reason. Right, the guard condition still applies to the loop, but let say in the preheader there exists an instruction which throw, then the loop is not executed even if it entered the guarded region.
If I understand correctly, this is what people agreed upon in the loop group meeting. People want to start with a restricted definition and loose it as time goes by. I should have restrict the instructions allowed in preheader and exit block when I first introduce the loop guard, accidentally did not. People also agreed to allow basic blocks without control flow and without unsafe instructions in between GuardBB and Preheader, and between ExitFromLatch and GuardOtherSucc, which I will implement in the later PR. I am open to re-discuss the definition of a loop guard in the loop group meeting if that's required.
This doesn't make sense to me. I don't see why we need the speculation restriction here. The discussion mentions concern about side exits, but if so, that's a different property. (i.e. isGuaranteedToTransferToSuccessor)
This also needs more background as to motivation. Motivating use case? Link to a review would be ideal.
This doesn't make sense to me. I don't see why we need the speculation restriction here. The discussion mentions concern about side exits, but if so, that's a different property. (i.e. isGuaranteedToTransferToSuccessor)
You are right, I should use isGuaranteedToTransferExecutionToSuccessor instead of IsSafeToSpeculativelyExecute.
This also needs more background as to motivation. Motivating use case? Link to a review would be ideal.
The reason I am doing this PR is because I noticed that I forgot about this restriction in my original implementation (is my mistake). This PR is making the definition of loop guard more restricted, which means less loops would be considered as guarded. The previous review is https://reviews.llvm.org/D63885, but the decision of the definition of loop guard is made in the loop group meeting. I am ok to leave the definition of loop guard as is (before this patch) if that's what everyone preferred.
use isGuaranteedToTransferExecutionToSuccessor instead of IsSafeToSpeculativelyExecute
llvm/lib/Analysis/LoopInfo.cpp | ||
---|---|---|
402–405 | This applies to the preheader, but if an instruction throws in ExitFromLatch, the loop has been executed. I am not arguing that ExitFromLatch should allow side-effect instructions, but we should correctly justify why not. | |
llvm/unittests/Analysis/LoopInfoTest.cpp | ||
1414 | [typo] "becuase" | |
1415 | [style] indention |
I think the patch still misses a description of the motivation for the restriction in getLoopGuardBranch. I see why the restriction would be helpful for LoopFusion, but it seems like there could be other uses cases that do not require that restriction (e.g. if one wants to use the guard for reasoning about values in the loop).
I did a test with a loop that has a call which may throw inside, and SCEV is able to calculate the trip count, add recurrence of the induction variable, etc. Maybe we can keep getLoopGuardBranch() as is, and not worry about instructions which not guaranteed to transfer execution to successors? What do you think @Meinersbur?
I was assuming you need this change for your use case. If getLoopGuardBranch already fits your use case, I indeed do not see a reason to change it?
llvm/lib/Analysis/LoopInfo.cpp | ||
---|---|---|
402–405 | Btw, nothing guarantees that the loop itself is exiting, hence ExitFromLatchSucc may still not be executed. |
I was assuming you need this change for your use case. If getLoopGuardBranch already fits your use case, I indeed do not see a reason to change it?
I actually don't need this change. My motivation is only to make it closer to what we discussed in the loop opt meeting.
If I don't see any objection, I will cancel this patch and keep getLoopGuardBranch as is. Thanks everyone for spending the time to review it.
This applies to the preheader, but if an instruction throws in ExitFromLatch, the loop has been executed.
I am not arguing that ExitFromLatch should allow side-effect instructions, but we should correctly justify why not.