LLVM  8.0.1
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/InstIterator.h"
17 #include "llvm/IR/LLVMContext.h"
20 using namespace llvm;
21 
22 namespace {
23  struct MemDepPrinter : public FunctionPass {
24  const Function *F;
25 
26  enum DepType {
27  Clobber = 0,
28  Def,
29  NonFuncLocal,
30  Unknown
31  };
32 
33  static const char *const DepTypeStr[];
34 
36  typedef std::pair<InstTypePair, const BasicBlock *> Dep;
37  typedef SmallSetVector<Dep, 4> DepSet;
38  typedef DenseMap<const Instruction *, DepSet> DepSetMap;
39  DepSetMap Deps;
40 
41  static char ID; // Pass identifcation, replacement for typeid
42  MemDepPrinter() : FunctionPass(ID) {
44  }
45 
46  bool runOnFunction(Function &F) override;
47 
48  void print(raw_ostream &OS, const Module * = nullptr) const override;
49 
50  void getAnalysisUsage(AnalysisUsage &AU) const override {
53  AU.setPreservesAll();
54  }
55 
56  void releaseMemory() override {
57  Deps.clear();
58  F = nullptr;
59  }
60 
61  private:
62  static InstTypePair getInstTypePair(MemDepResult dep) {
63  if (dep.isClobber())
64  return InstTypePair(dep.getInst(), Clobber);
65  if (dep.isDef())
66  return InstTypePair(dep.getInst(), Def);
67  if (dep.isNonFuncLocal())
68  return InstTypePair(dep.getInst(), NonFuncLocal);
69  assert(dep.isUnknown() && "unexpected dependence type");
70  return InstTypePair(dep.getInst(), Unknown);
71  }
72  static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
73  return InstTypePair(inst, type);
74  }
75  };
76 }
77 
78 char MemDepPrinter::ID = 0;
79 INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
80  "Print MemDeps of function", false, true)
83  "Print MemDeps of function", false, true)
84 
86  return new MemDepPrinter();
87 }
88 
89 const char *const MemDepPrinter::DepTypeStr[]
90  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
91 
93  this->F = &F;
94  MemoryDependenceResults &MDA = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
95 
96  // All this code uses non-const interfaces because MemDep is not
97  // const-friendly, though nothing is actually modified.
98  for (auto &I : instructions(F)) {
99  Instruction *Inst = &I;
100 
101  if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
102  continue;
103 
104  MemDepResult Res = MDA.getDependency(Inst);
105  if (!Res.isNonLocal()) {
106  Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
107  static_cast<BasicBlock *>(nullptr)));
108  } else if (auto *Call = dyn_cast<CallBase>(Inst)) {
110  MDA.getNonLocalCallDependency(Call);
111 
112  DepSet &InstDeps = Deps[Inst];
113  for (const NonLocalDepEntry &I : NLDI) {
114  const MemDepResult &Res = I.getResult();
115  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
116  }
117  } else {
119  assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
120  isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
121  MDA.getNonLocalPointerDependency(Inst, NLDI);
122 
123  DepSet &InstDeps = Deps[Inst];
124  for (const NonLocalDepResult &I : NLDI) {
125  const MemDepResult &Res = I.getResult();
126  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
127  }
128  }
129  }
130 
131  return false;
132 }
133 
134 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
135  for (const auto &I : instructions(*F)) {
136  const Instruction *Inst = &I;
137 
138  DepSetMap::const_iterator DI = Deps.find(Inst);
139  if (DI == Deps.end())
140  continue;
141 
142  const DepSet &InstDeps = DI->second;
143 
144  for (const auto &I : InstDeps) {
145  const Instruction *DepInst = I.first.getPointer();
146  DepType type = I.first.getInt();
147  const BasicBlock *DepBB = I.second;
148 
149  OS << " ";
150  OS << DepTypeStr[type];
151  if (DepBB) {
152  OS << " in block ";
153  DepBB->printAsOperand(OS, /*PrintType=*/false, M);
154  }
155  if (DepInst) {
156  OS << " from: ";
157  DepInst->print(OS);
158  }
159  OS << "\n";
160  }
161 
162  Inst->print(OS);
163  OS << "\n\n";
164  }
165 }
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...
This class represents lattice values for constants.
Definition: AllocatorList.h:24
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:65
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)
block Block Frequency true
#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)
FunctionPass * createMemDepPrinter()
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
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:4148
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:4225
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:847
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
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())
const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
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.