[llvm] r328004 - Add an analysis printer for must execute reasoning

Philip Reames via llvm-commits llvm-commits at lists.llvm.org
Thu Mar 29 12:25:40 PDT 2018


Should be fixed in 328816.


On 03/29/2018 10:28 AM, Philip Reames via llvm-commits wrote:
>
> I'll have to look at the compiler errors to see what's used.  I hadn't 
> intended to leave any of the required functionality in Transforms and 
> I'm confused as to what I might have missed.  I'm hoping it's 
> something minor.
>
>
> On 03/29/2018 10:24 AM, David Blaikie wrote:
>> Ah, sorry - I think I tested that first & found it was used. I forget 
>> what the particular use was - but should be easy to reproduce & 
>> hopefully there's some good fix for it. Happy to help with the 
>> implementation or ideas about how to address it if you like.
>>
>> On Thu, Mar 29, 2018 at 10:15 AM Philip Reames 
>> <listmail at philipreames.com <mailto:listmail at philipreames.com>> wrote:
>>
>>
>>
>>     On 03/28/2018 04:16 PM, David Blaikie wrote:
>>>
>>>
>>>     On Tue, Mar 20, 2018 at 10:11 AM Philip Reames via llvm-commits
>>>     <llvm-commits at lists.llvm.org
>>>     <mailto:llvm-commits at lists.llvm.org>> wrote:
>>>
>>>         Author: reames
>>>         Date: Tue Mar 20 10:09:21 2018
>>>         New Revision: 328004
>>>
>>>         URL: http://llvm.org/viewvc/llvm-project?rev=328004&view=rev
>>>         Log:
>>>         Add an analysis printer for must execute reasoning
>>>
>>>         Many of our loop passes make use of so called "must execute"
>>>         or "guaranteed to execute" facts to prove the legality of
>>>         code motion. The basic notion is that we know (by
>>>         assumption) an instruction didn't fault at it's original
>>>         location, so if the location we move it to is strictly post
>>>         dominated by the original, then we can't have introduced a
>>>         new fault.
>>>
>>>         At the moment, the testing for this logic is somewhat adhoc
>>>         and done mostly through LICM. Since I'm working on that
>>>         code, I want to improve the testing. This patch is the first
>>>         step in that direction. It doesn't actually test the variant
>>>         used by the loop passes - I need to move that to the
>>>         Analysis library first - but instead exercises an alternate
>>>         implementation used by SCEV. (I plan on merging both
>>>         implementations.)
>>>
>>>         Note: I'll be replacing the printing logic within this with
>>>         an annotation based version in the near future.  Anna
>>>         suggested this in review, and it seems like a strictly
>>>         better format.
>>>
>>>         Differential Revision: https://reviews.llvm.org/D44524
>>>
>>>
>>>         Added:
>>>             llvm/trunk/lib/Analysis/MustExecute.cpp
>>>             llvm/trunk/test/Analysis/MustExecute/
>>>         llvm/trunk/test/Analysis/MustExecute/loop-header.ll
>>>         Modified:
>>>             llvm/trunk/include/llvm/Analysis/Passes.h
>>>             llvm/trunk/include/llvm/InitializePasses.h
>>>             llvm/trunk/include/llvm/LinkAllPasses.h
>>>             llvm/trunk/lib/Analysis/Analysis.cpp
>>>             llvm/trunk/lib/Analysis/CMakeLists.txt
>>>
>>>         Modified: llvm/trunk/include/llvm/Analysis/Passes.h
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Passes.h?rev=328004&r1=328003&r2=328004&view=diff
>>>         ==============================================================================
>>>         --- llvm/trunk/include/llvm/Analysis/Passes.h (original)
>>>         +++ llvm/trunk/include/llvm/Analysis/Passes.h Tue Mar 20
>>>         10:09:21 2018
>>>         @@ -96,6 +96,14 @@ namespace llvm {
>>>            //
>>>            FunctionPass *createMemDerefPrinter();
>>>
>>>         +
>>>         //===--------------------------------------------------------------------===//
>>>         +  //
>>>         +  // createMustExecutePrinter - This pass collects
>>>         information about which
>>>         +  // instructions within a loop are guaranteed to execute
>>>         if the loop header is
>>>         +  // entered and prints it with -analyze.
>>>         +  //
>>>         +  FunctionPass *createMustExecutePrinter();
>>>         +
>>>          }
>>>
>>>          #endif
>>>
>>>         Modified: llvm/trunk/include/llvm/InitializePasses.h
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=328004&r1=328003&r2=328004&view=diff
>>>         ==============================================================================
>>>         --- llvm/trunk/include/llvm/InitializePasses.h (original)
>>>         +++ llvm/trunk/include/llvm/InitializePasses.h Tue Mar 20
>>>         10:09:21 2018
>>>         @@ -268,6 +268,7 @@ void initializeMergedLoadStoreMotionLega
>>>          void initializeMetaRenamerPass(PassRegistry&);
>>>          void initializeModuleDebugInfoPrinterPass(PassRegistry&);
>>>          void
>>>         initializeModuleSummaryIndexWrapperPassPass(PassRegistry&);
>>>         +void initializeMustExecutePrinterPass(PassRegistry&);
>>>          void initializeNameAnonGlobalLegacyPassPass(PassRegistry&);
>>>          void initializeNaryReassociateLegacyPassPass(PassRegistry&);
>>>          void initializeNewGVNLegacyPassPass(PassRegistry&);
>>>
>>>         Modified: llvm/trunk/include/llvm/LinkAllPasses.h
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=328004&r1=328003&r2=328004&view=diff
>>>         ==============================================================================
>>>         --- llvm/trunk/include/llvm/LinkAllPasses.h (original)
>>>         +++ llvm/trunk/include/llvm/LinkAllPasses.h Tue Mar 20
>>>         10:09:21 2018
>>>         @@ -207,6 +207,7 @@ namespace {
>>>                (void) llvm::createRewriteSymbolsPass();
>>>                (void) llvm::createStraightLineStrengthReducePass();
>>>                (void) llvm::createMemDerefPrinter();
>>>         +      (void) llvm::createMustExecutePrinter();
>>>                (void) llvm::createFloat2IntPass();
>>>                (void) llvm::createEliminateAvailableExternallyPass();
>>>                (void) llvm::createScalarizeMaskedMemIntrinPass();
>>>
>>>         Modified: llvm/trunk/lib/Analysis/Analysis.cpp
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=328004&r1=328003&r2=328004&view=diff
>>>         ==============================================================================
>>>         --- llvm/trunk/lib/Analysis/Analysis.cpp (original)
>>>         +++ llvm/trunk/lib/Analysis/Analysis.cpp Tue Mar 20 10:09:21
>>>         2018
>>>         @@ -65,6 +65,7 @@ void llvm::initializeAnalysis(PassRegist
>>>          initializeMemoryDependenceWrapperPassPass(Registry);
>>>            initializeModuleDebugInfoPrinterPass(Registry);
>>>          initializeModuleSummaryIndexWrapperPassPass(Registry);
>>>         +  initializeMustExecutePrinterPass(Registry);
>>>            initializeObjCARCAAWrapperPassPass(Registry);
>>>          initializeOptimizationRemarkEmitterWrapperPassPass(Registry);
>>>          initializePostDominatorTreeWrapperPassPass(Registry);
>>>
>>>         Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=328004&r1=328003&r2=328004&view=diff
>>>         ==============================================================================
>>>         --- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
>>>         +++ llvm/trunk/lib/Analysis/CMakeLists.txt Tue Mar 20
>>>         10:09:21 2018
>>>         @@ -58,6 +58,7 @@ add_llvm_library(LLVMAnalysis
>>>            MemorySSAUpdater.cpp
>>>            ModuleDebugInfoPrinter.cpp
>>>            ModuleSummaryAnalysis.cpp
>>>         +  MustExecute.cpp
>>>            ObjCARCAliasAnalysis.cpp
>>>            ObjCARCAnalysisUtils.cpp
>>>            ObjCARCInstKind.cpp
>>>
>>>         Added: llvm/trunk/lib/Analysis/MustExecute.cpp
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MustExecute.cpp?rev=328004&view=auto
>>>         ==============================================================================
>>>         --- llvm/trunk/lib/Analysis/MustExecute.cpp (added)
>>>         +++ llvm/trunk/lib/Analysis/MustExecute.cpp Tue Mar 20
>>>         10:09:21 2018
>>>         @@ -0,0 +1,102 @@
>>>         +//===- MustExecute.cpp - Printer for isGuaranteedToExecute
>>>         ----------------===//
>>>         +//
>>>         +//                     The LLVM Compiler Infrastructure
>>>         +//
>>>         +// This file is distributed under the University of
>>>         Illinois Open Source
>>>         +// License. See LICENSE.TXT for details.
>>>         +//
>>>         +//===----------------------------------------------------------------------===//
>>>         +
>>>         +#include "llvm/Analysis/LoopInfo.h"
>>>         +#include "llvm/Analysis/Passes.h"
>>>         +#include "llvm/Analysis/ValueTracking.h"
>>>         +#include "llvm/IR/DataLayout.h"
>>>         +#include "llvm/IR/InstIterator.h"
>>>         +#include "llvm/IR/LLVMContext.h"
>>>         +#include "llvm/IR/Module.h"
>>>         +#include "llvm/Support/ErrorHandling.h"
>>>         +#include "llvm/Support/raw_ostream.h"
>>>         +#include "llvm/Transforms/Utils/LoopUtils.h"
>>>
>>>
>>>     This looks like a circular/invalid dependency? Transforms depend
>>>     on Analysis, not the other way around?
>>>
>>>     Would be great to get this fixed - happy to help, if you've some
>>>     ideas.
>>>
>>>     Moving the whole LoopUtils isn't immediately possible, its
>>>     implementation depends on BasicBlockUtils. (& also many of these
>>>     utilities seem more for mutation, which isn't relevant to
>>>     Analysis - so maybe it needs to be split up?)
>>     I think this is just a stale header include.  I'm building to
>>     confirm now and if so will remove it.
>>>
>>>         +using namespace llvm;
>>>         +
>>>         +namespace {
>>>         +  struct MustExecutePrinter : public FunctionPass {
>>>         +    DenseMap<Value*, SmallVector<Loop*, 4> > MustExec;
>>>         +    SmallVector<Value *, 4> Ordering;
>>>         +
>>>         +    static char ID; // Pass identification, replacement for
>>>         typeid
>>>         +    MustExecutePrinter() : FunctionPass(ID) {
>>>         +
>>>         initializeMustExecutePrinterPass(*PassRegistry::getPassRegistry());
>>>         +    }
>>>         +    void getAnalysisUsage(AnalysisUsage &AU) const override {
>>>         +      AU.setPreservesAll();
>>>         + AU.addRequired<DominatorTreeWrapperPass>();
>>>         + AU.addRequired<LoopInfoWrapperPass>();
>>>         +    }
>>>         +    bool runOnFunction(Function &F) override;
>>>         +    void print(raw_ostream &OS, const Module * = nullptr)
>>>         const override;
>>>         +    void releaseMemory() override {
>>>         +      MustExec.clear();
>>>         +      Ordering.clear();
>>>         +    }
>>>         +  };
>>>         +}
>>>         +
>>>         +char MustExecutePrinter::ID = 0;
>>>         +INITIALIZE_PASS_BEGIN(MustExecutePrinter, "print-mustexecute",
>>>         +                      "Instructions which execute on loop
>>>         entry", false, true)
>>>         +INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
>>>         +INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
>>>         +INITIALIZE_PASS_END(MustExecutePrinter, "print-mustexecute",
>>>         +                    "Instructions which execute on loop
>>>         entry", false, true)
>>>         +
>>>         +FunctionPass *llvm::createMustExecutePrinter() {
>>>         +  return new MustExecutePrinter();
>>>         +}
>>>         +
>>>         +bool isMustExecuteIn(Instruction &I, Loop *L, DominatorTree
>>>         *DT) {
>>>         +  // TODO: move loop specific code to analysis
>>>         +  //LoopSafetyInfo LSI;
>>>         +  //computeLoopSafetyInfo(&LSI, L);
>>>         +  //return isGuaranteedToExecute(I, DT, L, &LSI);
>>>         +  return isGuaranteedToExecuteForEveryIteration(&I, L);
>>>         +}
>>>         +
>>>         +bool MustExecutePrinter::runOnFunction(Function &F) {
>>>         +  auto &LI = getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
>>>         +  auto &DT =
>>>         getAnalysis<DominatorTreeWrapperPass>().getDomTree();
>>>         +  for (auto &I: instructions(F)) {
>>>         +    Loop *L = LI.getLoopFor(I.getParent());
>>>         +    while (L) {
>>>         +      if (isMustExecuteIn(I, L, &DT)) {
>>>         +        if (!MustExec.count(&I))
>>>         +          Ordering.push_back(&I);
>>>         +        MustExec[&I].push_back(L);
>>>         +      }
>>>         +      L = L->getParentLoop();
>>>         +    };
>>>         +  }
>>>         +  return false;
>>>         +}
>>>         +
>>>         +void MustExecutePrinter::print(raw_ostream &OS, const
>>>         Module *M) const {
>>>         +  OS << "The following are guaranteed to execute (for the
>>>         respective loops):\n";
>>>         +  for (Value *V: Ordering) {
>>>         +    V->printAsOperand(OS);
>>>         +    auto NumLoops = MustExec.lookup(V).size();
>>>         +    if (NumLoops > 1)
>>>         +      OS << "\t(mustexec in " << NumLoops << " loops: ";
>>>         +    else
>>>         +      OS << "\t(mustexec in: ";
>>>         +
>>>         +    bool first = true;
>>>         +    for (const Loop *L : MustExec.lookup(V)) {
>>>         +      if (!first)
>>>         +        OS << ", ";
>>>         +      first = false;
>>>         +      OS << L->getHeader()->getName();
>>>         +    }
>>>         +    OS << ")\n";
>>>         +  }
>>>         +  OS << "\n";
>>>         +}
>>>
>>>         Added: llvm/trunk/test/Analysis/MustExecute/loop-header.ll
>>>         URL:
>>>         http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/MustExecute/loop-header.ll?rev=328004&view=auto
>>>         ==============================================================================
>>>         --- llvm/trunk/test/Analysis/MustExecute/loop-header.ll (added)
>>>         +++ llvm/trunk/test/Analysis/MustExecute/loop-header.ll Tue
>>>         Mar 20 10:09:21 2018
>>>         @@ -0,0 +1,80 @@
>>>         +; RUN: opt -analyze -print-mustexecute %s
>>>         +
>>>         +; CHECK: Printing analysis 'Instructions which execute on
>>>         loop entry' for function 'header_with_icf':
>>>         +; CHECK: The following are guaranteed to execute (for the
>>>         respective loops):
>>>         +; CHECK:   %iv = phi i32 [ 0, %entry ], [ %iv.next, %loop
>>>         ]    (mustexec in: loop)
>>>         +; CHECK:   %v = load i32, i32* %p      (mustexec in: loop)
>>>         +; CHECK:   call void @maythrow_and_use(i32 %v) (mustexec
>>>         in: loop)
>>>         +; CHECK-NOT: add
>>>         +define i1 @header_with_icf(i32* noalias %p, i32 %high) {
>>>         +entry:
>>>         +  br label %loop
>>>         +
>>>         +loop:
>>>         +  %iv = phi i32 [0, %entry], [%iv.next, %loop]
>>>         +  %v = load i32, i32* %p
>>>         +  call void @maythrow_and_use(i32 %v)
>>>         +  %iv.next = add nsw nuw i32 %iv, 1
>>>         +  %exit.test = icmp slt i32 %iv, %high
>>>         +  br i1 %exit.test, label %exit, label %loop
>>>         +
>>>         +exit:
>>>         +  ret i1 false
>>>         +}
>>>         +
>>>         +; CHECK: Printing analysis 'Instructions which execute on
>>>         loop entry' for function 'test':
>>>         +; CHECK: The following are guaranteed to execute (for the
>>>         respective loops):
>>>         +; CHECK:   %iv = phi i32 [ 0, %entry ], [ %iv.next, %next
>>>         ]    (mustexec in: loop)
>>>         +; CHECK:   %v = load i32, i32* %p      (mustexec in: loop)
>>>         +; CHECK:   br label %next      (mustexec in: loop)
>>>         +define i1 @test(i32* noalias %p, i32 %high) {
>>>         +entry:
>>>         +  br label %loop
>>>         +
>>>         +loop:
>>>         +  %iv = phi i32 [0, %entry], [%iv.next, %next]
>>>         +  %v = load i32, i32* %p
>>>         +  br label %next
>>>         +next:
>>>         +  call void @maythrow_and_use(i32 %v)
>>>         +  %iv.next = add nsw nuw i32 %iv, 1
>>>         +  %exit.test = icmp slt i32 %iv, %high
>>>         +  br i1 %exit.test, label %exit, label %loop
>>>         +
>>>         +exit:
>>>         +  ret i1 false
>>>         +}
>>>         +
>>>         +; CHECK: Printing analysis 'Instructions which execute on
>>>         loop entry' for function 'nested':
>>>         +; CHECK: The following are guaranteed to execute (for the
>>>         respective loops):
>>>         +; CHECK:   %iv = phi i32 [ 0, %entry ], [ %iv.next, %next
>>>         ]    (mustexec in: loop)
>>>         +; CHECK:   br label %inner_loop        (mustexec in: loop)
>>>         +; FIXME: These three are also must execute for the outer loop.
>>>         +; CHECK:   %v = load i32, i32* %p      (mustexec in:
>>>         inner_loop)
>>>         +; CHECK:   %inner.test = icmp eq i32 %v, 0  (mustexec in:
>>>         inner_loop)
>>>         +; CHECK:   br i1 %inner.test, label %inner_loop, label
>>>         %next   (mustexec in: inner_loop)
>>>         +define i1 @nested(i32* noalias %p, i32 %high) {
>>>         +entry:
>>>         +  br label %loop
>>>         +
>>>         +loop:
>>>         +  %iv = phi i32 [0, %entry], [%iv.next, %next]
>>>         +  br label %inner_loop
>>>         +
>>>         +inner_loop:
>>>         +  %v = load i32, i32* %p
>>>         +  %inner.test = icmp eq i32 %v, 0
>>>         +  br i1 %inner.test, label %inner_loop, label %next
>>>         +
>>>         +next:
>>>         +  call void @maythrow_and_use(i32 %v)
>>>         +  %iv.next = add nsw nuw i32 %iv, 1
>>>         +  %exit.test = icmp slt i32 %iv, %high
>>>         +  br i1 %exit.test, label %exit, label %loop
>>>         +
>>>         +exit:
>>>         +  ret i1 false
>>>         +}
>>>         +
>>>         +
>>>         +declare void @maythrow_and_use(i32)
>>>
>>>
>>>         _______________________________________________
>>>         llvm-commits mailing list
>>>         llvm-commits at lists.llvm.org <mailto:llvm-commits at lists.llvm.org>
>>>         http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits
>>>
>>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180329/d8e5a564/attachment.html>


More information about the llvm-commits mailing list