LLVM  6.0.0svn
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/ADT/SetVector.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"
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 
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  MemDepPrinter() : FunctionPass(ID) {
45  }
46 
47  bool runOnFunction(Function &F) override;
48 
49  void print(raw_ostream &OS, const Module * = nullptr) const override;
50 
51  void getAnalysisUsage(AnalysisUsage &AU) const override {
54  AU.setPreservesAll();
55  }
56 
57  void releaseMemory() override {
58  Deps.clear();
59  F = nullptr;
60  }
61 
62  private:
63  static InstTypePair getInstTypePair(MemDepResult dep) {
64  if (dep.isClobber())
65  return InstTypePair(dep.getInst(), Clobber);
66  if (dep.isDef())
67  return InstTypePair(dep.getInst(), Def);
68  if (dep.isNonFuncLocal())
69  return InstTypePair(dep.getInst(), NonFuncLocal);
70  assert(dep.isUnknown() && "unexpected dependence type");
71  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 INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
81  "Print MemDeps of function", false, true)
84  "Print MemDeps of function", false, true)
85 
87  return new MemDepPrinter();
88 }
89 
90 const char *const MemDepPrinter::DepTypeStr[]
91  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
92 
94  this->F = &F;
95  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  for (auto &I : instructions(F)) {
100  Instruction *Inst = &I;
101 
102  if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
103  continue;
104 
105  MemDepResult Res = MDA.getDependency(Inst);
106  if (!Res.isNonLocal()) {
107  Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
108  static_cast<BasicBlock *>(nullptr)));
109  } else if (auto CS = CallSite(Inst)) {
112 
113  DepSet &InstDeps = Deps[Inst];
114  for (const NonLocalDepEntry &I : NLDI) {
115  const MemDepResult &Res = I.getResult();
116  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
117  }
118  } else {
120  assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
121  isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
122  MDA.getNonLocalPointerDependency(Inst, NLDI);
123 
124  DepSet &InstDeps = Deps[Inst];
125  for (const NonLocalDepResult &I : NLDI) {
126  const MemDepResult &Res = I.getResult();
127  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
128  }
129  }
130  }
131 
132  return false;
133 }
134 
135 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
136  for (const auto &I : instructions(*F)) {
137  const Instruction *Inst = &I;
138 
139  DepSetMap::const_iterator DI = Deps.find(Inst);
140  if (DI == Deps.end())
141  continue;
142 
143  const DepSet &InstDeps = DI->second;
144 
145  for (const auto &I : InstDeps) {
146  const Instruction *DepInst = I.first.getPointer();
147  DepType type = I.first.getInt();
148  const BasicBlock *DepBB = I.second;
149 
150  OS << " ";
151  OS << DepTypeStr[type];
152  if (DepBB) {
153  OS << " in block ";
154  DepBB->printAsOperand(OS, /*PrintType=*/false, M);
155  }
156  if (DepInst) {
157  OS << " from: ";
158  DepInst->print(OS);
159  }
160  OS << "\n";
161  }
162 
163  Inst->print(OS);
164  OS << "\n\n";
165  }
166 }
Provides a lazy, caching interface for making common memory aliasing information queries, backed by LLVM&#39;s alias analysis passes.
void initializeMemDepPrinterPass(PassRegistry &)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Compute iterated dominance frontiers using a linear time algorithm.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:63
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block...
bool mayWriteToMemory() const
Return true if this instruction may modify memory.
F(f)
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:51
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst&#39;s specified memory location...
INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps", "Print MemDeps of function", false, true) INITIALIZE_PASS_END(MemDepPrinter
static bool runOnFunction(Function &F, bool PostInlining)
const NonLocalDepInfo & getNonLocalCallDependency(CallSite QueryCS)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
FunctionPass * createMemDepPrinter()
LLVM Basic Block Representation.
Definition: BasicBlock.h:59
PointerIntPair - This class implements a pair of a pointer and small integer.
This is a result from a NonLocal dependence query.
Represent the analysis usage information of a pass.
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:3494
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:285
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance...
void printAsOperand(raw_ostream &O, bool PrintType=true, const Module *M=nullptr) const
Print the name of this Value out to the specified raw_ostream.
Definition: AsmWriter.cpp:3573
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
A memory dependence query can return one of three different answers.
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:298
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:864
print memdeps
void setPreservesAll()
Set by analyses that do not transform their input at all.
bool isNonFuncLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the function...
std::vector< NonLocalDepEntry > NonLocalDepInfo
Basic Alias true
bool isUnknown() const
Tests if this MemDepResult represents a query which cannot and/or will not be computed.
Instruction * getInst() const
If this is a normal dependency, returns the instruction that is depended on.
#define I(x, y, z)
Definition: MD5.cpp:58
bool mayReadFromMemory() const
Return true if this instruction may read memory.
AnalysisUsage & addRequiredTransitive()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
print Print MemDeps of function
inst_range instructions(Function *F)
Definition: InstIterator.h:134
This is an entry in the NonLocalDepInfo cache.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.