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/Passes.h"
14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/SetVector.h"
15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Analysis/MemoryDependenceAnalysis.h"
1636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/CallSite.h"
1736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/InstIterator.h"
180b8c9a80f20772c3793201ab5b251d3520b9cea3Chandler Carruth#include "llvm/IR/LLVMContext.h"
19ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman#include "llvm/Support/ErrorHandling.h"
208945db73d198f912d6821975d9960ab1deb0a45fDan Gohman#include "llvm/Support/raw_ostream.h"
21ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanusing namespace llvm;
22ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
23ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmannamespace {
24ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  struct MemDepPrinter : public FunctionPass {
25ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    const Function *F;
26ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
27b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    enum DepType {
28b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      Clobber = 0,
29b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      Def,
30b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      NonFuncLocal,
31b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      Unknown
32b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    };
33b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman
34e32981048244ecfa67d0bdc211af1bac2020a555Craig Topper    static const char *const DepTypeStr[];
35b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman
36b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    typedef PointerIntPair<const Instruction *, 2, DepType> InstTypePair;
37b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    typedef std::pair<InstTypePair, const BasicBlock *> Dep;
38ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    typedef SmallSetVector<Dep, 4> DepSet;
39ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    typedef DenseMap<const Instruction *, DepSet> DepSetMap;
40ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    DepSetMap Deps;
41ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
42ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    static char ID; // Pass identifcation, replacement for typeid
43081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    MemDepPrinter() : FunctionPass(ID) {
44081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson      initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
45081c34b725980f995be9080eaec24cd3dfaaf065Owen Anderson    }
46ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
4736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    bool runOnFunction(Function &F) override;
48ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    void print(raw_ostream &OS, const Module * = nullptr) const override;
50ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void getAnalysisUsage(AnalysisUsage &AU) const override {
52075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman      AU.addRequiredTransitive<AliasAnalysis>();
53075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman      AU.addRequiredTransitive<MemoryDependenceAnalysis>();
54ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      AU.setPreservesAll();
55ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
56ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void releaseMemory() override {
58ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      Deps.clear();
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      F = nullptr;
60ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
61b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman
62b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman  private:
63b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    static InstTypePair getInstTypePair(MemDepResult dep) {
64b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      if (dep.isClobber())
65b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman        return InstTypePair(dep.getInst(), Clobber);
66b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      if (dep.isDef())
67b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman        return InstTypePair(dep.getInst(), Def);
68b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      if (dep.isNonFuncLocal())
69b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman        return InstTypePair(dep.getInst(), NonFuncLocal);
7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      assert(dep.isUnknown() && "unexpected dependence type");
71b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      return InstTypePair(dep.getInst(), Unknown);
72b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    }
73b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
74b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      return InstTypePair(inst, type);
75b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman    }
76ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  };
77ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
78ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
79ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanchar MemDepPrinter::ID = 0;
802ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
812ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                      "Print MemDeps of function", false, true)
822ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis)
832ab36d350293c77fc8941ce1023e4899df7e3a82Owen AndersonINITIALIZE_PASS_END(MemDepPrinter, "print-memdeps",
842ab36d350293c77fc8941ce1023e4899df7e3a82Owen Anderson                      "Print MemDeps of function", false, true)
85ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
86ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan GohmanFunctionPass *llvm::createMemDepPrinter() {
87ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  return new MemDepPrinter();
88ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
89ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
90e32981048244ecfa67d0bdc211af1bac2020a555Craig Topperconst char *const MemDepPrinter::DepTypeStr[]
91b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
92b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman
93ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanbool MemDepPrinter::runOnFunction(Function &F) {
94ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  this->F = &F;
95075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
96ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>();
97ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
98ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  // All this code uses non-const interfaces because MemDep is not
99ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  // const-friendly, though nothing is actually modified.
100ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
101ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    Instruction *Inst = &*I;
102ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
103ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
104ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      continue;
105ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
106ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    MemDepResult Res = MDA.getDependency(Inst);
107ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    if (!Res.isNonLocal()) {
108b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                       static_cast<BasicBlock *>(nullptr)));
110ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    } else if (CallSite CS = cast<Value>(Inst)) {
111ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      const MemoryDependenceAnalysis::NonLocalDepInfo &NLDI =
112ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        MDA.getNonLocalCallDependency(CS);
113ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
114ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      DepSet &InstDeps = Deps[Inst];
115ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
116ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman           I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
117ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        const MemDepResult &Res = I->getResult();
118b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman        InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
119ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
120ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    } else {
121ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      SmallVector<NonLocalDepResult, 4> NLDI;
122ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
123667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman        if (!LI->isUnordered()) {
124667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman          // FIXME: Handle atomic/volatile loads.
125dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Deps[Inst].insert(std::make_pair(getInstTypePair(nullptr, Unknown),
126dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           static_cast<BasicBlock *>(nullptr)));
127667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman          continue;
128667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman        }
1296d8eb156e6be727570b300bac7712f745a318c7dDan Gohman        AliasAnalysis::Location Loc = AA.getLocation(LI);
130667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman        MDA.getNonLocalPointerDependency(Loc, true, LI->getParent(), NLDI);
131ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
132e6109828d795d4dd060200aede9c991735b8e5f3Eli Friedman        if (!SI->isUnordered()) {
133667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman          // FIXME: Handle atomic/volatile stores.
134dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Deps[Inst].insert(std::make_pair(getInstTypePair(nullptr, Unknown),
135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                           static_cast<BasicBlock *>(nullptr)));
136667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman          continue;
137667ccf231b57857ea9e36f1d93bd895242d58284Eli Friedman        }
1386d8eb156e6be727570b300bac7712f745a318c7dDan Gohman        AliasAnalysis::Location Loc = AA.getLocation(SI);
139075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman        MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDI);
140ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      } else if (VAArgInst *VI = dyn_cast<VAArgInst>(Inst)) {
1416d8eb156e6be727570b300bac7712f745a318c7dDan Gohman        AliasAnalysis::Location Loc = AA.getLocation(VI);
142075fb5d68fcb55d26e44c48f07dfdbbfa21ccb2aDan Gohman        MDA.getNonLocalPointerDependency(Loc, false, VI->getParent(), NLDI);
143ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      } else {
144ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        llvm_unreachable("Unknown memory instruction!");
145ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
146ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
147ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      DepSet &InstDeps = Deps[Inst];
148ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      for (SmallVectorImpl<NonLocalDepResult>::const_iterator
149ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman           I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
150ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        const MemDepResult &Res = I->getResult();
151b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman        InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
152ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
153ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
154ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  }
155ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
156ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  return false;
157ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
158ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
159ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohmanvoid MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
160ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) {
161ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    const Instruction *Inst = &*I;
162ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
163a627e9bfcdd40454c6942228ab9614dc4154d974Dan Gohman    DepSetMap::const_iterator DI = Deps.find(Inst);
164a627e9bfcdd40454c6942228ab9614dc4154d974Dan Gohman    if (DI == Deps.end())
165ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      continue;
166ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
167a627e9bfcdd40454c6942228ab9614dc4154d974Dan Gohman    const DepSet &InstDeps = DI->second;
168ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
169ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end();
170ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman         I != E; ++I) {
171ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      const Instruction *DepInst = I->first.getPointer();
172b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      DepType type = I->first.getInt();
173ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      const BasicBlock *DepBB = I->second;
174ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
175a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      OS << "    ";
176b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman      OS << DepTypeStr[type];
177ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      if (DepBB) {
178ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman        OS << " in block ";
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        DepBB->printAsOperand(OS, /*PrintType=*/false, M);
180ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      }
181a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      if (DepInst) {
182a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman        OS << " from: ";
183b414142036012dd9432c4e8c5fef09d4d49fcc22Eli Friedman        DepInst->print(OS);
184a990e071f2f29ba326b97a4288207a2c406c5b66Eli Friedman      }
185ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman      OS << "\n";
186ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    }
187ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman
188ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    Inst->print(OS);
189ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman    OS << "\n\n";
190ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman  }
191ead0109f5bc010af837d0fa7c9bb2401b34fb29dDan Gohman}
192