LLVM  3.7.0
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/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)
83 INITIALIZE_PASS_END(MemDepPrinter, "print-memdeps",
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 
93 bool MemDepPrinter::runOnFunction(Function &F) {
94  this->F = &F;
95  MemoryDependenceAnalysis &MDA = getAnalysis<MemoryDependenceAnalysis>();
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 : inst_range(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 (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
115  I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
116  const MemDepResult &Res = I->getResult();
117  InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
118  }
119  } else {
121  assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
122  isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
123  MDA.getNonLocalPointerDependency(Inst, NLDI);
124 
125  DepSet &InstDeps = Deps[Inst];
127  I = NLDI.begin(), E = NLDI.end(); I != E; ++I) {
128  const MemDepResult &Res = I->getResult();
129  InstDeps.insert(std::make_pair(getInstTypePair(Res), I->getBB()));
130  }
131  }
132  }
133 
134  return false;
135 }
136 
137 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
138  for (const auto &I : inst_range(*F)) {
139  const Instruction *Inst = &I;
140 
141  DepSetMap::const_iterator DI = Deps.find(Inst);
142  if (DI == Deps.end())
143  continue;
144 
145  const DepSet &InstDeps = DI->second;
146 
147  for (const auto &I : InstDeps) {
148  const Instruction *DepInst = I.first.getPointer();
149  DepType type = I.first.getInt();
150  const BasicBlock *DepBB = I.second;
151 
152  OS << " ";
153  OS << DepTypeStr[type];
154  if (DepBB) {
155  OS << " in block ";
156  DepBB->printAsOperand(OS, /*PrintType=*/false, M);
157  }
158  if (DepInst) {
159  OS << " from: ";
160  DepInst->print(OS);
161  }
162  OS << "\n";
163  }
164 
165  Inst->print(OS);
166  OS << "\n\n";
167  }
168 }
void initializeMemDepPrinterPass(PassRegistry &)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isDef() const
isDef - Return true if this MemDepResult represents a query that is an instruction definition depende...
A Module instance is used to store all the information related to an LLVM module. ...
Definition: Module.h:114
void Print(const Unit &U, const char *PrintAfter="")
Definition: FuzzerUtil.cpp:23
F(f)
bool isUnknown() const
isUnknown - Return true if this MemDepResult represents a query which cannot and/or will not be compu...
bool isClobber() const
isClobber - Return true if this MemDepResult represents a query that is an instruction clobber depend...
INITIALIZE_PASS_BEGIN(MemDepPrinter,"print-memdeps","Print MemDeps of function", false, true) INITIALIZE_PASS_END(MemDepPrinter
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:70
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APInt.h:33
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:75
MemoryDependenceAnalysis - This is an analysis that determines, for a given memory operation...
void print(raw_ostream &O) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:3209
bool mayReadFromMemory() const
mayReadFromMemory - Return true if this instruction may read memory.
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:3287
#define true
Definition: ConvertUTF.c:66
FunctionPass * createMemDepPrinter()
LLVM Basic Block Representation.
Definition: BasicBlock.h:65
PointerIntPair - This class implements a pair of a pointer and small integer.
print Print MemDeps of false
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:294
bool mayWriteToMemory() const
mayWriteToMemory - Return true if this instruction may modify memory.
MemDepResult - A memory dependence query can return one of three different answers, described below.
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:217
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:861
bool isNonLocal() const
isNonLocal - Return true if this MemDepResult represents a query that is transparent to the start of ...
std::vector< NonLocalDepEntry > NonLocalDepInfo
print memdeps
void setPreservesAll()
Set by analyses that do not transform their input at all.
Instruction * getInst() const
getInst() - If this is a normal dependency, return the instruction that is depended on...
MemDepResult getDependency(Instruction *QueryInst)
getDependency - Return the instruction on which a memory operation depends.
iterator_range< inst_iterator > inst_range(Function *F)
Definition: InstIterator.h:129
#define I(x, y, z)
Definition: MD5.cpp:54
const NonLocalDepInfo & getNonLocalCallDependency(CallSite QueryCS)
getNonLocalCallDependency - Perform a full dependency query for the specified call, returning the set of blocks that the value is potentially live across.
AnalysisUsage & addRequiredTransitive()
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:38
print Print MemDeps of function
bool isNonFuncLocal() const
isNonFuncLocal - Return true if this MemDepResult represents a query that is transparent to the start...
void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
getNonLocalPointerDependency - Perform a full dependency query for an access to the QueryInst's speci...