MemDepPrinter.cpp revision 2ab36d350293c77fc8941ce1023e4899df7e3a82
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/Analysis/MemoryDependenceAnalysis.h" 14#include "llvm/Analysis/Passes.h" 15#include "llvm/Assembly/Writer.h" 16#include "llvm/Support/CallSite.h" 17#include "llvm/Support/InstIterator.h" 18#include "llvm/Support/ErrorHandling.h" 19#include "llvm/Support/raw_ostream.h" 20#include "llvm/ADT/SetVector.h" 21using namespace llvm; 22 23namespace { 24 struct MemDepPrinter : public FunctionPass { 25 const Function *F; 26 27 typedef PointerIntPair<const Instruction *, 1> InstAndClobberFlag; 28 typedef std::pair<InstAndClobberFlag, const BasicBlock *> Dep; 29 typedef SmallSetVector<Dep, 4> DepSet; 30 typedef DenseMap<const Instruction *, DepSet> DepSetMap; 31 DepSetMap Deps; 32 33 static char ID; // Pass identifcation, replacement for typeid 34 MemDepPrinter() : FunctionPass(ID) {} 35 36 virtual bool runOnFunction(Function &F); 37 38 void print(raw_ostream &OS, const Module * = 0) const; 39 40 virtual void getAnalysisUsage(AnalysisUsage &AU) const { 41 AU.addRequired<MemoryDependenceAnalysis>(); 42 AU.setPreservesAll(); 43 } 44 45 virtual void releaseMemory() { 46 Deps.clear(); 47 F = 0; 48 } 49 }; 50} 51 52char MemDepPrinter::ID = 0; 53INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps", 54 "Print MemDeps of function", false, true) 55INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) 56INITIALIZE_PASS_END(MemDepPrinter, "print-memdeps", 57 "Print MemDeps of function", false, true) 58 59FunctionPass *llvm::createMemDepPrinter() { 60 return new MemDepPrinter(); 61} 62 63bool MemDepPrinter::runOnFunction(Function &F) { 64 this->F = &F; 65 MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>(); 66 67 // All this code uses non-const interfaces because MemDep is not 68 // const-friendly, though nothing is actually modified. 69 for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 70 Instruction *Inst = &*I; 71 72 if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory()) 73 continue; 74 75 MemDepResult Res = MDA.getDependency(Inst); 76 if (!Res.isNonLocal()) { 77 assert(Res.isClobber() != Res.isDef() && 78 "Local dep should be def or clobber!"); 79 Deps[Inst].insert(std::make_pair(InstAndClobberFlag(Res.getInst(), 80 Res.isClobber()), 81 static_cast<BasicBlock *>(0))); 82 } else if (CallSite CS = cast<Value>(Inst)) { 83 const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI = 84 MDA.getNonLocalCallDependency(CS); 85 86 DepSet &InstDeps = Deps[Inst]; 87 for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator 88 I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { 89 const MemDepResult &Res = I->getResult(); 90 assert(Res.isClobber() != Res.isDef() && 91 "Resolved non-local call dep should be def or clobber!"); 92 InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), 93 Res.isClobber()), 94 I->getBB())); 95 } 96 } else { 97 SmallVector<NonLocalDepResult, 4> NLDI; 98 if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) { 99 // FIXME: Volatile is not handled properly here. 100 MDA.getNonLocalPointerDependency(LI->getPointerOperand(), !LI->isVolatile(), 101 LI->getParent(), NLDI); 102 } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { 103 // FIXME: Volatile is not handled properly here. 104 MDA.getNonLocalPointerDependency(SI->getPointerOperand(), false, 105 SI->getParent(), NLDI); 106 } else if (VAArgInst *VI = dyn_cast<VAArgInst>(Inst)) { 107 MDA.getNonLocalPointerDependency(VI->getPointerOperand(), false, 108 VI->getParent(), NLDI); 109 } else { 110 llvm_unreachable("Unknown memory instruction!"); 111 } 112 113 DepSet &InstDeps = Deps[Inst]; 114 for (SmallVectorImpl<NonLocalDepResult>::const_iterator 115 I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { 116 const MemDepResult &Res = I->getResult(); 117 assert(Res.isClobber() != Res.isDef() && 118 "Resolved non-local pointer dep should be def or clobber!"); 119 InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), 120 Res.isClobber()), 121 I->getBB())); 122 } 123 } 124 } 125 126 return false; 127} 128 129void MemDepPrinter::print(raw_ostream &OS, const Module *M) const { 130 for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) { 131 const Instruction *Inst = &*I; 132 133 DepSetMap::const_iterator DI = Deps.find(Inst); 134 if (DI == Deps.end()) 135 continue; 136 137 const DepSet &InstDeps = DI->second; 138 139 for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end(); 140 I != E; ++I) { 141 const Instruction *DepInst = I->first.getPointer(); 142 bool isClobber = I->first.getInt(); 143 const BasicBlock *DepBB = I->second; 144 145 OS << " " << (isClobber ? "Clobber" : " Def"); 146 if (DepBB) { 147 OS << " in block "; 148 WriteAsOperand(OS, DepBB, /*PrintType=*/false, M); 149 } 150 OS << " from: "; 151 DepInst->print(OS); 152 OS << "\n"; 153 } 154 155 Inst->print(OS); 156 OS << "\n\n"; 157 } 158} 159