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/Analysis/MemoryDependenceAnalysis.h"
14 #include "llvm/Analysis/Passes.h"
15 #include "llvm/Assembly/Writer.h"
16 #include "llvm/Support/CallSite.h"
17 #include "llvm/Support/InstIterator.h"
18 #include "llvm/Support/ErrorHandling.h"
19 #include "llvm/Support/raw_ostream.h"
20 #include "llvm/ADT/SetVector.h"
24 struct MemDepPrinter
: public FunctionPass
{
27 typedef PointerIntPair
<const Instruction
*, 1> InstAndClobberFlag
;
28 typedef std::pair
<InstAndClobberFlag
, const BasicBlock
*> Dep
;
29 typedef SmallSetVector
<Dep
, 4> DepSet
;
30 typedef DenseMap
<const Instruction
*, DepSet
> DepSetMap
;
33 static char ID
; // Pass identifcation, replacement for typeid
34 MemDepPrinter() : FunctionPass(ID
) {
35 initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
38 virtual bool runOnFunction(Function
&F
);
40 void print(raw_ostream
&OS
, const Module
* = 0) const;
42 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
43 AU
.addRequired
<MemoryDependenceAnalysis
>();
47 virtual void releaseMemory() {
54 char MemDepPrinter::ID
= 0;
55 INITIALIZE_PASS_BEGIN(MemDepPrinter
, "print-memdeps",
56 "Print MemDeps of function", false, true)
57 INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis
)
58 INITIALIZE_PASS_END(MemDepPrinter
, "print-memdeps",
59 "Print MemDeps of function", false, true)
61 FunctionPass
*llvm::createMemDepPrinter() {
62 return new MemDepPrinter();
65 bool MemDepPrinter::runOnFunction(Function
&F
) {
67 MemoryDependenceAnalysis
&MDA
= getAnalysis
<MemoryDependenceAnalysis
>();
69 // All this code uses non-const interfaces because MemDep is not
70 // const-friendly, though nothing is actually modified.
71 for (inst_iterator I
= inst_begin(F
), E
= inst_end(F
); I
!= E
; ++I
) {
72 Instruction
*Inst
= &*I
;
74 if (!Inst
->mayReadFromMemory() && !Inst
->mayWriteToMemory())
77 MemDepResult Res
= MDA
.getDependency(Inst
);
78 if (!Res
.isNonLocal()) {
79 assert(Res
.isClobber() != Res
.isDef() &&
80 "Local dep should be def or clobber!");
81 Deps
[Inst
].insert(std::make_pair(InstAndClobberFlag(Res
.getInst(),
83 static_cast<BasicBlock
*>(0)));
84 } else if (CallSite CS
= cast
<Value
>(Inst
)) {
85 const MemoryDependenceAnalysis::NonLocalDepInfo
&NLDI
=
86 MDA
.getNonLocalCallDependency(CS
);
88 DepSet
&InstDeps
= Deps
[Inst
];
89 for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
90 I
= NLDI
.begin(), E
= NLDI
.end(); I
!= E
; ++I
) {
91 const MemDepResult
&Res
= I
->getResult();
92 assert(Res
.isClobber() != Res
.isDef() &&
93 "Resolved non-local call dep should be def or clobber!");
94 InstDeps
.insert(std::make_pair(InstAndClobberFlag(Res
.getInst(),
99 SmallVector
<NonLocalDepResult
, 4> NLDI
;
100 if (LoadInst
*LI
= dyn_cast
<LoadInst
>(Inst
)) {
101 // FIXME: Volatile is not handled properly here.
102 MDA
.getNonLocalPointerDependency(LI
->getPointerOperand(), !LI
->isVolatile(),
103 LI
->getParent(), NLDI
);
104 } else if (StoreInst
*SI
= dyn_cast
<StoreInst
>(Inst
)) {
105 // FIXME: Volatile is not handled properly here.
106 MDA
.getNonLocalPointerDependency(SI
->getPointerOperand(), false,
107 SI
->getParent(), NLDI
);
108 } else if (VAArgInst
*VI
= dyn_cast
<VAArgInst
>(Inst
)) {
109 MDA
.getNonLocalPointerDependency(VI
->getPointerOperand(), false,
110 VI
->getParent(), NLDI
);
112 llvm_unreachable("Unknown memory instruction!");
115 DepSet
&InstDeps
= Deps
[Inst
];
116 for (SmallVectorImpl
<NonLocalDepResult
>::const_iterator
117 I
= NLDI
.begin(), E
= NLDI
.end(); I
!= E
; ++I
) {
118 const MemDepResult
&Res
= I
->getResult();
119 assert(Res
.isClobber() != Res
.isDef() &&
120 "Resolved non-local pointer dep should be def or clobber!");
121 InstDeps
.insert(std::make_pair(InstAndClobberFlag(Res
.getInst(),
131 void MemDepPrinter::print(raw_ostream
&OS
, const Module
*M
) const {
132 for (const_inst_iterator I
= inst_begin(*F
), E
= inst_end(*F
); I
!= E
; ++I
) {
133 const Instruction
*Inst
= &*I
;
135 DepSetMap::const_iterator DI
= Deps
.find(Inst
);
136 if (DI
== Deps
.end())
139 const DepSet
&InstDeps
= DI
->second
;
141 for (DepSet::const_iterator I
= InstDeps
.begin(), E
= InstDeps
.end();
143 const Instruction
*DepInst
= I
->first
.getPointer();
144 bool isClobber
= I
->first
.getInt();
145 const BasicBlock
*DepBB
= I
->second
;
147 OS
<< " " << (isClobber
? "Clobber" : " Def");
150 WriteAsOperand(OS
, DepBB
, /*PrintType=*/false, M
);
154 OS
<< "<unspecified>";