From: Dan Gohman Date: Thu, 16 Sep 2010 22:08:32 +0000 (+0000) Subject: Add a pass which prints out all the memdep dependencies. X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=commitdiff_plain;h=ead0109f5bc010af837d0fa7c9bb2401b34fb29d Add a pass which prints out all the memdep dependencies. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114121 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/Analysis/Passes.h b/include/llvm/Analysis/Passes.h index 37425ebe835..5541a848bc0 100644 --- a/include/llvm/Analysis/Passes.h +++ b/include/llvm/Analysis/Passes.h @@ -170,6 +170,13 @@ namespace llvm { // Print module-level debug info metadata in human-readable form. ModulePass *createModuleDebugInfoPrinterPass(); + + //===--------------------------------------------------------------------===// + // + // createMemDepPrinter - This pass exhaustively collects all memdep + // information and prints it with -analyze. + // + FunctionPass *createMemDepPrinter(); } #endif diff --git a/include/llvm/LinkAllPasses.h b/include/llvm/LinkAllPasses.h index 35dab62143d..19c2df217e6 100644 --- a/include/llvm/LinkAllPasses.h +++ b/include/llvm/LinkAllPasses.h @@ -147,6 +147,7 @@ namespace { (void) llvm::createSinkingPass(); (void) llvm::createLowerAtomicPass(); (void) llvm::createCorrelatedValuePropagationPass(); + (void) llvm::createMemDepPrinter(); (void)new llvm::IntervalPartition(); (void)new llvm::FindUsedTypes(); diff --git a/lib/Analysis/MemDepPrinter.cpp b/lib/Analysis/MemDepPrinter.cpp new file mode 100644 index 00000000000..1cbacff02d2 --- /dev/null +++ b/lib/Analysis/MemDepPrinter.cpp @@ -0,0 +1,153 @@ +//===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// +//===----------------------------------------------------------------------===// + +#include "llvm/Analysis/MemoryDependenceAnalysis.h" +#include "llvm/Analysis/Passes.h" +#include "llvm/Assembly/Writer.h" +#include "llvm/Support/CallSite.h" +#include "llvm/Support/InstIterator.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/ADT/SetVector.h" +using namespace llvm; + +namespace { + struct MemDepPrinter : public FunctionPass { + const Function *F; + + typedef PointerIntPair InstAndClobberFlag; + typedef std::pair Dep; + typedef SmallSetVector DepSet; + typedef DenseMap DepSetMap; + DepSetMap Deps; + + static char ID; // Pass identifcation, replacement for typeid + MemDepPrinter() : FunctionPass(ID) {} + + virtual bool runOnFunction(Function &F); + + void print(raw_ostream &OS, const Module * = 0) const; + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); + AU.setPreservesAll(); + } + + virtual void releaseMemory() { + Deps.clear(); + F = 0; + } + }; +} + +char MemDepPrinter::ID = 0; +INITIALIZE_PASS(MemDepPrinter, "print-memdeps", "Print MemDeps of function", false, true); + +FunctionPass *llvm::createMemDepPrinter() { + return new MemDepPrinter(); +} + +bool MemDepPrinter::runOnFunction(Function &F) { + this->F = &F; + MemoryDependenceAnalysis &MDA = getAnalysis(); + + // All this code uses non-const interfaces because MemDep is not + // const-friendly, though nothing is actually modified. + for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) { + Instruction *Inst = &*I; + + if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory()) + continue; + + MemDepResult Res = MDA.getDependency(Inst); + if (!Res.isNonLocal()) { + assert(Res.isClobber() != Res.isDef() && + "Local dep should be def or clobber!"); + Deps[Inst].insert(std::make_pair(InstAndClobberFlag(Res.getInst(), + Res.isClobber()), + static_cast(0))); + } else if (CallSite CS = cast(Inst)) { + const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI = + MDA.getNonLocalCallDependency(CS); + + DepSet &InstDeps = Deps[Inst]; + for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator + I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { + const MemDepResult &Res = I->getResult(); + assert(Res.isClobber() != Res.isDef() && + "Resolved non-local call dep should be def or clobber!"); + InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), + Res.isClobber()), + I->getBB())); + } + } else { + SmallVector NLDI; + if (LoadInst *LI = dyn_cast(Inst)) { + // FIXME: Volatile is not handled properly here. + MDA.getNonLocalPointerDependency(LI->getPointerOperand(), !LI->isVolatile(), + LI->getParent(), NLDI); + } else if (StoreInst *SI = dyn_cast(Inst)) { + // FIXME: Volatile is not handled properly here. + MDA.getNonLocalPointerDependency(SI->getPointerOperand(), false, + SI->getParent(), NLDI); + } else if (VAArgInst *VI = dyn_cast(Inst)) { + MDA.getNonLocalPointerDependency(VI->getPointerOperand(), false, + VI->getParent(), NLDI); + } else { + llvm_unreachable("Unknown memory instruction!"); + } + + DepSet &InstDeps = Deps[Inst]; + for (SmallVectorImpl::const_iterator + I = NLDI.begin(), E = NLDI.end(); I != E; ++I) { + const MemDepResult &Res = I->getResult(); + assert(Res.isClobber() != Res.isDef() && + "Resolved non-local pointer dep should be def or clobber!"); + InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(), + Res.isClobber()), + I->getBB())); + } + } + } + + return false; +} + +void MemDepPrinter::print(raw_ostream &OS, const Module *M) const { + for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) { + const Instruction *Inst = &*I; + + DepSetMap::const_iterator I = Deps.find(Inst); + if (I == Deps.end()) + continue; + + const DepSet &InstDeps = I->second; + + for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end(); + I != E; ++I) { + const Instruction *DepInst = I->first.getPointer(); + bool isClobber = I->first.getInt(); + const BasicBlock *DepBB = I->second; + + OS << " " << (isClobber ? "Clobber" : " Def"); + if (DepBB) { + OS << " in block "; + WriteAsOperand(OS, DepBB, /*PrintType=*/false, M); + } + OS << " from: "; + DepInst->print(OS); + OS << "\n"; + } + + Inst->print(OS); + OS << "\n\n"; + } +}