1 //===- ProfileInfoLoaderPass.cpp - LLVM Pass to load profile info ---------===//
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 concrete implementation of profiling information that
11 // loads the information from a profile dump file.
13 //===----------------------------------------------------------------------===//
14 #define DEBUG_TYPE "profile-loader"
15 #include "llvm/BasicBlock.h"
16 #include "llvm/InstrTypes.h"
17 #include "llvm/Module.h"
18 #include "llvm/Pass.h"
19 #include "llvm/Analysis/Passes.h"
20 #include "llvm/Analysis/ProfileInfo.h"
21 #include "llvm/Analysis/ProfileInfoLoader.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/CFG.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/raw_ostream.h"
26 #include "llvm/Support/Format.h"
27 #include "llvm/ADT/Statistic.h"
28 #include "llvm/ADT/SmallSet.h"
32 STATISTIC(NumEdgesRead
, "The # of edges read.");
34 static cl::opt
<std::string
>
35 ProfileInfoFilename("profile-info-file", cl::init("llvmprof.out"),
36 cl::value_desc("filename"),
37 cl::desc("Profile file loaded by -profile-loader"));
40 class LoaderPass
: public ModulePass
, public ProfileInfo
{
42 std::set
<Edge
> SpanningTree
;
43 std::set
<const BasicBlock
*> BBisUnvisited
;
46 static char ID
; // Class identification, replacement for typeinfo
47 explicit LoaderPass(const std::string
&filename
= "")
48 : ModulePass(ID
), Filename(filename
) {
49 initializeLoaderPassPass(*PassRegistry::getPassRegistry());
50 if (filename
.empty()) Filename
= ProfileInfoFilename
;
53 virtual void getAnalysisUsage(AnalysisUsage
&AU
) const {
57 virtual const char *getPassName() const {
58 return "Profiling information loader";
61 // recurseBasicBlock() - Calculates the edge weights for as much basic
62 // blocks as possbile.
63 virtual void recurseBasicBlock(const BasicBlock
*BB
);
64 virtual void readEdgeOrRemember(Edge
, Edge
&, unsigned &, double &);
65 virtual void readEdge(ProfileInfo::Edge
, std::vector
<unsigned>&);
67 /// getAdjustedAnalysisPointer - This method is used when a pass implements
68 /// an analysis interface through multiple inheritance. If needed, it
69 /// should override this to adjust the this pointer as needed for the
70 /// specified pass info.
71 virtual void *getAdjustedAnalysisPointer(AnalysisID PI
) {
72 if (PI
== &ProfileInfo::ID
)
73 return (ProfileInfo
*)this;
77 /// run - Load the profile information from the specified file.
78 virtual bool runOnModule(Module
&M
);
80 } // End of anonymous namespace
82 char LoaderPass::ID
= 0;
83 INITIALIZE_AG_PASS(LoaderPass
, ProfileInfo
, "profile-loader",
84 "Load profile information from llvmprof.out", false, true, false)
86 char &llvm::ProfileLoaderPassID
= LoaderPass::ID
;
88 ModulePass
*llvm::createProfileLoaderPass() { return new LoaderPass(); }
90 /// createProfileLoaderPass - This function returns a Pass that loads the
91 /// profiling information for the module from the specified filename, making it
92 /// available to the optimizers.
93 Pass
*llvm::createProfileLoaderPass(const std::string
&Filename
) {
94 return new LoaderPass(Filename
);
97 void LoaderPass::readEdgeOrRemember(Edge edge
, Edge
&tocalc
,
98 unsigned &uncalc
, double &count
) {
100 if ((w
= getEdgeWeight(edge
)) == MissingValue
) {
108 // recurseBasicBlock - Visits all neighbours of a block and then tries to
109 // calculate the missing edge values.
110 void LoaderPass::recurseBasicBlock(const BasicBlock
*BB
) {
112 // break recursion if already visited
113 if (BBisUnvisited
.find(BB
) == BBisUnvisited
.end()) return;
114 BBisUnvisited
.erase(BB
);
117 for (succ_const_iterator bbi
= succ_begin(BB
), bbe
= succ_end(BB
);
119 recurseBasicBlock(*bbi
);
121 for (const_pred_iterator bbi
= pred_begin(BB
), bbe
= pred_end(BB
);
123 recurseBasicBlock(*bbi
);
127 if (CalculateMissingEdge(BB
, tocalc
)) {
128 SpanningTree
.erase(tocalc
);
132 void LoaderPass::readEdge(ProfileInfo::Edge e
,
133 std::vector
<unsigned> &ECs
) {
134 if (ReadCount
< ECs
.size()) {
135 double weight
= ECs
[ReadCount
++];
136 if (weight
!= ProfileInfoLoader::Uncounted
) {
137 // Here the data realm changes from the unsigned of the file to the
138 // double of the ProfileInfo. This conversion is save because we know
139 // that everything thats representable in unsinged is also representable
141 EdgeInformation
[getFunction(e
)][e
] += (double)weight
;
143 DEBUG(dbgs() << "--Read Edge Counter for " << e
144 << " (# "<< (ReadCount
-1) << "): "
145 << (unsigned)getEdgeWeight(e
) << "\n");
147 // This happens only if reading optimal profiling information, not when
148 // reading regular profiling information.
149 SpanningTree
.insert(e
);
154 bool LoaderPass::runOnModule(Module
&M
) {
155 ProfileInfoLoader
PIL("profile-loader", Filename
, M
);
157 EdgeInformation
.clear();
158 std::vector
<unsigned> Counters
= PIL
.getRawEdgeCounts();
159 if (Counters
.size() > 0) {
161 for (Module::iterator F
= M
.begin(), E
= M
.end(); F
!= E
; ++F
) {
162 if (F
->isDeclaration()) continue;
163 DEBUG(dbgs()<<"Working on "<<F
->getNameStr()<<"\n");
164 readEdge(getEdge(0,&F
->getEntryBlock()), Counters
);
165 for (Function::iterator BB
= F
->begin(), E
= F
->end(); BB
!= E
; ++BB
) {
166 TerminatorInst
*TI
= BB
->getTerminator();
167 for (unsigned s
= 0, e
= TI
->getNumSuccessors(); s
!= e
; ++s
) {
168 readEdge(getEdge(BB
,TI
->getSuccessor(s
)), Counters
);
172 if (ReadCount
!= Counters
.size()) {
173 errs() << "WARNING: profile information is inconsistent with "
174 << "the current program!\n";
176 NumEdgesRead
= ReadCount
;
179 Counters
= PIL
.getRawOptimalEdgeCounts();
180 if (Counters
.size() > 0) {
182 for (Module::iterator F
= M
.begin(), E
= M
.end(); F
!= E
; ++F
) {
183 if (F
->isDeclaration()) continue;
184 DEBUG(dbgs()<<"Working on "<<F
->getNameStr()<<"\n");
185 readEdge(getEdge(0,&F
->getEntryBlock()), Counters
);
186 for (Function::iterator BB
= F
->begin(), E
= F
->end(); BB
!= E
; ++BB
) {
187 TerminatorInst
*TI
= BB
->getTerminator();
188 if (TI
->getNumSuccessors() == 0) {
189 readEdge(getEdge(BB
,0), Counters
);
191 for (unsigned s
= 0, e
= TI
->getNumSuccessors(); s
!= e
; ++s
) {
192 readEdge(getEdge(BB
,TI
->getSuccessor(s
)), Counters
);
195 while (SpanningTree
.size() > 0) {
197 unsigned size
= SpanningTree
.size();
199 BBisUnvisited
.clear();
200 for (std::set
<Edge
>::iterator ei
= SpanningTree
.begin(),
201 ee
= SpanningTree
.end(); ei
!= ee
; ++ei
) {
202 BBisUnvisited
.insert(ei
->first
);
203 BBisUnvisited
.insert(ei
->second
);
205 while (BBisUnvisited
.size() > 0) {
206 recurseBasicBlock(*BBisUnvisited
.begin());
209 if (SpanningTree
.size() == size
) {
211 for (std::set
<Edge
>::iterator ei
= SpanningTree
.begin(),
212 ee
= SpanningTree
.end(); ei
!= ee
; ++ei
) {
213 DEBUG(dbgs()<< *ei
<<",");
215 assert(0 && "No edge calculated!");
220 if (ReadCount
!= Counters
.size()) {
221 errs() << "WARNING: profile information is inconsistent with "
222 << "the current program!\n";
224 NumEdgesRead
= ReadCount
;
227 BlockInformation
.clear();
228 Counters
= PIL
.getRawBlockCounts();
229 if (Counters
.size() > 0) {
231 for (Module::iterator F
= M
.begin(), E
= M
.end(); F
!= E
; ++F
) {
232 if (F
->isDeclaration()) continue;
233 for (Function::iterator BB
= F
->begin(), E
= F
->end(); BB
!= E
; ++BB
)
234 if (ReadCount
< Counters
.size())
235 // Here the data realm changes from the unsigned of the file to the
236 // double of the ProfileInfo. This conversion is save because we know
237 // that everything thats representable in unsinged is also
238 // representable in double.
239 BlockInformation
[F
][BB
] = (double)Counters
[ReadCount
++];
241 if (ReadCount
!= Counters
.size()) {
242 errs() << "WARNING: profile information is inconsistent with "
243 << "the current program!\n";
247 FunctionInformation
.clear();
248 Counters
= PIL
.getRawFunctionCounts();
249 if (Counters
.size() > 0) {
251 for (Module::iterator F
= M
.begin(), E
= M
.end(); F
!= E
; ++F
) {
252 if (F
->isDeclaration()) continue;
253 if (ReadCount
< Counters
.size())
254 // Here the data realm changes from the unsigned of the file to the
255 // double of the ProfileInfo. This conversion is save because we know
256 // that everything thats representable in unsinged is also
257 // representable in double.
258 FunctionInformation
[F
] = (double)Counters
[ReadCount
++];
260 if (ReadCount
!= Counters
.size()) {
261 errs() << "WARNING: profile information is inconsistent with "
262 << "the current program!\n";