ManagerUDDUChainsStandard.cpp

Go to the documentation of this file.
00001 
00015 #include "ManagerUDDUChainsStandard.hpp"
00016 
00017 namespace OA {
00018   namespace UDDUChains {
00019 
00020 bool debug = false;
00021 
00025 ManagerUDDUChainsStandard::ManagerUDDUChainsStandard(OA_ptr<UDDUChainsIRInterface> _ir) : mIR(_ir) 
00026 {
00027  OA_DEBUG_CTRL_MACRO("DEBUG_ManagerUDDUChainsStandard:ALL", debug);
00028 }
00029 
00030 
00034 OA_ptr<UDDUChainsStandard> ManagerUDDUChainsStandard::performAnalysis(ProcHandle proc, 
00035         OA_ptr<Alias::Interface> alias, OA_ptr<ReachDefs::Interface> reachDefs,
00036         OA_ptr<SideEffect::InterSideEffectInterface> interSE)
00037 {
00038   OA_ptr<UDDUChainsStandard> aUDDUChains;
00039   aUDDUChains = new UDDUChainsStandard(proc);
00040 
00041   // for each reaching definition for a statement, need to determine 
00042   // if that reaching definition has a def (due to memref or function call)
00043   // that may alias a use (due to memref or function call) in the statement
00044 
00045   if (debug) {
00046     std::cout << "ManagerUDDUChainsStandard::performAnalysis: ";
00047     std::cout << std::endl;
00048   }
00049 
00050   // for each statement in the procedure
00051   OA_ptr<OA::IRStmtIterator> stmtIterPtr = mIR->getStmtIterator(proc);
00052   for ( ; stmtIterPtr->isValid(); (*stmtIterPtr)++) {
00053     OA::StmtHandle stmt = stmtIterPtr->current();
00054     if (debug) {
00055       std::cout << "\tstmt (" << stmt.hval() << ") = " << mIR->toString(stmt);
00056       std::cout << std::endl;
00057     }
00058  
00059     // for each stmt keep track of number of reaching defs that are must
00060     // reaching defs, if there are no must reaching defs and there
00061     // were uses, we should add
00062     // StmtHandle(0) into the udchain indicating that the define might be
00063     // happening out of scope
00064     int mustCountForStmt = 0;
00065     int mayUseCountForStmt = 0;
00066 
00067     // loop over defs in this statement to make sure their du-chain
00068     // is initialized to empty
00069     OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(stmt);
00070     for (; defIterPtr->isValid(); (*defIterPtr)++) {
00071         MemRefHandle def = defIterPtr->current();
00072         aUDDUChains->insertMemRefDef(def);
00073     }
00074   
00075     // loop over uses in this statement
00076     OA_ptr<MemRefHandleIterator> useIterPtr = mIR->getUseMemRefs(stmt);
00077     for (; useIterPtr->isValid(); (*useIterPtr)++) {
00078         mayUseCountForStmt++;
00079         MemRefHandle use = useIterPtr->current();
00080         aUDDUChains->insertMemRefUse(use);
00081 
00082         if (debug) {
00083           std::cout << "\t\tuse (" << use.hval() << ") = " << mIR->toString(use);
00084           std::cout << std::endl;
00085         }
00086 
00087         // keep track of must reaching defs for this use
00088         int mustCountForUse = 0;
00089 
00090         // for each reaching definition
00091         OA_ptr<ReachDefs::Interface::ReachDefsIterator> rdIterPtr 
00092             = reachDefs->getReachDefsIterator(stmt);
00093         for (; rdIterPtr->isValid(); ++(*rdIterPtr)) {
00094           StmtHandle reachStmt = rdIterPtr->current();
00095           if (debug) {
00096             std::cout << "\t\treachStmt (" << reachStmt.hval() 
00097                       << ")= " << mIR->toString(reachStmt);
00098             std::cout << std::endl;
00099           }
00100 
00101           // loop over defs due to memref in that reaching definition
00102           OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(reachStmt);
00103           for (; defIterPtr->isValid(); (*defIterPtr)++) {
00104             MemRefHandle def = defIterPtr->current();
00105             aUDDUChains->insertMemRefDef(def);
00106 
00107             if (debug) {
00108               std::cout << "\t\t\tdef (" << def.hval() << ") = " 
00109                         << mIR->toString(def);
00110               std::cout << std::endl;
00111             }
00112  
00113             // if the def may aliases the use then add this
00114             // information to UDDUChains
00115             if (alias->alias(use,def)==Alias::MAYALIAS ||
00116                 alias->alias(use,def)==Alias::MUSTALIAS ) 
00117             {
00118               if (debug) { std::cout << "line 115, inserting ";
00119                 std::cout << "reachStmt = " << mIR->toString(reachStmt);
00120                 std::cout << ", stmt = " << mIR->toString(stmt);
00121                 std::cout << ", def = " << mIR->toString(def);
00122                 std::cout << ", use = " << mIR->toString(use);
00123                 std::cout << std::endl;
00124               }
00125               aUDDUChains->insertDefUse(reachStmt,stmt);
00126               aUDDUChains->insertMemRefDefStmtUse(def,stmt);
00127               aUDDUChains->insertStmtDefMemRefUse(reachStmt,use);
00128             }
00129             // count must defs
00130             if (alias->alias(use,def)==Alias::MUSTALIAS) {
00131               mustCountForStmt++;
00132               mustCountForUse++;
00133             }
00134 
00135           }
00136           
00137           // loop over defs due to function calls in that reaching definition
00138           // must or may defines from procedure calls
00139           OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(reachStmt);
00140           for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00141             CallHandle expr = callsiteItPtr->current();
00142 
00143             OA_ptr<LocIterator> locIterPtr;
00144       
00145             // MOD
00146             locIterPtr = interSE->getMODIterator(expr);
00147             for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00148               OA_ptr<Location> modLoc= locIterPtr->current();
00149            
00150               // if the def may aliases the use then add this
00151               // information to UDDUChains
00152               if (locMayAliasMemRef(alias,modLoc,use))
00153               {
00154                 if (debug) { std::cout << "line 152, inserting ";
00155                   std::cout << "reachStmt = " << mIR->toString(reachStmt);
00156                   std::cout << ", stmt = " << mIR->toString(stmt);
00157                   std::cout << ", use = " << mIR->toString(use);
00158                   std::cout << std::endl;
00159                 }
00160                 aUDDUChains->insertDefUse(reachStmt,stmt);
00161                 aUDDUChains->insertStmtDefMemRefUse(reachStmt,use);
00162               }
00163               if (locMustAliasMemRef(alias,modLoc,use)) {
00164                 mustCountForStmt++;
00165                 mustCountForUse++;
00166               }
00167             }
00168           } // loop over callsites
00169 
00170         } // loop over reaching definitions
00171 
00172         // if current use had no must reaching defs then add StmtHandle(0)
00173         if (mustCountForUse==0) {
00174           if (debug) { std::cout << "line 169, inserting ";
00175             std::cout << "reachStmt = StmtHandle(0)";
00176             std::cout << ", stmt = " << mIR->toString(stmt);
00177             std::cout << ", use = " << mIR->toString(use);
00178             std::cout << std::endl;
00179           }
00180           aUDDUChains->insertDefUse(StmtHandle(0),stmt);
00181           aUDDUChains->insertStmtDefMemRefUse(StmtHandle(0),use);
00182         }
00183           
00184     } // loop over uses in current stmt
00185     
00186     // loop over uses due to function calls in this statement
00187     OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(stmt);
00188     for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00189       CallHandle expr = callsiteItPtr->current();
00190 
00191       // USE
00192       OA_ptr<LocIterator> locIterPtr;
00193       locIterPtr = interSE->getUSEIterator(expr);
00194       for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00195         mayUseCountForStmt++;
00196         OA_ptr<Location> useLoc= locIterPtr->current();
00197 
00198         int mustCountForUse=0;
00199 
00200         // for each reaching definition
00201         OA_ptr<ReachDefs::Interface::ReachDefsIterator> rdIterPtr 
00202             = reachDefs->getReachDefsIterator(stmt);
00203         for (; rdIterPtr->isValid(); ++(*rdIterPtr)) {
00204           StmtHandle reachStmt = rdIterPtr->current();
00205           if (debug) {
00206             std::cout << "\t\treachStmt (" << reachStmt.hval() 
00207                       << ")= " << mIR->toString(reachStmt);
00208             std::cout << std::endl;
00209           }
00210 
00211           // loop over defs due to memref in that reaching definition
00212           OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(reachStmt);
00213           for (; defIterPtr->isValid(); (*defIterPtr)++) {
00214             MemRefHandle def = defIterPtr->current();
00215             aUDDUChains->insertMemRefDef(def);
00216  
00217             // if the def may aliases the use loc then add this
00218             // information to UDDUChains
00219             if (locMayAliasMemRef(alias,useLoc,def))
00220             {
00221               if (debug) { std::cout << "line 213, inserting ";
00222                 std::cout << "reachStmt = " << mIR->toString(reachStmt);
00223                 std::cout << ", stmt = " << mIR->toString(stmt);
00224                 std::cout << std::endl;
00225               }
00226               aUDDUChains->insertDefUse(reachStmt,stmt);
00227               aUDDUChains->insertMemRefDefStmtUse(def,stmt);
00228              // aUDDUChains->insertStmtDefMemRefUse(reachStmt,use);
00229             }
00230             if (locMustAliasMemRef(alias,useLoc,def)) {
00231               mustCountForStmt++;
00232             }
00233 
00234           }
00235           
00236           // loop over defs due to function calls in that reaching definition
00237           // must or may defines from procedure calls
00238           OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(reachStmt);
00239           for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00240             CallHandle expr = callsiteItPtr->current();
00241 
00242             OA_ptr<LocIterator> locIterPtr;
00243       
00244             // MOD
00245             locIterPtr = interSE->getMODIterator(expr);
00246             for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00247               OA_ptr<Location> modLoc= locIterPtr->current();
00248            
00249               // if the def may aliases the use then add this
00250               // information to UDDUChains
00251               if (modLoc->mayOverlap(*useLoc)) {
00252                 if (debug) { std::cout << "line 243, inserting ";
00253                   std::cout << "reachStmt = " << mIR->toString(reachStmt);
00254                   std::cout << ", stmt = " << mIR->toString(stmt);
00255                   std::cout << std::endl;
00256                 }
00257                 aUDDUChains->insertDefUse(reachStmt,stmt);
00258               }
00259               if (modLoc->mustOverlap(*useLoc)) {
00260                 mustCountForStmt++;
00261                 mustCountForUse++;
00262               }
00263             } // loop over locations modified by callsite
00264           } // loop over callsites in reachstmt
00265 
00266         } // loop over reaching statements
00267 
00268         if (mustCountForUse==0) {
00269            if (debug) { std::cout << "line 169, inserting ";
00270               std::cout << "reachStmt = StmtHandle(0)";
00271               std::cout << ", stmt = " << mIR->toString(stmt);
00272               std::cout << std::endl;
00273            }
00274            aUDDUChains->insertDefUse(StmtHandle(0),stmt);
00275         }
00276 
00277       } // loop over uses in callsite
00278     } // loop over callsites
00279 
00280     // if there were no must reaching definitions for this statement then
00281     // add StmtHandle(0) into the ud chain
00282     if (mustCountForStmt==0 && mayUseCountForStmt>0) {
00283         // loop over uses in this statement
00284         OA_ptr<MemRefHandleIterator> useIterPtr = mIR->getUseMemRefs(stmt);
00285         for (; useIterPtr->isValid(); (*useIterPtr)++) {
00286             MemRefHandle use = useIterPtr->current();
00287             if (debug) { std::cout << "line 272, inserting ";
00288               std::cout << "reachStmt = StmtHandle(0)";
00289               std::cout << ", stmt = " << mIR->toString(stmt);
00290               std::cout << ", use = " << mIR->toString(use);
00291               std::cout << std::endl;
00292             }
00293             aUDDUChains->insertDefUse(StmtHandle(0),stmt);
00294             aUDDUChains->insertStmtDefMemRefUse(StmtHandle(0),use);
00295         }
00296     }
00297  
00298   } // loop over stmts
00299 
00300   // loop over all exit reaching definitions, insert an out-of-scope use for
00301   // all non-local locations that are may defined in those reaching definitions
00302   OA_ptr<ReachDefs::Interface::ReachDefsIterator> rdIterPtr 
00303       = reachDefs->getExitReachDefsIterator();
00304   for (; rdIterPtr->isValid(); ++(*rdIterPtr)) {
00305     StmtHandle reachStmt = rdIterPtr->current();
00306     if (debug) {
00307       std::cout << "\t\treachStmt (" << reachStmt.hval() 
00308                 << ")= " << mIR->toString(reachStmt);
00309       std::cout << std::endl;
00310     }
00311 
00312     // loop over defs due to memref in that reaching definition
00313     OA_ptr<MemRefHandleIterator> defIterPtr = mIR->getDefMemRefs(reachStmt);
00314     for (; defIterPtr->isValid(); (*defIterPtr)++) {
00315       MemRefHandle def = defIterPtr->current();
00316 
00317       // get all may locations for that def and if the may location is not 
00318       // local insert a possible out-of-scope use
00319       OA_ptr<LocIterator> locIterPtr = alias->getMayLocs(def);
00320       for ( ; locIterPtr->isValid(); (*locIterPtr)++ ) {
00321         OA_ptr<Location> loc = locIterPtr->current();
00322         if (debug) {
00323           std::cout << "\t\tloc = ";
00324           loc->dump(std::cout, mIR);
00325         }
00326         // need to get base location if we have a subset
00327         if (loc->isaSubSet()) {
00328           loc = loc->getBaseLoc(); 
00329         }
00330         if (debug) {
00331           std::cout << "\t\tloc = ";
00332           loc->dump(std::cout, mIR);
00333         }
00334         // all non-local locations
00335         if (!loc->isLocal()) {
00336           if (debug) { std::cout << "line 313, inserting ";
00337               std::cout << "reachStmt = " << mIR->toString(reachStmt);
00338               std::cout << ", stmt = StmtHandle(0)";
00339               std::cout << ", def = " << mIR->toString(def);
00340               std::cout << std::endl;
00341           }
00342           aUDDUChains->insertMemRefDefStmtUse(def,StmtHandle(0));
00343           aUDDUChains->insertDefUse(reachStmt,StmtHandle(0));
00344         // determine if this is a reference parameter
00345         } else if(loc->isaInvisible()) {
00346             /*OA_ptr<InvisibleLoc> nloc = loc.convert<InvisibleLoc>();
00347             OA_ptr<MemRefExpr> mre = nloc->getMemRefExpr();
00348             OA_ptr<RefOp> refop;
00349             if(mre->isaRefOp()) {
00350                  aUDDUChains->insertDefUse(reachStmt,StmtHandle(0));
00351                  aUDDUChains->insertMemRefDefStmtUse(def,StmtHandle(0));
00352             } else{
00353                 assert(0);
00354             }
00355             */
00356 
00357             aUDDUChains->insertDefUse(reachStmt,StmtHandle(0));
00358             aUDDUChains->insertMemRefDefStmtUse(def,StmtHandle(0));
00359 
00360         }// else if (loc->isaNamed()) {
00361          // OA_ptr<NamedLoc> nloc = loc.convert<NamedLoc>();
00362          // assert(0); // MMS 8/9/06, need to revamp without isRefParam
00363 
00378        // }
00379           
00380       }
00381     }
00382     // loop over defs due to function calls in that reaching definition
00383     // must or may defines from procedure calls
00384     OA_ptr<IRCallsiteIterator> callsiteItPtr = mIR->getCallsites(reachStmt);
00385     for ( ; callsiteItPtr->isValid(); ++(*callsiteItPtr)) {
00386       CallHandle expr = callsiteItPtr->current();
00387 
00388       OA_ptr<LocIterator> locIterPtr;
00389       
00390       // MOD
00391       locIterPtr = interSE->getMODIterator(expr);
00392       for ( ; locIterPtr->isValid(); (*locIterPtr)++) {
00393         OA_ptr<Location> modLoc= locIterPtr->current();
00394         if (!modLoc->isLocal()) {
00395           if (debug) { std::cout << "line 343, inserting ";
00396               std::cout << "reachStmt = " << mIR->toString(reachStmt);
00397               std::cout << ", stmt = StmtHandle(0)";
00398               std::cout << std::endl;
00399           }
00400           aUDDUChains->insertDefUse(reachStmt,StmtHandle(0));
00401         }
00402          else if(modLoc->isaInvisible()) {
00403             aUDDUChains->insertDefUse(reachStmt,StmtHandle(0));
00404 
00405         }
00406       }
00407     }
00408   }
00409  
00410  
00411   return aUDDUChains;
00412 
00413   
00414 }
00415 
00419 bool ManagerUDDUChainsStandard::locMustAliasMemRef(OA_ptr<Alias::Interface> alias,
00420                                         OA_ptr<Location> loc,
00421                                         MemRefHandle memref)
00422 {
00423     bool retval = false;
00424 
00425     // get iterator for all locations that the memref must reference
00426     OA_ptr<LocIterator> locIterPtr = alias->getMustLocs(memref);
00427     for (; locIterPtr->isValid(); (*locIterPtr)++) {
00428         if (loc->mustOverlap(*(locIterPtr->current())) ) {
00429             retval = true;
00430         }
00431     }
00432 
00433     return retval;
00434 }
00438 bool ManagerUDDUChainsStandard::locMayAliasMemRef(OA_ptr<Alias::Interface> alias,
00439                                         OA_ptr<Location> loc,
00440                                         MemRefHandle memref)
00441 {
00442     bool retval = false;
00443 
00444     // get iterator for all locations that the memref may reference
00445     OA_ptr<LocIterator> locIterPtr = alias->getMayLocs(memref);
00446     for (; locIterPtr->isValid(); (*locIterPtr)++) {
00447         if (loc->mayOverlap(*(locIterPtr->current())) ) {
00448             retval = true;
00449         }
00450     }
00451 
00452     return retval;
00453 }
00454 
00455   } // end of namespace UDDUChains
00456 } // end of namespace OA