1 #ifndef _QPROF_COMMON_H
2 #define _QPROF_COMMON_H
5 #include <common/util/stdlib.h>
11 #define QPROF_DECLARE_LL_SITESTACKS_OPT(P, VAR) \
12 static cl::opt<std::string> \
13 VAR(#P "-ll-sitestacks", \
14 cl::desc("Specify all the long-lived sitestacks on a per-task basis in qprof format"), \
15 cl::init(""), cl::NotHidden, cl::ValueRequired)
17 #define QPROF_DECLARE_DEEPEST_LL_LOOPS_OPT(P, VAR) \
18 static cl::opt<std::string> \
19 VAR(#P "-deepest-ll-loops", \
20 cl::desc("Specify all the deepest long-lived loops on a per-task basis in qprof format"), \
21 cl::init(""), cl::NotHidden, cl::ValueRequired)
23 #define QPROF_DECLARE_DEEPEST_LL_LIBS_OPT(P, VAR) \
24 static cl::opt<std::string> \
25 VAR(#P "-deepest-ll-libs", \
26 cl::desc("Specify all the deepest long-lived loop lib calls on a per-task basis in qprof format"), \
27 cl::init(""), cl::NotHidden, cl::ValueRequired)
29 #define QPROF_DECLARE_TASK_CLASSES_OPT(P, VAR) \
30 static cl::opt<std::string> \
31 VAR(#P "-task-classes", \
32 cl::desc("Specify all the task classes in qprof format"), \
33 cl::init(""), cl::NotHidden, cl::ValueRequired)
35 #define QPROF_DECLARE_ALL_OPTS(P, VAR1, VAR2, VAR3, VAR4) \
36 QPROF_DECLARE_LL_SITESTACKS_OPT(P, VAR1); \
37 QPROF_DECLARE_DEEPEST_LL_LOOPS_OPT(P, VAR2); \
38 QPROF_DECLARE_DEEPEST_LL_LIBS_OPT(P, VAR3); \
39 QPROF_DECLARE_TASK_CLASSES_OPT(P, VAR4) \
47 static QProfSite
* get(Module
&M
, int taskClassID
, int taskSiteID
, std::string moduleName
, int lineNum
, std::string functionName
, std::string siteName
, std::string siteFuncName
, int siteDepth
, int lib
, unsigned long libFlags
, bool refreshSite
=true);
48 static QProfSite
* getFromString(Module
&M
, int taskClassID
, int taskSiteID
, std::string
&siteString
, bool refreshSite
=true);
49 static std::vector
<QProfSite
*> getFromSitesString(Module
&M
, std::string
&sitesString
, bool refreshSites
=true);
51 void refresh(Module
&M
);
52 std::string
toString();
57 bool equals(QProfSite
*other
);
61 std::string moduleName
;
63 std::string functionName
;
65 std::string siteFuncName
;
66 unsigned long libFlags
;
68 Function
*siteFunction
;
69 Instruction
*siteInstruction
;
79 static QProfConf
* get(Module
&M
, std::string
*llSitestacks
, std::string
*deepestLLLoops
, std::string
*deepestLLLibs
, std::string
*taskClasses
, bool refreshSites
=true);
81 std::map
<int, std::vector
<QProfSite
*> > getTaskClassLLSitestacks();
82 std::map
<int, QProfSite
*> getTaskClassDeepestLLLoops();
83 std::map
<int, std::vector
<QProfSite
*> > getTaskClassDeepestLLLibs();
84 int getNumTaskClasses();
85 int getNumLLTaskClasses();
86 int getNumLLBlockExtTaskClasses();
87 int getNumLLBlockIntTaskClasses();
88 int getNumLLBlockExtLibs();
89 int getNumLLBlockIntLibs();
91 std::vector
<QProfSite
*> getLLFunctions();
92 std::vector
<QProfSite
*> getDeepestLLLoops();
93 std::vector
<QProfSite
*> getDeepestLLLibs();
94 bool lookupTaskClassLibFlags(int taskClassID
, int *libFlags
);
95 void mergeTaskClassLLSitestacks(int taskClassID
, int otherTaskClassID
);
96 void mergeTaskClassDeepestLLLoops(int taskClassID
, int otherTaskClassID
);
97 void mergeTaskClassDeepestLLLibs(int taskClassID
, int otherTaskClassID
);
98 void mergeTaskClassPair(int taskClassID
, int otherTaskClassID
);
99 void mergeAllTaskClassesWithSameDeepestLLLoops();
100 void print(raw_ostream
&O
);
101 void printSiteList(raw_ostream
&O
, std::vector
<QProfSite
*> &list
);
106 static std::map
<int, std::vector
<QProfSite
*> > parseTaskClassSiteList(Module
&M
, std::string
&str
, bool refreshSites
=true);
107 static std::map
<int, QProfSite
*> parseTaskClassSite(Module
&M
, std::string
&str
, bool refreshSites
=true);
108 static std::vector
<int> parseIntList(std::string
&str
);
110 std::map
<int, std::vector
<QProfSite
*> > taskClassLLSitestacks
;
111 std::map
<int, QProfSite
*> taskClassDeepestLLLoops
;
112 std::map
<int, std::vector
<QProfSite
*> > taskClassDeepestLLLibs
;
114 int numLLTaskClasses
;
115 int numLLBlockExtTaskClasses
;
116 int numLLBlockIntTaskClasses
;
117 int numLLBlockExtLibs
;
118 int numLLBlockIntLibs
;
121 static int stringRefToInt(StringRef
&ref
)
123 return atoi(ref
.str().c_str());
126 inline QProfSite
* QProfSite::get(Module
&M
, int taskClassID
, int taskSiteID
,
127 std::string moduleName
, int lineNum
, std::string functionName
,
128 std::string siteName
, std::string siteFuncName
, int siteDepth
, int lib
,
129 unsigned long libFlags
, bool refreshSite
)
131 QProfSite
*site
= new QProfSite();
132 site
->taskClassID
= taskClassID
;
133 site
->taskSiteID
= taskSiteID
;
134 site
->moduleName
= moduleName
;
135 site
->lineNum
= lineNum
;
136 site
->functionName
= functionName
;
137 site
->siteName
= siteName
;
138 site
->siteFuncName
= siteFuncName
;
139 site
->siteDepth
= siteDepth
;
141 site
->libFlags
= libFlags
;
142 site
->function
= NULL
;
143 site
->siteFunction
= NULL
;
144 site
->siteInstruction
= NULL
;
152 inline QProfSite
* QProfSite::getFromString(Module
&M
, int taskClassID
, int taskSiteID
,
153 std::string
&siteString
, bool refreshSite
)
155 StringRef
ref(siteString
);
156 SmallVector
< StringRef
, 3 > tokenVector
;
157 if (!siteString
.compare("")) {
160 ref
.split(tokenVector
, QPROF_SEP3
);
161 assert(tokenVector
.size() == 8);
162 return get(M
, taskClassID
, taskSiteID
, tokenVector
[0], stringRefToInt(tokenVector
[1]),
163 tokenVector
[2], tokenVector
[3], tokenVector
[4],
164 stringRefToInt(tokenVector
[5]), stringRefToInt(tokenVector
[6]),
165 stringRefToInt(tokenVector
[7]), refreshSite
);
168 inline std::vector
<QProfSite
*> QProfSite::getFromSitesString(Module
&M
,
169 std::string
&sitesString
, bool refreshSites
)
173 std::vector
<QProfSite
*> sites
;
174 StringRef
ref(sitesString
);
175 SmallVector
< StringRef
, 3 > tokenVector
;
176 if (!sitesString
.compare("")) {
179 ref
.split(tokenVector
, QPROF_SEP2
);
180 assert(tokenVector
.size() > 1);
181 taskClassID
= stringRefToInt(tokenVector
[0]);
182 for (i
=1;i
<tokenVector
.size();i
++) {
183 std::string token
= tokenVector
[i
].str();
184 QProfSite
*site
= QProfSite::getFromString(M
, taskClassID
, i
, token
,
186 sites
.push_back(site
);
191 inline void QProfSite::refresh(Module
&M
)
193 BasicBlock
*siteBB
= NULL
;
196 siteInstruction
= NULL
;
197 function
= M
.getFunction(functionName
);
198 siteFunction
= M
.getFunction(siteFuncName
);
200 errs() << "Function " << siteFuncName
<< " not found. Invalid qprof profiling data?\n";
202 assert(siteFunction
);
203 for (Function::iterator BB
= siteFunction
->begin(),
204 e
= siteFunction
->end(); BB
!= e
; ++BB
) {
205 if (!BB
->getName().compare(siteName
)) {
212 for (BasicBlock::iterator it
= siteBB
->begin(); it
!= siteBB
->end(); ++it
) {
214 if (CS
.getInstruction() && CS
.getCalledFunction() == function
) {
215 siteInstruction
= it
;
219 assert(siteInstruction
&& "Invalid qprof callsite?");
222 siteInstruction
= &siteBB
->front();
226 inline std::string
QProfSite::toString()
229 raw_string_ostream
ostream(str
);
230 ostream
<< taskClassID
<< QPROF_SEP3
<< taskSiteID
<< QPROF_SEP3
<< moduleName
<< QPROF_SEP3
<< lineNum
<< QPROF_SEP3
<< functionName
<< QPROF_SEP3
<< siteName
<< QPROF_SEP3
<< siteFuncName
<< QPROF_SEP3
<< siteDepth
<< QPROF_SEP3
<< lib
<< QPROF_SEP3
<< libFlags
;
235 inline bool QProfSite::isLoop()
237 return siteDepth
> 0;
240 inline bool QProfSite::isFunction()
242 return !isLoop() && !isCallsite();
245 inline bool QProfSite::isCallsite()
247 return isLibCallsite();
250 inline bool QProfSite::isLibCallsite()
255 inline bool QProfSite::equals(QProfSite
*other
)
257 if (lineNum
!= other
->lineNum
) {
260 if (libFlags
!= other
->libFlags
) {
263 if (moduleName
.compare(other
->moduleName
)) {
266 if (functionName
.compare(other
->functionName
)) {
269 if (siteName
.compare(other
->siteName
)) {
272 if (siteFuncName
.compare(other
->siteFuncName
)) {
278 inline QProfConf
* QProfConf::get(Module
&M
, std::string
*llSitestacks
,
279 std::string
*deepestLLLoops
, std::string
*deepestLLLibs
,
280 std::string
*taskClasses
, bool refreshSites
)
282 std::vector
<int> intValues
;
283 QProfConf
*conf
= new QProfConf();
285 conf
->taskClassLLSitestacks
= parseTaskClassSiteList(M
,
286 *llSitestacks
, refreshSites
);
288 if (deepestLLLoops
) {
289 conf
->taskClassDeepestLLLoops
= parseTaskClassSite(M
,
290 *deepestLLLoops
, refreshSites
);
293 conf
->taskClassDeepestLLLibs
= parseTaskClassSiteList(M
,
294 *deepestLLLibs
, refreshSites
);
297 intValues
= parseIntList(*taskClasses
);
299 if (intValues
.size() > 0) {
300 assert(intValues
.size() == 6);
301 conf
->numTaskClasses
= intValues
[0];
302 conf
->numLLTaskClasses
= intValues
[1];
303 conf
->numLLBlockExtTaskClasses
= intValues
[2];
304 conf
->numLLBlockIntTaskClasses
= intValues
[3];
305 conf
->numLLBlockExtLibs
= intValues
[4];
306 conf
->numLLBlockIntLibs
= intValues
[5];
309 conf
->numTaskClasses
= 0;
310 conf
->numLLTaskClasses
= 0;
311 conf
->numLLBlockExtTaskClasses
= 0;
312 conf
->numLLBlockIntTaskClasses
= 0;
313 conf
->numLLBlockExtLibs
= 0;
314 conf
->numLLBlockIntLibs
= 0;
320 inline std::map
<int, std::vector
<QProfSite
*> > QProfConf::getTaskClassLLSitestacks()
322 return taskClassLLSitestacks
;
325 inline std::map
<int, QProfSite
*> QProfConf::getTaskClassDeepestLLLoops()
327 return taskClassDeepestLLLoops
;
330 inline std::map
<int, std::vector
<QProfSite
*> > QProfConf::getTaskClassDeepestLLLibs()
332 return taskClassDeepestLLLibs
;
335 inline int QProfConf::getNumTaskClasses()
337 return numTaskClasses
;
340 inline int QProfConf::getNumLLTaskClasses()
342 return numLLTaskClasses
;
345 inline int QProfConf::getNumLLBlockExtTaskClasses()
347 return numLLBlockExtTaskClasses
;
350 inline int QProfConf::getNumLLBlockIntTaskClasses()
352 return numLLBlockIntTaskClasses
;
355 inline int QProfConf::getNumLLBlockExtLibs()
357 return numLLBlockExtLibs
;
360 inline int QProfConf::getNumLLBlockIntLibs()
362 return numLLBlockIntLibs
;
365 inline std::vector
<QProfSite
*> QProfConf::getLLFunctions()
367 std::vector
<QProfSite
*> sites
;
368 std::map
<int, std::vector
<QProfSite
*> >::iterator it
;
369 it
= taskClassLLSitestacks
.begin();
370 for (; it
!= taskClassLLSitestacks
.end(); it
++) {
371 std::vector
<QProfSite
*> *siteVector
= &it
->second
;
372 for (unsigned i
=0;i
<siteVector
->size();i
++) {
373 QProfSite
* site
= (*siteVector
)[i
];
374 if (site
->isFunction()) {
375 sites
.push_back((*siteVector
)[i
]);
382 inline std::vector
<QProfSite
*> QProfConf::getDeepestLLLoops()
384 std::vector
<QProfSite
*> sites
;
385 std::map
<int, QProfSite
*>::iterator it
;
386 it
= taskClassDeepestLLLoops
.begin();
387 for (; it
!= taskClassDeepestLLLoops
.end(); it
++) {
388 sites
.push_back(it
->second
);
393 inline std::vector
<QProfSite
*> QProfConf::getDeepestLLLibs()
395 std::vector
<QProfSite
*> sites
;
396 std::map
<int, std::vector
<QProfSite
*> >::iterator it
;
397 it
= taskClassDeepestLLLibs
.begin();
398 for (; it
!= taskClassDeepestLLLibs
.end(); it
++) {
399 std::vector
<QProfSite
*> *siteVector
= &it
->second
;
400 for (unsigned i
=0;i
<siteVector
->size();i
++) {
401 sites
.push_back((*siteVector
)[i
]);
407 inline bool QProfConf::lookupTaskClassLibFlags(int taskClassID
, int *libFlags
)
410 std::vector
<QProfSite
*> deepestLLLibs
= getDeepestLLLibs();
413 for (unsigned i
=0;i
<deepestLLLibs
.size();i
++) {
414 QProfSite
*site
= deepestLLLibs
[i
];
415 if (site
->taskClassID
== taskClassID
) {
416 *libFlags
|= site
->libFlags
;
423 inline void QProfConf::mergeTaskClassLLSitestacks(int taskClassID
, int otherTaskClassID
)
425 size_t erased
= taskClassLLSitestacks
.erase(otherTaskClassID
);
429 inline void QProfConf::mergeTaskClassDeepestLLLoops(int taskClassID
, int otherTaskClassID
)
431 size_t erased
= taskClassDeepestLLLoops
.erase(otherTaskClassID
);
435 inline void QProfConf::mergeTaskClassDeepestLLLibs(int taskClassID
, int otherTaskClassID
)
437 size_t erased
= taskClassDeepestLLLibs
.erase(otherTaskClassID
);
441 inline void QProfConf::mergeTaskClassPair(int taskClassID
,
442 int otherTaskClassID
)
445 mergeTaskClassLLSitestacks(taskClassID
, otherTaskClassID
);
446 mergeTaskClassDeepestLLLoops(taskClassID
, otherTaskClassID
);
447 mergeTaskClassDeepestLLLibs(taskClassID
, otherTaskClassID
);
450 if (lookupTaskClassLibFlags(taskClassID
, &libFlags
)) {
452 if (libFlags
& _UTIL_STLIB_FLAG(STLIB_BLOCK_EXT
)) {
453 numLLBlockExtTaskClasses
--;
456 numLLBlockIntTaskClasses
--;
461 inline void QProfConf::mergeAllTaskClassesWithSameDeepestLLLoops()
463 std::vector
<QProfSite
*> deepestLLLoops
= getDeepestLLLoops();
464 std::vector
<std::pair
<QProfSite
*, QProfSite
*> > loopPairs
;
466 for (unsigned i
=0;i
<deepestLLLoops
.size();i
++) {
467 QProfSite
*site
= deepestLLLoops
[i
];
468 for (unsigned j
=0;j
<i
;j
++) {
469 if (site
->equals(deepestLLLoops
[j
])) {
470 loopPairs
.push_back(std::pair
<QProfSite
*, QProfSite
*>(site
, deepestLLLoops
[j
]));
474 for (unsigned i
=0;i
<loopPairs
.size();i
++) {
475 int taskClassID
= loopPairs
[i
].first
->taskClassID
;
476 int otherTaskClassID
= loopPairs
[i
].second
->taskClassID
;
477 mergeTaskClassPair(taskClassID
, otherTaskClassID
);
481 inline void QProfConf::print(raw_ostream
&O
)
483 std::vector
<QProfSite
*> list
;
484 O
<< "*** QProfConf:\n";
485 O
<< " - numTaskClasses=" << getNumTaskClasses() << "\n";
486 O
<< " - numLLTaskClasses=" << getNumLLTaskClasses() << "\n";
487 O
<< " - numLLBlockExtTaskClasses=" << getNumLLBlockExtTaskClasses() << "\n";
488 O
<< " - numLLBlockIntTaskClasses=" << getNumLLBlockIntTaskClasses() << "\n";
489 O
<< " - numLLBlockExtLibs=" << getNumLLBlockExtLibs() << "\n";
490 O
<< " - numLLBlockIntLibs=" << getNumLLBlockIntLibs() << "\n";
491 list
= getLLFunctions();
492 O
<< " - LLFunctions="; printSiteList(O
, list
); O
<< "\n";
493 list
= getDeepestLLLoops();
494 O
<< " - deepestLLLoops="; printSiteList(O
, list
); O
<< "\n";
495 list
= getDeepestLLLibs();
496 O
<< " - deepestLLLibs="; printSiteList(O
, list
); O
<< "\n";
499 inline void QProfConf::printSiteList(raw_ostream
&O
, std::vector
<QProfSite
*> &list
)
501 for (std::vector
<QProfSite
*>::iterator it
= list
.begin(); it
!= list
.end(); it
++) {
502 QProfSite
* site
= *it
;
503 if (it
!= list
.begin()) {
507 O
<< site
->toString();
512 inline std::map
<int, std::vector
<QProfSite
*> > QProfConf::parseTaskClassSiteList(Module
&M
,
513 std::string
&str
, bool refreshSites
)
515 std::map
<int, std::vector
<QProfSite
*> > siteListMap
;
517 SmallVector
< StringRef
, 3 > tokenVector
;
518 if (!str
.compare("")) {
521 ref
.split(tokenVector
, QPROF_SEP
);
522 for (unsigned i
=0;i
<tokenVector
.size();i
++) {
523 std::string token
= tokenVector
[i
].str();
524 std::vector
<QProfSite
*> sites
= QProfSite::getFromSitesString(M
,
525 token
, refreshSites
);
526 if (sites
.size() > 0) {
527 int taskClassID
= sites
[0]->taskClassID
;
528 siteListMap
.insert(std::pair
<int, std::vector
<QProfSite
*> >(taskClassID
,
535 inline std::map
<int, QProfSite
*> QProfConf::parseTaskClassSite(Module
&M
,
536 std::string
&str
, bool refreshSites
)
538 std::map
<int, std::vector
<QProfSite
*> >::iterator it
;
539 std::map
<int, std::vector
<QProfSite
*> > siteListMap
=
540 parseTaskClassSiteList(M
, str
, refreshSites
);
541 std::map
<int, QProfSite
*> siteMap
;
542 for (it
=siteListMap
.begin();it
!=siteListMap
.end();it
++) {
543 std::vector
<QProfSite
*> list
= it
->second
;
544 assert(list
.size() == 1);
545 siteMap
.insert(std::pair
<int, QProfSite
*>(it
->first
, list
[0]));
551 inline std::vector
<int> QProfConf::parseIntList(std::string
&str
)
553 std::vector
<int> intValues
;
555 SmallVector
< StringRef
, 3 > tokenVector
;
556 if (!str
.compare("")) {
559 ref
.split(tokenVector
, QPROF_SEP
);
560 for (unsigned i
=0;i
<tokenVector
.size();i
++) {
561 intValues
.push_back(stringRefToInt(tokenVector
[i
]));
569 #endif /* _QPROF_COMMON_H */