OpenADFortTk (including Open64 and OpenAnalysis references)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
DUGStandard.cpp
Go to the documentation of this file.
1 
14 //--------------------------------------------------------------------
15 //--------------------------------------------------------------------
16 
17 // standard headers
18 
19 #include <string.h>
20 #include <stdlib.h>
21 #include <iostream>
22 using std::ostream;
23 using std::endl;
24 using std::cout;
25 using std::cerr;
26 
27 #include "DUGStandard.hpp"
28 
29 namespace OA {
30  namespace DUG {
31 
32 //--------------------------------------------------------------------
33 
34 //--------------------------------------------------------------------
35 // must be updated any time DUG::Interface::EdgeType changes
36 static const char *sEdgeTypeToString[] = {
37  "F",
38  "C",
39  "R",
40  "P"
41 // "CFLOW",
42 // "CALL",
43 // "RETURN",
44 // "PARAM"
45 };
46 static const char *sNodeTypeToString[] = {
47  "FORMALPARAM_NODE",
48  "NONEFORMAL_NODE",
49 };
50 
51 //--------------------------------------------------------------------
54 void Node::Ctor() {
55 
57 
58  mVaried = false;
59  mUseful = false;
60  mSelfDependent = false;
61 #ifdef DEBUG_DUAA
62  static unsigned nodeCnt=0;
63  nodeCnt++;
64  std::cout << "getId(" << getId() << ")" << std::endl;
65  std::cout << "nodeCnt(" << nodeCnt << ")" << std::endl;
66 #endif
67 }
68 
69 
70 OA_ptr<EdgeInterface> EdgesIterator::currentDUGEdge() const
71 {
72  return current().convert<Edge>();
73 }
74 
75 
76 
77 OA_ptr<NodeInterface> NodesIterator::currentDUGNode() const
78 {
79  return current().convert<Node>();
80 }
81 
82 
83 
84 
85 //--------------------------------------------------------------------
86 void
87 Node::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
88 {
89  os << sNodeTypeToString[mType] << std::endl;
90 }
91 
92 bool Node::operator==(DGraph::NodeInterface& other)
93 {
94 
95  return mDGNode->operator==(other);
96 }
97 
98 bool Node::operator<(DGraph::NodeInterface& other)
99 {
100  return mDGNode->operator<(other);
101 }
102 
103 
104 
105 void
106 Node::longdump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
107 {
108  // print the node ID
109  os << "DUGStandard Node: ";
110  dump(os,ir);
111 
112  if (isAnEntry()) {
113  os << " (ENTRY)";
114  } else if (isAnExit()) {
115  os << " (EXIT)";
116  }
117  os << endl;
118 
119  // print the source(s)
120  unsigned int count = 0;
121  OA_ptr<NodesIteratorInterface> srcIter = getDUGSourceNodesIterator();
122  for ( ; srcIter->isValid(); ++(*srcIter), ++count) {
123  OA_ptr<NodeInterface> node = srcIter->currentDUGNode();
124  if (count == 0) { os << " <-- ("; }
125  else { os << ", "; }
126 
127  node->dump(os,ir);
128  }
129  if (count > 0) { os << ")" << endl; }
130 
131  // print the sink(s)
132  count = 0;
133  OA_ptr<NodesIteratorInterface> outIter = getDUGSinkNodesIterator();
134  for ( ; outIter->isValid(); ++(*outIter), ++count) {
135  OA_ptr<NodeInterface> node = outIter->currentDUGNode();
136  if (count == 0) { os << " --> ("; }
137  else { os << ", "; }
138 
139  node->dump(os,ir);
140  }
141  if (count > 0) { os << ")" << endl; }
142 }
143 
144 void
145 Node::dumpdot (ostream& os, OA_ptr<DUGIRInterface> ir)
146 {
147  SymHandle sym = getSym();
148  IRHandle ih = getDef();
149  std::string str = ir->toString(sym);
150 
151  char buf1[20], buf2[20];
152  sprintf(buf1, "(%u)\\n", getId());
153  sprintf(buf2, "@%u", ih.hval());
154 
155  std::string::size_type loc = str.find( "::", 0);
156  if( loc != std::string::npos ) str.erase(loc, 2);
157 
158  str.insert(loc, std::string(buf1));
159  str.append(std::string(buf2));
160 
161  OA_ptr<Location> memLoc = mDUG->mIR->getLocation(mProc, sym);
162  if (memLoc.ptrEqual(0)){
163 #ifdef DEBUG_DUAA
164  std::cout << "^^^^^ NULL LOCATION ^^^^^" << std::endl;
165  std::cout << "\tmProc(" << mDUG->mIR->toString(mProc);
166  std::cout << "), sym(" << mDUG->mIR->toString(sym)
167  << ")" << std::endl;
168  if (mDef == IRHandle(0) || mDef == IRHandle(1) || mDef == IRHandle(2))
169  std::cout << "stmt(012)" << std::endl;
170  else
171  std::cout << "stmt(" << mDUG->mIR->toString((StmtHandle)mDef)
172  << ")" << std::endl;
173 #endif
174  }
175  else if (!memLoc->isLocal()) {
176  str.erase(0, loc);
177  str.insert(0, std::string("JWGLOBAL"));
178  }
179 
180  os << "\"" << str << "\"";
181 }
182 
183 //--------------------------------------------------------------------
184 
185 OA_ptr<DGraph::EdgesIteratorInterface>
187 {
189 }
190 
191 OA_ptr<DGraph::EdgesIteratorInterface>
193 {
195 }
196 
197 OA_ptr<DGraph::NodesIteratorInterface>
199 {
201 }
202 
203 OA_ptr<DGraph::NodesIteratorInterface>
205 {
207 }
208 
209 OA_ptr<EdgesIteratorInterface>
211 {
212  OA_ptr<EdgesIterator> retval;
213  retval = new EdgesIterator(getIncomingEdgesIterator());
214  return retval;
215 
216 }
217 
218 OA_ptr<EdgesIteratorInterface>
220 {
221  OA_ptr<EdgesIterator> retval;
222  retval = new EdgesIterator(getOutgoingEdgesIterator());
223  return retval;
224 
225 }
226 
227 OA_ptr<NodesIteratorInterface>
229 {
230  OA_ptr<NodesIterator> retval;
231  retval = new NodesIterator(getSourceNodesIterator());
232  return retval;
233 
234 }
235 
236 OA_ptr<NodesIteratorInterface>
238 {
239  OA_ptr<NodesIterator> retval;
240  retval = new NodesIterator(getSinkNodesIterator());
241  return retval;
242 
243 }
244 
245 
246 
247 //--------------------------------------------------------------------
248 //--------------------------------------------------------------------
249 Edge::Edge (OA_ptr<DUGStandard> pDUG,
250  OA_ptr<Node> pNode1,
251  OA_ptr<Node> pNode2,
252  EdgeType pType, CallHandle call,
253  ProcHandle proc)
254  : mDUG(pDUG), mNode1(pNode1), mNode2(pNode2), mType(pType),
255  mCall(call), mProc(proc)
256 {
257 
258  // create DGraphEdge for associated DGraph
259  mDGEdge = new DGraph::EdgeImplement(pNode1->mDGNode,
260  pNode2->mDGNode);
261 
262 }
263 
264 
265 //--------------------------------------------------------------------
266 bool Edge::operator==(DGraph::EdgeInterface& other)
267 {
268 
269  return mDGEdge->operator==(other);
270 }
271 
272 bool Edge::operator<(DGraph::EdgeInterface& other)
273 {
274  return mDGEdge->operator<(other);
275 }
276 
277 
278 
279 void Edge::dump(ostream& os)
280 {
281  os << sEdgeTypeToString[mType];
282 }
283 
284 void filterStr(std::string& s)
285 {
286  std::string::size_type loc = s.find( "::", 0);
287  if( loc != std::string::npos ) s.erase(0, loc+2);
288 }
289 
290 
291 void Edge::dumpdot(ostream& os, OA_ptr<DUGIRInterface> ir)
292 {
293  OA_ptr<NodeInterface> srcNode = getDUGSource();
294  OA_ptr<NodeInterface> sinkNode = getDUGSink();
295 
296  srcNode->dumpdot(os, ir);
297  os << "->";
298  sinkNode->dumpdot(os, ir);
299  dumpdot_label(os, ir);
300 }
301 
302 
303 
304 void Edge::dumpdot_label(ostream& os, OA_ptr<DUGIRInterface> ir)
305 {
306  CallHandle call = getCall();
307  EdgeType etype = getType();
308  os << "[label=\"" << sEdgeTypeToString[etype];
309  if (call != CallHandle(0)) os << "(" << call.hval() << ")";
310  os << "\\n";
311 
312  ProcHandle proc = getProc();
313  std::string procStr = ir->toString(proc);
314  filterStr(procStr);
315  os << procStr;
316 
317  if (call != CallHandle(0)){
318  if (etype == CALL_EDGE)
319  os << "\\n-> ";
320  else{
321  assert(etype == RETURN_EDGE);
322  os << "\\n<- ";
323  }
324  SymHandle calleeSym = ir->getSymHandle(call);
325  procStr = ir->toString(calleeSym);
326  filterStr(procStr);
327  os << procStr;
328  os << "\", style=dashed];" << endl;
329  }
330  else
331  os << "\"];" << endl;
332 }
333 
334 
335 //--------------------------------------------------------------------
336 //--------------------------------------------------------------------
337 DUGStandard::DUGStandard(
338  OA_ptr<DUGIRInterface> pIR,
339  OA_ptr<DataFlow::ParamBindings> pParamBind)
340  : mIR(pIR), mParamBind(pParamBind)
341 {
342  mEntry = mExit = NULL;
343  mDGraph = new DGraph::DGraphImplement;
344  mCallNodes = new std::list<OA_ptr<Node> >;
345  mReturnNodes = new std::list<OA_ptr<Node> >;
346  mActiveSymSet = new std::set<SymHandle>;
347  mActiveMemRefSet = new std::set<MemRefHandle>;
348  mActiveStmtSet = new std::set<StmtHandle>;
349  mUnknownLocActive = false;
350 }
351 
352 
353 DUGStandard::~DUGStandard()
354 {
355  mEntry = NULL;
356  mExit = NULL;
357 }
358 
359 //--------------------------------------------------------------------
360 // DUGStandard Methods
361 //--------------------------------------------------------------------
362 
363 OA_ptr<Edge>
364 DUGStandard::getDUGEdge(
365  const OA_ptr<DGraph::EdgeInterface> dgEdge) const
366 {
367 
368 
369  assert (0);
370  OA_ptr<Edge> retval;
371  return retval;
372 }
373 
374 OA_ptr<Node>
375 DUGStandard::getDUGNode(
376  const OA_ptr<DGraph::NodeInterface> dgNode) const
377 {
378  assert(0);
379  OA_ptr<Node> retval;
380  return retval;
381 }
382 
383 void DUGStandard::addEdge(OA_ptr<DGraph::EdgeInterface> pEdge)
384 {
385  mDGraph->addEdge(pEdge);
386 }
387 
388 void DUGStandard::addNode(OA_ptr<DGraph::NodeInterface> pNode)
389 {
390 
391  mDGraph->addNode(pNode);
392 }
393 
394 
395 OA_ptr<DGraph::NodesIteratorInterface> DUGStandard::getNodesIterator() const
396 {
397  return mDGraph->getNodesIterator();
398 }
399 
400 OA_ptr<DGraph::NodesIteratorInterface>
401 DUGStandard::getEntryNodesIterator( ) const
402 {
403 
404  return mDGraph->getEntryNodesIterator();
405 }
406 
407 OA_ptr<DGraph::NodesIteratorInterface>
408 DUGStandard::getExitNodesIterator( ) const
409 {
410  return mDGraph->getExitNodesIterator();
411 }
412 
413 
414 OA_ptr<DGraph::EdgesIteratorInterface> DUGStandard::getEdgesIterator() const
415 {
416 
417  return mDGraph->getEdgesIterator();
418 }
419 
420 OA_ptr<DGraph::NodesIteratorInterface> DUGStandard::getDFSIterator(OA_ptr<DGraph::NodeInterface> n)
421 {
422 
423 
424  return mDGraph->getDFSIterator(n);
425 }
426 
427 OA_ptr<DGraph::NodesIteratorInterface> DUGStandard::getBFSIterator()
428 {
429  assert(0);
430  OA_ptr<DGraph::NodesIteratorInterface> retval;
431  return retval;
432 }
433 
434 
435 OA_ptr<DGraph::NodesIteratorInterface>
436 DUGStandard::getReversePostDFSIterator( DGraph::DGraphEdgeDirection pOrient)
437 {
438  return mDGraph->getReversePostDFSIterator(pOrient);
439 }
440 
441 OA_ptr<DGraph::NodesIteratorInterface>
442 DUGStandard::getReversePostDFSIterator(OA_ptr<DGraph::NodeInterface> root,
444 {
445  assert(0);
446 }
447 
453 OA_ptr<DGraph::NodesIteratorInterface>
454 DUGStandard::getPostDFSIterator(DGraph::DGraphEdgeDirection pOrient)
455 {
456  assert(0);
457 }
458 
459 OA_ptr<DGraph::NodesIteratorInterface>
460 DUGStandard::getPostDFSIterator(OA_ptr<DGraph::NodeInterface> root,
462 {
463  assert(0);
464 }
465 
466 
467 OA_ptr<NodesIteratorInterface> DUGStandard::getDUGNodesIterator() const
468 {
469  OA_ptr<NodesIterator> retval;
470  retval = new NodesIterator(getNodesIterator());
471  return retval;
472 
473 }
474 
475 
476 OA_ptr<NodesIteratorInterface>
477 DUGStandard::getDUGEntryNodesIterator( ) const
478 {
479  OA_ptr<NodesIterator> retval;
480  retval = new NodesIterator(getEntryNodesIterator());
481  return retval;
482 
483 
484 }
485 
486 OA_ptr<NodesIteratorInterface>
487 DUGStandard::getDUGExitNodesIterator( ) const
488 {
489  OA_ptr<NodesIterator> retval;
490  retval = new NodesIterator(getExitNodesIterator());
491  return retval;
492 
493 
494 }
495 
496 OA_ptr<EdgesIteratorInterface> DUGStandard::getDUGEdgesIterator() const
497 {
498  OA_ptr<EdgesIterator> retval;
499  retval = new EdgesIterator(getEdgesIterator());
500  return retval;
501 
502 
503 }
504 
505 
506 OA_ptr<NodesIteratorInterface>
507 DUGStandard::getDUGReversePostDFSIterator( DGraph::DGraphEdgeDirection pOrient)
508 {
509  OA_ptr<NodesIterator> retval;
510  retval = new NodesIterator(getReversePostDFSIterator(pOrient));
511  return retval;
512 }
513 
514 OA_ptr<NodesIteratorInterface>
515 DUGStandard::getDUGDFSIterator(OA_ptr<NodeInterface> n)
516 {
517  OA_ptr<NodesIterator> retval;
518  retval = new NodesIterator(getDFSIterator(n));
519  return retval;
520 
521 
522 }
523 
524 void
525 DUGStandard::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
526 {
527  os << "===== DUGStandard: =====\n"
528  << endl;
529 
530  // print the contents of all the nodes
531  OA_ptr<NodesIteratorInterface> nodeIter = getDUGNodesIterator();
532  for ( ; nodeIter->isValid(); ++(*nodeIter)) {
533  OA_ptr<NodeInterface> node = nodeIter->currentDUGNode();
534  node->longdump(os, ir);
535  os << endl;
536  }
537 
538  os << "====================" << endl;
539 
540 }
541 
542 
543 
544 void
545 DUGStandard::dumpdot(ostream& os, OA_ptr<DUGIRInterface> ir)
546 {
547 
548  os << "digraph OA_DUG {" << endl;
549  os << "node [shape=rectangle];" << endl;
550 
551  // then output nodes and edges by procedure
552  OA_ptr<EdgesIteratorInterface> iter;
553  iter = getDUGEdgesIterator();
554  for (; iter->isValid(); (*iter)++ ) {
555  OA_ptr<EdgeInterface> edge = iter->currentDUGEdge();
556  edge->dumpdot(os, ir);
557  }
558 
559  os << "}" << endl;
560  os.flush();
561 }
562 
563 OA_ptr<Node>
564 DUGStandard::getNode(IRSymHandle ish, ProcHandle proc){
565 
566  IRHandle ih = ish.first;
567  SymHandle sym = ish.second;
568  assert(sym);
569 #ifdef DEBUG_DUAA
570  std::cout << "getNode: " << mIR->toString(sym) << "("
571  << sym.hval() << ")@" << mIR->toString(proc) << "("
572  << proc.hval() << ") --- ";
573 #endif
574  IRSymHandle key(ih, sym);
575 
576  OA_ptr<Node> retval = mSymToNode[key];
577  if (!retval.ptrEqual(0)) {
578 #ifdef DEBUG_DUAA
579  std::cout << "found itself" << std::endl;
580 #endif
581  return retval;
582  }
583  OA_ptr<Location> loc = mIR->getLocation(proc, sym);
584  assert (!loc.ptrEqual(0));
585  OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
586  OA_ptr<SymHandleIterator> symIter = nloc->getFullOverlapIter();
587  for ( ; symIter->isValid(); (*symIter)++) {
588  retval = mSymToNode[IRSymHandle(ih,symIter->current())];
589  if (!retval.ptrEqual(0)) {
590 #ifdef DEBUG_DUAA
591  std::cout << "found FullOverlap" << std::endl;
592 #endif
593  return retval;
594  }
595  }
596 #if 0
597  symIter = nloc->getPartOverlapIter();
598  for ( ; symIter->isValid(); (*symIter)++) {
599  retval = mSymToNode[IRSymHandle(ih,symIter->current())];
600  if (!retval.ptrEqual(0)) {
601 #ifdef DEBUG_DUAA
602  std::cout << "found PartOverlap" << std::endl;
603 #endif
604  return retval;
605  }
606  }
607 #endif
608 
609  assert (retval.ptrEqual(0));
610  OA_ptr<DUGStandard> temp; temp = this;
611  retval = new Node(temp, proc, ih, sym);
612  assert(!retval.ptrEqual(0));
613  mSymToNode[key] = retval;
614  addNode(retval);
615 #ifdef DEBUG_DUAA
616  std::cout << "added" << std::endl;
617 #endif
618  if (isIndependent(proc, sym) || isDependent(proc, sym))
619  mInDepSymToNodes[sym].insert(retval);
620 
621  return retval;
622 }
623 
624 // true if a node exists for 'loc'
625 bool
626 DUGStandard::isNode(IRSymHandle ish, ProcHandle proc){
627  IRHandle ih = ish.first;
628  SymHandle sym = ish.second;
629  assert(sym);
630 #ifdef DEBUG_DUAA
631  std::cout << "isNode: " << mIR->toString(sym) << "("
632  << sym.hval() << ")@" << mIR->toString(proc) << "("
633  << proc.hval() << ") --- ";
634 #endif
635  std::pair<IRHandle, SymHandle> key(ih, sym);
636  OA_ptr<Node> retval = mSymToNode[key];
637 
638  if (!retval.ptrEqual(0)) {
639 #ifdef DEBUG_DUAA
640  std::cout << "found itself" << std::endl;
641 #endif
642  return true;
643  }
644 
645  OA_ptr<Location> loc = mIR->getLocation(proc, sym);
646  if (loc.ptrEqual(0)) {
647 #ifdef DEBUG_DUAA
648  std::cout << "NULL location" << std::endl;
649 #endif
650  return false;
651  }
652  OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
654  for ( ; symIter->isValid(); (*symIter)++) {
655  retval = mSymToNode[IRSymHandle(ih,symIter->current())];
656  if (!retval.ptrEqual(0)) {
657 #ifdef DEBUG_DUAA
658  std::cout << "found FullOverlap" << std::endl;
659 #endif
660  return true;
661  }
662  }
663 #if 0
664  symIter = nloc->getPartOverlapIter();
665  for ( ; symIter->isValid(); (*symIter)++) {
666  retval = mSymToNode[IRSymHandle(ih,symIter->current())];
667  if (!retval.ptrEqual(0)) {
668 #ifdef DEBUG_DUAA
669  std::cout << "found PartOverlap" << std::endl;
670 #endif
671  return true;
672  }
673  }
674 #endif
675 #ifdef DEBUG_DUAA
676  std::cout << "not found" << std::endl;
677 #endif
678  return false;
679 }
680 
681 void
682 DUGStandard::insertActiveSymSet(OA_ptr<Location> loc)
683 {
684  // Unknown
685  if (loc->isaUnknown()) {
686 
687  mUnknownLocActive = true;
688 
689  // Named
690  } else if (loc->isaNamed()) {
691 
692  OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
693 #ifdef DEBUG_DUAA
694  std::cout << "DUGStandard::insertActiveSymSet:(loc)";
695  loc->dump(std::cout, mIR);
696  std::cout << std::endl;
697 #endif
698  insertActiveSymSet( nloc->getSymHandle() );
699 
701  for ( ; symIter->isValid(); (*symIter)++) {
702 #ifdef DEBUG_DUAA
703  std::cout << "\tFullOverlap: " << mIR->toString(symIter->current());
704  std::cout << std::endl;
705 #endif
706  insertActiveSymSet( symIter->current());
707  }
708  symIter = nloc->getPartOverlapIter();
709  for ( ; symIter->isValid(); (*symIter)++) {
710 #ifdef DEBUG_DUAA
711  std::cout << "\tPartialOverlap: ";
712  std::cout << std::endl;
713 #endif
714  insertActiveSymSet(symIter->current());
715  }
716 
717  // Unnamed
718  } else if (loc->isaUnnamed()) {
719 
720  //assert(0);
721  // not handling this yet
722 
723  // Invisible
724  } else if (loc->isaInvisible()) {
725 
726  OA_ptr<InvisibleLoc> invLoc
727  = loc.convert<InvisibleLoc>();
728  OA_ptr<MemRefExpr> mre = invLoc->getMemRefExpr();
729 
730  // get symbol from memory reference expression if no derefs
731  // FIXME: here need another visitor for MemRefExpr, for now assuming
732  // only named ones
733  if (mre->isaNamed()) {
734  OA_ptr<NamedRef> namedRef
735  = namedRef.convert<NamedRef>();
736  insertActiveSymSet( namedRef->getSymHandle() );
737  } else {
738  assert(0);
739  }
740 
741  // LocSubSet
742  } else if (loc->isaSubSet()) {
743 
744  OA_ptr<Location> baseLoc = loc->getBaseLoc();
745  // FIXME: now really want to call visitor on this guy but instead will just
746  // call this function recursively
747  insertActiveSymSet(baseLoc);
748 
749  } else {
750 
751  assert(0);
752  }
753 }
754 
755 
756 void
757 Node::setActive(SymHandle sym)
758 {
759  assert(mProc);
760  // will be storing activity results for stmt and memrefs in
761  // ActiveStandard for current procedure
762  if (mDUG->mActiveMap[mProc].ptrEqual(0)) {
763  mDUG->mActiveMap[mProc] = new OA::Activity::ActiveStandard(mProc);
764  }
765 
766  mDUG->insertActiveSymSet(sym);
767 
768  std::set<MemRefHandle> mrefSet;
769  mrefSet = mDUG->getMemRefSet(sym);
770  if (!mrefSet.empty()){
771  std::set<MemRefHandle>::iterator i = mrefSet.begin();
772  for(; i != mrefSet.end(); i++) {
773  mDUG->insertActiveMemRefSet(*i, mProc);
774  }
775  }
776 
777 
778  std::set<StmtHandle> stmtSet;
779  stmtSet = mDUG->getStmtSet(sym);
780  if (!stmtSet.empty()){
781  std::set<StmtHandle>::iterator i = stmtSet.begin();
782  for(; i != stmtSet.end(); i++)
783  mDUG->insertActiveStmtSet(*i, mProc);
784  }
785 
786 }
787 
788 
789 void
790 Node::setActive()
791 {
792  setActive(mSym);
793 
794  OA_ptr<Location> loc = mDUG->mIR->getLocation(getProc(), mSym);
795  OA_ptr<NamedLoc> nmloc = loc.convert<NamedLoc>();
796  assert(!nmloc.ptrEqual(0));
797  OA_ptr<SymHandleIterator> overlapIter = nmloc->getFullOverlapIter();
798  for ( ; overlapIter->isValid(); (*overlapIter)++ ) {
799  SymHandle sym = overlapIter->current();
800  setActive(sym);
801  }
802 
803  overlapIter = nmloc->getPartOverlapIter();
804  for ( ; overlapIter->isValid(); (*overlapIter)++ ) {
805  SymHandle sym = overlapIter->current();
806  setActive(sym);
807  }
808 }
809 
810 
811 void
812 Node::markVaried(std::list<CallHandle>& callStack,
814  std::set<OA_ptr<EdgeInterface> >& visited,
815  std::set<std::pair<unsigned,unsigned> >& onPath,
816  ProcHandle proc,
817  SymHandle prevSym,
818  OA_ptr<EdgeInterface> parenEdge)
819 {
820  SymHandle currSym = getSym();
821 
822  EdgeType parenEType = CFLOW_EDGE;
823  CallHandle parenCall = CallHandle(0);
824  if (!parenEdge.ptrEqual(0)) {
825  parenEType = parenEdge->getType();
826  parenCall = parenEdge->getCall();
827  }
828 
829 
830 #ifdef DEBUG_DUAA
831  std::cout << "-v->";
832  if (parenEdge.ptrEqual(0)) {
833  std::cout << "NULL edge";
834  }else
835  parenEdge->dumpdot(std::cout, mDUG->mIR);
836  std::cout << std::endl;
837 #endif
838  bool isVariedBefore = isVaried();
839  int nonParentSuccessors = 0;
840  setVaried();
841 
842  bool valueThroughGlobals = false;
843  if (callStack.front() == CallHandle(1)) valueThroughGlobals = true;
844 
845  // set up iterator for successor edges
846  OA_ptr<EdgesIteratorInterface> succIterPtr;
847  succIterPtr = getDUGOutgoingEdgesIterator();
848  // iterate over the successors
849  for (; succIterPtr->isValid(); ++(*succIterPtr)) {
850 
851  OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
852  OA_ptr<NodeInterface> succNode = succEdge->getDUGSink();
853 
854  SymHandle succSym = succNode->getSym();
855  unsigned succId = succNode->getId();
856  EdgeType etype = succEdge->getType();
857 
858  std::pair<unsigned, unsigned> pathNode;
859  switch(etype) {
860  case CALL_EDGE:
861  pathNode = std::pair<unsigned,unsigned>
862  (succEdge->getCall().hval(),succId); break;
863  case PARAM_EDGE:
864  if (callStack.empty())
865  pathNode = std::pair<unsigned,unsigned>(1,succId);
866  else
867  pathNode = std::pair<unsigned,unsigned>
868  (callStack.front().hval(),succId); break;
869  case RETURN_EDGE:
870  case CFLOW_EDGE:
871  pathNode = std::pair<unsigned,unsigned>(1,succId); break;
872  default: assert(0);
873  }
874 
875  if (succSym != prevSym || parenCall != succEdge->getCall()) nonParentSuccessors++;
876 
877  if (visited.find(succEdge) != visited.end() ||
878  onPath.find(pathNode) != onPath.end() )
879  {
880  continue;
881  }
882 
883  onPath.insert(pathNode);
884 
885  switch(etype) {
886  case (CALL_EDGE):
887  {
888  // to deal with value passing through global variables between procedures
889  ProcHandle callerProc = succEdge->getSourceProc();
890  if (proc != callerProc){
891 #ifdef DEBUG_DUAA
892  std::cout << "valthruglobals: begin" << std::endl;
893 #endif
894  callStack.push_front(CallHandle(1));
895  }
896 
897  callStack.push_front(succEdge->getCall());
898  visited.insert(succEdge);
899 
900  succNode->markVaried(callStack, ir, visited, onPath,
901  succEdge->getSinkProc(), currSym,
902  succEdge);
903  callStack.pop_front();
904  if (proc != callerProc){
905 #ifdef DEBUG_DUAA
906  std::cout << "valthruglobals: end" << std::endl;
907 #endif
908  callStack.pop_front();
909  }
910  break;
911  }
912  case (RETURN_EDGE):
913  if (callStack.front() == succEdge->getCall() || valueThroughGlobals){
914  if (!valueThroughGlobals) callStack.pop_front();
915  visited.insert(succEdge);
916 
917  succNode->markVaried(callStack, ir, visited, onPath,
918  succEdge->getProc(), currSym,
919  succEdge);
920  if (!valueThroughGlobals) callStack.push_front(succEdge->getCall());
921  }
922 #ifdef DEBUG_DUAA
923  else{
924  std::cout << "markVaried: stackTop(" << (unsigned)callStack.front().hval()
925  << ") <-> edgeCallExp("
926  << (unsigned)succEdge->getCall().hval() << ")" << std::endl;
927  }
928 #endif
929  break;
930  default: // for both CFLOW_EDGE and PARAM_EDGE
931  if (succEdge->getType() != PARAM_EDGE)
932  visited.insert(succEdge);
933  // value passing through global variables between procedures
934  ProcHandle succProc = succEdge->getProc();
935  if (proc != succProc) {
936  callStack.push_front(CallHandle(1));
937 
938  succNode->markVaried(callStack, ir, visited, onPath,
939  succProc, currSym, succEdge);
940  callStack.pop_front();
941  }
942  else{
943  succNode->markVaried(callStack, ir, visited, onPath,
944  proc, currSym, succEdge);
945  }
946  break;
947  }
948 
949  onPath.erase(pathNode);
950  }
951  // Actual or formal parameters without any outgoing edges shouldn't be
952  // activated.
953  if (nonParentSuccessors == 0 && !isVariedBefore && !isSelfDependent() &&
954  ( parenEType == CALL_EDGE || parenEType == RETURN_EDGE) &&
955  !mDUG->isDependent(getProc(), getSym()) ){
956  unsetVaried();
957 #ifdef DEBUG_DUAA
958  std::cout << "unsetVaried("; dumpdot(std::cout, mDUG->mIR);
959  std::cout << ")" << std::endl;
960 #endif
961  }
962 #ifdef DEBUG_DUAA
963  std::cout << "<-" << std::endl;
964 #endif
965 }
966 
967 void
968 Node::markUseful(std::list<CallHandle>& callStack,
970  std::set<OA_ptr<EdgeInterface> >& visited,
971  std::set<std::pair<unsigned,unsigned> >& onPath,
972  ProcHandle proc,
973  SymHandle prevSym,
974  OA_ptr<EdgeInterface> parenEdge)
975 {
976  if (!isVaried()) {
977  return;
978  }
979  SymHandle currSym = getSym();
980 
981  EdgeType parenEType = CFLOW_EDGE;
982  CallHandle parenCall = CallHandle(0);
983  if (!parenEdge.ptrEqual(0)) {
984  parenEType = parenEdge->getType();
985  parenCall = parenEdge->getCall();
986  }
987 
988 #ifdef DEBUG_DUAA
989  std::cout << "-u->";
990  if (parenEdge.ptrEqual(0)) {
991  std::cout << "NULL edge";
992  }else
993  parenEdge->dumpdot(std::cout, mDUG->mIR);
994  std::cout << "(call:" << parenCall.hval() << ")" << std::endl;
995 #endif
996  bool isUsefulBefore = isUseful();
997  setUseful();
998  int nonChildAncestors = 0;
999 
1000  bool valueThroughGlobals = false;
1001  if (callStack.front() == CallHandle(1)) valueThroughGlobals = true;
1002 
1003  // set up iterator for predecessor edges
1004  OA_ptr<EdgesIteratorInterface> predIterPtr;
1005  predIterPtr = getDUGIncomingEdgesIterator();
1006  // iterate over the predecessors unless 'this' node is for indenepdent variable
1007  // we assume no independent variables are dependent on another independent variables
1008  for (; predIterPtr->isValid(); ++(*predIterPtr)) {
1009 
1010  OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
1011  OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
1012 
1013  SymHandle predSym = predNode->getSym();
1014  unsigned predId = predNode->getId();
1015  EdgeType etype = predEdge->getType();
1016 
1017  std::pair<unsigned, unsigned> pathNode;
1018  switch(etype) {
1019  case RETURN_EDGE:
1020  pathNode = std::pair<unsigned,unsigned>
1021  (predEdge->getCall().hval(),predId); break;
1022  case PARAM_EDGE:
1023  if (callStack.empty())
1024  pathNode = std::pair<unsigned,unsigned>(1,predId);
1025  else
1026  pathNode = std::pair<unsigned,unsigned>
1027  (callStack.front().hval(),predId); break;
1028  case CALL_EDGE:
1029  case CFLOW_EDGE:
1030  pathNode = std::pair<unsigned,unsigned>
1031  (1,predId); break;
1032  default: assert(0);
1033  }
1034  if (predSym != prevSym || parenCall != predEdge->getCall()) nonChildAncestors++;
1035  if (visited.find(predEdge) != visited.end() ||
1036  onPath.find(pathNode) != onPath.end() ) continue;
1037  onPath.insert(pathNode);
1038 
1039  switch(etype) {
1040  case (CALL_EDGE):
1041  if (callStack.front() == predEdge->getCall() || valueThroughGlobals ){
1042  if (!valueThroughGlobals) callStack.pop_front();
1043  visited.insert(predEdge);
1044  predNode->markUseful(callStack, ir, visited, onPath,
1045  predEdge->getProc(), currSym, predEdge);
1046  if (!valueThroughGlobals) callStack.push_front(predEdge->getCall());
1047  }
1048  break;
1049  case (RETURN_EDGE):
1050  {
1051  ProcHandle callerProc = predEdge->getSinkProc();
1052  if (proc != callerProc){
1053  callStack.push_front(CallHandle(1));
1054 #ifdef DEBUG_DUAA
1055  std::cout << "valthruglobals: begin" << std::endl;
1056 #endif
1057  }
1058 
1059  callStack.push_front(predEdge->getCall());
1060  visited.insert(predEdge);
1061  predNode->markUseful(callStack, ir, visited, onPath,
1062  predEdge->getSourceProc(),
1063  currSym, predEdge);
1064  callStack.pop_front();
1065  if (proc != callerProc){
1066  callStack.pop_front();
1067 #ifdef DEBUG_DUAA
1068  std::cout << "valthruglobals: end" << std::endl;
1069 #endif
1070  }
1071  break;
1072  }
1073  default: // for both CFLOW_EDGE and PARAM_EDGE
1074  if (predEdge->getType() != PARAM_EDGE) visited.insert(predEdge);
1075  ProcHandle predProc = predEdge->getProc();
1076  if (proc != predProc) {
1077  callStack.push_front(CallHandle(1));
1078 #ifdef DEBUG_DUAA
1079  std::cout << "valthruglobals: begin" << std::endl;
1080 #endif
1081  predNode->markUseful(callStack, ir, visited, onPath,
1082  predProc, currSym, predEdge);
1083  callStack.pop_front();
1084 #ifdef DEBUG_DUAA
1085  std::cout << "valthruglobals: end" << std::endl;
1086 #endif
1087  }
1088  else
1089  {
1090  predNode->markUseful(callStack, ir, visited, onPath,
1091  proc, currSym, predEdge);
1092  }
1093  break;
1094  }
1095 
1096  onPath.erase(pathNode);
1097  }
1098 
1099  unsigned currId = getId();
1100  // Formal parameters without any outgoing edges shouldn't be
1101  // activated.
1102  if (nonChildAncestors == 0 && !isUsefulBefore && !isSelfDependent() &&
1103  ( parenEType == RETURN_EDGE || parenEType == CALL_EDGE) &&
1104  !mDUG->isIndependent(getProc(), getSym()) ){
1105 #ifdef DEBUG_DUAA
1106  std::cout << "unsetUseful(" << currId << ")" << std::endl;
1107 #endif
1108  unsetUseful();
1109  }else{
1110 #ifdef DEBUG_DUAA
1111  std::cout << "setActive(" << currId << ")" << std::endl;
1112 #endif
1113  setActive();
1114  }
1115 
1116 #ifdef DEBUG_DUAA
1117  std::cout << "<-" << std::endl;
1118 #endif
1119 }
1120 
1122 bool DUGStandard::isActive(SymHandle sym)
1123 {
1124  // an unknown location is active, therefore all symbols are active
1125  if (mUnknownLocActive) {
1126  return true;
1127  } else if (mActiveSymSet->find(sym) != mActiveSymSet->end()) {
1128  return true;
1129  } else {
1130  return false;
1131  }
1132 }
1133 
1134 
1135 
1137 bool DUGStandard::isActive(MemRefHandle memref)
1138 {
1139  if (mActiveMemRefSet->find(memref) != mActiveMemRefSet->end()) {
1140  return true;
1141  } else {
1142  return false;
1143  }
1144 }
1145 
1146 
1147 
1148 // 'true' if there is a path from 'useNode' to 'this'
1149 bool
1150 Node::isPathFrom(OA_ptr<NodeInterface> useNode,
1151  std::set<OA_ptr<NodeInterface> >& visited)
1152 {
1153  if (useNode.ptrEqual(this)) return true;
1154 
1155  // traverse backward from this nodes
1156  OA_ptr<EdgesIteratorInterface> predIterPtr
1157  = getDUGIncomingEdgesIterator();
1158  for (; predIterPtr->isValid(); ++(*predIterPtr)) {
1159  OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
1160  OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
1161 
1162  if (visited.find(predNode) != visited.end()) continue;
1163  visited.insert(predNode);
1164  if (predNode->isPathFrom(useNode, visited)) return true;
1165  }
1166 
1167  return false;
1168 }
1169 
1170 
1171 
1172 // true if this has an outgoing edge to other procedures
1173 bool
1174 Node::hasOutgoingEdgesToOtherProcs(ProcHandle proc)
1175 {
1176  OA_ptr<EdgesIteratorInterface> succIterPtr
1177  = getDUGOutgoingEdgesIterator();
1178  for (; succIterPtr->isValid(); ++(*succIterPtr)) {
1179  OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
1180  if (succEdge->getType() != CFLOW_EDGE) continue;
1181  if (succEdge->getProc() != proc) return true;
1182  }
1183 
1184  return false;
1185 }
1186 
1187 
1188 
1189 // returns a set of outgoing nodes of this proc
1190 void
1191 Node::findOutgoingNodes(ProcHandle proc,
1192  std::set<IRSymHandle>& OutGoingNodeSet,
1193  std::set<IRSymHandle>& visited)
1194 {
1195  IRSymHandle nodeKey = getIRSymHandle();
1196  if (visited.find(nodeKey) != visited.end()) return;
1197  visited.insert(nodeKey);
1198 
1199  if (hasOutgoingEdgesToOtherProcs(proc))
1200  OutGoingNodeSet.insert(nodeKey);
1201 
1202  // traverse foreward from this nodes
1203  OA_ptr<EdgesIteratorInterface> succIterPtr
1204  = getDUGOutgoingEdgesIterator();
1205  for (; succIterPtr->isValid(); ++(*succIterPtr)) {
1206  OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
1207  OA_ptr<NodeInterface> succNode = succEdge->getDUGSink();
1208 
1209  if (succEdge->getType() != CFLOW_EDGE) continue;
1210  if (succEdge->getProc() != proc) continue;
1211 
1212  succNode->findOutgoingNodes(proc, OutGoingNodeSet, visited);
1213  }
1214 }
1215 
1216 
1217 
1218 // true if this has an incoming edge to other procedures
1219 bool
1220 Node::hasIncomingEdgesFromOtherProcs(ProcHandle proc)
1221 {
1222  OA_ptr<EdgesIteratorInterface> predIterPtr
1223  = getDUGIncomingEdgesIterator();
1224  for (; predIterPtr->isValid(); ++(*predIterPtr)) {
1225  OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
1226  if (predEdge->getType() != CFLOW_EDGE) continue;
1227  if (predEdge->getProc() != proc) return true;
1228  }
1229  return false;
1230 }
1231 
1232 
1233 
1234 // returns a set of incoming nodes of this proc
1235 void
1236 Node::findIncomingNodes(ProcHandle proc,
1237  std::set<IRSymHandle>& InComingNodeSet,
1238  std::set<IRSymHandle>& visited)
1239 {
1240  IRSymHandle nodeKey = getIRSymHandle();
1241  if (visited.find(nodeKey) != visited.end()) return;
1242  visited.insert(nodeKey);
1243 
1244  if (hasIncomingEdgesFromOtherProcs(proc))
1245  InComingNodeSet.insert(nodeKey);
1246 
1247  // traverse backward from this nodes
1248  OA_ptr<EdgesIteratorInterface> predIterPtr = getDUGIncomingEdgesIterator();
1249  for (; predIterPtr->isValid(); ++(*predIterPtr)) {
1250  OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
1251  OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
1252 
1253  if (predEdge->getType() != CFLOW_EDGE) continue;
1254  if (predEdge->getProc() != proc) continue;
1255 
1256  predNode->findIncomingNodes(proc, InComingNodeSet, visited);
1257  }
1258 }
1259 
1260 
1261 
1262 bool
1263 Node::hasEdgesToOtherProc(ProcHandle proc, std::set<IRSymHandle>& visited)
1264 {
1265  IRSymHandle ish = getIRSymHandle();
1266  if (visited.find(ish) != visited.end()) return false;
1267  visited.insert(ish);
1268 
1269  // traverse foreward from this nodes
1270  OA_ptr<EdgesIteratorInterface> succIterPtr = getDUGOutgoingEdgesIterator();
1271  for (; succIterPtr->isValid(); ++(*succIterPtr)) {
1272  OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
1273  OA_ptr<NodeInterface> succNode = succEdge->getDUGSink();
1274 
1275  EdgeType etype = succEdge->getType();
1276  if (etype != CFLOW_EDGE && etype != CALL_EDGE) continue;
1277  if (succEdge->getProc() != proc) return true;
1278  if (etype == CFLOW_EDGE && succNode->hasEdgesToOtherProc(proc, visited))
1279  return true;
1280  }
1281  return false;
1282 }
1283 
1284 
1285 
1286 // true if this has an incoming edge to other procedures
1287 bool
1288 Node::hasEdgesFromOtherProc(ProcHandle proc, std::set<IRSymHandle>& visited)
1289 {
1290  IRSymHandle ish = getIRSymHandle();
1291  if (visited.find(ish) != visited.end()) return false;
1292  visited.insert(ish);
1293 
1294  // traverse backward from this nodes
1295  OA_ptr<EdgesIteratorInterface> predIterPtr = getDUGIncomingEdgesIterator();
1296  for (; predIterPtr->isValid(); ++(*predIterPtr)) {
1297  OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
1298  OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
1299 
1300  EdgeType etype = predEdge->getType();
1301  if (etype != CFLOW_EDGE) continue;
1302  if (predEdge->getProc() != proc) return true;
1303  if (predNode->hasEdgesFromOtherProc(proc, visited))
1304  return true;
1305  }
1306  return false;
1307 }
1308 
1309 
1310 
1311  } // end namespace DUGStandard
1312 } // end namespace OA