MemDepPrinter.cpp revision 218885
1186681Sed//===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===// 2186681Sed// 3186681Sed// The LLVM Compiler Infrastructure 4186681Sed// 5186681Sed// This file is distributed under the University of Illinois Open Source 6186681Sed// License. See LICENSE.TXT for details. 7186681Sed// 8186681Sed//===----------------------------------------------------------------------===// 9186681Sed// 10186681Sed// 11186681Sed//===----------------------------------------------------------------------===// 12186681Sed 13186681Sed#include "llvm/Analysis/MemoryDependenceAnalysis.h" 14186681Sed#include "llvm/LLVMContext.h" 15186681Sed#include "llvm/Analysis/Passes.h" 16186681Sed#include "llvm/Assembly/Writer.h" 17186681Sed#include "llvm/Support/CallSite.h" 18186681Sed#include "llvm/Support/InstIterator.h" 19186681Sed#include "llvm/Support/ErrorHandling.h" 20186681Sed#include "llvm/Support/raw_ostream.h" 21186681Sed#include "llvm/ADT/SetVector.h" 22186681Sedusing namespace llvm; 23186681Sed 24186681Sednamespace { 25186681Sed struct MemDepPrinter : public FunctionPass { 26186681Sed const Function *F; 27186681Sed 28186681Sed typedef PointerIntPair<const Instruction *, 1> InstAndClobberFlag; 29186681Sed typedef std::pair<InstAndClobberFlag, const BasicBlock *> Dep; 30186681Sed typedef SmallSetVector<Dep, 4> DepSet; 31186681Sed typedef DenseMap<const Instruction *, DepSet> DepSetMap; 32186681Sed DepSetMap Deps; 33186681Sed 34186681Sed static char ID; // Pass identifcation, replacement for typeid 35186681Sed MemDepPrinter() : FunctionPass(ID) { 36187367Sed initializeMemDepPrinterPass(*PassRegistry::getPassRegistry()); 37187367Sed } 38187367Sed 39187367Sed virtual bool runOnFunction(Function &F); 40187367Sed 41186681Sed void print(raw_ostream &OS, const Module * = 0) const; 42186681Sed 43187367Sed virtual void getAnalysisUsage(AnalysisUsage &AU) const { 44187367Sed AU.addRequiredTransitive<AliasAnalysis>(); 45187367Sed AU.addRequiredTransitive<MemoryDependenceAnalysis>(); 46186681Sed AU.setPreservesAll(); 47186681Sed } 48186681Sed 49186681Sed virtual void releaseMemory() { 50186681Sed Deps.clear(); 51186681Sed F = 0; 52186681Sed } 53186681Sed }; 54186681Sed} 55186681Sed 56186681Sedchar MemDepPrinter::ID = 0; 57186681SedINITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps", 58186681Sed "Print MemDeps of function", false, true) 59186681SedINITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis) 60186681SedINITIALIZE_PASS_END(MemDepPrinter, "print-memdeps", 61186681Sed "Print MemDeps of function", false, true) 62186681Sed 63186681SedFunctionPass *llvm::createMemDepPrinter() { 64186681Sed return new MemDepPrinter(); 65186681Sed} 66186681Sed 67186681Sedbool MemDepPrinter::runOnFunction(Function &F) { 68186681Sed this->F = &F; 69186681Sed AliasAnalysis &AA = getAnalysis<AliasAnalysis>(); 70186681Sed MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>(); 71186681Sed 72186681Sed // All this code uses non-const interfaces because MemDep is not 73186681Sed // const-friendly, though nothing is actually modified. 74186681Sed for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { 75186681Sed Instruction *Inst = &*I; 76186681Sed 77186681Sed if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory()) 78186681Sed continue; 79186681Sed 80186681Sed MemDepResult Res = MDA.getDependency(Inst); 81186681Sed if (!Res.isNonLocal()) { 82186681Sed assert(Res.isClobber() != Res.isDef() && 83186681Sed "Local dep should be def or clobber!"); 84186681Sed Deps[Inst].insert(std::make_pair(InstAndClobberFlag(Res.getInst(), 85186681Sed Res.isClobber()), 86186681Sed static_cast<BasicBlock *>(0))); 87186681Sed } else if (CallSite CS = cast<Value>(Inst)) { 88186681Sed const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI = 89186681Sed MDA.getNonLocalCallDependency(CS); 90186681Sed 91186681Sed DepSet &InstDeps = Deps[Inst]; 92186681Sed for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator 93186681Sed I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { 94186681Sed const MemDepResult &Res = I->getResult(); 95186681Sed assert(Res.isClobber() != Res.isDef() && 96186681Sed "Resolved non-local call dep should be def or clobber!"); 97186681Sed InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), 98186681Sed Res.isClobber()), 99186681Sed I->getBB())); 100186681Sed } 101186681Sed } else { 102186681Sed SmallVector<NonLocalDepResult, 4> NLDI; 103186681Sed if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) { 104186681Sed // FIXME: Volatile is not handled properly here. 105186681Sed AliasAnalysis::Location Loc = AA.getLocation(LI); 106186681Sed MDA.getNonLocalPointerDependency(Loc, !LI->isVolatile(), 107186681Sed LI->getParent(), NLDI); 108186681Sed } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) { 109186681Sed // FIXME: Volatile is not handled properly here. 110186681Sed AliasAnalysis::Location Loc = AA.getLocation(SI); 111186681Sed MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDI); 112186681Sed } else if (VAArgInst *VI = dyn_cast<VAArgInst>(Inst)) { 113186681Sed AliasAnalysis::Location Loc = AA.getLocation(VI); 114186681Sed MDA.getNonLocalPointerDependency(Loc, false, VI->getParent(), NLDI); 115186681Sed } else { 116186681Sed llvm_unreachable("Unknown memory instruction!"); 117186681Sed } 118186681Sed 119186681Sed DepSet &InstDeps = Deps[Inst]; 120187469Sed for (SmallVectorImpl<NonLocalDepResult>::const_iterator 121187469Sed I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { 122187469Sed const MemDepResult &Res = I->getResult(); 123187469Sed assert(Res.isClobber() != Res.isDef() && 124186681Sed "Resolved non-local pointer dep should be def or clobber!"); 125186681Sed InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), 126186681Sed Res.isClobber()), 127186681Sed I->getBB())); 128186681Sed } 129186681Sed } 130186681Sed } 131186681Sed 132186681Sed return false; 133186681Sed} 134186681Sed 135186681Sedvoid MemDepPrinter::print(raw_ostream &OS, const Module *M) const { 136186681Sed for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) { 137186681Sed const Instruction *Inst = &*I; 138186681Sed 139186681Sed DepSetMap::const_iterator DI = Deps.find(Inst); 140186681Sed if (DI == Deps.end()) 141186681Sed continue; 142186681Sed 143186681Sed const DepSet &InstDeps = DI->second; 144186681Sed 145186681Sed for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end(); 146186681Sed I != E; ++I) { 147186681Sed const Instruction *DepInst = I->first.getPointer(); 148186681Sed bool isClobber = I->first.getInt(); 149186681Sed const BasicBlock *DepBB = I->second; 150186681Sed 151186681Sed OS << " " << (isClobber ? "Clobber" : " Def"); 152186681Sed if (DepBB) { 153187469Sed OS << " in block "; 154186681Sed WriteAsOperand(OS, DepBB, /*PrintType=*/false, M); 155186681Sed } 156187469Sed OS << " from: "; 157187469Sed if (DepInst == Inst) 158186681Sed OS << "<unspecified>"; 159187469Sed else 160187469Sed DepInst->print(OS); 161187469Sed OS << "\n"; 162187469Sed } 163187469Sed 164187469Sed Inst->print(OS); 165186681Sed OS << "\n\n"; 166186681Sed } 167186681Sed} 168186681Sed