1ff0cc061SDimitry Andric //===- MemDerefPrinter.cpp - Printer for isDereferenceablePointer ---------===//
2ff0cc061SDimitry Andric //
3ff0cc061SDimitry Andric // The LLVM Compiler Infrastructure
4ff0cc061SDimitry Andric //
5ff0cc061SDimitry Andric // This file is distributed under the University of Illinois Open Source
6ff0cc061SDimitry Andric // License. See LICENSE.TXT for details.
7ff0cc061SDimitry Andric //
8ff0cc061SDimitry Andric //===----------------------------------------------------------------------===//
9ff0cc061SDimitry Andric
103ca95b02SDimitry Andric #include "llvm/Analysis/Loads.h"
11*db17bf38SDimitry Andric #include "llvm/Analysis/Passes.h"
12ff0cc061SDimitry Andric #include "llvm/IR/CallSite.h"
13ff0cc061SDimitry Andric #include "llvm/IR/DataLayout.h"
14ff0cc061SDimitry Andric #include "llvm/IR/InstIterator.h"
15ff0cc061SDimitry Andric #include "llvm/IR/LLVMContext.h"
16ff0cc061SDimitry Andric #include "llvm/IR/Module.h"
17ff0cc061SDimitry Andric #include "llvm/Support/ErrorHandling.h"
18ff0cc061SDimitry Andric #include "llvm/Support/raw_ostream.h"
19ff0cc061SDimitry Andric using namespace llvm;
20ff0cc061SDimitry Andric
21ff0cc061SDimitry Andric namespace {
22ff0cc061SDimitry Andric struct MemDerefPrinter : public FunctionPass {
237d523365SDimitry Andric SmallVector<Value *, 4> Deref;
247d523365SDimitry Andric SmallPtrSet<Value *, 4> DerefAndAligned;
25ff0cc061SDimitry Andric
26ff0cc061SDimitry Andric static char ID; // Pass identification, replacement for typeid
MemDerefPrinter__anon607228110111::MemDerefPrinter27ff0cc061SDimitry Andric MemDerefPrinter() : FunctionPass(ID) {
28ff0cc061SDimitry Andric initializeMemDerefPrinterPass(*PassRegistry::getPassRegistry());
29ff0cc061SDimitry Andric }
getAnalysisUsage__anon607228110111::MemDerefPrinter30ff0cc061SDimitry Andric void getAnalysisUsage(AnalysisUsage &AU) const override {
31ff0cc061SDimitry Andric AU.setPreservesAll();
32ff0cc061SDimitry Andric }
33ff0cc061SDimitry Andric bool runOnFunction(Function &F) override;
34ff0cc061SDimitry Andric void print(raw_ostream &OS, const Module * = nullptr) const override;
releaseMemory__anon607228110111::MemDerefPrinter35ff0cc061SDimitry Andric void releaseMemory() override {
367d523365SDimitry Andric Deref.clear();
377d523365SDimitry Andric DerefAndAligned.clear();
38ff0cc061SDimitry Andric }
39ff0cc061SDimitry Andric };
403dac3a9bSDimitry Andric }
41ff0cc061SDimitry Andric
42ff0cc061SDimitry Andric char MemDerefPrinter::ID = 0;
43ff0cc061SDimitry Andric INITIALIZE_PASS_BEGIN(MemDerefPrinter, "print-memderefs",
44ff0cc061SDimitry Andric "Memory Dereferenciblity of pointers in function", false, true)
45ff0cc061SDimitry Andric INITIALIZE_PASS_END(MemDerefPrinter, "print-memderefs",
46ff0cc061SDimitry Andric "Memory Dereferenciblity of pointers in function", false, true)
47ff0cc061SDimitry Andric
createMemDerefPrinter()48ff0cc061SDimitry Andric FunctionPass *llvm::createMemDerefPrinter() {
49ff0cc061SDimitry Andric return new MemDerefPrinter();
50ff0cc061SDimitry Andric }
51ff0cc061SDimitry Andric
runOnFunction(Function & F)52ff0cc061SDimitry Andric bool MemDerefPrinter::runOnFunction(Function &F) {
53ff0cc061SDimitry Andric const DataLayout &DL = F.getParent()->getDataLayout();
547d523365SDimitry Andric for (auto &I: instructions(F)) {
55ff0cc061SDimitry Andric if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
56ff0cc061SDimitry Andric Value *PO = LI->getPointerOperand();
57ff0cc061SDimitry Andric if (isDereferenceablePointer(PO, DL))
587d523365SDimitry Andric Deref.push_back(PO);
597d523365SDimitry Andric if (isDereferenceableAndAlignedPointer(PO, LI->getAlignment(), DL))
607d523365SDimitry Andric DerefAndAligned.insert(PO);
61ff0cc061SDimitry Andric }
62ff0cc061SDimitry Andric }
63ff0cc061SDimitry Andric return false;
64ff0cc061SDimitry Andric }
65ff0cc061SDimitry Andric
print(raw_ostream & OS,const Module * M) const66ff0cc061SDimitry Andric void MemDerefPrinter::print(raw_ostream &OS, const Module *M) const {
67ff0cc061SDimitry Andric OS << "The following are dereferenceable:\n";
687d523365SDimitry Andric for (Value *V: Deref) {
69ff0cc061SDimitry Andric V->print(OS);
707d523365SDimitry Andric if (DerefAndAligned.count(V))
717d523365SDimitry Andric OS << "\t(aligned)";
727d523365SDimitry Andric else
737d523365SDimitry Andric OS << "\t(unaligned)";
74ff0cc061SDimitry Andric OS << "\n\n";
75ff0cc061SDimitry Andric }
76ff0cc061SDimitry Andric }
77