[llvm] r291651 - [PM] Rewrite the loop pass manager to use a worklist and augmented run

Ivan Krasin via llvm-commits llvm-commits at lists.llvm.org
Wed Jan 11 16:55:14 PST 2017


On Wed, Jan 11, 2017 at 4:49 PM, Pete Cooper <peter_cooper at apple.com> wrote:

>
> On Jan 11, 2017, at 4:48 PM, Ivan Krasin <krasin at google.com> wrote:
>
>
>
> On Wed, Jan 11, 2017 at 4:40 PM, Pete Cooper <peter_cooper at apple.com>
> wrote:
>
>>
>> On Jan 11, 2017, at 4:20 PM, Ivan Krasin <krasin at google.com> wrote:
>>
>> Hi Pete,
>>
>> On Wed, Jan 11, 2017 at 4:17 PM, Pete Cooper <peter_cooper at apple.com>
>> wrote:
>>
>>> Hi Ivan
>>>
>>> We frequently discuss which minimum version of GCC/MSVC LLVM should
>>> support building on.  The minimum GCC has often been driven from wanting to
>>> support building on Ubuntu LTS (currently I think this is 12.04).
>>>
>>> Surely if 16.04 is needed for this fix, then this could impact users
>>> outside of the bots?  In that case, we should either raise the minimum to
>>> 16.04, or we need Chanler to fix the code?
>>>
>> This upgrade only affects sanitizer bots which build LLVM / Clang with
>> UBSan. The regular bots will stay the same, and therefore no immediate
>> impact on the users of older systems is expected.
>>
>> So, we don't need to raise the minimum and I also believe there's nothing
>> for Chandler to fix. The issue (undefined behavior) is in the libstdc++ map
>> implementation.
>>
>> I'm not sure I agree, but then i'm not a linux user so maybe i'm missing
>> something.
>>
>> We want clang to build on Ubuntu LTS without any need to install
>> anything.  If we were willing to get users to install new software then we
>> would also be able to get them to download a new GCC, but we decided
>> against that in the various discussions on raising the minimum requirements.
>>
>> Then again, maybe we don't have as strict a requirement if sanitizes are
>> enabled?
>>
> Oh, I see the confusion here. There are no issues with building Clang on
> Linux and the sanitizers are still enabled there.
> The only issue is when Clang itself is instrumented with UBSan
> (-fsanitize=alignment, in particular). Then running Clang might cause UBSan
> to complain about an undefined behavior. This is not an issue for Clang
> users, as they use a regular, non-instrumented Clang.
>
> This is only an issue for sanitizers bots which build Clang with multiple
> different sanitizers to make sure Clang itself does not have any bugs which
> can be found with sanitizers. And I am only upgrading those meta-bots. All
> regular bots stay the same, and no changes in the systems support of the
> compilers we ship is expected.
>
> That makes a lot more sense.  Thanks for the detailed explanation, and
> sorry for the confusion.
>
No problem. I have planted the seeds for this confusion in my first reply
to Mike as I have forgot to specify which bots I am going to upgrade. And
re-reading that message really leaves an impression that I am on the
crusade to upgrade everything to 16.04 (which I am not).

Thank you for raising the concerns, and I am glad that the confusion is now
cleared!

krasin

>
>
>>
>> At the very least, I think this should be documented here
>> http://llvm.org/docs/GettingStarted.html#host-c-toolcha
>> in-both-compiler-and-standard-library.
>>
> As I have (hopefully) explained above, the readers of this document won't
> hit this issue, as they will only deal with the regular Clang, not a
> special debug version.
>
> Yep, totally agree.  Thanks!
>
> Pete
>
>
>
>> Thanks,
>> Pete
>>
>>
>>
>>> Short term, the code needs to be fixed, as raising the minimum version
>>> is never a short conversation.
>>>
>>> Thanks,
>>> Pete
>>>
>>> On Jan 11, 2017, at 3:54 PM, Ivan Krasin via llvm-commits <
>>> llvm-commits at lists.llvm.org> wrote:
>>>
>>> Grrr. A typo. Please, read: there's nothing wrong with the code
>>> (Chandler's CL) *AND* the remedy would be ...
>>>
>>> On Wed, Jan 11, 2017 at 3:51 PM, Ivan Krasin <krasin at google.com> wrote:
>>>
>>>> Mike,
>>>>
>>>> this is a known and fixed issue in libstdc++: https://gcc.gnu.org
>>>> /bugzilla/show_bug.cgi?id=60734
>>>> There's nothing wrong with the code in the remedy would be to upgrade
>>>> buildbots to newer Ubuntu (16.04) which have this undefined behavior fixed.
>>>> This work is in the progress. ETA: end of day.
>>>>
>>>> On Wed, Jan 11, 2017 at 3:49 PM, Mike Aizatsky <aizatsky at google.com>
>>>> wrote:
>>>>
>>>>> Chandler,
>>>>>
>>>>> Looks like ubsan complains about this change:
>>>>>
>>>>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-fas
>>>>> t/builds/2034
>>>>>
>>>>> [ RUN      ] LoopPassManagerTest.FunctionPa
>>>>> ssInvalidationOfLoopAnalyses
>>>>> /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_tree.h:1540:28:
>>>>> runtime error: upcast of address 0x00000366a0d0 with insufficient space for
>>>>> an object of type 'std::_Rb_tree_node<std::pair<const void *const,
>>>>> testing::(anonymous namespace)::MockObjectState> >'
>>>>> 0x00000366a0d0: note: pointer points here
>>>>>  00 00 00 00  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  d0 a0
>>>>> 66 03 00 00 00 00  d0 a0 66 03
>>>>>               ^
>>>>>     #0 0xc4d1b7 in std::_Rb_tree<void const*, std::pair<void const*
>>>>> const, testing::(anonymous namespace)::MockObjectState>,
>>>>> std::_Select1st<std::pair<void const* const, testing::(anonymous
>>>>> namespace)::MockObjectState> >, std::less<void const*>,
>>>>> std::allocator<std::pair<void const* const, testing::(anonymous
>>>>> namespace)::MockObjectState> > >::_M_get_insert_hint_unique_p
>>>>> os(std::_Rb_tree_const_iterator<std::pair<void const* const,
>>>>> testing::(anonymous namespace)::MockObjectState> >, void const* const&)
>>>>> /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.
>>>>> 9/bits/stl_tree.h:1540:28
>>>>>     #1 0xc4ce76 in std::_Rb_tree_iterator<std::pair<void const*
>>>>> const, testing::(anonymous namespace)::MockObjectState> >
>>>>> std::_Rb_tree<void const*, std::pair<void const* const, testing::(anonymous
>>>>> namespace)::MockObjectState>, std::_Select1st<std::pair<void const* const,
>>>>> testing::(anonymous namespace)::MockObjectState> >, std::less<void const*>,
>>>>> std::allocator<std::pair<void const* const, testing::(anonymous
>>>>> namespace)::MockObjectState> > >::_M_emplace_hint_unique<std::piecewise_construct_t
>>>>> const&, std::tuple<void const* const&>, std::tuple<>
>>>>> >(std::_Rb_tree_const_iterator<std::pair<void const* const,
>>>>> testing::(anonymous namespace)::MockObjectState> >,
>>>>> std::piecewise_construct_t const&, std::tuple<void const* const&>&&,
>>>>> std::tuple<>&&) /usr/lib/gcc/x86_64-linux-gnu/
>>>>> 4.9/../../../../include/c++/4.9/bits/stl_tree.h:1794:19
>>>>>     #2 0xc4b713 in std::map<void const*, testing::(anonymous
>>>>> namespace)::MockObjectState, std::less<void const*>,
>>>>> std::allocator<std::pair<void const* const, testing::(anonymous
>>>>> namespace)::MockObjectState> > >::operator[](void const* const&)
>>>>> /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.
>>>>> 9/bits/stl_map.h:500:15
>>>>>     #3 0xc4a2d8 in testing::Mock::Register(void const*,
>>>>> testing::internal::UntypedFunctionMockerBase*)
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googlemock/src/gmock-spec-builders.cc:715:3
>>>>>     #4 0xc4a27c in testing::internal::UntypedFunc
>>>>> tionMockerBase::RegisterOwner(void const*)
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googlemock/src/gmock-spec-builders.cc:285:3
>>>>>     #5 0x4efbc9 in (anonymous namespace)::MockLoopAnalysisHa
>>>>> ndleTemplate<18446744073709551615ul>::gmock_run(testing::Matcher<llvm::Loop&>
>>>>> const&, testing::Matcher<llvm::AnalysisManager<llvm::Loop,
>>>>> llvm::LoopStandardAnalysisResults&>&> const&,
>>>>> testing::Matcher<llvm::LoopStandardAnalysisResults&> const&)
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/unittests/Analysis/LoopPassManagerTest.cpp:120:3
>>>>>     #6 0x4ed31b in (anonymous namespace)::MockAnalysisHandleBase<(anonymous
>>>>> namespace)::MockLoopAnalysisHandleTemplate<18446744073709551615ul>,
>>>>> llvm::Loop, llvm::AnalysisManager<llvm::Loop,
>>>>> llvm::LoopStandardAnalysisResults&>, llvm::LoopStandardAnalysisResults&>::setDefaults()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/unittests/Analysis/LoopPassManagerTest.cpp:82:5
>>>>>     #7 0x4eb262 in (anonymous namespace)::LoopPassManagerTest::LoopPassManagerTest()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/unittests/Analysis/LoopPassManagerTest.cpp:242:3
>>>>>     #8 0x4f44ba in (anonymous namespace)::LoopPassManagerTes
>>>>> t_FunctionPassInvalidationOfLoopAnalyses_Test::LoopPassManag
>>>>> erTest_FunctionPassInvalidationOfLoopAnalyses_Test()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/unittests/Analysis/LoopPassManagerTest.cpp:346:1
>>>>>     #9 0x4f447f in testing::internal::TestFactoryImpl<(anonymous
>>>>> namespace)::LoopPassManagerTest_FunctionPassInvalidationOfLoopAnalyses_Test>::CreateTest()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googletest/include/gtest/internal/gtest
>>>>> -internal.h:484:43
>>>>>     #10 0xc15510 in testing::TestInfo::Run()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googletest/src/gtest.cc:2647:22
>>>>>     #11 0xc15c32 in testing::TestCase::Run()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googletest/src/gtest.cc:2774:28
>>>>>     #12 0xc1c013 in testing::internal::UnitTestImpl::RunAllTests()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googletest/src/gtest.cc:4649:43
>>>>>     #13 0xc1bcab in testing::UnitTest::Run()
>>>>> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build
>>>>> /llvm/utils/unittest/googletest/src/gtest.cc:4257:10
>>>>>     #14 0xc0aef3 in main /mnt/b/sanitizer-buildbot3/san
>>>>> itizer-x86_64-linux-fast/build/llvm/utils/unittest/UnitTestM
>>>>> ain/TestMain.cpp:51:10
>>>>>     #15 0x7fe430cb6f44 in __libc_start_main
>>>>> (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
>>>>>     #16 0x414903 in _start (/mnt/b/sanitizer-buildbot3/sa
>>>>> nitizer-x86_64-linux-fast/build/llvm_build_ubsan/unittests/A
>>>>> nalysis/AnalysisTests+0x414903)
>>>>>
>>>>>
>>>>>
>>>>> On Tue, Jan 10, 2017 at 10:34 PM Chandler Carruth via llvm-commits <
>>>>> llvm-commits at lists.llvm.org> wrote:
>>>>>
>>>>>> Author: chandlerc
>>>>>> Date: Wed Jan 11 00:23:21 2017
>>>>>> New Revision: 291651
>>>>>>
>>>>>> URL: http://llvm.org/viewvc/llvm-project?rev=291651&view=rev
>>>>>> Log:
>>>>>> [PM] Rewrite the loop pass manager to use a worklist and augmented run
>>>>>> arguments much like the CGSCC pass manager.
>>>>>>
>>>>>> This is a major redesign following the pattern establish for the
>>>>>> CGSCC layer to
>>>>>> support updates to the set of loops during the traversal of the loop
>>>>>> nest and
>>>>>> to support invalidation of analyses.
>>>>>>
>>>>>> An additional significant burden in the loop PM is that so many
>>>>>> passes require
>>>>>> access to a large number of function analyses. Manually ensuring
>>>>>> these are
>>>>>> cached, available, and preserved has been a long-standing burden in
>>>>>> LLVM even
>>>>>> with the help of the automatic scheduling in the old pass manager.
>>>>>> And it made
>>>>>> the new pass manager extremely unweildy. With this design, we can
>>>>>> package the
>>>>>> common analyses up while in a function pass and make them immediately
>>>>>> available
>>>>>> to all the loop passes. While in some cases this is unnecessary, I
>>>>>> think the
>>>>>> simplicity afforded is worth it.
>>>>>>
>>>>>> This does not (yet) address loop simplified form or LCSSA form, but
>>>>>> those are
>>>>>> the next things on my radar and I have a clear plan for them.
>>>>>>
>>>>>> While the patch is very large, most of it is either mechanically
>>>>>> updating loop
>>>>>> passes to the new API or the new testing for the loop PM. The code
>>>>>> for it is
>>>>>> reasonably compact.
>>>>>>
>>>>>> I have not yet updated all of the loop passes to correctly leverage
>>>>>> the update
>>>>>> mechanisms demonstrated in the unittests. I'll do that in follow-up
>>>>>> patches
>>>>>> along with improved FileCheck tests for those passes that ensure
>>>>>> things work in
>>>>>> more realistic scenarios. In many cases, there isn't much we can do
>>>>>> with these
>>>>>> until the loop simplified form and LCSSA form are in place.
>>>>>>
>>>>>> Differential Revision: https://reviews.llvm.org/D28292
>>>>>>
>>>>>> Modified:
>>>>>>     llvm/trunk/include/llvm/Analysis/IVUsers.h
>>>>>>     llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h
>>>>>>     llvm/trunk/include/llvm/Analysis/LoopInfo.h
>>>>>>     llvm/trunk/include/llvm/Analysis/LoopPassManager.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/IndVarSimplify.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LICM.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopDeletion.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopInstSimplify.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopRotation.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
>>>>>>     llvm/trunk/include/llvm/Transforms/Scalar/LoopUnrollPass.h
>>>>>>     llvm/trunk/lib/Analysis/IVUsers.cpp
>>>>>>     llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp
>>>>>>     llvm/trunk/lib/Analysis/LoopInfo.cpp
>>>>>>     llvm/trunk/lib/Analysis/LoopPass.cpp
>>>>>>     llvm/trunk/lib/Analysis/LoopPassManager.cpp
>>>>>>     llvm/trunk/lib/Passes/PassBuilder.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LICM.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopStrengthReduce.cpp
>>>>>>     llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
>>>>>>     llvm/trunk/lib/Transforms/Vectorize/LoopVectorize.cpp
>>>>>>     llvm/trunk/test/Other/loop-pass-ordering.ll
>>>>>>     llvm/trunk/test/Other/new-pass-manager.ll
>>>>>>     llvm/trunk/test/Other/pass-pipeline-parsing.ll
>>>>>>     llvm/trunk/unittests/Analysis/LoopPassManagerTest.cpp
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Analysis/IVUsers.h?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Analysis/IVUsers.h (original)
>>>>>> +++ llvm/trunk/include/llvm/Analysis/IVUsers.h Wed Jan 11 00:23:21
>>>>>> 2017
>>>>>> @@ -193,7 +193,8 @@ class IVUsersAnalysis : public AnalysisI
>>>>>>  public:
>>>>>>    typedef IVUsers Result;
>>>>>>
>>>>>> -  IVUsers run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  IVUsers run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +              LoopStandardAnalysisResults &AR);
>>>>>>  };
>>>>>>
>>>>>>  /// Printer pass for the \c IVUsers for a loop.
>>>>>> @@ -202,7 +203,8 @@ class IVUsersPrinterPass : public PassIn
>>>>>>
>>>>>>  public:
>>>>>>    explicit IVUsersPrinterPass(raw_ostream &OS) : OS(OS) {}
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  }
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Analysis/LoopAccessAnalysis.h?rev=291651&r1=291650&r2=291651
>>>>>> &view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h (original)
>>>>>> +++ llvm/trunk/include/llvm/Analysis/LoopAccessAnalysis.h Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -753,8 +753,8 @@ class LoopAccessAnalysis
>>>>>>
>>>>>>  public:
>>>>>>    typedef LoopAccessInfo Result;
>>>>>> -  Result run(Loop &, LoopAnalysisManager &);
>>>>>> -  static StringRef name() { return "LoopAccessAnalysis"; }
>>>>>> +
>>>>>> +  Result run(Loop &L, LoopAnalysisManager &AM,
>>>>>> LoopStandardAnalysisResults &AR);
>>>>>>  };
>>>>>>
>>>>>>  /// \brief Printer pass for the \c LoopAccessInfo results.
>>>>>> @@ -764,7 +764,8 @@ class LoopAccessInfoPrinterPass
>>>>>>
>>>>>>  public:
>>>>>>    explicit LoopAccessInfoPrinterPass(raw_ostream &OS) : OS(OS) {}
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>
>>>>>>  inline Instruction *MemoryDepChecker::Dependence::getSource(
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Analysis/LoopInfo.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Analysis/LoopInfo.h?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Analysis/LoopInfo.h (original)
>>>>>> +++ llvm/trunk/include/llvm/Analysis/LoopInfo.h Wed Jan 11 00:23:21
>>>>>> 2017
>>>>>> @@ -853,17 +853,8 @@ public:
>>>>>>    void getAnalysisUsage(AnalysisUsage &AU) const override;
>>>>>>  };
>>>>>>
>>>>>> -/// \brief Pass for printing a loop's contents as LLVM's text IR
>>>>>> assembly.
>>>>>> -class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
>>>>>> -  raw_ostream &OS;
>>>>>> -  std::string Banner;
>>>>>> -
>>>>>> -public:
>>>>>> -  PrintLoopPass();
>>>>>> -  PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
>>>>>> -
>>>>>> -  PreservedAnalyses run(Loop &L, AnalysisManager<Loop> &);
>>>>>> -};
>>>>>> +/// Function to print a loop's contents as LLVM's text IR assembly.
>>>>>> +void printLoop(Loop &L, raw_ostream &OS, const std::string &Banner =
>>>>>> "");
>>>>>>
>>>>>>  } // End llvm namespace
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Analysis/LoopPassManager.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Analysis/LoopPassManager.h?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Analysis/LoopPassManager.h (original)
>>>>>> +++ llvm/trunk/include/llvm/Analysis/LoopPassManager.h Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -8,63 +8,342 @@
>>>>>>  //===------------------------------------------------------
>>>>>> ----------------===//
>>>>>>  /// \file
>>>>>>  ///
>>>>>> -/// This header provides classes for managing passes over loops in
>>>>>> LLVM IR.
>>>>>> +/// This header provides classes for managing a pipeline of passes
>>>>>> over loops
>>>>>> +/// in LLVM IR.
>>>>>> +///
>>>>>> +/// The primary loop pass pipeline is managed in a very particular
>>>>>> way to
>>>>>> +/// provide a set of core guarantees:
>>>>>> +/// 1) Loops are, where possible, in simplified form.
>>>>>> +/// 2) Loops are *always* in LCSSA form.
>>>>>> +/// 3) A collection of Loop-specific analysis results are available:
>>>>>> +///    - LoopInfo
>>>>>> +///    - DominatorTree
>>>>>> +///    - ScalarEvolution
>>>>>> +///    - AAManager
>>>>>> +/// 4) All loop passes preserve #1 (where possible), #2, and #3.
>>>>>> +/// 5) Loop passes run over each loop in the loop nest from the
>>>>>> innermost to
>>>>>> +///    the outermost. Specifically, all inner loops are processed
>>>>>> before
>>>>>> +///    passes run over outer loops. When running the pipeline across
>>>>>> an inner
>>>>>> +///    loop creates new inner loops, those are added and processed
>>>>>> in this
>>>>>> +///    order as well.
>>>>>> +///
>>>>>> +/// This process is designed to facilitate transformations which
>>>>>> simplify,
>>>>>> +/// reduce, and remove loops. For passes which are more oriented
>>>>>> towards
>>>>>> +/// optimizing loops, especially optimizing loop *nests* instead of
>>>>>> single
>>>>>> +/// loops in isolation, this framework is less interesting.
>>>>>>  ///
>>>>>>  //===------------------------------------------------------
>>>>>> ----------------===//
>>>>>>
>>>>>>  #ifndef LLVM_ANALYSIS_LOOPPASSMANAGER_H
>>>>>>  #define LLVM_ANALYSIS_LOOPPASSMANAGER_H
>>>>>>
>>>>>> +#include "llvm/ADT/PostOrderIterator.h"
>>>>>> +#include "llvm/ADT/PriorityWorklist.h"
>>>>>>  #include "llvm/ADT/STLExtras.h"
>>>>>>  #include "llvm/Analysis/AliasAnalysis.h"
>>>>>> +#include "llvm/Analysis/BasicAliasAnalysis.h"
>>>>>> +#include "llvm/Analysis/GlobalsModRef.h"
>>>>>>  #include "llvm/Analysis/LoopInfo.h"
>>>>>>  #include "llvm/Analysis/ScalarEvolution.h"
>>>>>> +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
>>>>>>  #include "llvm/Analysis/TargetLibraryInfo.h"
>>>>>> +#include "llvm/Analysis/TargetTransformInfo.h"
>>>>>>  #include "llvm/IR/Dominators.h"
>>>>>>  #include "llvm/IR/PassManager.h"
>>>>>>
>>>>>>  namespace llvm {
>>>>>>
>>>>>> -extern template class PassManager<Loop>;
>>>>>> -/// \brief The loop pass manager.
>>>>>> -///
>>>>>> -/// See the documentation for the PassManager template for details.
>>>>>> It runs a
>>>>>> -/// sequency of loop passes over each loop that the manager is run
>>>>>> over. This
>>>>>> -/// typedef serves as a convenient way to refer to this construct.
>>>>>> -typedef PassManager<Loop> LoopPassManager;
>>>>>> +// Forward declarations of a update tracking and analysis result
>>>>>> tracking
>>>>>> +// structures used in the API of loop passes that work within this
>>>>>> +// infrastructure.
>>>>>> +class LPMUpdater;
>>>>>> +struct LoopStandardAnalysisResults;
>>>>>>
>>>>>> -extern template class AnalysisManager<Loop>;
>>>>>> +/// Extern template declaration for the analysis set for this IR
>>>>>> unit.
>>>>>> +extern template class AllAnalysesOn<Loop>;
>>>>>> +
>>>>>> +extern template class AnalysisManager<Loop,
>>>>>> LoopStandardAnalysisResults &>;
>>>>>>  /// \brief The loop analysis manager.
>>>>>>  ///
>>>>>>  /// See the documentation for the AnalysisManager template for detail
>>>>>>  /// documentation. This typedef serves as a convenient way to refer
>>>>>> to this
>>>>>>  /// construct in the adaptors and proxies used to integrate this
>>>>>> into the larger
>>>>>>  /// pass manager infrastructure.
>>>>>> -typedef AnalysisManager<Loop> LoopAnalysisManager;
>>>>>> +typedef AnalysisManager<Loop, LoopStandardAnalysisResults &>
>>>>>> +    LoopAnalysisManager;
>>>>>> +
>>>>>> +// Explicit specialization and instantiation declarations for the
>>>>>> pass manager.
>>>>>> +// See the comments on the definition of the specialization for
>>>>>> details on how
>>>>>> +// it differs from the primary template.
>>>>>> +template <>
>>>>>> +PreservedAnalyses
>>>>>> +PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
>>>>>> +            LPMUpdater &>::run(Loop &InitialL, LoopAnalysisManager
>>>>>> &AM,
>>>>>> +                               LoopStandardAnalysisResults
>>>>>> &AnalysisResults,
>>>>>> +                               LPMUpdater &U);
>>>>>> +extern template class PassManager<Loop, LoopAnalysisManager,
>>>>>> +                                  LoopStandardAnalysisResults &,
>>>>>> LPMUpdater &>;
>>>>>> +
>>>>>> +/// \brief The Loop pass manager.
>>>>>> +///
>>>>>> +/// See the documentation for the PassManager template for details.
>>>>>> It runs
>>>>>> +/// a sequence of Loop passes over each Loop that the manager is run
>>>>>> over. This
>>>>>> +/// typedef serves as a convenient way to refer to this construct.
>>>>>> +typedef PassManager<Loop, LoopAnalysisManager,
>>>>>> LoopStandardAnalysisResults &,
>>>>>> +                    LPMUpdater &>
>>>>>> +    LoopPassManager;
>>>>>> +
>>>>>> +/// A partial specialization of the require analysis template pass
>>>>>> to forward
>>>>>> +/// the extra parameters from a transformation's run method to the
>>>>>> +/// AnalysisManager's getResult.
>>>>>> +template <typename AnalysisT>
>>>>>> +struct RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
>>>>>> +                           LoopStandardAnalysisResults &, LPMUpdater
>>>>>> &>
>>>>>> +    : PassInfoMixin<
>>>>>> +          RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
>>>>>> +                              LoopStandardAnalysisResults &,
>>>>>> LPMUpdater &>> {
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &) {
>>>>>> +    (void)AM.template getResult<AnalysisT>(L, AR);
>>>>>> +    return PreservedAnalyses::all();
>>>>>> +  }
>>>>>> +};
>>>>>> +
>>>>>> +/// An alias template to easily name a require analysis loop pass.
>>>>>> +template <typename AnalysisT>
>>>>>> +using RequireAnalysisLoopPass =
>>>>>> +    RequireAnalysisPass<AnalysisT, Loop, LoopAnalysisManager,
>>>>>> +                        LoopStandardAnalysisResults &, LPMUpdater &>;
>>>>>>
>>>>>>  /// A proxy from a \c LoopAnalysisManager to a \c Function.
>>>>>>  typedef InnerAnalysisManagerProxy<LoopAnalysisManager, Function>
>>>>>>      LoopAnalysisManagerFunctionProxy;
>>>>>>
>>>>>> -/// Specialization of the invalidate method for the \c
>>>>>> -/// LoopAnalysisManagerFunctionProxy's result.
>>>>>> +/// A specialized result for the \c LoopAnalysisManagerFunctionProxy
>>>>>> which
>>>>>> +/// retains a \c LoopInfo reference.
>>>>>> +///
>>>>>> +/// This allows it to collect loop objects for which analysis
>>>>>> results may be
>>>>>> +/// cached in the \c LoopAnalysisManager.
>>>>>> +template <> class LoopAnalysisManagerFunctionProxy::Result {
>>>>>> +public:
>>>>>> +  explicit Result(LoopAnalysisManager &InnerAM, LoopInfo &LI)
>>>>>> +      : InnerAM(&InnerAM), LI(&LI) {}
>>>>>> +  Result(Result &&Arg) : InnerAM(std::move(Arg.InnerAM)),
>>>>>> LI(Arg.LI) {
>>>>>> +    // We have to null out the analysis manager in the moved-from
>>>>>> state
>>>>>> +    // because we are taking ownership of the responsibilty to clear
>>>>>> the
>>>>>> +    // analysis state.
>>>>>> +    Arg.InnerAM = nullptr;
>>>>>> +  }
>>>>>> +  Result &operator=(Result &&RHS) {
>>>>>> +    InnerAM = RHS.InnerAM;
>>>>>> +    LI = RHS.LI <http://rhs.li/>;
>>>>>> +    // We have to null out the analysis manager in the moved-from
>>>>>> state
>>>>>> +    // because we are taking ownership of the responsibilty to clear
>>>>>> the
>>>>>> +    // analysis state.
>>>>>> +    RHS.InnerAM = nullptr;
>>>>>> +    return *this;
>>>>>> +  }
>>>>>> +  ~Result() {
>>>>>> +    // InnerAM is cleared in a moved from state where there is
>>>>>> nothing to do.
>>>>>> +    if (!InnerAM)
>>>>>> +      return;
>>>>>> +
>>>>>> +    // Clear out the analysis manager if we're being destroyed -- it
>>>>>> means we
>>>>>> +    // didn't even see an invalidate call when we got invalidated.
>>>>>> +    InnerAM->clear();
>>>>>> +  }
>>>>>> +
>>>>>> +  /// Accessor for the analysis manager.
>>>>>> +  LoopAnalysisManager &getManager() { return *InnerAM; }
>>>>>> +
>>>>>> +  /// Handler for invalidation of the proxy for a particular
>>>>>> function.
>>>>>> +  ///
>>>>>> +  /// If the proxy, \c LoopInfo, and associated analyses are
>>>>>> preserved, this
>>>>>> +  /// will merely forward the invalidation event to any cached loop
>>>>>> analysis
>>>>>> +  /// results for loops within this function.
>>>>>> +  ///
>>>>>> +  /// If the necessary loop infrastructure is not preserved, this
>>>>>> will forcibly
>>>>>> +  /// clear all of the cached analysis results that are keyed on the
>>>>>> \c
>>>>>> +  /// LoopInfo for this function.
>>>>>> +  bool invalidate(Function &F, const PreservedAnalyses &PA,
>>>>>> +                  FunctionAnalysisManager::Invalidator &Inv);
>>>>>> +
>>>>>> +private:
>>>>>> +  LoopAnalysisManager *InnerAM;
>>>>>> +  LoopInfo *LI;
>>>>>> +};
>>>>>> +
>>>>>> +/// Provide a specialized run method for the \c
>>>>>> LoopAnalysisManagerFunctionProxy
>>>>>> +/// so it can pass the \c LoopInfo to the result.
>>>>>>  template <>
>>>>>> -bool LoopAnalysisManagerFunctionProxy::Result::invalidate(
>>>>>> -    Function &F, const PreservedAnalyses &PA,
>>>>>> -    FunctionAnalysisManager::Invalidator &Inv);
>>>>>> +LoopAnalysisManagerFunctionProxy::Result
>>>>>> +LoopAnalysisManagerFunctionProxy::run(Function &F,
>>>>>> FunctionAnalysisManager &AM);
>>>>>>
>>>>>>  // Ensure the \c LoopAnalysisManagerFunctionProxy is provided as an
>>>>>> extern
>>>>>>  // template.
>>>>>>  extern template class InnerAnalysisManagerProxy<LoopAnalysisManager,
>>>>>> Function>;
>>>>>>
>>>>>> -extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager,
>>>>>> Loop>;
>>>>>> +extern template class OuterAnalysisManagerProxy<FunctionAnalysisManager,
>>>>>> Loop,
>>>>>> +
>>>>>> LoopStandardAnalysisResults &>;
>>>>>>  /// A proxy from a \c FunctionAnalysisManager to a \c Loop.
>>>>>> -typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop>
>>>>>> +typedef OuterAnalysisManagerProxy<FunctionAnalysisManager, Loop,
>>>>>> +                                  LoopStandardAnalysisResults &>
>>>>>>      FunctionAnalysisManagerLoopProxy;
>>>>>>
>>>>>>  /// Returns the minimum set of Analyses that all loop passes must
>>>>>> preserve.
>>>>>>  PreservedAnalyses getLoopPassPreservedAnalyses();
>>>>>>
>>>>>> +namespace internal {
>>>>>> +/// Helper to implement appending of loops onto a worklist.
>>>>>> +///
>>>>>> +/// We want to process loops in postorder, but the worklist is a
>>>>>> LIFO data
>>>>>> +/// structure, so we append to it in *reverse* postorder.
>>>>>> +///
>>>>>> +/// For trees, a preorder traversal is a viable reverse postorder,
>>>>>> so we
>>>>>> +/// actually append using a preorder walk algorithm.
>>>>>> +template <typename RangeT>
>>>>>> +inline void appendLoopsToWorklist(RangeT &&Loops,
>>>>>> +                                  SmallPriorityWorklist<Loop *, 4>
>>>>>> &Worklist) {
>>>>>> +  // We use an internal worklist to build up the preorder traversal
>>>>>> without
>>>>>> +  // recursion.
>>>>>> +  SmallVector<Loop *, 4> PreOrderLoops, PreOrderWorklist;
>>>>>> +
>>>>>> +  // We walk the initial sequence of loops in reverse because we
>>>>>> generally want
>>>>>> +  // to visit defs before uses and the worklist is LIFO.
>>>>>> +  for (Loop *RootL : reverse(Loops)) {
>>>>>> +    assert(PreOrderLoops.empty() && "Must start with an empty
>>>>>> preorder walk.");
>>>>>> +    assert(PreOrderWorklist.empty() &&
>>>>>> +           "Must start with an empty preorder walk worklist.");
>>>>>> +    PreOrderWorklist.push_back(RootL);
>>>>>> +    do {
>>>>>> +      Loop *L = PreOrderWorklist.pop_back_val();
>>>>>> +      PreOrderWorklist.append(L->begin(), L->end());
>>>>>> +      PreOrderLoops.push_back(L);
>>>>>> +    } while (!PreOrderWorklist.empty());
>>>>>> +
>>>>>> +    Worklist.insert(std::move(PreOrderLoops));
>>>>>> +    PreOrderLoops.clear();
>>>>>> +  }
>>>>>> +}
>>>>>> +}
>>>>>> +
>>>>>> +/// The adaptor from a function pass to a loop pass directly computes
>>>>>> +/// a standard set of analyses that are especially useful to loop
>>>>>> passes and
>>>>>> +/// makes them available in the API. Loop passes are also expected
>>>>>> to update
>>>>>> +/// all of these so that they remain correct across the entire loop
>>>>>> pipeline.
>>>>>> +struct LoopStandardAnalysisResults {
>>>>>> +  AAResults &AA;
>>>>>> +  AssumptionCache &AC;
>>>>>> +  DominatorTree &DT;
>>>>>> +  LoopInfo &LI;
>>>>>> +  ScalarEvolution &SE;
>>>>>> +  TargetLibraryInfo &TLI;
>>>>>> +  TargetTransformInfo &TTI;
>>>>>> +};
>>>>>> +
>>>>>> +template <typename LoopPassT> class FunctionToLoopPassAdaptor;
>>>>>> +
>>>>>> +/// This class provides an interface for updating the loop pass
>>>>>> manager based
>>>>>> +/// on mutations to the loop nest.
>>>>>> +///
>>>>>> +/// A reference to an instance of this class is passed as an
>>>>>> argument to each
>>>>>> +/// Loop pass, and Loop passes should use it to update LPM
>>>>>> infrastructure if
>>>>>> +/// they modify the loop nest structure.
>>>>>> +class LPMUpdater {
>>>>>> +public:
>>>>>> +  /// This can be queried by loop passes which run other loop passes
>>>>>> (like pass
>>>>>> +  /// managers) to know whether the loop needs to be skipped due to
>>>>>> updates to
>>>>>> +  /// the loop nest.
>>>>>> +  ///
>>>>>> +  /// If this returns true, the loop object may have been deleted,
>>>>>> so passes
>>>>>> +  /// should take care not to touch the object.
>>>>>> +  bool skipCurrentLoop() const { return SkipCurrentLoop; }
>>>>>> +
>>>>>> +  /// Loop passes should use this method to indicate they have
>>>>>> deleted a loop
>>>>>> +  /// from the nest.
>>>>>> +  ///
>>>>>> +  /// Note that this loop must either be the current loop or a
>>>>>> subloop of the
>>>>>> +  /// current loop. This routine must be called prior to removing
>>>>>> the loop from
>>>>>> +  /// the loop nest.
>>>>>> +  ///
>>>>>> +  /// If this is called for the current loop, in addition to
>>>>>> clearing any
>>>>>> +  /// state, this routine will mark that the current loop should be
>>>>>> skipped by
>>>>>> +  /// the rest of the pass management infrastructure.
>>>>>> +  void markLoopAsDeleted(Loop &L) {
>>>>>> +    LAM.clear(L);
>>>>>> +    assert(CurrentL->contains(&L) && "Cannot delete a loop outside
>>>>>> of the "
>>>>>> +                                     "subloop tree currently being
>>>>>> processed.");
>>>>>> +    if (&L == CurrentL)
>>>>>> +      SkipCurrentLoop = true;
>>>>>> +  }
>>>>>> +
>>>>>> +  /// Loop passes should use this method to indicate they have added
>>>>>> new child
>>>>>> +  /// loops of the current loop.
>>>>>> +  ///
>>>>>> +  /// \p NewChildLoops must contain only the immediate children. Any
>>>>>> nested
>>>>>> +  /// loops within them will be visited in postorder as usual for
>>>>>> the loop pass
>>>>>> +  /// manager.
>>>>>> +  void addChildLoops(ArrayRef<Loop *> NewChildLoops) {
>>>>>> +    // Insert ourselves back into the worklist first, as this loop
>>>>>> should be
>>>>>> +    // revisited after all the children have been processed.
>>>>>> +    Worklist.insert(CurrentL);
>>>>>> +
>>>>>> +#ifndef NDEBUG
>>>>>> +    for (Loop *NewL : NewChildLoops)
>>>>>> +      assert(NewL->getParentLoop() == CurrentL && "All of the new
>>>>>> loops must "
>>>>>> +                                                  "be immediate
>>>>>> children of "
>>>>>> +                                                  "the current
>>>>>> loop!");
>>>>>> +#endif
>>>>>> +
>>>>>> +    internal::appendLoopsToWorklist(NewChildLoops, Worklist);
>>>>>> +
>>>>>> +    // Also skip further processing of the current loop--it will be
>>>>>> revisited
>>>>>> +    // after all of its newly added children are accounted for.
>>>>>> +    SkipCurrentLoop = true;
>>>>>> +  }
>>>>>> +
>>>>>> +  /// Loop passes should use this method to indicate they have added
>>>>>> new
>>>>>> +  /// sibling loops to the current loop.
>>>>>> +  ///
>>>>>> +  /// \p NewSibLoops must only contain the immediate sibling loops.
>>>>>> Any nested
>>>>>> +  /// loops within them will be visited in postorder as usual for
>>>>>> the loop pass
>>>>>> +  /// manager.
>>>>>> +  void addSiblingLoops(ArrayRef<Loop *> NewSibLoops) {
>>>>>> +#ifndef NDEBUG
>>>>>> +    for (Loop *NewL : NewSibLoops)
>>>>>> +      assert(NewL->getParentLoop() == ParentL &&
>>>>>> +             "All of the new loops must be siblings of the current
>>>>>> loop!");
>>>>>> +#endif
>>>>>> +
>>>>>> +    internal::appendLoopsToWorklist(NewSibLoops, Worklist);
>>>>>> +
>>>>>> +    // No need to skip the current loop or revisit it, as sibling
>>>>>> loops
>>>>>> +    // shouldn't impact anything.
>>>>>> +  }
>>>>>> +
>>>>>> +private:
>>>>>> +  template <typename LoopPassT> friend class
>>>>>> llvm::FunctionToLoopPassAdaptor;
>>>>>> +
>>>>>> +  /// The \c FunctionToLoopPassAdaptor's worklist of loops to
>>>>>> process.
>>>>>> +  SmallPriorityWorklist<Loop *, 4> &Worklist;
>>>>>> +
>>>>>> +  /// The analysis manager for use in the current loop nest.
>>>>>> +  LoopAnalysisManager &LAM;
>>>>>> +
>>>>>> +  Loop *CurrentL;
>>>>>> +  bool SkipCurrentLoop;
>>>>>> +
>>>>>> +#ifndef NDEBUG
>>>>>> +  // In debug builds we also track the parent loop to implement
>>>>>> asserts even in
>>>>>> +  // the face of loop deletion.
>>>>>> +  Loop *ParentL;
>>>>>> +#endif
>>>>>> +
>>>>>> +  LPMUpdater(SmallPriorityWorklist<Loop *, 4> &Worklist,
>>>>>> +             LoopAnalysisManager &LAM)
>>>>>> +      : Worklist(Worklist), LAM(LAM) {}
>>>>>> +};
>>>>>> +
>>>>>>  /// \brief Adaptor that maps from a function to its loops.
>>>>>>  ///
>>>>>>  /// Designed to allow composition of a LoopPass(Manager) and a
>>>>>> @@ -87,42 +366,61 @@ public:
>>>>>>      // Get the loop structure for this function
>>>>>>      LoopInfo &LI = AM.getResult<LoopAnalysis>(F);
>>>>>>
>>>>>> -    // Also precompute all of the function analyses used by loop
>>>>>> passes.
>>>>>> -    // FIXME: These should be handed into the loop passes when the
>>>>>> loop pass
>>>>>> -    // management layer is reworked to follow the design of CGSCC.
>>>>>> -    (void)AM.getResult<AAManager>(F);
>>>>>> -    (void)AM.getResult<DominatorTreeAnalysis>(F);
>>>>>> -    (void)AM.getResult<ScalarEvolutionAnalysis>(F);
>>>>>> -    (void)AM.getResult<TargetLibraryAnalysis>(F);
>>>>>> +    // If there are no loops, there is nothing to do here.
>>>>>> +    if (LI.empty())
>>>>>> +      return PreservedAnalyses::all();
>>>>>> +
>>>>>> +    // Get the analysis results needed by loop passes.
>>>>>> +    LoopStandardAnalysisResults LAR = {AM.getResult<AAManager>(F),
>>>>>> +                                       AM.getResult<AssumptionAnalys
>>>>>> is>(F),
>>>>>> +                                       AM.getResult<DominatorTreeAna
>>>>>> lysis>(F),
>>>>>> +                                       AM.getResult<LoopAnalysis>(F)
>>>>>> ,
>>>>>> +                                       AM.getResult<ScalarEvolutionA
>>>>>> nalysis>(F),
>>>>>> +                                       AM.getResult<TargetLibraryAna
>>>>>> lysis>(F),
>>>>>> +                                       AM.getResult<TargetIRAnalysis
>>>>>> >(F)};
>>>>>>
>>>>>>      PreservedAnalyses PA = PreservedAnalyses::all();
>>>>>>
>>>>>> -    // We want to visit the loops in reverse post-order. We'll build
>>>>>> the stack
>>>>>> -    // of loops to visit in Loops by first walking the loops in
>>>>>> pre-order.
>>>>>> -    SmallVector<Loop *, 2> Loops;
>>>>>> -    SmallVector<Loop *, 2> WorkList(LI.begin(), LI.end());
>>>>>> -    while (!WorkList.empty()) {
>>>>>> -      Loop *L = WorkList.pop_back_val();
>>>>>> -      WorkList.insert(WorkList.end(), L->begin(), L->end());
>>>>>> -      Loops.push_back(L);
>>>>>> -    }
>>>>>> -
>>>>>> -    // Now pop each element off of the stack to visit the loops in
>>>>>> reverse
>>>>>> -    // post-order.
>>>>>> -    for (auto *L : reverse(Loops)) {
>>>>>> -      PreservedAnalyses PassPA = Pass.run(*L, LAM);
>>>>>> +    // A postorder worklist of loops to process.
>>>>>> +    SmallPriorityWorklist<Loop *, 4> Worklist;
>>>>>> +
>>>>>> +    // Register the worklist and loop analysis manager so that loop
>>>>>> passes can
>>>>>> +    // update them when they mutate the loop nest structure.
>>>>>> +    LPMUpdater Updater(Worklist, LAM);
>>>>>> +
>>>>>> +    // Add the loop nests in the reverse order of LoopInfo. For some
>>>>>> reason,
>>>>>> +    // they are stored in RPO w.r.t. the control flow graph in
>>>>>> LoopInfo. For
>>>>>> +    // the purpose of unrolling, loop deletion, and LICM, we largely
>>>>>> want to
>>>>>> +    // work forward across the CFG so that we visit defs before uses
>>>>>> and can
>>>>>> +    // propagate simplifications from one loop nest into the next.
>>>>>> +    // FIXME: Consider changing the order in LoopInfo.
>>>>>> +    internal::appendLoopsToWorklist(reverse(LI), Worklist);
>>>>>> +
>>>>>> +    do {
>>>>>> +      Loop *L = Worklist.pop_back_val();
>>>>>> +
>>>>>> +      // Reset the update structure for this loop.
>>>>>> +      Updater.CurrentL = L;
>>>>>> +      Updater.SkipCurrentLoop = false;
>>>>>> +#ifndef NDEBUG
>>>>>> +      Updater.ParentL = L->getParentLoop();
>>>>>> +#endif
>>>>>> +
>>>>>> +      PreservedAnalyses PassPA = Pass.run(*L, LAM, LAR, Updater);
>>>>>>        // FIXME: We should verify the set of analyses relevant to
>>>>>> Loop passes
>>>>>>        // are preserved.
>>>>>>
>>>>>> -      // We know that the loop pass couldn't have invalidated any
>>>>>> other loop's
>>>>>> -      // analyses (that's the contract of a loop pass), so directly
>>>>>> handle the
>>>>>> -      // loop analysis manager's invalidation here.
>>>>>> -      LAM.invalidate(*L, PassPA);
>>>>>> +      // If the loop hasn't been deleted, we need to handle
>>>>>> invalidation here.
>>>>>> +      if (!Updater.skipCurrentLoop())
>>>>>> +        // We know that the loop pass couldn't have invalidated any
>>>>>> other
>>>>>> +        // loop's analyses (that's the contract of a loop pass), so
>>>>>> directly
>>>>>> +        // handle the loop analysis manager's invalidation here.
>>>>>> +        LAM.invalidate(*L, PassPA);
>>>>>>
>>>>>>        // Then intersect the preserved set so that invalidation of
>>>>>> module
>>>>>>        // analyses will eventually occur when the module pass
>>>>>> completes.
>>>>>>        PA.intersect(std::move(PassPA));
>>>>>> -    }
>>>>>> +    } while (!Worklist.empty());
>>>>>>
>>>>>>      // By definition we preserve the proxy. We also preserve all
>>>>>> analyses on
>>>>>>      // Loops. This precludes *any* invalidation of loop analyses by
>>>>>> the proxy,
>>>>>> @@ -130,6 +428,17 @@ public:
>>>>>>      // loop analysis manager incrementally above.
>>>>>>      PA.preserveSet<AllAnalysesOn<Loop>>();
>>>>>>      PA.preserve<LoopAnalysisManagerFunctionProxy>();
>>>>>> +    // We also preserve the set of standard analyses.
>>>>>> +    PA.preserve<AssumptionAnalysis>();
>>>>>> +    PA.preserve<DominatorTreeAnalysis>();
>>>>>> +    PA.preserve<LoopAnalysis>();
>>>>>> +    PA.preserve<ScalarEvolutionAnalysis>();
>>>>>> +    // FIXME: What we really want to do here is preserve an AA
>>>>>> category, but
>>>>>> +    // that concept doesn't exist yet.
>>>>>> +    PA.preserve<AAManager>();
>>>>>> +    PA.preserve<BasicAA>();
>>>>>> +    PA.preserve<GlobalsAA>();
>>>>>> +    PA.preserve<SCEVAA>();
>>>>>>      return PA;
>>>>>>    }
>>>>>>
>>>>>> @@ -144,6 +453,19 @@ FunctionToLoopPassAdaptor<LoopPassT>
>>>>>>  createFunctionToLoopPassAdaptor(LoopPassT Pass) {
>>>>>>    return FunctionToLoopPassAdaptor<LoopPassT>(std::move(Pass));
>>>>>>  }
>>>>>> +
>>>>>> +/// \brief Pass for printing a loop's contents as textual IR.
>>>>>> +class PrintLoopPass : public PassInfoMixin<PrintLoopPass> {
>>>>>> +  raw_ostream &OS;
>>>>>> +  std::string Banner;
>>>>>> +
>>>>>> +public:
>>>>>> +  PrintLoopPass();
>>>>>> +  PrintLoopPass(raw_ostream &OS, const std::string &Banner = "");
>>>>>> +
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
>>>>>> +                        LoopStandardAnalysisResults &, LPMUpdater &);
>>>>>> +};
>>>>>>  }
>>>>>>
>>>>>>  #endif // LLVM_ANALYSIS_LOOPPASSMANAGER_H
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/IndVarSimplify.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/IndVarSimplify.h?rev=291651&r1=291650&r2=2
>>>>>> 91651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/IndVarSimplify.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/IndVarSimplify.h Wed
>>>>>> Jan 11 00:23:21 2017
>>>>>> @@ -23,7 +23,8 @@ namespace llvm {
>>>>>>
>>>>>>  class IndVarSimplifyPass : public PassInfoMixin<IndVarSimplifyPass>
>>>>>> {
>>>>>>  public:
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  }
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/LICM.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LICM.h?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LICM.h (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LICM.h Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -42,7 +42,8 @@ namespace llvm {
>>>>>>  /// Performs Loop Invariant Code Motion Pass.
>>>>>>  class LICMPass : public PassInfoMixin<LICMPass> {
>>>>>>  public:
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  } // end namespace llvm
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/LoopDeletion.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopDeletion.h?rev=291651&r1=291650&r2=291
>>>>>> 651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopDeletion.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopDeletion.h Wed Jan
>>>>>> 11 00:23:21 2017
>>>>>> @@ -24,7 +24,8 @@ namespace llvm {
>>>>>>  class LoopDeletionPass : public PassInfoMixin<LoopDeletionPass> {
>>>>>>  public:
>>>>>>    LoopDeletionPass() {}
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>    bool runImpl(Loop *L, DominatorTree &DT, ScalarEvolution &SE,
>>>>>>                LoopInfo &loopInfo);
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transf
>>>>>> orms/Scalar/LoopIdiomRecognize.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopIdiomRecognize.h?rev=291651&r1=291650&
>>>>>> r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopIdiomRecognize.h
>>>>>> Wed Jan 11 00:23:21 2017
>>>>>> @@ -25,7 +25,8 @@ namespace llvm {
>>>>>>  /// Performs Loop Idiom Recognize Pass.
>>>>>>  class LoopIdiomRecognizePass : public PassInfoMixin<LoopIdiomRecognizePass>
>>>>>> {
>>>>>>  public:
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  } // end namespace llvm
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transf
>>>>>> orms/Scalar/LoopInstSimplify.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopInstSimplify.h?rev=291651&r1=291650&r2
>>>>>> =291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopInstSimplify.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopInstSimplify.h Wed
>>>>>> Jan 11 00:23:21 2017
>>>>>> @@ -23,7 +23,8 @@ namespace llvm {
>>>>>>  /// Performs Loop Inst Simplify Pass.
>>>>>>  class LoopInstSimplifyPass : public PassInfoMixin<LoopInstSimplifyPass>
>>>>>> {
>>>>>>  public:
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  } // end namespace llvm
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/LoopRotation.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopRotation.h?rev=291651&r1=291650&r2=291
>>>>>> 651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopRotation.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopRotation.h Wed Jan
>>>>>> 11 00:23:21 2017
>>>>>> @@ -24,7 +24,8 @@ namespace llvm {
>>>>>>  class LoopRotatePass : public PassInfoMixin<LoopRotatePass> {
>>>>>>  public:
>>>>>>    LoopRotatePass(bool EnableHeaderDuplication = true);
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>
>>>>>>  private:
>>>>>>    const bool EnableHeaderDuplication;
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopSimplifyCFG.h?rev=291651&r1=291650&r2=
>>>>>> 291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopSimplifyCFG.h Wed
>>>>>> Jan 11 00:23:21 2017
>>>>>> @@ -26,7 +26,8 @@ namespace llvm {
>>>>>>  /// Performs basic CFG simplifications to assist other loop passes.
>>>>>>  class LoopSimplifyCFGPass : public PassInfoMixin<LoopSimplifyCFGPass>
>>>>>> {
>>>>>>  public:
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  } // end namespace llvm
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transf
>>>>>> orms/Scalar/LoopStrengthReduce.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopStrengthReduce.h?rev=291651&r1=291650&
>>>>>> r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopStrengthReduce.h
>>>>>> Wed Jan 11 00:23:21 2017
>>>>>> @@ -31,7 +31,8 @@ namespace llvm {
>>>>>>  /// Performs Loop Strength Reduce Pass.
>>>>>>  class LoopStrengthReducePass : public PassInfoMixin<LoopStrengthReducePass>
>>>>>> {
>>>>>>  public:
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  } // end namespace llvm
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/include/llvm/Transforms/Scalar/LoopUnrollPass.h
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>>>>>> Transforms/Scalar/LoopUnrollPass.h?rev=291651&r1=291650&r2=2
>>>>>> 91651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/include/llvm/Transforms/Scalar/LoopUnrollPass.h
>>>>>> (original)
>>>>>> +++ llvm/trunk/include/llvm/Transforms/Scalar/LoopUnrollPass.h Wed
>>>>>> Jan 11 00:23:21 2017
>>>>>> @@ -23,7 +23,8 @@ struct LoopUnrollPass : public PassInfoM
>>>>>>    Optional<bool> ProvidedRuntime;
>>>>>>    Optional<bool> ProvidedUpperBound;
>>>>>>
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM);
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                        LoopStandardAnalysisResults &AR, LPMUpdater
>>>>>> &U);
>>>>>>  };
>>>>>>  } // end namespace llvm
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Analysis/IVUsers.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/
>>>>>> IVUsers.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Analysis/IVUsers.cpp (original)
>>>>>> +++ llvm/trunk/lib/Analysis/IVUsers.cpp Wed Jan 11 00:23:21 2017
>>>>>> @@ -36,19 +36,15 @@ using namespace llvm;
>>>>>>
>>>>>>  AnalysisKey IVUsersAnalysis::Key;
>>>>>>
>>>>>> -IVUsers IVUsersAnalysis::run(Loop &L, LoopAnalysisManager &AM) {
>>>>>> -  const auto &FAM =
>>>>>> -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager
>>>>>> ();
>>>>>> -  Function *F = L.getHeader()->getParent();
>>>>>> -
>>>>>> -  return IVUsers(&L, FAM.getCachedResult<AssumptionAnalysis>(*F),
>>>>>> -                 FAM.getCachedResult<LoopAnalysis>(*F),
>>>>>> -                 FAM.getCachedResult<DominatorTreeAnalysis>(*F),
>>>>>> -                 FAM.getCachedResult<ScalarEvolutionAnalysis>(*F));
>>>>>> +IVUsers IVUsersAnalysis::run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                             LoopStandardAnalysisResults &AR) {
>>>>>> +  return IVUsers(&L, &AR.AC <http://ar.ac/>, &AR.LI <http://ar.li/>,
>>>>>> &AR.DT, &AR.SE <http://ar.se/>);
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses IVUsersPrinterPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM) {
>>>>>> -  AM.getResult<IVUsersAnalysis>(L).print(OS);
>>>>>> +PreservedAnalyses IVUsersPrinterPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM,
>>>>>> +
>>>>>> LoopStandardAnalysisResults &AR,
>>>>>> +                                          LPMUpdater &U) {
>>>>>> +  AM.getResult<IVUsersAnalysis>(L, AR).print(OS);
>>>>>>    return PreservedAnalyses::all();
>>>>>>  }
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/
>>>>>> LoopAccessAnalysis.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp (original)
>>>>>> +++ llvm/trunk/lib/Analysis/LoopAccessAnalysis.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -2120,31 +2120,16 @@ INITIALIZE_PASS_END(LoopAccessLegacyAnal
>>>>>>
>>>>>>  AnalysisKey LoopAccessAnalysis::Key;
>>>>>>
>>>>>> -LoopAccessInfo LoopAccessAnalysis::run(Loop &L, LoopAnalysisManager
>>>>>> &AM) {
>>>>>> -  const FunctionAnalysisManager &FAM =
>>>>>> -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager
>>>>>> ();
>>>>>> -  Function &F = *L.getHeader()->getParent();
>>>>>> -  auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(F);
>>>>>> -  auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(F);
>>>>>> -  auto *AA = FAM.getCachedResult<AAManager>(F);
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(F);
>>>>>> -  if (!SE)
>>>>>> -    report_fatal_error(
>>>>>> -        "ScalarEvolution must have been cached at a higher level");
>>>>>> -  if (!AA)
>>>>>> -    report_fatal_error("AliasAnalysis must have been cached at a
>>>>>> higher level");
>>>>>> -  if (!DT)
>>>>>> -    report_fatal_error("DominatorTree must have been cached at a
>>>>>> higher level");
>>>>>> -  if (!LI)
>>>>>> -    report_fatal_error("LoopInfo must have been cached at a higher
>>>>>> level");
>>>>>> -  return LoopAccessInfo(&L, SE, TLI, AA, DT, LI);
>>>>>> +LoopAccessInfo LoopAccessAnalysis::run(Loop &L, LoopAnalysisManager
>>>>>> &AM,
>>>>>> +                                       LoopStandardAnalysisResults
>>>>>> &AR) {
>>>>>> +  return LoopAccessInfo(&L, &AR.SE <http://ar.se/>, &AR.TLI,
>>>>>> &AR.AA, &AR.DT, &AR.LI <http://ar.li/>);
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses LoopAccessInfoPrinterPass::run(Loop &L,
>>>>>> -                                                 LoopAnalysisManager
>>>>>> &AM) {
>>>>>> +PreservedAnalyses
>>>>>> +LoopAccessInfoPrinterPass::run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                               LoopStandardAnalysisResults &AR,
>>>>>> LPMUpdater &) {
>>>>>>    Function &F = *L.getHeader()->getParent();
>>>>>> -  auto &LAI = AM.getResult<LoopAccessAnalysis>(L);
>>>>>> +  auto &LAI = AM.getResult<LoopAccessAnalysis>(L, AR);
>>>>>>    OS << "Loop access info in function '" << F.getName() << "':\n";
>>>>>>    OS.indent(2) << L.getHeader()->getName() << ":\n";
>>>>>>    LAI.print(OS, 4);
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Analysis/LoopInfo.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/
>>>>>> LoopInfo.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Analysis/LoopInfo.cpp (original)
>>>>>> +++ llvm/trunk/lib/Analysis/LoopInfo.cpp Wed Jan 11 00:23:21 2017
>>>>>> @@ -689,18 +689,13 @@ PreservedAnalyses LoopPrinterPass::run(F
>>>>>>    return PreservedAnalyses::all();
>>>>>>  }
>>>>>>
>>>>>> -PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
>>>>>> -PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string
>>>>>> &Banner)
>>>>>> -    : OS(OS), Banner(Banner) {}
>>>>>> -
>>>>>> -PreservedAnalyses PrintLoopPass::run(Loop &L, AnalysisManager<Loop>
>>>>>> &) {
>>>>>> +void llvm::printLoop(Loop &L, raw_ostream &OS, const std::string
>>>>>> &Banner) {
>>>>>>    OS << Banner;
>>>>>>    for (auto *Block : L.blocks())
>>>>>>      if (Block)
>>>>>>        Block->print(OS);
>>>>>>      else
>>>>>>        OS << "Printing <null> block";
>>>>>> -  return PreservedAnalyses::all();
>>>>>>  }
>>>>>>
>>>>>>  //===------------------------------------------------------
>>>>>> ----------------===//
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Analysis/LoopPass.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/
>>>>>> LoopPass.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Analysis/LoopPass.cpp (original)
>>>>>> +++ llvm/trunk/lib/Analysis/LoopPass.cpp Wed Jan 11 00:23:21 2017
>>>>>> @@ -32,13 +32,14 @@ namespace {
>>>>>>  /// PrintLoopPass - Print a Function corresponding to a Loop.
>>>>>>  ///
>>>>>>  class PrintLoopPassWrapper : public LoopPass {
>>>>>> -  PrintLoopPass P;
>>>>>> +  raw_ostream &OS;
>>>>>> +  std::string Banner;
>>>>>>
>>>>>>  public:
>>>>>>    static char ID;
>>>>>> -  PrintLoopPassWrapper() : LoopPass(ID) {}
>>>>>> +  PrintLoopPassWrapper() : LoopPass(ID), OS(dbgs()) {}
>>>>>>    PrintLoopPassWrapper(raw_ostream &OS, const std::string &Banner)
>>>>>> -      : LoopPass(ID), P(OS, Banner) {}
>>>>>> +      : LoopPass(ID), OS(OS), Banner(Banner) {}
>>>>>>
>>>>>>    void getAnalysisUsage(AnalysisUsage &AU) const override {
>>>>>>      AU.setPreservesAll();
>>>>>> @@ -49,8 +50,7 @@ public:
>>>>>>                         [](BasicBlock *BB) { return BB; });
>>>>>>      if (BBI != L->blocks().end() &&
>>>>>>          isFunctionInPrintList((*BBI)->getParent()->getName())) {
>>>>>> -      LoopAnalysisManager DummyLAM;
>>>>>> -      P.run(*L, DummyLAM);
>>>>>> +      printLoop(*L, OS, Banner);
>>>>>>      }
>>>>>>      return false;
>>>>>>    }
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Analysis/LoopPassManager.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/
>>>>>> LoopPassManager.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Analysis/LoopPassManager.cpp (original)
>>>>>> +++ llvm/trunk/lib/Analysis/LoopPassManager.cpp Wed Jan 11 00:23:21
>>>>>> 2017
>>>>>> @@ -20,34 +20,191 @@ using namespace llvm;
>>>>>>  // Explicit template instantiations and specialization defininitions
>>>>>> for core
>>>>>>  // template typedefs.
>>>>>>  namespace llvm {
>>>>>> -template class PassManager<Loop>;
>>>>>> -template class AnalysisManager<Loop>;
>>>>>> +template class AllAnalysesOn<Loop>;
>>>>>> +template class AnalysisManager<Loop, LoopStandardAnalysisResults &>;
>>>>>> +template class PassManager<Loop, LoopAnalysisManager,
>>>>>> +                           LoopStandardAnalysisResults &, LPMUpdater
>>>>>> &>;
>>>>>>  template class InnerAnalysisManagerProxy<LoopAnalysisManager,
>>>>>> Function>;
>>>>>> -template class OuterAnalysisManagerProxy<FunctionAnalysisManager,
>>>>>> Loop>;
>>>>>> +template class OuterAnalysisManagerProxy<FunctionAnalysisManager,
>>>>>> Loop,
>>>>>> +                                         LoopStandardAnalysisResults
>>>>>> &>;
>>>>>>
>>>>>> +/// Explicitly specialize the pass manager's run method to handle
>>>>>> loop nest
>>>>>> +/// structure updates.
>>>>>>  template <>
>>>>>> +PreservedAnalyses
>>>>>> +PassManager<Loop, LoopAnalysisManager, LoopStandardAnalysisResults &,
>>>>>> +            LPMUpdater &>::run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                               LoopStandardAnalysisResults &AR,
>>>>>> LPMUpdater &U) {
>>>>>> +  PreservedAnalyses PA = PreservedAnalyses::all();
>>>>>> +
>>>>>> +  if (DebugLogging)
>>>>>> +    dbgs() << "Starting Loop pass manager run.\n";
>>>>>> +
>>>>>> +  for (auto &Pass : Passes) {
>>>>>> +    if (DebugLogging)
>>>>>> +      dbgs() << "Running pass: " << Pass->name() << " on " << L;
>>>>>> +
>>>>>> +    PreservedAnalyses PassPA = Pass->run(L, AM, AR, U);
>>>>>> +
>>>>>> +    // If the loop was deleted, abort the run and return to the
>>>>>> outer walk.
>>>>>> +    if (U.skipCurrentLoop()) {
>>>>>> +      PA.intersect(std::move(PassPA));
>>>>>> +      break;
>>>>>> +    }
>>>>>> +
>>>>>> +    // Update the analysis manager as each pass runs and potentially
>>>>>> +    // invalidates analyses.
>>>>>> +    AM.invalidate(L, PassPA);
>>>>>> +
>>>>>> +    // Finally, we intersect the final preserved analyses to compute
>>>>>> the
>>>>>> +    // aggregate preserved set for this pass manager.
>>>>>> +    PA.intersect(std::move(PassPA));
>>>>>> +
>>>>>> +    // FIXME: Historically, the pass managers all called the LLVM
>>>>>> context's
>>>>>> +    // yield function here. We don't have a generic way to acquire
>>>>>> the
>>>>>> +    // context and it isn't yet clear what the right pattern is for
>>>>>> yielding
>>>>>> +    // in the new pass manager so it is currently omitted.
>>>>>> +    // ...getContext().yield();
>>>>>> +  }
>>>>>> +
>>>>>> +  // Invalidation for the current loop should be handled above, and
>>>>>> other loop
>>>>>> +  // analysis results shouldn't be impacted by runs over this loop.
>>>>>> Therefore,
>>>>>> +  // the remaining analysis results in the AnalysisManager are
>>>>>> preserved. We
>>>>>> +  // mark this with a set so that we don't need to inspect each one
>>>>>> +  // individually.
>>>>>> +  // FIXME: This isn't correct! This loop and all nested loops'
>>>>>> analyses should
>>>>>> +  // be preserved, but unrolling should invalidate the parent loop's
>>>>>> analyses.
>>>>>> +  PA.preserveSet<AllAnalysesOn<Loop>>();
>>>>>> +
>>>>>> +  if (DebugLogging)
>>>>>> +    dbgs() << "Finished Loop pass manager run.\n";
>>>>>> +
>>>>>> +  return PA;
>>>>>> +}
>>>>>> +
>>>>>>  bool LoopAnalysisManagerFunctionProxy::Result::invalidate(
>>>>>>      Function &F, const PreservedAnalyses &PA,
>>>>>>      FunctionAnalysisManager::Invalidator &Inv) {
>>>>>> -  // If this proxy isn't marked as preserved, the set of Function
>>>>>> objects in
>>>>>> -  // the module may have changed. We therefore can't call
>>>>>> -  // InnerAM->invalidate(), because any pointers to Functions it has
>>>>>> may be
>>>>>> -  // stale.
>>>>>> +  // First compute the sequence of IR units covered by this proxy.
>>>>>> We will want
>>>>>> +  // to visit this in postorder, but because this is a tree
>>>>>> structure we can do
>>>>>> +  // this by building a preorder sequence and walking it in reverse.
>>>>>> +  SmallVector<Loop *, 4> PreOrderLoops, PreOrderWorklist;
>>>>>> +  // Note that we want to walk the roots in reverse order because we
>>>>>> will end
>>>>>> +  // up reversing the preorder sequence. However, it happens that
>>>>>> the loop nest
>>>>>> +  // roots are in reverse order within the LoopInfo object. So we
>>>>>> just walk
>>>>>> +  // forward here.
>>>>>> +  // FIXME: If we change the order of LoopInfo we will want to add a
>>>>>> reverse
>>>>>> +  // here.
>>>>>> +  for (Loop *RootL : *LI) {
>>>>>> +    assert(PreOrderWorklist.empty() &&
>>>>>> +           "Must start with an empty preorder walk worklist.");
>>>>>> +    PreOrderWorklist.push_back(RootL);
>>>>>> +    do {
>>>>>> +      Loop *L = PreOrderWorklist.pop_back_val();
>>>>>> +      PreOrderWorklist.append(L->begin(), L->end());
>>>>>> +      PreOrderLoops.push_back(L);
>>>>>> +    } while (!PreOrderWorklist.empty());
>>>>>> +  }
>>>>>> +
>>>>>> +  // If this proxy or the loop info is going to be invalidated, we
>>>>>> also need
>>>>>> +  // to clear all the keys coming from that analysis. We also
>>>>>> completely blow
>>>>>> +  // away the loop analyses if any of the standard analyses provided
>>>>>> by the
>>>>>> +  // loop pass manager go away so that loop analyses can freely use
>>>>>> these
>>>>>> +  // without worrying about declaring dependencies on them etc.
>>>>>> +  // FIXME: It isn't clear if this is the right tradeoff. We could
>>>>>> instead make
>>>>>> +  // loop analyses declare any dependencies on these and use the
>>>>>> more general
>>>>>> +  // invalidation logic below to act on that.
>>>>>>    auto PAC = PA.getChecker<LoopAnalysisManagerFunctionProxy>();
>>>>>> -  if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Loop>>())
>>>>>> -    InnerAM->clear();
>>>>>> +  if (!(PAC.preserved() || PAC.preservedSet<AllAnalysesOn<Function>>())
>>>>>> ||
>>>>>> +      Inv.invalidate<AAManager>(F, PA) ||
>>>>>> +      Inv.invalidate<AssumptionAnalysis>(F, PA) ||
>>>>>> +      Inv.invalidate<DominatorTreeAnalysis>(F, PA) ||
>>>>>> +      Inv.invalidate<LoopAnalysis>(F, PA) ||
>>>>>> +      Inv.invalidate<ScalarEvolutionAnalysis>(F, PA)) {
>>>>>> +    // Note that the LoopInfo may be stale at this point, however
>>>>>> the loop
>>>>>> +    // objects themselves remain the only viable keys that could be
>>>>>> in the
>>>>>> +    // analysis manager's cache. So we just walk the keys and
>>>>>> forcibly clear
>>>>>> +    // those results. Note that the order doesn't matter here as
>>>>>> this will just
>>>>>> +    // directly destroy the results without calling methods on them.
>>>>>> +    for (Loop *L : PreOrderLoops)
>>>>>> +      InnerAM->clear(*L);
>>>>>> +
>>>>>> +    // We also need to null out the inner AM so that when the object
>>>>>> gets
>>>>>> +    // destroyed as invalid we don't try to clear the inner AM
>>>>>> again. At that
>>>>>> +    // point we won't be able to reliably walk the loops for this
>>>>>> function and
>>>>>> +    // only clear results associated with those loops the way we do
>>>>>> here.
>>>>>> +    // FIXME: Making InnerAM null at this point isn't very nice.
>>>>>> Most analyses
>>>>>> +    // try to remain valid during invalidation. Maybe we should add
>>>>>> an
>>>>>> +    // `IsClean` flag?
>>>>>> +    InnerAM = nullptr;
>>>>>> +
>>>>>> +    // Now return true to indicate this *is* invalid and a fresh
>>>>>> proxy result
>>>>>> +    // needs to be built. This is especially important given the
>>>>>> null InnerAM.
>>>>>> +    return true;
>>>>>> +  }
>>>>>> +
>>>>>> +  // Directly check if the relevant set is preserved so we can short
>>>>>> circuit
>>>>>> +  // invalidating loops.
>>>>>> +  bool AreLoopAnalysesPreserved =
>>>>>> +      PA.allAnalysesInSetPreserved<AllAnalysesOn<Loop>>();
>>>>>> +
>>>>>> +  // Since we have a valid LoopInfo we can actually leave the cached
>>>>>> results in
>>>>>> +  // the analysis manager associated with the Loop keys, but we need
>>>>>> to
>>>>>> +  // propagate any necessary invalidation logic into them. We'd like
>>>>>> to
>>>>>> +  // invalidate things in roughly the same order as they were put
>>>>>> into the
>>>>>> +  // cache and so we walk the preorder list in reverse to form a
>>>>>> valid
>>>>>> +  // postorder.
>>>>>> +  for (Loop *L : reverse(PreOrderLoops)) {
>>>>>> +    Optional<PreservedAnalyses> InnerPA;
>>>>>> +
>>>>>> +    // Check to see whether the preserved set needs to be adjusted
>>>>>> based on
>>>>>> +    // function-level analysis invalidation triggering deferred
>>>>>> invalidation
>>>>>> +    // for this loop.
>>>>>> +    if (auto *OuterProxy =
>>>>>> +            InnerAM->getCachedResult<Funct
>>>>>> ionAnalysisManagerLoopProxy>(*L))
>>>>>> +      for (const auto &OuterInvalidationPair :
>>>>>> +           OuterProxy->getOuterInvalidations()) {
>>>>>> +        AnalysisKey *OuterAnalysisID = OuterInvalidationPair.first;
>>>>>> +        const auto &InnerAnalysisIDs = OuterInvalidationPair.second;
>>>>>> +        if (Inv.invalidate(OuterAnalysisID, F, PA)) {
>>>>>> +          if (!InnerPA)
>>>>>> +            InnerPA = PA;
>>>>>> +          for (AnalysisKey *InnerAnalysisID : InnerAnalysisIDs)
>>>>>> +            InnerPA->abandon(InnerAnalysisID);
>>>>>> +        }
>>>>>> +      }
>>>>>> +
>>>>>> +    // Check if we needed a custom PA set. If so we'll need to run
>>>>>> the inner
>>>>>> +    // invalidation.
>>>>>> +    if (InnerPA) {
>>>>>> +      InnerAM->invalidate(*L, *InnerPA);
>>>>>> +      continue;
>>>>>> +    }
>>>>>>
>>>>>> -  // FIXME: Proper suppor for invalidation isn't yet implemented for
>>>>>> the LPM.
>>>>>> +    // Otherwise we only need to do invalidation if the original PA
>>>>>> set didn't
>>>>>> +    // preserve all Loop analyses.
>>>>>> +    if (!AreLoopAnalysesPreserved)
>>>>>> +      InnerAM->invalidate(*L, PA);
>>>>>> +  }
>>>>>>
>>>>>>    // Return false to indicate that this result is still a valid
>>>>>> proxy.
>>>>>>    return false;
>>>>>>  }
>>>>>> +
>>>>>> +template <>
>>>>>> +LoopAnalysisManagerFunctionProxy::Result
>>>>>> +LoopAnalysisManagerFunctionProxy::run(Function &F,
>>>>>> +                                      FunctionAnalysisManager &AM) {
>>>>>> +  return Result(*InnerAM, AM.getResult<LoopAnalysis>(F));
>>>>>> +}
>>>>>>  }
>>>>>>
>>>>>>  PreservedAnalyses llvm::getLoopPassPreservedAnalyses() {
>>>>>>    PreservedAnalyses PA;
>>>>>> +  PA.preserve<AssumptionAnalysis>();
>>>>>>    PA.preserve<DominatorTreeAnalysis>();
>>>>>>    PA.preserve<LoopAnalysis>();
>>>>>> +  PA.preserve<LoopAnalysisManagerFunctionProxy>();
>>>>>>    PA.preserve<ScalarEvolutionAnalysis>();
>>>>>>    // TODO: What we really want to do here is preserve an AA
>>>>>> category, but that
>>>>>>    // concept doesn't exist yet.
>>>>>> @@ -57,3 +214,14 @@ PreservedAnalyses llvm::getLoopPassPrese
>>>>>>    PA.preserve<SCEVAA>();
>>>>>>    return PA;
>>>>>>  }
>>>>>> +
>>>>>> +PrintLoopPass::PrintLoopPass() : OS(dbgs()) {}
>>>>>> +PrintLoopPass::PrintLoopPass(raw_ostream &OS, const std::string
>>>>>> &Banner)
>>>>>> +    : OS(OS), Banner(Banner) {}
>>>>>> +
>>>>>> +PreservedAnalyses PrintLoopPass::run(Loop &L, LoopAnalysisManager &,
>>>>>> +                                     LoopStandardAnalysisResults &,
>>>>>> +                                     LPMUpdater &) {
>>>>>> +  printLoop(L, OS, Banner);
>>>>>> +  return PreservedAnalyses::all();
>>>>>> +}
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Passes/PassBuilder.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Passes/Pa
>>>>>> ssBuilder.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Passes/PassBuilder.cpp (original)
>>>>>> +++ llvm/trunk/lib/Passes/PassBuilder.cpp Wed Jan 11 00:23:21 2017
>>>>>> @@ -38,6 +38,7 @@
>>>>>>  #include "llvm/Analysis/LazyValueInfo.h"
>>>>>>  #include "llvm/Analysis/LoopAccessAnalysis.h"
>>>>>>  #include "llvm/Analysis/LoopInfo.h"
>>>>>> +#include "llvm/Analysis/LoopPassManager.h"
>>>>>>  #include "llvm/Analysis/MemoryDependenceAnalysis.h"
>>>>>>  #include "llvm/Analysis/ModuleSummaryAnalysis.h"
>>>>>>  #include "llvm/Analysis/OptimizationDiagnosticInfo.h"
>>>>>> @@ -220,7 +221,8 @@ public:
>>>>>>
>>>>>>  /// \brief No-op loop pass which does nothing.
>>>>>>  struct NoOpLoopPass {
>>>>>> -  PreservedAnalyses run(Loop &L, LoopAnalysisManager &) {
>>>>>> +  PreservedAnalyses run(Loop &L, LoopAnalysisManager &,
>>>>>> +                        LoopStandardAnalysisResults &, LPMUpdater &)
>>>>>> {
>>>>>>      return PreservedAnalyses::all();
>>>>>>    }
>>>>>>    static StringRef name() { return "NoOpLoopPass"; }
>>>>>> @@ -233,7 +235,9 @@ class NoOpLoopAnalysis : public Analysis
>>>>>>
>>>>>>  public:
>>>>>>    struct Result {};
>>>>>> -  Result run(Loop &, LoopAnalysisManager &) { return Result(); }
>>>>>> +  Result run(Loop &, LoopAnalysisManager &,
>>>>>> LoopStandardAnalysisResults &) {
>>>>>> +    return Result();
>>>>>> +  }
>>>>>>    static StringRef name() { return "NoOpLoopAnalysis"; }
>>>>>>  };
>>>>>>
>>>>>> @@ -1019,7 +1023,9 @@ bool PassBuilder::parseLoopPass(LoopPass
>>>>>>  #define LOOP_ANALYSIS(NAME, CREATE_PASS)
>>>>>>            \
>>>>>>    if (Name == "require<" NAME ">") {
>>>>>>            \
>>>>>>      LPM.addPass(RequireAnalysisPass<
>>>>>>            \
>>>>>> -                std::remove_reference<decltype(CREATE_PASS)>::type,
>>>>>> Loop>());  \
>>>>>> +                std::remove_reference<decltype(CREATE_PASS)>::type,
>>>>>> Loop,      \
>>>>>> +                LoopAnalysisManager, LoopStandardAnalysisResults &,
>>>>>>           \
>>>>>> +                LPMUpdater &>());
>>>>>>           \
>>>>>>      return true;
>>>>>>            \
>>>>>>    }
>>>>>>           \
>>>>>>    if (Name == "invalidate<" NAME ">") {
>>>>>>           \
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/IndVarSimplify.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -2482,23 +2482,13 @@ bool IndVarSimplify::run(Loop *L) {
>>>>>>    return Changed;
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses IndVarSimplifyPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM) {
>>>>>> -  auto &FAM = AM.getResult<FunctionAnalysisM
>>>>>> anagerLoopProxy>(L).getManager();
>>>>>> +PreservedAnalyses IndVarSimplifyPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM,
>>>>>> +
>>>>>> LoopStandardAnalysisResults &AR,
>>>>>> +                                          LPMUpdater &) {
>>>>>>    Function *F = L.getHeader()->getParent();
>>>>>>    const DataLayout &DL = F->getParent()->getDataLayout();
>>>>>>
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -  auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -
>>>>>> -  assert((LI && SE && DT) &&
>>>>>> -         "Analyses required for indvarsimplify not available!");
>>>>>> -
>>>>>> -  // Optional analyses.
>>>>>> -  auto *TTI = FAM.getCachedResult<TargetIRAnalysis>(*F);
>>>>>> -  auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(*F);
>>>>>> -
>>>>>> -  IndVarSimplify IVS(LI, SE, DT, DL, TLI, TTI);
>>>>>> +  IndVarSimplify IVS(&AR.LI <http://ar.li/>, &AR.SE <http://ar.se/>,
>>>>>> &AR.DT, DL, &AR.TLI, &AR.TTI);
>>>>>>    if (!IVS.run(&L))
>>>>>>      return PreservedAnalyses::all();
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LICM.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Wed Jan 11 00:23:21
>>>>>> 2017
>>>>>> @@ -185,23 +185,20 @@ private:
>>>>>>  };
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM) {
>>>>>> +PreservedAnalyses LICMPass::run(Loop &L, LoopAnalysisManager &AM,
>>>>>> +                                LoopStandardAnalysisResults &AR,
>>>>>> LPMUpdater &) {
>>>>>>    const auto &FAM =
>>>>>> -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager
>>>>>> ();
>>>>>> +      AM.getResult<FunctionAnalysisManagerLoopProxy>(L,
>>>>>> AR).getManager();
>>>>>>    Function *F = L.getHeader()->getParent();
>>>>>>
>>>>>> -  auto *AA = FAM.getCachedResult<AAManager>(*F);
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -  auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(*F);
>>>>>> -  auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
>>>>>>    auto *ORE = FAM.getCachedResult<Optimizati
>>>>>> onRemarkEmitterAnalysis>(*F);
>>>>>> -  assert((AA && LI && DT && TLI && SE && ORE) &&
>>>>>> -         "Analyses for LICM not available");
>>>>>> +  // FIXME: This should probably be optional rather than required.
>>>>>> +  if (!ORE)
>>>>>> +    report_fatal_error("LICM: OptimizationRemarkEmitterAnalysis not
>>>>>> "
>>>>>> +                       "cached at a higher level");
>>>>>>
>>>>>>    LoopInvariantCodeMotion LICM;
>>>>>> -
>>>>>> -  if (!LICM.runOnLoop(&L, AA, LI, DT, TLI, SE, ORE, true))
>>>>>> +  if (!LICM.runOnLoop(&L, &AR.AA, &AR.LI <http://ar.li/>, &AR.DT,
>>>>>> &AR.TLI, &AR.SE <http://ar.se/>, ORE, true))
>>>>>>      return PreservedAnalyses::all();
>>>>>>
>>>>>>    // FIXME: There is no setPreservesCFG in the new PM. When that
>>>>>> becomes
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LoopDeletion.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -215,15 +215,10 @@ bool LoopDeletionPass::runImpl(Loop *L,
>>>>>>    return Changed;
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses LoopDeletionPass::run(Loop &L, LoopAnalysisManager
>>>>>> &AM) {
>>>>>> -  auto &FAM = AM.getResult<FunctionAnalysisM
>>>>>> anagerLoopProxy>(L).getManager();
>>>>>> -  Function *F = L.getHeader()->getParent();
>>>>>> -
>>>>>> -  auto &DT = *FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -  auto &SE = *FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
>>>>>> -  auto &LI = *FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -
>>>>>> -  bool Changed = runImpl(&L, DT, SE, LI);
>>>>>> +PreservedAnalyses LoopDeletionPass::run(Loop &L, LoopAnalysisManager
>>>>>> &AM,
>>>>>> +                                        LoopStandardAnalysisResults
>>>>>> &AR,
>>>>>> +                                        LPMUpdater &) {
>>>>>> +  bool Changed = runImpl(&L, AR.DT, AR.SE <http://ar.se/>, AR.LI
>>>>>> <http://ar.li/>);
>>>>>>    if (!Changed)
>>>>>>      return PreservedAnalyses::all();
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LoopDistribute.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopDistribute.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -946,10 +946,18 @@ PreservedAnalyses LoopDistributePass::ru
>>>>>>    auto &SE = AM.getResult<ScalarEvolutionAnalysis>(F);
>>>>>>    auto &ORE = AM.getResult<OptimizationRemarkEmitterAnalysis>(F);
>>>>>>
>>>>>> +  // We don't directly need these analyses but they're required for
>>>>>> loop
>>>>>> +  // analyses so provide them below.
>>>>>> +  auto &AA = AM.getResult<AAManager>(F);
>>>>>> +  auto &AC = AM.getResult<AssumptionAnalysis>(F);
>>>>>> +  auto &TTI = AM.getResult<TargetIRAnalysis>(F);
>>>>>> +  auto &TLI = AM.getResult<TargetLibraryAnalysis>(F);
>>>>>> +
>>>>>>    auto &LAM = AM.getResult<LoopAnalysisManag
>>>>>> erFunctionProxy>(F).getManager();
>>>>>>    std::function<const LoopAccessInfo &(Loop &)> GetLAA =
>>>>>>        [&](Loop &L) -> const LoopAccessInfo & {
>>>>>> -    return LAM.getResult<LoopAccessAnalysis>(L);
>>>>>> +    LoopStandardAnalysisResults AR = {AA, AC, DT, LI, SE, TLI, TTI};
>>>>>> +    return LAM.getResult<LoopAccessAnalysis>(L, AR);
>>>>>>    };
>>>>>>
>>>>>>    bool Changed = runImpl(F, &LI, &DT, &SE, &ORE, GetLAA);
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LoopIdiomRecognize.cpp?rev=291651&r1=291650&r2=2916
>>>>>> 51&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
>>>>>> (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Wed Jan
>>>>>> 11 00:23:21 2017
>>>>>> @@ -186,24 +186,12 @@ public:
>>>>>>  };
>>>>>>  } // End anonymous namespace.
>>>>>>
>>>>>> -PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L,
>>>>>> -                                              LoopAnalysisManager
>>>>>> &AM) {
>>>>>> -  const auto &FAM =
>>>>>> -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager
>>>>>> ();
>>>>>> -  Function *F = L.getHeader()->getParent();
>>>>>> -
>>>>>> -  // Use getCachedResult because Loop pass cannot trigger a function
>>>>>> analysis.
>>>>>> -  auto *AA = FAM.getCachedResult<AAManager>(*F);
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -  auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
>>>>>> -  auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(*F);
>>>>>> -  const auto *TTI = FAM.getCachedResult<TargetIRAnalysis>(*F);
>>>>>> +PreservedAnalyses LoopIdiomRecognizePass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM,
>>>>>> +
>>>>>> LoopStandardAnalysisResults &AR,
>>>>>> +                                              LPMUpdater &) {
>>>>>>    const auto *DL = &L.getHeader()->getModule()->getDataLayout();
>>>>>> -  assert((AA && DT && LI && SE && TLI && TTI && DL) &&
>>>>>> -         "Analyses for Loop Idiom Recognition not available");
>>>>>>
>>>>>> -  LoopIdiomRecognize LIR(AA, DT, LI, SE, TLI, TTI, DL);
>>>>>> +  LoopIdiomRecognize LIR(&AR.AA, &AR.DT, &AR.LI <http://ar.li/>, &
>>>>>> AR.SE <http://ar.se/>, &AR.TLI, &AR.TTI, DL);
>>>>>>    if (!LIR.runOnLoop(&L))
>>>>>>      return PreservedAnalyses::all();
>>>>>>
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LoopInstSimplify.cpp?rev=291651&r1=291650&r2=291651
>>>>>> &view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -183,20 +183,10 @@ public:
>>>>>>  };
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses LoopInstSimplifyPass::run(Loop &L,
>>>>>> -                                            LoopAnalysisManager &AM)
>>>>>> {
>>>>>> -  const auto &FAM =
>>>>>> -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager
>>>>>> ();
>>>>>> -  Function *F = L.getHeader()->getParent();
>>>>>> -
>>>>>> -  // Use getCachedResult because Loop pass cannot trigger a function
>>>>>> analysis.
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -  auto *AC = FAM.getCachedResult<AssumptionAnalysis>(*F);
>>>>>> -  const auto *TLI = FAM.getCachedResult<TargetLibraryAnalysis>(*F);
>>>>>> -  assert((LI && AC && TLI) && "Analyses for Loop Inst Simplify not
>>>>>> available");
>>>>>> -
>>>>>> -  if (!SimplifyLoopInst(&L, DT, LI, AC, TLI))
>>>>>> +PreservedAnalyses LoopInstSimplifyPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM,
>>>>>> +
>>>>>> LoopStandardAnalysisResults &AR,
>>>>>> +                                            LPMUpdater &) {
>>>>>> +  if (!SimplifyLoopInst(&L, &AR.DT, &AR.LI <http://ar.li/>, &AR.AC
>>>>>> <http://ar.ac/>, &AR.TLI))
>>>>>>      return PreservedAnalyses::all();
>>>>>>
>>>>>>    return getLoopPassPreservedAnalyses();
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LoopRotation.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -625,20 +625,11 @@ bool LoopRotate::processLoop(Loop *L) {
>>>>>>  LoopRotatePass::LoopRotatePass(bool EnableHeaderDuplication)
>>>>>>      : EnableHeaderDuplication(EnableHeaderDuplication) {}
>>>>>>
>>>>>> -PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager
>>>>>> &AM) {
>>>>>> -  auto &FAM = AM.getResult<FunctionAnalysisM
>>>>>> anagerLoopProxy>(L).getManager();
>>>>>> -  Function *F = L.getHeader()->getParent();
>>>>>> -
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -  const auto *TTI = FAM.getCachedResult<TargetIRAnalysis>(*F);
>>>>>> -  auto *AC = FAM.getCachedResult<AssumptionAnalysis>(*F);
>>>>>> -  assert((LI && TTI && AC) && "Analyses for loop rotation not
>>>>>> available");
>>>>>> -
>>>>>> -  // Optional analyses.
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -  auto *SE = FAM.getCachedResult<ScalarEvolutionAnalysis>(*F);
>>>>>> +PreservedAnalyses LoopRotatePass::run(Loop &L, LoopAnalysisManager
>>>>>> &AM,
>>>>>> +                                      LoopStandardAnalysisResults
>>>>>> &AR,
>>>>>> +                                      LPMUpdater &) {
>>>>>>    int Threshold = EnableHeaderDuplication ? DefaultRotationThreshold
>>>>>> : 0;
>>>>>> -  LoopRotate LR(Threshold, LI, TTI, AC, DT, SE);
>>>>>> +  LoopRotate LR(Threshold, &AR.LI <http://ar.li/>, &AR.TTI, &AR.AC
>>>>>> <http://ar.ac/>, &AR.DT, &AR.SE <http://ar.se/>);
>>>>>>
>>>>>>    bool Changed = LR.processLoop(&L);
>>>>>>    if (!Changed)
>>>>>>
>>>>>> Modified: llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
>>>>>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transform
>>>>>> s/Scalar/LoopSimplifyCFG.cpp?rev=291651&r1=291650&r2=291651&view=diff
>>>>>> ============================================================
>>>>>> ==================
>>>>>> --- llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp (original)
>>>>>> +++ llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp Wed Jan 11
>>>>>> 00:23:21 2017
>>>>>> @@ -64,16 +64,10 @@ static bool simplifyLoopCFG(Loop &L, Dom
>>>>>>    return Changed;
>>>>>>  }
>>>>>>
>>>>>> -PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM) {
>>>>>> -  const auto &FAM =
>>>>>> -      AM.getResult<FunctionAnalysisManagerLoopProxy>(L).getManager
>>>>>> ();
>>>>>> -  Function *F = L.getHeader()->getParent();
>>>>>> -
>>>>>> -  auto *LI = FAM.getCachedResult<LoopAnalysis>(*F);
>>>>>> -  auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(*F);
>>>>>> -  assert((LI && DT) && "Analyses for LoopSimplifyCFG not available");
>>>>>> -
>>>>>> -  if (!simplifyLoopCFG(L, *DT, *LI))
>>>>>> +PreservedAnalyses LoopSimplifyCFGPass::run(Loop &L,
>>>>>> LoopAnalysisManager &AM,
>>>>>> +
>>>>>>  LoopStandardAnalysisResults &AR,
>>>>>> +                                           LPMUpdater &) {
>>>>>> +  if (!simplifyLoopCFG(L, AR.DT, AR.LI <http://ar.li/>))
>>>>>>      return PreservedAnalyses::all();
>>>>>>
>>>>>
>>>>> --
>>>>> Mike
>>>>> Sent from phone
>>>>>
>>>>
>>>>
>>> _______________________________________________
>>> 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/20170111/4bfc8a22/attachment-0001.html>


More information about the llvm-commits mailing list