MemDerefPrinter.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //===- MemDerefPrinter.cpp - Printer for isDereferenceablePointer ---------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/Analysis/MemDerefPrinter.h"
  9. #include "llvm/Analysis/Loads.h"
  10. #include "llvm/Analysis/Passes.h"
  11. #include "llvm/IR/InstIterator.h"
  12. #include "llvm/IR/Instructions.h"
  13. #include "llvm/IR/Module.h"
  14. #include "llvm/InitializePasses.h"
  15. #include "llvm/Pass.h"
  16. #include "llvm/Support/raw_ostream.h"
  17. using namespace llvm;
  18. namespace {
  19. struct MemDerefPrinter : public FunctionPass {
  20. SmallVector<Value *, 4> Deref;
  21. SmallPtrSet<Value *, 4> DerefAndAligned;
  22. static char ID; // Pass identification, replacement for typeid
  23. MemDerefPrinter() : FunctionPass(ID) {
  24. initializeMemDerefPrinterPass(*PassRegistry::getPassRegistry());
  25. }
  26. void getAnalysisUsage(AnalysisUsage &AU) const override {
  27. AU.setPreservesAll();
  28. }
  29. bool runOnFunction(Function &F) override;
  30. void print(raw_ostream &OS, const Module * = nullptr) const override;
  31. void releaseMemory() override {
  32. Deref.clear();
  33. DerefAndAligned.clear();
  34. }
  35. };
  36. }
  37. char MemDerefPrinter::ID = 0;
  38. INITIALIZE_PASS_BEGIN(MemDerefPrinter, "print-memderefs",
  39. "Memory Dereferenciblity of pointers in function", false, true)
  40. INITIALIZE_PASS_END(MemDerefPrinter, "print-memderefs",
  41. "Memory Dereferenciblity of pointers in function", false, true)
  42. FunctionPass *llvm::createMemDerefPrinter() {
  43. return new MemDerefPrinter();
  44. }
  45. bool MemDerefPrinter::runOnFunction(Function &F) {
  46. const DataLayout &DL = F.getParent()->getDataLayout();
  47. for (auto &I: instructions(F)) {
  48. if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
  49. Value *PO = LI->getPointerOperand();
  50. if (isDereferenceablePointer(PO, LI->getType(), DL))
  51. Deref.push_back(PO);
  52. if (isDereferenceableAndAlignedPointer(PO, LI->getType(), LI->getAlign(),
  53. DL))
  54. DerefAndAligned.insert(PO);
  55. }
  56. }
  57. return false;
  58. }
  59. void MemDerefPrinter::print(raw_ostream &OS, const Module *M) const {
  60. OS << "The following are dereferenceable:\n";
  61. for (Value *V: Deref) {
  62. OS << " ";
  63. V->print(OS);
  64. if (DerefAndAligned.count(V))
  65. OS << "\t(aligned)";
  66. else
  67. OS << "\t(unaligned)";
  68. OS << "\n";
  69. }
  70. }
  71. PreservedAnalyses MemDerefPrinterPass::run(Function &F,
  72. FunctionAnalysisManager &AM) {
  73. OS << "Memory Dereferencibility of pointers in function '" << F.getName()
  74. << "'\n";
  75. SmallVector<Value *, 4> Deref;
  76. SmallPtrSet<Value *, 4> DerefAndAligned;
  77. const DataLayout &DL = F.getParent()->getDataLayout();
  78. for (auto &I : instructions(F)) {
  79. if (LoadInst *LI = dyn_cast<LoadInst>(&I)) {
  80. Value *PO = LI->getPointerOperand();
  81. if (isDereferenceablePointer(PO, LI->getType(), DL))
  82. Deref.push_back(PO);
  83. if (isDereferenceableAndAlignedPointer(PO, LI->getType(), LI->getAlign(),
  84. DL))
  85. DerefAndAligned.insert(PO);
  86. }
  87. }
  88. OS << "The following are dereferenceable:\n";
  89. for (Value *V : Deref) {
  90. OS << " ";
  91. V->print(OS);
  92. if (DerefAndAligned.count(V))
  93. OS << "\t(aligned)";
  94. else
  95. OS << "\t(unaligned)";
  96. OS << "\n";
  97. }
  98. return PreservedAnalyses::all();
  99. }