LLVM 17.0.0git
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"
21
22using namespace llvm;
23
24namespace {
25 struct MemDepPrinter : public FunctionPass {
26 const Function *F;
27
28 enum DepType {
29 Clobber = 0,
30 Def,
31 NonFuncLocal,
33 };
34
35 static const char *const DepTypeStr[];
36
38 typedef std::pair<InstTypePair, const BasicBlock *> Dep;
39 typedef SmallSetVector<Dep, 4> DepSet;
41 DepSetMap Deps;
42
43 static char ID; // Pass identifcation, replacement for typeid
44 MemDepPrinter() : FunctionPass(ID) {
46 }
47
48 bool runOnFunction(Function &F) override;
49
50 void print(raw_ostream &OS, const Module * = nullptr) const override;
51
52 void getAnalysisUsage(AnalysisUsage &AU) const override {
55 AU.setPreservesAll();
56 }
57
58 void releaseMemory() override {
59 Deps.clear();
60 F = nullptr;
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() && "unexpected dependence type");
72 return InstTypePair(dep.getInst(), Unknown);
73 }
74 };
75}
76
77char MemDepPrinter::ID = 0;
78INITIALIZE_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
88const char *const MemDepPrinter::DepTypeStr[]
89 = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
90
91bool MemDepPrinter::runOnFunction(Function &F) {
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)) {
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
133void 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}
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
basic Basic Alias true
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
print Print MemDeps of function
print memdeps
print must be executed print the must be executed context for all instructions
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition: PassSupport.h:55
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:59
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:52
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
raw_pwrite_stream & OS
This file implements a set that has insertion order iteration characteristics.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object.
Represent the analysis usage information of a pass.
void setPreservesAll()
Set by analyses that do not transform their input at all.
AnalysisUsage & addRequiredTransitive()
LLVM Basic Block Representation.
Definition: BasicBlock.h:56
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:311
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
bool mayWriteToMemory() const LLVM_READONLY
Return true if this instruction may modify memory.
bool mayReadFromMemory() const LLVM_READONLY
Return true if this instruction may read memory.
A memory dependence query can return one of three different answers.
bool isClobber() const
Tests if this MemDepResult represents a query that is an instruction clobber dependency.
bool isNonLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the block,...
bool isNonFuncLocal() const
Tests if this MemDepResult represents a query that is transparent to the start of the function.
bool isDef() const
Tests if this MemDepResult represents a query that is an instruction definition dependency.
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.
Provides a lazy, caching interface for making common memory aliasing information queries,...
std::vector< NonLocalDepEntry > NonLocalDepInfo
MemDepResult getDependency(Instruction *QueryInst)
Returns the instruction on which a memory operation depends.
const NonLocalDepInfo & getNonLocalCallDependency(CallBase *QueryCall)
Perform a full dependency query for the specified call, returning the set of blocks that the value is...
void getNonLocalPointerDependency(Instruction *QueryInst, SmallVectorImpl< NonLocalDepResult > &Result)
Perform a full dependency query for an access to the QueryInst's specified memory location,...
A wrapper analysis pass for the legacy pass manager that exposes a MemoryDepnedenceResults instance.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
This is an entry in the NonLocalDepInfo cache.
This is a result from a NonLocal dependence query.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual void print(raw_ostream &OS, const Module *M) const
print - Print out the internal state of the pass.
Definition: Pass.cpp:130
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition: Pass.cpp:98
virtual void releaseMemory()
releaseMemory() - This member can be implemented by a pass if it wants to be able to release its memo...
Definition: Pass.cpp:102
PointerIntPair - This class implements a pair of a pointer and small integer.
A SetVector that performs no allocations if smaller than a certain size.
Definition: SetVector.h:312
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
void print(raw_ostream &O, bool IsForDebug=false) const
Implement operator<< on Value.
Definition: AsmWriter.cpp:4695
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:4778
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
void initializeMemDepPrinterPass(PassRegistry &)
FunctionPass * createMemDepPrinter()