This is an archive of the discontinued LLVM Phabricator instance.

[LVI] Add an LVI printer pass to capture test LVI cache after transformations
ClosedPublic

Authored by anna on Mar 9 2017, 1:43 PM.

Details

Summary

Adding a printer pass for printing the LVI cache values after transformations
that use LVI.
This will help us in identifying cases where LVI
invariants are violated, or transforms that leave LVI in an incorrect state.
Right now, I have added two test cases to show that the printer pass is working.
I will be adding more test cases in a later change, once this change is
checked in upstream.

Event Timeline

anna created this revision.Mar 9 2017, 1:43 PM
apilipenko edited edge metadata.Mar 10 2017, 3:04 AM

It's worth noting for others that the motivation for the change is a bug we found in JumpThreading LVI cache invalidation. The bug is easily triggered with our downstream changes, but is difficult to trigger it upstream. We need the printer pass to write an isolated upstream test case for this problem.

include/llvm/Analysis/LazyValueInfo.h
101

Here and below - /// doxygen documentation comment

102

Here and below - just printCache?

lib/Analysis/LazyValueInfo.cpp
449

For the sake of completeness you might also want to print overdefined cache.

anna added a comment.Mar 10 2017, 5:08 AM

It's worth noting for others that the motivation for the change is a bug we found in JumpThreading LVI cache invalidation. The bug is easily triggered with our downstream changes, but is difficult to trigger it upstream. We need the printer pass to write an isolated upstream test case for this problem.

Yes, the motivation is the bug :)
It is *easier* to trigger the bug upstream with printer pass after jump-threading. This pass will also help in uncovering/testing any other LVI caching issues or LVI broken invariants. Also, we can easily print the LVI cache within any pass (using LVI) as LVI->printLazyValueInfoCache(errs()).

anna marked 2 inline comments as done.Mar 10 2017, 9:04 AM
anna added inline comments.
include/llvm/Analysis/LazyValueInfo.h
102

how about printCaches? Since we'll print both the overdefined and the LVICache.

lib/Analysis/LazyValueInfo.cpp
449

agreed. I've added printing of overdefined per basic block.

apilipenko added inline comments.Mar 10 2017, 9:06 AM
include/llvm/Analysis/LazyValueInfo.h
102

Works for me

anna updated this revision to Diff 91364.Mar 10 2017, 9:21 AM
anna marked an inline comment as done.

Added printing for the overdefined cache, updated tests.

anna marked an inline comment as done.Mar 10 2017, 9:22 AM
anna added inline comments.
include/llvm/Analysis/LazyValueInfo.h
102

Both overdefined and latticevaluecache are defined within the LVICache. So, left as printCache itself.

apilipenko accepted this revision.Mar 10 2017, 9:55 AM
This revision is now accepted and ready to land.Mar 10 2017, 9:55 AM
dberlin added inline comments.Mar 10 2017, 10:09 AM
include/llvm/Analysis/LazyValueInfo.h
102

What's the reason for datalayout?
It's always gettable from any instruction, etc.

lib/Analysis/LazyValueInfo.cpp
444

FWIW: I would generally recommend you do this as an annotation to the basic blocks/values, using the asm printer interface, and adding them as comments.

This would produce output similar to print-predicateinfo, print-memoryssa, etc, where the values are right above the instructions they belong to.

This usually makes it significantly easier to test and understand what is going on, IME.

I have not looked at this specific case, of course.

But, for example, the iteration order here is *completely* undefined, meaning you have to be prepared for the output to appear in any order.

448

BB's don't always have names, i would use BV.first->printAsOperand(), which will also handle the nameless ones properly.

1858

You should add a new PM version of this as well.

1871

I do not believe we normally print to errs for printing passes.
I believe they still print to dbgs()

anna added inline comments.Mar 10 2017, 10:35 AM
include/llvm/Analysis/LazyValueInfo.h
102

We need it here for getting the LazyValueInfoImpl within this function. I don't think we have any other way for getting the datalayout.

see: getImpl(PImpl, AC, &DL, DT).printCache(OS);

lib/Analysis/LazyValueInfo.cpp
444

Yes, since the order would be completely undefined, I used the CHECK-DAG part here along with the CHECK-LABEL.
Thanks, I will take a look at the asm printer interface used in the other print functions.

1871

So, couple of ones still print to errs, like the AliasSetPrinter (that's the one I followed for this). It looks like most printing passes print to dbgs(), I can change to that.

dberlin added inline comments.Mar 10 2017, 10:41 AM
include/llvm/Analysis/LazyValueInfo.h
102

Oh, yeah, this is just silly.
It looks like LazyValueInfo doesn't have DL, but all the impl's require it.
This looks like it was just the simplest conversion possible.

I would just add it to the class LazyValueInfo interface, since everything else is there.

anna marked an inline comment as done.Mar 12 2017, 1:00 PM

Hi folks,
Daniel added a suggestion regarding the printing of the LVI:

FWIW: I would generally recommend you do this as an annotation to the basic blocks/values, using the asm printer interface, and adding them as comments.

This would produce output similar to print-predicateinfo, print-memoryssa, etc, where the values are right above the instructions they belong to.

This usually makes it significantly easier to test and understand what is going on, IME.

I had a look at the print-predicateinfo, and agree with Daniel - adding annotations as comments before the instruction makes it easier to see what's the transformation (along with the LVI values). However, in the LVI case, an instruction would have a list of LatticeValues corresponding to different basic blocks. Also, the LatticeValueCache structure enables printing the annotation per instruction (the cache key is ssa value). The overdefined cache structure enables printing per basic block. So, the print would be something like this:

For test2 example (see annotations added as comments):

entry:
; ' i32 %n ' is overdefined
  br label %loop

loop
;  %iv2 = phi i32 [ %n, %entry ], [ %iv2.next, %backedge ] '  is overdefined
; 'constantrange<0, -2147483647>' at the beginning of 'loop'
; 'constantrange<0, -2147483648>' at the beginning of 'backedge'
  %iv = phi i32 [0, %entry], [%iv.next, %backedge] <-- the values corresponding to the `%iv` per basic block, are annotated before the instruction.
  %iv2 = phi i32 [%n, %entry], [%iv2.next, %backedge]
  %cnd1 = icmp sge i32 %iv, 0
  %cnd2 = icmp sgt i32 %iv2, 0
  %cnd = and i1 %cnd1, %cnd2
  br i1 %cnd, label %backedge, label %exit

backedge:
; 'constantrange<1, -2147483647>' at the beginning of  'backedge'
  %iv.next = add nsw i32 %iv, 1
  %iv2.next = sub nsw i32 %iv2, 1
  %cont1 = icmp slt i32 %iv.next, 400
  %cont2 = icmp sgt i32 %iv2.next, 0
  %cont = and i1 %cont1, %cont2
  br i1 %cont, label %loop, label %exit

exit:
  ret i8 0

I think it looks clearer than the CHECK-DAG and CHECK-LABEL combination I have for test2 currently.

Does this look better?

include/llvm/Analysis/LazyValueInfo.h
102

Thanks, added as a separate NFC.

anna marked an inline comment as done.Mar 12 2017, 1:03 PM
anna planned changes to this revision.Mar 13 2017, 6:24 AM

As per comment above. Changing this to use the AssemblyAnnotationWriter.

anna updated this revision to Diff 91722.Mar 14 2017, 7:29 AM
anna marked 3 inline comments as done.

Updated the pass to use the AseemblyAnnotationWriter.
Addressed other review comments.
Tests updated accordingly.

I have not yet added the new pass manager version, I'll add for review once this is completed.
(The new pass manager version of the LVIPrinter compiles, but it does not use the existing LVI object, I'll debug that on the side.
Don't want to block this review on that issue).

This revision is now accepted and ready to land.Mar 14 2017, 7:29 AM
anna requested review of this revision.Mar 14 2017, 7:31 AM
anna edited edge metadata.

Review for the updated version. The previous LGTMed version did not return the annotation as comments.

dberlin accepted this revision.Mar 22 2017, 9:48 AM

I think this looks good to me :)
Thanks for doing this!

This revision is now accepted and ready to land.Mar 22 2017, 9:48 AM
This revision was automatically updated to reflect the committed changes.
anna added a comment.Mar 23 2017, 10:52 AM

Thanks Daniel!

I'll submit a follow on patch (directly) for capturing lattice values of the function's arguments. Just realized while adding some test cases that the AssemblyAnnotationWriter only prints info for instructions and basic blocks.