This is an archive of the discontinued LLVM Phabricator instance.

[LoopGuard] Instructions in loop preheader and loop exit must be safe to execute speculatively.
AbandonedPublic

Authored by Whitney on Dec 11 2019, 6:16 PM.

Details

Summary

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

Event Timeline

Whitney created this revision.Dec 11 2019, 6:16 PM
fhahn requested changes to this revision.Dec 12 2019, 2:45 AM

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?

This revision now requires changes to proceed.Dec 12 2019, 2:45 AM
Whitney updated this revision to Diff 233612.Dec 12 2019, 7:08 AM

Added comments to explain why the preheader and exit block should not contain instructions which are not safe to execute speculatively.

Whitney added a comment.EditedDec 12 2019, 7:15 AM

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.

Whitney updated this revision to Diff 233622.Dec 12 2019, 8:23 AM

clarify the comment.

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.

Whitney updated this revision to Diff 233671.Dec 12 2019, 12:57 PM

use isGuaranteedToTransferExecutionToSuccessor instead of IsSafeToSpeculativelyExecute

Meinersbur added inline comments.Dec 13 2019, 3:39 PM
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
1504

[typo] "becuase"

1505

[style] indention

Whitney updated this revision to Diff 233896.Dec 13 2019, 5:07 PM
Whitney marked 2 inline comments as done.

[NFC] Update comment and fix typos.

Whitney marked an inline comment as done.Dec 13 2019, 5:08 PM

I am ok with this patch. @fhahn what do you think?

fhahn added a comment.Dec 16 2019, 9:51 AM

I am ok with this patch. @fhahn what do you think?

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 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.

Whitney added a comment.EditedDec 16 2019, 3:34 PM

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.

Whitney abandoned this revision.Dec 17 2019, 1:23 PM