]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Analysis/MemDepPrinter.cpp
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/Passes.h"
14 #include "llvm/ADT/SetVector.h"
15 #include "llvm/Analysis/MemoryDependenceAnalysis.h"
16 #include "llvm/Assembly/Writer.h"
17 #include "llvm/IR/LLVMContext.h"
18 #include "llvm/Support/CallSite.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/Support/InstIterator.h"
21 #include "llvm/Support/raw_ostream.h"
25 struct MemDepPrinter
: public FunctionPass
{
35 static const char *const DepTypeStr
[];
37 typedef PointerIntPair
<const Instruction
*, 2, DepType
> InstTypePair
;
38 typedef std::pair
<InstTypePair
, const BasicBlock
*> Dep
;
39 typedef SmallSetVector
<Dep
, 4> DepSet
;
40 typedef DenseMap
<const Instruction
*, DepSet
> DepSetMap
;
43 static char ID
; // Pass identifcation, replacement for typeid
44 MemDepPrinter() : FunctionPass(ID
) {
45 initializeMemDepPrinterPass(*PassRegistry::getPassRegistry());
48 virtual bool runOnFunction(Function
&F
);
50 void print(raw_ostream
&OS
, const Module
* = 0) const;
52 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
53 AU
.addRequiredTransitive
<AliasAnalysis
>();
54 AU
.addRequiredTransitive
<MemoryDependenceAnalysis
>();
58 virtual void releaseMemory() {
64 static InstTypePair
getInstTypePair(MemDepResult dep
) {
66 return InstTypePair(dep
.getInst(), Clobber
);
68 return InstTypePair(dep
.getInst(), Def
);
69 if (dep
.isNonFuncLocal())
70 return InstTypePair(dep
.getInst(), NonFuncLocal
);
71 assert(dep
.isUnknown() && "unexptected dependence type");
72 return InstTypePair(dep
.getInst(), Unknown
);
74 static InstTypePair
getInstTypePair(const Instruction
* inst
, DepType type
) {
75 return InstTypePair(inst
, type
);
80 char MemDepPrinter::ID
= 0;
81 INITIALIZE_PASS_BEGIN(MemDepPrinter
, "print-memdeps",
82 "Print MemDeps of function", false, true)
83 INITIALIZE_PASS_DEPENDENCY(MemoryDependenceAnalysis
)
84 INITIALIZE_PASS_END(MemDepPrinter
, "print-memdeps",
85 "Print MemDeps of function", false, true)
87 FunctionPass
*llvm::createMemDepPrinter() {
88 return new MemDepPrinter();
91 const char *const MemDepPrinter::DepTypeStr
[]
92 = {"Clobber", "Def", "NonFuncLocal", "Unknown"};
94 bool MemDepPrinter::runOnFunction(Function
&F
) {
96 AliasAnalysis
&AA
= getAnalysis
<AliasAnalysis
>();
97 MemoryDependenceAnalysis
&MDA
= getAnalysis
<MemoryDependenceAnalysis
>();
99 // All this code uses non-const interfaces because MemDep is not
100 // const-friendly, though nothing is actually modified.
101 for (inst_iterator I
= inst_begin(F
), E
= inst_end(F
); I
!= E
; ++I
) {
102 Instruction
*Inst
= &*I
;
104 if (!Inst
->mayReadFromMemory() && !Inst
->mayWriteToMemory())
107 MemDepResult Res
= MDA
.getDependency(Inst
);
108 if (!Res
.isNonLocal()) {
109 Deps
[Inst
].insert(std::make_pair(getInstTypePair(Res
),
110 static_cast<BasicBlock
*>(0)));
111 } else if (CallSite CS
= cast
<Value
>(Inst
)) {
112 const MemoryDependenceAnalysis::NonLocalDepInfo
&NLDI
=
113 MDA
.getNonLocalCallDependency(CS
);
115 DepSet
&InstDeps
= Deps
[Inst
];
116 for (MemoryDependenceAnalysis::NonLocalDepInfo::const_iterator
117 I
= NLDI
.begin(), E
= NLDI
.end(); I
!= E
; ++I
) {
118 const MemDepResult
&Res
= I
->getResult();
119 InstDeps
.insert(std::make_pair(getInstTypePair(Res
), I
->getBB()));
122 SmallVector
<NonLocalDepResult
, 4> NLDI
;
123 if (LoadInst
*LI
= dyn_cast
<LoadInst
>(Inst
)) {
124 if (!LI
->isUnordered()) {
125 // FIXME: Handle atomic/volatile loads.
126 Deps
[Inst
].insert(std::make_pair(getInstTypePair(0, Unknown
),
127 static_cast<BasicBlock
*>(0)));
130 AliasAnalysis::Location Loc
= AA
.getLocation(LI
);
131 MDA
.getNonLocalPointerDependency(Loc
, true, LI
->getParent(), NLDI
);
132 } else if (StoreInst
*SI
= dyn_cast
<StoreInst
>(Inst
)) {
133 if (!SI
->isUnordered()) {
134 // FIXME: Handle atomic/volatile stores.
135 Deps
[Inst
].insert(std::make_pair(getInstTypePair(0, Unknown
),
136 static_cast<BasicBlock
*>(0)));
139 AliasAnalysis::Location Loc
= AA
.getLocation(SI
);
140 MDA
.getNonLocalPointerDependency(Loc
, false, SI
->getParent(), NLDI
);
141 } else if (VAArgInst
*VI
= dyn_cast
<VAArgInst
>(Inst
)) {
142 AliasAnalysis::Location Loc
= AA
.getLocation(VI
);
143 MDA
.getNonLocalPointerDependency(Loc
, false, VI
->getParent(), NLDI
);
145 llvm_unreachable("Unknown memory instruction!");
148 DepSet
&InstDeps
= Deps
[Inst
];
149 for (SmallVectorImpl
<NonLocalDepResult
>::const_iterator
150 I
= NLDI
.begin(), E
= NLDI
.end(); I
!= E
; ++I
) {
151 const MemDepResult
&Res
= I
->getResult();
152 InstDeps
.insert(std::make_pair(getInstTypePair(Res
), I
->getBB()));
160 void MemDepPrinter::print(raw_ostream
&OS
, const Module
*M
) const {
161 for (const_inst_iterator I
= inst_begin(*F
), E
= inst_end(*F
); I
!= E
; ++I
) {
162 const Instruction
*Inst
= &*I
;
164 DepSetMap::const_iterator DI
= Deps
.find(Inst
);
165 if (DI
== Deps
.end())
168 const DepSet
&InstDeps
= DI
->second
;
170 for (DepSet::const_iterator I
= InstDeps
.begin(), E
= InstDeps
.end();
172 const Instruction
*DepInst
= I
->first
.getPointer();
173 DepType type
= I
->first
.getInt();
174 const BasicBlock
*DepBB
= I
->second
;
177 OS
<< DepTypeStr
[type
];
180 WriteAsOperand(OS
, DepBB
, /*PrintType=*/false, M
);