[PATCH] D37460: [GVN] Prevent LoadPRE from hoisting through guards

Daniel Berlin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 6 15:21:23 PDT 2017


dberlin added a comment.

The problem:
Right now, for each load, you go through the loadbb, and see if you hit a guard.
This information does not change for each load. At most it changes as GVN removes things (and even then, no).
The number of guards is smaller than the number of blocks.

Thus, you could use ordered instructions to make this O(guards) * O(Number of loads) instead of O(number of instructions in each load block) * O(number of loads)
Trivially.
But you can do even better, and this is the constant time i refer to:
To make it constant time to check, and O(guards) to compute:

For each guard in the program:

  // Make FirstGuard point to the first guard in each block
  auto Iter = FirstGuard.(guard->getParent())
  if (Iter != FIrstGuard.end())
     FirstGuard.insert({guard->parent(), guard})
  else
    if (OrderedInstructions->dominates(*Iter, guard))
     Iter->second = guard

In processLoad, replace your entire loop with:

  if the bb doesn't exist in firstguard
      you are fine
  if the bb does, check whether orderedinstructions->dominates(FirstGuard[BB], load)

Basically, this is: Build a table of where the first guard in the block is.  Since you are trying to see if there is a guard above a given instruction in the block, the only thing that matters is where the first guard in the block is, because eventually you will hit that guard if you go up.   OrderedInstructions will tell you whether that first guard is before or after the load in the block.

You already walk all the instructions in the main gvn loop in RPO order. You can fill in firstguard as you go, as it will see all the guards before anything that one could try to lift above, except in the case of loops.


https://reviews.llvm.org/D37460





More information about the llvm-commits mailing list