LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MemDepPrinter.cpp
Go to the documentation of this file.
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/Analysis/Passes.h"
14 #include "llvm/ADT/SetVector.h"
16 #include "llvm/Assembly/Writer.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/Support/CallSite.h"
22 using namespace llvm;
23 
24 namespace {
25  struct MemDepPrinter : public FunctionPass {
26  const Function *F;
27 
28  enum DepType {
29  Clobber = 0,
30  Def,
31  NonFuncLocal,
32  Unknown
33  };
34 
35  static const char *const DepTypeStr[];
36 
38  typedef std::pair<InstTypePair, const BasicBlock *> Dep;
39  typedef SmallSetVector<Dep, 4> DepSet;
40  typedef DenseMap<const Instruction *, DepSet> DepSetMap;
41  DepSetMap Deps;
42 
43  static char ID; // Pass identifcation, replacement for typeid
44  MemDepPrinter() : FunctionPass(ID) {
46  }
47 
48  virtual bool runOnFunction(Function &F);
49 
50  void print(raw_ostream &OS, const Module * = 0) const;
51 
52  virtual void getAnalysisUsage(AnalysisUsage &AU) const {
55  AU.setPreservesAll();
56  }
57 
58  virtual void releaseMemory() {
59  Deps.clear();
60  F = 0;
61  }
62 
63  private:
64  static InstTypePair getInstTypePair(MemDepResult dep) {
65  if (dep.isClobber())
66  return InstTypePair(dep.getInst(), Clobber);
67  if (dep.isDef())
68  return InstTypePair(dep.getInst(), Def);
69  if (dep.isNonFuncLocal())
70  return InstTypePair(dep.getInst(), NonFuncLocal);
71  assert(dep.isUnknown() && "unexptected dependence type");
72  return InstTypePair(dep.getInst(), Unknown);
73  }
74  static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
75  return InstTypePair(inst, type);
76  }
77  };
78 }
79 
80 char MemDepPrinter::ID = 0;
81 INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
82  "Print MemDeps of function", false, true)
84 INITIALIZE_PASS_END(MemDepPrinter, "print-memdeps",
85  "Print MemDeps of function", false, true)
86 
88  return new MemDepPrinter();
89 }
90 
91 const char *const MemDepPrinter::DepTypeStr[]
92  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
93 
94 bool MemDepPrinter::runOnFunction(Function &F) {
95  this->F = &F;
96  AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
97  MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>();
98 
99  // All this code uses non-const interfaces because MemDep is not
100  // const-friendly, though nothing is actually modified.
101  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
102  Instruction *Inst = &*I;
103 
104  if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
105  continue;
106 
107  MemDepResult Res = MDA.getDependency(Inst);
108  if (!Res.isNonLocal()) {
109  Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
110  static_cast<BasicBlock *>(0)));
111  } else if (CallSite CS = cast<Value>(Inst)) {
113  MDA.getNonLocalCallDependency(CS);
114 
115  DepSet &InstDeps = Deps[Inst];
116  for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
117  I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
118  const MemDepResult &Res = I->getResult();
119  InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
120  }
121  } else {
123  if (LoadInst *LI = dyn_cast<LoadInst>(Inst)) {
124  if (!LI->isUnordered()) {
125  // FIXME: Handle atomic/volatile loads.
126  Deps[Inst].insert(std::make_pair(getInstTypePair(0, Unknown),
127  static_cast<BasicBlock *>(0)));
128  continue;
129  }
131  MDA.getNonLocalPointerDependency(Loc, true, LI->getParent(), NLDI);
132  } else if (StoreInst *SI = dyn_cast<StoreInst>(Inst)) {
133  if (!SI->isUnordered()) {
134  // FIXME: Handle atomic/volatile stores.
135  Deps[Inst].insert(std::make_pair(getInstTypePair(0, Unknown),
136  static_cast<BasicBlock *>(0)));
137  continue;
138  }
140  MDA.getNonLocalPointerDependency(Loc, false, SI->getParent(), NLDI);
141  } else if (VAArgInst *VI = dyn_cast<VAArgInst>(Inst)) {
143  MDA.getNonLocalPointerDependency(Loc, false, VI->getParent(), NLDI);
144  } else {
145  llvm_unreachable("Unknown memory instruction!");
146  }
147 
148  DepSet &InstDeps = Deps[Inst];
150  I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
151  const MemDepResult &Res = I->getResult();
152  InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
153  }
154  }
155  }
156 
157  return false;
158 }
159 
160 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
161  for (const_inst_iterator I = inst_begin(*F), E = inst_end(*F); I != E; ++I) {
162  const Instruction *Inst = &*I;
163 
164  DepSetMap::const_iterator DI = Deps.find(Inst);
165  if (DI == Deps.end())
166  continue;
167 
168  const DepSet &InstDeps = DI->second;
169 
170  for (DepSet::const_iterator I = InstDeps.begin(), E = InstDeps.end();
171  I != E; ++I) {
172  const Instruction *DepInst = I->first.getPointer();
173  DepType type = I->first.getInt();
174  const BasicBlock *DepBB = I->second;
175 
176  OS << " ";
177  OS << DepTypeStr[type];
178  if (DepBB) {
179  OS << " in block ";
180  WriteAsOperand(OS, DepBB, /*PrintType=*/false, M);
181  }
182  if (DepInst) {
183  OS << " from: ";
184  DepInst->print(OS);
185  }
186  OS << "\n";
187  }
188 
189  Inst->print(OS);
190  OS << "\n\n";
191  }
192 }
void initializeMemDepPrinterPass(PassRegistry &)
static PassRegistry * getPassRegistry()
The main container class for the LLVM Intermediate Representation.
Definition: Module.h:112
iterator insert(iterator I, const T &Elt)
Definition: SmallVector.h:537
F(f)
LoopInfoBase< BlockT, LoopT > * LI
Definition: LoopInfoImpl.h:411
void WriteAsOperand(raw_ostream &, const Value *, bool PrintTy=true, const Module *Context=0)
Definition: AsmWriter.cpp:1179
INITIALIZE_PASS_BEGIN(MemDepPrinter,"print-memdeps","Print MemDeps of function", false, true) INITIALIZE_PASS_END(MemDepPrinter
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:167
inst_iterator inst_begin(Function *F)
Definition: InstIterator.h:128
#define llvm_unreachable(msg)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:172
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
bool mayReadFromMemory() const
#define true
Definition: ConvertUTF.c:65
FunctionPass * createMemDepPrinter()
LLVM Basic Block Representation.
Definition: BasicBlock.h:72
print Print MemDeps of false
Location - A description of a memory location.
bool mayWriteToMemory() const
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:218
std::vector< NonLocalDepEntry > NonLocalDepInfo
print memdeps
Location getLocation(const LoadInst *LI)
Instruction * getInst() const
#define I(x, y, z)
Definition: MD5.cpp:54
AnalysisUsage & addRequiredTransitive()
void print(raw_ostream &O, AssemblyAnnotationWriter *AAW=0) const
Definition: AsmWriter.cpp:2162
print Print MemDeps of function
inst_iterator inst_end(Function *F)
Definition: InstIterator.h:129