1 //===- MemDepPrinter.cpp - Printer for MemoryDependenceAnalysis -----------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 //===----------------------------------------------------------------------===//
13 #include "llvm/ADT/SetVector.h"
14 #include "llvm/Analysis/MemoryDependenceAnalysis.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"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
24 struct MemDepPrinter
: public FunctionPass
{
34 static const char *const DepTypeStr
[];
36 typedef PointerIntPair
<const Instruction
*, 2, DepType
> InstTypePair
;
37 typedef std::pair
<InstTypePair
, const BasicBlock
*> Dep
;
38 typedef SmallSetVector
<Dep
, 4> DepSet
;
39 typedef DenseMap
<const Instruction
*, DepSet
> DepSetMap
;
42 static char ID
; // Pass identifcation, replacement for typeid
43 MemDepPrinter() : FunctionPass(ID
) {
44 initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
47 bool runOnFunction(Function
&F
) override
;
49 void print(raw_ostream
&OS
, const Module
* = nullptr) const override
;
51 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
52 AU
.addRequiredTransitive
<AAResultsWrapperPass
>();
53 AU
.addRequiredTransitive
<MemoryDependenceWrapperPass
>();
57 void releaseMemory() override
{
63 static InstTypePair
getInstTypePair(MemDepResult dep
) {
65 return InstTypePair(dep
.getInst(), Clobber
);
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
);
73 static InstTypePair
getInstTypePair(const Instruction
* inst
, DepType type
) {
74 return InstTypePair(inst
, type
);
79 char MemDepPrinter::ID
= 0;
80 INITIALIZE_PASS_BEGIN(MemDepPrinter
, "print-memdeps",
81 "Print MemDeps of function", false, true)
82 INITIALIZE_PASS_DEPENDENCY(MemoryDependenceWrapperPass
)
83 INITIALIZE_PASS_END(MemDepPrinter
, "print-memdeps",
84 "Print MemDeps of function", false, true)
86 FunctionPass
*llvm::createMemDepPrinter() {
87 return new MemDepPrinter();
90 const char *const MemDepPrinter::DepTypeStr
[]
91 = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
93 bool MemDepPrinter::runOnFunction(Function
&F
) {
95 MemoryDependenceResults
&MDA
= getAnalysis
<MemoryDependenceWrapperPass
>().getMemDep();
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
;
102 if (!Inst
->mayReadFromMemory() && !Inst
->mayWriteToMemory())
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
)) {
110 const MemoryDependenceResults::NonLocalDepInfo
&NLDI
=
111 MDA
.getNonLocalCallDependency(CS
);
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()));
119 SmallVector
<NonLocalDepResult
, 4> NLDI
;
120 assert( (isa
<LoadInst
>(Inst
) || isa
<StoreInst
>(Inst
) ||
121 isa
<VAArgInst
>(Inst
)) && "Unknown memory instruction!");
122 MDA
.getNonLocalPointerDependency(Inst
, NLDI
);
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()));
135 void MemDepPrinter::print(raw_ostream
&OS
, const Module
*M
) const {
136 for (const auto &I
: instructions(*F
)) {
137 const Instruction
*Inst
= &I
;
139 DepSetMap::const_iterator DI
= Deps
.find(Inst
);
140 if (DI
== Deps
.end())
143 const DepSet
&InstDeps
= DI
->second
;
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
;
151 OS
<< DepTypeStr
[type
];
154 DepBB
->printAsOperand(OS
, /*PrintType=*/false, M
);