systemc-clang 2.0.0
Parsing SystemC constructs
Loading...
Searching...
No Matches
SuspensionAutomata.cpp
Go to the documentation of this file.
2#include "FindArgument.h"
3
4#include <algorithm>
5
6using namespace systemc_clang;
7
8SusCFG::SusCFG(CFGBlock *block)
9 : _block(block),
10 _parentCFGBlock(NULL),
11 _parentSusCFGBlock(NULL),
12 _isWaitBlock(false),
13 _isParentBlock(false),
14 _isGPUFit(false) {}
15
17
18void SusCFG::addParentBlock(CFGBlock *parentBlock) {
19 _parentCFGBlock = parentBlock;
20}
21
22void SusCFG::addParentBlock(SusCFG *parentBlock) {
23 _parentSusCFGBlock = parentBlock;
24}
25
26void SusCFG::addPredBlocks(SusCFG *block) { _predBlocks.push_back(block); }
27
28void SusCFG::addSuccBlocks(SusCFG *block) { _succBlocks.push_back(block); }
29
30void SusCFG::addGPUFit() { _isGPUFit = true; }
31
32void SusCFG::denyGPUFit() { _isGPUFit = false; }
33
35 _childBlockList.push_back(block);
36}
37
38void SusCFG::addChildBlockList(vector<SusCFG *> blockList) {
39 for (unsigned int i = 0; i < blockList.size(); i++) {
40 _childBlockList.push_back(blockList.at(i));
41 }
42}
43
45
47
48void SusCFG::setWaitStmt(Stmt *stmt) { _waitStmt = stmt; }
49
50vector<SusCFG *> SusCFG::getChildBlockList() { return _childBlockList; }
51
52vector<SusCFG *> SusCFG::getPredBlocks() { return _predBlocks; }
53
54vector<SusCFG *> SusCFG::getSuccBlocks() { return _succBlocks; }
55
56unsigned int SusCFG::getBlockID() { return _block->getBlockID(); }
57
59
61
62bool SusCFG::isGPUFit() { return _isGPUFit; }
63
65 if (_parentCFGBlock) {
66 return _parentCFGBlock->getBlockID();
67 } else {
68 return 0;
69 }
70}
71
72CFGBlock *SusCFG::getBlock() { return _block; }
73
75
77
78Stmt *SusCFG::getWaitStmt() { return _waitStmt; }
79
81State::State(SusCFG *susCFG, bool isTimed, bool isDelta, bool isInitial,
82 bool isEvent)
83 : _susCFGBlock(susCFG),
84 _isTimed(isTimed),
85 _isDelta(isDelta),
86 _isInitial(isInitial),
87 _isEvent(isEvent) {}
88
90
91bool State::isTimed() { return _isTimed; }
92
93bool State::isDelta() { return _isDelta; }
94
95bool State::isEvent() { return _isEvent; }
96
97bool State::isInitial() { return _isInitial; }
98
99void State::setInitial() { _isInitial = true; }
100
101void State::setTimed() { _isTimed = true; }
102
103void State::setEvent() { _isEvent = true; }
104
105void State::setDelta() { _isDelta = true; }
106
107void State::addEventName(string eventName) { _eventName = eventName; }
108
109void State::addSimTime(float simTime) { _timeInNS = simTime; }
110
111string State::getEventName() { return _eventName; }
112
113float State::getSimTime() { return _timeInNS; }
114
116
118Transition::Transition() : _initialState(NULL), _finalState(NULL) {}
119
121 delete _initialState;
122 delete _finalState;
123}
124
125void Transition::addInstanceId(int instanceId) { _instanceId = instanceId; }
126
128
130
132 _codeBlockVector.push_back(susCFG);
133}
134
135void Transition::addCodeBlocks(vector<SusCFG *> susCFG) {
136 for (unsigned int i = 0; i < susCFG.size(); i++) {
137 _codeBlockVector.push_back(susCFG.at(i));
138 }
139}
140
142
144
146
147vector<SusCFG *> Transition::returnCodeBlocks() { return _codeBlockVector; }
148
149void Transition::dump(raw_ostream &os) {
150 os << "\n ####### Transition #######";
151 os << "\n Initial State : "
153 os << "\n Final State : " << _finalState->returnSusCFGBlock()->getBlockID();
154 os << "\n Transition Blocks : ";
155 for (unsigned int i = 0; i < _codeBlockVector.size(); i++) {
156 os << _codeBlockVector.at(i)->getBlockID() << " ";
157 }
158}
159
161SuspensionAutomata::SuspensionAutomata(vector<WaitContainer *> waitCalls,
162 CXXMethodDecl *d, ASTContext *a,
163 raw_ostream &os)
164 : _d(d), _a(a), _os(os) {
165 for (std::size_t i{0}; i < waitCalls.size(); i++) {
166 WaitContainer *wc{waitCalls.at(i)};
167 _waitCalls.push_back(wc->getASTNode());
168 }
169}
170
172
174 const CFG::BuildOptions &b = CFG::BuildOptions();
175
176 _cfg = CFG::buildCFG(cast<Decl>(_d), _d->getBody(), _a, b);
177
178 if (_cfg != NULL) {
179 return true;
180 }
181
182 return false;
183}
184
185bool SuspensionAutomata::isWaitCall(const CFGStmt *cs) {
186 bool f = false;
187
188 Stmt *s = const_cast<Stmt *>(cs->getStmt());
189
190 CXXMemberCallExpr *m = dyn_cast<CXXMemberCallExpr>(s);
191
192 if (!m) {
193 return f;
194 }
195 for (std::size_t i{0}; i < _waitCalls.size(); i++) {
196 CallExpr *ce{_waitCalls.at(i)};
197 if (m == ce) {
198 f = true;
199 }
200 }
201 /*
202 for (EntryFunctionContainer::waitContainerListType::iterator it =
203 _waitCalls.begin(), eit = _waitCalls.end(); it != eit; ++it)
204 WaitContainer *w = (*it);
205 if (m == w->getASTNode()) {
206 f = true;
207 }
208 */
209 return f;
210}
211
212/*************************************************************************
213Description : Locates the suspension points in the CFG and
214creates new CFG blocks that isolates the suspension statements from the code.
215*************************************************************************/
217 LangOptions LO;
218
219 LO.CPlusPlus = true;
220 PrintingPolicy Policy(LO);
221
222 vector<Optional<CFGStmt>> pre;
223 vector<unsigned int> waitBlockIDVector;
224 vector<const CFGBlock *> CFGBlockVector;
225 ;
226
227 typedef map<CFGBlock *, SusCFG *> susCFGBlockMapType;
228 typedef pair<CFGBlock *, SusCFG *> susCFGBlockPairType;
229
230 susCFGBlockMapType susCFGBlockMap;
231
232 bool isFirstCFGBlockID = false;
233
234 for (CFG::iterator it = _cfg->end() - 1, eit = _cfg->begin(); it != eit;
235 --it) {
236 const CFGBlock *b = *it;
237 SusCFG *currBlock;
238
239 if (susCFGBlockMap.find(const_cast<CFGBlock *>(b)) ==
240 susCFGBlockMap.end()) {
241 currBlock = new SusCFG(const_cast<CFGBlock *>(b));
242 susCFGBlockMap.insert(
243 susCFGBlockPairType(const_cast<CFGBlock *>(b), currBlock));
244 } else {
245 susCFGBlockMapType::iterator susCFGBlockFound =
246 susCFGBlockMap.find(const_cast<CFGBlock *>(b));
247 currBlock = susCFGBlockFound->second;
248 }
249
250 bool foundWait = false;
251
252 vector<CFGBlock *> splitBlocksVector;
253 /*
254 _os << "==========================================================\n";
255 _os << "Dump CFG Block\n";
256 b->dump(_cfg, LO, false);
257 */
258 unsigned int prevCFGBlockID;
259
260 for (CFGBlock::const_iterator bit = b->begin(), bite = b->end();
261 bit != bite; bit++) {
262 if (Optional<CFGStmt> cs = bit->getAs<CFGStmt>()) {
263 const CFGStmt *s = (CFGStmt const *)&cs;
264
265 if (isWaitCall(s)) {
266 foundWait = true;
267 CFGBlock *newSplitBlock = _cfg->createBlock();
268
269 for (unsigned int i = 0; i < pre.size(); i++) {
270 newSplitBlock->appendStmt(const_cast<Stmt *>(pre.at(i)->getStmt()),
271 _cfg->getBumpVectorContext());
272 }
273
274 CFGBlock *waitBlock = _cfg->createBlock();
275
276 waitBlock->appendStmt(const_cast<Stmt *>(cs->getStmt()),
277 _cfg->getBumpVectorContext());
278 waitBlock->setLabel(const_cast<Stmt *>(cs->getStmt()));
279 splitBlocksVector.push_back(newSplitBlock);
280 splitBlocksVector.push_back(waitBlock);
281 pre.clear();
282
283 } else {
284 pre.push_back(cs);
285 }
286 }
287 }
288 // pre.clear();
289
290 if (foundWait) {
291 currBlock->setParentBlock();
292 CFGBlock *prev = NULL;
293 SusCFG *prevBlock = NULL;
294
295 for (std::size_t i = 0; i < splitBlocksVector.size(); i++) {
296 CFGBlock *current = splitBlocksVector.at(i);
297 SusCFG *splitBlock =
298 new SusCFG(const_cast<CFGBlock *>(splitBlocksVector.at(i)));
299 currBlock->addChildBlockList(splitBlock);
300 if (current->getLabel()) {
301 splitBlock->setWaitBlock();
302 splitBlock->setWaitStmt(current->getLabel());
303 }
304 if (pre.size() != 0) {
305 // add trailing statements to post block wait stmt
306 CFGBlock *newCFGBlock = _cfg->createBlock();
307 for (std::size_t j{0}; j < pre.size(); j++) {
308 newCFGBlock->appendStmt(const_cast<Stmt *>(pre.at(j)->getStmt()),
309 _cfg->getBumpVectorContext());
310 }
311 // SusCFG * postSusCFGBlock = new SusCFG(newCFGBlock);
312 // susCFGBlockMap.insert(susCFGBlockPairType(newCFGBlock,
313 // postSusCFGBlock));
314 splitBlocksVector.push_back(newCFGBlock);
315 pre.clear();
316 }
317 if (i == 0) {
318 for (CFGBlock::const_pred_iterator pit = b->pred_begin(),
319 pite = b->pred_end();
320 pit != pite; pit++) {
321 const CFGBlock *pred = *pit;
322
323 if (susCFGBlockMap.find(const_cast<CFGBlock *>(pred)) ==
324 susCFGBlockMap.end()) {
325 SusCFG *tmpBlock = new SusCFG(const_cast<CFGBlock *>(pred));
326 susCFGBlockMap.insert(
327 susCFGBlockPairType(const_cast<CFGBlock *>(pred), tmpBlock));
328 splitBlock->addPredBlocks(tmpBlock);
329 } else {
330 susCFGBlockMapType::iterator susCFGBlockFound =
331 susCFGBlockMap.find(const_cast<CFGBlock *>(pred));
332 splitBlock->addPredBlocks(susCFGBlockFound->second);
333 }
334 }
335
336 splitBlock->addParentBlock(const_cast<CFGBlock *>(b));
337 splitBlock->addParentBlock(currBlock);
338 prevBlock = splitBlock;
339 } else if (i == splitBlocksVector.size() - 1) {
340 prev = splitBlocksVector.at(i - 1);
341 if (susCFGBlockMap.find(prev) == susCFGBlockMap.end()) {
342 SusCFG *tmpBlock = new SusCFG(const_cast<CFGBlock *>(prev));
343 susCFGBlockMap.insert(
344 susCFGBlockPairType(const_cast<CFGBlock *>(prev), tmpBlock));
345 splitBlock->addPredBlocks(tmpBlock);
346 } else {
347 susCFGBlockMapType::iterator susCFGBlockFound =
348 susCFGBlockMap.find(const_cast<CFGBlock *>(prev));
349 splitBlock->addPredBlocks(susCFGBlockFound->second);
350 }
351 prevBlock->addSuccBlocks(splitBlock);
352
353 for (CFGBlock::const_succ_iterator sit = b->succ_begin(),
354 site = b->succ_end();
355 sit != site; sit++) {
356 const CFGBlock *succ = *sit;
357
358 if (susCFGBlockMap.find(const_cast<CFGBlock *>(succ)) ==
359 susCFGBlockMap.end()) {
360 SusCFG *tmpBlock = new SusCFG(const_cast<CFGBlock *>(succ));
361 susCFGBlockMap.insert(
362 susCFGBlockPairType(const_cast<CFGBlock *>(succ), tmpBlock));
363 splitBlock->addSuccBlocks(tmpBlock);
364 } else {
365 susCFGBlockMapType::iterator susCFGBlockFound =
366 susCFGBlockMap.find(const_cast<CFGBlock *>(succ));
367 splitBlock->addSuccBlocks(susCFGBlockFound->second);
368 }
369 }
370 } else {
371 prev = splitBlocksVector.at(i - 1);
372 if (susCFGBlockMap.find(const_cast<CFGBlock *>(prev)) ==
373 susCFGBlockMap.end()) {
374 SusCFG *tmpBlock = new SusCFG(const_cast<CFGBlock *>(prev));
375 susCFGBlockMap.insert(
376 susCFGBlockPairType(const_cast<CFGBlock *>(prev), tmpBlock));
377 splitBlock->addPredBlocks(tmpBlock);
378 } else {
379 susCFGBlockMapType::iterator susCFGBlockFound =
380 susCFGBlockMap.find(const_cast<CFGBlock *>(prev));
381 splitBlock->addPredBlocks(susCFGBlockFound->second);
382 }
383 prevBlock->addSuccBlocks(splitBlock);
384 prevBlock = splitBlock;
385 }
386 _susCFGVector.push_back(splitBlock);
387 }
388 } else {
389 for (CFGBlock::const_pred_iterator pit = b->pred_begin(),
390 pite = b->pred_end();
391 pit != pite; pit++) {
392 const CFGBlock *predBlock = *pit;
393
394 if (predBlock) {
395 if (susCFGBlockMap.find(const_cast<CFGBlock *>(predBlock)) ==
396 susCFGBlockMap.end()) {
397 SusCFG *tmpBlock = new SusCFG(const_cast<CFGBlock *>(predBlock));
398 susCFGBlockMap.insert(susCFGBlockPairType(
399 const_cast<CFGBlock *>(predBlock), tmpBlock));
400 currBlock->addPredBlocks(tmpBlock);
401 } else {
402 susCFGBlockMapType::iterator predSusCFGBlockFound =
403 susCFGBlockMap.find(const_cast<CFGBlock *>(predBlock));
404 currBlock->addPredBlocks(predSusCFGBlockFound->second);
405 }
406 }
407 }
408 for (CFGBlock::const_succ_iterator sit = b->succ_begin(),
409 site = b->succ_end();
410 sit != site; sit++) {
411 const CFGBlock *succBlock = *sit;
412 SusCFG *tmpBlock{nullptr};
413
414 if (succBlock) {
415 if (susCFGBlockMap.find(const_cast<CFGBlock *>(succBlock)) ==
416 susCFGBlockMap.end()) {
417 tmpBlock = new SusCFG(const_cast<CFGBlock *>(succBlock));
418 susCFGBlockMap.insert(susCFGBlockPairType(
419 const_cast<CFGBlock *>(succBlock), tmpBlock));
420 currBlock->addSuccBlocks(tmpBlock);
421 } else {
422 susCFGBlockMapType::iterator succSusCFGBlockFound =
423 susCFGBlockMap.find(const_cast<CFGBlock *>(succBlock));
424 currBlock->addSuccBlocks(succSusCFGBlockFound->second);
425 }
426 }
427 }
428 _susCFGVector.push_back(currBlock);
429 }
430 }
431}
432
434 State *initialState, vector<SusCFG *> &transitionBlocks) {
435 bool duplicate = false;
436 if (_stateCommonCodeBlockMap.find(initialState) !=
438 stateCommonCodeBlockMapType::iterator stateFound =
439 _stateCommonCodeBlockMap.find(initialState);
440 checkInsert(stateFound->second, transitionBlocks);
441 }
442}
443
444vector<SusCFG *> SuspensionAutomata::modifDFS(SusCFG *block,
445 State *initialState) {
446 deque<SusCFG *> traversedBlocks;
447 vector<SusCFG *> visitedBlocks;
448
449 traversedBlocks.push_front(block);
450 bool isWaitEncounter = false;
451 vector<SusCFG *> transitionBlocks;
452 while (traversedBlocks.size() != 0) {
453 SusCFG *currentBlock = traversedBlocks.front();
454
455 traversedBlocks.pop_front();
456 if (currentBlock->isWaitBlock()) {
457 float timeInNs;
458 string eventName;
459 isWaitEncounter = true;
460 susCFGStateMapType::iterator stateFound =
461 susCFGStateMap.find(currentBlock);
462 State *finalState = stateFound->second;
463
464 if (isTimedWait(currentBlock->getWaitStmt())) {
465 finalState->setTimed();
466 timeInNs = getTime(currentBlock->getWaitStmt());
467 } else if (isEventWait(currentBlock->getWaitStmt())) {
468 finalState->setEvent();
469 eventName = getEvent(currentBlock->getWaitStmt());
470 } else if (isDeltaWait(currentBlock->getWaitStmt())) {
471 finalState->setDelta();
472 } else {
473 finalState->setInitial();
474 }
475
476 Transition *t = new Transition();
477 finalState->addEventName(eventName);
478 finalState->addSimTime(timeInNs);
479 t->addInitialState(initialState);
480 t->addFinalState(finalState);
481 addRemainingBlocks(initialState, transitionBlocks);
482 t->addCodeBlocks(transitionBlocks);
483
484 _transitionVector.push_back(t);
485 return transitionBlocks;
486
487 } else {
488 // When adding blocks to traversed blocks, check if the last node prior to
489 // the wait call has which branch discovered. Also need to check
490 // terminator block or block 0
491 //
492 if (susCFGSuccIDMap.find(currentBlock) == susCFGSuccIDMap.end()) {
493 // currentBlock is not our concern yet, so insert the 0th successive
494 // block
495 //_os <<"\n Current Block : " <<currentBlock->getBlockID()<<" not of
496 // concern";
497 //
498 // TODO: BUG: There is an issue here.
499 // There exists a getSuccBlocks(), but it happens to be empty.
500 // This happens when there is a thread that uses a wait(), but no while
501 // loop.
502 if (currentBlock->getSuccBlocks().at(0)->isParentBlock()) {
503 if (!isFound(
504 visitedBlocks,
505 currentBlock->getSuccBlocks().at(0)->getChildBlockList().at(
506 0))) {
507 traversedBlocks.push_front(
508 currentBlock->getSuccBlocks().at(0)->getChildBlockList().at(0));
509 }
510 } else {
511 if (!isFound(visitedBlocks, currentBlock->getSuccBlocks().at(0))) {
512 if (currentBlock->getSuccBlocks().at(0)->getBlockID() != 0) {
513 traversedBlocks.push_front(currentBlock->getSuccBlocks().at(0));
514 }
515 }
516 }
517 } else {
518 // currentBlock has a previous entry in the map, so take the other
519 // succesive block if it exists
520 //_os <<"\n Current block : " <<currentBlock->getBlockID()<<" is of
521 // concern";
522 susCFGSuccIDMapType::iterator susCFGFound =
523 susCFGSuccIDMap.find(currentBlock);
524 if (susCFGFound->second == currentBlock->getSuccBlocks().size() - 1) {
525 // All the child branches of this node have been discovered. So, there
526 // is nothing to discover
527 //_os <<"\n Current block : " <<currentBlock->getBlockID()<<" has all
528 // children accounted for";
529 break;
530 } else {
531 if (currentBlock->getSuccBlocks()
532 .at(susCFGFound->second + 1)
533 ->isParentBlock()) {
534 if (!isFound(visitedBlocks, currentBlock->getSuccBlocks()
535 .at(susCFGFound->second + 1)
536 ->getChildBlockList()
537 .at(0))) {
538 traversedBlocks.push_front(currentBlock->getSuccBlocks()
539 .at(susCFGFound->second + 1)
540 ->getChildBlockList()
541 .at(0));
542 }
543 } else {
544 if (!isFound(visitedBlocks, currentBlock->getSuccBlocks().at(
545 susCFGFound->second + 1))) {
546 if (currentBlock->getSuccBlocks()
547 .at(susCFGFound->second + 1)
548 ->getBlockID() != 0) {
549 traversedBlocks.push_front(
550 currentBlock->getSuccBlocks().at(susCFGFound->second + 1));
551 }
552 }
553 }
554 }
555 }
556 visitedBlocks.push_back(currentBlock);
557 transitionBlocks.push_back(currentBlock);
558 }
559 }
560 if (isWaitEncounter == false) {
561 // we found a path that does not end in a wait block. So,
562 // it will be in all paths from this initial state to all final wait states
563 if (_stateCommonCodeBlockMap.find(initialState) ==
566 stateCommonCodeBlockPairType(initialState, transitionBlocks));
567 } else {
568 stateCommonCodeBlockMapType::iterator stateFound =
569 _stateCommonCodeBlockMap.find(initialState);
570 vector<SusCFG *> remainingCodeBlocks = stateFound->second;
571 checkInsert(transitionBlocks, remainingCodeBlocks);
572 }
573 }
574 return transitionBlocks;
575}
576
577void SuspensionAutomata::checkInsert(vector<SusCFG *> source,
578 vector<SusCFG *> &target) {
579 bool duplicate;
580 for (std::size_t i{0}; i < source.size(); i++) {
581 duplicate = false;
582 for (int j = 0; j < target.size(); j++) {
583 if (source.at(i) == target.at(j)) {
584 duplicate = true;
585 break;
586 }
587 }
588 if (duplicate == false) {
589 target.push_back(source.at(i));
590 }
591 }
592}
593
595 susCFGVectorType susCFGVector = _susCFGVector;
596 susCFGVectorType waitBlocks;
597 for (std::size_t i{0}; i < susCFGVector.size(); i++) {
598 if (susCFGVector.at(i)->isWaitBlock() || i == 0) {
599 waitBlocks.push_back(susCFGVector.at(i));
600 State *state = new State(susCFGVector.at(i), false, false, false, false);
601 if (i == 0) {
602 state->setInitial();
603 //_os <<"\n State susblock set to initial : "
604 //<<state->returnSusCFGBlock()->getBlockID(); _os <<"\n State : "
605 //<<state->isTimed()<<" " <<state->isInitial()<<" " <<state->isDelta();
606 }
607 susCFGStateMap.insert(susCFGStatePairType(susCFGVector.at(i), state));
608 }
609 }
610
611 for (std::size_t i{0}; i < waitBlocks.size(); i++) {
612 SusCFG *waitBlock = waitBlocks.at(i);
613
614 //_os <<"\n Looking at Wait Block : " <<waitBlock->getBlockID();
615
616 susCFGStateMapType::iterator stateFound =
617 susCFGStateMap.find(waitBlocks.at(i));
618 State *initialState = stateFound->second;
619
620 vector<SusCFG *> backTrackCodeBlocks;
621 SusCFG *lastBlock;
622 susCFGSuccIDMap.clear(); // For each new initial state, start fresh...
623 // Left child.. do the same for the right child
624 do {
625 SusCFG *initialInsertBlock;
626 if (waitBlock->getSuccBlocks().at(0)->isParentBlock()) {
627 initialInsertBlock =
628 waitBlock->getSuccBlocks().at(0)->getChildBlockList().at(0);
629 }
630
631 else {
632 initialInsertBlock = waitBlock->getSuccBlocks().at(0);
633 }
634 vector<SusCFG *> transitionCodeBlocks =
635 modifDFS(initialInsertBlock, initialState);
636
637 //_os <<"\n Transition Blocks : ";
638 backTrackCodeBlocks.clear();
639 for (std::size_t j{0}; j < transitionCodeBlocks.size(); j++) {
640 backTrackCodeBlocks.push_back(transitionCodeBlocks.at(j));
641 //_os <<" "<<transitionCodeBlocks.at(j)->getBlockID();;
642 }
643 std::size_t j{};
644 for (j = backTrackCodeBlocks.size() - 2; j >= 0; j--) {
645 if (backTrackCodeBlocks.at(j)->getSuccBlocks().size() > 1) {
646 //_os <<"\n Block : " <<backTrackCodeBlocks.at(j)->getBlockID()<<" has
647 // more than one successor";
648 SusCFG *backBlock = backTrackCodeBlocks.at(j);
649 if (backBlock->getSuccBlocks().at(0)->isParentBlock()) {
650 if (backBlock->getSuccBlocks().at(0)->getChildBlockList().at(0) ==
651 backTrackCodeBlocks.at(j + 1)) {
652 //_os <<"\n Block : " <<backBlock->getBlockID()<<" used the first
653 // successor";
654 susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 0));
655 //_os <<"\n Map value : " <<susCFGSuccIDMap[backBlock];
656 break;
657 }
658 } else if (backBlock->getSuccBlocks().at(1)->isParentBlock()) {
659 if (backBlock->getSuccBlocks().at(1)->getChildBlockList().at(0) ==
660 backTrackCodeBlocks.at(j + 1)) {
661 //_os <<"\n Block : " <<backBlock->getBlockID()<<" used the second
662 // successor";
663 susCFGSuccIDMap.erase(backBlock);
664 susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 1));
665 break;
666 }
667 }
668
669 else if (backBlock->getSuccBlocks().at(0) ==
670 backTrackCodeBlocks.at(j + 1)) {
671 //_os <<"\n Block : " <<backBlock->getBlockID()<<" used the first
672 // successor";
673
674 susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 0));
675 break;
676 } else if (backBlock->getSuccBlocks().at(1) ==
677 backTrackCodeBlocks.at(j + 1)) {
678 //_os <<"\n Block : " <<backBlock->getBlockID()<<" used the second
679 // successor";
680
681 susCFGSuccIDMap.erase(backBlock);
682 susCFGSuccIDMap.insert(susCFGSuccIDPairType(backBlock, 1));
683 break;
684 }
685 }
686 }
687 //_os <<"\n J value : " <<j;
688 if (j == -1) {
689 if (susCFGSuccIDMap.find(backTrackCodeBlocks.back()) ==
690 susCFGSuccIDMap.end()) {
691 susCFGSuccIDMap.insert(
692 susCFGSuccIDPairType(backTrackCodeBlocks.back(), 0));
693 } else {
694 if (susCFGSuccIDMap[backTrackCodeBlocks.back()] == 0) {
695 susCFGSuccIDMap.erase(backTrackCodeBlocks.back());
696 susCFGSuccIDMap.insert(
697 susCFGSuccIDPairType(backTrackCodeBlocks.back(), 1));
698 } else {
699 }
700 }
701 }
702
703 // delete the blocks from the back to j
704 if (backTrackCodeBlocks.size() != 0) {
705 backTrackCodeBlocks.pop_back();
706 }
707
708 } while (backTrackCodeBlocks.size() != 0);
709 }
710}
711
712template <typename Node>
713bool is_found(Node n1, Node n2) {
714 return n1 == n2;
715}
716
717template <template <typename, typename> class Container, typename Node,
718 typename Allocator>
719bool generic_isFound(Container<Node, Allocator> &container, Node node) {
720 bool foundBlock = false;
721
722 typename Container<Node, Allocator>::iterator itr = std::find_if(
723 container.begin(), container.end(),
724 std::bind1st(std::ptr_fun<Node, Node, bool>(is_found), node));
725
726 return itr != container.end();
727}
728
729// need a utility class and this should be a template function
730bool SuspensionAutomata::isFound(vector<SusCFG *> visitedState, SusCFG *block) {
731 return generic_isFound(visitedState, block);
732}
733
734bool SuspensionAutomata::isFound(vector<Transition *> visitedState,
735 Transition *block) {
736 return generic_isFound(visitedState, block);
737}
738
740 float factor;
741 if (CXXMemberCallExpr *ce = dyn_cast<CXXMemberCallExpr>(stmt)) {
742 if (getArgumentName(ce->getArg(1)) == "SC_FS") {
743 factor = 1000000;
744 } else if (getArgumentName(ce->getArg(1)) == "SC_PS") {
745 factor = 1000;
746 } else if (getArgumentName(ce->getArg(1)) == "SC_NS") {
747 factor = 1;
748 } else if (getArgumentName(ce->getArg(1)) == "SC_US") {
749 factor = 0.001;
750 } else if (getArgumentName(ce->getArg(1)) == "SC_MS") {
751 factor = 0.000001;
752 } else if (getArgumentName(ce->getArg(1)) == "SC_SEC") {
753 factor = 0.0000000001;
754 }
755 return (atof(getArgumentName(ce->getArg(0)).c_str()) * factor);
756 }
757}
758
760 if (CXXMemberCallExpr *ce = dyn_cast<CXXMemberCallExpr>(stmt)) {
761 return (getArgumentName(ce->getArg(0)));
762 }
763}
764
766 if (CXXMemberCallExpr *ce = dyn_cast<CXXMemberCallExpr>(stmt)) {
767 if (ce->getNumArgs() > 1) {
768 return true;
769 }
770 }
771 return false;
772}
773
775 if (arg == NULL) return string("NULL");
776
777 clang::LangOptions LangOpts;
778 LangOpts.CPlusPlus = true;
779 clang::PrintingPolicy Policy(LangOpts);
780
781 string TypeS;
782
783 llvm::raw_string_ostream s(TypeS);
784
785 arg->printPretty(s, 0, Policy);
786 // _os << ", argument: " << s.str() << "\n";
787 return s.str();
788}
789
791 if (CXXMemberCallExpr *ce = dyn_cast<CXXMemberCallExpr>(stmt)) {
792 if (ce->getNumArgs() == 1) {
793 string eventName = getArgumentName(ce->getArg(0));
794
795 if (eventName == "SC_ZERO_TIME") {
796 return true;
797 } else {
798 return false;
799 }
800 }
801 }
802 return false;
803}
804
806 if (CXXMemberCallExpr *ce = dyn_cast<CXXMemberCallExpr>(stmt)) {
807 if (ce->getNumArgs() == 1) {
808 return true;
809 }
810 }
811 return false;
812}
813
817
821
823 susCFGVectorType susCFGVector = _susCFGVector;
824
825 for (unsigned int i = 0; i < susCFGVector.size(); i++) {
826 _os << "\n Block ID : " << susCFGVector.at(i)->getBlockID();
827 _os << "\n Is Wait Block : " << susCFGVector.at(i)->isWaitBlock();
828 if (susCFGVector.at(i)->getParentBlockID()) {
829 _os << "\n Parent ID : " << susCFGVector.at(i)->getParentBlockID();
830 SusCFG *parentBlock = susCFGVector.at(i)->getParentSusCFGBlock();
831
832 _os << "\n Parent Block ID : " << parentBlock->getBlockID();
833 _os << "\n Size of Children : "
834 << parentBlock->getChildBlockList().size();
835 }
836 vector<SusCFG *> predBlocks = susCFGVector.at(i)->getPredBlocks();
837 vector<SusCFG *> succBlocks = susCFGVector.at(i)->getSuccBlocks();
838 _os << "\n Predecessor Blocks : ";
839 for (unsigned int j = 0; j < predBlocks.size(); j++) {
840 if (predBlocks.at(j)) {
841 _os << predBlocks.at(j)->getBlockID() << " ";
842 }
843 }
844 _os << "\n Successor Blocks : ";
845 for (unsigned int j = 0; j < succBlocks.size(); j++) {
846 if (succBlocks.at(j)) {
847 _os << succBlocks.at(j)->getBlockID() << " ";
848 }
849 }
850 }
851}
852
854 vector<Transition *> transitionVector = _transitionVector;
855 _os << "\n Size of transitionVector : " << transitionVector.size();
856 for (unsigned int i = 0; i < transitionVector.size(); i++) {
857 Transition *t = transitionVector.at(i);
858 t->dump(_os);
859 }
860}
861
bool is_found(Node n1, Node n2)
bool generic_isFound(Container< Node, Allocator > &container, Node node)
State(SusCFG *, bool, bool, bool, bool)
vector< SusCFG * > getSuccBlocks()
void addParentBlock(CFGBlock *)
vector< SusCFG * > getChildBlockList()
vector< SusCFG * > getPredBlocks()
vector< SusCFG * > _childBlockList
vector< SusCFG * > _predBlocks
vector< SusCFG * > _succBlocks
SuspensionAutomata(vector< WaitContainer * >, CXXMethodDecl *, ASTContext *, llvm::raw_ostream &)
pair< SusCFG *, int > susCFGSuccIDPairType
pair< State *, vector< SusCFG * > > stateCommonCodeBlockPairType
pair< SusCFG *, State * > susCFGStatePairType
stateCommonCodeBlockMapType _stateCommonCodeBlockMap
vector< Transition * > transitionVectorType
void addRemainingBlocks(State *, vector< SusCFG * > &)
vector< SusCFG * > modifDFS(SusCFG *, State *)
bool isFound(vector< SusCFG * >, SusCFG *)
void checkInsert(vector< SusCFG * >, vector< SusCFG * > &)
vector< SusCFG * > _codeBlockVector
vector< SusCFG * > returnCodeBlocks()