This is an archive of the discontinued LLVM Phabricator instance.

[BreakCritEdges] Support preserving loop-simplify form with indirectbr. (WIP)
AbandonedPublic

Authored by fhahn on Jun 10 2020, 9:16 AM.

Details

Reviewers
None
Summary

This patch updates SplitCriticalEdges preserve loop-simplify form, even
if we would have to split the predecessors of the exit block.

Instead of splitting the predecessors of the exit block, it splits the
exit block at the first non-PHI instruction and updates the branch in
the new block to jump to the new split block. It also adds PHIs as
required.

Unfortunately a few users rely on the contents of a block not being
moved. I managed to fix most of them, but I am not too sure what to do
about the caching in MemoryDependenceAnalsysis.

Diff Detail

Event Timeline

fhahn created this revision.Jun 10 2020, 9:16 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 10 2020, 9:16 AM
Herald added a subscriber: hiraditya. · View Herald Transcript

We could make preserving LoopSimplify form optional, and let users turn it on with CriticalEdgeSplittingOptions. That way, if some user isn't prepared to handle the transform, they can just let LoopSimplify form break, and fix it up later if necessary. We probably should do that anyway: there isn't any obvious connection between preserving LoopInfo and preserving LoopSimplify form.

llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
324

Missing LoopInfo update?

fhahn marked an inline comment as done.Jun 10 2020, 2:18 PM

We could make preserving LoopSimplify form optional, and let users turn it on with CriticalEdgeSplittingOptions. That way, if some user isn't prepared to handle the transform, they can just let LoopSimplify form break, and fix it up later if necessary. We probably should do that anyway: there isn't any obvious connection between preserving LoopInfo and preserving LoopSimplify form.

Agreed. I think that would go well with D81582, i.e. have a PreserveLoopSimplify option, that guarantees loop-simplify form is preserved or nullptr is returned if it's not possible. If PreserveLoopSimplify is false, don't preserve it if it is not possible . But currently GVN for example preserves loop-simplify form, but I suppose we could change that. Might be best as a follow-on of the bail out if preserving is not possible. What do you think?

Also, do you agree that preserving loop-simplify form by moving instructions to a different BB is more trouble than it is worth?

llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
324

I don't think we need to do anything about LI here, as the block should already be added to LI by SplitBlock and we only adjust the successor to another successor in the same loop I think.

Agreed. I think that would go well with D81582, i.e. have a PreserveLoopSimplify option, that guarantees loop-simplify form is preserved or nullptr is returned if it's not possible

We can kill off the call to SplitBlockPredecessors, and add an option to bail out if preserving loop-simplify form would require transforming other edges, sure. (I'd rather not condition it on whether the other edges are IndirectBr edges; I'd like to avoid obscure IndirectBr edge cases where possible.)

Also, do you agree that preserving loop-simplify form by moving instructions to a different BB is more trouble than it is worth?

This doesn't seem worse than calling SplitBlockPredecessors(), in terms of transforming the CFG in unpredictable ways.

llvm/lib/Transforms/Utils/BreakCriticalEdges.cpp
324

Okay, that makes sense.

fhahn added a comment.Jun 10 2020, 5:15 PM

Agreed. I think that would go well with D81582, i.e. have a PreserveLoopSimplify option, that guarantees loop-simplify form is preserved or nullptr is returned if it's not possible

We can kill off the call to SplitBlockPredecessors, and add an option to bail out if preserving loop-simplify form would require transforming other edges, sure. (I'd rather not condition it on whether the other edges are IndirectBr edges; I'd like to avoid obscure IndirectBr edge cases where possible.)

Ok. In the short term, I'd like the fix the crash in GVN asap. Preserving simplify-form as in this patch will require a bit of extra work in a couple of places. I think in the short-term, it might be best to add a PreserveLoopSimplify option and have GVN not preserve loop-simplify form, until this patch is ready. What do you think?

Also, do you agree that preserving loop-simplify form by moving instructions to a different BB is more trouble than it is worth?

This doesn't seem worse than calling SplitBlockPredecessors(), in terms of transforming the CFG in unpredictable ways.

Agreed, unfortunately the existing users don't deal too gratefully with moving instructions, but I don't think anything in the SplitCriticalEdges interface guarantees that. If you are not concerned about the general approach and the small hoops that existing users have to jump through (see GVN & LSR changes), I am happy to continue with this approach, but it will probably require a few additional changes.

I think in the short-term, it might be best to add a PreserveLoopSimplify option and have GVN not preserve loop-simplify form, until this patch is ready. What do you think?

That seems reasonable. I'm not sure why GVN is trying to preserve LoopSimplify in the first place.

I think in the short-term, it might be best to add a PreserveLoopSimplify option and have GVN not preserve loop-simplify form, until this patch is ready. What do you think?

That seems reasonable. I'm not sure why GVN is trying to preserve LoopSimplify in the first place.

I think it was because I initially *thought* all the utilities used to modify the CFG actually preserve loop-simplify form. I updated D81582 with the option & made GVN use it. It would be great if you could take a look.

fhahn abandoned this revision.Sep 13 2022, 2:18 AM

Should be superseded by D81582

Herald added a project: Restricted Project. · View Herald TranscriptSep 13 2022, 2:18 AM