MemDepPrinter.cpp revision a990e071f2f29ba326b97a4288207a2c406c5b66
1ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===//
2ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//
3ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//                     The LLVM Compiler Infrastructure
4ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//
5ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman// This file is distributed under the University of Illinois Open Source
6ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman// License. See LICENSE.TXT for details.
7ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//
8ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//===----------------------------------------------------------------------===//
9ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//
10ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//
11ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman//===----------------------------------------------------------------------===//
12ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
13ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Analysis/MemoryDependenceAnalysis.h"
14075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman#include "llvm/LLVMContext.h"
15ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Analysis/Passes.h"
16ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Assembly/Writer.h"
17ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Support/CallSite.h"
18ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Support/InstIterator.h"
19ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Support/ErrorHandling.h"
208945db73d198f912d6821975d9960ab1deb0a45fDan Gohman#include "llvm/Support/raw_ostream.h"
21ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/ADT/SetVector.h"
22ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanusing namespace llvm;
23ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
24ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmannamespace {
25ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  struct MemDepPrinter : public FunctionPass {
26ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    const Function *F;
27ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
28ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    typedef PointerIntPair<const Instruction *, 1> InstAndClobberFlag;
29ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    typedef std::pair<InstAndClobberFlag, const BasicBlock *> Dep;
30ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    typedef SmallSetVector<Dep, 4> DepSet;
31ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    typedef DenseMap<const Instruction *, DepSet> DepSetMap;
32ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    DepSetMap Deps;
33ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
34ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    static char ID; // Pass identifcation, replacement for typeid
35081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    MemDepPrinter() : FunctionPass(ID) {
36081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson      initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
37081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    }
38ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
39ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    virtual bool runOnFunction(Function &F);
40ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
41ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    void print(raw_ostream &OS, const Module * = 0) const;
42ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
43ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    virtual void getAnalysisUsage(AnalysisUsage &AU) const {
44075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman      AU.addRequiredTransitive<AliasAnalysis>();
45075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman      AU.addRequiredTransitive<MemoryDependenceAnalysis>();
46ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      AU.setPreservesAll();
47ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
48ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
49ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    virtual void releaseMemory() {
50ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      Deps.clear();
51ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      F = 0;
52ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
53ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  };
54ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
55ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
56ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanchar MemDepPrinter::ID = 0;
572ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
582ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                      "Print MemDeps of function", false, true)
592ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis)
602ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(MemDepPrinter, "print-memdeps",
612ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                      "Print MemDeps of function", false, true)
62ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
63ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan GohmanFunctionPass *llvm::createMemDepPrinter() {
64ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  return new MemDepPrinter();
65ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
66ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
67ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanbool MemDepPrinter::runOnFunction(Function &F) {
68ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  this->F = &F;
69075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
70ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>();
71ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
72ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  // All this code uses non-const interfaces because MemDep is not
73ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  // const-friendly, though nothing is actually modified.
74ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
75ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    Instruction *Inst = &*I;
76ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
77ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
78ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      continue;
79ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
80ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    MemDepResult Res = MDA.getDependency(Inst);
81ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    if (!Res.isNonLocal()) {
82a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      assert((Res.isUnknown() || Res.isClobber() || Res.isDef()) &&
83a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman              "Local dep should be unknown, def or clobber!");
84ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      Deps[Inst].insert(std::make_pair(InstAndClobberFlag(Res.getInst(),
85ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                                          Res.isClobber()),
86ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                       static_cast<BasicBlock *>(0)));
87ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    } else if (CallSite CS = cast<Value>(Inst)) {
88ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI =
89ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        MDA.getNonLocalCallDependency(CS);
90ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
91ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      DepSet &InstDeps = Deps[Inst];
92ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
93ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman           I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
94ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        const MemDepResult &Res = I->getResult();
95a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        assert((Res.isUnknown() || Res.isClobber() || Res.isDef()) &&
96a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman                "Resolved non-local call dep should be unknown, def or "
97a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman                "clobber!");
98ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(),
99ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                                          Res.isClobber()),
100ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                       I->getBB()));
101ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
102ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    } else {
103ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      SmallVector<NonLocalDepResult, 4> NLDI;
104ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
105ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        // FIXME: Volatile is not handled properly here.
1066d8eb156e6be727570b300bac7712f745a318c7dDan Gohman        AliasAnalysis::Location Loc = AA.getLocation(LI);
107075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman        MDA.getNonLocalPointerDependency(Loc, !LI->isVolatile(),
108ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                         LI->getParent(), NLDI);
109ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
110ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        // FIXME: Volatile is not handled properly here.
1116d8eb156e6be727570b300bac7712f745a318c7dDan Gohman        AliasAnalysis::Location Loc = AA.getLocation(SI);
112075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman        MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDI);
113ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      } else if (VAArgInst *VI = dyn_cast<VAArgInst>(Inst)) {
1146d8eb156e6be727570b300bac7712f745a318c7dDan Gohman        AliasAnalysis::Location Loc = AA.getLocation(VI);
115075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman        MDA.getNonLocalPointerDependency(Loc, false, VI->getParent(), NLDI);
116ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      } else {
117ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        llvm_unreachable("Unknown memory instruction!");
118ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
119ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
120ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      DepSet &InstDeps = Deps[Inst];
121ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      for (SmallVectorImpl<NonLocalDepResult>::const_iterator
122ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman           I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
123ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        const MemDepResult &Res = I->getResult();
124ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        assert(Res.isClobber() != Res.isDef() &&
125ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman               "Resolved non-local pointer dep should be def or clobber!");
126ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        InstDeps.insert(std::make_pair(InstAndClobberFlag(Res.getInst(),
127ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                                          Res.isClobber()),
128ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman                                       I->getBB()));
129ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
130ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
131ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  }
132ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
133ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  return false;
134ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
135ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
136ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanvoid MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
137ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) {
138ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    const Instruction *Inst = &*I;
139ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
140a627e9bfcdd40454c6942228ab9614dc4154d974Dan Gohman    DepSetMap::const_iterator DI = Deps.find(Inst);
141a627e9bfcdd40454c6942228ab9614dc4154d974Dan Gohman    if (DI == Deps.end())
142ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      continue;
143ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
144a627e9bfcdd40454c6942228ab9614dc4154d974Dan Gohman    const DepSet &InstDeps = DI->second;
145ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
146ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end();
147ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman         I != E; ++I) {
148ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      const Instruction *DepInst = I->first.getPointer();
149ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      bool isClobber = I->first.getInt();
150ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      const BasicBlock *DepBB = I->second;
151ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
152a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      OS << "    ";
153a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      if (!DepInst)
154a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        OS << "Unknown";
155a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      else if (isClobber)
156a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        OS << "Clobber";
157a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      else
158a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        OS << "    Def";
159ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      if (DepBB) {
160ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        OS << " in block ";
161ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        WriteAsOperand(OS, DepBB, /*PrintType=*/false, M);
162ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
163a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      if (DepInst) {
164a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        OS << " from: ";
165a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        if (DepInst == Inst)
166a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman          OS << "<unspecified>";
167a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        else
168a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman          DepInst->print(OS);
169a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      }
170ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      OS << "\n";
171ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
172ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
173ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    Inst->print(OS);
174ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    OS << "\n\n";
175ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  }
176ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
177