[llvm] r261316 - [LPM] Factor all of the loop analysis usage updates into a common helper

Chandler Carruth via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 20:39:26 PST 2016


Nice test case! This was a latent bug in LICM that was exposed by the
change here. I've fixed LICM in r262108 and included a still further
reduced test case for this pattern. Thanks again!

-Chandler

On Thu, Feb 25, 2016 at 11:26 PM Mikael Holmén <mikael.holmen at ericsson.com>
wrote:

> Hi Chandler,
>
> The attached test case (originally generated by Csmith, ran through
> clang, and then bugpoint-reduced) now makes LICM hit the following assert:
>
> opt: ../lib/Transforms/Scalar/LICM.cpp:1048: llvm::AliasSetTracker
> *(anonymous namespace)::LICM::collectAliasInfoFromSubLoops(llvm::Loop
> *): Assertion `InnerAST && "Where is my AST?"' failed.
>
> when I run opt on it with the following command line:
>
> build-all/bin/opt -S -simplifycfg -functionattrs -instcombine -lcssa
> -loop-rotate -licm -loop-unswitch -loop-idiom -loop-unroll
> ./bugpoint-reduced-simplified.ll
>
>
> If I revert your commit:
>
> "[LPM] Factor all of the loop analysis usage updates into a common
> helper routine."
>
> the crash goes away.
>
> Best regards,
> Mikael
>
> On 02/19/2016 11:45 AM, Chandler Carruth via llvm-commits wrote:
> > Author: chandlerc
> > Date: Fri Feb 19 04:45:18 2016
> > New Revision: 261316
> >
> > URL: http://llvm.org/viewvc/llvm-project?rev=261316&view=rev
> > Log:
> > [LPM] Factor all of the loop analysis usage updates into a common helper
> > routine.
> >
> > We were getting this wrong in small ways and generally being very
> > inconsistent about it across loop passes. Instead, let's have a common
> > place where we do this. One minor downside is that this will require
> > some analyses like SCEV in more places than they are strictly needed.
> > However, this seems benign as these analyses are complete no-ops, and
> > without this consistency we can in many cases end up with the legacy
> > pass manager scheduling deciding to split up a loop pass pipeline in
> > order to run the function analysis half-way through. It is very, very
> > annoying to fix these without just being very pedantic across the board.
> >
> > The only loop passes I've not updated here are ones that use
> > AU.setPreservesAll() such as IVUsers (an analysis) and the pass printer.
> > They seemed less relevant.
> >
> > With this patch, almost all of the problems in PR24804 around loop pass
> > pipelines are fixed. The one remaining issue is that we run simplify-cfg
> > and instcombine in the middle of the loop pass pipeline. We've recently
> > added some loop variants of these passes that would seem substantially
> > cleaner to use, but this at least gets us much closer to the previous
> > state. Notably, the seven loop pass managers is down to three.
> >
> > I've not updated the loop passes using LoopAccessAnalysis because that
> > analysis hasn't been fully wired into LoopSimplify/LCSSA, and it isn't
> > clear that those transforms want to support those forms anyways. They
> > all run late anyways, so this is harmless. Similarly, LSR is left alone
> > because it already carefully manages its forms and doesn't need to get
> > fused into a single loop pass manager with a bunch of other loop passes.
> >
> > LoopReroll didn't use loop simplified form previously, and I've updated
> > the test case to match the trivially different output.
> >
> > Finally, I've also factored all the pass initialization for the passes
> > that use this technique as well, so that should be done regularly and
> > reliably.
> >
> > Thanks to James for the help reviewing and thinking about this stuff,
> > and Ben for help thinking about it as well!
> >
> > Differential Revision: http://reviews.llvm.org/D17435
> >
> > Modified:
> >      llvm/trunk/include/llvm/InitializePasses.h
> >      llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> >      llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
> >      llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopRerollPass.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
> >      llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> >      llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
> >      llvm/trunk/test/Other/pass-pipelines.ll
> >      llvm/trunk/test/Transforms/LoopReroll/nonconst_lb.ll
> >
> > Modified: llvm/trunk/include/llvm/InitializePasses.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/InitializePasses.h (original)
> > +++ llvm/trunk/include/llvm/InitializePasses.h Fri Feb 19 04:45:18 2016
> > @@ -163,6 +163,7 @@ void initializeLiveStacksPass(PassRegist
> >   void initializeLiveVariablesPass(PassRegistry&);
> >   void initializeLoaderPassPass(PassRegistry&);
> >   void initializeLocalStackSlotPassPass(PassRegistry&);
> > +void initializeLoopPassPass(PassRegistry&);
> >   void initializeLoopDeletionPass(PassRegistry&);
> >   void initializeLoopExtractorPass(PassRegistry&);
> >   void initializeLoopInfoWrapperPassPass(PassRegistry&);
> >
> > Modified: llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h (original)
> > +++ llvm/trunk/include/llvm/Transforms/Utils/LoopUtils.h Fri Feb 19
> 04:45:18 2016
> > @@ -385,6 +385,14 @@ bool checkStringMetadataIntoLoop(Loop *T
> >   /// \brief Set input string into loop metadata by keeping other values
> intact.
> >   void addStringMetadataToLoop(Loop *TheLoop, const char *MDString,
> >                                unsigned V = 0);
> > +
> > +/// Helper to consistently add the set of standard passes to a loop
> pass's \c
> > +/// AnalysisUsage.
> > +///
> > +/// All loop passes should call this as part of implementing their \c
> > +/// getAnalysisUsage.
> > +void getLoopAnalysisUsage(AnalysisUsage &AU);
> > +
> >   }
> >
> >   #endif
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/IndVarSimplify.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -107,16 +107,8 @@ public:
> >     bool runOnLoop(Loop *L, LPPassManager &LPM) override;
> >
> >     void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -    AU.addRequired<DominatorTreeWrapperPass>();
> > -    AU.addRequired<LoopInfoWrapperPass>();
> > -    AU.addRequired<ScalarEvolutionWrapperPass>();
> > -    AU.addRequiredID(LoopSimplifyID);
> > -    AU.addRequiredID(LCSSAID);
> > -    AU.addPreserved<GlobalsAAWrapperPass>();
> > -    AU.addPreserved<ScalarEvolutionWrapperPass>();
> > -    AU.addPreservedID(LoopSimplifyID);
> > -    AU.addPreservedID(LCSSAID);
> >       AU.setPreservesCFG();
> > +    getLoopAnalysisUsage(AU);
> >     }
> >
> >   private:
> > @@ -148,11 +140,7 @@ private:
> >   char IndVarSimplify::ID = 0;
> >   INITIALIZE_PASS_BEGIN(IndVarSimplify, "indvars",
> >                   "Induction Variable Simplification", false, false)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_END(IndVarSimplify, "indvars",
> >                   "Induction Variable Simplification", false, false)
> >
> >
> > Modified:
> llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
> (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/InductiveRangeCheckElimination.cpp
> Fri Feb 19 04:45:18 2016
> > @@ -211,11 +211,8 @@ public:
> >     }
> >
> >     void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -    AU.addRequired<LoopInfoWrapperPass>();
> > -    AU.addRequiredID(LoopSimplifyID);
> > -    AU.addRequiredID(LCSSAID);
> > -    AU.addRequired<ScalarEvolutionWrapperPass>();
> >       AU.addRequired<BranchProbabilityInfoWrapperPass>();
> > +    getLoopAnalysisUsage(AU);
> >     }
> >
> >     bool runOnLoop(Loop *L, LPPassManager &LPM) override;
> > @@ -226,11 +223,8 @@ char InductiveRangeCheckElimination::ID
> >
> >   INITIALIZE_PASS_BEGIN(InductiveRangeCheckElimination, "irce",
> >                         "Inductive range check elimination", false,
> false)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> >   INITIALIZE_PASS_DEPENDENCY(BranchProbabilityInfoWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_END(InductiveRangeCheckElimination, "irce",
> >                       "Inductive range check elimination", false, false)
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LICM.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LICM.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LICM.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LICM.cpp Fri Feb 19 04:45:18 2016
> > @@ -118,19 +118,8 @@ namespace {
> >       ///
> >       void getAnalysisUsage(AnalysisUsage &AU) const override {
> >         AU.setPreservesCFG();
> > -      AU.addRequired<DominatorTreeWrapperPass>();
> > -      AU.addRequired<LoopInfoWrapperPass>();
> > -      AU.addRequiredID(LoopSimplifyID);
> > -      AU.addPreservedID(LoopSimplifyID);
> > -      AU.addRequiredID(LCSSAID);
> > -      AU.addPreservedID(LCSSAID);
> > -      AU.addRequired<AAResultsWrapperPass>();
> > -      AU.addPreserved<AAResultsWrapperPass>();
> > -      AU.addPreserved<BasicAAWrapperPass>();
> > -      AU.addPreserved<GlobalsAAWrapperPass>();
> > -      AU.addPreserved<ScalarEvolutionWrapperPass>();
> > -      AU.addPreserved<SCEVAAWrapperPass>();
> >         AU.addRequired<TargetLibraryInfoWrapperPass>();
> > +      getLoopAnalysisUsage(AU);
> >       }
> >
> >       using llvm::Pass::doFinalization;
> > @@ -174,16 +163,8 @@ namespace {
> >
> >   char LICM::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LICM, "licm", "Loop Invariant Code Motion",
> false, false)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
> >   INITIALIZE_PASS_END(LICM, "licm", "Loop Invariant Code Motion", false,
> false)
> >
> >   Pass *llvm::createLICMPass() { return new LICM(); }
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopDeletion.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -21,6 +21,7 @@
> >   #include "llvm/Analysis/LoopPass.h"
> >   #include "llvm/Analysis/ScalarEvolution.h"
> >   #include "llvm/IR/Dominators.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   using namespace llvm;
> >
> >   #define DEBUG_TYPE "loop-delete"
> > @@ -39,18 +40,7 @@ namespace {
> >       bool runOnLoop(Loop *L, LPPassManager &) override;
> >
> >       void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -      AU.addRequired<DominatorTreeWrapperPass>();
> > -      AU.addRequired<LoopInfoWrapperPass>();
> > -      AU.addRequired<ScalarEvolutionWrapperPass>();
> > -      AU.addRequiredID(LoopSimplifyID);
> > -      AU.addRequiredID(LCSSAID);
> > -
> > -      AU.addPreserved<ScalarEvolutionWrapperPass>();
> > -      AU.addPreserved<DominatorTreeWrapperPass>();
> > -      AU.addPreserved<LoopInfoWrapperPass>();
> > -      AU.addPreserved<GlobalsAAWrapperPass>();
> > -      AU.addPreservedID(LoopSimplifyID);
> > -      AU.addPreservedID(LCSSAID);
> > +      getLoopAnalysisUsage(AU);
> >       }
> >
> >     private:
> > @@ -64,11 +54,7 @@ namespace {
> >   char LoopDeletion::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopDeletion, "loop-deletion",
> >                   "Delete dead loops", false, false)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_END(LoopDeletion, "loop-deletion",
> >                   "Delete dead loops", false, false)
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopIdiomRecognize.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -54,6 +54,7 @@
> >   #include "llvm/Support/Debug.h"
> >   #include "llvm/Support/raw_ostream.h"
> >   #include "llvm/Transforms/Utils/Local.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   using namespace llvm;
> >
> >   #define DEBUG_TYPE "loop-idiom"
> > @@ -85,23 +86,9 @@ public:
> >     /// loop preheaders be inserted into the CFG.
> >     ///
> >     void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -    AU.addRequired<LoopInfoWrapperPass>();
> > -    AU.addPreserved<LoopInfoWrapperPass>();
> > -    AU.addRequiredID(LoopSimplifyID);
> > -    AU.addPreservedID(LoopSimplifyID);
> > -    AU.addRequiredID(LCSSAID);
> > -    AU.addPreservedID(LCSSAID);
> > -    AU.addRequired<AAResultsWrapperPass>();
> > -    AU.addPreserved<AAResultsWrapperPass>();
> > -    AU.addRequired<ScalarEvolutionWrapperPass>();
> > -    AU.addPreserved<ScalarEvolutionWrapperPass>();
> > -    AU.addPreserved<SCEVAAWrapperPass>();
> > -    AU.addRequired<DominatorTreeWrapperPass>();
> > -    AU.addPreserved<DominatorTreeWrapperPass>();
> >       AU.addRequired<TargetLibraryInfoWrapperPass>();
> >       AU.addRequired<TargetTransformInfoWrapperPass>();
> > -    AU.addPreserved<BasicAAWrapperPass>();
> > -    AU.addPreserved<GlobalsAAWrapperPass>();
> > +    getLoopAnalysisUsage(AU);
> >     }
> >
> >   private:
> > @@ -154,16 +141,8 @@ private:
> >   char LoopIdiomRecognize::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopIdiomRecognize, "loop-idiom", "Recognize
> loop idioms",
> >                         false, false)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
> >   INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_END(LoopIdiomRecognize, "loop-idiom", "Recognize loop
> idioms",
> >                       false, false)
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopInstSimplify.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -25,6 +25,7 @@
> >   #include "llvm/Support/Debug.h"
> >   #include "llvm/Analysis/TargetLibraryInfo.h"
> >   #include "llvm/Transforms/Utils/Local.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   using namespace llvm;
> >
> >   #define DEBUG_TYPE "loop-instsimplify"
> > @@ -42,14 +43,10 @@ namespace {
> >       bool runOnLoop(Loop*, LPPassManager&) override;
> >
> >       void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -      AU.setPreservesCFG();
> >         AU.addRequired<AssumptionCacheTracker>();
> > -      AU.addRequired<LoopInfoWrapperPass>();
> > -      AU.addRequiredID(LoopSimplifyID);
> > -      AU.addPreservedID(LoopSimplifyID);
> > -      AU.addPreservedID(LCSSAID);
> > -      AU.addPreserved<ScalarEvolutionWrapperPass>();
> >         AU.addRequired<TargetLibraryInfoWrapperPass>();
> > +      AU.setPreservesCFG();
> > +      getLoopAnalysisUsage(AU);
> >       }
> >     };
> >   }
> > @@ -58,10 +55,8 @@ char LoopInstSimplify::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopInstSimplify, "loop-instsimplify",
> >                   "Simplify instructions in loops", false, false)
> >   INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> >   INITIALIZE_PASS_END(LoopInstSimplify, "loop-instsimplify",
> >                   "Simplify instructions in loops", false, false)
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopRerollPass.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRerollPass.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopRerollPass.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopRerollPass.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -147,13 +147,8 @@ namespace {
> >       bool runOnLoop(Loop *L, LPPassManager &LPM) override;
> >
> >       void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -      AU.addRequired<AAResultsWrapperPass>();
> > -      AU.addRequired<LoopInfoWrapperPass>();
> > -      AU.addPreserved<LoopInfoWrapperPass>();
> > -      AU.addRequired<DominatorTreeWrapperPass>();
> > -      AU.addPreserved<DominatorTreeWrapperPass>();
> > -      AU.addRequired<ScalarEvolutionWrapperPass>();
> >         AU.addRequired<TargetLibraryInfoWrapperPass>();
> > +      getLoopAnalysisUsage(AU);
> >       }
> >
> >     protected:
> > @@ -439,10 +434,7 @@ namespace {
> >
> >   char LoopReroll::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopReroll, "loop-reroll", "Reroll loops",
> false, false)
> > -INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
> >   INITIALIZE_PASS_END(LoopReroll, "loop-reroll", "Reroll loops", false,
> false)
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopRotation.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -34,6 +34,7 @@
> >   #include "llvm/Support/raw_ostream.h"
> >   #include "llvm/Transforms/Utils/BasicBlockUtils.h"
> >   #include "llvm/Transforms/Utils/Local.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   #include "llvm/Transforms/Utils/SSAUpdater.h"
> >   #include "llvm/Transforms/Utils/ValueMapper.h"
> >   using namespace llvm;
> > @@ -578,20 +579,9 @@ public:
> >
> >     // LCSSA form makes instruction renaming easier.
> >     void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -    AU.addPreserved<AAResultsWrapperPass>();
> >       AU.addRequired<AssumptionCacheTracker>();
> > -    AU.addPreserved<DominatorTreeWrapperPass>();
> > -    AU.addRequired<LoopInfoWrapperPass>();
> > -    AU.addPreserved<LoopInfoWrapperPass>();
> > -    AU.addRequiredID(LoopSimplifyID);
> > -    AU.addPreservedID(LoopSimplifyID);
> > -    AU.addRequiredID(LCSSAID);
> > -    AU.addPreservedID(LCSSAID);
> > -    AU.addPreserved<ScalarEvolutionWrapperPass>();
> > -    AU.addPreserved<SCEVAAWrapperPass>();
> >       AU.addRequired<TargetTransformInfoWrapperPass>();
> > -    AU.addPreserved<BasicAAWrapperPass>();
> > -    AU.addPreserved<GlobalsAAWrapperPass>();
> > +    getLoopAnalysisUsage(AU);
> >     }
> >
> >     bool runOnLoop(Loop *L, LPPassManager &LPM) override {
> > @@ -614,14 +604,9 @@ public:
> >
> >   char LoopRotate::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopRotate, "loop-rotate", "Rotate Loops",
> false, false)
> > -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > -INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> > +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_END(LoopRotate, "loop-rotate", "Rotate Loops", false,
> false)
> >
> >   Pass *llvm::createLoopRotatePass(int MaxHeaderSize) {
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopSimplifyCFG.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -29,6 +29,7 @@
> >   #include "llvm/Analysis/TargetTransformInfo.h"
> >   #include "llvm/IR/Dominators.h"
> >   #include "llvm/Transforms/Utils/Local.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   using namespace llvm;
> >
> >   #define DEBUG_TYPE "loop-simplifycfg"
> > @@ -44,19 +45,8 @@ public:
> >     bool runOnLoop(Loop *L, LPPassManager &) override;
> >
> >     void getAnalysisUsage(AnalysisUsage &AU) const override {
> > -    AU.addRequired<DominatorTreeWrapperPass>();
> > -    AU.addRequired<LoopInfoWrapperPass>();
> > -
> > -    AU.addPreserved<DominatorTreeWrapperPass>();
> > -    AU.addPreserved<LoopInfoWrapperPass>();
> > -    AU.addPreserved<GlobalsAAWrapperPass>();
> > -    AU.addPreserved<BasicAAWrapperPass>();
> > -    AU.addPreserved<AAResultsWrapperPass>();
> > -    AU.addPreserved<ScalarEvolutionWrapperPass>();
> > -    AU.addPreserved<SCEVAAWrapperPass>();
> >       AU.addPreserved<DependenceAnalysis>();
> > -    AU.addPreservedID(LoopSimplifyID);
> > -    AU.addPreservedID(LCSSAID);
> > +    getLoopAnalysisUsage(AU);
> >     }
> >   };
> >   }
> > @@ -64,8 +54,7 @@ public:
> >   char LoopSimplifyCFG::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopSimplifyCFG, "loop-simplifycfg", "Simplify
> loop CFG",
> >                         false, false)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> >   INITIALIZE_PASS_END(LoopSimplifyCFG, "loop-simplifycfg", "Simplify
> loop CFG",
> >                       false, false)
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopUnrollPass.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -32,6 +32,7 @@
> >   #include "llvm/Support/CommandLine.h"
> >   #include "llvm/Support/Debug.h"
> >   #include "llvm/Support/raw_ostream.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   #include "llvm/Transforms/Utils/UnrollLoop.h"
> >   #include <climits>
> >
> > @@ -744,35 +745,19 @@ public:
> >     ///
> >     void getAnalysisUsage(AnalysisUsage &AU) const override {
> >       AU.addRequired<AssumptionCacheTracker>();
> > -    AU.addRequired<DominatorTreeWrapperPass>();
> > -    AU.addRequired<LoopInfoWrapperPass>();
> > -    AU.addPreserved<LoopInfoWrapperPass>();
> > -    AU.addRequiredID(LoopSimplifyID);
> > -    AU.addPreservedID(LoopSimplifyID);
> > -    AU.addRequiredID(LCSSAID);
> > -    AU.addPreservedID(LCSSAID);
> > -    AU.addRequired<ScalarEvolutionWrapperPass>();
> > -    AU.addPreserved<ScalarEvolutionWrapperPass>();
> >       AU.addRequired<TargetTransformInfoWrapperPass>();
> > -    // FIXME: Loop unroll requires LCSSA. And LCSSA requires dom info.
> > -    // If loop unroll does not preserve dom info then LCSSA pass on next
> > -    // loop will receive invalid dom info.
> > -    // For now, recreate dom info, if loop is unrolled.
> > -    AU.addPreserved<DominatorTreeWrapperPass>();
> > -    AU.addPreserved<GlobalsAAWrapperPass>();
> > +    // FIXME: Loop passes are required to preserve domtree, and for now
> we just
> > +    // recreate dom info if anything gets unrolled.
> > +    getLoopAnalysisUsage(AU);
> >     }
> >   };
> >   }
> >
> >   char LoopUnroll::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopUnroll, "loop-unroll", "Unroll loops",
> false, false)
> > -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
> > -INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > -INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> > +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_END(LoopUnroll, "loop-unroll", "Unroll loops", false,
> false)
> >
> >   Pass *llvm::createLoopUnrollPass(int Threshold, int Count, int
> AllowPartial,
> >
> > Modified: llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Scalar/LoopUnswitch.cpp Fri Feb 19
> 04:45:18 2016
> > @@ -55,6 +55,7 @@
> >   #include "llvm/Transforms/Utils/BasicBlockUtils.h"
> >   #include "llvm/Transforms/Utils/Cloning.h"
> >   #include "llvm/Transforms/Utils/Local.h"
> > +#include "llvm/Transforms/Utils/LoopUtils.h"
> >   #include <algorithm>
> >   #include <map>
> >   #include <set>
> > @@ -211,17 +212,8 @@ namespace {
> >       ///
> >       void getAnalysisUsage(AnalysisUsage &AU) const override {
> >         AU.addRequired<AssumptionCacheTracker>();
> > -      AU.addRequiredID(LoopSimplifyID);
> > -      AU.addPreservedID(LoopSimplifyID);
> > -      AU.addRequired<LoopInfoWrapperPass>();
> > -      AU.addPreserved<LoopInfoWrapperPass>();
> > -      AU.addRequiredID(LCSSAID);
> > -      AU.addPreservedID(LCSSAID);
> > -      AU.addRequired<DominatorTreeWrapperPass>();
> > -      AU.addPreserved<DominatorTreeWrapperPass>();
> > -      AU.addPreserved<ScalarEvolutionWrapperPass>();
> >         AU.addRequired<TargetTransformInfoWrapperPass>();
> > -      AU.addPreserved<GlobalsAAWrapperPass>();
> > +      getLoopAnalysisUsage(AU);
> >       }
> >
> >     private:
> > @@ -382,11 +374,9 @@ void LUAnalysisCache::cloneData(const Lo
> >   char LoopUnswitch::ID = 0;
> >   INITIALIZE_PASS_BEGIN(LoopUnswitch, "loop-unswitch", "Unswitch loops",
> >                         false, false)
> > -INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_DEPENDENCY(AssumptionCacheTracker)
> > -INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > -INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > -INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > +INITIALIZE_PASS_DEPENDENCY(LoopPass)
> > +INITIALIZE_PASS_DEPENDENCY(TargetTransformInfoWrapperPass)
> >   INITIALIZE_PASS_END(LoopUnswitch, "loop-unswitch", "Unswitch loops",
> >                         false, false)
> >
> >
> > Modified: llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp (original)
> > +++ llvm/trunk/lib/Transforms/Utils/LoopUtils.cpp Fri Feb 19 04:45:18
> 2016
> > @@ -11,13 +11,19 @@
> >   //
> >
>  //===----------------------------------------------------------------------===//
> >
> > +#include "llvm/Analysis/AliasAnalysis.h"
> > +#include "llvm/Analysis/BasicAliasAnalysis.h"
> >   #include "llvm/Analysis/LoopInfo.h"
> > +#include "llvm/Analysis/GlobalsModRef.h"
> >   #include "llvm/Analysis/ScalarEvolution.h"
> >   #include "llvm/Analysis/ScalarEvolutionExpressions.h"
> > +#include "llvm/Analysis/ScalarEvolutionAliasAnalysis.h"
> > +#include "llvm/IR/Dominators.h"
> >   #include "llvm/IR/Instructions.h"
> >   #include "llvm/IR/Module.h"
> >   #include "llvm/IR/PatternMatch.h"
> >   #include "llvm/IR/ValueHandle.h"
> > +#include "llvm/Pass.h"
> >   #include "llvm/Support/Debug.h"
> >   #include "llvm/Transforms/Utils/LoopUtils.h"
> >
> > @@ -727,3 +733,57 @@ SmallVector<Instruction *, 8> llvm::find
> >
> >     return UsedOutside;
> >   }
> > +
> > +void llvm::getLoopAnalysisUsage(AnalysisUsage &AU) {
> > +  // By definition, all loop passes need the LoopInfo analysis and the
> > +  // Dominator tree it depends on. Because they all participate in the
> loop
> > +  // pass manager, they must also preserve these.
> > +  AU.addRequired<DominatorTreeWrapperPass>();
> > +  AU.addPreserved<DominatorTreeWrapperPass>();
> > +  AU.addRequired<LoopInfoWrapperPass>();
> > +  AU.addPreserved<LoopInfoWrapperPass>();
> > +
> > +  // We must also preserve LoopSimplify and LCSSA. We locally access
> their IDs
> > +  // here because users shouldn't directly get them from this header.
> > +  extern char &LoopSimplifyID;
> > +  extern char &LCSSAID;
> > +  AU.addRequiredID(LoopSimplifyID);
> > +  AU.addPreservedID(LoopSimplifyID);
> > +  AU.addRequiredID(LCSSAID);
> > +  AU.addPreservedID(LCSSAID);
> > +
> > +  // Loop passes are designed to run inside of a loop pass manager
> which means
> > +  // that any function analyses they require must be required by the
> first loop
> > +  // pass in the manager (so that it is computed before the loop pass
> manager
> > +  // runs) and preserved by all loop pasess in the manager. To make this
> > +  // reasonably robust, the set needed for most loop passes is
> maintained here.
> > +  // If your loop pass requires an analysis not listed here, you will
> need to
> > +  // carefully audit the loop pass manager nesting structure that
> results.
> > +  AU.addRequired<AAResultsWrapperPass>();
> > +  AU.addPreserved<AAResultsWrapperPass>();
> > +  AU.addPreserved<BasicAAWrapperPass>();
> > +  AU.addPreserved<GlobalsAAWrapperPass>();
> > +  AU.addPreserved<SCEVAAWrapperPass>();
> > +  AU.addRequired<ScalarEvolutionWrapperPass>();
> > +  AU.addPreserved<ScalarEvolutionWrapperPass>();
> > +}
> > +
> > +/// Manually defined generic "LoopPass" dependency initialization. This
> is used
> > +/// to initialize the exact set of passes from above in \c
> > +/// getLoopAnalysisUsage. It can be used within a loop pass's
> initialization
> > +/// with:
> > +///
> > +///   INITIALIZE_PASS_DEPENDENCY(LoopPass)
> > +///
> > +/// As-if "LoopPass" were a pass.
> > +void llvm::initializeLoopPassPass(PassRegistry &Registry) {
> > +  INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
> > +  INITIALIZE_PASS_DEPENDENCY(LoopInfoWrapperPass)
> > +  INITIALIZE_PASS_DEPENDENCY(LoopSimplify)
> > +  INITIALIZE_PASS_DEPENDENCY(LCSSA)
> > +  INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
> > +  INITIALIZE_PASS_DEPENDENCY(BasicAAWrapperPass)
> > +  INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)
> > +  INITIALIZE_PASS_DEPENDENCY(SCEVAAWrapperPass)
> > +  INITIALIZE_PASS_DEPENDENCY(ScalarEvolutionWrapperPass)
> > +}
> >
> > Modified: llvm/trunk/test/Other/pass-pipelines.ll
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Other/pass-pipelines.ll?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/test/Other/pass-pipelines.ll (original)
> > +++ llvm/trunk/test/Other/pass-pipelines.ll Fri Feb 19 04:45:18 2016
> > @@ -38,12 +38,6 @@
> >   ; CHECK-O2-NOT: Manager
> >   ; CHECK-O2: Loop Pass Manager
> >   ; CHECK-O2-NOT: Manager
> > -; FIXME: We shouldn't have this extra loop pass manager!
> > -; CHECK-O2: Loop Pass Manager
> > -; CHECK-O2-NOT: Manager
> > -; FIXME: Yet another pointless loop pass manager!
> > -; CHECK-O2: Loop Pass Manager
> > -; CHECK-O2-NOT: Manager
> >   ; FIXME: We shouldn't be pulling out to simplify-cfg and instcombine
> and
> >   ; causing new loop pass managers.
> >   ; CHECK-O2: Simplify the CFG
> > @@ -52,12 +46,6 @@
> >   ; CHECK-O2-NOT: Manager
> >   ; CHECK-O2: Loop Pass Manager
> >   ; CHECK-O2-NOT: Manager
> > -; FIXME: Yet another pointless loop pass manager!
> > -; CHECK-O2: Loop Pass Manager
> > -; CHECK-O2-NOT: Manager
> > -; FIXME: Yet another pointless loop pass manager!
> > -; CHECK-O2: Loop Pass Manager
> > -; CHECK-O2-NOT: Manager
> >   ; FIXME: It isn't clear that we need yet another loop pass pipeline
> >   ; and run of LICM here.
> >   ; CHECK-O2-NOT: Manager
> >
> > Modified: llvm/trunk/test/Transforms/LoopReroll/nonconst_lb.ll
> > URL:
> http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LoopReroll/nonconst_lb.ll?rev=261316&r1=261315&r2=261316&view=diff
> >
> ==============================================================================
> > --- llvm/trunk/test/Transforms/LoopReroll/nonconst_lb.ll (original)
> > +++ llvm/trunk/test/Transforms/LoopReroll/nonconst_lb.ll Fri Feb 19
> 04:45:18 2016
> > @@ -58,7 +58,7 @@ for.end:
> >   ; CHECK:   br label %for.body
> >
> >   ; CHECK: for.body:                                         ; preds =
> %for.body, %for.body.preheader
> > -; CHECK:   %indvar = phi i32 [ %indvar.next, %for.body ], [ 0,
> %for.body.preheader ]
> > +; CHECK:   %indvar = phi i32 [ 0, %for.body.preheader ], [
> %indvar.next, %for.body ]
> >   ; CHECK:   %6 = add i32 %m, %indvar
> >   ; CHECK:   %arrayidx = getelementptr inbounds i32, i32* %B, i32 %6
> >   ; CHECK:   %7 = load i32, i32* %arrayidx, align 4
> > @@ -67,7 +67,7 @@ for.end:
> >   ; CHECK:   store i32 %mul, i32* %arrayidx2, align 4
> >   ; CHECK:   %indvar.next = add i32 %indvar, 1
> >   ; CHECK:   %exitcond = icmp eq i32 %6, %5
> > -; CHECK:   br i1 %exitcond, label %for.end, label %for.body
> > +; CHECK:   br i1 %exitcond, label %for.end.loopexit, label %for.body
> >
> >   ;void daxpy_ur(int n,float da,float *dx,float *dy)
> >   ;    {
> > @@ -138,7 +138,7 @@ for.end:
> >   ; CHECK:   br label %for.body
> >
> >   ; CHECK: for.body:
> > -; CHECK:   %indvar = phi i32 [ %indvar.next, %for.body ], [ 0,
> %for.body.preheader ]
> > +; CHECK:   %indvar = phi i32 [ 0, %for.body.preheader ], [
> %indvar.next, %for.body ]
> >   ; CHECK:   %6 = add i32 %rem, %indvar
> >   ; CHECK:   %arrayidx = getelementptr inbounds float, float* %dy, i32 %6
> >   ; CHECK:   %7 = load float, float* %arrayidx, align 4
> > @@ -149,4 +149,4 @@ for.end:
> >   ; CHECK:   store float %add, float* %arrayidx, align 4
> >   ; CHECK:   %indvar.next = add i32 %indvar, 1
> >   ; CHECK:   %exitcond = icmp eq i32 %6, %5
> > -; CHECK:   br i1 %exitcond, label %for.end, label %for.body
> > +; CHECK:   br i1 %exitcond, label %for.end.loopexit, label %for.body
> >
> >
> > _______________________________________________
> > 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/20160227/3d6124b8/attachment.html>


More information about the llvm-commits mailing list