LCOV - code coverage report
Current view: top level - lib/Analysis - MemDepPrinter.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 3 72 4.2 %
Date: 2017-09-14 15:23:50 Functions: 2 11 18.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===//
       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             : //
      10             : //
      11             : //===----------------------------------------------------------------------===//
      12             : 
      13             : #include "llvm/ADT/SetVector.h"
      14             : #include "llvm/Analysis/MemoryDependenceAnalysis.h"
      15             : #include "llvm/Analysis/Passes.h"
      16             : #include "llvm/IR/CallSite.h"
      17             : #include "llvm/IR/InstIterator.h"
      18             : #include "llvm/IR/LLVMContext.h"
      19             : #include "llvm/Support/ErrorHandling.h"
      20             : #include "llvm/Support/raw_ostream.h"
      21             : using namespace llvm;
      22             : 
      23             : namespace {
      24           0 :   struct MemDepPrinter : public FunctionPass {
      25             :     const Function *F;
      26             : 
      27             :     enum DepType {
      28             :       Clobber = 0,
      29             :       Def,
      30             :       NonFuncLocal,
      31             :       Unknown
      32             :     };
      33             : 
      34             :     static const char *const DepTypeStr[];
      35             : 
      36             :     typedef PointerIntPair<const Instruction *, 2, DepType> InstTypePair;
      37             :     typedef std::pair<InstTypePair, const BasicBlock *> Dep;
      38             :     typedef SmallSetVector<Dep, 4> DepSet;
      39             :     typedef DenseMap<const Instruction *, DepSet> DepSetMap;
      40             :     DepSetMap Deps;
      41             : 
      42             :     static char ID; // Pass identifcation, replacement for typeid
      43           0 :     MemDepPrinter() : FunctionPass(ID) {
      44           0 :       initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
      45           0 :     }
      46             : 
      47             :     bool runOnFunction(Function &F) override;
      48             : 
      49             :     void print(raw_ostream &OS, const Module * = nullptr) const override;
      50             : 
      51           0 :     void getAnalysisUsage(AnalysisUsage &AU) const override {
      52           0 :       AU.addRequiredTransitive<AAResultsWrapperPass>();
      53           0 :       AU.addRequiredTransitive<MemoryDependenceWrapperPass>();
      54           0 :       AU.setPreservesAll();
      55           0 :     }
      56             : 
      57           0 :     void releaseMemory() override {
      58           0 :       Deps.clear();
      59           0 :       F = nullptr;
      60           0 :     }
      61             : 
      62             :   private:
      63           0 :     static InstTypePair getInstTypePair(MemDepResult dep) {
      64           0 :       if (dep.isClobber())
      65           0 :         return InstTypePair(dep.getInst(), Clobber);
      66           0 :       if (dep.isDef())
      67           0 :         return InstTypePair(dep.getInst(), Def);
      68           0 :       if (dep.isNonFuncLocal())
      69           0 :         return InstTypePair(dep.getInst(), NonFuncLocal);
      70             :       assert(dep.isUnknown() && "unexpected dependence type");
      71           0 :       return InstTypePair(dep.getInst(), Unknown);
      72             :     }
      73             :     static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
      74             :       return InstTypePair(inst, type);
      75             :     }
      76             :   };
      77             : }
      78             : 
      79             : char MemDepPrinter::ID = 0;
      80        9158 : INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
      81             :                       "Print MemDeps of function", false, true)
      82        9158 : INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
      83       45790 : INITIALIZE_PASS_END(MemDepPrinter, "print-memdeps",
      84             :                       "Print MemDeps of function", false, true)
      85             : 
      86           0 : FunctionPass *llvm::createMemDepPrinter() {
      87           0 :   return new MemDepPrinter();
      88             : }
      89             : 
      90             : const char *const MemDepPrinter::DepTypeStr[]
      91             :   = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
      92             : 
      93           0 : bool MemDepPrinter::runOnFunction(Function &F) {
      94           0 :   this->F = &F;
      95           0 :   MemoryDependenceResults &MDA = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
      96             : 
      97             :   // All this code uses non-const interfaces because MemDep is not
      98             :   // const-friendly, though nothing is actually modified.
      99           0 :   for (auto &I : instructions(F)) {
     100           0 :     Instruction *Inst = &I;
     101             : 
     102           0 :     if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
     103           0 :       continue;
     104             : 
     105           0 :     MemDepResult Res = MDA.getDependency(Inst);
     106           0 :     if (!Res.isNonLocal()) {
     107           0 :       Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
     108             :                                        static_cast<BasicBlock *>(nullptr)));
     109           0 :     } else if (auto CS = CallSite(Inst)) {
     110             :       const MemoryDependenceResults::NonLocalDepInfo &NLDI =
     111           0 :         MDA.getNonLocalCallDependency(CS);
     112             : 
     113           0 :       DepSet &InstDeps = Deps[Inst];
     114           0 :       for (const NonLocalDepEntry &I : NLDI) {
     115           0 :         const MemDepResult &Res = I.getResult();
     116           0 :         InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
     117             :       }
     118             :     } else {
     119           0 :       SmallVector<NonLocalDepResult, 4> NLDI;
     120             :       assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
     121             :                isa<VAArgInst>(Inst)) && "Unknown memory instruction!"); 
     122           0 :       MDA.getNonLocalPointerDependency(Inst, NLDI);
     123             : 
     124           0 :       DepSet &InstDeps = Deps[Inst];
     125           0 :       for (const NonLocalDepResult &I : NLDI) {
     126           0 :         const MemDepResult &Res = I.getResult();
     127           0 :         InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
     128             :       }
     129             :     }
     130             :   }
     131             : 
     132           0 :   return false;
     133             : }
     134             : 
     135           0 : void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
     136           0 :   for (const auto &I : instructions(*F)) {
     137           0 :     const Instruction *Inst = &I;
     138             : 
     139           0 :     DepSetMap::const_iterator DI = Deps.find(Inst);
     140           0 :     if (DI == Deps.end())
     141           0 :       continue;
     142             : 
     143           0 :     const DepSet &InstDeps = DI->second;
     144             : 
     145           0 :     for (const auto &I : InstDeps) {
     146           0 :       const Instruction *DepInst = I.first.getPointer();
     147           0 :       DepType type = I.first.getInt();
     148           0 :       const BasicBlock *DepBB = I.second;
     149             : 
     150           0 :       OS << "    ";
     151           0 :       OS << DepTypeStr[type];
     152           0 :       if (DepBB) {
     153           0 :         OS << " in block ";
     154           0 :         DepBB->printAsOperand(OS, /*PrintType=*/false, M);
     155             :       }
     156           0 :       if (DepInst) {
     157           0 :         OS << " from: ";
     158           0 :         DepInst->print(OS);
     159             :       }
     160           0 :       OS << "\n";
     161             :     }
     162             : 
     163           0 :     Inst->print(OS);
     164           0 :     OS << "\n\n";
     165             :   }
     166           0 : }

Generated by: LCOV version 1.13