1 //===- AliasAnalysisEvaluator.cpp - Alias Analysis Accuracy Evaluator -----===//
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 //===----------------------------------------------------------------------===//
10 // This file implements a simple N^2 alias analysis accuracy evaluator.
11 // Basically, for each function in the program, it simply queries to see how the
12 // alias analysis implementation answers alias queries between each pair of
13 // pointers in the function.
15 // This is inspired and adapted from code by: Naveen Neelakantam, Francesco
16 // Spadini, and Wojciech Stryjewski.
18 //===----------------------------------------------------------------------===//
20 #include "llvm/Constants.h"
21 #include "llvm/DerivedTypes.h"
22 #include "llvm/Function.h"
23 #include "llvm/Instructions.h"
24 #include "llvm/Pass.h"
25 #include "llvm/Analysis/Passes.h"
26 #include "llvm/Analysis/AliasAnalysis.h"
27 #include "llvm/Assembly/Writer.h"
28 #include "llvm/Target/TargetData.h"
29 #include "llvm/Support/InstIterator.h"
30 #include "llvm/Support/CommandLine.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/Streams.h"
37 static cl::opt
<bool> PrintAll("print-all-alias-modref-info", cl::ReallyHidden
);
39 static cl::opt
<bool> PrintNoAlias("print-no-aliases", cl::ReallyHidden
);
40 static cl::opt
<bool> PrintMayAlias("print-may-aliases", cl::ReallyHidden
);
41 static cl::opt
<bool> PrintMustAlias("print-must-aliases", cl::ReallyHidden
);
43 static cl::opt
<bool> PrintNoModRef("print-no-modref", cl::ReallyHidden
);
44 static cl::opt
<bool> PrintMod("print-mod", cl::ReallyHidden
);
45 static cl::opt
<bool> PrintRef("print-ref", cl::ReallyHidden
);
46 static cl::opt
<bool> PrintModRef("print-modref", cl::ReallyHidden
);
49 class VISIBILITY_HIDDEN AAEval
: public FunctionPass
{
50 unsigned NoAlias
, MayAlias
, MustAlias
;
51 unsigned NoModRef
, Mod
, Ref
, ModRef
;
54 static char ID
; // Pass identification, replacement for typeid
55 AAEval() : FunctionPass(&ID
) {}
57 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
58 AU
.addRequired
<AliasAnalysis
>();
62 bool doInitialization(Module
&M
) {
63 NoAlias
= MayAlias
= MustAlias
= 0;
64 NoModRef
= Mod
= Ref
= ModRef
= 0;
67 PrintNoAlias
= PrintMayAlias
= PrintMustAlias
= true;
68 PrintNoModRef
= PrintMod
= PrintRef
= PrintModRef
= true;
73 bool runOnFunction(Function
&F
);
74 bool doFinalization(Module
&M
);
79 static RegisterPass
<AAEval
>
80 X("aa-eval", "Exhaustive Alias Analysis Precision Evaluator", false, true);
82 FunctionPass
*llvm::createAAEvalPass() { return new AAEval(); }
84 static void PrintResults(const char *Msg
, bool P
, const Value
*V1
, const Value
*V2
,
87 std::stringstream s1
, s2
;
88 WriteAsOperand(s1
, V1
, true, M
);
89 WriteAsOperand(s2
, V2
, true, M
);
90 std::string
o1(s1
.str()), o2(s2
.str());
93 cerr
<< " " << Msg
<< ":\t"
100 PrintModRefResults(const char *Msg
, bool P
, Instruction
*I
, Value
*Ptr
,
103 cerr
<< " " << Msg
<< ": Ptr: ";
104 WriteAsOperand(*cerr
.stream(), Ptr
, true, M
);
105 cerr
<< "\t<->" << *I
;
109 bool AAEval::runOnFunction(Function
&F
) {
110 AliasAnalysis
&AA
= getAnalysis
<AliasAnalysis
>();
112 const TargetData
&TD
= AA
.getTargetData();
114 std::set
<Value
*> Pointers
;
115 std::set
<CallSite
> CallSites
;
117 for (Function::arg_iterator I
= F
.arg_begin(), E
= F
.arg_end(); I
!= E
; ++I
)
118 if (isa
<PointerType
>(I
->getType())) // Add all pointer arguments
121 for (inst_iterator I
= inst_begin(F
), E
= inst_end(F
); I
!= E
; ++I
) {
122 if (isa
<PointerType
>(I
->getType())) // Add all pointer instructions
123 Pointers
.insert(&*I
);
124 Instruction
&Inst
= *I
;
125 User::op_iterator OI
= Inst
.op_begin();
126 CallSite CS
= CallSite::get(&Inst
);
127 if (CS
.getInstruction() &&
128 isa
<Function
>(CS
.getCalledValue()))
129 ++OI
; // Skip actual functions for direct function calls.
130 for (; OI
!= Inst
.op_end(); ++OI
)
131 if (isa
<PointerType
>((*OI
)->getType()) && !isa
<ConstantPointerNull
>(*OI
))
132 Pointers
.insert(*OI
);
134 if (CS
.getInstruction()) CallSites
.insert(CS
);
137 if (PrintNoAlias
|| PrintMayAlias
|| PrintMustAlias
||
138 PrintNoModRef
|| PrintMod
|| PrintRef
|| PrintModRef
)
139 cerr
<< "Function: " << F
.getName() << ": " << Pointers
.size()
140 << " pointers, " << CallSites
.size() << " call sites\n";
142 // iterate over the worklist, and run the full (n^2)/2 disambiguations
143 for (std::set
<Value
*>::iterator I1
= Pointers
.begin(), E
= Pointers
.end();
146 const Type
*I1ElTy
= cast
<PointerType
>((*I1
)->getType())->getElementType();
147 if (I1ElTy
->isSized()) I1Size
= TD
.getTypeStoreSize(I1ElTy
);
149 for (std::set
<Value
*>::iterator I2
= Pointers
.begin(); I2
!= I1
; ++I2
) {
151 const Type
*I2ElTy
=cast
<PointerType
>((*I2
)->getType())->getElementType();
152 if (I2ElTy
->isSized()) I2Size
= TD
.getTypeStoreSize(I2ElTy
);
154 switch (AA
.alias(*I1
, I1Size
, *I2
, I2Size
)) {
155 case AliasAnalysis::NoAlias
:
156 PrintResults("NoAlias", PrintNoAlias
, *I1
, *I2
, F
.getParent());
158 case AliasAnalysis::MayAlias
:
159 PrintResults("MayAlias", PrintMayAlias
, *I1
, *I2
, F
.getParent());
161 case AliasAnalysis::MustAlias
:
162 PrintResults("MustAlias", PrintMustAlias
, *I1
, *I2
, F
.getParent());
165 cerr
<< "Unknown alias query result!\n";
170 // Mod/ref alias analysis: compare all pairs of calls and values
171 for (std::set
<CallSite
>::iterator C
= CallSites
.begin(),
172 Ce
= CallSites
.end(); C
!= Ce
; ++C
) {
173 Instruction
*I
= C
->getInstruction();
175 for (std::set
<Value
*>::iterator V
= Pointers
.begin(), Ve
= Pointers
.end();
178 const Type
*ElTy
= cast
<PointerType
>((*V
)->getType())->getElementType();
179 if (ElTy
->isSized()) Size
= TD
.getTypeStoreSize(ElTy
);
181 switch (AA
.getModRefInfo(*C
, *V
, Size
)) {
182 case AliasAnalysis::NoModRef
:
183 PrintModRefResults("NoModRef", PrintNoModRef
, I
, *V
, F
.getParent());
185 case AliasAnalysis::Mod
:
186 PrintModRefResults(" Mod", PrintMod
, I
, *V
, F
.getParent());
188 case AliasAnalysis::Ref
:
189 PrintModRefResults(" Ref", PrintRef
, I
, *V
, F
.getParent());
191 case AliasAnalysis::ModRef
:
192 PrintModRefResults(" ModRef", PrintModRef
, I
, *V
, F
.getParent());
195 cerr
<< "Unknown alias query result!\n";
203 static void PrintPercent(unsigned Num
, unsigned Sum
) {
204 cerr
<< "(" << Num
*100ULL/Sum
<< "."
205 << ((Num
*1000ULL/Sum
) % 10) << "%)\n";
208 bool AAEval::doFinalization(Module
&M
) {
209 unsigned AliasSum
= NoAlias
+ MayAlias
+ MustAlias
;
210 cerr
<< "===== Alias Analysis Evaluator Report =====\n";
212 cerr
<< " Alias Analysis Evaluator Summary: No pointers!\n";
214 cerr
<< " " << AliasSum
<< " Total Alias Queries Performed\n";
215 cerr
<< " " << NoAlias
<< " no alias responses ";
216 PrintPercent(NoAlias
, AliasSum
);
217 cerr
<< " " << MayAlias
<< " may alias responses ";
218 PrintPercent(MayAlias
, AliasSum
);
219 cerr
<< " " << MustAlias
<< " must alias responses ";
220 PrintPercent(MustAlias
, AliasSum
);
221 cerr
<< " Alias Analysis Evaluator Pointer Alias Summary: "
222 << NoAlias
*100/AliasSum
<< "%/" << MayAlias
*100/AliasSum
<< "%/"
223 << MustAlias
*100/AliasSum
<< "%\n";
226 // Display the summary for mod/ref analysis
227 unsigned ModRefSum
= NoModRef
+ Mod
+ Ref
+ ModRef
;
228 if (ModRefSum
== 0) {
229 cerr
<< " Alias Analysis Mod/Ref Evaluator Summary: no mod/ref!\n";
231 cerr
<< " " << ModRefSum
<< " Total ModRef Queries Performed\n";
232 cerr
<< " " << NoModRef
<< " no mod/ref responses ";
233 PrintPercent(NoModRef
, ModRefSum
);
234 cerr
<< " " << Mod
<< " mod responses ";
235 PrintPercent(Mod
, ModRefSum
);
236 cerr
<< " " << Ref
<< " ref responses ";
237 PrintPercent(Ref
, ModRefSum
);
238 cerr
<< " " << ModRef
<< " mod & ref responses ";
239 PrintPercent(ModRef
, ModRefSum
);
240 cerr
<< " Alias Analysis Evaluator Mod/Ref Summary: "
241 << NoModRef
*100/ModRefSum
<< "%/" << Mod
*100/ModRefSum
<< "%/"
242 << Ref
*100/ModRefSum
<< "%/" << ModRef
*100/ModRefSum
<< "%\n";