<div dir="ltr"><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">I see similar (potential) issues in other metadata like branch weights or updating analysis results like BFI.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif">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.</div><div class="gmail_default" style="font-family:arial,helvetica,sans-serif"><br></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Mar 20, 2020 at 10:47 AM Colin McEwan via llvm-dev <<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hi all,<br>
<br>
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.<br>
<br>
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)<br>
<br>
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.<br>
<br>
For example:<br>
<br>
        preheader:<br>
                ...<br>
        loop.body: ; preds = %preheader, %loop.body<br>
                ...<br>
                br i1 %cmp, label %loop.body, %loop.exit, !llvm.loop !123<br>
        loop.exit:<br>
<br>
If a pass needs to split the critical edge from %loop.body -> %loop.body, it will create something like<br>
<br>
        preheader:<br>
                ...<br>
        loop.body: ; preds = %preheader, %loop.body.crit_edge<br>
                ...<br>
                br i1 %cmp, label %loop.body.crit_edge, %loop.exit, !llvm.loop !123   // No longer a loop latch block<br>
        loop.body.crit_edge:<br>
                ... <br>
                br %loop.body                                                         // Now a loop latch, with no !llvm.loop<br>
        loop.exit:<br>
<br>
<br>
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.<br>
<br>
<br>
I can think of a few approaches to address this, but each has its issues:<br>
<br>
    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.<br>
<br>
    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.<br>
<br>
    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.<br>
<br>
<br>
Additionally, it should probably be explicitly stated in the IR language reference that !llvm.loop preservation is best-effort and may be lost.<br>
<br>
Does anyone have any opinions or other insight?<br>
<br>
<br>
Many thanks,<br>
-- <br>
Colin<br>
_______________________________________________<br>
LLVM Developers mailing list<br>
<a href="mailto:llvm-dev@lists.llvm.org" target="_blank">llvm-dev@lists.llvm.org</a><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev</a><br>
</blockquote></div>