This is an archive of the discontinued LLVM Phabricator instance.

[LoopVersioning] Allow versionLoop to create plain branch inst when no runtime check is specified
ClosedPublic

Authored by eopXD on Jun 21 2021, 3:41 AM.

Details

Summary

After this function call, the LLVM IR would look like the following:

if (true)
  /* NonVersionedLoop */
else
  /* VersionedLoop */

Diff Detail

Event Timeline

eopXD created this revision.Jun 21 2021, 3:41 AM
eopXD requested review of this revision.Jun 21 2021, 3:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 21 2021, 3:41 AM
eopXD added a comment.EditedJun 21 2021, 3:44 AM

User may need to create versioned loops of such structure to append more runtime checks conditions to the branch instruction.

fhahn added a comment.Jun 21 2021, 3:49 AM

User may need to create versioned loops of such structure to append more runtime checks conditions to the branch instruction.

Are you planning on sharing a follow-up that makes use of the new functionality? That would be helpful to review this and the earlier patch, to make sure the new API is a good fit. Also, it would be good to have a way to test this.

The design seems weird here.
I think it would be best to first see the intended use case.

fhahn added a comment.Jun 24 2021, 7:06 AM

In terms of structuring of LoopVersioning, I think it would be great if the existing functionality could be refactored so that there is a set of helper functions that expose the functionality for re-use, rather than growing the existing LoopVersioning class.

eopXD updated this revision to Diff 354655.Jun 26 2021, 1:47 AM

Preserve information inside versionLoop and add helper functions to get them.

eopXD updated this revision to Diff 354656.Jun 26 2021, 1:53 AM

Preserve information inside versionLoop and add helper functions to get them.

eopXD added a comment.EditedJun 26 2021, 1:56 AM

Hi @fhahn ,

Aside from adding helper functions, I think removing the assertion that "ensures RuntimeCheck is not a nullptr is necessary,
since in my use-case, the loop provided to LoopVersioning doesn't require any MemRuntimeCheck and SCEVRuntimeCheck but wants to clone the loop and setup a branch instruction for them.
Other than that I kept the interface and logic of versionLoop the same.

Thank you for reviewing this patch.

eopXD updated this revision to Diff 354658.Jun 26 2021, 2:15 AM

Address comments.

eopXD updated this revision to Diff 354659.Jun 26 2021, 2:16 AM

pushed to the wrong patch. revert.

Whitney accepted this revision.Aug 24 2021, 10:59 AM

LGTM.

This revision is now accepted and ready to land.Aug 24 2021, 10:59 AM

Hi @fhahn ,

Aside from adding helper functions, I think removing the assertion that "ensures RuntimeCheck is not a nullptr is necessary,
since in my use-case, the loop provided to LoopVersioning doesn't require any MemRuntimeCheck and SCEVRuntimeCheck but wants to clone the loop and setup a branch instruction for them.
Other than that I kept the interface and logic of versionLoop the same.

Right, currently versionLoop roughly does the following things: 1) create memory runtime checks (if requested), 2) generate SCEV predicate checks (if requested) and 3) clone the loop and 4) branch to the right version depending on the generated runtime checks.

IIUC you only need 3). Personally it seems like extending versionLoop to only do 3) makes the interface more complicated than it needs to be. Instead, would it be possible to extract the code to do 3) into a utility function that returns the conditional branch to select the loop? Then you could use that in LoopIdiomRecognize directly.

llvm/include/llvm/Transforms/Utils/LoopVersioning.h
79

dead code? (same for the other changes here)

eopXD retitled this revision from [LoopVersioning] add function to create versioned loop with plain runtime check to [LoopVersioning] Allow versionLoop to create plain branch inst when no runtime check is specified.Aug 25 2021, 11:53 PM
eopXD edited the summary of this revision. (Show Details)
eopXD added a comment.Dec 10 2021, 8:21 AM

IIUC you only need 3). Personally it seems like extending versionLoop to only do 3) makes the interface more complicated than it needs to be. Instead, would it be possible to extract the code to do 3) into a utility function that returns the conditional branch to select the loop? Then you could use that in LoopIdiomRecognize directly.

Hi @fhahn,

Sorry for the late reply.
I think I have made minimum change for versionLoop and only exposed utility functions (getRuntimeCheckBB and getRuntimeCheckBI) for use.
The usage of these two functions are inside D104636.
Since @Whitney have accepted it I think we can land this and proceed to the child patches and give LoopNestIdiomRecognize a try?

/// versionTopLoop - Create a fallback version the TopLoop
void LoopIdiomRecognize::versionTopLoop() {
  const LoopAccessInfo LAI(TopLoop, SE, TLI, AA, DT, LI);
  LoopVersioning LV(LAI, LAI.getRuntimePointerChecking()->getChecks(), TopLoop,
                    LI, DT, SE);

  LV.versionLoopWithPlainRuntimeCheck();

  RuntimeCheckBB = LV.getRuntimeCheckBB();
  FallBackLoop = LV.getNonVersionedLoop();
}
llvm/include/llvm/Transforms/Utils/LoopVersioning.h
79

It is dead code right now but will be used in D104636.

eopXD updated this revision to Diff 393501.Dec 10 2021, 8:22 AM

Rebase.

eopXD updated this revision to Diff 393502.Dec 10 2021, 8:24 AM

Rebase.

I am landing this utility to give it a try on D104636.

This revision was landed with ongoing or failed builds.Dec 16 2021, 12:41 AM
This revision was automatically updated to reflect the committed changes.
fhahn added a comment.Dec 16 2021, 1:28 AM

IIUC you only need 3). Personally it seems like extending versionLoop to only do 3) makes the interface more complicated than it needs to be. Instead, would it be possible to extract the code to do 3) into a utility function that returns the conditional branch to select the loop? Then you could use that in LoopIdiomRecognize directly.

Hi @fhahn,

Sorry for the late reply.
I think I have made minimum change for versionLoop and only exposed utility functions (getRuntimeCheckBB and getRuntimeCheckBI) for use.
The usage of these two functions are inside D104636.

FWIW I still think the interface should be adopted to make this more useable, rather than just adding on additional state that makes it even harder to make further changes. While the changes here are indeed a bit smaller than improving the interface, the additional state that needs maintained increases the complexity of the class even further, which has a cost down the road.

I *think* the patch should only be committed once D104636 has also been accepted; at the moment there's nothing to test the new functionality.

eopXD added a comment.Dec 16 2021, 2:07 AM

You are right. Patch reverted.