diff --git a/llvm/include/llvm/Analysis/MemorySSA.h b/llvm/include/llvm/Analysis/MemorySSA.h --- a/llvm/include/llvm/Analysis/MemorySSA.h +++ b/llvm/include/llvm/Analysis/MemorySSA.h @@ -946,9 +946,11 @@ /// Printer pass for \c MemorySSA. class MemorySSAPrinterPass : public PassInfoMixin { raw_ostream &OS; + bool EnsureOptimizedUses; public: - explicit MemorySSAPrinterPass(raw_ostream &OS) : OS(OS) {} + explicit MemorySSAPrinterPass(raw_ostream &OS, bool EnsureOptimizedUses) + : OS(OS), EnsureOptimizedUses(EnsureOptimizedUses) {} PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; diff --git a/llvm/lib/Analysis/MemorySSA.cpp b/llvm/lib/Analysis/MemorySSA.cpp --- a/llvm/lib/Analysis/MemorySSA.cpp +++ b/llvm/lib/Analysis/MemorySSA.cpp @@ -364,7 +364,8 @@ } // end anonymous namespace -static bool isUseTriviallyOptimizableToLiveOnEntry(BatchAAResults &AA, +template +static bool isUseTriviallyOptimizableToLiveOnEntry(AliasAnalysisType &AA, const Instruction *I) { // If the memory can't be changed, then loads of the memory can't be // clobbered. @@ -1361,11 +1362,6 @@ if (MU->isOptimized()) continue; - if (isUseTriviallyOptimizableToLiveOnEntry(*AA, MU->getMemoryInst())) { - MU->setDefiningAccess(MSSA->getLiveOnEntryDef(), true); - continue; - } - MemoryLocOrCall UseMLOC(MU); auto &LocInfo = LocStackInfo[UseMLOC]; // If the pop epoch changed, it means we've removed stuff from top of @@ -1781,10 +1777,15 @@ return nullptr; MemoryUseOrDef *MUD; - if (Def) + if (Def) { MUD = new MemoryDef(I->getContext(), nullptr, I, I->getParent(), NextID++); - else + } else { MUD = new MemoryUse(I->getContext(), nullptr, I, I->getParent()); + if (isUseTriviallyOptimizableToLiveOnEntry(*AAP, I)) { + MemoryAccess *LiveOnEntry = getLiveOnEntryDef(); + MUD->setOptimized(LiveOnEntry); + } + } ValueToMemoryAccess[I] = MUD; return MUD; } @@ -2318,7 +2319,8 @@ PreservedAnalyses MemorySSAPrinterPass::run(Function &F, FunctionAnalysisManager &AM) { auto &MSSA = AM.getResult(F).getMSSA(); - MSSA.ensureOptimizedUses(); + if (EnsureOptimizedUses) + MSSA.ensureOptimizedUses(); if (DotCFGMSSA != "") { DOTFuncMSSAInfo CFGInfo(F, MSSA); WriteGraph(&CFGInfo, "", false, "MSSA", DotCFGMSSA); diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -1066,6 +1066,11 @@ return *L; } +Expected parseMemorySSAPrinterPassOptions(StringRef Params) { + return parseSinglePassOption(Params, "no-ensure-optimized-uses", + "MemorySSAPrinterPass"); +} + } // namespace /// Tests whether a pass name starts with a valid prefix for a default pipeline diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -379,7 +379,6 @@ FUNCTION_PASS("print", InlineSizeEstimatorAnalysisPrinterPass(dbgs())) FUNCTION_PASS("print", LoopPrinterPass(dbgs())) -FUNCTION_PASS("print", MemorySSAPrinterPass(dbgs())) FUNCTION_PASS("print", MemorySSAWalkerPrinterPass(dbgs())) FUNCTION_PASS("print", PhiValuesPrinterPass(dbgs())) FUNCTION_PASS("print", RegionInfoPrinterPass(dbgs())) @@ -557,6 +556,13 @@ }, parseFunctionSimplificationPipelineOptions, "O1;O2;O3;Os;Oz") +FUNCTION_PASS_WITH_PARAMS("print", + "MemorySSAPrinterPass", + [](bool NoEnsureOptimizedUses) { + return MemorySSAPrinterPass(dbgs(), !NoEnsureOptimizedUses); + }, + parseMemorySSAPrinterPassOptions, + "no-ensure-optimized-uses") #undef FUNCTION_PASS_WITH_PARAMS #ifndef LOOPNEST_PASS diff --git a/llvm/test/Analysis/MemorySSA/tbaa.ll b/llvm/test/Analysis/MemorySSA/tbaa.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/MemorySSA/tbaa.ll @@ -0,0 +1,13 @@ +; RUN: opt -aa-pipeline=basic-aa,tbaa -passes='print' -disable-output < %s 2>&1 | FileCheck %s + +define i8 @test1_yes(ptr %a, ptr %b) { +; CHECK: 1 = MemoryDef(liveOnEntry) + store i8 0, ptr %a, align 1 +; CHECK: MemoryUse(liveOnEntry) + %y = load i8, ptr %b, align 1, !tbaa !0 + ret i8 %y +} + +!0 = !{!1, !1, i64 0, i1 true} +!1 = !{!"qux", !2} +!2 = !{}