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 @@ -953,6 +953,17 @@ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); }; +/// Printer pass for \c MemorySSA via the walker. +class MemorySSAWalkerPrinterPass + : public PassInfoMixin { + raw_ostream &OS; + +public: + explicit MemorySSAWalkerPrinterPass(raw_ostream &OS) : OS(OS) {} + + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; + /// Verifier pass for \c MemorySSA. struct MemorySSAVerifierPass : PassInfoMixin { 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 @@ -95,13 +95,11 @@ VerifyMemorySSAX("verify-memoryssa", cl::location(VerifyMemorySSA), cl::Hidden, cl::desc("Enable verification of MemorySSA.")); -namespace llvm { +namespace { /// An assembly annotator class to print Memory SSA information in /// comments. class MemorySSAAnnotatedWriter : public AssemblyAnnotationWriter { - friend class MemorySSA; - const MemorySSA *MSSA; public: @@ -120,7 +118,29 @@ } }; -} // end namespace llvm +/// An assembly annotator class to print Memory SSA information in +/// comments. +class MemorySSAWalkerAnnotatedWriter : public AssemblyAnnotationWriter { + MemorySSA *MSSA; + MemorySSAWalker *Walker; + +public: + MemorySSAWalkerAnnotatedWriter(MemorySSA *M) + : MSSA(M), Walker(M->getWalker()) {} + + void emitInstructionAnnot(const Instruction *I, + formatted_raw_ostream &OS) override { + if (MemoryAccess *MA = MSSA->getMemoryAccess(I)) { + MemoryAccess *Clobber = Walker->getClobberingMemoryAccess(MA); + OS << "; " << *MA; + if (Clobber) + OS << " - clobbered by " << *Clobber; + OS << "\n"; + } + } +}; + +} // namespace namespace { @@ -2351,6 +2371,16 @@ return PreservedAnalyses::all(); } +PreservedAnalyses MemorySSAWalkerPrinterPass::run(Function &F, + FunctionAnalysisManager &AM) { + auto &MSSA = AM.getResult(F).getMSSA(); + OS << "MemorySSA (walker) for function: " << F.getName() << "\n"; + MemorySSAWalkerAnnotatedWriter Writer(&MSSA); + F.print(OS, &Writer); + + return PreservedAnalyses::all(); +} + PreservedAnalyses MemorySSAVerifierPass::run(Function &F, FunctionAnalysisManager &AM) { AM.getResult(F).getMSSA().verifyMemorySSA(); 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 @@ -297,6 +297,7 @@ 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())) FUNCTION_PASS("print", ScalarEvolutionPrinterPass(dbgs())) diff --git a/llvm/test/Analysis/MemorySSA/print-walker.ll b/llvm/test/Analysis/MemorySSA/print-walker.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/MemorySSA/print-walker.ll @@ -0,0 +1,35 @@ +; RUN: opt -passes='print' -disable-output < %s 2>&1 | FileCheck %s + +; CHECK: define void @test +; CHECK: 1 = MemoryDef(liveOnEntry)->liveOnEntry - clobbered by 0 = MemoryDef(liveOnEntry) +; CHECK: store i8 42, i8* %a1 +; CHECK: 2 = MemoryDef(1)->liveOnEntry - clobbered by 0 = MemoryDef(liveOnEntry) +; CHECK: store i8 42, i8* %a2 +; CHECK: MemoryUse(1) MustAlias - clobbered by 1 = MemoryDef(liveOnEntry)->liveOnEntry +; CHECK: %l1 = load i8, i8* %a1 +; CHECK: MemoryUse(2) MustAlias - clobbered by 2 = MemoryDef(1)->liveOnEntry +; CHECK: %l2 = load i8, i8* %a2 +; CHECK: 3 = MemoryDef(2)->liveOnEntry - clobbered by 0 = MemoryDef(liveOnEntry) +; CHECK: store i8 42, i8* %p +; CHECK: 4 = MemoryDef(3)->3 MustAlias - clobbered by 3 = MemoryDef(2)->liveOnEntry +; CHECK: store i8 42, i8* %p +; CHECK: MemoryUse(4) MustAlias - clobbered by 4 = MemoryDef(3)->3 MustAlias +; CHECK: %p1 = load i8, i8* %p +; CHECK: MemoryUse(4) MustAlias - clobbered by 4 = MemoryDef(3)->3 MustAlias +; CHECK: %p2 = load i8, i8* %p + +define void @test(i8* %p) { + %a1 = alloca i8 + %a2 = alloca i8 + store i8 42, i8* %a1 + store i8 42, i8* %a2 + %l1 = load i8, i8* %a1 + %l2 = load i8, i8* %a2 + + store i8 42, i8* %p + store i8 42, i8* %p + %p1 = load i8, i8* %p + %p2 = load i8, i8* %p + + ret void +}