[llvm] r228369 - Introduce print-memderefs to test isDereferenceablePointer

Ramkumar Ramachandra artagnon at gmail.com
Thu Feb 5 17:46:42 PST 2015


Author: artagnon
Date: Thu Feb  5 19:46:42 2015
New Revision: 228369

URL: http://llvm.org/viewvc/llvm-project?rev=228369&view=rev
Log:
Introduce print-memderefs to test isDereferenceablePointer

Since testing the function indirectly is tricky, introduce a direct
print-memderefs pass, in the same spirit as print-memdeps, which prints
dereferenceability information matched by FileCheck.

Differential Revision: http://reviews.llvm.org/D7075

Added:
    llvm/trunk/lib/Analysis/MemDerefPrinter.cpp
    llvm/trunk/test/Analysis/ValueTracking/
    llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll
Modified:
    llvm/trunk/include/llvm/Analysis/Passes.h
    llvm/trunk/include/llvm/IR/InstIterator.h
    llvm/trunk/include/llvm/InitializePasses.h
    llvm/trunk/include/llvm/LinkAllPasses.h
    llvm/trunk/lib/Analysis/Analysis.cpp
    llvm/trunk/lib/Analysis/CMakeLists.txt

Modified: llvm/trunk/include/llvm/Analysis/Passes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/Passes.h?rev=228369&r1=228368&r2=228369&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/Passes.h (original)
+++ llvm/trunk/include/llvm/Analysis/Passes.h Thu Feb  5 19:46:42 2015
@@ -162,6 +162,14 @@ namespace llvm {
   // createJumpInstrTableInfoPass - This creates a pass that stores information
   // about the jump tables created by JumpInstrTables
   ImmutablePass *createJumpInstrTableInfoPass();
+
+  //===--------------------------------------------------------------------===//
+  //
+  // createMemDerefPrinter - This pass collects memory dereferenceability
+  // information and prints it with -analyze.
+  //
+  FunctionPass *createMemDerefPrinter();
+
 }
 
 #endif

Modified: llvm/trunk/include/llvm/IR/InstIterator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InstIterator.h?rev=228369&r1=228368&r2=228369&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InstIterator.h (original)
+++ llvm/trunk/include/llvm/IR/InstIterator.h Thu Feb  5 19:46:42 2015
@@ -127,20 +127,32 @@ typedef InstIterator<const iplist<BasicB
 
 inline inst_iterator inst_begin(Function *F) { return inst_iterator(*F); }
 inline inst_iterator inst_end(Function *F)   { return inst_iterator(*F, true); }
+inline iterator_range<inst_iterator> inst_range(Function *F) {
+  return iterator_range<inst_iterator>(inst_begin(F), inst_end(F));
+}
 inline const_inst_iterator inst_begin(const Function *F) {
   return const_inst_iterator(*F);
 }
 inline const_inst_iterator inst_end(const Function *F) {
   return const_inst_iterator(*F, true);
 }
+inline iterator_range<const_inst_iterator> inst_range(const Function *F) {
+  return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F));
+}
 inline inst_iterator inst_begin(Function &F) { return inst_iterator(F); }
 inline inst_iterator inst_end(Function &F)   { return inst_iterator(F, true); }
+inline iterator_range<inst_iterator> inst_range(Function &F) {
+  return iterator_range<inst_iterator>(inst_begin(F), inst_end(F));
+}
 inline const_inst_iterator inst_begin(const Function &F) {
   return const_inst_iterator(F);
 }
 inline const_inst_iterator inst_end(const Function &F) {
   return const_inst_iterator(F, true);
 }
+inline iterator_range<const_inst_iterator> inst_range(const Function &F) {
+  return iterator_range<const_inst_iterator>(inst_begin(F), inst_end(F));
+}
 
 } // End llvm namespace
 

Modified: llvm/trunk/include/llvm/InitializePasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=228369&r1=228368&r2=228369&view=diff
==============================================================================
--- llvm/trunk/include/llvm/InitializePasses.h (original)
+++ llvm/trunk/include/llvm/InitializePasses.h Thu Feb  5 19:46:42 2015
@@ -199,6 +199,7 @@ void initializeMachineTraceMetricsPass(P
 void initializeMachineVerifierPassPass(PassRegistry&);
 void initializeMemCpyOptPass(PassRegistry&);
 void initializeMemDepPrinterPass(PassRegistry&);
+void initializeMemDerefPrinterPass(PassRegistry&);
 void initializeMemoryDependenceAnalysisPass(PassRegistry&);
 void initializeMergedLoadStoreMotionPass(PassRegistry &);
 void initializeMetaRenamerPass(PassRegistry&);

Modified: llvm/trunk/include/llvm/LinkAllPasses.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/LinkAllPasses.h?rev=228369&r1=228368&r2=228369&view=diff
==============================================================================
--- llvm/trunk/include/llvm/LinkAllPasses.h (original)
+++ llvm/trunk/include/llvm/LinkAllPasses.h Thu Feb  5 19:46:42 2015
@@ -168,6 +168,7 @@ namespace {
       (void) llvm::createSeparateConstOffsetFromGEPPass();
       (void) llvm::createRewriteSymbolsPass();
       (void) llvm::createStraightLineStrengthReducePass();
+      (void) llvm::createMemDerefPrinter();
 
       (void)new llvm::IntervalPartition();
       (void)new llvm::ScalarEvolution();

Modified: llvm/trunk/lib/Analysis/Analysis.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/Analysis.cpp?rev=228369&r1=228368&r2=228369&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/Analysis.cpp (original)
+++ llvm/trunk/lib/Analysis/Analysis.cpp Thu Feb  5 19:46:42 2015
@@ -55,6 +55,7 @@ void llvm::initializeAnalysis(PassRegist
   initializeLintPass(Registry);
   initializeLoopInfoWrapperPassPass(Registry);
   initializeMemDepPrinterPass(Registry);
+  initializeMemDerefPrinterPass(Registry);
   initializeMemoryDependenceAnalysisPass(Registry);
   initializeModuleDebugInfoPrinterPass(Registry);
   initializePostDominatorTreePass(Registry);

Modified: llvm/trunk/lib/Analysis/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/CMakeLists.txt?rev=228369&r1=228368&r2=228369&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/CMakeLists.txt (original)
+++ llvm/trunk/lib/Analysis/CMakeLists.txt Thu Feb  5 19:46:42 2015
@@ -38,6 +38,7 @@ add_llvm_library(LLVMAnalysis
   LoopInfo.cpp
   LoopPass.cpp
   MemDepPrinter.cpp
+  MemDerefPrinter.cpp
   MemoryBuiltins.cpp
   MemoryDependenceAnalysis.cpp
   ModuleDebugInfoPrinter.cpp

Added: llvm/trunk/lib/Analysis/MemDerefPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/MemDerefPrinter.cpp?rev=228369&view=auto
==============================================================================
--- llvm/trunk/lib/Analysis/MemDerefPrinter.cpp (added)
+++ llvm/trunk/lib/Analysis/MemDerefPrinter.cpp Thu Feb  5 19:46:42 2015
@@ -0,0 +1,61 @@
+//===- MemDerefPrinter.cpp - Printer for isDereferenceablePointer ---------===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/Passes.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Analysis/MemoryDependenceAnalysis.h"
+#include "llvm/IR/CallSite.h"
+#include "llvm/IR/InstIterator.h"
+#include "llvm/IR/LLVMContext.h"
+#include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/raw_ostream.h"
+using namespace llvm;
+
+namespace {
+  struct MemDerefPrinter : public FunctionPass {
+    SmallVector<Value *, 4> Vec;
+
+    static char ID; // Pass identifcation, replacement for typeid
+    MemDerefPrinter() : FunctionPass(ID) {
+      initializeMemDerefPrinterPass(*PassRegistry::getPassRegistry());
+    }
+    bool runOnFunction(Function &F) override;
+    void print(raw_ostream &OS, const Module * = nullptr) const override;
+    void releaseMemory() override {
+      Vec.clear();
+    }
+  };
+}
+
+char MemDerefPrinter::ID = 0;
+INITIALIZE_PASS(MemDerefPrinter, "print-memderefs",
+                "Memory Dereferenciblity of pointers in function", false, true)
+
+FunctionPass *llvm::createMemDerefPrinter() {
+  return new MemDerefPrinter();
+}
+
+bool MemDerefPrinter::runOnFunction(Function &F) {
+  for (auto &I: inst_range(F)) {
+    if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
+      Value *PO = LI->getPointerOperand();
+      if (PO->isDereferenceablePointer(nullptr))
+        Vec.push_back(PO);
+    }
+  }
+  return false;
+}
+
+void MemDerefPrinter::print(raw_ostream &OS, const Module *M) const {
+  OS << "The following are dereferenceable:\n";
+  for (auto &V: Vec) {
+    V->print(OS);
+    OS << "\n\n";
+  }
+}

Added: llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll?rev=228369&view=auto
==============================================================================
--- llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll (added)
+++ llvm/trunk/test/Analysis/ValueTracking/memory-dereferenceable.ll Thu Feb  5 19:46:42 2015
@@ -0,0 +1,33 @@
+; RUN: opt -print-memderefs -analyze -S <%s | FileCheck %s
+
+; Uses the print-deref (+ analyze to print) pass to run
+; isDereferenceablePointer() on many load instruction operands
+
+declare zeroext i1 @return_i1()
+
+ at globalstr = global [6 x i8] c"hello\00"
+
+define void @test(i32 addrspace(1)* byval %dparam) {
+; CHECK: The following are dereferenceable:
+; CHECK: %globalptr
+; CHECK: %alloca
+; CHECK: %dparam
+; We haven't yet taught it to look through relocations
+; CHECK-NOT: %relocate
+; CHECK-NOT: %nparam
+entry:
+    %globalptr = getelementptr inbounds [6 x i8]* @globalstr, i32 0, i32 0
+    %load1 = load i8* %globalptr
+    %alloca = alloca i1
+    %load2 = load i1* %alloca
+    %load3 = load i32 addrspace(1)* %dparam
+    %tok = tail call i32 (i1 ()*, i32, i32, ...)* @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 addrspace(1)* %dparam)
+    %relocate = call i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32 %tok, i32 4, i32 4)
+    %load4 = load i32 addrspace(1)* %relocate
+    %nparam = getelementptr i32 addrspace(1)* %dparam, i32 5
+    %load5 = load i32 addrspace(1)* %nparam
+    ret void
+}
+
+declare i32 @llvm.experimental.gc.statepoint.p0f_i1f(i1 ()*, i32, i32, ...)
+declare i32 addrspace(1)* @llvm.experimental.gc.relocate.p1i32(i32, i32, i32)





More information about the llvm-commits mailing list