ManagerUDDUChainsXAIF.cpp

Go to the documentation of this file.
00001 
00015 #include "ManagerUDDUChainsXAIF.hpp"
00016 
00017 
00018 namespace OA {
00019   namespace XAIF {
00020 
00021     static bool debug = false;
00022 
00025     ManagerUDDUChainsXAIF::ManagerUDDUChainsXAIF(OA_ptr<XAIFIRInterface> _ir) : mIR(_ir)
00026     {
00027       OA_DEBUG_CTRL_MACRO("DEBUG_ManagerUDDUChainsXAIF:ALL", debug);
00028     }
00029 
00033     OA_ptr<UDDUChainsXAIF> ManagerUDDUChainsXAIF::performAnalysis(OA_ptr<CFG::CFGInterface> cfg, 
00034                                                                   OA_ptr<UDDUChains::Interface> udChains,
00035                                                                   bool donotfilterBB) {
00036       if (debug) {
00037         std::cout << "In ReachDefs::ManagerUDDUChainsXAIF::performAnalysis" << std::endl;
00038       }
00039       OA_ptr<UDDUChainsXAIF> aUDDUChainsXAIF;
00040       aUDDUChainsXAIF = new UDDUChainsXAIF();
00041       // making a mapping of Stmt's to basic block id's
00042       // FIXME: add functionality to CFG?
00043       // also mapping memory references to stmts
00044       // first assign StmtHandle(0) to entry node, which should have no
00045       // other statements in it
00046       mStmtToBBMap[StmtHandle(0)] = cfg->getEntry();
00047       if (debug) { std::cout << "mStmtToBBMap[StmtHandle(0)] = "
00048                              << mStmtToBBMap[StmtHandle(0)] << std::endl; }
00049       OA_ptr<DGraph::NodesIteratorInterface> nodeIterPtr;
00050       nodeIterPtr = cfg->getNodesIterator();
00051       // looping over basic blocks
00052       for ( ;nodeIterPtr->isValid(); ++(*nodeIterPtr) ) {
00053         OA_ptr<DGraph::NodeInterface> dnode = nodeIterPtr->current();
00054         OA_ptr<CFG::NodeInterface> node = dnode.convert<CFG::NodeInterface>();
00055         OA_ptr<CFG::NodeStatementsIteratorInterface> stmtIterPtr 
00056           = node->getNodeStatementsIterator();
00057         // looping over statements in basic blocks
00058         for (; stmtIterPtr->isValid(); ++(*stmtIterPtr)) {
00059           OA::StmtHandle stmt = stmtIterPtr->current();
00060           // mapping of statement to CFG nodes
00061           mStmtToBBMap[stmt] = node;
00062           if (debug && !donotfilterBB) { 
00063             std::cout << "mapping stmt: "
00064                       << mIR->toString(stmt)
00065                       << " to CFG node >"; 
00066             node->output(*mIR);
00067             std::cout << "< end of CFG node and the following memrefs are mapped to this statement: " << std::endl;
00068           }
00069           // for all memory references in the statement
00070           OA_ptr<MemRefHandleIterator> mrItPtr = mIR->getAllMemRefs(stmt);
00071           for ( ; mrItPtr->isValid(); (*mrItPtr)++) {
00072             if (debug) {
00073               std::cout << "memref (" << mrItPtr->current().hval() 
00074                         << ") = " << mIR->toString(mrItPtr->current()) << std::endl;
00075             }
00076             mMemRefToStmt[mrItPtr->current()] = stmt;
00077           }
00078         }
00079       }
00080       // for each UDChain start from a use memory reference:
00081       OA_ptr<UDDUChains::Interface::MemRefsWithUDChainIterator> useIterPtr; 
00082       useIterPtr = udChains->getMemRefsWithUDChainIterator();
00083       for (; useIterPtr->isValid(); ++(*useIterPtr)) {
00084         bool haveDefinitionBeforeUse=false; 
00085         MemRefHandle use = useIterPtr->current();
00086         if (debug) {
00087           std::cout << "use memref (" << use.hval() << ") = " << mIR->toString(use);
00088           std::cout << std::endl;
00089         }
00090         // get the BB in which the use occurs
00091         OA_ptr<CFG::NodeInterface> useBB = mStmtToBBMap[mMemRefToStmt[use]];
00092         if (debug) {
00093           std::cout << " occurs in useBB = " << useBB << std::endl;
00094         }
00095         StmtSet subSet;
00096         OA_ptr<UDDUChains::Interface::ChainStmtIterator> defStmtIterPtr;
00097         defStmtIterPtr = udChains->getUDChainStmtIterator(use);
00098         // iterate through all possible definitions: 
00099         for (; defStmtIterPtr->isValid(); (*defStmtIterPtr)++) {
00100           StmtHandle defStmt = defStmtIterPtr->current();
00101           if (debug) {
00102             std::cout << "  def stmt (" << defStmt.hval() << ") = " 
00103                       << mIR->toString(defStmt) << std::endl;
00104             std::cout << "    mStmtToBBMap[defStmt] = " << mStmtToBBMap[defStmt] 
00105                       << std::endl;
00106           }
00107           if (donotfilterBB) {
00108             subSet.insert(defStmt);
00109             if (debug) { std::cout << "    Filter off - inserting def stmt" << std::endl; }
00110           }
00111           else { // do filter 
00112             // determine the subset of the def statements that are
00113             // within the same basic block, include the StmtHandle(0) if
00114             // a def statement is not within the same basic block
00115             // or comes after the use statement
00116             if (mStmtToBBMap[defStmt]==useBB) {
00117               if (debug) { std::cout << "  Filter on - stmts are in same basic block" << std::endl; }
00118               // iterate over statements in this basic block, if hit def
00119               // first then insert it, if hit use first then insert StmtHandle(0)
00120               OA_ptr<CFG::NodeStatementsIteratorInterface> stmtIterPtr 
00121                 = useBB->getNodeStatementsIterator();
00122               // looping over statements in basic blocks
00123               for (; stmtIterPtr->isValid(); ++(*stmtIterPtr)) {
00124                 OA::StmtHandle stmt = stmtIterPtr->current();
00125                 if (!haveDefinitionBeforeUse && stmt == mMemRefToStmt[use]) {
00126                   if (debug) { std::cout << "Filter on - out of order - inserting StmtHandle(0)" << std::endl; }
00127                   subSet.insert(StmtHandle(0)); // outside of block definition
00128                   haveDefinitionBeforeUse=true;
00129                   break;
00130                 } 
00131                 if (stmt == defStmt) {
00132                   if (debug) { std::cout << "    Filter on - inserting def stmt" << std::endl; }
00133                   subSet.insert(defStmt);
00134                   haveDefinitionBeforeUse=true;
00135                   break;
00136                 } 
00137               }
00138               // not in same basic block
00139             } else {
00140               if (debug) { std::cout << "    Filter on - outside def - inserting StmtHandle(0)" << std::endl; }
00141               subSet.insert(StmtHandle(0));
00142               haveDefinitionBeforeUse=true;
00143             }
00144           }
00145         } // end for def stmts
00146         // see if the subset is already in a UDDUChainsXAIF data structure
00147         int chainId = aUDDUChainsXAIF->findChain(subSet);
00148         if (chainId != UDDUChainsXAIF::CHAIN_ID_NONE) {
00149           // if it is then insert the use memory reference into that chain
00150           aUDDUChainsXAIF->insertInto(use, chainId);
00151           if (debug) { std::cout << "  found as existing chain id: " << chainId << std::endl; }
00152         } else {
00153           // if it isn't then make a new chain in the UDDUChainsXAIF 
00154           // and add the subset of statements into that chain
00155           int newChainId = getNextChainId();
00156           aUDDUChainsXAIF->insertInto(use,newChainId);
00157           if (debug) { std::cout << "  make new chain id: " << newChainId << std::endl; }
00158           aUDDUChainsXAIF->addStmtSet(subSet,newChainId);
00159         }
00160       } // end for use stmts
00161       // for each DUChain starting from a def memory reference
00162       OA_ptr<UDDUChains::Interface::MemRefsWithDUChainIterator> defIterPtr; 
00163       defIterPtr = udChains->getMemRefsWithDUChainIterator();
00164       for (; defIterPtr->isValid(); ++(*defIterPtr)) {
00165         bool haveUseAfterDefinition=false; 
00166         MemRefHandle def = defIterPtr->current();
00167         if (debug) {
00168           std::cout << "def memref (" << def.hval() << ") = " << mIR->toString(def);
00169           std::cout << std::endl;
00170         }
00171         // BB for def
00172         OA_ptr<CFG::NodeInterface> defBB 
00173           = mStmtToBBMap[mMemRefToStmt[def]];
00174         if (debug) {
00175           std::cout << " occurs in defBB = " << defBB << std::endl;
00176         }
00177         // determine the subset of the use statements that are
00178         // within the same basic block, include the StmtHandle(0) if
00179         // a statement is not within the same basic block
00180         StmtSet subSet;
00181         OA_ptr<UDDUChains::Interface::ChainStmtIterator> useStmtIterPtr;
00182         useStmtIterPtr = udChains->getDUChainStmtIterator(def);
00183         for (; useStmtIterPtr->isValid(); (*useStmtIterPtr)++) {
00184           StmtHandle useStmt = useStmtIterPtr->current();
00185           if (debug) {
00186             std::cout << "  useStmt (" << useStmt.hval() << ") = " 
00187                       << mIR->toString(useStmt) << std::endl; 
00188             std::cout << "    mStmtToBBMap[useStmt] = " << mStmtToBBMap[useStmt];
00189             std::cout << std::endl;
00190           }
00191           if (donotfilterBB) { 
00192             subSet.insert(useStmt);
00193             if (debug) { std::cout << "    Filter off - inserting use stmt" << std::endl; }
00194           } 
00195           else { // filtered
00196             // determine the subset of use statements that are
00197             // within the same basic block, include the StmtHandle(0) if
00198             // a use statement is not within the same basic block
00199             // or comes before the def statement
00200             if (mStmtToBBMap[useStmt]==defBB) { // in same basic block
00201               if (debug) { std::cout << "    Filter on - stmts are in same basic block" << std::endl; }
00202               // iterate over statements in this basic block, if hit def
00203               // first then insert use, if hit use first then insert StmtHandle(0)
00204               OA_ptr<CFG::NodeStatementsIteratorInterface> stmtIterPtr 
00205                 = defBB->getNodeStatementsIterator();
00206               // looping over statements in basic blocks
00207               for (; stmtIterPtr->isValid(); ++(*stmtIterPtr)) {
00208                 OA::StmtHandle stmt = stmtIterPtr->current();
00209                 if (!haveUseAfterDefinition && stmt == useStmt) {
00210                   if (debug) { std::cout << "    Filter on - out of order - inserting StmtHandle(0)" << std::endl; }
00211                   subSet.insert(StmtHandle(0));
00212                   haveUseAfterDefinition=true;
00213                   break;
00214                 } 
00215                 if (stmt == mMemRefToStmt[def]) {
00216                   if (debug) { std::cout << "    Filter on - inserting use stmt" << std::endl; }
00217                   subSet.insert(useStmt);
00218                   haveUseAfterDefinition=true;
00219                   break;
00220                 } 
00221               }
00222             } 
00223             else { //  not in same basic block
00224               if (debug) { std::cout << "    Filter on - outside use - inserting StmtHandle(0)" << std::endl; }
00225               subSet.insert(StmtHandle(0));
00226               haveUseAfterDefinition=true;
00227             }
00228           }
00229         } // use stmts
00230         // see if the subset is already in a UDDUChainsXAIF data structure
00231         int chainId = aUDDUChainsXAIF->findChain(subSet);
00232         if (chainId != UDDUChainsXAIF::CHAIN_ID_NONE) {
00233           // if it is then insert the use memory reference into that chain
00234           aUDDUChainsXAIF->insertInto(def, chainId);
00235           if (debug) { std::cout << "  found as existing chain id: " << chainId << std::endl; }
00236         } 
00237         else {
00238           // if it isn't then make a new chain in the UDDUChainsXAIF 
00239           // and add the subset of statements into that chain
00240           int newChainId = getNextChainId();
00241           aUDDUChainsXAIF->insertInto(def,newChainId);
00242           aUDDUChainsXAIF->addStmtSet(subSet,newChainId);
00243           if (debug) { std::cout << "  make new chain id: " << newChainId << std::endl; }
00244         }
00245       } // def stmts
00246       // insert an empty chain as chain 0 because that is the default chain in XAIF
00247       // don't insert it until the end because while building, we don't want to find
00248       // empty chains at 0, want to find it at 1
00249       StmtSet emptySet;
00250       aUDDUChainsXAIF->addStmtSet(emptySet,0);
00251       return aUDDUChainsXAIF;
00252     }
00253 
00254     int ManagerUDDUChainsXAIF::ourCurrentStartId=3;
00255 
00256     int ManagerUDDUChainsXAIF::getNextChainId() {
00257       return ourCurrentStartId++;
00258     }
00259       
00260   } 
00261 
00262 }