CSFSActivity/DUGStandard.cpp

Go to the documentation of this file.
00001 
00014 //--------------------------------------------------------------------
00015 //--------------------------------------------------------------------
00016 
00017 // standard headers
00018 
00019 #include <string.h>
00020 #include <stdlib.h>
00021 #include <iostream>
00022 using std::ostream;
00023 using std::endl;
00024 using std::cout;
00025 using std::cerr;
00026 
00027 #include "DUGStandard.hpp"
00028 
00029 namespace OA {
00030     namespace DUG {
00031 
00032 //--------------------------------------------------------------------
00033 
00034 //--------------------------------------------------------------------
00035 // must be updated any time DUG::Interface::EdgeType changes
00036 static const char *sEdgeTypeToString[] = { 
00037     "F",
00038     "C",
00039     "R",
00040     "P"
00041 //   "CFLOW",
00042 //   "CALL",
00043 //   "RETURN",
00044 //   "PARAM"
00045 };
00046 static const char *sNodeTypeToString[] = { 
00047     "FORMALPARAM_NODE",
00048     "NONEFORMAL_NODE",
00049 };
00050 
00051 //--------------------------------------------------------------------
00054 void Node::Ctor() { 
00055 
00056     mDGNode = new DGraph::NodeImplement;
00057 
00058     mVaried = false;
00059     mUseful = false;
00060     mSelfDependent = false;
00061 #ifdef DEBUG_DUAA
00062     static unsigned nodeCnt=0;
00063     nodeCnt++;
00064     std::cout << "getId(" << getId() << ")" << std::endl;
00065     std::cout << "nodeCnt(" << nodeCnt << ")" << std::endl;
00066 #endif
00067 }
00068 
00069 
00070 OA_ptr<EdgeInterface> EdgesIterator::currentDUGEdge() const
00071 {
00072     return current().convert<Edge>();
00073 }
00074 
00075 
00076 
00077 OA_ptr<NodeInterface> NodesIterator::currentDUGNode() const
00078 {
00079     return current().convert<Node>();
00080 }
00081 
00082 
00083 
00084 
00085 //--------------------------------------------------------------------
00086 void
00087 Node::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00088 {
00089     os << sNodeTypeToString[mType] << std::endl;
00090 }
00091 
00092 bool Node::operator==(DGraph::NodeInterface& other) 
00093 {
00094     
00095     return mDGNode->operator==(other);
00096 }
00097 
00098 bool Node::operator<(DGraph::NodeInterface& other) 
00099 {
00100     return mDGNode->operator<(other);
00101 }
00102 
00103 
00104 
00105 void
00106 Node::longdump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00107 {
00108     // print the node ID
00109     os << "DUGStandard Node: ";
00110     dump(os,ir);
00111   
00112     if (isAnEntry()) {
00113         os << " (ENTRY)";
00114     } else if (isAnExit()) {
00115         os << " (EXIT)"; 
00116     }
00117     os << endl;
00118   
00119     // print the source(s)
00120     unsigned int count = 0;
00121     OA_ptr<NodesIteratorInterface> srcIter = getDUGSourceNodesIterator();
00122     for ( ; srcIter->isValid(); ++(*srcIter), ++count) {
00123         OA_ptr<NodeInterface> node = srcIter->currentDUGNode();
00124         if (count == 0) { os << " <-- ("; }
00125         else            { os << ", "; }
00126 
00127         node->dump(os,ir);
00128     }
00129     if (count > 0) { os << ")" << endl; }
00130   
00131     // print the sink(s)
00132     count = 0;
00133     OA_ptr<NodesIteratorInterface> outIter = getDUGSinkNodesIterator();
00134     for ( ; outIter->isValid(); ++(*outIter), ++count) {
00135         OA_ptr<NodeInterface> node = outIter->currentDUGNode();
00136         if (count == 0) { os << " --> ("; } 
00137         else            { os << ", "; }
00138     
00139         node->dump(os,ir);
00140     }
00141     if (count > 0) { os << ")" << endl; }
00142 }
00143 
00144 void
00145 Node::dumpdot (ostream& os, OA_ptr<DUGIRInterface> ir)
00146 {
00147     SymHandle sym   = getSym();
00148     IRHandle  ih    = getDef(); 
00149     std::string str = ir->toString(sym);
00150 
00151     char buf1[20], buf2[20];
00152     sprintf(buf1, "(%u)\\n", getId());
00153     sprintf(buf2, "@%u", ih.hval());
00154 
00155     std::string::size_type loc = str.find( "::", 0);
00156     if( loc != std::string::npos ) str.erase(loc, 2);
00157 
00158     str.insert(loc, std::string(buf1));
00159     str.append(std::string(buf2));
00160 
00161     OA_ptr<Location> memLoc = mDUG->mIR->getLocation(mProc, sym);
00162     if (memLoc.ptrEqual(0)){
00163 #ifdef DEBUG_DUAA
00164         std::cout << "^^^^^ NULL LOCATION ^^^^^" << std::endl;
00165         std::cout << "\tmProc(" << mDUG->mIR->toString(mProc);
00166         std::cout << "), sym(" << mDUG->mIR->toString(sym) 
00167                   << ")" << std::endl;
00168         if (mDef == IRHandle(0) || mDef == IRHandle(1) || mDef == IRHandle(2))
00169             std::cout << "stmt(012)" << std::endl;
00170         else
00171             std::cout << "stmt(" << mDUG->mIR->toString((StmtHandle)mDef)
00172                       << ")" << std::endl;
00173 #endif
00174     }
00175     else if (!memLoc->isLocal()) {
00176         str.erase(0, loc);
00177         str.insert(0, std::string("JWGLOBAL"));
00178     }
00179 
00180     os << "\"" << str << "\"";
00181 }
00182 
00183 //--------------------------------------------------------------------
00184 
00185 OA_ptr<DGraph::EdgesIteratorInterface> 
00186 Node::getIncomingEdgesIterator() const
00187 {
00188     return mDGNode->getIncomingEdgesIterator();
00189 }
00190 
00191 OA_ptr<DGraph::EdgesIteratorInterface> 
00192 Node::getOutgoingEdgesIterator() const
00193 {
00194     return mDGNode->getOutgoingEdgesIterator();
00195 }
00196 
00197 OA_ptr<DGraph::NodesIteratorInterface> 
00198 Node::getSourceNodesIterator() const
00199 {
00200     return mDGNode->getSourceNodesIterator();
00201 }
00202 
00203 OA_ptr<DGraph::NodesIteratorInterface> 
00204 Node::getSinkNodesIterator() const
00205 {
00206     return mDGNode->getSourceNodesIterator();
00207 }
00208 
00209 OA_ptr<EdgesIteratorInterface>
00210 Node::getDUGIncomingEdgesIterator() const
00211 {
00212     OA_ptr<EdgesIterator> retval;
00213     retval = new EdgesIterator(getIncomingEdgesIterator());
00214     return retval;
00215 
00216 }
00217 
00218 OA_ptr<EdgesIteratorInterface>
00219 Node::getDUGOutgoingEdgesIterator() const
00220 {
00221     OA_ptr<EdgesIterator> retval;
00222     retval = new EdgesIterator(getOutgoingEdgesIterator());
00223     return retval;
00224 
00225 }
00226 
00227 OA_ptr<NodesIteratorInterface>
00228 Node::getDUGSourceNodesIterator() const
00229 {
00230     OA_ptr<NodesIterator> retval;
00231     retval = new NodesIterator(getSourceNodesIterator());
00232     return retval;
00233 
00234 }
00235 
00236 OA_ptr<NodesIteratorInterface>
00237 Node::getDUGSinkNodesIterator() const
00238 {
00239     OA_ptr<NodesIterator> retval;
00240     retval = new NodesIterator(getSinkNodesIterator());
00241     return retval;
00242 
00243 }
00244 
00245 
00246 
00247 //--------------------------------------------------------------------
00248 //--------------------------------------------------------------------
00249 Edge::Edge (OA_ptr<DUGStandard> pDUG,
00250             OA_ptr<Node> pNode1, 
00251             OA_ptr<Node> pNode2, 
00252             EdgeType pType, CallHandle call,
00253             ProcHandle proc)
00254     : mDUG(pDUG), mNode1(pNode1), mNode2(pNode2), mType(pType), 
00255       mCall(call), mProc(proc)
00256 {
00257 
00258     // create DGraphEdge for associated DGraph
00259     mDGEdge = new DGraph::EdgeImplement(pNode1->mDGNode,
00260                                         pNode2->mDGNode);
00261 
00262 }
00263 
00264 
00265 //--------------------------------------------------------------------
00266 bool Edge::operator==(DGraph::EdgeInterface& other) 
00267 {
00268     
00269     return mDGEdge->operator==(other);
00270 }
00271 
00272 bool Edge::operator<(DGraph::EdgeInterface& other) 
00273 {
00274     return mDGEdge->operator<(other);
00275 }
00276 
00277 
00278 
00279 void Edge::dump(ostream& os)
00280 {
00281     os << sEdgeTypeToString[mType];
00282 }
00283 
00284 void filterStr(std::string& s)
00285 {
00286     std::string::size_type loc = s.find( "::", 0);
00287     if( loc != std::string::npos ) s.erase(0, loc+2);
00288 }
00289 
00290 
00291 void Edge::dumpdot(ostream& os, OA_ptr<DUGIRInterface> ir)
00292 {
00293     OA_ptr<NodeInterface> srcNode  = getDUGSource();
00294     OA_ptr<NodeInterface> sinkNode = getDUGSink();
00295 
00296     srcNode->dumpdot(os, ir);
00297     os << "->";
00298     sinkNode->dumpdot(os, ir);
00299     dumpdot_label(os, ir);
00300 }
00301 
00302 
00303 
00304 void Edge::dumpdot_label(ostream& os, OA_ptr<DUGIRInterface> ir)
00305 {
00306     CallHandle call = getCall();
00307     EdgeType etype = getType();
00308     os << "[label=\"" << sEdgeTypeToString[etype];
00309     if (call != CallHandle(0)) os << "(" << call.hval() << ")";
00310     os << "\\n";
00311 
00312     ProcHandle proc = getProc();
00313     std::string procStr = ir->toString(proc);
00314     filterStr(procStr);
00315     os << procStr;
00316 
00317     if (call != CallHandle(0)){
00318         if (etype == CALL_EDGE)
00319             os << "\\n-> ";
00320         else{
00321             assert(etype == RETURN_EDGE);
00322             os << "\\n<- ";
00323         }
00324         SymHandle calleeSym = ir->getSymHandle(call);
00325         procStr = ir->toString(calleeSym);
00326         filterStr(procStr);
00327         os << procStr;
00328         os << "\", style=dashed];" << endl;
00329     }
00330     else
00331         os << "\"];" << endl;
00332 }
00333 
00334 
00335 //--------------------------------------------------------------------
00336 //--------------------------------------------------------------------
00337 DUGStandard::DUGStandard(
00338     OA_ptr<DUGIRInterface> pIR,
00339     OA_ptr<DataFlow::ParamBindings> pParamBind)
00340     : mIR(pIR), mParamBind(pParamBind)
00341 {
00342     mEntry       = mExit = NULL;
00343     mDGraph      = new DGraph::DGraphImplement;
00344     mCallNodes   = new std::list<OA_ptr<Node> >;
00345     mReturnNodes = new std::list<OA_ptr<Node> >;
00346     mActiveSymSet    = new std::set<SymHandle>;
00347     mActiveMemRefSet = new std::set<MemRefHandle>;
00348     mActiveStmtSet   = new std::set<StmtHandle>;
00349     mUnknownLocActive = false;
00350 }
00351 
00352 
00353 DUGStandard::~DUGStandard()
00354 {
00355     mEntry = NULL;
00356     mExit = NULL;
00357 }
00358 
00359 //--------------------------------------------------------------------
00360 // DUGStandard Methods
00361 //--------------------------------------------------------------------
00362 
00363 OA_ptr<Edge> 
00364 DUGStandard::getDUGEdge(
00365     const OA_ptr<DGraph::EdgeInterface> dgEdge) const
00366 {
00367 
00368     
00369     assert (0); 
00370     OA_ptr<Edge> retval;
00371     return retval;
00372 }
00373 
00374 OA_ptr<Node> 
00375 DUGStandard::getDUGNode(
00376     const OA_ptr<DGraph::NodeInterface> dgNode) const
00377 {
00378     assert(0);   
00379     OA_ptr<Node> retval;
00380     return retval; 
00381 }
00382 
00383 void DUGStandard::addEdge(OA_ptr<DGraph::EdgeInterface> pEdge)
00384 {
00385     mDGraph->addEdge(pEdge);
00386 }
00387 
00388 void DUGStandard::addNode(OA_ptr<DGraph::NodeInterface> pNode)
00389 {
00390     
00391     mDGraph->addNode(pNode);
00392 }
00393 
00394 
00395 OA_ptr<DGraph::NodesIteratorInterface> DUGStandard::getNodesIterator() const
00396 {
00397     return mDGraph->getNodesIterator();
00398 }
00399 
00400 OA_ptr<DGraph::NodesIteratorInterface>
00401 DUGStandard::getEntryNodesIterator( ) const
00402 {
00403     
00404     return mDGraph->getEntryNodesIterator();
00405 }
00406 
00407 OA_ptr<DGraph::NodesIteratorInterface>
00408 DUGStandard::getExitNodesIterator( ) const
00409 {
00410     return mDGraph->getExitNodesIterator();
00411 }
00412 
00413 
00414 OA_ptr<DGraph::EdgesIteratorInterface> DUGStandard::getEdgesIterator() const
00415 {
00416     
00417     return mDGraph->getEdgesIterator();
00418 }
00419 
00420 OA_ptr<DGraph::NodesIteratorInterface> DUGStandard::getDFSIterator(OA_ptr<DGraph::NodeInterface> n) 
00421 {
00422     
00423     
00424     return mDGraph->getDFSIterator(n);
00425 }
00426 
00427 OA_ptr<DGraph::NodesIteratorInterface> DUGStandard::getBFSIterator() 
00428 { 
00429     assert(0); 
00430     OA_ptr<DGraph::NodesIteratorInterface> retval; 
00431     return retval;
00432 }
00433 
00434 
00435 OA_ptr<DGraph::NodesIteratorInterface>
00436 DUGStandard::getReversePostDFSIterator( DGraph::DGraphEdgeDirection pOrient)
00437 {
00438     return mDGraph->getReversePostDFSIterator(pOrient);
00439 }
00440 
00441 OA_ptr<DGraph::NodesIteratorInterface>
00442 DUGStandard::getReversePostDFSIterator(OA_ptr<DGraph::NodeInterface> root, 
00443                                        DGraph::DGraphEdgeDirection pOrient)
00444 {
00445     assert(0);
00446 }
00447 
00453 OA_ptr<DGraph::NodesIteratorInterface> 
00454 DUGStandard::getPostDFSIterator(DGraph::DGraphEdgeDirection pOrient)
00455 {
00456     assert(0);
00457 }
00458 
00459 OA_ptr<DGraph::NodesIteratorInterface>
00460 DUGStandard::getPostDFSIterator(OA_ptr<DGraph::NodeInterface> root, 
00461                                 DGraph::DGraphEdgeDirection pOrient)
00462 {
00463     assert(0);
00464 }
00465 
00466 
00467 OA_ptr<NodesIteratorInterface> DUGStandard::getDUGNodesIterator() const
00468 {
00469     OA_ptr<NodesIterator> retval;
00470     retval = new NodesIterator(getNodesIterator());
00471     return retval;
00472 
00473 }
00474 
00475 
00476 OA_ptr<NodesIteratorInterface>
00477 DUGStandard::getDUGEntryNodesIterator( ) const
00478 {
00479     OA_ptr<NodesIterator> retval;
00480     retval = new NodesIterator(getEntryNodesIterator());
00481     return retval;
00482 
00483 
00484 }
00485 
00486 OA_ptr<NodesIteratorInterface>
00487 DUGStandard::getDUGExitNodesIterator( ) const
00488 {
00489     OA_ptr<NodesIterator> retval;
00490     retval = new NodesIterator(getExitNodesIterator());
00491     return retval;
00492 
00493 
00494 }
00495 
00496 OA_ptr<EdgesIteratorInterface> DUGStandard::getDUGEdgesIterator() const
00497 {
00498     OA_ptr<EdgesIterator> retval;
00499     retval = new EdgesIterator(getEdgesIterator());
00500     return retval;
00501 
00502 
00503 }
00504 
00505 
00506 OA_ptr<NodesIteratorInterface>
00507 DUGStandard::getDUGReversePostDFSIterator( DGraph::DGraphEdgeDirection pOrient)
00508 {
00509     OA_ptr<NodesIterator> retval;
00510     retval = new NodesIterator(getReversePostDFSIterator(pOrient));
00511     return retval;
00512 }
00513 
00514 OA_ptr<NodesIteratorInterface>
00515 DUGStandard::getDUGDFSIterator(OA_ptr<NodeInterface> n)
00516 {
00517     OA_ptr<NodesIterator> retval;
00518     retval = new NodesIterator(getDFSIterator(n));
00519     return retval;
00520 
00521 
00522 }
00523 
00524 void
00525 DUGStandard::dump (ostream& os, OA_ptr<IRHandlesIRInterface> ir)
00526 {
00527     os << "===== DUGStandard: =====\n"
00528        << endl;
00529   
00530     // print the contents of all the nodes
00531     OA_ptr<NodesIteratorInterface> nodeIter = getDUGNodesIterator();
00532     for ( ; nodeIter->isValid(); ++(*nodeIter)) {
00533         OA_ptr<NodeInterface> node = nodeIter->currentDUGNode();
00534         node->longdump(os, ir);
00535         os << endl;
00536     }
00537   
00538     os << "====================" << endl;
00539 
00540 }
00541 
00542 
00543 
00544 void
00545 DUGStandard::dumpdot(ostream& os, OA_ptr<DUGIRInterface> ir)
00546 {
00547 
00548     os << "digraph OA_DUG {" << endl;
00549     os << "node [shape=rectangle];" << endl;
00550 
00551     // then output nodes and edges by procedure
00552     OA_ptr<EdgesIteratorInterface> iter;
00553     iter = getDUGEdgesIterator();
00554     for (; iter->isValid(); (*iter)++ ) {
00555         OA_ptr<EdgeInterface> edge = iter->currentDUGEdge();
00556         edge->dumpdot(os, ir);
00557     }
00558 
00559     os << "}" << endl;
00560     os.flush();
00561 }
00562 
00563 OA_ptr<Node> 
00564 DUGStandard::getNode(IRSymHandle ish, ProcHandle proc){
00565     
00566     IRHandle ih = ish.first;
00567     SymHandle sym = ish.second;
00568     assert(sym);
00569 #ifdef DEBUG_DUAA
00570     std::cout << "getNode: " << mIR->toString(sym) << "("
00571               << sym.hval() << ")@" << mIR->toString(proc) << "("
00572               << proc.hval() << ") --- ";
00573 #endif
00574     IRSymHandle key(ih, sym);
00575 
00576     OA_ptr<Node> retval = mSymToNode[key];
00577     if (!retval.ptrEqual(0)) {
00578 #ifdef DEBUG_DUAA
00579         std::cout << "found itself" << std::endl;
00580 #endif
00581         return retval;
00582     }
00583     OA_ptr<Location> loc = mIR->getLocation(proc, sym);
00584     assert (!loc.ptrEqual(0));
00585     OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
00586     OA_ptr<SymHandleIterator> symIter = nloc->getFullOverlapIter();
00587     for ( ; symIter->isValid(); (*symIter)++) {
00588         retval = mSymToNode[IRSymHandle(ih,symIter->current())];
00589         if (!retval.ptrEqual(0)) {
00590 #ifdef DEBUG_DUAA
00591             std::cout << "found FullOverlap" << std::endl;
00592 #endif
00593             return retval;
00594         }
00595     }
00596 #if 0
00597     symIter = nloc->getPartOverlapIter();
00598     for ( ; symIter->isValid(); (*symIter)++) {
00599         retval = mSymToNode[IRSymHandle(ih,symIter->current())];
00600         if (!retval.ptrEqual(0)) {
00601 #ifdef DEBUG_DUAA
00602             std::cout << "found PartOverlap" << std::endl;
00603 #endif
00604             return retval;
00605         }
00606     }
00607 #endif
00608 
00609     assert (retval.ptrEqual(0));
00610     OA_ptr<DUGStandard> temp; temp = this;
00611     retval = new Node(temp, proc, ih, sym);
00612     assert(!retval.ptrEqual(0));
00613     mSymToNode[key] = retval;
00614     addNode(retval);
00615 #ifdef DEBUG_DUAA
00616     std::cout << "added" << std::endl;
00617 #endif
00618     if (isIndependent(proc, sym) || isDependent(proc, sym))
00619         mInDepSymToNodes[sym].insert(retval);
00620 
00621     return retval;
00622 }
00623 
00624 // true if a node exists for 'loc'
00625 bool
00626 DUGStandard::isNode(IRSymHandle ish, ProcHandle proc){
00627     IRHandle ih = ish.first;
00628     SymHandle sym = ish.second;
00629     assert(sym);
00630 #ifdef DEBUG_DUAA
00631     std::cout << "isNode: " << mIR->toString(sym) << "("
00632               << sym.hval() << ")@" << mIR->toString(proc) << "("
00633               << proc.hval() << ") --- ";
00634 #endif
00635     std::pair<IRHandle, SymHandle> key(ih, sym);
00636     OA_ptr<Node> retval = mSymToNode[key];
00637 
00638     if (!retval.ptrEqual(0)) {
00639 #ifdef DEBUG_DUAA
00640         std::cout << "found itself" << std::endl;
00641 #endif
00642         return true;
00643     }
00644 
00645     OA_ptr<Location> loc = mIR->getLocation(proc, sym);
00646     if (loc.ptrEqual(0)) {
00647 #ifdef DEBUG_DUAA
00648         std::cout << "NULL location" << std::endl;
00649 #endif
00650         return false;
00651     }
00652     OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
00653     OA_ptr<SymHandleIterator> symIter = nloc->getFullOverlapIter();
00654     for ( ; symIter->isValid(); (*symIter)++) {
00655         retval = mSymToNode[IRSymHandle(ih,symIter->current())];
00656         if (!retval.ptrEqual(0)) {
00657 #ifdef DEBUG_DUAA
00658             std::cout << "found FullOverlap" << std::endl;
00659 #endif
00660             return true;
00661         }
00662     }
00663 #if 0
00664     symIter = nloc->getPartOverlapIter();
00665     for ( ; symIter->isValid(); (*symIter)++) {
00666         retval = mSymToNode[IRSymHandle(ih,symIter->current())];
00667         if (!retval.ptrEqual(0)) {
00668 #ifdef DEBUG_DUAA
00669             std::cout << "found PartOverlap" << std::endl;
00670 #endif
00671             return true;
00672         }
00673     }
00674 #endif
00675 #ifdef DEBUG_DUAA
00676     std::cout << "not found" << std::endl;
00677 #endif
00678     return false;
00679 }
00680 
00681 void 
00682 DUGStandard::insertActiveSymSet(OA_ptr<Location> loc)
00683 {
00684     // Unknown
00685     if (loc->isaUnknown()) {
00686 
00687         mUnknownLocActive = true;
00688 
00689         // Named
00690     } else if (loc->isaNamed()) {
00691       
00692         OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
00693 #ifdef DEBUG_DUAA
00694         std::cout << "DUGStandard::insertActiveSymSet:(loc)"; 
00695         loc->dump(std::cout, mIR);
00696         std::cout << std::endl;
00697 #endif  
00698         insertActiveSymSet( nloc->getSymHandle() );
00699 
00700         OA_ptr<SymHandleIterator> symIter = nloc->getFullOverlapIter();
00701         for ( ; symIter->isValid(); (*symIter)++) {
00702 #ifdef DEBUG_DUAA
00703             std::cout << "\tFullOverlap: " << mIR->toString(symIter->current()); 
00704             std::cout << std::endl;
00705 #endif  
00706             insertActiveSymSet( symIter->current());
00707         }
00708         symIter = nloc->getPartOverlapIter();
00709         for ( ; symIter->isValid(); (*symIter)++) {
00710 #ifdef DEBUG_DUAA
00711             std::cout << "\tPartialOverlap: "; 
00712             std::cout << std::endl;
00713 #endif  
00714             insertActiveSymSet(symIter->current());
00715         }
00716  
00717         // Unnamed
00718     } else if (loc->isaUnnamed()) {
00719     
00720         //assert(0);
00721         // not handling this yet
00722 
00723         // Invisible
00724     } else if (loc->isaInvisible()) {
00725 
00726         OA_ptr<InvisibleLoc> invLoc 
00727             = loc.convert<InvisibleLoc>();
00728         OA_ptr<MemRefExpr> mre = invLoc->getMemRefExpr();
00729 
00730         // get symbol from memory reference expression if no derefs
00731         // FIXME: here need another visitor for MemRefExpr, for now assuming
00732         // only named ones
00733         if (mre->isaNamed()) {
00734             OA_ptr<NamedRef> namedRef 
00735                 = namedRef.convert<NamedRef>();
00736             insertActiveSymSet( namedRef->getSymHandle() );
00737         } else {
00738             assert(0);
00739         }
00740 
00741         // LocSubSet
00742     } else if (loc->isaSubSet()) {
00743 
00744         OA_ptr<Location> baseLoc = loc->getBaseLoc();
00745         // FIXME: now really want to call visitor on this guy but instead will just
00746         // call this function recursively
00747         insertActiveSymSet(baseLoc);
00748 
00749     } else {
00750 
00751         assert(0);
00752     }
00753 }
00754 
00755 
00756 void 
00757 Node::setActive(SymHandle sym)
00758 {
00759     assert(mProc);
00760     // will be storing activity results for stmt and memrefs in
00761     // ActiveStandard for current procedure
00762     if (mDUG->mActiveMap[mProc].ptrEqual(0)) {
00763         mDUG->mActiveMap[mProc] = new OA::Activity::ActiveStandard(mProc);
00764     }
00765 
00766     mDUG->insertActiveSymSet(sym);
00767 
00768     std::set<MemRefHandle> mrefSet;
00769     mrefSet = mDUG->getMemRefSet(sym);
00770     if (!mrefSet.empty()){
00771         std::set<MemRefHandle>::iterator i = mrefSet.begin();
00772         for(; i != mrefSet.end(); i++) {
00773             mDUG->insertActiveMemRefSet(*i, mProc);
00774         }
00775     }
00776 
00777 
00778     std::set<StmtHandle> stmtSet;
00779     stmtSet = mDUG->getStmtSet(sym);
00780     if (!stmtSet.empty()){
00781         std::set<StmtHandle>::iterator i = stmtSet.begin();
00782         for(; i != stmtSet.end(); i++)
00783             mDUG->insertActiveStmtSet(*i, mProc);
00784     }
00785 
00786 }
00787 
00788 
00789 void 
00790 Node::setActive()
00791 {
00792     setActive(mSym);
00793 
00794     OA_ptr<Location> loc = mDUG->mIR->getLocation(getProc(), mSym);
00795     OA_ptr<NamedLoc> nmloc = loc.convert<NamedLoc>();
00796     assert(!nmloc.ptrEqual(0));
00797     OA_ptr<SymHandleIterator> overlapIter = nmloc->getFullOverlapIter();
00798     for ( ; overlapIter->isValid(); (*overlapIter)++ ) {
00799         SymHandle sym = overlapIter->current();
00800         setActive(sym);
00801     }
00802 
00803     overlapIter = nmloc->getPartOverlapIter();
00804     for ( ; overlapIter->isValid(); (*overlapIter)++ ) {
00805         SymHandle sym = overlapIter->current();
00806         setActive(sym);
00807     }
00808 }
00809 
00810 
00811 void 
00812 Node::markVaried(std::list<CallHandle>& callStack,
00813                  OA_ptr<Activity::ActivityIRInterface> ir,
00814                  std::set<OA_ptr<EdgeInterface> >& visited,
00815                  std::set<std::pair<unsigned,unsigned> >& onPath,
00816                  ProcHandle proc,
00817                  SymHandle prevSym, 
00818                  OA_ptr<EdgeInterface> parenEdge)
00819 { 
00820     SymHandle currSym = getSym();
00821 
00822     EdgeType parenEType = CFLOW_EDGE;
00823     CallHandle parenCall = CallHandle(0);
00824     if (!parenEdge.ptrEqual(0)) {
00825         parenEType = parenEdge->getType();
00826         parenCall = parenEdge->getCall();
00827     }
00828 
00829 
00830 #ifdef DEBUG_DUAA
00831     std::cout << "-v->"; 
00832     if (parenEdge.ptrEqual(0)) {
00833         std::cout << "NULL edge";
00834     }else
00835         parenEdge->dumpdot(std::cout, mDUG->mIR);
00836     std::cout << std::endl;
00837 #endif  
00838     bool isVariedBefore = isVaried();
00839     int nonParentSuccessors = 0;
00840     setVaried();
00841 
00842     bool valueThroughGlobals = false;
00843     if (callStack.front() == CallHandle(1)) valueThroughGlobals = true;
00844 
00845     // set up iterator for successor edges
00846     OA_ptr<EdgesIteratorInterface> succIterPtr;
00847     succIterPtr = getDUGOutgoingEdgesIterator();
00848     // iterate over the successors
00849     for (; succIterPtr->isValid(); ++(*succIterPtr)) {
00850 
00851         OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
00852         OA_ptr<NodeInterface> succNode = succEdge->getDUGSink();
00853 
00854         SymHandle succSym = succNode->getSym();
00855         unsigned succId = succNode->getId();
00856         EdgeType etype = succEdge->getType();
00857 
00858         std::pair<unsigned, unsigned> pathNode;
00859         switch(etype) {
00860             case CALL_EDGE: 
00861                 pathNode = std::pair<unsigned,unsigned>
00862                     (succEdge->getCall().hval(),succId); break;
00863             case PARAM_EDGE:
00864                 if (callStack.empty())
00865                     pathNode = std::pair<unsigned,unsigned>(1,succId); 
00866                 else
00867                     pathNode = std::pair<unsigned,unsigned>
00868                         (callStack.front().hval(),succId); break;
00869             case RETURN_EDGE:
00870             case CFLOW_EDGE:
00871                 pathNode = std::pair<unsigned,unsigned>(1,succId); break;
00872             default: assert(0);
00873         }
00874 
00875         if (succSym != prevSym || parenCall != succEdge->getCall()) nonParentSuccessors++;
00876 
00877         if (visited.find(succEdge) != visited.end() ||
00878             onPath.find(pathNode)  != onPath.end()  ) 
00879         {
00880             continue;
00881         }
00882 
00883         onPath.insert(pathNode);
00884 
00885         switch(etype) {
00886             case (CALL_EDGE):
00887             {
00888                 // to deal with value passing through global variables between procedures
00889                 ProcHandle callerProc = succEdge->getSourceProc();
00890                 if (proc != callerProc){ 
00891 #ifdef DEBUG_DUAA
00892                     std::cout << "valthruglobals: begin" << std::endl;
00893 #endif  
00894                     callStack.push_front(CallHandle(1));
00895                 }
00896           
00897                 callStack.push_front(succEdge->getCall());
00898                 visited.insert(succEdge);
00899         
00900                 succNode->markVaried(callStack, ir, visited, onPath, 
00901                                      succEdge->getSinkProc(), currSym, 
00902                                      succEdge);
00903                 callStack.pop_front();
00904                 if (proc != callerProc){ 
00905 #ifdef DEBUG_DUAA
00906                     std::cout << "valthruglobals: end" << std::endl;
00907 #endif  
00908                     callStack.pop_front();
00909                 }
00910                 break;
00911             }
00912             case (RETURN_EDGE):
00913                 if (callStack.front() == succEdge->getCall() || valueThroughGlobals){
00914                     if (!valueThroughGlobals) callStack.pop_front();
00915                     visited.insert(succEdge);
00916 
00917                     succNode->markVaried(callStack, ir, visited, onPath, 
00918                                          succEdge->getProc(), currSym, 
00919                                          succEdge);
00920                     if (!valueThroughGlobals) callStack.push_front(succEdge->getCall());
00921                 }
00922 #ifdef DEBUG_DUAA
00923                 else{
00924                     std::cout << "markVaried: stackTop(" << (unsigned)callStack.front().hval() 
00925                               << ") <-> edgeCallExp("
00926                               << (unsigned)succEdge->getCall().hval() << ")" << std::endl;
00927                 }
00928 #endif  
00929                 break;
00930             default: // for both CFLOW_EDGE and PARAM_EDGE
00931                 if (succEdge->getType() != PARAM_EDGE) 
00932                     visited.insert(succEdge);
00933                 // value passing through global variables between procedures
00934                 ProcHandle succProc = succEdge->getProc();
00935                 if (proc != succProc) {
00936                     callStack.push_front(CallHandle(1));
00937           
00938                     succNode->markVaried(callStack, ir, visited, onPath, 
00939                                          succProc, currSym, succEdge);
00940                     callStack.pop_front();
00941                 }
00942                 else{
00943                     succNode->markVaried(callStack, ir, visited, onPath, 
00944                                          proc, currSym, succEdge);
00945                 }
00946                 break;
00947         }
00948 
00949         onPath.erase(pathNode);
00950     }
00951     // Actual or formal parameters without any outgoing edges shouldn't be
00952     // activated.
00953     if (nonParentSuccessors == 0 && !isVariedBefore && !isSelfDependent() && 
00954         ( parenEType == CALL_EDGE || parenEType == RETURN_EDGE) && 
00955         !mDUG->isDependent(getProc(), getSym()) ){
00956         unsetVaried();
00957 #ifdef DEBUG_DUAA
00958         std::cout << "unsetVaried("; dumpdot(std::cout, mDUG->mIR); 
00959         std::cout << ")" << std::endl;
00960 #endif  
00961     }
00962 #ifdef DEBUG_DUAA
00963     std::cout << "<-" << std::endl;
00964 #endif  
00965 }
00966 
00967 void
00968 Node::markUseful(std::list<CallHandle>& callStack,
00969                  OA_ptr<Activity::ActivityIRInterface> ir,
00970                  std::set<OA_ptr<EdgeInterface> >& visited,
00971                  std::set<std::pair<unsigned,unsigned> >& onPath,
00972                  ProcHandle proc,
00973                  SymHandle prevSym, 
00974                  OA_ptr<EdgeInterface> parenEdge)
00975 {
00976     if (!isVaried()) {
00977         return;
00978     }
00979     SymHandle currSym = getSym();
00980 
00981     EdgeType parenEType = CFLOW_EDGE;
00982     CallHandle parenCall = CallHandle(0);
00983     if (!parenEdge.ptrEqual(0)) {
00984         parenEType = parenEdge->getType();
00985         parenCall = parenEdge->getCall();
00986     }
00987 
00988 #ifdef DEBUG_DUAA
00989     std::cout << "-u->"; 
00990     if (parenEdge.ptrEqual(0)) {
00991         std::cout << "NULL edge";
00992     }else
00993         parenEdge->dumpdot(std::cout, mDUG->mIR);
00994     std::cout << "(call:" << parenCall.hval() << ")" << std::endl; 
00995 #endif  
00996     bool isUsefulBefore = isUseful();
00997     setUseful();
00998     int nonChildAncestors = 0;
00999 
01000     bool valueThroughGlobals = false;
01001     if (callStack.front() == CallHandle(1)) valueThroughGlobals = true;
01002 
01003     // set up iterator for predecessor edges
01004     OA_ptr<EdgesIteratorInterface> predIterPtr;
01005     predIterPtr = getDUGIncomingEdgesIterator();
01006     // iterate over the predecessors unless 'this' node is for indenepdent variable
01007     // we assume no independent variables are dependent on another independent variables
01008     for (; predIterPtr->isValid(); ++(*predIterPtr)) {
01009       
01010         OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
01011         OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
01012 
01013         SymHandle predSym = predNode->getSym();
01014         unsigned predId = predNode->getId();
01015         EdgeType etype = predEdge->getType();
01016 
01017         std::pair<unsigned, unsigned> pathNode;
01018         switch(etype) {
01019             case RETURN_EDGE:
01020                 pathNode = std::pair<unsigned,unsigned>
01021                     (predEdge->getCall().hval(),predId); break;
01022             case PARAM_EDGE:
01023                 if (callStack.empty())
01024                     pathNode = std::pair<unsigned,unsigned>(1,predId); 
01025                 else
01026                     pathNode = std::pair<unsigned,unsigned>
01027                         (callStack.front().hval(),predId); break;
01028             case CALL_EDGE: 
01029             case CFLOW_EDGE:
01030                 pathNode = std::pair<unsigned,unsigned>
01031                     (1,predId); break;
01032             default: assert(0);
01033         }
01034         if (predSym != prevSym || parenCall != predEdge->getCall()) nonChildAncestors++;
01035         if (visited.find(predEdge) != visited.end() ||
01036             onPath.find(pathNode)  != onPath.end()  ) continue;
01037         onPath.insert(pathNode);
01038 
01039         switch(etype) {
01040             case (CALL_EDGE):
01041                 if (callStack.front() == predEdge->getCall() || valueThroughGlobals ){
01042                     if (!valueThroughGlobals) callStack.pop_front();
01043                     visited.insert(predEdge);
01044                     predNode->markUseful(callStack, ir, visited, onPath, 
01045                                          predEdge->getProc(), currSym, predEdge);
01046                     if (!valueThroughGlobals) callStack.push_front(predEdge->getCall());
01047                 }
01048                 break;
01049             case (RETURN_EDGE):
01050             {
01051                 ProcHandle callerProc = predEdge->getSinkProc();
01052                 if (proc != callerProc){ 
01053                     callStack.push_front(CallHandle(1));
01054 #ifdef DEBUG_DUAA
01055                     std::cout << "valthruglobals: begin" << std::endl;
01056 #endif  
01057                 }
01058 
01059                 callStack.push_front(predEdge->getCall());
01060                 visited.insert(predEdge);
01061                 predNode->markUseful(callStack, ir, visited, onPath, 
01062                                      predEdge->getSourceProc(), 
01063                                      currSym, predEdge);
01064                 callStack.pop_front();
01065                 if (proc != callerProc){ 
01066                     callStack.pop_front();
01067 #ifdef DEBUG_DUAA
01068                     std::cout << "valthruglobals: end" << std::endl;
01069 #endif  
01070                 }
01071                 break;
01072             }
01073             default: // for both CFLOW_EDGE and PARAM_EDGE
01074                 if (predEdge->getType() != PARAM_EDGE) visited.insert(predEdge);
01075                 ProcHandle predProc = predEdge->getProc();
01076                 if (proc != predProc) {
01077                     callStack.push_front(CallHandle(1));
01078 #ifdef DEBUG_DUAA
01079                     std::cout << "valthruglobals: begin" << std::endl;
01080 #endif  
01081                     predNode->markUseful(callStack, ir, visited, onPath, 
01082                                          predProc, currSym, predEdge);
01083                     callStack.pop_front();
01084 #ifdef DEBUG_DUAA
01085                     std::cout << "valthruglobals: end" << std::endl;
01086 #endif  
01087                 }
01088                 else
01089                 {
01090                     predNode->markUseful(callStack, ir, visited, onPath, 
01091                                          proc, currSym, predEdge);
01092                 }
01093                 break;
01094         }
01095 
01096         onPath.erase(pathNode);
01097     }
01098 
01099     unsigned currId = getId();
01100     // Formal parameters without any outgoing edges shouldn't be
01101     // activated.
01102     if (nonChildAncestors == 0 && !isUsefulBefore && !isSelfDependent() && 
01103         ( parenEType == RETURN_EDGE || parenEType == CALL_EDGE) &&
01104         !mDUG->isIndependent(getProc(), getSym()) ){
01105 #ifdef DEBUG_DUAA
01106         std::cout << "unsetUseful(" << currId << ")" << std::endl;
01107 #endif  
01108         unsetUseful();
01109     }else{
01110 #ifdef DEBUG_DUAA
01111         std::cout << "setActive(" << currId << ")" << std::endl;
01112 #endif  
01113         setActive();
01114     }
01115 
01116 #ifdef DEBUG_DUAA
01117     std::cout << "<-" << std::endl;
01118 #endif  
01119 }
01120 
01122 bool DUGStandard::isActive(SymHandle sym)
01123 {
01124     // an unknown location is active, therefore all symbols are active
01125     if (mUnknownLocActive) {
01126         return true;
01127     } else if (mActiveSymSet->find(sym) != mActiveSymSet->end()) {
01128         return true;
01129     } else {
01130         return false;
01131     }  
01132 }
01133 
01134 
01135 
01137 bool DUGStandard::isActive(MemRefHandle memref)
01138 {
01139     if (mActiveMemRefSet->find(memref) != mActiveMemRefSet->end()) {
01140         return true;
01141     } else {
01142         return false;
01143     }
01144 }
01145 
01146 
01147 
01148 // 'true' if there is a path from 'useNode' to 'this'
01149 bool
01150 Node::isPathFrom(OA_ptr<NodeInterface> useNode,
01151                  std::set<OA_ptr<NodeInterface> >& visited)
01152 { 
01153     if (useNode.ptrEqual(this)) return true;
01154 
01155     // traverse backward from this nodes
01156     OA_ptr<EdgesIteratorInterface> predIterPtr
01157         = getDUGIncomingEdgesIterator();
01158     for (; predIterPtr->isValid(); ++(*predIterPtr)) {
01159         OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
01160         OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
01161   
01162         if (visited.find(predNode) != visited.end()) continue;
01163         visited.insert(predNode);
01164         if (predNode->isPathFrom(useNode, visited)) return true;
01165     }
01166 
01167     return false;
01168 }
01169 
01170 
01171 
01172 // true if this has an outgoing edge to other procedures
01173 bool
01174 Node::hasOutgoingEdgesToOtherProcs(ProcHandle proc)
01175 { 
01176     OA_ptr<EdgesIteratorInterface> succIterPtr
01177         = getDUGOutgoingEdgesIterator();
01178     for (; succIterPtr->isValid(); ++(*succIterPtr)) {
01179         OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
01180         if (succEdge->getType() != CFLOW_EDGE) continue;
01181         if (succEdge->getProc() != proc) return true;
01182     }
01183 
01184     return false;
01185 }
01186 
01187 
01188 
01189 // returns a set of outgoing nodes of this proc
01190 void
01191 Node::findOutgoingNodes(ProcHandle proc, 
01192                         std::set<IRSymHandle>& OutGoingNodeSet,
01193                         std::set<IRSymHandle>& visited)
01194 { 
01195     IRSymHandle nodeKey = getIRSymHandle();
01196     if (visited.find(nodeKey) != visited.end()) return;
01197     visited.insert(nodeKey);
01198 
01199     if (hasOutgoingEdgesToOtherProcs(proc)) 
01200         OutGoingNodeSet.insert(nodeKey);
01201 
01202     // traverse foreward from this nodes
01203     OA_ptr<EdgesIteratorInterface> succIterPtr
01204         = getDUGOutgoingEdgesIterator();
01205     for (; succIterPtr->isValid(); ++(*succIterPtr)) {
01206         OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
01207         OA_ptr<NodeInterface> succNode = succEdge->getDUGSink();
01208 
01209         if (succEdge->getType() != CFLOW_EDGE) continue;
01210         if (succEdge->getProc() != proc) continue;
01211   
01212         succNode->findOutgoingNodes(proc, OutGoingNodeSet, visited);
01213     }
01214 }
01215 
01216 
01217 
01218 // true if this has an incoming edge to other procedures
01219 bool
01220 Node::hasIncomingEdgesFromOtherProcs(ProcHandle proc)
01221 { 
01222     OA_ptr<EdgesIteratorInterface> predIterPtr
01223         = getDUGIncomingEdgesIterator();
01224     for (; predIterPtr->isValid(); ++(*predIterPtr)) {
01225         OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
01226         if (predEdge->getType() != CFLOW_EDGE) continue;
01227         if (predEdge->getProc() != proc) return true;
01228     }
01229     return false;
01230 }
01231 
01232 
01233 
01234 // returns a set of incoming nodes of this proc
01235 void
01236 Node::findIncomingNodes(ProcHandle proc, 
01237                         std::set<IRSymHandle>& InComingNodeSet,
01238                         std::set<IRSymHandle>& visited)
01239 { 
01240     IRSymHandle nodeKey = getIRSymHandle();
01241     if (visited.find(nodeKey) != visited.end()) return;
01242     visited.insert(nodeKey);
01243 
01244     if (hasIncomingEdgesFromOtherProcs(proc)) 
01245         InComingNodeSet.insert(nodeKey);
01246 
01247     // traverse backward from this nodes
01248     OA_ptr<EdgesIteratorInterface> predIterPtr = getDUGIncomingEdgesIterator();
01249     for (; predIterPtr->isValid(); ++(*predIterPtr)) {
01250         OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
01251         OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
01252   
01253         if (predEdge->getType() != CFLOW_EDGE) continue;
01254         if (predEdge->getProc() != proc) continue;
01255 
01256         predNode->findIncomingNodes(proc, InComingNodeSet, visited);
01257     }
01258 }
01259 
01260 
01261 
01262 bool
01263 Node::hasEdgesToOtherProc(ProcHandle proc, std::set<IRSymHandle>& visited)
01264 { 
01265     IRSymHandle ish = getIRSymHandle();
01266     if (visited.find(ish) != visited.end()) return false;
01267     visited.insert(ish);
01268 
01269     // traverse foreward from this nodes
01270     OA_ptr<EdgesIteratorInterface> succIterPtr = getDUGOutgoingEdgesIterator();
01271     for (; succIterPtr->isValid(); ++(*succIterPtr)) {
01272         OA_ptr<EdgeInterface> succEdge = succIterPtr->currentDUGEdge();
01273         OA_ptr<NodeInterface> succNode = succEdge->getDUGSink();
01274         
01275         EdgeType etype = succEdge->getType();
01276         if (etype != CFLOW_EDGE && etype != CALL_EDGE) continue;
01277         if (succEdge->getProc() != proc) return true;
01278         if (etype == CFLOW_EDGE && succNode->hasEdgesToOtherProc(proc, visited)) 
01279             return true;
01280     }
01281     return false;
01282 }
01283 
01284 
01285 
01286 // true if this has an incoming edge to other procedures
01287 bool
01288 Node::hasEdgesFromOtherProc(ProcHandle proc, std::set<IRSymHandle>& visited)
01289 { 
01290     IRSymHandle ish = getIRSymHandle();
01291     if (visited.find(ish) != visited.end()) return false;
01292     visited.insert(ish);
01293 
01294     // traverse backward from this nodes
01295     OA_ptr<EdgesIteratorInterface> predIterPtr = getDUGIncomingEdgesIterator();
01296     for (; predIterPtr->isValid(); ++(*predIterPtr)) {
01297         OA_ptr<EdgeInterface> predEdge = predIterPtr->currentDUGEdge();
01298         OA_ptr<NodeInterface> predNode = predEdge->getDUGSource();
01299   
01300         EdgeType etype = predEdge->getType();
01301         if (etype != CFLOW_EDGE) continue;
01302         if (predEdge->getProc() != proc) return true;
01303         if (predNode->hasEdgesFromOtherProc(proc, visited)) 
01304             return true;
01305     }
01306     return false;
01307 }
01308 
01309 
01310 
01311     } // end namespace DUGStandard
01312 } // end namespace OA