Remove building with NOCRYPTO option
[minix.git] / minix / llvm / passes / include / common / qprof_common.h
blobc61296fc41d51eabe0c3f10a7ac203500f1ee364
1 #ifndef _QPROF_COMMON_H
2 #define _QPROF_COMMON_H
4 #include <cstdlib>
5 #include <common/util/stdlib.h>
7 #define QPROF_SEP ","
8 #define QPROF_SEP2 ":"
9 #define QPROF_SEP3 "|"
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) \
41 using namespace llvm;
43 namespace llvm {
45 class QProfSite {
46 public:
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();
53 bool isLoop();
54 bool isFunction();
55 bool isCallsite();
56 bool isLibCallsite();
57 bool equals(QProfSite *other);
59 int taskClassID;
60 int taskSiteID;
61 std::string moduleName;
62 int lineNum;
63 std::string functionName;
64 std::string siteName;
65 std::string siteFuncName;
66 unsigned long libFlags;
67 Function *function;
68 Function *siteFunction;
69 Instruction *siteInstruction;
70 private:
71 QProfSite() {}
73 int siteDepth;
74 int lib;
77 class QProfConf {
78 public:
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);
103 private:
104 QProfConf() {}
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;
113 int numTaskClasses;
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;
140 site->lib = lib;
141 site->libFlags = libFlags;
142 site->function = NULL;
143 site->siteFunction = NULL;
144 site->siteInstruction = NULL;
145 if (refreshSite) {
146 site->refresh(M);
149 return site;
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("")) {
158 return NULL;
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)
171 unsigned i;
172 int taskClassID;
173 std::vector<QProfSite*> sites;
174 StringRef ref(sitesString);
175 SmallVector< StringRef, 3 > tokenVector;
176 if (!sitesString.compare("")) {
177 return sites;
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,
185 refreshSites);
186 sites.push_back(site);
188 return sites;
191 inline void QProfSite::refresh(Module &M)
193 BasicBlock *siteBB = NULL;
194 function = NULL;
195 siteFunction = NULL;
196 siteInstruction = NULL;
197 function = M.getFunction(functionName);
198 siteFunction = M.getFunction(siteFuncName);
199 if (!siteFunction) {
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)) {
206 siteBB = BB;
207 break;
210 assert(siteBB);
211 if (isCallsite()) {
212 for (BasicBlock::iterator it = siteBB->begin(); it != siteBB->end(); ++it) {
213 CallSite CS(it);
214 if (CS.getInstruction() && CS.getCalledFunction() == function) {
215 siteInstruction = it;
216 break;
219 assert(siteInstruction && "Invalid qprof callsite?");
221 else {
222 siteInstruction = &siteBB->front();
226 inline std::string QProfSite::toString()
228 std::string str;
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;
231 ostream.flush();
232 return str;
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()
252 return lib != 0;
255 inline bool QProfSite::equals(QProfSite *other)
257 if (lineNum != other->lineNum) {
258 return false;
260 if (libFlags != other->libFlags) {
261 return false;
263 if (moduleName.compare(other->moduleName)) {
264 return false;
266 if (functionName.compare(other->functionName)) {
267 return false;
269 if (siteName.compare(other->siteName)) {
270 return false;
272 if (siteFuncName.compare(other->siteFuncName)) {
273 return false;
275 return true;
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();
284 if (llSitestacks) {
285 conf->taskClassLLSitestacks = parseTaskClassSiteList(M,
286 *llSitestacks, refreshSites);
288 if (deepestLLLoops) {
289 conf->taskClassDeepestLLLoops = parseTaskClassSite(M,
290 *deepestLLLoops, refreshSites);
292 if (deepestLLLibs) {
293 conf->taskClassDeepestLLLibs = parseTaskClassSiteList(M,
294 *deepestLLLibs, refreshSites);
296 if (taskClasses) {
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];
308 else {
309 conf->numTaskClasses = 0;
310 conf->numLLTaskClasses = 0;
311 conf->numLLBlockExtTaskClasses = 0;
312 conf->numLLBlockIntTaskClasses = 0;
313 conf->numLLBlockExtLibs = 0;
314 conf->numLLBlockIntLibs = 0;
317 return conf;
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]);
379 return sites;
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);
390 return sites;
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]);
404 return sites;
407 inline bool QProfConf::lookupTaskClassLibFlags(int taskClassID, int *libFlags)
409 bool found = false;
410 std::vector<QProfSite*> deepestLLLibs = getDeepestLLLibs();
412 *libFlags = 0;
413 for (unsigned i=0;i<deepestLLLibs.size();i++) {
414 QProfSite *site = deepestLLLibs[i];
415 if (site->taskClassID == taskClassID) {
416 *libFlags |= site->libFlags;
417 found = true;
420 return found;
423 inline void QProfConf::mergeTaskClassLLSitestacks(int taskClassID, int otherTaskClassID)
425 size_t erased = taskClassLLSitestacks.erase(otherTaskClassID);
426 assert(erased == 1);
429 inline void QProfConf::mergeTaskClassDeepestLLLoops(int taskClassID, int otherTaskClassID)
431 size_t erased = taskClassDeepestLLLoops.erase(otherTaskClassID);
432 assert(erased == 1);
435 inline void QProfConf::mergeTaskClassDeepestLLLibs(int taskClassID, int otherTaskClassID)
437 size_t erased = taskClassDeepestLLLibs.erase(otherTaskClassID);
438 assert(erased == 1);
441 inline void QProfConf::mergeTaskClassPair(int taskClassID,
442 int otherTaskClassID)
444 int libFlags;
445 mergeTaskClassLLSitestacks(taskClassID, otherTaskClassID);
446 mergeTaskClassDeepestLLLoops(taskClassID, otherTaskClassID);
447 mergeTaskClassDeepestLLLibs(taskClassID, otherTaskClassID);
449 numTaskClasses--;
450 if (lookupTaskClassLibFlags(taskClassID, &libFlags)) {
451 numLLTaskClasses--;
452 if (libFlags & _UTIL_STLIB_FLAG(STLIB_BLOCK_EXT)) {
453 numLLBlockExtTaskClasses--;
455 else {
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()) {
504 O << ", ";
506 O << "{ ";
507 O << site->toString();
508 O << " }";
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;
516 StringRef ref(str);
517 SmallVector< StringRef, 3 > tokenVector;
518 if (!str.compare("")) {
519 return siteListMap;
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,
529 sites));
532 return siteListMap;
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]));
548 return siteMap;
551 inline std::vector<int> QProfConf::parseIntList(std::string &str)
553 std::vector<int> intValues;
554 StringRef ref(str);
555 SmallVector< StringRef, 3 > tokenVector;
556 if (!str.compare("")) {
557 return intValues;
559 ref.split(tokenVector, QPROF_SEP);
560 for (unsigned i=0;i<tokenVector.size();i++) {
561 intValues.push_back(stringRefToInt(tokenVector[i]));
564 return intValues;
569 #endif /* _QPROF_COMMON_H */