| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 1 | //===- MemDerefPrinter.cpp - Printer for isDereferenceablePointer ---------===// | 
|  | 2 | // | 
|  | 3 | //                     The LLVM Compiler Infrastructure | 
|  | 4 | // | 
|  | 5 | // This file is distributed under the University of Illinois Open Source | 
|  | 6 | // License. See LICENSE.TXT for details. | 
|  | 7 | // | 
|  | 8 | //===----------------------------------------------------------------------===// | 
|  | 9 |  | 
| Artur Pilipenko | 31bcca4 | 2016-02-24 12:49:04 +0000 | [diff] [blame] | 10 | #include "llvm/Analysis/Loads.h" | 
| Chandler Carruth | 6bda14b | 2017-06-06 11:49:48 +0000 | [diff] [blame] | 11 | #include "llvm/Analysis/Passes.h" | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 12 | #include "llvm/IR/CallSite.h" | 
| Ramkumar Ramachandra | 82ab65c | 2015-02-09 21:50:03 +0000 | [diff] [blame] | 13 | #include "llvm/IR/DataLayout.h" | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 14 | #include "llvm/IR/InstIterator.h" | 
|  | 15 | #include "llvm/IR/LLVMContext.h" | 
| Mehdi Amini | 46a4355 | 2015-03-04 18:43:29 +0000 | [diff] [blame] | 16 | #include "llvm/IR/Module.h" | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 17 | #include "llvm/Support/ErrorHandling.h" | 
|  | 18 | #include "llvm/Support/raw_ostream.h" | 
|  | 19 | using namespace llvm; | 
|  | 20 |  | 
|  | 21 | namespace { | 
|  | 22 | struct MemDerefPrinter : public FunctionPass { | 
| Artur Pilipenko | 34d8ba8 | 2015-08-17 15:54:26 +0000 | [diff] [blame] | 23 | SmallVector<Value *, 4> Deref; | 
|  | 24 | SmallPtrSet<Value *, 4> DerefAndAligned; | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 25 |  | 
| Artur Pilipenko | 0f90c86 | 2015-05-21 11:57:38 +0000 | [diff] [blame] | 26 | static char ID; // Pass identification, replacement for typeid | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 27 | MemDerefPrinter() : FunctionPass(ID) { | 
|  | 28 | initializeMemDerefPrinterPass(*PassRegistry::getPassRegistry()); | 
|  | 29 | } | 
| Ramkumar Ramachandra | 82ab65c | 2015-02-09 21:50:03 +0000 | [diff] [blame] | 30 | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
| Ramkumar Ramachandra | 82ab65c | 2015-02-09 21:50:03 +0000 | [diff] [blame] | 31 | AU.setPreservesAll(); | 
|  | 32 | } | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 33 | bool runOnFunction(Function &F) override; | 
|  | 34 | void print(raw_ostream &OS, const Module * = nullptr) const override; | 
|  | 35 | void releaseMemory() override { | 
| Artur Pilipenko | 34d8ba8 | 2015-08-17 15:54:26 +0000 | [diff] [blame] | 36 | Deref.clear(); | 
|  | 37 | DerefAndAligned.clear(); | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 38 | } | 
|  | 39 | }; | 
| Alexander Kornienko | f00654e | 2015-06-23 09:49:53 +0000 | [diff] [blame] | 40 | } | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 41 |  | 
|  | 42 | char MemDerefPrinter::ID = 0; | 
| Ramkumar Ramachandra | 82ab65c | 2015-02-09 21:50:03 +0000 | [diff] [blame] | 43 | INITIALIZE_PASS_BEGIN(MemDerefPrinter, "print-memderefs", | 
|  | 44 | "Memory Dereferenciblity of pointers in function", false, true) | 
| Ramkumar Ramachandra | 82ab65c | 2015-02-09 21:50:03 +0000 | [diff] [blame] | 45 | INITIALIZE_PASS_END(MemDerefPrinter, "print-memderefs", | 
|  | 46 | "Memory Dereferenciblity of pointers in function", false, true) | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 47 |  | 
|  | 48 | FunctionPass *llvm::createMemDerefPrinter() { | 
|  | 49 | return new MemDerefPrinter(); | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | bool MemDerefPrinter::runOnFunction(Function &F) { | 
| Mehdi Amini | 46a4355 | 2015-03-04 18:43:29 +0000 | [diff] [blame] | 53 | const DataLayout &DL = F.getParent()->getDataLayout(); | 
| Nico Rieck | 7819951 | 2015-08-06 19:10:45 +0000 | [diff] [blame] | 54 | for (auto &I: instructions(F)) { | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 55 | if (LoadInst *LI = dyn_cast<LoadInst>(&I)) { | 
|  | 56 | Value *PO = LI->getPointerOperand(); | 
| Philip Reames | 5461d45 | 2015-04-23 17:36:48 +0000 | [diff] [blame] | 57 | if (isDereferenceablePointer(PO, DL)) | 
| Artur Pilipenko | 34d8ba8 | 2015-08-17 15:54:26 +0000 | [diff] [blame] | 58 | Deref.push_back(PO); | 
|  | 59 | if (isDereferenceableAndAlignedPointer(PO, LI->getAlignment(), DL)) | 
|  | 60 | DerefAndAligned.insert(PO); | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 61 | } | 
|  | 62 | } | 
|  | 63 | return false; | 
|  | 64 | } | 
|  | 65 |  | 
|  | 66 | void MemDerefPrinter::print(raw_ostream &OS, const Module *M) const { | 
|  | 67 | OS << "The following are dereferenceable:\n"; | 
| Artur Pilipenko | 34d8ba8 | 2015-08-17 15:54:26 +0000 | [diff] [blame] | 68 | for (Value *V: Deref) { | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 69 | V->print(OS); | 
| Artur Pilipenko | 34d8ba8 | 2015-08-17 15:54:26 +0000 | [diff] [blame] | 70 | if (DerefAndAligned.count(V)) | 
|  | 71 | OS << "\t(aligned)"; | 
|  | 72 | else | 
|  | 73 | OS << "\t(unaligned)"; | 
| Ramkumar Ramachandra | 8378ac3 | 2015-02-06 01:46:42 +0000 | [diff] [blame] | 74 | OS << "\n\n"; | 
|  | 75 | } | 
|  | 76 | } |