[llvm-dev] CFG manipulation and !llvm.loop metadata

Hiroshi Yamauchi via llvm-dev
Mon, 23 Mar 2020 16:53:57 -0000

I see similar (potential) issues in other metadata like branch weights or
updating analysis results like BFI.

I don't have a solution but I suspect some sort of verification/checks
and/or enforcement through the API might be needed to get it right.


On Fri, Mar 20, 2020 at 10:47 AM Colin McEwan via llvm-dev <
llvm-dev at lists.llvm.org> wrote:

> Hi all,
>
> I have encountered some issues with the preservation of the location of
> llvm.loop metadata (containing optimisation hints), and would appreciate
> some feedback on the issue.
>
> The IR language description states that llvm.loop metadata is attached to
> terminator of a loop latch block, and accordingly Loop::getLoopID()
> searches for it in all loop latches (and only successfully finds it if all
> latches reference the same metadata)
>
> However, transforms which modify the CFG, for example using
> SplitCriticalEdge(), generally don't make any attempt to preserve this
> property. Some transforms dealing specifically with loops use getLoopID and
> setLoopID to preserve and reset the metadata after transformations, but
> function transforms such as GVN and Jump Threading can modify control flow
> without any attempt to update the location.
>
> For example:
>
>         preheader:
>                 ...
>         loop.body: ; preds = %preheader, %loop.body
>                 ...
>                 br i1 %cmp, label %loop.body, %loop.exit, !llvm.loop !123
>         loop.exit:
>
> If a pass needs to split the critical edge from %loop.body ->
%loop.body,
> it will create something like
>
>         preheader:
>                 ...
>         loop.body: ; preds = %preheader, %loop.body.crit_edge
>                 ...
>                 br i1 %cmp, label %loop.body.crit_edge, %loop.exit,
> !llvm.loop !123   // No longer a loop latch block
>         loop.body.crit_edge:
>                 ...
>                 br %loop.body
>            // Now a loop latch, with no !llvm.loop
>         loop.exit:
>
>
> Now the loop's latch block is %loop.body.crit_edge, and the !llvm.loop
> will not be found by Loop::getLoopID(), meaning it is effectively lost.
> This can happen in many different places.
>
>
> I can think of a few approaches to address this, but each has its issues:
>
>     1. Modify the framework's CFG manipulation tools to maintain the
> location of the !llvm.loop. A major drawback of this is that LoopInfo is
> needed to be able to tell whether a block is a loop latch or not (in the
> example of splitting a latch block's back edge, we need LoopInfo to
know
> whether the edge we're splitting is the latch edge or exit edge) and
it's
> not necessary available or up to date when we manipulate the CFG.
>
>     2. Have Loop::getLoopID() search other blocks in the loop for
> metadata. This has potential compile-time implications, and would change
> the IR language definition of the !llvm.loop as potentially existing (in a
> valid form) anywhere in the loop.
>
>     3. Fixup utility functions for function passes to use, to search a
> loop and move any errant !llvm.loop to the latch block(s) of its loop.
>
>
> Additionally, it should probably be explicitly stated in the IR language
> reference that !llvm.loop preservation is best-effort and may be lost.
>
> Does anyone have any opinions or other insight?
>
>
> Many thanks,
> --
> Colin
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL:
<http://lists.llvm.org/pipermail/llvm-dev/attachments/20200323/95988b86/attachment.html>