Line data Source code
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/ADT/SetVector.h"
14 : #include "llvm/Analysis/MemoryDependenceAnalysis.h"
15 : #include "llvm/Analysis/Passes.h"
16 : #include "llvm/IR/CallSite.h"
17 : #include "llvm/IR/InstIterator.h"
18 : #include "llvm/IR/LLVMContext.h"
19 : #include "llvm/Support/ErrorHandling.h"
20 : #include "llvm/Support/raw_ostream.h"
21 : using namespace llvm;
22 :
23 : namespace {
24 : struct MemDepPrinter : public FunctionPass {
25 : const Function *F;
26 :
27 : enum DepType {
28 : Clobber = 0,
29 : Def,
30 : NonFuncLocal,
31 : Unknown
32 : };
33 :
34 : static const char *const DepTypeStr[];
35 :
36 : typedef PointerIntPair<const Instruction *, 2, DepType> InstTypePair;
37 : typedef std::pair<InstTypePair, const BasicBlock *> Dep;
38 : typedef SmallSetVector<Dep, 4> DepSet;
39 : typedef DenseMap<const Instruction *, DepSet> DepSetMap;
40 : DepSetMap Deps;
41 :
42 : static char ID; // Pass identifcation, replacement for typeid
43 0 : MemDepPrinter() : FunctionPass(ID) {
44 0 : initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
45 0 : }
46 :
47 : bool runOnFunction(Function &F) override;
48 :
49 : void print(raw_ostream &OS, const Module * = nullptr) const override;
50 :
51 0 : void getAnalysisUsage(AnalysisUsage &AU) const override {
52 : AU.addRequiredTransitive<AAResultsWrapperPass>();
53 : AU.addRequiredTransitive<MemoryDependenceWrapperPass>();
54 : AU.setPreservesAll();
55 0 : }
56 :
57 0 : void releaseMemory() override {
58 0 : Deps.clear();
59 0 : F = nullptr;
60 0 : }
61 :
62 : private:
63 0 : static InstTypePair getInstTypePair(MemDepResult dep) {
64 0 : if (dep.isClobber())
65 0 : return InstTypePair(dep.getInst(), Clobber);
66 0 : if (dep.isDef())
67 0 : return InstTypePair(dep.getInst(), Def);
68 : if (dep.isNonFuncLocal())
69 0 : return InstTypePair(dep.getInst(), NonFuncLocal);
70 : assert(dep.isUnknown() && "unexpected dependence type");
71 0 : return InstTypePair(dep.getInst(), Unknown);
72 : }
73 : static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
74 : return InstTypePair(inst, type);
75 : }
76 : };
77 : }
78 :
79 : char MemDepPrinter::ID = 0;
80 10756 : INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
81 : "Print MemDeps of function", false, true)
82 10756 : INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass)
83 21512 : INITIALIZE_PASS_END(MemDepPrinter, "print-memdeps",
84 : "Print MemDeps of function", false, true)
85 :
86 0 : FunctionPass *llvm::createMemDepPrinter() {
87 0 : return new MemDepPrinter();
88 : }
89 :
90 : const char *const MemDepPrinter::DepTypeStr[]
91 : = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
92 :
93 0 : bool MemDepPrinter::runOnFunction(Function &F) {
94 0 : this->F = &F;
95 0 : MemoryDependenceResults &MDA = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
96 :
97 : // All this code uses non-const interfaces because MemDep is not
98 : // const-friendly, though nothing is actually modified.
99 0 : for (auto &I : instructions(F)) {
100 : Instruction *Inst = &I;
101 :
102 0 : if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
103 0 : continue;
104 :
105 0 : MemDepResult Res = MDA.getDependency(Inst);
106 : if (!Res.isNonLocal()) {
107 0 : Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
108 0 : static_cast<BasicBlock *>(nullptr)));
109 0 : } else if (auto CS = CallSite(Inst)) {
110 : const MemoryDependenceResults::NonLocalDepInfo &NLDI =
111 0 : MDA.getNonLocalCallDependency(CS);
112 :
113 0 : DepSet &InstDeps = Deps[Inst];
114 0 : for (const NonLocalDepEntry &I : NLDI) {
115 : const MemDepResult &Res = I.getResult();
116 0 : InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
117 : }
118 : } else {
119 : SmallVector<NonLocalDepResult, 4> NLDI;
120 : assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
121 : isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
122 0 : MDA.getNonLocalPointerDependency(Inst, NLDI);
123 :
124 0 : DepSet &InstDeps = Deps[Inst];
125 0 : for (const NonLocalDepResult &I : NLDI) {
126 : const MemDepResult &Res = I.getResult();
127 0 : InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
128 : }
129 : }
130 : }
131 :
132 0 : return false;
133 : }
134 :
135 0 : void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
136 0 : for (const auto &I : instructions(*F)) {
137 : const Instruction *Inst = &I;
138 :
139 0 : DepSetMap::const_iterator DI = Deps.find(Inst);
140 0 : if (DI == Deps.end())
141 0 : continue;
142 :
143 : const DepSet &InstDeps = DI->second;
144 :
145 0 : for (const auto &I : InstDeps) {
146 0 : const Instruction *DepInst = I.first.getPointer();
147 : DepType type = I.first.getInt();
148 0 : const BasicBlock *DepBB = I.second;
149 :
150 0 : OS << " ";
151 0 : OS << DepTypeStr[type];
152 0 : if (DepBB) {
153 0 : OS << " in block ";
154 0 : DepBB->printAsOperand(OS, /*PrintType=*/false, M);
155 : }
156 0 : if (DepInst) {
157 0 : OS << " from: ";
158 0 : DepInst->print(OS);
159 : }
160 0 : OS << "\n";
161 : }
162 :
163 0 : Inst->print(OS);
164 0 : OS << "\n\n";
165 : }
166 0 : }
|