[all-commits] [llvm/llvm-project] 6d88f6: Reapply [LVI] Normalize pointer behavior

Nikita Popov via All-commits all-commits at lists.llvm.org
Sat Aug 29 12:17:23 PDT 2020


  Branch: refs/heads/master
  Home:   https://github.com/llvm/llvm-project
  Commit: 6d88f6efd44852b995de3a1620ea67b6381c1ad9
      https://github.com/llvm/llvm-project/commit/6d88f6efd44852b995de3a1620ea67b6381c1ad9
  Author: Nikita Popov <nikita.ppv at gmail.com>
  Date:   2020-08-29 (Sat, 29 Aug 2020)

  Changed paths:
    M llvm/lib/Analysis/LazyValueInfo.cpp
    M llvm/test/Transforms/CorrelatedValuePropagation/non-null.ll

  Log Message:
  -----------
  Reapply [LVI] Normalize pointer behavior

This got reverted because a dependency was reverted. It has since
been reapplied, so reapply this as well.

-----

Related to D69686. As noted there, LVI currently behaves differently
for integer and pointer values: For integers, the block value is always
valid inside the basic block, while for pointers it is only valid at
the end of the basic block. I believe the integer behavior is the
correct one, and CVP relies on it via its getConstantRange() uses.

The reason for the special pointer behavior is that LVI checks whether
a pointer is dereferenced in a given basic block and marks it as
non-null in that case. Of course, this information is valid only after
the dereferencing instruction, or in conservative approximation,
at the end of the block.

This patch changes the treatment of dereferencability: Instead of
including it inside the block value, we instead treat it as something
similar to an assume (it essentially is a non-nullness assume) and
incorporate this information in intersectAssumeOrGuardBlockValueConstantRange()
if the context instruction is the terminator of the basic block.
This happens either when determining an edge-value internally in LVI,
or when a terminator was explicitly passed to getValueAt(). The latter
case makes this more powerful than the previous implementation as
a side-effect, and this does actually seem benefitial in practice.

Of course, we do not want to recompute dereferencability on each
intersectAssume call, so we need a new cache for this. The
dereferencability analysis requires walking the entire basic block
and computing underlying objects of all memory operands. This was
previously done separately for each queried pointer value. In the
new implementation (both because this makes the caching simpler,
and because it is faster), I instead only walk the full BB once and
cache all the dereferenced pointers. So the traversal is now performed
only once per BB, instead of once per queried pointer value.

I think the overall model now makes more sense than before, and there
will be no more pitfalls due to differing integer/pointer behavior.

Differential Revision: https://reviews.llvm.org/D69914




More information about the All-commits mailing list