<div dir="ltr"><div><div><span style="font-size:12.8px">> I'm not convinced this is the right model in the new pass manager - it's</span><br></div><span style="font-size:12.8px">> essentially giving us two layers of caching, since the new PM already</span><br style="font-size:12.8px"><span style="font-size:12.8px">> computes the analysis on demand (when you first call getResult) and</span><br style="font-size:12.8px"><span style="font-size:12.8px">> caches that until its invalidated.</span><br><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">IIRC, the lazy pass was made before we decided to just compute everything eagerly all the time (which lets us provide the uses-point-to-their-actual-clobbering-defs guarantee). So, the name here is somewhat misleading. If it turns out that we don't need this at all, I think it would be fine to remove it. Otherwise, renaming it to just MemorySSAPass (or similar) would probably be best.</span></div></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">> This is pretty weird in a printer pass. Does this mean we would need to</span><br style="font-size:12.8px"><span style="font-size:12.8px">> call buildMemorySSA in *any* user of the analysis pass?</span><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px"><br></span></div><div><span style="font-size:12.8px">Yeah, the API is a bit ugly here. :)</span></div><div><span style="font-size:12.8px">buildMemorySSA is actually more like "buildMemorySSAOrGetTheWalkerIfWeveAlreadyBuiltMemorySSA". It may be cleaner to just have whatever pass that ends up wrapping MemorySSA hold a pointer to the walker that buildMemorySSA returns, and provide an accessor to that (in addition to allowing users to still grab MSSA, if they want).</span></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 4, 2016 at 10:40 AM, Justin Bogner <span dir="ltr"><<a href="mailto:mail@justinbogner.com" target="_blank">mail@justinbogner.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>Geoff Berry via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>> writes:<br>
> gberry updated this revision to Diff 55623.<br>
<br>
</span>A couple of comments below. In short, I don't think this has quite the<br>
right model. I've also cc'd Chandler for his thoughts.<br>
<span><br>
><br>
> <a href="http://reviews.llvm.org/D19664" rel="noreferrer" target="_blank">http://reviews.llvm.org/D19664</a><br>
><br>
> Files:<br>
>   include/llvm/InitializePasses.h<br>
>   include/llvm/Transforms/Utils/MemorySSA.h<br>
>   lib/Passes/PassBuilder.cpp<br>
>   lib/Passes/PassRegistry.def<br>
>   lib/Transforms/Utils/MemorySSA.cpp<br>
>   lib/Transforms/Utils/Utils.cpp<br>
>   test/Transforms/Util/MemorySSA/assume.ll<br>
>   test/Transforms/Util/MemorySSA/atomic-clobber.ll<br>
>   test/Transforms/Util/MemorySSA/cyclicphi.ll<br>
>   test/Transforms/Util/MemorySSA/function-clobber.ll<br>
>   test/Transforms/Util/MemorySSA/function-mem-attrs.ll<br>
>   test/Transforms/Util/MemorySSA/livein.ll<br>
>   test/Transforms/Util/MemorySSA/load-invariant.ll<br>
>   test/Transforms/Util/MemorySSA/many-dom-backedge.ll<br>
>   test/Transforms/Util/MemorySSA/many-doms.ll<br>
>   test/Transforms/Util/MemorySSA/multi-edges.ll<br>
>   test/Transforms/Util/MemorySSA/multiple-backedges-hal.ll<br>
>   test/Transforms/Util/MemorySSA/multiple-locations.ll<br>
>   test/Transforms/Util/MemorySSA/no-disconnected.ll<br>
>   test/Transforms/Util/MemorySSA/optimize-use.ll<br>
>   test/Transforms/Util/MemorySSA/phi-translation.ll<br>
>   test/Transforms/Util/MemorySSA/volatile-clobber.ll<br>
><br>
</span>> Index: test/Transforms/Util/MemorySSA/volatile-clobber.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/volatile-clobber.ll<br>
> +++ test/Transforms/Util/MemorySSA/volatile-clobber.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Ensures that volatile stores/loads count as MemoryDefs<br>
><br>
> Index: test/Transforms/Util/MemorySSA/phi-translation.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/phi-translation.ll<br>
> +++ test/Transforms/Util/MemorySSA/phi-translation.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
><br>
>  ; %ptr can't alias %local, so we should be able to optimize the use of %local to<br>
>  ; point to the store to %local.<br>
> Index: test/Transforms/Util/MemorySSA/optimize-use.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/optimize-use.ll<br>
> +++ test/Transforms/Util/MemorySSA/optimize-use.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -analyze -verify-memoryssa < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
><br>
>  ; Function Attrs: ssp uwtable<br>
>  define i32 @main() {<br>
> Index: test/Transforms/Util/MemorySSA/no-disconnected.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/no-disconnected.ll<br>
> +++ test/Transforms/Util/MemorySSA/no-disconnected.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -analyze -verify-memoryssa < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; This test ensures we don't end up with multiple reaching defs for a single<br>
>  ; use/phi edge If we were to optimize defs, we would end up with 2=<br>
> Index: test/Transforms/Util/MemorySSA/multiple-locations.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/multiple-locations.ll<br>
> +++ test/Transforms/Util/MemorySSA/multiple-locations.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Checks that basicAA is doing some amount of disambiguation for us<br>
><br>
> Index: test/Transforms/Util/MemorySSA/multiple-backedges-hal.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/multiple-backedges-hal.ll<br>
> +++ test/Transforms/Util/MemorySSA/multiple-backedges-hal.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
><br>
>  ; hfinkel's case<br>
>  ; [entry]<br>
> Index: test/Transforms/Util/MemorySSA/multi-edges.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/multi-edges.ll<br>
> +++ test/Transforms/Util/MemorySSA/multi-edges.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Makes sure we have a sane model if both successors of some block is the same<br>
>  ; block.<br>
> Index: test/Transforms/Util/MemorySSA/many-doms.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/many-doms.ll<br>
> +++ test/Transforms/Util/MemorySSA/many-doms.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Testing many dominators, specifically from a switch statement in C.<br>
><br>
> Index: test/Transforms/Util/MemorySSA/many-dom-backedge.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/many-dom-backedge.ll<br>
> +++ test/Transforms/Util/MemorySSA/many-dom-backedge.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; many-dom.ll, with an added back-edge back into the switch.<br>
>  ; Because people love their gotos.<br>
> Index: test/Transforms/Util/MemorySSA/load-invariant.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/load-invariant.ll<br>
> +++ test/Transforms/Util/MemorySSA/load-invariant.ll<br>
> @@ -1,5 +1,6 @@<br>
>  ; XFAIL: *<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Invariant loads should be considered live on entry, because, once the<br>
>  ; location is known to be dereferenceable, the value can never change.<br>
> Index: test/Transforms/Util/MemorySSA/livein.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/livein.ll<br>
> +++ test/Transforms/Util/MemorySSA/livein.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  define void @F(i8*) {<br>
>    br i1 true, label %left, label %right<br>
>  left:<br>
> Index: test/Transforms/Util/MemorySSA/function-mem-attrs.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/function-mem-attrs.ll<br>
> +++ test/Transforms/Util/MemorySSA/function-mem-attrs.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Test that various function attributes give us sane results.<br>
><br>
> Index: test/Transforms/Util/MemorySSA/function-clobber.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/function-clobber.ll<br>
> +++ test/Transforms/Util/MemorySSA/function-clobber.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Ensuring that external functions without attributes are MemoryDefs<br>
><br>
> Index: test/Transforms/Util/MemorySSA/cyclicphi.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/cyclicphi.ll<br>
> +++ test/Transforms/Util/MemorySSA/cyclicphi.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
><br>
>  %struct.hoge = type { i32, %struct.widget }<br>
>  %struct.widget = type { i64 }<br>
> Index: test/Transforms/Util/MemorySSA/atomic-clobber.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/atomic-clobber.ll<br>
> +++ test/Transforms/Util/MemorySSA/atomic-clobber.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Ensures that atomic loads count as MemoryDefs<br>
><br>
> Index: test/Transforms/Util/MemorySSA/assume.ll<br>
> ===================================================================<br>
> --- test/Transforms/Util/MemorySSA/assume.ll<br>
> +++ test/Transforms/Util/MemorySSA/assume.ll<br>
> @@ -1,4 +1,5 @@<br>
>  ; RUN: opt -basicaa -print-memoryssa -verify-memoryssa -analyze < %s 2>&1 | FileCheck %s<br>
> +; RUN: opt -aa-pipeline=basic-aa -passes='print<memoryssa>' -verify-memoryssa -disable-output < %s 2>&1 | FileCheck %s<br>
>  ;<br>
>  ; Ensures that assumes are treated as not reading or writing memory.<br>
><br>
> Index: lib/Transforms/Utils/Utils.cpp<br>
> ===================================================================<br>
> --- lib/Transforms/Utils/Utils.cpp<br>
> +++ lib/Transforms/Utils/Utils.cpp<br>
> @@ -34,7 +34,7 @@<br>
>    initializeInstSimplifierPass(Registry);<br>
>    initializeMetaRenamerPass(Registry);<br>
>    initializeMemorySSALazyPass(Registry);<br>
> -  initializeMemorySSAPrinterPassPass(Registry);<br>
> +  initializeMemorySSAPrinterLegacyPassPass(Registry);<br>
>  }<br>
><br>
>  /// LLVMInitializeTransformUtils - C binding for initializeTransformUtilsPasses.<br>
> Index: lib/Transforms/Utils/MemorySSA.cpp<br>
> ===================================================================<br>
> --- lib/Transforms/Utils/MemorySSA.cpp<br>
> +++ lib/Transforms/Utils/MemorySSA.cpp<br>
> @@ -46,15 +46,19 @@<br>
>  STATISTIC(NumClobberCacheLookups, "Number of Memory SSA version cache lookups");<br>
>  STATISTIC(NumClobberCacheHits, "Number of Memory SSA version cache hits");<br>
>  STATISTIC(NumClobberCacheInserts, "Number of MemorySSA version cache inserts");<br>
> -INITIALIZE_PASS_WITH_OPTIONS_BEGIN(MemorySSAPrinterPass, "print-memoryssa",<br>
> -                                   "Memory SSA", true, true)<br>
> +INITIALIZE_PASS_BEGIN(MemorySSAPrinterLegacyPass, "print-memoryssa",<br>
> +                      "Memory SSA", true, true)<br>
>  INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)<br>
>  INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)<br>
>  INITIALIZE_PASS_DEPENDENCY(GlobalsAAWrapperPass)<br>
> -INITIALIZE_PASS_END(MemorySSAPrinterPass, "print-memoryssa", "Memory SSA", true,<br>
> -                    true)<br>
> +INITIALIZE_PASS_END(MemorySSAPrinterLegacyPass, "print-memoryssa", "Memory SSA",<br>
> +                    true, true)<br>
>  INITIALIZE_PASS(MemorySSALazy, "memoryssalazy", "Memory SSA", true, true)<br>
><br>
> +static cl::opt<bool> VerifyMemorySSA("verify-memoryssa", cl::init(false),<br>
> +                                     cl::Hidden,<br>
> +                                     cl::desc("Run the Memory SSA verifier"));<br>
> +<br>
>  namespace llvm {<br>
><br>
>  /// \brief An assembly annotator class to print Memory SSA information in<br>
> @@ -677,45 +681,36 @@<br>
>    dbgs() << "\n";<br>
>  }<br>
><br>
> -char MemorySSAPrinterPass::ID = 0;<br>
> +char MemorySSAPrinterLegacyPass::ID = 0;<br>
><br>
> -MemorySSAPrinterPass::MemorySSAPrinterPass() : FunctionPass(ID) {<br>
> -  initializeMemorySSAPrinterPassPass(*PassRegistry::getPassRegistry());<br>
> +MemorySSAPrinterLegacyPass::MemorySSAPrinterLegacyPass() : FunctionPass(ID) {<br>
> +  initializeMemorySSAPrinterLegacyPassPass(*PassRegistry::getPassRegistry());<br>
>  }<br>
><br>
> -void MemorySSAPrinterPass::releaseMemory() {<br>
> +void MemorySSAPrinterLegacyPass::releaseMemory() {<br>
>    // Subtlety: Be sure to delete the walker before MSSA, because the walker's<br>
>    // dtor may try to access MemorySSA.<br>
>    Walker.reset();<br>
>    MSSA.reset();<br>
>  }<br>
><br>
> -void MemorySSAPrinterPass::getAnalysisUsage(AnalysisUsage &AU) const {<br>
> +void MemorySSAPrinterLegacyPass::getAnalysisUsage(AnalysisUsage &AU) const {<br>
>    AU.setPreservesAll();<br>
>    AU.addRequired<AAResultsWrapperPass>();<br>
>    AU.addRequired<DominatorTreeWrapperPass>();<br>
>    AU.addPreserved<DominatorTreeWrapperPass>();<br>
>    AU.addPreserved<GlobalsAAWrapperPass>();<br>
>  }<br>
><br>
> -bool MemorySSAPrinterPass::doInitialization(Module &M) {<br>
> -  VerifyMemorySSA = M.getContext()<br>
> -                        .getOption<bool, MemorySSAPrinterPass,<br>
> -                                   &MemorySSAPrinterPass::VerifyMemorySSA>();<br>
> +bool MemorySSAPrinterLegacyPass::doInitialization(Module &M) {<br>
>    return false;<br>
>  }<br>
><br>
> -void MemorySSAPrinterPass::registerOptions() {<br>
> -  OptionRegistry::registerOption<bool, MemorySSAPrinterPass,<br>
> -                                 &MemorySSAPrinterPass::VerifyMemorySSA>(<br>
> -      "verify-memoryssa", "Run the Memory SSA verifier", false);<br>
> -}<br>
> -<br>
> -void MemorySSAPrinterPass::print(raw_ostream &OS, const Module *M) const {<br>
> +void MemorySSAPrinterLegacyPass::print(raw_ostream &OS, const Module *M) const {<br>
>    MSSA->print(OS);<br>
>  }<br>
><br>
> -bool MemorySSAPrinterPass::runOnFunction(Function &F) {<br>
> +bool MemorySSAPrinterLegacyPass::runOnFunction(Function &F) {<br>
>    this->F = &F;<br>
>    MSSA.reset(new MemorySSA(F));<br>
>    AliasAnalysis *AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();<br>
> @@ -729,6 +724,36 @@<br>
>    return false;<br>
>  }<br>
><br>
> +MemorySSAPrinterPass::MemorySSAPrinterPass(raw_ostream &OS) : OS(OS) {}<br>
> +<br>
> +PreservedAnalyses MemorySSAPrinterPass::run(Function &F,<br>
> +                                            FunctionAnalysisManager &AM) {<br>
> +  OS << "MemorySSA for function: " << F.getName() << "\n";<br>
> +<br>
> +  auto &DT = AM.getResult<DominatorTreeAnalysis>(F);<br>
> +  auto &AA = AM.getResult<AAManager>(F);<br>
> +  MemorySSA &MSSA = AM.getResult<MemorySSALazyAnalysis>(F).getMSSA();<br>
> +<br>
> +  MSSA.buildMemorySSA(&AA, &DT);<br>
<br>
This is pretty weird in a printer pass. Does this mean we would need to<br>
call buildMemorySSA in *any* user of the analysis pass?<br>
<br>
> +  MSSA.print(OS);<br>
> +<br>
> +  if (VerifyMemorySSA)<br>
> +    MSSA.verifyMemorySSA();<br>
<br>
Just write a separate verify<memoryssa> pass, like we do for domtree and<br>
the like. Having a cl::opt that modifies the print behaviour is<br>
inflexible and awkward.<br>
<br>
> +<br>
> +  return PreservedAnalyses::all();<br>
> +}<br>
> +<br>
> +MemorySSALazyResults::MemorySSALazyResults(Function &F) {<br>
> +  MSSA.reset(new MemorySSA(F));<br>
> +}<br>
> +<br>
> +char MemorySSALazyAnalysis::PassID;<br>
> +<br>
> +MemorySSALazyResults<br>
> +MemorySSALazyAnalysis::run(Function &F, AnalysisManager<Function> &AM) {<br>
> +  return MemorySSALazyResults(F);<br>
> +}<br>
> +<br>
>  char MemorySSALazy::ID = 0;<br>
><br>
>  MemorySSALazy::MemorySSALazy() : FunctionPass(ID) {<br>
> Index: lib/Passes/PassRegistry.def<br>
> ===================================================================<br>
> --- lib/Passes/PassRegistry.def<br>
> +++ lib/Passes/PassRegistry.def<br>
> @@ -74,6 +74,7 @@<br>
>  FUNCTION_ANALYSIS("domfrontier", DominanceFrontierAnalysis())<br>
>  FUNCTION_ANALYSIS("loops", LoopAnalysis())<br>
>  FUNCTION_ANALYSIS("memdep", MemoryDependenceAnalysis())<br>
> +FUNCTION_ANALYSIS("memoryssa", MemorySSALazyAnalysis())<br>
>  FUNCTION_ANALYSIS("regions", RegionInfoAnalysis())<br>
>  FUNCTION_ANALYSIS("no-op-function", NoOpFunctionAnalysis())<br>
>  FUNCTION_ANALYSIS("scalar-evolution", ScalarEvolutionAnalysis())<br>
> @@ -112,6 +113,7 @@<br>
>  FUNCTION_PASS("print<demanded-bits>", DemandedBitsPrinterPass(dbgs()))<br>
>  FUNCTION_PASS("print<domfrontier>", DominanceFrontierPrinterPass(dbgs()))<br>
>  FUNCTION_PASS("print<loops>", LoopPrinterPass(dbgs()))<br>
> +FUNCTION_PASS("print<memoryssa>", MemorySSAPrinterPass(dbgs()))<br>
>  FUNCTION_PASS("print<regions>", RegionInfoPrinterPass(dbgs()))<br>
>  FUNCTION_PASS("print<scalar-evolution>", ScalarEvolutionPrinterPass(dbgs()))<br>
>  FUNCTION_PASS("reassociate", ReassociatePass())<br>
> Index: lib/Passes/PassBuilder.cpp<br>
> ===================================================================<br>
> --- lib/Passes/PassBuilder.cpp<br>
> +++ lib/Passes/PassBuilder.cpp<br>
> @@ -62,6 +62,7 @@<br>
>  #include "llvm/Transforms/Scalar/SROA.h"<br>
>  #include "llvm/Transforms/Scalar/SimplifyCFG.h"<br>
>  #include "llvm/Transforms/Scalar/Sink.h"<br>
> +#include "llvm/Transforms/Utils/MemorySSA.h"<br>
>  #include <type_traits><br>
><br>
>  using namespace llvm;<br>
> Index: include/llvm/Transforms/Utils/MemorySSA.h<br>
> ===================================================================<br>
> --- include/llvm/Transforms/Utils/MemorySSA.h<br>
> +++ include/llvm/Transforms/Utils/MemorySSA.h<br>
> @@ -561,7 +561,7 @@<br>
>  protected:<br>
>    // Used by Memory SSA annotater, dumpers, and wrapper pass<br>
>    friend class MemorySSAAnnotatedWriter;<br>
> -  friend class MemorySSAPrinterPass;<br>
> +  friend class MemorySSAPrinterLegacyPass;<br>
>    void verifyDefUses(Function &F) const;<br>
>    void verifyDomination(Function &F) const;<br>
><br>
> @@ -599,28 +599,63 @@<br>
><br>
>  // This pass does eager building and then printing of MemorySSA. It is used by<br>
>  // the tests to be able to build, dump, and verify Memory SSA.<br>
> -class MemorySSAPrinterPass : public FunctionPass {<br>
> +class MemorySSAPrinterLegacyPass : public FunctionPass {<br>
>  public:<br>
> -  MemorySSAPrinterPass();<br>
> +  MemorySSAPrinterLegacyPass();<br>
><br>
>    static char ID;<br>
>    bool doInitialization(Module &M) override;<br>
>    bool runOnFunction(Function &) override;<br>
>    void releaseMemory() override;<br>
>    void getAnalysisUsage(AnalysisUsage &AU) const override;<br>
>    void print(raw_ostream &OS, const Module *M) const override;<br>
> -  static void registerOptions();<br>
>    MemorySSA &getMSSA() { return *MSSA; }<br>
><br>
>  private:<br>
> -  bool VerifyMemorySSA;<br>
> -<br>
>    std::unique_ptr<MemorySSA> MSSA;<br>
>    // FIXME(gbiv): It seems that MemorySSA doesn't own the walker it returns?<br>
>    std::unique_ptr<MemorySSAWalker> Walker;<br>
>    Function *F;<br>
>  };<br>
><br>
> +/// \brief Printer pass for the \c MemorySSA.<br>
> +class MemorySSAPrinterPass<br>
> +    : public PassInfoMixin<MemorySSAPrinterPass> {<br>
> +  raw_ostream &OS;<br>
> +<br>
> +public:<br>
> +  explicit MemorySSAPrinterPass(raw_ostream &OS);<br>
> +  PreservedAnalyses run(Function &F, AnalysisManager<Function> &AM);<br>
> +};<br>
> +<br>
> +class MemorySSALazyResults {<br>
> +public:<br>
> +  MemorySSALazyResults(Function &F);<br>
> +<br>
> +  MemorySSA &getMSSA() {<br>
> +    assert(MSSA);<br>
> +    return *MSSA;<br>
> +  }<br>
> +<br>
> +private:<br>
> +  std::unique_ptr<MemorySSA> MSSA;<br>
> +};<br>
<br>
I'm not convinced this is the right model in the new pass manager - it's<br>
essentially giving us two layers of caching, since the new PM already<br>
computes the analysis on demand (when you first call getResult) and<br>
caches that until its invalidated.<br>
<br>
> +<br>
> +/// An analysis that produces \c MemorySSA for a function.<br>
> +///<br>
> +/// This is essentially a no-op because the results are computed entirely<br>
> +/// lazily.<br>
> +class MemorySSALazyAnalysis<br>
> +    : public AnalysisInfoMixin<MemorySSALazyAnalysis> {<br>
> +  friend AnalysisInfoMixin<MemorySSALazyAnalysis>;<br>
> +  static char PassID;<br>
> +<br>
> +public:<br>
> +  typedef MemorySSALazyResults Result;<br>
> +<br>
> +  MemorySSALazyResults run(Function &F, AnalysisManager<Function> &AM);<br>
> +};<br>
> +<br>
>  class MemorySSALazy : public FunctionPass {<br>
>  public:<br>
>    MemorySSALazy();<br>
> Index: include/llvm/InitializePasses.h<br>
> ===================================================================<br>
> --- include/llvm/InitializePasses.h<br>
> +++ include/llvm/InitializePasses.h<br>
> @@ -219,7 +219,7 @@<br>
>  void initializeMemDerefPrinterPass(PassRegistry&);<br>
>  void initializeMemoryDependenceWrapperPassPass(PassRegistry&);<br>
>  void initializeMemorySSALazyPass(PassRegistry&);<br>
> -void initializeMemorySSAPrinterPassPass(PassRegistry&);<br>
> +void initializeMemorySSAPrinterLegacyPassPass(PassRegistry&);<br>
>  void initializeMergedLoadStoreMotionPass(PassRegistry &);<br>
>  void initializeMetaRenamerPass(PassRegistry&);<br>
>  void initializeMergeFunctionsPass(PassRegistry&);<br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
> <a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>