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/LLVMContext.h"
15 #include "llvm/Analysis/Passes.h"
16 #include "llvm/Assembly/Writer.h"
17 #include "llvm/Support/CallSite.h"
18 #include "llvm/Support/InstIterator.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/raw_ostream.h"
21 #include "llvm/ADT/SetVector.h"
25 struct MemDepPrinter
: public FunctionPass
{
28 typedef PointerIntPair
<const Instruction
*, 1> InstAndClobberFlag
;
29 typedef std::pair
<InstAndClobberFlag
, const BasicBlock
*> Dep
;
30 typedef SmallSetVector
<Dep
, 4> DepSet
;
31 typedef DenseMap
<const Instruction
*, DepSet
> DepSetMap
;
34 static char ID
; // Pass identifcation, replacement for typeid
35 MemDepPrinter() : FunctionPass(ID
) {
36 initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
39 virtual bool runOnFunction(Function
&F
);
41 void print(raw_ostream
&OS
, const Module
* = 0) const;
43 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
44 AU
.addRequiredTransitive
<AliasAnalysis
>();
45 AU
.addRequiredTransitive
<MemoryDependenceAnalysis
>();
49 virtual void releaseMemory() {
56 char MemDepPrinter::ID
= 0;
57 INITIALIZE_PASS_BEGIN(MemDepPrinter
, "print-memdeps",
58 "Print MemDeps of function", false, true)
59 INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis
)
60 INITIALIZE_PASS_END(MemDepPrinter
, "print-memdeps",
61 "Print MemDeps of function", false, true)
63 FunctionPass
*llvm::createMemDepPrinter() {
64 return new MemDepPrinter();
67 bool MemDepPrinter::runOnFunction(Function
&F
) {
69 AliasAnalysis
&AA
= getAnalysis
<AliasAnalysis
>();
70 MemoryDependenceAnalysis
&MDA
= getAnalysis
<MemoryDependenceAnalysis
>();
72 // All this code uses non-const interfaces because MemDep is not
73 // const-friendly, though nothing is actually modified.
74 for (inst_iterator I
= inst_begin(F
), E
= inst_end(F
); I
!= E
; ++I
) {
75 Instruction
*Inst
= &*I
;
77 if (!Inst
->mayReadFromMemory() && !Inst
->mayWriteToMemory())
80 MemDepResult Res
= MDA
.getDependency(Inst
);
81 if (!Res
.isNonLocal()) {
82 assert((Res
.isUnknown() || Res
.isClobber() || Res
.isDef()) &&
83 "Local dep should be unknown, def or clobber!");
84 Deps
[Inst
].insert(std::make_pair(InstAndClobberFlag(Res
.getInst(),
86 static_cast<BasicBlock
*>(0)));
87 } else if (CallSite CS
= cast
<Value
>(Inst
)) {
88 const MemoryDependenceAnalysis::NonLocalDepInfo
&NLDI
=
89 MDA
.getNonLocalCallDependency(CS
);
91 DepSet
&InstDeps
= Deps
[Inst
];
92 for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
93 I
= NLDI
.begin(), E
= NLDI
.end(); I
!= E
; ++I
) {
94 const MemDepResult
&Res
= I
->getResult();
95 assert((Res
.isUnknown() || Res
.isClobber() || Res
.isDef()) &&
96 "Resolved non-local call dep should be unknown, def or "
98 InstDeps
.insert(std::make_pair(InstAndClobberFlag(Res
.getInst(),
103 SmallVector
<NonLocalDepResult
, 4> NLDI
;
104 if (LoadInst
*LI
= dyn_cast
<LoadInst
>(Inst
)) {
105 // FIXME: Volatile is not handled properly here.
106 AliasAnalysis::Location Loc
= AA
.getLocation(LI
);
107 MDA
.getNonLocalPointerDependency(Loc
, !LI
->isVolatile(),
108 LI
->getParent(), NLDI
);
109 } else if (StoreInst
*SI
= dyn_cast
<StoreInst
>(Inst
)) {
110 // FIXME: Volatile is not handled properly here.
111 AliasAnalysis::Location Loc
= AA
.getLocation(SI
);
112 MDA
.getNonLocalPointerDependency(Loc
, false, SI
->getParent(), NLDI
);
113 } else if (VAArgInst
*VI
= dyn_cast
<VAArgInst
>(Inst
)) {
114 AliasAnalysis::Location Loc
= AA
.getLocation(VI
);
115 MDA
.getNonLocalPointerDependency(Loc
, false, VI
->getParent(), NLDI
);
117 llvm_unreachable("Unknown memory instruction!");
120 DepSet
&InstDeps
= Deps
[Inst
];
121 for (SmallVectorImpl
<NonLocalDepResult
>::const_iterator
122 I
= NLDI
.begin(), E
= NLDI
.end(); I
!= E
; ++I
) {
123 const MemDepResult
&Res
= I
->getResult();
124 assert(Res
.isClobber() != Res
.isDef() &&
125 "Resolved non-local pointer dep should be def or clobber!");
126 InstDeps
.insert(std::make_pair(InstAndClobberFlag(Res
.getInst(),
136 void MemDepPrinter::print(raw_ostream
&OS
, const Module
*M
) const {
137 for (const_inst_iterator I
= inst_begin(*F
), E
= inst_end(*F
); I
!= E
; ++I
) {
138 const Instruction
*Inst
= &*I
;
140 DepSetMap::const_iterator DI
= Deps
.find(Inst
);
141 if (DI
== Deps
.end())
144 const DepSet
&InstDeps
= DI
->second
;
146 for (DepSet::const_iterator I
= InstDeps
.begin(), E
= InstDeps
.end();
148 const Instruction
*DepInst
= I
->first
.getPointer();
149 bool isClobber
= I
->first
.getInt();
150 const BasicBlock
*DepBB
= I
->second
;
161 WriteAsOperand(OS
, DepBB
, /*PrintType=*/false, M
);
166 OS
<< "<unspecified>";