LLVM  9.0.0svn
MemDepPrinter.cpp
Go to the documentation of this file.
1 //===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //
10 //===----------------------------------------------------------------------===//
11 
12 #include "llvm/ADT/SetVector.h"
14 #include "llvm/Analysis/Passes.h"
15 #include "llvm/IR/InstIterator.h"
16 #include "llvm/IR/LLVMContext.h"
19 using namespace llvm;
20 
21 namespace {
22  struct MemDepPrinter : public FunctionPass {
23  const Function *F;
24 
25  enum DepType {
26  Clobber = 0,
27  Def,
28  NonFuncLocal,
29  Unknown
30  };
31 
32  static const char *const DepTypeStr[];
33 
35  typedef std::pair<InstTypePair, const BasicBlock *> Dep;
36  typedef SmallSetVector<Dep, 4> DepSet;
37  typedef DenseMap<const Instruction *, DepSet> DepSetMap;
38  DepSetMap Deps;
39 
40  static char ID; // Pass identifcation, replacement for typeid
41  MemDepPrinter() : FunctionPass(ID) {
43  }
44 
45  bool runOnFunction(Function &F) override;
46 
47  void print(raw_ostream &OS, const Module * = nullptr) const override;
48 
49  void getAnalysisUsage(AnalysisUsage &AU) const override {
52  AU.setPreservesAll();
53  }
54 
55  void releaseMemory() override {
56  Deps.clear();
57  F = nullptr;
58  }
59 
60  private:
61  static InstTypePair getInstTypePair(MemDepResult dep) {
62  if (dep.isClobber())
63  return InstTypePair(dep.getInst(), Clobber);
64  if (dep.isDef())
65  return InstTypePair(dep.getInst(), Def);
66  if (dep.isNonFuncLocal())
67  return InstTypePair(dep.getInst(), NonFuncLocal);
68  assert(dep.isUnknown() && "unexpected dependence type");
69  return InstTypePair(dep.getInst(), Unknown);
70  }
71  static InstTypePair getInstTypePair(const Instruction* inst, DepType type) {
72  return InstTypePair(inst, type);
73  }
74  };
75 }
76 
77 char MemDepPrinter::ID = 0;
78 INITIALIZE_PASS_BEGIN(MemDepPrinter, "print-memdeps",
79  "Print MemDeps of function", false, true)
82  "Print MemDeps of function", false, true)
83 
85  return new MemDepPrinter();
86 }
87 
88 const char *const MemDepPrinter::DepTypeStr[]
89  = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
90 
92  this->F = &F;
93  MemoryDependenceResults &MDA = getAnalysis<MemoryDependenceWrapperPass>().getMemDep();
94 
95  // All this code uses non-const interfaces because MemDep is not
96  // const-friendly, though nothing is actually modified.
97  for (auto &I : instructions(F)) {
98  Instruction *Inst = &I;
99 
100  if (!Inst->mayReadFromMemory() && !Inst->mayWriteToMemory())
101  continue;
102 
103  MemDepResult Res = MDA.getDependency(Inst);
104  if (!Res.isNonLocal()) {
105  Deps[Inst].insert(std::make_pair(getInstTypePair(Res),
106  static_cast<BasicBlock *>(nullptr)));
107  } else if (auto *Call = dyn_cast<CallBase>(Inst)) {
109  MDA.getNonLocalCallDependency(Call);
110 
111  DepSet &InstDeps = Deps[Inst];
112  for (const NonLocalDepEntry &I : NLDI) {
113  const MemDepResult &Res = I.getResult();
114  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
115  }
116  } else {
118  assert( (isa<LoadInst>(Inst) || isa<StoreInst>(Inst) ||
119  isa<VAArgInst>(Inst)) && "Unknown memory instruction!");
120  MDA.getNonLocalPointerDependency(Inst, NLDI);
121 
122  DepSet &InstDeps = Deps[Inst];
123  for (const NonLocalDepResult &I : NLDI) {
124  const MemDepResult &Res = I.getResult();
125  InstDeps.insert(std::make_pair(getInstTypePair(Res), I.getBB()));
126  }
127  }
128  }
129 
130  return false;
131 }
132 
133 void MemDepPrinter::print(raw_ostream &OS, const Module *M) const {
134  for (const auto &I : instructions(*F)) {
135  const Instruction *Inst = &I;
136 
137  DepSetMap::const_iterator DI = Deps.find(Inst);
138  if (DI == Deps.end())
139  continue;
140 
141  const DepSet &InstDeps = DI->second;
142 
143  for (const auto &I : InstDeps) {
144  const Instruction *DepInst = I.first.getPointer();
145  DepType type = I.first.getInt();
146  const BasicBlock *DepBB = I.second;
147 
148  OS << " ";
149  OS << DepTypeStr[type];
150  if (DepBB) {
151  OS << " in block ";
152  DepBB->printAsOperand(OS, /*PrintType=*/false, M);
153  }
154  if (DepInst) {
155  OS << " from: ";
156  DepInst->print(OS);
157  }
158  OS << "\n";
159  }
160 
161  Inst->print(OS);
162  OS << "\n\n";
163  }
164 }
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:23
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.
MemDepResult getDependency(Instruction *QueryInst, OrderedBasicBlock *OBB=nullptr)
Returns the instruction on which a memory operation depends.
F(f)
block Block Frequency true
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:50
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:57
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:4212
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:284
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:4289
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:297
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:841
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:45
print Print MemDeps of function
inst_range instructions(Function *F)
Definition: InstIterator.h:133
This is an entry in the NonLocalDepInfo cache.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...