[PATCH] D32720: [LICM] Introduce a finer granularity option to compute early exits.

Daniel Berlin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 29 19:29:13 PDT 2017


dberlin added inline comments.


================
Comment at: lib/Transforms/Utils/LoopUtils.cpp:1053
+    for (Instruction *ExitInst : SafetyInfo->EarlyExits)
+      if (!SafetyInfo->OI.dominates(&Inst, ExitInst))
+        return false;
----------------
trentxintong wrote:
> efriedma wrote:
> > Actually, one more issue we probably need to address.
> > 
> > This is potentially linear in the number of calls in the loop, since we don't try to prune EarlyExits at all.  This makes LICM potentially O(n^2) overall.  Can we store this information in some more efficient way?
> We could certainly prune the early exits by discovering them walking the dominator tree. If an instruction dominates an early exit (Inst A), it certainly dominates all the other early exits dominated by Inst A.  So we do not need to include those early exits in the list.
> 
> The drawback with this is that if an early exit is deleted, which is possible but unlikely. We need to invalidate the early exit list (we could try to recompute everything, but probably not worth it).
> 
> By doing this, we potentially save a lot of OI.dominates checks.  Worst case is still O(n^2) in case of a loop with many basic blocks that do not dominate each other and each one of them have early exits ... but this happens infrequently in practice IMO.
> 

Unless i'm misunderstanding, and maybe i am (!), I believe this  can be made optimal:

Here's the normal way:

The ordering is completely described by the DFS in/out numbers of the dom tree + local numbers.

It should completely suffice to, instead of just ordering the in/out of the DT nodes, model in/out of the entire block.

IE
```

Count = 0
number(root of DT)

number(DTNode):
   In = Count
   for each DT child:
     number(child)
    for each instruction in this block
      InstNum[I] = ++Count
   Out = Count

```

(or something similar)

The early exits you dominate is, in the same block, any early exit with a number greater than yours, and for other blocks, any block with an in > your in and  out < your out.

This is trivially stored in a sorted smallvector.

You dominate all the early exits only if using the above comparator, lower bound says you would appear first in the smallvector.

I believe you can get away with a lot less, but not positive ATM:

By definition, anything that dominates all the early exits must be in a block that has a DT level number <= than all of them.

If all the exits are terminators, than you don't need the local numbering or DFS numbering at all, i think (I rely on Eli to point out any flaw in my reasoning, since i'm dashing this off pretty quickly).

You just need the entries with the lowest DT level (in case they are siblings in the dominator tree)

Then it would just be:
```

if DT level number < lowest DT level number of an exit, you dominate all exits
if DT level number == lowest DT level number then:
   if vector.size() == 1 && exit block == instruction block 
    you dominate all exits
   else
    you do not (because there must be a sibling you don't dominate)

```

I think one or the other of the above should work.

The DT level numbers are now available in the DomTree :)



https://reviews.llvm.org/D32720





More information about the llvm-commits mailing list