diff --git a/llvm/include/llvm/Analysis/MemDerefPrinter.h b/llvm/include/llvm/Analysis/MemDerefPrinter.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Analysis/MemDerefPrinter.h @@ -0,0 +1,24 @@ +//===- MemDerefPrinter.h - Printer for isDereferenceablePointer -----------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_ANALYSIS_MEMDEREFPRINTER_H +#define LLVM_ANALYSIS_MEMDEREFPRINTER_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { +class MemDerefPrinterPass : public PassInfoMixin { + raw_ostream &OS; + +public: + MemDerefPrinterPass(raw_ostream &OS) : OS(OS) {} + PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); +}; +} // namespace llvm + +#endif // LLVM_ANALYSIS_MEMDEREFPRINTER_H diff --git a/llvm/lib/Analysis/MemDerefPrinter.cpp b/llvm/lib/Analysis/MemDerefPrinter.cpp --- a/llvm/lib/Analysis/MemDerefPrinter.cpp +++ b/llvm/lib/Analysis/MemDerefPrinter.cpp @@ -6,6 +6,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/Analysis/MemDerefPrinter.h" #include "llvm/Analysis/Loads.h" #include "llvm/Analysis/Passes.h" #include "llvm/IR/DataLayout.h" @@ -17,6 +18,7 @@ #include "llvm/Pass.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" + using namespace llvm; namespace { @@ -76,3 +78,35 @@ OS << "\n\n"; } } + +PreservedAnalyses MemDerefPrinterPass::run(Function &F, + FunctionAnalysisManager &AM) { + OS << "Memory Dereferencibility of pointers in function '" << F.getName() + << "'\n"; + + SmallVector Deref; + SmallPtrSet DerefAndAligned; + + const DataLayout &DL = F.getParent()->getDataLayout(); + for (auto &I : instructions(F)) { + if (LoadInst *LI = dyn_cast(&I)) { + Value *PO = LI->getPointerOperand(); + if (isDereferenceablePointer(PO, LI->getType(), DL)) + Deref.push_back(PO); + if (isDereferenceableAndAlignedPointer( + PO, LI->getType(), MaybeAlign(LI->getAlignment()), DL)) + DerefAndAligned.insert(PO); + } + } + + OS << "The following are dereferenceable:\n"; + for (Value *V : Deref) { + V->print(OS); + if (DerefAndAligned.count(V)) + OS << "\t(aligned)"; + else + OS << "\t(unaligned)"; + OS << "\n\n"; + } + return PreservedAnalyses::all(); +} 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 @@ -47,6 +47,7 @@ #include "llvm/Analysis/LoopCacheAnalysis.h" #include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopNestAnalysis.h" +#include "llvm/Analysis/MemDerefPrinter.h" #include "llvm/Analysis/MemoryDependenceAnalysis.h" #include "llvm/Analysis/MemorySSA.h" #include "llvm/Analysis/ModuleDebugInfoPrinter.h" 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 @@ -286,6 +286,7 @@ FUNCTION_PASS("print-alias-sets", AliasSetsPrinterPass(dbgs())) FUNCTION_PASS("print-predicateinfo", PredicateInfoPrinterPass(dbgs())) FUNCTION_PASS("print-mustexecute", MustExecutePrinterPass(dbgs())) +FUNCTION_PASS("print-memderefs", MemDerefPrinterPass(dbgs())) FUNCTION_PASS("reassociate", ReassociatePass()) FUNCTION_PASS("redundant-dbg-inst-elim", RedundantDbgInstEliminationPass()) FUNCTION_PASS("reg2mem", RegToMemPass()) diff --git a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll --- a/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll +++ b/llvm/test/Analysis/ValueTracking/memory-dereferenceable.ll @@ -1,4 +1,5 @@ ; RUN: opt -print-memderefs -analyze -S < %s -enable-new-pm=0 | FileCheck %s +; RUN: opt -passes=print-memderefs -S < %s -disable-output 2>&1 | FileCheck %s ; Uses the print-deref (+ analyze to print) pass to run ; isDereferenceablePointer() on many load instruction operands