MemDerefPrinter.cpp 3.6 KB

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