OpenADFortTk (basic)
src/lib/support/Open64IRInterface/Open64IRInterface.cpp
Go to the documentation of this file.
00001 // ##########################################################
00002 // # This file is part of OpenADFortTk.                     #
00003 // # The full COPYRIGHT notice can be found in the top      #
00004 // # level directory of the OpenADFortTk source tree.       #
00005 // # For more information visit                             #
00006 // # http://www.mcs.anl.gov/openad                          #
00007 // ##########################################################
00008 
00009 static bool debug = false;
00010 
00011 #include <list>
00012 #include <climits>
00013 #include <cassert>
00014 //using std::list;
00015 
00016 #include "Open64BasicTypes.h"
00017 #include "ir_reader.h" // for fdump_wn()
00018 
00019 #include "Open64IRInterface.hpp"
00020 #include "SymTab.h"
00021 #include "wn_attr.h"
00022 #include "stab_attr.h"
00023 #include "IntrinsicInfo.cpp"
00024 
00025 //***************************************************************************
00026 // Static Class Members
00027 //***************************************************************************
00028 std::map<OA::IRHandle,OA::ProcHandle> Open64IRInterface::sProcContext;
00029 PU_Info* Open64IRInterface::sProgContext = NULL;
00030 //PU_Info* Open64IRInterface::sCurrentProc = NULL;
00031 bool Open64IRInterface::sContextInit = false;
00032 
00033 std::map<OA::StmtHandle,std::set<OA::MemRefHandle> > 
00034     Open64IRInterface::sStmt2allMemRefsMap;
00035 
00036 std::map<OA::MemRefHandle,OA::StmtHandle> Open64IRInterface::sMemRef2StmtMap;
00037 
00038 std::map<OA::MemRefHandle,set<OA::OA_ptr<OA::MemRefExpr> > > 
00039     Open64IRInterface::sMemref2mreSetMap;
00040 
00041 std::map<OA::SymHandle,OA::ProcHandle> Open64IRInterface::sCallSymToProc;
00042 
00043 std::map<fully_qualified_name,
00044          std::set<OA::SymHandle> > Open64IRInterface::sGlobalVarMap;
00045 
00046 std::map<fully_qualified_name,std::map<OA::ProcHandle,OA::SymHandle> >
00047       Open64IRInterface::sFQNToProcToLocalSymMap;
00048 
00049 std::map<OA::SymHandle,fully_qualified_name> Open64IRInterface::sSymToFQNMap;
00050 
00051 std::map<OA::SymHandle,std::string> Open64IRInterface::sSymToVarStringMap;
00052 
00053 std::map<OA::ExprHandle,OA::CallHandle> Open64IRInterface::sParamToCallMap;
00054 
00055 std::map<OA::ProcHandle,std::set<OA::SymHandle> > 
00056     Open64IRInterface::sProcToSymRefSetMap;
00057 
00058 std::map<OA::StmtHandle,std::set<OA::ExprHandle> >  
00059     Open64IRInterface::mStmt2allExprsMap;
00060 
00061 bool Open64IRInterface::ourIgnoreBlackBoxRoutines=false; 
00062 
00063 std::map<OA::StmtHandle,
00064            std::set<
00065                std::pair<OA::OA_ptr<OA::MemRefExpr>,
00066                          OA::OA_ptr<OA::MemRefExpr> > > > mStmtToPtrPairs;
00067 
00068 
00069 // Abstraction to store AssignPairs.
00070 std::map<OA::StmtHandle,
00071            std::set<
00072                std::pair<OA::MemRefHandle,
00073                          OA::ExprHandle> > > mStmtToAssignPairs;
00074 
00075 // Map between Stmt and Index Exprs because Index Exprs are not differentiable
00076 std::map<OA::StmtHandle, std::set<OA::MemRefHandle> > mStmtToIndexExprs;
00077 
00078 //***************************************************************************
00079 // Iterators
00080 //***************************************************************************
00081 
00082 //---------------------------------------------------------------------------
00083 // Open64IRProcIterator
00084 //---------------------------------------------------------------------------
00085 
00086 Open64IRProcIterator::Open64IRProcIterator(PU_Info* pu_forest)
00087 {
00088   if (pu_forest) {
00089     // Builds in a DFS order
00090     for (PU_Info *pu = pu_forest; pu != NULL; pu = PU_Info_next(pu)) {
00091       build_pu_list(pu);
00092     }
00093   }
00094   
00095   reset();
00096 }
00097 
00098 Open64IRProcIterator::~Open64IRProcIterator()
00099 {
00100 }
00101 
00102 void
00103 Open64IRProcIterator::operator++()
00104 {
00105   // Advance current PU
00106   ++pulist_iter;
00107   prepare_current_pu();
00108 }
00109 
00110 void
00111 Open64IRProcIterator::reset()
00112 {
00113   // Reset
00114   pulist_iter = pulist.begin();
00115   prepare_current_pu();
00116 }
00117 
00118 void 
00119 Open64IRProcIterator::prepare_current_pu()
00120 {
00121   if (isValid()) {
00122     PU_Info *pu = (*pulist_iter);
00123     PU_SetGlobalState(pu);
00124   }
00125 }
00126 
00127 void 
00128 Open64IRProcIterator::build_pu_list(PU_Info* pu)
00129 {
00130   pulist.push_back(pu);
00131   
00132   // Now recursively process the child PU's.
00133   for (PU_Info *child = PU_Info_child(pu); child != NULL;
00134        child = PU_Info_next(child)) {
00135     build_pu_list(child);
00136   }
00137 }
00138 
00139 
00140 //---------------------------------------------------------------------------
00141 // Open64IRStmtIterator
00142 //---------------------------------------------------------------------------
00143 Open64IRStmtIterator::Open64IRStmtIterator(OA::ProcHandle h)
00144 {
00145   create(h);
00146   reset();
00147   mValid = true;
00148 }
00149 
00150 Open64IRStmtIterator::~Open64IRStmtIterator()
00151 {
00152 }
00153      
00154 OA::StmtHandle 
00155 Open64IRStmtIterator::current() const
00156 {
00157   if (mValid) { 
00158     return (*mStmtIter); 
00159   } else { 
00160     return OA::StmtHandle(0); 
00161   }
00162 }
00163 
00164 void 
00165 Open64IRStmtIterator::operator++()
00166 {
00167   if (mValid) {
00168     mStmtIter++;
00169   }
00170 }
00171 
00172 void 
00173 Open64IRStmtIterator::reset()
00174 {
00175   mStmtIter = mStmtList.begin();
00176   mEnd = mStmtList.end();
00177   mBegin = mStmtList.begin();
00178 }
00179 
00180 void 
00181 Open64IRStmtIterator::create(OA::ProcHandle h)
00182 {
00183   // NOTE: for now we just create a new list.  we could save some
00184   // memory and use the WHIRL pre-order iterator directly.
00185   PU_Info* pu = (PU_Info*)h.hval();
00186   if (!pu) { return; }
00187   
00188   PU_SetGlobalState(pu);
00189   
00190   WN* wn_pu = PU_Info_tree_ptr(pu);
00191   
00192   WN_TREE_CONTAINER<PRE_ORDER> wtree(wn_pu);
00193   WN_TREE_CONTAINER<PRE_ORDER>::iterator it;
00194   for (it = wtree.begin(); it != wtree.end(); /* */) {
00195     WN* curWN = it.Wn();
00196     OPERATOR opr = WN_operator(curWN);
00197     
00198     // Decide whether to record 'wn' as a statement
00199     bool isCF = 
00200       (!(opr == OPR_FUNC_ENTRY || opr == OPR_BLOCK || opr == OPR_REGION)
00201        && OPERATOR_is_scf(opr) || OPERATOR_is_non_scf(opr));
00202     if (OPERATOR_is_stmt(opr) || isCF) {
00203       //std::cerr << "iterating: " << OPERATOR_name(opr) << std::endl;
00204       mStmtList.push_back(OA::StmtHandle((OA::irhandle_t)curWN));
00205     }
00206 
00207     // Decide how to advance iteration.  For non-compound non-control-
00208     // flow statements, we want to advance to curWN's siblings instead
00209     // of examining its child expressions. This is both more efficient and
00210     // prevents incorrectly classifying embedded CALLs as statements!
00211     bool isPlainStmt = OPERATOR_is_stmt(opr)
00212       && !(OPERATOR_is_scf(opr) || OPERATOR_is_non_scf(opr));
00213     if (isPlainStmt) {
00214       it.WN_TREE_next_skip();
00215     } else {
00216       ++it;
00217     }
00218   }
00219 }
00220 
00221 //---------------------------------------------------------------------------
00222 // Open64IRPtrAsgnIterator
00223 //---------------------------------------------------------------------------
00224 Open64IRPtrAsgnIterator::Open64IRPtrAsgnIterator(OA::ProcHandle h)
00225 {
00226   create(h);
00227   reset();
00228   mValid = true;
00229 }
00230 
00231 Open64IRPtrAsgnIterator::~Open64IRPtrAsgnIterator()
00232 {
00233 }
00234      
00235 OA::StmtHandle 
00236 Open64IRPtrAsgnIterator::current() const
00237 {
00238   if (mValid) { 
00239     return (*mStmtIter); 
00240   } else { 
00241     return OA::StmtHandle(0); 
00242   }
00243 }
00244 
00245 void 
00246 Open64IRPtrAsgnIterator::operator++()
00247 {
00248   if (mValid) {
00249     mStmtIter++;
00250   }
00251 }
00252 
00253 void 
00254 Open64IRPtrAsgnIterator::reset()
00255 {
00256   mStmtIter = mStmtList.begin();
00257   mEnd = mStmtList.end();
00258   mBegin = mStmtList.begin();
00259 }
00260 
00261 void 
00262 Open64IRPtrAsgnIterator::create(OA::ProcHandle h)
00263 {
00264   // NOTE: for now we just create a new list.  we could save some
00265   // memory and use the WHIRL pre-order iterator directly.
00266   PU_Info* pu = (PU_Info*)h.hval();
00267   if (!pu) { return; }
00268   
00269   PU_SetGlobalState(pu);
00270   
00271   WN* wn_pu = PU_Info_tree_ptr(pu);
00272   
00273   WN_TREE_CONTAINER<PRE_ORDER> wtree(wn_pu);
00274   WN_TREE_CONTAINER<PRE_ORDER>::iterator it;
00275   for (it = wtree.begin(); it != wtree.end(); /* */) {
00276     WN* curWN = it.Wn();
00277     OPERATOR opr = WN_operator(curWN);
00278     if (opr==OPR_PSTID || opr==OPR_PSTORE) {
00279       //std::cerr << "iterating: " << OPERATOR_name(opr) << std::endl;
00280       mStmtList.push_back(OA::StmtHandle((OA::irhandle_t)curWN));
00281     }
00282     bool isPlainStmt = OPERATOR_is_stmt(opr)
00283       && !(OPERATOR_is_scf(opr) || OPERATOR_is_non_scf(opr));
00284     if (isPlainStmt) {
00285       it.WN_TREE_next_skip();
00286     } else {
00287       ++it;
00288     }
00289   }
00290 }
00291 
00292 
00293 //---------------------------------------------------------------------------
00294 // Open64IRCallsiteIterator
00295 //---------------------------------------------------------------------------
00296 Open64IRCallsiteIterator::Open64IRCallsiteIterator(WN *wn)
00297 {
00298   if (wn && !OPERATOR_is_not_executable(WN_operator(wn))) {
00299     build_func_call_list(wn);
00300   }
00301   
00302   reset();
00303 }
00304 
00305 Open64IRCallsiteIterator::~Open64IRCallsiteIterator()
00306 {
00307 }
00308 
00309 void 
00310 Open64IRCallsiteIterator::build_func_call_list(WN *wn)
00311 {
00312   if (!wn) { return; }
00313   
00314   OPERATOR opr = WN_operator(wn);
00315 
00316   // Add calls to call list but filter out calls to intrinsics
00317   if (OPERATOR_is_call(opr) 
00318       && 
00319       !(IntrinsicInfo::isIntrinsic(wn)) 
00320       &&
00321       !((opr == OPR_INTRINSIC_CALL) 
00322         &&
00323         (strcmp(IntrinsicInfo::intrinsicBaseName(WN_intrinsic(wn)), "CASSIGNSTMT")==0))
00324       &&
00325       (!Open64IRInterface::ignoreBlackBoxRoutines()
00326        ||
00327        (Open64IRInterface::ignoreBlackBoxRoutines()
00328         &&
00329         Open64IRInterface::haveDefinition(wn))))
00330   {
00331     ST* st = WN_st(wn);
00332     const char* funcNm = ST_name(st);
00333     if(strcmp(funcNm,"_ALLOCATE")!=0) {
00334        wnlist.push_back(wn);
00335     }
00336   }
00337   // Recur on subexpressions
00338   for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
00339     WN* kid = WN_kid(wn, kidno);
00340     build_func_call_list(kid);
00341   }
00342 }
00343 
00344 //---------------------------------------------------------------------------
00345 // Callsite Parameter Iterator
00346 //---------------------------------------------------------------------------
00347 Open64IRCallsiteParamIterator::Open64IRCallsiteParamIterator(WN *wn)
00348 {
00349   OPERATOR opr = WN_operator(wn);
00350   assert(OPERATOR_is_call(opr));
00351 
00352   // FIXME: should we test for a return value at the front?
00353   
00354   // Note: each kid is an OPR_PARM
00355   mINT16 numactuals = WN_num_actuals(wn);
00356   INT first_arg_idx = 0;
00357 
00358   // Gather all parameter expressions
00359   for (INT kidno = first_arg_idx; kidno < numactuals; kidno++) {
00360     WN* kid = WN_kid(wn, kidno);
00362     if(kid == NULL) {
00363         continue;
00364     }
00365     wnlist.push_back(kid);
00366   }
00367   
00368   reset();
00369 }
00370 
00371 //---------------------------------------------------------------------------
00372 // Memory Reference Iterator
00373 //---------------------------------------------------------------------------
00374 Open64IRMemRefIterator::Open64IRMemRefIterator(OA::StmtHandle h)
00375 {
00376   create(h);
00377   reset();
00378   mValid = true;
00379 }
00380         
00381 OA::MemRefHandle 
00382 Open64IRMemRefIterator::current() const
00383 {
00384   if (mValid) { 
00385     return (*mMemRefIter); 
00386   } else { 
00387     return OA::MemRefHandle(0); 
00388   }
00389 }
00390 
00391 void 
00392 Open64IRMemRefIterator::operator++()
00393 {
00394   if (mValid) {
00395     mMemRefIter++;
00396   }
00397 }
00398 
00399 void 
00400 Open64IRMemRefIterator::reset()
00401 {
00402   mMemRefIter = mMemRefList.begin();
00403   mEnd = mMemRefList.end();
00404   mBegin = mMemRefList.begin();
00405 }
00406 
00413 void 
00414 Open64IRMemRefIterator::create(OA::StmtHandle stmt)
00415 {
00416   // loop through MemRefHandle's for this statement and for now put them
00417   // into our own list
00418   std::set<OA::MemRefHandle>::iterator setIter;
00419 
00420   for (setIter=Open64IRInterface::sStmt2allMemRefsMap[stmt].begin(); 
00421        setIter!=Open64IRInterface::sStmt2allMemRefsMap[stmt].end(); setIter++) 
00422   {
00423     mMemRefList.push_back(*setIter);
00424   }
00425 }
00426 
00427 //---------------------------------------------------------------------------
00428 // Expr Iterator
00429 //---------------------------------------------------------------------------
00430 Open64IRExprHandleIterator::Open64IRExprHandleIterator(OA::StmtHandle h)
00431 {
00432   create(h);
00433   reset();
00434   mValid = true;
00435 }
00436 
00437 OA::ExprHandle
00438 Open64IRExprHandleIterator::current() const
00439 {
00440   if (mValid) {
00441     return (*mExprIter);
00442   } else {
00443     return OA::ExprHandle(0);
00444   }
00445 }
00446 
00447 void
00448 Open64IRExprHandleIterator::operator++()
00449 {
00450   if (mValid) {
00451     mExprIter++;
00452   }
00453 }
00454 
00455 void
00456 Open64IRExprHandleIterator::reset()
00457 {
00458   mExprIter = mExprList.begin();
00459   mEnd = mExprList.end();
00460   mBegin = mExprList.begin();
00461 }
00462 
00469 void
00470 Open64IRExprHandleIterator::create(OA::StmtHandle stmt)
00471 {
00472   // loop through MemRefHandle's for this statement and for now put them
00473   // into our own list
00474   std::set<OA::ExprHandle>::iterator setIter;
00475   for (setIter=Open64IRInterface::mStmt2allExprsMap[stmt].begin();
00476        setIter!=Open64IRInterface::mStmt2allExprsMap[stmt].end(); setIter++)
00477   {
00478     mExprList.push_back(*setIter);
00479   }
00480 }
00481 
00482 //---------------------------------------------------------------------------
00483 // Open64IRSymIterator
00484 //---------------------------------------------------------------------------
00485 class insert_ST {
00486 public:
00487   insert_ST(std::list<ST*>& symlist_)
00488     : symlist(symlist_)
00489   { } 
00490   
00491   // A function object applied to every entry of a ST_TAB
00492   void operator()(UINT32 idx, ST* st) const 
00493   { 
00494     symlist.push_back(st);
00495   }
00496   
00497 private:
00498   std::list<ST*>& symlist;
00499 };
00500 
00501 
00502 Open64IRSymIterator::Open64IRSymIterator(PU_Info* pu)
00503 {
00504   create(pu);
00505   reset();
00506 }
00507 
00508 
00509 void
00510 Open64IRSymIterator::create(PU_Info* pu)
00511 {
00512   if (!pu) { return; }
00513   
00514   PU_SetGlobalState(pu);
00515   
00516   // The global symbol table contains symbols that may not have been
00517   // lexically visible in the original source code.  For example,
00518   // given two procedures, one uses a common block and the other
00519   // doesn't, but the common block symbols are placed in the global
00520   // symbol table even though the second procedure never lexically saw
00521   // them.  (The same is true for modules.)  Thus, we are careful to
00522   // only insert globabl symbosl *referenced* in the AST.
00523 
00524   // 1. Iterate through the non-global lexical symbol tables.  These
00525   // tables should truly correspond to lexically visible symbols.
00526   for (SYMTAB_IDX lvl = CURRENT_SYMTAB; lvl > GLOBAL_SYMTAB; --lvl) {
00527     // Scope_tab[lvl].st_tab;
00528     For_all(St_Table, lvl, insert_ST(symlist));
00529   }
00530   
00531   // 2. Enter global symbols referenced in the AST
00532   WN *wn_pu = PU_Info_tree_ptr(pu);
00533 
00534   WN_TREE_CONTAINER<PRE_ORDER> wtree(wn_pu);
00535   WN_TREE_CONTAINER<PRE_ORDER>::iterator it;
00536   for (it = wtree.begin(); it != wtree.end(); ++it) {
00537     WN* curWN = it.Wn();
00538     
00539     // If the node has a global symbol, push it in the list
00540     OPERATOR opr = WN_operator(curWN);
00541     if (OPERATOR_has_sym(opr)) {
00542       ST* st = WN_st(curWN);
00543       if (ST_level(st) == GLOBAL_SYMTAB) {
00544         symlist.push_back(st);
00545       }
00546     }
00547   }
00548 
00549 }
00550 
00551 //---------------------------------------------------------------------------
00552 // Open64PtrAssignPairStmtIterator
00553 //---------------------------------------------------------------------------
00554 
00555 //---------------------------------------------------------------------------
00556 // Open64ParamBindPtrAssignIterator
00557 //---------------------------------------------------------------------------
00558 
00559 //***************************************************************************
00560 // Abstract Interfaces
00561 //***************************************************************************
00562 
00563 Open64IRInterface::Open64IRInterface()
00564 {
00565 }
00566 
00567 
00568 Open64IRInterface::~Open64IRInterface()
00569 {
00570 }
00571 
00572 //---------------------------------------------------------------------------
00573 // IRHandlesIRInterface
00574 //---------------------------------------------------------------------------
00575 
00576 std::string 
00577 Open64IRInterface::toString(const OA::ProcHandle h)
00578 { 
00579   PU_Info* pu = (PU_Info*)h.hval();
00580   
00581   std::ostringstream oss;
00582   //oss << pu;
00583   if (h==OA::ProcHandle(0)) {
00584     oss << "ProcHandle(0)";
00585   } else {
00586     oss << toString(getSymHandle(h));
00587   }
00588   return oss.str();
00589 }
00590 
00591 std::string 
00592 Open64IRInterface::toString(const OA::StmtHandle h)
00593 { 
00594   setCurrentProcToProcContext(h);
00595   WN* wn = (WN*)h.hval();
00596   
00597   std::ostringstream oss;
00598   if (wn==0) {
00599     oss << "StmtHandle(0)";
00600   } else {
00601     DumpWN(wn, oss);
00602   }
00603   return oss.str();
00604 }
00605 
00606 std::string 
00607 Open64IRInterface::toString(const OA::ExprHandle h) 
00608 {
00609   setCurrentProcToProcContext(h);
00610   WN* wn = (WN*)h.hval();
00611 
00612   std::ostringstream oss;
00613   if (wn==0) {
00614     oss << "ExprHandle(0)";
00615   } else {
00616     DumpWN(wn, oss);
00617   }
00618   return oss.str();
00619 }
00620 
00621 std::string 
00622 Open64IRInterface::toString(const OA::OpHandle h) 
00623 {
00624   setCurrentProcToProcContext(h);
00625   WN* wn = (WN*)h.hval();
00626 
00627   std::ostringstream oss;
00628   if (wn==0) {
00629     oss << "OpHandle(0)";
00630   } else {
00631     //    DumpWN(wn, oss);
00632     //oss << OPCODE_name(WN_opcode(wn));
00633     
00634     OPERATOR opr = WN_operator(wn);
00635     string op;
00636     switch (opr) {
00637       // Unary expression operations.
00638     case OPR_CVT:
00639     case OPR_CVTL:
00640     case OPR_TAS:
00641       oss << OPCODE_name(WN_opcode(wn)) << "(";
00642       //    DumpWN(WN_kid0(wn), os);
00643       oss << ")";
00644       break;
00645     case OPR_PARM:
00646       if (WN_flag(wn) & WN_PARM_BY_REFERENCE)
00647         oss << "&"; 
00648       //DumpWN(WN_kid0(wn), os);
00649       break;
00650     case OPR_ABS:
00651       oss << "ABS(";
00652       //DumpWN(WN_kid0(wn), os);
00653       oss << ")";
00654       break;
00655     case OPR_SQRT:
00656       oss << "SQRT(";
00657       //DumpWN(WN_kid0(wn), os);
00658       oss << ")";
00659       break;
00660     case OPR_RSQRT:
00661       oss << "RSQRT(";
00662       //DumpWN(WN_kid0(wn), os);
00663       oss << ")";
00664       break;
00665     case OPR_RECIP:
00666       oss << "RECIP(";
00667       //DumpWN(WN_kid0(wn), os);
00668       oss << ")";
00669       break;
00670     case OPR_PAREN:
00671       oss << "(";
00672       //DumpWN(WN_kid0(wn), os);
00673       oss << ")";
00674       break;
00675     case OPR_RND:
00676       oss << "RND(";
00677       //DumpWN(WN_kid0(wn), os);
00678       oss << ")";
00679       break;
00680     case OPR_TRUNC:
00681       oss << "TRUNC(";
00682       //DumpWN(WN_kid0(wn), os);
00683       oss << ")";
00684       break;
00685     case OPR_CEIL:
00686       oss << "CEIL(";
00687       //DumpWN(WN_kid0(wn), os);
00688       oss << ")";
00689       break;
00690     case OPR_FLOOR:
00691       oss << "FLOOR(";
00692       //DumpWN(WN_kid0(wn), os);
00693       oss << ")";
00694       break;
00695     case OPR_NEG:
00696       op = "-";
00697       goto print_generic_unary;
00698     case OPR_BNOT:
00699       op = "~";
00700       goto print_generic_unary;
00701     case OPR_LNOT:
00702       op = "!";
00703       goto print_generic_unary;
00704     print_generic_unary:
00705       oss << op;
00706       //DumpWN(WN_kid0(wn), os);
00707       break;
00708 
00709       // Binary expression operations.
00710     case OPR_ADD:
00711       op = "+";
00712       goto print_generic_binary;
00713     case OPR_SUB:
00714       op = "-";
00715       goto print_generic_binary;
00716     case OPR_MPY:
00717       op = "*";
00718       goto print_generic_binary;
00719     case OPR_DIV:
00720       op = "/";
00721       goto print_generic_binary;
00722     case OPR_MOD:
00723       oss << "MOD(";
00724       //DumpWN(WN_kid0(wn), os);
00725       //oss << ",";
00726       //DumpWN(WN_kid1(wn), os);
00727       oss << ")";
00728       break;
00729     case OPR_REM:
00730       op = "%";
00731       goto print_generic_binary;
00732     case OPR_EQ:
00733       op = "==";
00734       goto print_generic_binary;
00735     case OPR_NE:
00736       op = "!=";
00737       goto print_generic_binary;
00738     case OPR_GE:
00739       op = ">=";
00740       goto print_generic_binary;
00741     case OPR_LE:
00742       op = "<=";
00743       goto print_generic_binary;
00744     case OPR_GT:
00745       op = '>';
00746       goto print_generic_binary;
00747     case OPR_LT:
00748       op = '<';
00749       goto print_generic_binary;
00750     case OPR_MAX:
00751       oss << "MAX(";
00752       //DumpWN(WN_kid0(wn), os);
00753       //oss << ",";
00754       //DumpWN(WN_kid1(wn), os);
00755       oss << ")";
00756       break;
00757     case OPR_MIN:
00758       oss << "MIN(";
00759       //DumpWN(WN_kid0(wn), os);
00760       oss << ",";
00761       //DumpWN(WN_kid1(wn), os);
00762       oss << ")";
00763       break;
00764     case OPR_SHL:
00765       op = "<<";
00766       goto print_generic_binary;
00767     case OPR_ASHR:
00768     case OPR_LSHR:
00769       op = ">>";
00770       goto print_generic_binary;
00771     case OPR_LAND:
00772       op = "&&";
00773       goto print_generic_binary;
00774     case OPR_LIOR:
00775       op = "||";
00776       goto print_generic_binary;
00777     case OPR_BAND:
00778       op = "&";
00779       goto print_generic_binary;
00780     case OPR_BIOR:
00781       op = "|";
00782       goto print_generic_binary;
00783     case OPR_BXOR:
00784       op = "^";
00785     print_generic_binary:
00786       //DumpWN(WN_kid0(wn), os);
00787       oss << op;
00788       //DumpWN(WN_kid1(wn), os);
00789       break;
00790       
00791       // Ternary operations.
00792     case OPR_SELECT:
00793       //DumpWN(WN_kid0(wn), os);
00794       oss << " ? "; 
00795       //DumpWN(WN_kid1(wn), os);
00796       oss << " : "; 
00797       //DumpWN(WN_kid2(wn), os);
00798       break;
00799     case OPR_MADD:
00800       oss << "(";
00801       //DumpWN(WN_kid0(wn), os);
00802       oss << "*";
00803       //DumpWN(WN_kid1(wn), os);
00804       oss << ")+";
00805       //DumpWN(WN_kid2(wn), os);
00806       break;
00807     case OPR_MSUB:
00808       oss << "(";
00809       //DumpWN(WN_kid0(wn), os);
00810       oss << "*";
00811       //DumpWN(WN_kid1(wn), os);
00812       oss << ")-";
00813       //DumpWN(WN_kid2(wn), os);
00814       break;
00815     case OPR_NMADD:
00816       oss << "-((";
00817       //DumpWN(WN_kid0(wn), os);
00818       oss << "*";
00819       //DumpWN(WN_kid1(wn), os);
00820       oss << ")+";
00821       //DumpWN(WN_kid2(wn), os);
00822       oss << ")";
00823       break;
00824     case OPR_NMSUB:
00825       oss << "-((";
00826       //DumpWN(WN_kid0(wn), os);
00827       oss << "*";
00828       //DumpWN(WN_kid1(wn), os);
00829       oss << ")-";
00830       //DumpWN(WN_kid2(wn), os);
00831       oss << ")";
00832       break;
00833       
00834       /* Don't know about these ...  
00835     // N-ary operations.
00836     case OPR_ARRAY: {
00837       int ndims = WN_kid_count(wn) >> 1;
00838       DumpWN(WN_kid0(wn), os);
00839       os << "(";
00840       for (int i = 0; i < ndims; i++) {
00841         DumpWN(WN_kid(wn, i+ndims+1), os);
00842         if (i < ndims-1) 
00843           os << ",";
00844       }
00845       os << ")";
00846       break;
00847     }
00848     case OPR_TRIPLET: // Output as LB:UB:STRIDE
00849       DumpWN(WN_kid0(wn), os);
00850       os << ":";
00851       DumpWN(WN_kid2(wn), os);
00852       os << ":";
00853       DumpWN(WN_kid1(wn), os);
00854       break; 
00855     case OPR_ARRAYEXP:
00856       DumpWN(WN_kid0(wn), os);
00857       break; 
00858     case OPR_ARRSECTION: {
00859       int ndims = WN_kid_count(wn) >> 1;
00860       DumpWN(WN_kid0(wn), os);
00861       os << "(";
00862       for (int i = 0; i < ndims; i++) {
00863         DumpWN(WN_kid(wn, i+ndims+1), os);
00864         if (i < ndims-1) 
00865           os << ",";
00866       }
00867       os << ")";
00868       break;
00869     }
00870       * Don't know about the above ...
00871       */
00872 
00873     default:
00874       DumpWN(wn, oss);
00875       break;
00876     }
00877   }
00878   return oss.str();
00879 }
00880 
00881 std::string 
00882 Open64IRInterface::toString(const OA::MemRefHandle h)
00883 {
00884   setCurrentProcToProcContext(h);
00885   WN* wn = (WN*)h.hval();
00886   std::ostringstream oss;
00887   DumpWNMemRef(wn, oss);
00888   return oss.str();
00889 }
00890 
00891 std::string 
00892 Open64IRInterface::toString(const OA::SymHandle h) 
00893 {
00894   ST* st = (ST*)h.hval();
00895   std::string symnm; 
00896   if (st) {
00897     setCurrentProcToProcContext(h);
00898     symnm = createCharStarForST(st);
00899     PU_Info* origPU = Current_PU_Info;
00900     if(origPU != NULL) {
00901      ST_IDX idx = PU_Info_proc_sym(origPU);
00902      std::string procname = ST_name(idx);
00903      symnm = procname + "::" + symnm;
00904     }
00905 
00906   } else {
00907     symnm = "<no-symbol>";
00908   }
00909   return symnm;
00910 }
00911 
00912 std::string 
00913 Open64IRInterface::toString(const OA::ConstSymHandle h) 
00914 {
00915   setCurrentProcToProcContext(h);
00916   std::ostringstream oss;
00917   //  oss << h.hval();
00918 
00919   WN* wn = (WN*)h.hval();
00920   if (wn==0) {
00921     oss << "ConstSymHandle(0)";
00922   } else {
00923     DumpWN(wn, oss);
00924   }
00925 
00926   return oss.str();
00927 }
00928 
00929 std::string 
00930 Open64IRInterface::toString(const OA::ConstValHandle h) 
00931 {
00932   setCurrentProcToProcContext(h);
00933   WN* wn = (WN*)h.hval();
00934 
00935   std::ostringstream oss;
00936   //oss << h.hval();
00937 
00938   if (wn==0) {
00939     oss << "ConstValHandle(0)";
00940   } else {
00941     DumpWN(wn, oss);
00942   }
00943   
00944   return oss.str();
00945 }
00946 
00947 std::string 
00948 Open64IRInterface::toString(const OA::CallHandle h) 
00949 {
00950   setCurrentProcToProcContext(h);
00951   WN* wn = (WN*)h.hval();
00952 
00953   std::ostringstream oss;
00954   if (wn==0) {
00955     oss << "CallHandle(0)";
00956   } else {
00957     DumpWN(wn, oss);
00958   }
00959   return oss.str();
00960 }
00961 
00962 
00963 void 
00964 Open64IRInterface::dump(OA::StmtHandle stmt, std::ostream& os)
00965 { 
00966   setCurrentProcToProcContext(stmt);
00967   WN* wn = (WN*)stmt.hval();
00968   if (wn==0) {
00969     os << "StmtHandle(0)";
00970   } else {
00971     DumpWN(wn, os);
00972   }
00973   os << std::endl;
00974 }
00975 
00976 void 
00977 Open64IRInterface::dump(OA::MemRefHandle h, std::ostream& os)
00978 {
00979   setCurrentProcToProcContext(h);
00980   WN* wn = (WN*)h.hval();
00981 
00982   os << "hval = " << h.hval() << ", ";
00983   
00984   OPERATOR opr = WN_operator(wn);
00985   // STOREs represent the left-hand-side memory-ref
00986   if (OPERATOR_is_store(opr)) {
00987     if (WN_kid_count(wn) > 1) {
00988       DumpWN(WN_kid1(wn), os); // left-hand-side (FIXME: add offset!)
00989     } else {
00990       std::string n = toString(OA::SymHandle((OA::irhandle_t)WN_st(wn)));
00991       os << n;
00992     } 
00993   } else {
00994     DumpWN(wn, os);
00995   }
00996   os << std::endl;
00997 }
00998 
00999 void 
01000 Open64IRInterface::dump(OA::SymHandle sym, std::ostream& os)
01001 { 
01002   std::string n = toString(sym);
01003   os << n; 
01004   os << std::endl;
01005 }
01006 
01007 
01008 //---------------------------------------------------------------------------
01009 // CallGraphIRInterface
01010 //---------------------------------------------------------------------------
01011 
01012 OA::OA_ptr<OA::IRStmtIterator> 
01013 Open64IRInterface::getStmtIterator(OA::ProcHandle h)
01014 {
01015   OA::OA_ptr<OA::IRStmtIterator> retval;
01016   retval = new Open64IRStmtIterator(h);
01017   return retval;
01018 }
01019 
01020 OA::SymHandle 
01021 Open64IRInterface::getProcSymHandle(OA::ProcHandle h) 
01022 {
01023   PU_Info* pu = (PU_Info*)h.hval(); 
01024   ST* st = NULL;
01025   if (pu) {
01026     PU_Info* origPU = Current_PU_Info;
01027     if (pu != Current_PU_Info) { 
01028       PU_SetGlobalState(pu); 
01029     }
01030     
01031     st = ST_ptr(PU_Info_proc_sym(pu)); // WN_st(PU_Info_tree_ptr(pu));
01032     
01033     if (Current_PU_Info != origPU) { 
01034       PU_SetGlobalState(origPU); 
01035     }
01036   }
01037   return (OA::irhandle_t)st;
01038 }
01039 
01040 OA::OA_ptr<OA::IRCallsiteIterator>
01041 Open64IRInterface::getCallsites(OA::StmtHandle h)
01042 {
01043   setCurrentProcToProcContext(h);
01044   WN* wn = (WN *)h.hval();
01045   OA::OA_ptr<OA::IRCallsiteIterator> retval;
01046   retval =  new Open64IRCallsiteIterator(wn);
01047   return retval;
01048 }
01049 
01050 //---------------------------------------------------------------------------
01051 // CallGraphDFProblemIRInterface
01052 //---------------------------------------------------------------------------
01053 // !Get IRCallsiteParamIterator for a callsite. 
01054 OA::OA_ptr<OA::IRCallsiteParamIterator> 
01055 Open64IRInterface::getCallsiteParams(OA::CallHandle h) {
01056   setCurrentProcToProcContext(h);
01057   WN* wn = (WN*)h.hval();
01058   OA::OA_ptr<OA::IRCallsiteParamIterator> retval;
01059   retval = new Open64IRCallsiteParamIterator(wn);
01060   return retval;
01061 }
01062 
01063 bool Open64IRInterface::isRefParam(OA::SymHandle sym)
01064 {
01065   // "X"  inout: C_VAR S_FORMAL_REF (flg 0x80 0x0)
01066   // "Y"  inout: C_VAR S_FORMAL_REF (flg 0x80 0x0)
01067   // "AA" in   : C_VAR S_FORMAL_REF (flg 0x80 0x20[in])
01068   // "BB" out  : C_VAR S_FORMAL_REF (flg 0x80 0x40[out])
01069 
01070   // save off the current context and then switch to one for this sym
01071   OA::ProcHandle currContext = getCurrentProcContext();
01072   setCurrentProcToProcContext(sym);
01073 
01074   ST* st = (ST*)sym.hval();
01075   ST_SCLASS sclass = ST_sclass(st);
01076   bool retval;
01077   
01078   if (ST_is_intent_out_argument(st)) {
01079     retval = true; // parameter: intent(out)
01080   }
01081   else if (ST_is_intent_in_argument(st)) {
01082     retval = true; // parameter: intent(in)
01083     //return true; // when modeling reference params with ptrs, on 1/9/06
01084                  // Jean came up with example where need to model intent(in)
01085                  // as pass by reference, MMS
01086                  // yeah but I can't find this example!!
01087   }
01088   else if (sclass == SCLASS_FORMAL_REF) {
01089     retval = true; // pass-by-ref parameter
01090   }
01091   else if (sclass == SCLASS_FORMAL) {
01092     // FIXME: this is going to be wrong for C, but flags aren't set to
01093     // indicate fortran correctly and when pass arrays by ref for some
01094     // reason the formal isn't set to SCLASS_FORMAL_REF in Whirl
01095     retval = true; // may be pass-by-ref in the source language
01096   }
01097   else {
01098     retval = false; // not a parameter at all
01099   }
01100 
01101   // reset the context
01102   setCurrentProcContext(currContext);
01103   return retval;
01104 }
01105                
01107 OA::SymHandle 
01108 Open64IRInterface::getFormalForActual(OA::ProcHandle caller, 
01109                                       OA::CallHandle call, 
01110                                       OA::ProcHandle callee, 
01111                                       OA::ExprHandle param) {
01112   // Setup context for caller
01113   setCurrentProcToProcContext(call);
01114 
01115   PU_Info* callerPU = (PU_Info*)caller.hval();
01116   PU_Info* calleePU = (PU_Info*)callee.hval();
01117   WN* callWN = (WN*)call.hval();
01118   WN* parmWN = (WN*)param.hval();
01119 
01120   //debugging ...
01121   //{ std::cout << "getFormalForActual:  caller='"
01122   //            << toString(caller) << "' called='"
01123   //            << toString(callee)<< std::endl;
01124   //}
01125 
01126   assert(callerPU && calleePU);
01127   ST* formalST = NULL; // sym for corresponding formal parameter
01128   
01129   // Find the index of the actual parameter within the call node
01130   int numParamsCaller = WN_kid_count(callWN);
01131   int parmIdx = -1;
01132   for (int kidno = 0; kidno < numParamsCaller; ++kidno) {
01133     WN* kid = WN_kid(callWN, kidno);
01134     if (kid == parmWN) {
01135       parmIdx = kidno;
01136       break;
01137     }
01138   }
01139 
01140   if (parmIdx >= 0) {
01141       // Given the index of the actual parameter, find the formal parameter
01142       PU_SetGlobalState(calleePU);
01143   
01144       WN* wn_pu = PU_Info_tree_ptr(calleePU);
01145 
01178       assert(parmIdx <= WN_num_formals(wn_pu));
01179 
01207       WN* maybeReturnVar = WN_formal(wn_pu, 0);
01208       ST* returnVarST    = WN_st(maybeReturnVar);
01209       bool isReturnVar = ST_is_return_var (*returnVarST) ;
01210       
01211       WN  *formalWN=0;
01212       if(isReturnVar == true) {
01213         formalWN = WN_formal(wn_pu, parmIdx+1);
01214       } else {
01215         formalWN = WN_formal(wn_pu, parmIdx);
01216       }
01217       
01218       formalST = WN_st(formalWN);
01219       assert(formalST);
01220       
01226   }
01227 
01228   // Reset context for caller
01229   PU_SetGlobalState(callerPU);
01230 
01231   return (OA::irhandle_t)formalST;
01232 }
01233 
01234 OA::SymHandle Open64IRInterface::getSymHandle(OA::CallHandle h) {
01235   assert( h != OA::CallHandle(0));  
01236   WN* wn = (WN*)h.hval(); 
01237   ST* st = NULL;
01238   if (wn) {
01239     st = ((OPERATOR_has_sym(WN_operator(wn))) ? WN_st(wn) : NULL);
01240   }
01241   assert(st != NULL);
01242   return (OA::irhandle_t)st;
01243 }
01244 
01245 //---------------------------------------------------------------------------
01246 // CFGIRInterfaceDefault
01247 //---------------------------------------------------------------------------
01248 
01249 OA::OA_ptr<OA::IRRegionStmtIterator>
01250 Open64IRInterface::procBody(OA::ProcHandle h)
01251 {
01252   PU_Info* pu = (PU_Info*)h.hval();
01253   currentProc(h);
01254   WN* wn_pu = PU_Info_tree_ptr(pu);
01255   //WN* wn_pu = (WN*)h.hval();
01256   assert(WN_operator(wn_pu) == OPR_FUNC_ENTRY);
01257   
01258   WN* wn = WN_func_body(wn_pu);
01259   OA::OA_ptr<Open64IRRegionStmtIterator> retval;
01260   retval = new Open64IRRegionStmtIterator(wn);
01261   return retval;
01262 }
01263 
01264 //----------------------------------------------------------
01265 // Statements: General
01266 //----------------------------------------------------------
01267 
01268 // Translate a whirl statement type into a IRStmtType.
01269 OA::CFG::IRStmtType
01270 Open64IRInterface::getCFGStmtType(OA::StmtHandle h) 
01271 {
01272   //setCurrentProcToProcContext(h); // not setting up context for hierarchical stmts
01273   OA::CFG::IRStmtType ty;
01274   WN *wn = (WN *)h.hval();
01275   OPERATOR opr = WN_operator(wn);
01276 
01277   //
01278   // There are currently three IRStmtTypes that are not returned by this
01279   // function-- BREAK, LOOP_CONTINUE and STRUCT_MULTIWAY_CONDITIONAL.
01280   // That is, Whirl does not appear to have a structured switch statement or
01281   // high-level forms of break or loop continue.
01282   //
01283 
01284   switch (opr) {
01285 
01286   // Return statements.
01287   case OPR_RETURN:
01288   case OPR_RETURN_VAL:
01289     ty = OA::CFG::RETURN;
01290     break;
01291 
01292   // Top-tested loops.
01293   case OPR_DO_LOOP:
01294   case OPR_WHILE_DO:
01295     ty = OA::CFG::LOOP;
01296     break;
01297 
01298   // End-tested loop.
01299   case OPR_DO_WHILE:
01300     ty = OA::CFG::END_TESTED_LOOP;
01301     break;
01302 
01303   // Structured IF-statement.
01304   case OPR_IF:
01305     ty = OA::CFG::STRUCT_TWOWAY_CONDITIONAL;
01306     break;
01307 
01308   // Unconditional jump.
01309   case OPR_GOTO:
01310     ty = OA::CFG::UNCONDITIONAL_JUMP;
01311     break;
01312 
01313   // Unconditional jump (indirect).
01314   case OPR_AGOTO:
01315     ty = OA::CFG::UNCONDITIONAL_JUMP_I;
01316     break;
01317 
01318   // Unstructured two-way branches.
01319   case OPR_TRUEBR:
01320     ty = OA::CFG::USTRUCT_TWOWAY_CONDITIONAL_T;
01321     break;
01322 
01323   case OPR_FALSEBR:
01324     ty = OA::CFG::USTRUCT_TWOWAY_CONDITIONAL_F;
01325     break;
01326 
01327   // Unstructured multi-way branch.
01328   case OPR_COMPGOTO:  // FIXME: Also, OPR_XGOTO?
01329   case OPR_SWITCH:
01330     ty = OA::CFG::USTRUCT_MULTIWAY_CONDITIONAL;
01331     break;
01332 
01333   // Alternate entry point.
01334   case OPR_ALTENTRY:
01335     ty = OA::CFG::ALTERNATE_PROC_ENTRY;
01336     break;
01337 
01338   // A block of statements.
01339     //case OPR_FUNC_ENTRY: // FIXME
01340   case OPR_BLOCK:
01341     ty = OA::CFG::COMPOUND;
01342     break;
01343 
01344   // Simple statements.   // FIXME: Is this all of them?
01345   case OPR_CALL:
01346   case OPR_ICALL:
01347   case OPR_PICCALL:
01348   case OPR_VFCALL:
01349   case OPR_INTRINSIC_CALL:
01350   case OPR_PRAGMA:
01351   case OPR_XPRAGMA:
01352   case OPR_ASM_STMT:
01353   case OPR_EVAL:
01354   case OPR_PREFETCH:
01355   case OPR_PREFETCHX:
01356   case OPR_COMMENT:
01357   case OPR_AFFIRM:
01358   case OPR_FORWARD_BARRIER:     // FIXME: ???
01359   case OPR_BACKWARD_BARRIER:    // FIXME: ???
01360   case OPR_LABEL:
01361   case OPR_WHERE:
01362   case OPR_IO:                  // FIXME: Internal control flow possible?
01363   case OPR_LDID:
01364   case OPR_STID:
01365   case OPR_PSTID:  
01366   case OPR_ILOAD:
01367   case OPR_ISTORE:
01368   case OPR_ILOADX:
01369   case OPR_ISTOREX:
01370   case OPR_MLOAD:
01371   case OPR_MSTORE:
01372   case OPR_PSTORE:
01373   case OPR_LDBITS:
01374   case OPR_STBITS:
01375   case OPR_ILDBITS:
01376   case OPR_ISTBITS:
01377   case OPR_USE: // FIXME: how are these ordered?
01378   case OPR_INTERFACE: 
01379   case OPR_NULLIFY: 
01380     ty = OA::CFG::SIMPLE;
01381     break;
01382 
01383   // Bother.
01384   default: 
01385     // FIXME: OPR_ASSERT, OPR_GOTO_OUTER_BLOCK, OPR_TRAP, 
01386     //  OPR_REGION, OPR_REGION_EXIT
01387     fprintf(stderr, "*** Open64IRInterface: Unknown WHIRL operator %s ***.\n", 
01388             OPERATOR_name(opr));
01389     dump_wn(wn);
01390     assert(0);
01391     break;
01392   }
01393   return ty;
01394 }
01395 
01396 OA::StmtLabel
01397 Open64IRInterface::getLabel(OA::StmtHandle h)
01398 {
01399   //setCurrentProcToProcContext(h);
01400   WN *wn = (WN *) h.hval();
01401 
01402   if (WN_operator (wn) == OPR_LABEL) {
01403     return (OA::irhandle_t) WN_label_number (wn);
01404   } else {
01405     return 0;
01406   }
01407 }
01408 
01409 OA::OA_ptr<OA::IRRegionStmtIterator>
01410 Open64IRInterface::getFirstInCompound(OA::StmtHandle h)
01411 {
01412   //setCurrentProcToProcContext(h);
01413   WN *wn = (WN *) h.hval();
01414   OA::OA_ptr<OA::IRRegionStmtIterator> retval;
01415   retval = new Open64IRRegionStmtIterator (WN_first (wn));
01416   return retval;
01417 }
01418 
01419 
01420 //----------------------------------------------------------
01421 // Loops
01422 //----------------------------------------------------------
01423 
01424 OA::OA_ptr<OA::IRRegionStmtIterator>
01425 Open64IRInterface::loopBody(OA::StmtHandle h)
01426 {
01427   //setCurrentProcToProcContext(h);
01428   WN *wn = (WN *) h.hval();
01429   WN *body_wn = 0;
01430 
01431   switch (WN_operator (wn)) {
01432   case OPR_DO_LOOP:
01433     body_wn = WN_do_body (wn);
01434     break;
01435   case OPR_WHILE_DO:
01436   case OPR_DO_WHILE:
01437     body_wn = WN_while_body (wn);
01438     break;
01439   default:
01440     // FIXME: Any other statement types here?
01441     assert(0);
01442     break;
01443   }
01444 
01445   OA::OA_ptr<OA::IRRegionStmtIterator> retval;
01446   retval = new Open64IRRegionStmtIterator (body_wn);
01447   return retval;
01448 }
01449 
01450 OA::StmtHandle
01451 Open64IRInterface::loopHeader(OA::StmtHandle h)
01452 {
01453   //setCurrentProcToProcContext(h);
01454   WN *wn = (WN *) h.hval();
01455 
01456   // This is called for all top-tested loops, but only OPR_DO_LOOP has
01457   // an initialization statement.
01458   if (WN_operator (wn) == OPR_DO_LOOP) {
01459     return (OA::irhandle_t) WN_start (wn);
01460   } else if (WN_operator (wn) == OPR_WHILE_DO) {
01461     return 0;
01462   } else {
01463     assert(0);
01464   }
01465 }
01466 
01467 OA::StmtHandle
01468 Open64IRInterface::getLoopIncrement(OA::StmtHandle h)
01469 {
01470   //setCurrentProcToProcContext(h);
01471   WN *wn = (WN *) h.hval();
01472 
01473   // This is called for all top-tested loops, but only OPR_DO_LOOP has
01474   // an initialization statement.
01475   if (WN_operator (wn) == OPR_DO_LOOP) {
01476     return (OA::irhandle_t) WN_step (wn);
01477   } else if (WN_operator (wn) == OPR_WHILE_DO) {
01478     return 0;
01479   } else {
01480     assert(0);
01481   }
01482 }
01483 
01484 bool
01485 Open64IRInterface::loopIterationsDefinedAtEntry(OA::StmtHandle h)
01486 {
01487   //setCurrentProcToProcContext(h);
01488   //WN *wn = (WN *) h.hval();
01489 
01490   // In Whirl, only an OPR_DO_LOOP is specified to have Fortran semantics,
01491   // which means the increment is a loop-invariant expression.  However,
01492   // Open64 already enforces the restrictions, so we don't have to do
01493   // anything special here (i.e., always return false).
01494   return false;
01495 }
01496 
01497 OA::ExprHandle
01498 Open64IRInterface::getLoopCondition(OA::StmtHandle h)
01499 {
01500   //setCurrentProcToProcContext(h);
01501   WN *wn = (WN *) h.hval();
01502   WN *expr_wn = 0;
01503 
01504   switch (WN_operator (wn)) {
01505   case OPR_DO_LOOP:
01506     expr_wn = WN_end (wn);
01507     break;
01508   case OPR_WHILE_DO:
01509   case OPR_DO_WHILE:
01510     expr_wn = WN_while_test (wn);
01511     break;
01512   default:
01513     assert(0);
01514     break;
01515   }
01516 
01517   return (OA::irhandle_t) expr_wn;
01518 }
01519 
01520 //----------------------------------------------------------
01521 // Structured two-way conditionals
01522 //----------------------------------------------------------
01523 
01524 OA::OA_ptr<OA::IRRegionStmtIterator>
01525 Open64IRInterface::trueBody(OA::StmtHandle h)
01526 {
01527   //setCurrentProcToProcContext(h);
01528   WN *wn = (WN *) h.hval();
01529   OA::OA_ptr<OA::IRRegionStmtIterator> retval;
01530 
01531   if (WN_operator (wn) == OPR_IF) {
01532     retval = new Open64IRRegionStmtIterator (WN_then (wn));
01533     return retval;
01534   } else {
01535     assert(0);
01536   }
01537 }
01538 
01539 
01540 OA::OA_ptr<OA::IRRegionStmtIterator>
01541 Open64IRInterface::elseBody(OA::StmtHandle h)
01542 {
01543   //setCurrentProcToProcContext(h);
01544   WN *wn = (WN *) h.hval();
01545   OA::OA_ptr<OA::IRRegionStmtIterator> retval;
01546 
01547   if (WN_operator (wn) == OPR_IF) {
01548     retval = new Open64IRRegionStmtIterator (WN_else (wn));
01549     return retval;
01550   } else {
01551     assert(0);
01552   }
01553 }
01554 
01555 
01556 OA::ExprHandle
01557 Open64IRInterface::getCondition(OA::StmtHandle h)
01558 {
01559   //setCurrentProcToProcContext(h);
01560   WN *wn = (WN *) h.hval();
01561   WN *expr_wn = 0;
01562 
01563   if (WN_operator (wn) == OPR_IF) {
01564     expr_wn = WN_if_test (wn);
01565   } else if (WN_operator (wn) == OPR_TRUEBR
01566              || WN_operator (wn) == OPR_FALSEBR) {
01567     expr_wn = WN_kid0 (wn);
01568   } else {
01569     assert(0);
01570   }
01571   return (OA::irhandle_t) expr_wn;
01572 }
01573 
01574 
01575 //----------------------------------------------------------
01576 // Structured multiway conditionals
01577 //----------------------------------------------------------
01578 
01579 int
01580 Open64IRInterface::numMultiCases(OA::StmtHandle h)
01581 {
01582   // Whirl does not have a structured switch statement.
01583   assert(0);
01584   return 0;
01585 }
01586 
01587 OA::OA_ptr<OA::IRRegionStmtIterator>
01588 Open64IRInterface::multiBody(OA::StmtHandle h, int bodyIndex)
01589 {
01590   // Whirl does not have a structured switch statement.
01591   assert(0);
01592   OA::OA_ptr<OA::IRRegionStmtIterator> retval; retval = NULL;
01593   return retval;
01594 }
01595 
01596 bool
01597 Open64IRInterface::isBreakImplied(OA::StmtHandle multicond)
01598 {
01599   // Whirl does not have a structured switch statement.
01600   assert(0);
01601   return false;
01602 }
01603 
01604 bool
01605 Open64IRInterface::isCatchAll(OA::StmtHandle h, int bodyIndex)
01606 {
01607   // Whirl does not have a structured switch statement.
01608   assert(0);
01609   return false;
01610 }
01611 
01612 OA::OA_ptr<OA::IRRegionStmtIterator>
01613 Open64IRInterface::getMultiCatchall(OA::StmtHandle h)
01614 {
01615   // Whirl does not have a structured switch statement.
01616   assert(0);
01617   OA::OA_ptr<OA::IRRegionStmtIterator> retval; retval = NULL;
01618   return retval;
01619 }
01620 
01621 OA::ExprHandle
01622 Open64IRInterface::getSMultiCondition(OA::StmtHandle h, int bodyIndex)
01623 {
01624   // Whirl does not have a structured switch statement.
01625   assert(0);
01626   return (OA::irhandle_t) 0;
01627 }
01628 
01629 OA::ExprHandle 
01630 Open64IRInterface::getSMultiTest(OA::StmtHandle h)
01631 {
01632   // Whirl does not have a structured switch statement.
01633   assert(0);
01634   return (OA::irhandle_t) 0;
01635 }
01636 
01637 #if 0 // deprecated
01638 OA::ExprHandle
01639 Open64IRInterface::getMultiExpr(OA::StmtHandle h)
01640 {
01641   // Whirl does not have a structured switch statement.
01642   assert(0);
01643   return (OA::irhandle_t) 0;
01644 }
01645 #endif
01646 
01647 //----------------------------------------------------------
01648 // Unstructured two-way conditionals
01649 //----------------------------------------------------------
01650 
01651 OA::StmtLabel
01652 Open64IRInterface::getTargetLabel(OA::StmtHandle h, int n)
01653 {
01654   //setCurrentProcToProcContext(h);
01655   WN *wn = (WN *) h.hval();
01656 
01657   if (WN_operator (wn) == OPR_GOTO
01658       || WN_operator (wn) == OPR_TRUEBR
01659       || WN_operator (wn) == OPR_FALSEBR) {
01660     return (OA::irhandle_t) WN_label_number (wn);
01661   } else {
01662     assert(0);
01663   }
01664 }
01665 
01666 //----------------------------------------------------------
01667 // Unstructured multi-way conditionals
01668 //----------------------------------------------------------
01669 
01670 // Given an unstructured multi-way branch, return the number of targets.
01671 // The count does not include the optional default/catchall target.
01672 int
01673 Open64IRInterface::numUMultiTargets(OA::StmtHandle h)
01674 { 
01675   //setCurrentProcToProcContext(h);
01676   WN *wn = (WN *) h.hval();
01677 
01678   // FIXME: Support also OPR_XGOTO?
01679   OPERATOR opr = WN_operator(wn);
01680   if (opr == OPR_COMPGOTO || opr == OPR_SWITCH) {
01681     return WN_num_entries(wn);
01682   } else {
01683     assert(0);
01684   }
01685 }
01686 
01687 // Given an unstructured multi-way branch, return the label of the target
01688 // statement at 'targetIndex'. The n targets are indexed [0..n-1]. 
01689 OA::StmtLabel
01690 Open64IRInterface::getUMultiTargetLabel(OA::StmtHandle h, int targetIndex)
01691 {
01692   //setCurrentProcToProcContext(h);
01693   WN* wn = (WN*)h.hval();
01694   OA::StmtLabel target_label = 0;
01695   WN* curr_goto = NULL;
01696 
01697   // Whirl has a number of multiway branches: OPR_SWITCH, OPR_COMPGOTO,
01698   // and OPR_XGOTO. SWITCH and COMPGOTO are redundant in the sense that
01699   // SWITCH could be used for any COMPGOTO. Nevertheless, we have to handle
01700   // them all.
01701   // FIXME: XGOTO is a lowered form of COMPGOTO which isn't handled here yet. 
01702   OPERATOR opr = WN_operator(wn);
01703   assert(opr == OPR_COMPGOTO || opr == OPR_SWITCH);
01704   if (opr == OPR_COMPGOTO) {
01705     assert(WN_operator(WN_kid1(wn)) == OPR_BLOCK);
01706     curr_goto = WN_first(WN_kid1(wn));
01707   } else {
01708     assert(WN_operator(WN_switch_table(wn)) == OPR_BLOCK);
01709     curr_goto = WN_first(WN_switch_table(wn));
01710   }
01711   
01712   // For COMPGOTO, kid 1 is an OPR_BLOCK which contains the dispatch
01713   // table as a list of OPR_GOTOs to the corresponding targets. SWITCH
01714   // is similar, except its table is a list of OPR_CASEGOTOs.
01715   //
01716   // Below is somewhat inefficient, but the method wants random access to the
01717   // targets, while Whirl blocks have to be traversed sequentially.
01718   int curr_idx = 0;
01719   for ( ; (curr_goto); curr_goto = WN_next(curr_goto), ++curr_idx) {
01720     if (curr_idx == targetIndex) {
01721       assert(WN_operator(curr_goto) == OPR_GOTO 
01722              || WN_operator(curr_goto) == OPR_CASEGOTO);
01723       target_label = (OA::StmtLabel) WN_label_number(curr_goto);
01724       break;
01725     }
01726   }
01727   assert(curr_idx == targetIndex); // Ensure target is found...
01728   
01729   return target_label;
01730 }
01731 
01732 // Given an unstructured multi-way branch, return the label of the optional
01733 // default/catchall target. Return 0 if no default target.
01734 OA::StmtLabel
01735 Open64IRInterface::getUMultiCatchallLabel (OA::StmtHandle h)
01736 { 
01737   //setCurrentProcToProcContext(h);
01738   WN *wn = (WN *) h.hval();
01739   WN *target = 0;
01740 
01741   // FIXME: Support also OPR_XGOTO?
01742   if (WN_operator(wn) == OPR_COMPGOTO) {
01743     target = WN_kid2(wn);
01744   } else if (WN_operator(wn) == OPR_SWITCH) {
01745     target = WN_switch_default(wn);
01746   } else {
01747     assert(0);
01748   }
01749 
01750   if (target) {
01751     assert(WN_operator(target) == OPR_GOTO);
01752     return (OA::StmtLabel) WN_label_number(target);
01753   } else {
01754     return 0;
01755   }
01756 }
01757 
01758 // Given an unstructured multi-way branch, return the condition expression
01759 // corresponding to target 'targetIndex'. The n targets are indexed [0..n-1].
01760 // For OPR_SWITCH, return an OPR_CASEGOTO; for OPR_COMPGOTO, return OPR_GOTO.
01761 OA::ExprHandle
01762 Open64IRInterface::getUMultiCondition (OA::StmtHandle h, int targetIndex)
01763 {
01764   //setCurrentProcToProcContext(h);
01765   // Cf. GetUMultiTargetLabel (no need for assertions here)
01766   WN* wn = (WN*)h.hval();
01767   WN* curr_goto = NULL;
01768   OA::ExprHandle condExpr = 0;
01769 
01770   OPERATOR opr = WN_operator(wn);
01771   if (opr == OPR_COMPGOTO) {
01772     curr_goto = WN_first(WN_kid1(wn));
01773   } else {
01774     curr_goto = WN_first(WN_switch_table(wn));
01775   }
01776   
01777   int curr_idx = 0;
01778   for ( ; (curr_goto); curr_goto = WN_next(curr_goto), ++curr_idx) {
01779     if (curr_idx == targetIndex) {
01780       condExpr = (OA::irhandle_t)curr_goto; // OPR_CASEGOTO or OPR_GOTO
01781       break;
01782     }
01783   }
01784   return condExpr;
01785 }
01786 
01787 OA::ExprHandle 
01788 Open64IRInterface::getUMultiTest(OA::StmtHandle h) {
01789 
01790   //setCurrentProcToProcContext(h);
01791   WN* wn = (WN*)h.hval();
01792   WN *expr_wn = 0;
01793     
01794   if (WN_operator(wn)==OPR_SWITCH) {
01795     expr_wn = WN_switch_test (wn);
01796   } else {
01797     std::cout << "Not a SWITCH in getUMultiTest " << std::endl;
01798     std::cout.flush();
01799     //return (OA::irhandle_t) 0; // user will have to check in case not switch
01800     assert (0);
01801   }
01802 
01803   return (OA::irhandle_t) expr_wn;
01804 
01805 }
01806 
01807 //---------------------------------------------------------------------------
01808 // AliasIRInterfaceDefault
01809 //---------------------------------------------------------------------------
01810 
01811 OA::OA_ptr<OA::MemRefHandleIterator> 
01812 Open64IRInterface::getMemRefIterator(OA::StmtHandle h) 
01813 {
01814   setCurrentProcToProcContext(h);
01815   
01816   // if haven't already determined the set of memrefs for this stmt
01817   // initializing the mapping of MemRefHandle's to a set of MemRefExprs,
01818   // and based off that map get all the MemRefHandle's
01819   if (sStmt2allMemRefsMap[h].empty() ) {
01820       
01821     // first loop through call sites for this statement
01822     // to create a map of actual parameters (OPR_PARMs WNs)
01823     // to the call handle
01824     OA::OA_ptr<OA::IRCallsiteIterator> callIter = getCallsites(h);
01825     for ( ; callIter->isValid(); (*callIter)++ ) {
01826         OA::CallHandle call = callIter->current();
01827         OA::OA_ptr<OA::IRCallsiteParamIterator> paramIter 
01828             = getCallsiteParams(call);
01829         for ( ; paramIter->isValid(); (*paramIter)++ ) {
01830             OA::ExprHandle param = paramIter->current();
01831             sParamToCallMap[param] = call;
01832         }
01833     }
01834  
01835     findAllMemRefsAndMapToMemRefExprs(h,(WN*)h.hval(),0);
01836   }
01837 
01838   OA::OA_ptr<OA::MemRefHandleIterator> retval;
01839   retval = new Open64IRMemRefIterator(h);
01840   return retval;
01841 }
01842 
01843 
01844 
01845 
01846 // Given WHIRL statements (including control flow
01847 // statements representing embedded expressions, but not statements),
01848 // recursively find the memory-references in the statement and create
01849 // OA::MemRefExprs to model them to OA.  Note: Memory
01850 // references will generally be WHIRL expressions; however STORES --
01851 // WHIRL *statements* -- are returned to represent a left-hand-side
01852 // reference; and indirect CALLS are returned to represent a function
01853 // pointer reference.
01854 // Also map each MemRefHandle to a set of MemRefExprs in sMemRef2mreSetMap
01855 // and map each stmt to all MemRefHandles for that statement 
01856 // in sStmt2allMemRefsMap.
01857 void Open64IRInterface::findAllMemRefsAndMapToMemRefExprs(OA::StmtHandle stmt,
01858         WN* wn, unsigned lvl)
01859 {
01860   using namespace OA;
01861   // If we know the language is F90 or FORTRAN then we can get more
01862   // precise MemRefExprs
01863   Language = LANG_F90; // FIXME: Open64's global var Language isn't set
01864   bool isFortran = (Language == LANG_F77 || Language == LANG_F90);
01865   // Base case
01866   if (!wn) { return; }
01867 
01868   OPERATOR opr = WN_operator(wn);
01869     
01870   // -------------------------------------------------------
01871   // Gather information about this mem-ref
01872   // -------------------------------------------------------
01873   TY_IDX base_ty = 0, ref_ty = 0;
01874   WN_OFFSET offset = 0;
01875   UINT field_id = 0;
01876   if (OPERATOR_is_load(opr) || opr == OPR_LDA || opr == OPR_LDMA) {
01877       offset = WN_load_offset(wn); // == WN_lda_offset()
01878   }
01879   // Set accuracy
01880   bool fullAccuracy = false;
01881   // These only work on loads and stores
01882   // FIXME: asserts in wn_attr.cpp code on MLOADS
01883   if (opr!=OPR_MLOAD && opr!=OPR_MSTORE && 
01884       (OPERATOR_is_store(opr) || OPERATOR_is_load(opr) 
01885       || opr==OPR_LDA || opr==OPR_LDMA)) 
01886   {
01887       base_ty = WN_GetBaseObjType(wn);
01888       ref_ty = WN_GetRefObjType(wn);
01889       if (OPERATOR_has_field_id(opr)) {
01890           field_id = WN_field_id(wn);
01891       }
01892       if (offset == 0 && field_id == 0) { // we do not have a structure ref
01893         if (base_ty != 0 && WN2F_Can_Assign_Types(base_ty, ref_ty)) {
01894           // If assigning to same object, we have full accuracy
01895           fullAccuracy = true;
01896         }
01897       }
01898   }
01899 
01900   // Determination of these is the same for most, exceptions dealt with
01901   // in the big switch stmt
01902   MemRefExpr::MemRefType hty;
01903   if (lvl==0 && (OPERATOR_is_store(opr))) {
01904       OA::ExprHandle rhs((OA::irhandle_t)WN_kid0(wn));
01905       mStmt2allExprsMap[stmt].insert(rhs);
01906 
01907 
01908       // create AssignPair
01909       OA::MemRefHandle lhs = (OA::irhandle_t)wn;
01910       mStmtToAssignPairs[stmt].insert(pair<OA::MemRefHandle,
01911                                       OA::ExprHandle>(lhs, rhs));
01912 
01913       hty = MemRefExpr::DEF;
01914   } else {
01915       hty = MemRefExpr::USE;
01916   }
01917   
01918 bool isAddrOf = false;
01919   
01920   // -------------------------------------------------------
01921   // Gather information from children and generate MRE(s)
01922   // -------------------------------------------------------
01923   WN* subMemRef;
01924   // Large switch statement based on operator that current node represents
01925   switch (opr) {
01926     // NOTE: MLOAD, MSTORE?  FIXME?: we don't handle these, should we?
01927 
01928     case OPR_LDA:
01929     case OPR_LDMA:
01930     case OPR_LDID:    
01931     {
01933          ST* st = findBaseSymbol(wn);
01934          OA::SymHandle sym((OA::irhandle_t)st);
01935          assert(sym != OA::SymHandle(0));
01936 
01937          // do not want to create MemRefExpr if for Constants for Literals
01938          if(ST_is_constant (st)) {   
01939             break;   
01940          }
01941 
01942          // create MemRefExpr
01943          createAndMapNamedRef(stmt, wn, st, OA::MemRefExpr::USE);
01944 
01945          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
01946 
01948          if (isRefParam(sym)) {
01950              OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
01951              assert(m != OA::MemRefHandle(0));
01952              OA_ptr<MemRefExpr> newmre;
01953              newmre = *(sMemref2mreSetMap[m].begin());
01954              
01956              int numDerefs = 1;
01957              OA::OA_ptr<OA::Deref> deref_mre;
01958              OA::OA_ptr<OA::MemRefExpr> nullMRE;
01959              deref_mre = new OA::Deref(
01960                                        OA::MemRefExpr::USE,
01961                                        nullMRE,
01962                                        numDerefs);
01963              newmre = deref_mre->composeWith(newmre->clone());
01964 
01966              sMemref2mreSetMap[m].clear();
01967 
01969              sMemref2mreSetMap[m].insert(newmre);
01970 
01971          } 
01972 
01973 
01974          //TY_IDX ty = WN_GetRefObjType(wn);
01975 
01977          //if(TY_kind(sym) ==  KIND_POINTER) {
01978          //if(TY_kind(ST_type(st)) == KIND_POINTER) 
01979          //if (TY_Is_Pointer(ty)) 
01980          //if(ST_IS_POINTER(st))
01981          if(ST_is_my_pointer (st))
01982          {
01984              OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
01985              assert(m != OA::MemRefHandle(0));
01986              OA_ptr<MemRefExpr> newmre;
01987              newmre = *(sMemref2mreSetMap[m].begin());
01988 
01990              int numDerefs = 1;
01991              OA::OA_ptr<OA::Deref> deref_mre;
01992              OA::OA_ptr<OA::MemRefExpr> nullMRE;
01993              deref_mre = new OA::Deref(
01994                                        OA::MemRefExpr::USE,
01995                                        nullMRE,
01996                                        numDerefs);
01997              newmre = deref_mre->composeWith(newmre->clone());
01998 
02000              sMemref2mreSetMap[m].clear();
02001 
02003              sMemref2mreSetMap[m].insert(newmre);
02004 
02005          } 
02006 
02007          if (!isFortran) { isAddrOf = true; }
02008          break;          
02009 
02010     }
02011 
02012     case OPR_PSTID:
02013     {
02015          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02017          //findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid1(wn), lvl+1);
02018 
02020   
02022          ST* st = findBaseSymbol(wn);
02023          OA::SymHandle sym((OA::irhandle_t)st);
02024          assert(sym != OA::SymHandle(0));
02025          createAndMapNamedRef(stmt, wn, st, OA::MemRefExpr::DEF);
02026       
02027 
02028          OA::OA_ptr<OA::MemRefExpr> newmre, target_mre;
02029 
02031          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02032          assert(m != OA::MemRefHandle(0));
02033          newmre = *(sMemref2mreSetMap[m].begin());
02034 
02036          if (isRefParam(sym)) 
02037          {
02039              newmre->setMemRefType(OA::MemRefExpr::USE);
02040 
02042              int numDerefs = 1;
02043              OA::OA_ptr<OA::Deref> deref_mre;
02044              OA::OA_ptr<OA::MemRefExpr> nullMRE;
02045              deref_mre = new OA::Deref(
02046                                        OA::MemRefExpr::DEF,
02047                                        nullMRE,
02048                                        numDerefs);
02049              newmre = deref_mre->composeWith(newmre->clone());
02050 
02052              sMemref2mreSetMap[m].clear();
02053 
02055              sMemref2mreSetMap[m].insert(newmre);
02056 
02057          }
02058   
02060 
02062          WN* wn_rhs =  WN_kid(wn,0);
02063          m = OA::MemRefHandle((OA::irhandle_t)wn_rhs); 
02064          assert(m != OA::MemRefHandle(0));
02065          OA::OA_ptr<OA::MemRefExpr> target_newmre;
02066          target_newmre = *(sMemref2mreSetMap[m].begin());
02067  
02069          OA::OA_ptr<OA::MemRefExpr> nullMRE;
02070          OA::OA_ptr<OA::AddressOf> address_mre;
02071          address_mre = new OA::AddressOf( OA::MemRefExpr::USE, nullMRE);
02072          target_newmre = address_mre->composeWith(target_newmre->clone());
02073 
02075          sMemref2mreSetMap[m].clear();
02076 
02078          sMemref2mreSetMap[m].insert(target_newmre);
02079       
02080          mStmtToPtrPairs[stmt].insert(std::pair<OA::OA_ptr<OA::MemRefExpr>,
02081                          OA::OA_ptr<OA::MemRefExpr> > (newmre, target_newmre) );
02082 
02083          break;
02084     }
02085     
02086     case OPR_STID:
02087     {
02089          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02091          //findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid1(wn), lvl+1);
02092 
02094          ST* st = findBaseSymbol(wn);
02095          OA::SymHandle sym((OA::irhandle_t)st);
02096          assert(sym != OA::SymHandle(0));
02097          createAndMapNamedRef(stmt, wn, st, OA::MemRefExpr::DEF);
02098 
02100          if (isRefParam(sym)) {
02101 
02103              OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02104              assert(m != OA::MemRefHandle(0));
02105              OA_ptr<MemRefExpr> newmre;
02106              newmre = *(sMemref2mreSetMap[m].begin());
02107 
02109              newmre->setMemRefType(OA::MemRefExpr::USE);
02110 
02112              int numDerefs = 1;
02113              OA::OA_ptr<OA::Deref> deref_mre;
02114              OA::OA_ptr<OA::MemRefExpr> nullMRE;
02115              deref_mre = new OA::Deref(
02116                                        OA::MemRefExpr::DEF,
02117                                        nullMRE,
02118                                        numDerefs);
02119              newmre = deref_mre->composeWith(newmre);
02120 
02122              sMemref2mreSetMap[m].clear();
02123 
02125              sMemref2mreSetMap[m].insert(newmre->clone());
02126 
02127          }
02128 
02129 
02131          if(TY_kind(ST_type(st)) == KIND_POINTER)
02132          { 
02134              OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02135              assert(m != OA::MemRefHandle(0));
02136              OA_ptr<MemRefExpr> newmre;
02137              newmre = *(sMemref2mreSetMap[m].begin());
02138 
02140              newmre->setMemRefType(OA::MemRefExpr::USE);
02141 
02143              int numDerefs = 1;
02144              OA::OA_ptr<OA::Deref> deref_mre;
02145              OA::OA_ptr<OA::MemRefExpr> nullMRE;
02146              deref_mre = new OA::Deref(
02147                                        OA::MemRefExpr::DEF,
02148                                        nullMRE,
02149                                        numDerefs);
02150              newmre = deref_mre->composeWith(newmre->clone());
02151 
02153              sMemref2mreSetMap[m].clear();
02154 
02156              sMemref2mreSetMap[m].insert(newmre);
02157 
02158          }
02159  
02160          break;
02161     }
02162 
02163     case OPR_STRCTFLD:
02164     {
02165          //ST* st = WN_st(wn);
02166          //OA::SymHandle sym((OA::irhandle_t)st);
02167          //assert(sym != OA::SymHandle(0));
02168 
02170          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02171 
02173          OA::MemRefHandle mtop =  findTopMemRefHandle(wn);
02174          assert(mtop != OA::MemRefHandle(0));
02175 
02177          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02178          assert(m != OA::MemRefHandle(0));
02179 
02181          OA_ptr<MemRefExpr> newmre, newmre_clone;
02182          newmre_clone = *(sMemref2mreSetMap[mtop].begin());
02183          newmre = newmre_clone->clone();
02185          //sMemref2mreSetMap[mtop].clear();
02186          sMemref2mreSetMap.erase(mtop);
02187          sStmt2allMemRefsMap[stmt].erase(mtop);
02188 
02189          TY_IDX ty;
02190          ty = WN_GetBaseObjType(wn);
02191          UINT id = WN_field_id(wn);
02192          UINT cur_fld_id = 0;
02193          FLD_HANDLE fh = FLD_get_to_field(ty, id, cur_fld_id);
02194          char* fld_name = FLD_name(fh);
02195 
02196          //TY_IDX ref_ty;
02197          //ref_ty= WN_GetRefObjType(wn);
02198          newmre  = new OA::FieldAccess(OA::MemRefExpr::USE,
02199                                            newmre->clone(),
02200                                            fld_name);
02201         
02202          if(FLD_is_pointer(fh)) {
02204              //OA_ptr<MemRefExpr> newmre;
02205              //newmre = *(sMemref2mreSetMap[m].begin());
02206 
02207              
02209              newmre->setMemRefType(OA::MemRefExpr::USE);
02210 
02212              int numDerefs = 1;
02213              OA::OA_ptr<OA::Deref> deref_mre;
02214              OA::OA_ptr<OA::MemRefExpr> nullMRE;
02215              deref_mre = new OA::Deref(
02216                                        OA::MemRefExpr::USE,
02217                                        nullMRE,
02218                                        numDerefs);
02219              newmre = deref_mre->composeWith(newmre->clone());
02220          }
02221          
02222 
02223 
02224          
02226          sMemref2mreSetMap[m].insert(newmre);
02227          sStmt2allMemRefsMap[stmt].insert(m);
02228         
02229          break;
02230     }
02231 
02232     case OPR_ILOAD:
02233     case OPR_MLOAD:
02234     {
02236          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02237 
02239          OA::MemRefHandle mtop =  findTopMemRefHandle(wn);
02240          
02244          if(mtop == OA::MemRefHandle(0)) { break; }
02245 
02247          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02248          assert(m != OA::MemRefHandle(0));
02249 
02251          OA_ptr<MemRefExpr> newmre, newmre_clone;
02252          newmre_clone = *(sMemref2mreSetMap[mtop].begin());
02253          newmre = newmre_clone->clone();
02255          sMemref2mreSetMap.erase(mtop);
02256          sStmt2allMemRefsMap[stmt].erase(mtop);
02257 
02259          sMemref2mreSetMap[m].insert(newmre->clone());
02260          sStmt2allMemRefsMap[stmt].insert(m);
02261 
02262          break;
02263     }
02264 
02265     case OPR_ISTORE:
02266     case OPR_MSTORE:
02267     {
02269          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02270 
02272          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid1(wn), lvl+1);
02273 
02275          OA::MemRefHandle mtop =  findTopMemRefHandle(wn);
02276         
02277          
02281          if(mtop == OA::MemRefHandle(0)) { break; }
02282 
02284          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02285          assert(m != OA::MemRefHandle(0));
02286 
02288          OA_ptr<MemRefExpr> newmre, newmre_clone;
02289          newmre_clone = *(sMemref2mreSetMap[mtop].begin());
02290          newmre = newmre_clone->clone();
02292          sMemref2mreSetMap.erase(mtop);
02293          sStmt2allMemRefsMap[stmt].erase(mtop);
02294 
02296          newmre->setMemRefType(OA::MemRefExpr::DEF);
02297  
02299          sMemref2mreSetMap[m].insert(newmre->clone());
02300          sStmt2allMemRefsMap[stmt].insert(m);
02301 
02302          break;
02303     }
02304 
02305     case OPR_PSTORE:
02306     {
02308          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02309 
02311          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid1(wn), lvl+1);
02312 
02314          OA::MemRefHandle mtop =  findTopMemRefHandle(wn);
02315          assert(mtop != OA::MemRefHandle(0));
02316 
02318          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02319          assert(m != OA::MemRefHandle(0));
02320 
02322          OA_ptr<MemRefExpr> newmre, newmre_clone, target_newmre;
02323 
02324          newmre_clone = *(sMemref2mreSetMap[mtop].begin());
02325          newmre = newmre_clone->clone();
02327          sMemref2mreSetMap.erase(mtop);
02328          sStmt2allMemRefsMap[stmt].erase(mtop);
02329 
02330 
02332          newmre = newmre.convert<OA::RefOp>()->getMemRefExpr();
02333 
02335          OA::OA_ptr<OA::MemRefExpr> nullMRE;
02336          OA::OA_ptr<OA::AddressOf> address_mre;
02337          address_mre = new OA::AddressOf( OA::MemRefExpr::USE, nullMRE);
02338          newmre = address_mre->composeWith(newmre->clone());
02339             
02340          // set MemRefType=DEF
02341          newmre->setMemRefType(OA::MemRefExpr::DEF);
02342 
02344          sMemref2mreSetMap[m].insert(newmre->clone());
02345          sStmt2allMemRefsMap[stmt].insert(m);
02346 
02348 
02349          WN* kid0 = WN_kid(wn,0);
02350          mtop =  findTopMemRefHandle(kid0); 
02351          assert(m != OA::MemRefHandle(0));
02352 
02354          target_newmre = *(sMemref2mreSetMap[mtop].begin());
02356          sMemref2mreSetMap[mtop].clear();
02357    
02359          target_newmre = address_mre->composeWith(target_newmre->clone());
02360 
02361          sMemref2mreSetMap[mtop].insert(target_newmre->clone());
02362 
02363          mStmtToPtrPairs[stmt].insert(std::pair<OA::OA_ptr<OA::MemRefExpr>,
02364                          OA::OA_ptr<OA::MemRefExpr> > (newmre, target_newmre) );
02365          break;
02366     }
02367     case OPR_ARRAY:
02368     case OPR_ARRSECTION:
02369     {
02371          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02372 
02374          OA::MemRefHandle mtop =  findTopMemRefHandle(wn);
02375          assert(mtop != OA::MemRefHandle(0));
02376 
02378          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02379          assert(m != OA::MemRefHandle(0));
02380 
02382          OA_ptr<MemRefExpr> newmre,newmre_clone;
02383          newmre_clone = *(sMemref2mreSetMap[mtop].begin());
02384          newmre = newmre_clone->clone();
02386          sMemref2mreSetMap.erase(mtop);;
02387          sStmt2allMemRefsMap[stmt].erase(mtop);
02388 
02389          // composedWith SubSetRef
02390          OA::OA_ptr<OA::SubSetRef> subset_mre;
02391          OA::OA_ptr<OA::MemRefExpr> nullMRE;
02392          OA::OA_ptr<OA::MemRefExpr> composed_mre;
02393 
02394          subset_mre = new OA::SubSetRef(OA::MemRefExpr::USE,
02395                                         nullMRE);
02396 
02397          newmre = subset_mre->composeWith(newmre->clone());
02398 
02400          sMemref2mreSetMap[m].insert(newmre->clone());
02401          sStmt2allMemRefsMap[stmt].insert(m);
02402 
02403          // index expr are dim+1 ... 2*dim, dim = WN_kid_count(wn)-1 / 2
02404          for (INT kidno=(WN_kid_count(wn)-1)/2 +1;
02405              kidno<=WN_kid_count(wn)-1; kidno++)
02406          {
02407              WN* index = WN_kid(wn, kidno);
02408 
02410              OA::ExprHandle rhs((OA::irhandle_t)index);
02411         
02414              mStmt2allExprsMap[stmt].insert(rhs);
02415              mStmtToIndexExprs[stmt].insert(OA::MemRefHandle((OA::irhandle_t)index));
02416 
02417              findAllMemRefsAndMapToMemRefExprs(stmt, index,lvl);
02418          }
02419 
02420          break;
02421     }
02422 
02423     case OPR_ARRAYEXP:
02424     {
02426          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02427 
02428          break;
02429     }
02430 
02431     case OPR_CALL:
02432     {
02433         
02434         OA_ptr<MemRefExpr> newmre;
02436         for (INT kidno=0; kidno<=WN_kid_count(wn)-1; kidno++) {
02437             WN* param = WN_kid(wn,kidno);
02438 
02439             if(param == NULL) { continue; }
02440             
02441             findAllMemRefsAndMapToMemRefExprs(stmt, param, lvl+1);
02442 
02443             ST* st = findBaseSymbol(param);
02444 
02445             if(st == NULL || ST_is_constant (st)) {
02446               continue;
02447             }
02448 
02450             //if(TY_kind(ST_type(st)) == KIND_POINTER)
02451             if(ST_is_my_pointer (st) )
02452             {
02453                   OA::MemRefHandle m = MemRefHandle((irhandle_t)param);
02454                   assert(m != OA::MemRefHandle(0));
02455                   newmre = *(sMemref2mreSetMap[m].begin());
02456 
02458                   OA::OA_ptr<OA::MemRefExpr> nullMRE;
02459                   OA::OA_ptr<OA::AddressOf> address_mre;
02460                   address_mre = new OA::AddressOf( OA::MemRefExpr::USE, nullMRE);
02461                   newmre = address_mre->composeWith(newmre->clone());
02462 
02464                   sMemref2mreSetMap[m].clear();
02465 
02467                   sMemref2mreSetMap[m].insert(newmre);
02468             
02469             } 
02470         } 
02471 
02472         // Intrinsic call
02473         ST* st = WN_st(wn);
02474         const char* funcNm = ST_name(st);
02475         if (IntrinsicInfo::isIntrinsic(wn)
02476             &&
02477             strcmp(funcNm,"_ALLOCATE")!=0)  {
02478 
02480           for (INT kidno=0; kidno<=WN_kid_count(wn)-1; kidno++) {
02481 
02482             WN* param = WN_kid(wn,kidno);
02483 
02484             if(param == NULL) { continue; }
02485 
02486             // erase ExprHandles
02487             mStmt2allExprsMap[stmt].erase((OA::irhandle_t)param);
02488 
02490             OA::MemRefHandle m = MemRefHandle((irhandle_t)param);
02491             assert(m != OA::MemRefHandle(0));
02492 
02495 
02497             OA_ptr<MemRefExpr> newmre;
02498             newmre = *(sMemref2mreSetMap[m].begin());
02499 
02501             int numDerefs = 1;
02502             OA::OA_ptr<OA::Deref> deref_mre;
02503             OA::OA_ptr<OA::MemRefExpr> nullMRE;
02504             deref_mre = new OA::Deref(
02505                                        OA::MemRefExpr::USE,
02506                                        nullMRE,
02507                                        numDerefs);
02508             newmre = deref_mre->composeWith(newmre->clone());
02509  
02510 
02511             if(!newmre->isaUnnamed()) {
02512                sMemref2mreSetMap[m].clear();
02513                sMemref2mreSetMap[m].insert(newmre);
02514             } else {
02515                sMemref2mreSetMap.erase(m);
02517                sStmt2allMemRefsMap[stmt].erase(m);
02518 
02519 
02521                WN* kid = WN_kid(param,0);
02522                m = MemRefHandle((irhandle_t)kid);
02523                assert(m != OA::MemRefHandle(0));
02525                sMemref2mreSetMap.erase(m);
02526                sStmt2allMemRefsMap[stmt].erase(m);
02527 
02529                mStmt2allExprsMap[stmt].erase((OA::irhandle_t)kid);
02530 
02532                OA::MemRefHandle lhs((OA::irhandle_t)kid);
02533                OA::ExprHandle rhs((OA::irhandle_t)kid);
02534                mStmtToAssignPairs[stmt].erase(pair<OA::MemRefHandle, OA::ExprHandle>(lhs, rhs));
02535 
02536 
02537                OA::MemRefHandle lhs_kid((OA::irhandle_t)WN_kid0(wn));
02538                OA::ExprHandle rhs_kid((OA::irhandle_t)WN_kid0(wn));
02539                mStmtToAssignPairs[stmt].erase(pair<OA::MemRefHandle, OA::ExprHandle>(lhs_kid, rhs_kid));
02540 
02541             }
02542           }
02543         }
02544         if(strcmp(funcNm,"_ALLOCATE")==0) {
02545 
02546            for (INT kidno=0; kidno<=WN_kid_count(wn)-2; kidno++) {
02547                
02548                 WN* param = WN_kid(wn,kidno);
02549 
02551                 ST* st = findBaseSymbol(param);
02552  
02554                 OA::MemRefHandle m = MemRefHandle((irhandle_t)param);
02555                 assert(m != OA::MemRefHandle(0));
02556                 
02558                 OA_ptr<MemRefExpr> newmre;
02559                 newmre = *(sMemref2mreSetMap[m].begin());
02560 
02562                 sMemref2mreSetMap[m].erase(newmre);
02563 
02565                 int numDerefs = 1;
02566                 OA::OA_ptr<OA::Deref> deref_mre;
02567                 OA::OA_ptr<OA::MemRefExpr> nullMRE;
02568                 deref_mre = new OA::Deref(
02569                                      OA::MemRefExpr::DEF,
02570                                      nullMRE,
02571                                      numDerefs);
02572                 newmre = deref_mre->composeWith(newmre->clone());
02573                 
02575                 if(newmre->isaRefOp()) {
02576                    OA_ptr<RefOp> refOp;
02577                    refOp = newmre.convert<OA::RefOp>();
02578                    if(refOp->isaSubSetRef()) {
02579                       newmre = refOp->getMemRefExpr();
02580                    }
02581                    if(ST_is_my_pointer (st))
02582                    {
02584                       OA::OA_ptr<OA::AddressOf> address_mre;
02585                       address_mre = new OA::AddressOf( OA::MemRefExpr::USE, nullMRE);
02586                       newmre = address_mre->composeWith(newmre->clone());
02587                    }
02588                 }
02589 
02591                 newmre->setMemRefType(OA::MemRefExpr::DEF);
02593                 sMemref2mreSetMap[m].insert(newmre);
02594 
02595                 if(ST_is_my_pointer(st))
02596                 {
02599                   WN* param0 = WN_kid(param,0);
02600                   m = OA::MemRefHandle((OA::irhandle_t)param0);
02601                   assert(m != OA::MemRefHandle(0));
02603                   OA::ProcHandle proc = getCurrentProcContext();
02604                   OA::ExprHandle expr((OA::irhandle_t)param);
02605                   OA::OA_ptr<OA::MemRefExpr> target_newmre; 
02606                   target_newmre = new OA::UnnamedRef(OA::MemRefExpr::USE,expr,proc);
02608                   OA::OA_ptr<OA::MemRefExpr> nullMRE;
02609                   OA::OA_ptr<OA::AddressOf> address_mre;
02610                   address_mre = new OA::AddressOf( OA::MemRefExpr::USE, nullMRE);
02611                   target_newmre = address_mre->composeWith(target_newmre->clone());
02613                   sMemref2mreSetMap[m].insert(target_newmre);
02614                   sStmt2allMemRefsMap[stmt].insert(m);
02616                   mStmtToPtrPairs[stmt].insert(std::pair<OA::OA_ptr<OA::MemRefExpr>, OA::OA_ptr<OA::MemRefExpr> > (newmre, target_newmre) );
02617    
02618        
02620                   mStmt2allExprsMap[stmt].erase((OA::irhandle_t)param);
02621                   mStmt2allExprsMap[stmt].insert((OA::irhandle_t)param0);
02622  
02623                 }
02624            }
02625 
02626 
02628            WN* param = WN_kid(wn,(WN_kid_count(wn)-1));
02630            OA::MemRefHandle m = MemRefHandle((irhandle_t)param);
02631            assert(m != OA::MemRefHandle(0));
02633            sMemref2mreSetMap.erase(m);
02634            sStmt2allMemRefsMap[stmt].erase(m);
02636            WN* param_kid = WN_kid(param,0);
02637            m = MemRefHandle((irhandle_t)param_kid);
02639            sMemref2mreSetMap.erase(m);
02640            sStmt2allMemRefsMap[stmt].erase(m);
02641            // erase ExprHandles 
02642            mStmt2allExprsMap[stmt].erase((OA::irhandle_t)param);
02643            mStmt2allExprsMap[stmt].erase((OA::irhandle_t)param_kid);
02644         }
02645 
02646         break;
02647     }
02648     
02649     case OPR_INTRINSIC_CALL:
02650     case OPR_INTRINSIC_OP:
02651     {
02653          mStmt2allExprsMap[stmt].insert((OA::irhandle_t)wn);
02655          for (INT kidno=0; kidno<=WN_kid_count(wn)-1; kidno++) {
02656             
02657             WN* param = WN_kid(wn,kidno);
02658 
02660             findAllMemRefsAndMapToMemRefExprs(stmt, param, lvl+1);
02661 
02662 
02664             mStmt2allExprsMap[stmt].erase((OA::irhandle_t)param);
02665             //mStmt2allExprsMap[stmt].insert((OA::irhandle_t)(WN_kid0(param)));
02666          
02667 
02669             OA::MemRefHandle m = MemRefHandle((irhandle_t)param);
02670             assert(m != OA::MemRefHandle(0));
02671 
02673             OA_ptr<MemRefExpr> newmre;
02674             newmre = *(sMemref2mreSetMap[m].begin());
02675 
02677             int numDerefs = 1;
02678             OA::OA_ptr<OA::Deref> deref_mre;
02679             OA::OA_ptr<OA::MemRefExpr> nullMRE;
02680             deref_mre = new OA::Deref(
02681                                        OA::MemRefExpr::USE,
02682                                        nullMRE,
02683                                        numDerefs);
02684 
02685             newmre = deref_mre->composeWith(newmre->clone());
02686 
02687             if(!newmre->isaUnnamed()) {
02688                sMemref2mreSetMap[m].clear();
02689                sMemref2mreSetMap[m].insert(newmre);
02690             } else {
02691 
02692 
02693                sMemref2mreSetMap.erase(m);
02695                sStmt2allMemRefsMap[stmt].erase(m);
02696 
02697 
02698 
02699 
02701                WN* kid = WN_kid(param,0);
02702 
02703 
02705                mStmt2allExprsMap[stmt].erase((OA::irhandle_t)kid);
02707                OA::MemRefHandle lhs((OA::irhandle_t)kid);
02708                OA::ExprHandle rhs((OA::irhandle_t)kid);
02709                mStmtToAssignPairs[stmt].erase(pair<OA::MemRefHandle, OA::ExprHandle>(lhs, rhs));
02710 
02711 
02712                m = MemRefHandle((irhandle_t)kid);
02713                assert(m != OA::MemRefHandle(0));
02715                sMemref2mreSetMap.erase(m);
02716                sStmt2allMemRefsMap[stmt].erase(m);
02718                //mStmt2allExprsMap[stmt].erase((OA::irhandle_t)m);
02719             }
02720 
02721         }
02722 
02723         if(strcmp(IntrinsicInfo::intrinsicBaseName(WN_intrinsic(wn)),
02724                     "CASSIGNSTMT")==0) {
02725 
02726             WN* param = WN_kid(wn,0);
02728             OA::MemRefHandle m = MemRefHandle((irhandle_t)param);
02729             assert(m != OA::MemRefHandle(0));
02730 
02732             OA_ptr<MemRefExpr> newmre;
02733             newmre = *(sMemref2mreSetMap[m].begin());
02734             sMemref2mreSetMap[m].clear();
02735 
02736             newmre->setMemRefType(OA::MemRefExpr::DEF);
02737             sMemref2mreSetMap[m].insert(newmre);
02738 
02739 
02740              OA::MemRefHandle lhs;
02741              lhs = MemRefHandle((irhandle_t)WN_kid0(WN_kid0(wn)));
02742              OA::ExprHandle rhs;
02743              rhs = ExprHandle((irhandle_t)WN_kid0(WN_kid1(wn)));
02744              mStmtToAssignPairs[stmt].insert(pair<OA::MemRefHandle, OA::ExprHandle>(lhs, rhs));
02745 
02747              mStmt2allExprsMap[stmt].erase((OA::irhandle_t)wn);
02748 
02749              mStmt2allExprsMap[stmt].insert((OA::irhandle_t)WN_kid1(wn));
02750         }   
02751         break;
02752     }
02753 
02754     case OPR_PARM:
02755     {
02757          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid0(wn), lvl+1);
02758 
02759          OA_ptr<MemRefExpr> newmre;
02761          OA::MemRefHandle mtop =  findTopMemRefHandle(wn);
02762 
02764          mStmt2allExprsMap[stmt].insert((OA::irhandle_t)wn);
02765          mStmt2allExprsMap[stmt].erase((OA::irhandle_t)WN_kid0(wn));
02766 
02767          if(mtop == OA::MemRefHandle(0)) {
02769             WN* top = WN_kid0(wn);
02770             OA::ProcHandle proc = getCurrentProcContext();
02771             OA::ExprHandle expr((OA::irhandle_t)top);
02772             newmre = new OA::UnnamedRef(OA::MemRefExpr::DEF,expr,proc);
02773 
02775            OA::MemRefHandle m = MemRefHandle((irhandle_t)top);
02776            sMemref2mreSetMap[m].insert(newmre->clone());
02777            sStmt2allMemRefsMap[stmt].insert(m);
02778 
02779            // create the AssignPair
02780            OA::MemRefHandle lhs((OA::irhandle_t)WN_kid0(wn));
02781            OA::ExprHandle rhs((OA::irhandle_t)WN_kid0(wn));
02782            mStmtToAssignPairs[stmt].insert(pair<OA::MemRefHandle, OA::ExprHandle>(lhs, rhs));
02783            mStmt2allExprsMap[stmt].insert(rhs);
02784 
02785          } else {
02786 
02787            OA::OA_ptr<OA::MemRefExpr> newmre_clone;  
02789            newmre_clone = *(sMemref2mreSetMap[mtop].begin());
02790            newmre =newmre_clone->clone();
02792            sMemref2mreSetMap.erase(mtop);
02793            sStmt2allMemRefsMap[stmt].erase(mtop);
02794          }
02795 
02797          newmre->setMemRefType(OA::MemRefExpr::USE);
02798 
02800          OA::OA_ptr<OA::MemRefExpr> nullMRE;
02801          OA::OA_ptr<OA::AddressOf> address_mre;
02802          address_mre = new OA::AddressOf( OA::MemRefExpr::USE, nullMRE);
02803          newmre = address_mre->composeWith(newmre->clone());
02804 
02806          OA::MemRefHandle m = MemRefHandle((irhandle_t)wn);
02807 
02808          sMemref2mreSetMap[m].insert(newmre);
02809          sStmt2allMemRefsMap[stmt].insert(m);
02810 
02811          break;
02812     }
02813 
02814     case OPR_MIN:
02815     case OPR_MAX:
02816     case OPR_IF:
02817     case OPR_LAND:
02818     case OPR_LIOR:
02819     case OPR_LNOT:
02820     case OPR_MPY:
02821     case OPR_ADD:
02822     case OPR_SUB:
02823     case OPR_DIV:
02824     case OPR_LE:
02825     case OPR_LT:
02826     case OPR_GE:
02827     case OPR_GT:
02828     case OPR_EQ:
02829     case OPR_NE:
02830     case OPR_TRUNC:
02831     case OPR_RECIP:
02832     case OPR_PAREN:
02833     case OPR_NEG:
02834     case OPR_CVT:
02835     case OPR_SRCTRIPLET:
02836     case OPR_SWITCH:
02837     case OPR_COMPLEX:
02838     {
02839        if(opr == OPR_IF) { 
02840           mStmt2allExprsMap[stmt].insert((OA::irhandle_t)WN_kid0(wn));
02841        }
02842        for (INT kidno=0; kidno<=WN_kid_count(wn)-1; kidno++) {
02843          findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid(wn,kidno),lvl);
02844        }
02845        break;
02846     }
02847     case OPR_DO_LOOP:    
02848     {
02849        findAllMemRefsAndMapToMemRefExprs(stmt, WN_kid(wn,2),lvl);
02850 
02851        // Store conditional expression 
02852        WN* condition = WN_kid(wn,2);
02853        mStmt2allExprsMap[stmt].insert((OA::irhandle_t)condition);
02854 
02855        break;
02856     }
02857     case OPR_BLOCK:
02858     case OPR_INTCONST:
02859     case OPR_CONST:
02860     case OPR_GOTO:
02861     case OPR_CASEGOTO:
02862     case OPR_LABEL:
02863     {
02864         break;
02865     }
02866     // General recursive case
02867     default:
02868     {
02869       // Special case: examine only condition of control flow statements
02870       if (OPERATOR_is_scf(opr) || OPERATOR_is_non_scf(opr)) {
02871 
02872           findAllMemRefsAndMapToMemRefExprs(stmt,WN_kid(wn,0),lvl);
02873           // General case: recur on parameters (kids 0 ... n-1)
02874       }
02875 
02876       // some asserts to catch cases I don't expect to land here
02877       assert(!OPERATOR_is_store(opr));
02878       assert(!OPERATOR_is_load(opr));
02879       break;
02880     }
02881   }
02882 
02883 }
02884 
02885 
02886 
02887 
02888 ST* Open64IRInterface::findBaseSymbol(WN* wn)
02889 {
02890   ST* retval = NULL;
02891   OPERATOR opr = WN_operator(wn);
02892   switch (opr) {
02893     case OPR_ARRAYEXP:
02894     case OPR_ARRAY:
02895     case OPR_ARRSECTION:
02896     case OPR_PARM:
02897     case OPR_ILOAD:
02898     case OPR_MLOAD:
02899     case OPR_MIN:
02900     case OPR_MAX:
02901     case OPR_IF:
02902     case OPR_LAND:
02903     case OPR_LIOR:
02904     case OPR_LNOT:
02905     case OPR_MPY:
02906     case OPR_ADD:
02907     case OPR_SUB:
02908     case OPR_DIV:
02909     case OPR_LE:
02910     case OPR_LT:
02911     case OPR_GE:
02912     case OPR_GT:
02913     case OPR_EQ:
02914     case OPR_NE:
02915     case OPR_TRUNC:
02916     case OPR_RECIP:
02917     case OPR_PAREN:
02918     case OPR_NEG:
02919     case OPR_BLOCK:
02920     case OPR_STRCTFLD:
02921     case OPR_CALL:
02922     case OPR_INTRINSIC_OP:
02923     case OPR_CVT:    
02924     case OPR_COMPLEX:    
02925     case OPR_ARRAY_CONSTRUCT:    
02926         retval = findBaseSymbol(WN_kid0(wn));
02927         break;
02928     case OPR_STID:
02929     case OPR_PSTID:
02930     case OPR_LDID:
02931     case OPR_LDBITS:
02932     case OPR_LDA:
02933     case OPR_LDMA:
02934     case OPR_CONST:
02935         retval = WN_st(wn);
02936         break;
02937     case OPR_INTCONST:
02938         break;
02939     case OPR_INTRINSIC_CALL:
02940       {
02941         if (WN_kid_count(wn)>1) { 
02942           DBGMSG_PUB(0, "Warning: ignoring call to %s in non-hoisted expression",WN_intrinsic_name(WN_intrinsic(wn)));
02943         }
02944         else if( WN_kid_count(wn)==1) { 
02945           retval = findBaseSymbol(WN_kid0(wn));
02946         }
02947         break;
02948       }
02949     default: 
02950         assert(0);  // don't expect to get here
02951   }
02952   return retval;
02953 }
02954 
02955 
02956 
02957 
02958 
02959 void Open64IRInterface::createAndMapDerefs(OA::StmtHandle stmt, WN* wn, WN* subMemRef)
02960 {
02961     using namespace OA;
02962     // get all MREs for subMemRef
02963     set<OA_ptr<MemRefExpr> >::iterator mreIter;
02964     for (mreIter=sMemref2mreSetMap[MemRefHandle((irhandle_t)subMemRef)].begin();         mreIter!=sMemref2mreSetMap[MemRefHandle((irhandle_t)subMemRef)].end();
02965          mreIter++ )
02966     {
02967         // get the mre
02968         OA_ptr<MemRefExpr> submre = *mreIter;
02969 
02970         // create deref mre
02971         int numDerefs = 1;
02972         OA::OA_ptr<OA::Deref> deref_mre;
02973         OA::OA_ptr<OA::MemRefExpr> nullMRE;
02974         deref_mre = new OA::Deref(
02975                                    OA::MemRefExpr::USE,
02976                                    nullMRE,
02977                                    numDerefs);
02978 
02979         // compose with Deref
02980         submre = deref_mre->composeWith(submre);
02981 
02982         // Store mre
02983         sMemref2mreSetMap[MemRefHandle((irhandle_t)wn)].insert(submre);
02984         sStmt2allMemRefsMap[stmt].insert(MemRefHandle((irhandle_t)wn));
02985     }
02986 }
02987 
02988 
02989 
02990 OA::OA_ptr<OA::MemRefExpr>
02991            Open64IRInterface::convertSymToMemRefExpr(OA::SymHandle sym)
02992 {
02993     OA::OA_ptr<OA::MemRefExpr> mre;
02994     bool isAddrOf = false;
02995     bool fullAccuracy = false;
02996     OA::MemRefExpr::MemRefType hty;
02997     hty = OA::MemRefExpr::USE;
02998 
02999     if (isRefParam(sym)) {
03000 
03001         mre = new OA::NamedRef(hty, sym);
03002         mre = new OA::Deref(hty, mre, 1);
03003 
03004     } else {
03005 
03006         mre = new OA::NamedRef(hty, sym);
03007 
03008     }
03009 
03010     return mre;
03011 }
03012 
03013 
03014 
03015 void Open64IRInterface::createAndMapNamedRef(OA::StmtHandle stmt, WN* wn, ST* st, OA::MemRefExpr::MemRefType hty) {
03016     using namespace OA;
03017     OA::OA_ptr<OA::MemRefExpr> mre;
03018 
03019     // do not want to create MemRefExpr if for Constants for Literals
03020     assert(!ST_is_constant (st));
03021 
03022     // get symbol handle, need to use representative if a global or
03023     // module var.  Going to use first sym in set as representative.
03024     SymHandle sym = SymHandle((irhandle_t)st);
03025 
03026     // New Moficiations to OpenAD. 07/11/10
03027     // Different procedures get Same SymHandles for the module variable
03028     // and different SymHandles for Common Block Variable
03029 
03030     if (Stab_Is_Based_At_Common_Block(st)
03031         ||
03032         (ST_is_in_module(st) && ST_sym_class(st)==CLASS_VAR)) {
03033         std::set<SymHandle>::iterator setIter;
03034         fully_qualified_name fqn = sSymToFQNMap[sym];
03035         OA::ProcHandle pContext = getCurrentProcContext();
03036         // store the local incarnation of the global sym for this procedure
03037         sFQNToProcToLocalSymMap[fqn][pContext] = sym;
03038         // use the first symhandle in the set as a representative
03039         setIter = sGlobalVarMap[fqn].begin();
03040         sym = *setIter;
03041     }
03042 
03043     mre = new NamedRef(hty, sym);
03044     sMemref2mreSetMap[MemRefHandle((irhandle_t)wn)].insert(mre);
03045     sStmt2allMemRefsMap[stmt].insert(MemRefHandle((irhandle_t)wn));
03046 }
03047 
03048 
03049 OA::OA_ptr<OA::Alias::ParamBindPtrAssignIterator>
03050 Open64IRInterface::getParamBindPtrAssignIterator(OA::CallHandle call)
03051 {   
03052     // FIXME: for now just assuming Fortran
03053     bool isFortran = true;
03054 
03055     // Setup context for caller
03056     setCurrentProcToProcContext(call);
03057 
03058     OA::OA_ptr<Open64ParamBindPtrAssignIterator> retval;
03059     retval = new Open64ParamBindPtrAssignIterator;
03060 
03061     // start at 0 because that is how Open64 starts counting
03062     int count = 0;
03063     // iterate over all the parameters for this call site
03064     // and count off parameters
03065 
03066     OA::OA_ptr<OA::IRCallsiteParamIterator> paramIter = getCallsiteParams(call);
03067     for ( ; paramIter->isValid(); (*paramIter)++ ) {
03068         OA::ExprHandle param = paramIter->current();
03069 
03071         if(param == OA::ExprHandle(0)) {
03072             continue;
03073         }
03074         
03075         OA::OA_ptr<OA::ExprTree> eTreePtr = getExprTree(param);
03076         OA::EvalToMemRefVisitor evalVisitor;
03077         eTreePtr->acceptVisitor(evalVisitor);
03078        
03079         if ( evalVisitor.isMemRef() ) {
03080             
03081           OA::MemRefHandle memref = evalVisitor.getMemRef();
03082 
03083           // get the MREs for this memref
03084           OA::OA_ptr<OA::MemRefExprIterator> mreIter 
03085               = getMemRefExprIterator(memref);
03086           for ( ; mreIter->isValid(); (*mreIter)++ ) {
03087               OA::OA_ptr<OA::MemRefExpr> mre = mreIter->current();
03088 
03089               // if there is an address computation them we have a
03090               // pointer assignment happening at parameter bind time
03091               
03092               if(mre->isaRefOp()) {
03093                 OA::OA_ptr<OA::RefOp> refop = mre.convert<OA::RefOp>();
03094                 if(refop->isaAddressOf()) {
03095                    retval->insertParamBindPair(count,mre);
03096                 }
03097 
03098               // if it is a named ref to a reference param in
03099               // the caller then we also have a ParamBindPair
03100               } else if (mre->isaNamed()) {
03101                   OA::OA_ptr<OA::NamedRef> nref = mre.convert<OA::NamedRef>();
03102                   OA::SymHandle sym = nref->getSymHandle();
03103                   if (isRefParam(sym)) {
03104                       retval->insertParamBindPair(count,mre);
03105                   }
03106               }
03107           } 
03108           count++;
03109         } // iterate over actuals
03110     }
03111     return retval;
03112 }
03113 
03114 OA::SymHandle Open64IRInterface::getFormalSym(OA::ProcHandle proc, int formalID)
03115 {
03116     PU_Info* procPU = (PU_Info*)proc.hval();
03117     OA::SymHandle retval;
03118 
03119     PU_SetGlobalState(procPU);
03120   
03121     WN* wn_pu = PU_Info_tree_ptr(procPU);
03122     int numParamsProc = WN_num_formals(wn_pu);  
03123     if (formalID >= numParamsProc) {
03124         retval = OA::SymHandle(0);
03125     } else {
03126         WN* formalWN = WN_formal(wn_pu, formalID);
03127         if (!formalWN) {
03128             retval = OA::SymHandle(0);
03129         } else {
03130             ST* formalST = WN_st(formalWN);
03131             retval = (OA::irhandle_t)formalST;
03132         }
03133     }
03134 
03135     return retval;
03136 }
03137 
03141 OA::OA_ptr<OA::MemRefExpr> 
03142 Open64IRInterface::getCallMemRefExpr(OA::CallHandle h)
03143 { 
03144     // FIXME: this is not sufficient for function pointers
03145     OA::OA_ptr<OA::MemRefExpr> retval; 
03146     OA::SymHandle sym = getSymHandle(h);
03147     retval = new OA::NamedRef(OA::MemRefExpr::USE,sym);
03148     return retval; 
03149 }
03150 
03151 
03152 //-------------------------------------------------------------------------
03153 // ActivityIRInterface
03154 //-------------------------------------------------------------------------
03155   
03157 OA::OA_ptr<OA::MemRefExprIterator> 
03158 Open64IRInterface::getIndepMemRefExprIter(OA::ProcHandle h)
03159 {
03160   PU_Info* pu = (PU_Info*)h.hval();
03161   currentProc(h);
03162   OA::OA_ptr<OA::MemRefExpr> mre;
03163   
03164   // Get independent variables
03165   OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > indepList;
03166   indepList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
03167 
03168   WN* pragmaBlk = WN_func_pragmas(PU_Info_tree_ptr(pu));
03169   for (WN* wn = WN_first(pragmaBlk); wn != NULL; wn = WN_next(wn)) {
03170 
03171     if (WN_operator(wn) != OPR_PRAGMA) {
03172       continue; 
03173     }
03174     
03175     WN_PRAGMA_ID prag = (WN_PRAGMA_ID)WN_pragma(wn);
03176 
03177     if (prag == WN_PRAGMA_OPENAD_INDEPENDENT) {
03178       ST* st = WN_st(wn);
03179       OA::SymHandle sym = OA::SymHandle((OA::irhandle_t)st);
03181       OA::OA_ptr<OA::MemRefExpr> mre;
03182       mre = convertSymToMemRefExpr(sym);
03183       indepList->push_back(mre);
03184     }
03185   }
03186   
03187   OA::OA_ptr<OA::MemRefExprIterator> indepIter;
03188   indepIter = new Open64MemRefExprIterator(indepList);
03189   return indepIter;
03190 
03191 }
03192   
03194 OA::OA_ptr<OA::MemRefExprIterator> 
03195 Open64IRInterface::getDepMemRefExprIter(OA::ProcHandle h)
03196 {
03197 
03198   PU_Info* pu = (PU_Info*)h.hval();
03199   currentProc(h);
03200   OA::OA_ptr<OA::MemRefExpr> mre;
03201 
03202   // Get dependent variables
03203   OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > depList;
03204   depList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
03205   
03206   WN* pragmaBlk = WN_func_pragmas(PU_Info_tree_ptr(pu));
03207   for (WN* wn = WN_first(pragmaBlk); wn != NULL; wn = WN_next(wn)) {
03208     if (WN_operator(wn) != OPR_PRAGMA) {
03209       continue; 
03210     }
03211     
03212     WN_PRAGMA_ID prag = (WN_PRAGMA_ID)WN_pragma(wn);
03213     
03214     if (prag == WN_PRAGMA_OPENAD_DEPENDENT) {
03215       ST* st = WN_st(wn);
03216       OA::SymHandle sym = OA::SymHandle((OA::irhandle_t)st);
03218       OA::OA_ptr<OA::MemRefExpr> mre;
03219       mre = convertSymToMemRefExpr(sym);
03220       depList->push_back(mre);
03221     }
03222   }
03223 
03224   OA::OA_ptr<OA::MemRefExprIterator> depIter;
03225   depIter = new Open64MemRefExprIterator(depList);
03226   return depIter;
03227 }
03228  
03229 int Open64IRInterface::getSizeInBytes(OA::SymHandle h)
03230 {
03231     setCurrentProcToProcContext(h);
03232     return TY_size(ST_type((ST*)h.hval()));
03233 }
03234 
03235 //---------------------------------------------------------------------------
03236 // ReachDefsIRInterface
03237 //---------------------------------------------------------------------------
03238 
03239 OA::OA_ptr<OA::IRSymIterator>
03240 Open64IRInterface::getRefSymIterator(OA::ProcHandle h)
03241 {
03242   PU_Info* pu = (PU_Info*)h.hval();
03243   OA::OA_ptr<OA::IRSymIterator> retval;
03244   retval = new Open64IRSymIterator(pu);
03245   return retval;
03246 }
03247 
03251 OA::OA_ptr<OA::MemRefHandleIterator>
03252 Open64IRInterface::getDefMemRefs(OA::StmtHandle stmt)
03253 {
03254   setCurrentProcToProcContext(stmt);
03255   OA::OA_ptr<std::list<OA::MemRefHandle> > retList;
03256   retList = new std::list<OA::MemRefHandle>;
03257   
03258   // get iterator over memory references for this statement
03259   // and only put DEFs in the list
03260   OA::OA_ptr<OA::MemRefHandleIterator> mIter = getMemRefIterator(stmt);
03261   for ( ; mIter->isValid(); (*mIter)++ ) {
03262     OA::MemRefHandle memref = mIter->current();
03263 
03264     // loop over memory reference expressions for this memref handle
03265     set<OA::OA_ptr<OA::MemRefExpr> >::iterator mreIter;
03266     for (mreIter = sMemref2mreSetMap[memref].begin();
03267          mreIter != sMemref2mreSetMap[memref].end(); mreIter++ ) 
03268     {
03269         OA::OA_ptr<OA::MemRefExpr> mre = *mreIter;
03270 
03275 
03276         if(mre->isaRefOp()) {
03277            OA::OA_ptr<OA::RefOp> refop = mre.convert<OA::RefOp>();
03278            if(refop->isaAddressOf()) {
03279               continue;
03280            }
03281         }
03282 
03283         if (mre->isDef()) {
03284           retList->push_back(memref);
03285           break;
03286         }
03287     }
03288   }
03289 
03290   OA::OA_ptr<Open64MemRefHandleIterator> retval;
03291   retval = new Open64MemRefHandleIterator(retList);
03292   return retval;
03293 }
03294 
03298 OA::OA_ptr<OA::MemRefHandleIterator>
03299 Open64IRInterface::getAllMemRefs(OA::StmtHandle stmt)
03300 {
03301   setCurrentProcToProcContext(stmt);
03302   OA::OA_ptr<std::list<OA::MemRefHandle> > retList; 
03303   retList = new std::list<OA::MemRefHandle>;
03304   
03305   // get iterator over memory references for this statement
03306   // and for now just copy the list
03307   OA::OA_ptr<OA::MemRefHandleIterator> mIter = getMemRefIterator(stmt);
03308   for ( ; mIter->isValid(); (*mIter)++ ) {
03309     OA::MemRefHandle memref = mIter->current();
03310     retList->push_back(memref);
03311   }
03312 
03313   OA::OA_ptr<Open64MemRefHandleIterator> retval;
03314   retval = new Open64MemRefHandleIterator(retList);
03315   return retval;
03316 }
03317   
03318 //---------------------------------------------------------------------------
03319 // UDDUChainsIRInterface
03320 //---------------------------------------------------------------------------
03321 
03325 OA::OA_ptr<OA::MemRefHandleIterator>
03326 Open64IRInterface::getUseMemRefs(OA::StmtHandle stmt)
03327 {
03328   setCurrentProcToProcContext(stmt);
03329   OA::OA_ptr<std::list<OA::MemRefHandle> > retList; 
03330   retList = new std::list<OA::MemRefHandle>;
03331 
03332   // get iterator over memory references for this statement
03333   // and only put USES in the list
03334   OA::OA_ptr<OA::MemRefHandleIterator> mIter = getAllMemRefs(stmt);
03335   for ( ; mIter->isValid(); (*mIter)++ ) {
03336     OA::MemRefHandle memref = mIter->current();
03337     
03338     // loop over memory reference expressions for this memref handle
03339     set<OA::OA_ptr<OA::MemRefExpr> >::iterator mreIter;
03340     for (mreIter = sMemref2mreSetMap[memref].begin();
03341          mreIter != sMemref2mreSetMap[memref].end(); mreIter++ ) 
03342     {
03343         OA::OA_ptr<OA::MemRefExpr> mre = *mreIter;
03344 
03349 
03350         if(mre->isaRefOp()) {
03351            OA::OA_ptr<OA::RefOp> refop = mre.convert<OA::RefOp>();
03352            if(refop->isaAddressOf()) {
03353               continue;
03354            }
03355         }
03356           
03357         if (mre->isUse()) {
03358           retList->push_back(memref);
03359           break;
03360         } 
03361     }
03362   }
03363 
03364   OA::OA_ptr<Open64MemRefHandleIterator> retval;
03365   retval = new Open64MemRefHandleIterator(retList);
03366   return retval;
03367 }
03368 
03369 
03370 //---------------------------------------------------------------------------
03371 // ReachConstsIRInterface (and Open64ConstVal)
03372 //---------------------------------------------------------------------------
03373 
03374 OA::OA_ptr<OA::ConstValBasicInterface> 
03375 Open64ConstVal::eval(OPERATOR opr, 
03376                      const OA::OA_ptr<OA::ConstValBasicInterface> op2) const
03377 {
03378   OA::OA_ptr<OA::ConstValBasicInterface> retval;  retval = NULL;
03379 
03380   // Cannot eval without a specific type; return an opaque const object
03381   // return new Open64ConstVal();
03382 
03383   // returning NULL  -  NULL is recognizable, 
03384   //                    whereas new Open64ConstVal() is not
03385 
03386   return retval;
03387 }
03388 
03389 OA::OA_ptr<OA::ConstValBasicInterface> 
03390 Open64IntegerConstVal::eval(OPERATOR opr, 
03391     const OA::OA_ptr<OA::ConstValBasicInterface> op2_) const
03392 {
03393   int val = 0;
03394   OA::OA_ptr<OA::ConstValBasicInterface> retval;
03395 
03396   // if opr is a unary op, op2_ will be NULL
03397   if (op2_.ptrEqual(NULL)) {
03398 
03399     // right now, only works for opr==OPR_PARM
03400     switch (opr) {
03401     case OPR_PARM: 
03402       /*
03403         val = this->getIntegerVal();
03404         retval = new Open64IntegerConstVal(val);
03405       */
03406       // shouldn't get here anymore
03407 
03408       std::cout << "In OPR_PARM of eval in Open64IRInterface.cpp (error)\n";
03409       std::cout.flush();
03410       exit(555);
03411       
03412       break;
03413     default:
03414       retval = NULL;
03415     }
03416     return retval;
03417   }
03418 
03419   OA::OA_ptr<const Open64ConstVal> op2 = op2_.convert<const Open64ConstVal>();
03420   assert(op2->isaInteger());
03421   
03422   switch (opr) {
03423   case OPR_ADD:
03424     val = this->getIntegerVal() + op2->getIntegerVal();
03425     retval = new Open64IntegerConstVal(val);
03426     break;
03427   case OPR_SUB:
03428     val = this->getIntegerVal() - op2->getIntegerVal();
03429     retval = new Open64IntegerConstVal(val);
03430     break;
03431   case OPR_MPY:
03432     val = this->getIntegerVal() * op2->getIntegerVal();
03433     retval = new Open64IntegerConstVal(val);
03434     break;
03435   case OPR_DIV:
03436     val = this->getIntegerVal() / op2->getIntegerVal();
03437     retval = new Open64IntegerConstVal(val);
03438     break;
03439     
03440   default:
03441     //    return new Open64ConstVal();
03442 
03443     // NULL is recognizable, new Open64ConstVal() is not
03444     retval = NULL;
03445   }
03446   
03447   return retval;
03448 }
03449 
03450 
03451 
03452 OA::OA_ptr<OA::ExprHandleIterator>
03453 Open64IRInterface::getExprHandleIterator(OA::StmtHandle h)
03454 {
03455 
03456   OA::OA_ptr<OA::ExprHandleIterator> retval;
03457   retval = new Open64IRExprHandleIterator(h);
03458   return retval;
03459 
03460 }
03461 
03462 
03463 OA::OA_ptr<OA::AssignPairIterator> 
03464 Open64IRInterface::getAssignPairIterator(OA::StmtHandle stmt)
03465 { 
03466   if(sStmt2allMemRefsMap[stmt].empty()) {
03467      Open64IRInterface::findAllMemRefsAndMapToMemRefExprs(stmt,(WN*)stmt.hval(),0);
03468   }
03469 
03470   OA::OA_ptr<AssignPairList> assignPairList;
03471   assignPairList = new AssignPairList;
03472 
03473   std::set<std::pair<OA::MemRefHandle,
03474                      OA::ExprHandle> >::iterator pairIter;
03475 
03476   for (pairIter = mStmtToAssignPairs[stmt].begin();
03477        pairIter!= mStmtToAssignPairs[stmt].end();
03478        pairIter++)
03479   {
03480        OA::MemRefHandle lhsHandle = pairIter->first;
03481        OA::ExprHandle rhsHandle = pairIter->second;
03482        assignPairList->push_back(AssignPair(lhsHandle, rhsHandle));
03483   }
03484 
03485   OA::OA_ptr<OA::AssignPairIterator> retval;
03486   retval = new Open64AssignPairIterator(assignPairList);
03487   return retval;
03488 }
03489 
03490 
03491 void
03492 Open64PtrAssignPairStmtIterator::reset()
03493 {
03494   mIter = mMemRefList.begin();
03495   mEnd = mMemRefList.end();
03496   mBegin = mMemRefList.begin();
03497 }
03498 
03499 
03500 // Create iterator consisting of lhs/rhs pairs from pointer
03501 // assignments in stmt.
03502 void Open64PtrAssignPairStmtIterator::create(OA::StmtHandle stmt)
03503 {
03504   // loop through the pairs we found in initMemRefsAndPtrAssigns
03505   std::set<std::pair<OA::OA_ptr<OA::MemRefExpr>,
03506                      OA::OA_ptr<OA::MemRefExpr> > >::iterator pairIter;
03507   for (pairIter=mStmtToPtrPairs[stmt].begin();
03508        pairIter!=mStmtToPtrPairs[stmt].end();
03509        pairIter++)
03510   {
03511       mMemRefList.push_back(*pairIter);
03512   }
03513 }
03514 
03515 
03516 OA::OA_ptr<OA::IRStmtIterator>
03517 Open64IRInterface::getPtrAsgnIterator(OA::ProcHandle proc)
03518 {
03519   OA::OA_ptr<OA::IRStmtIterator> retval;
03520   retval = new Open64IRPtrAsgnIterator(proc);
03521   return retval;
03522 }
03523 
03526 OA::OA_ptr<OA::Alias::PtrAssignPairStmtIterator>
03527 Open64IRInterface::getPtrAssignStmtPairIterator(OA::StmtHandle stmt)
03528 {
03529   OA::OA_ptr<OA::Alias::PtrAssignPairStmtIterator> retval;
03530   retval = new Open64PtrAssignPairStmtIterator(stmt);
03531   return retval;
03532 }
03533 
03534 
03535 
03536 OA::OA_ptr<OA::ConstValBasicInterface> 
03537 Open64IRInterface::evalOp(OA::OpHandle op, 
03538                           OA::OA_ptr<OA::ConstValBasicInterface> operand1, 
03539                           OA::OA_ptr<OA::ConstValBasicInterface> operand2)
03540 { 
03541   WN* wn = (WN*)op.hval();
03542   OA::OA_ptr<OA::ConstValBasicInterface> retval;
03543   if (operand1.ptrEqual(NULL)) {retval = NULL; return retval;}
03544   const OA::OA_ptr<Open64ConstVal> op1 = operand1.convert<Open64ConstVal>();  
03545   return op1->eval(WN_operator(wn), operand2);
03546 }
03547 
03548 OA::OA_ptr<OA::ConstValBasicInterface> 
03549 Open64IRInterface::getConstValBasic(OA::ConstSymHandle c) 
03550 { 
03551   setCurrentProcToProcContext(c);
03552   ST* st = (ST*)c.hval();  
03553   return getConstValBasicFromST(st);
03554 }
03555 
03556 OA::OA_ptr<OA::ConstValBasicInterface> 
03557 Open64IRInterface::getConstValBasic(OA::ConstValHandle c)
03558 { 
03559   setCurrentProcToProcContext(c);
03560   OA::OA_ptr<OA::ConstValBasicInterface> cvb; cvb = NULL;
03561   
03562   WN* wn = (WN*)c.hval();
03563   if (!wn) { return cvb; }
03564   
03565   OPERATOR opr = WN_operator(wn);
03566   if (opr == OPR_CONST) {
03567     ST* st = WN_st(wn);
03568     cvb = getConstValBasicFromST(st);
03569   }
03570   else if (opr == OPR_INTCONST) {
03571     INT64 val = WN_const_val(wn);
03572     if (val < INT_MIN || val > INT_MAX) {
03573     // cvb = new Open64ConstVal(); // no current representation for this
03574       cvb = NULL;
03575     } else {
03576       cvb = new Open64IntegerConstVal((int)val);
03577     }
03578   }
03579   else {
03580     //    std::cout << static_cast<int>(opr) << std::endl;
03581     //    std::cout.flush();
03582     assert(0); // throw an assertion
03583   }
03584   
03585   return cvb;
03586 }
03587 
03589 // should be removed after testing
03590 int
03591 Open64IRInterface::returnOpEnumValInt(OA::OpHandle op)
03592 { 
03593   setCurrentProcToProcContext(op);
03594   WN* wn = (WN*)op.hval();
03595   OPERATOR opr = WN_operator(wn); 
03596   return (int)opr;
03597 }
03598 
03599 
03601 OA::StmtHandle 
03602 Open64IRInterface::getStmtFromMemRef(OA::MemRefHandle h) {
03603 
03604   // if haven't seen this MemRefHandle yet will assert in this call
03605   setCurrentProcToProcContext(h);
03606 
03607   return sMemRef2StmtMap[h];
03608 }
03609 
03611 // given a ConstValBasicInterface, print out value if any
03612 std::string 
03613 Open64IRInterface::toString(OA::OA_ptr<OA::ConstValBasicInterface> cvPtr)
03614 {
03615   std::ostringstream oss;
03616   if (cvPtr.ptrEqual(NULL)) {
03617     oss << "no value, null ConstValBasicInterface*";
03618   } else {
03619     const OA::OA_ptr<Open64ConstVal> op1 = cvPtr.convert<Open64ConstVal>();
03620     if (op1->isaInteger()) {
03621       oss << op1->getIntegerVal();
03622     } else {
03623       oss << "not an integer value";
03624     }
03625   }
03626   return oss.str();
03627   
03628 }
03629 
03631 // Given an unsigned int, return a ConstValBAsicInterface for it
03632 OA::OA_ptr<OA::ConstValBasicInterface> 
03633 Open64IRInterface::getConstValBasic (unsigned int val) {
03634   OA::OA_ptr<OA::ConstValBasicInterface>  retval;
03635   retval = new Open64IntegerConstVal((int)val);
03636   return retval;
03637 }
03638 
03639 //---------------------------------------------------------------------------
03640 // LinearityIRInterface.hpp
03641 //---------------------------------------------------------------------------
03642 
03644 OA::Linearity::LinOpType
03645 Open64IRInterface::getLinearityOpType(OA::OpHandle op)
03646 { 
03647   setCurrentProcToProcContext(op);
03648 
03649   OA::Linearity::LinOpType opt;
03650   
03651   
03652   WN* wn = (WN*)op.hval();
03653   OPERATOR opr = WN_operator(wn); 
03654 
03655 switch (opr) {
03656   // Unary expression operations.
03657   case OPR_NEG:
03658       opt = OA::Linearity::OPR_LINEAR;
03659       break;
03660       
03661   // Binary expression operations.
03662   case OPR_ADD:
03663   case OPR_SUB:
03664       opt = OA::Linearity::OPR_ADDSUB;
03665       break;
03666   case OPR_MPY:
03667   case OPR_DIV:
03668       opt = OA::Linearity::OPR_MPYDIV;
03669       break;
03670   case OPR_CALL:
03671 //    os << createCharStarForST(WN_st (wn)) << "(";
03672     opt = OA::Linearity::OPR_NONLINEAR;
03673     break;
03674   case OPR_INTRINSIC_CALL:
03675   case OPR_INTRINSIC_OP:
03676 //    os << INTRINSIC_name ((INTRINSIC) WN_intrinsic (wn)) << "(";
03677     opt = OA::Linearity::OPR_NONLINEAR;
03678     break;
03679   default:
03680     opt = OA::Linearity::OPR_NONLINEAR;
03681     break;
03682   }
03683 
03684   
03685   return opt;
03686   //return (int)opr;
03687 }
03688 
03689 //---------------------------------------------------------------------------
03690 // InterSideEffectIRInterface.hpp
03691 //---------------------------------------------------------------------------
03692 
03697 OA::OA_ptr<OA::SideEffect::SideEffectStandard> 
03698 Open64IRInterface::getSideEffect(OA::ProcHandle callerProc, 
03699                                  OA::SymHandle calleeSym)
03700 {
03701   setCurrentProcToProcContext(calleeSym);
03702   // create a new (waiting to be filled) SideEffectStandard as member
03703   OA::OA_ptr<OA::SideEffect::SideEffectStandard> retSideEffect;
03704   retSideEffect= new OA::SideEffect::SideEffectStandard();
03705  
03706 
03707   currentProc(callerProc);
03708   
03709   // see if symbol matches one of the procedures we want to have
03710   // optimistic results for
03711   std::set<std::string> noSideEffectProcs;
03712   sSymToVarStringMap[OA::SymHandle(0)] = "<no-symbol>";
03713   noSideEffectProcs.insert("<no-symbol>");
03714   noSideEffectProcs.insert("_END");
03715   noSideEffectProcs.insert("ABS");
03716   noSideEffectProcs.insert("LOG");
03717   noSideEffectProcs.insert("FLOAT");
03718   noSideEffectProcs.insert("SQRT");
03719   // hacks for NPB
03720   noSideEffectProcs.insert("randlc_");
03721   noSideEffectProcs.insert("timer_clear_");
03722   noSideEffectProcs.insert("timer_stop_");
03723   noSideEffectProcs.insert("timer_start_");
03724   noSideEffectProcs.insert("timer_read_");
03725   noSideEffectProcs.insert("print_results_");
03726   noSideEffectProcs.insert("print_timers_");
03727   noSideEffectProcs.insert("ctimer_");
03728   noSideEffectProcs.insert("integr_");
03729   // Other Intrinsics
03730   noSideEffectProcs.insert("DINT");
03731   noSideEffectProcs.insert("DSQRT");
03732   noSideEffectProcs.insert("DBLE");
03733   noSideEffectProcs.insert("DABS");
03734   noSideEffectProcs.insert("DFLOAT");
03735   noSideEffectProcs.insert("EXP");
03736   noSideEffectProcs.insert("DEXP");
03737   noSideEffectProcs.insert("vranlc_");
03738   noSideEffectProcs.insert("COS");
03739   noSideEffectProcs.insert("SIN");
03740   noSideEffectProcs.insert("DIMAG");
03741   noSideEffectProcs.insert("DCONJG");
03742   noSideEffectProcs.insert("DLOG");
03743   noSideEffectProcs.insert("REAL");
03744     
03745   if (noSideEffectProcs.find(sSymToVarStringMap[calleeSym])
03746       != noSideEffectProcs.end() )
03747   {
03748     // empty out all the sets
03749     retSideEffect->emptyLMOD();
03750     retSideEffect->emptyMOD();
03751     retSideEffect->emptyLDEF();
03752     retSideEffect->emptyDEF();
03753     retSideEffect->emptyLUSE();
03754     retSideEffect->emptyUSE();
03755     retSideEffect->emptyLREF();
03756     retSideEffect->emptyREF();
03757 
03758   }
03759   
03760   return retSideEffect;
03761 
03762 }
03763 
03764 //---------------------------------------------------------------------------
03765 // ExprTreeIRShortCircuit
03766 //---------------------------------------------------------------------------
03767 
03770 OA::OA_ptr<OA::ExprTree> 
03771 Open64IRInterface::getExprTree(OA::ExprHandle h) 
03772 { 
03773   setCurrentProcToProcContext(h);
03774 
03775   WN* wn = (WN*)h.hval();
03776   return createExprTree(wn);
03777 }
03778 
03780 bool Open64IRInterface::isParam(OA::SymHandle anOASymbolHandle){ 
03781   ST* anOpen64Symbol_p = (ST*)anOASymbolHandle.hval();
03782   return (((ST_sclass(anOpen64Symbol_p)==SCLASS_FORMAL) 
03783            || 
03784            (ST_sclass(anOpen64Symbol_p)==SCLASS_FORMAL_REF))
03785           &&
03786           (ST_level(anOpen64Symbol_p) == CURRENT_SYMTAB)); 
03787   // BK:  added the &&(CURRENT_SYMTAB) to distinguish between parameters
03788   //      in a global/enclosing subroutine versus a local parameters
03789   //      now:  answers false for the former, and still true for the latter
03790 } 
03791 
03792 //---------------------------------------------------------------------------
03793 // LocationIRShortCircuit
03794 //---------------------------------------------------------------------------
03795 
03803 OA::OA_ptr<OA::Location> 
03804 Open64IRInterface::getLocation(OA::ProcHandle p, OA::SymHandle s)
03805 {
03806     OA::OA_ptr<OA::NamedLoc> retval;
03807     if (s==OA::SymHandle(0)) {
03808         retval = NULL;
03809         return retval;
03810     }
03811 
03812     if (debug) {
03813       std::cout << std::endl << "getLocation: mIR->toString(p) = " << toString(p) 
03814               << ", <hval=" << p.hval() << std::endl;
03815       std::cout << "mIR->toString(s) = " << toString(s) 
03816               << ", <hval=" << s.hval() << std::endl;
03817     }
03818 
03819     // save off old context 
03820     OA::ProcHandle currContext = getCurrentProcContext();
03821 
03822     // change to context for the sym so can determine if it is global
03823     setCurrentProcToProcContext(s);
03824 
03825     // if this symbol is global then it is a representative for all the 
03826     // symbols in each different procedure for the same global
03827     // need to get symbol specific to this procedure
03828     // In the new Open64 revision, we get Same SymHandle for
03829     // the module variables used in different procedures Therefore
03830     // it is not needed to give special treatment to the module
03831     // variables - except for cases where the S/R in question is 
03832     // inside of the module that defines the variable.
03833     // we get different SymHandles for the Common Block variables
03834     // used in different procedures.
03835     ST* st = (ST*)s.hval();
03836     if (Stab_Is_Based_At_Common_Block(st)
03837         ||
03838         (ST_is_in_module(st) && ST_sym_class(st)==CLASS_VAR)) {
03839         fully_qualified_name fqn = sSymToFQNMap[s];
03840         s = sFQNToProcToLocalSymMap[fqn][p];
03841         // need context for this procedure now
03842         setCurrentProcContext(p);
03843     }
03844 
03845  
03846     bool isLocal, isUnique;
03847     bool hasNestedProc = (PU_Info_child(Current_PU_Info) != NULL);
03848 
03849     // check that SymHandle isn't null
03850     if (s!=OA::SymHandle(0)) {
03851       // make sure the symbol is visible within procedure
03852       if (sProcToSymRefSetMap[p].find(s)==sProcToSymRefSetMap[p].end()) {
03853         retval = NULL;
03854       } else {
03855 
03856         isLocal = (!hasNestedProc) && (ST_level((ST*)s.hval()) == CURRENT_SYMTAB);
03857         isUnique = isLocal;
03858 
03859         retval = new OA::NamedLoc(s, isLocal);
03860 
03861         // if it is a common block variable then need to make sure the same var
03862         // name within the same common block indicates the other symbol handles
03863         // for that same var name and common block that fully overlap
03864         if (Stab_Is_Based_At_Common_Block(st)
03865             ||
03866             (ST_is_in_module(st) && ST_sym_class(st)==CLASS_VAR)) {
03867           fully_qualified_name fqn = sSymToFQNMap[s];
03868           if (sGlobalVarMap[fqn].empty()) {
03869             assert(0); // this symbol should have been put in there
03870                        // around line 3233
03871           }
03872 
03873           retval = new OA::NamedLoc(s, isLocal);
03874 
03875           // indicate that all of the symbols in sGlobalVarMap with the same
03876           // fully qualified name overlap with this location
03877           std::set<OA::SymHandle>::iterator setIter;
03878           for (setIter = sGlobalVarMap[fqn].begin();
03879                setIter!=sGlobalVarMap[fqn].end(); setIter++)
03880           {
03881               OA::SymHandle overlapSym = *setIter;
03882               //std::cout << " sym (hval=" <<  overlapSym.hval()
03883               //          << ") = " << toString(*setIter) << std::endl;
03884               retval->addFullOverlap(*setIter);
03885           }
03886         }
03887         
03888       }
03889 
03890     } else {
03891       retval = NULL;
03892     }
03893 
03894 //     if (!retval.ptrEqual(0) && st!=0 /* && strcmp(ST_name(st),"I01")==0 */) { 
03895 //       ST* pust = ST_ptr(PU_Info_proc_sym(Current_PU_Info));
03896 //       const char* puName = ST_name(pust);
03897 //       std::cout << "getLoc for " << ST_name(st) << " islocal:" << isLocal << " and " <<  (unsigned short)ST_level((ST*)s.hval()) << " ?= " <<  (unsigned short)CURRENT_SYMTAB << " in " << puName << " returning " << &(*retval) <<  std::endl; 
03898 //     }
03899 
03900     // reset the context
03901     setCurrentProcContext(currContext);
03902 
03903     return retval;
03904 }
03905 
03906 
03907 Open64IRInterface::FindUseMREVisitor::FindUseMREVisitor() {
03908      retList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
03909      do_not_add_mre = false;
03910 }
03911 
03912 Open64IRInterface::FindUseMREVisitor::~FindUseMREVisitor() { }
03913 
03914 OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > >
03915 Open64IRInterface::FindUseMREVisitor::getAllUseMREs() {
03916      return retList;
03917 }
03918 
03919 void Open64IRInterface::FindUseMREVisitor::visitNamedRef(OA::NamedRef& ref) {
03920      if ( (!do_not_add_mre) && (ref.getMRType() == OA::MemRefExpr::USE)) {
03921           OA::OA_ptr<OA::MemRefExpr> mre;
03922           mre = ref.clone();
03923           retList->push_back(mre);
03924      }
03925 }
03926  
03927 void Open64IRInterface::FindUseMREVisitor::visitUnnamedRef(OA::UnnamedRef& ref) {
03928      if ( (!do_not_add_mre) && (ref.getMRType() == OA::MemRefExpr::USE)) {
03929           OA::OA_ptr<OA::MemRefExpr> mre;
03930           mre = ref.clone();
03931           retList->push_back(mre);
03932      }
03933 }
03934  
03935 void Open64IRInterface::FindUseMREVisitor::visitUnknownRef(OA::UnknownRef& ref) {
03936      if ( (!do_not_add_mre) && (ref.getMRType() == OA::MemRefExpr::USE)) {
03937           OA::OA_ptr<OA::MemRefExpr> mre;
03938           mre = ref.clone();
03939           retList->push_back(mre);
03940      }
03941 }
03942 
03943 
03944 void Open64IRInterface::FindUseMREVisitor::visitDeref(OA::Deref& ref) {
03945      OA::OA_ptr<OA::MemRefExpr> mre;
03946      mre = ref.clone();
03947      if ( (!do_not_add_mre) && (ref.getMRType() == OA::MemRefExpr::USE)) {
03948           retList->push_back(mre);
03949      }
03950      do_not_add_mre = false;
03951      mre = ref.getMemRefExpr();
03952      if(!mre.ptrEqual(0)) {
03953          mre->acceptVisitor(*this);
03954      }
03955 }
03956 
03957 
03958 void Open64IRInterface::FindUseMREVisitor::visitAddressOf(OA::AddressOf& ref) {
03959      do_not_add_mre = true;
03960      OA::OA_ptr<OA::MemRefExpr> mre;
03961      mre = ref.getMemRefExpr();
03962      if (!mre.ptrEqual(0)) {
03963          mre->acceptVisitor(*this);
03964      }
03965 }
03966 
03967 void Open64IRInterface::FindUseMREVisitor::visitSubSetRef(OA::SubSetRef& ref) {
03968      OA::OA_ptr<OA::MemRefExpr> mre;
03969      mre = ref.clone();
03970      if ( !(do_not_add_mre) && (ref.getMRType() == OA::MemRefExpr::USE)) {
03971           retList->push_back(mre);
03972           do_not_add_mre = true;
03973      }
03974 
03975      if ( !(do_not_add_mre) && (ref.getMRType() == OA::MemRefExpr::DEF)) {
03976           do_not_add_mre = true;
03977      }
03978 
03979      mre = ref.getMemRefExpr();
03980      if(!mre.ptrEqual(0)) {
03981          mre->acceptVisitor(*this);
03982      }
03983 }
03984 
03985 
03987 OA::OA_ptr<OA::MemRefExprIterator>
03988 Open64IRInterface::getUseMREs(OA::StmtHandle stmt)
03989 {
03990    OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > retList;
03991    retList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
03992 
03993    OA::OA_ptr<OA::MemRefHandleIterator> mIter = getMemRefIterator(stmt);
03994 
03995    for ( ; mIter->isValid(); (*mIter)++ ) {
03996        OA::MemRefHandle memref = mIter->current();
03997 
03998        set<OA::OA_ptr<OA::MemRefExpr> >::iterator mreIter;
03999        for (mreIter = sMemref2mreSetMap[memref].begin();
04000             mreIter != sMemref2mreSetMap[memref].end(); mreIter++ )
04001             {
04002               OA::OA_ptr<OA::MemRefExpr> mre;
04003               mre = *mreIter;
04004 
04005               FindUseMREVisitor visitor;
04006               // visit the mre in the callee
04007               mre->acceptVisitor(visitor);
04008 
04009               OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > tmpList;
04010               tmpList = visitor.getAllUseMREs();
04011 
04012               std::list<OA::OA_ptr<OA::MemRefExpr> >::iterator mreIter;
04013 
04014               for(mreIter = tmpList->begin(); mreIter != tmpList->end(); ++mreIter) {
04015                   retList->push_back(*mreIter);
04016               }
04017        }
04018    }
04019 
04020    OA::OA_ptr<Open64MemRefExprIterator> retval;
04021    retval = new Open64MemRefExprIterator(retList);
04022    return retval;
04023 }
04024 
04025 
04027 OA::OA_ptr<OA::MemRefExprIterator>
04028 Open64IRInterface::getDefMREs(OA::StmtHandle stmt)
04029 {
04030     OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > retList;
04031     retList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
04032 
04033     OA::OA_ptr<OA::MemRefHandleIterator> mIter = getMemRefIterator(stmt);
04034     for ( ; mIter->isValid(); (*mIter)++ ) {
04035           OA::MemRefHandle memref = mIter->current();
04036 
04037           // loop over memory reference expressions for this memref handle
04038           set<OA::OA_ptr<OA::MemRefExpr> >::iterator mreIter;
04039           for (mreIter = sMemref2mreSetMap[memref].begin();
04040                mreIter != sMemref2mreSetMap[memref].end(); mreIter++ )
04041           {
04042                OA::OA_ptr<OA::MemRefExpr> mre = *mreIter;
04043 
04048 
04049                if(mre->isaRefOp()) {
04050                   OA::OA_ptr<OA::RefOp> refop = mre.convert<OA::RefOp>();
04051                   if(refop->isaAddressOf()) {
04052                      continue;
04053                   }
04054                }
04055 
04056                if (mre->isDef()) {
04057                    retList->push_back(mre);
04058                    break;
04059                }
04060           }
04061     }
04062     OA::OA_ptr<Open64MemRefExprIterator> retval;
04063     retval = new Open64MemRefExprIterator(retList);
04064     return retval;
04065 }
04066 
04067 
04069 OA::OA_ptr<OA::MemRefExprIterator>
04070 Open64IRInterface::getDiffUseMREs(OA::StmtHandle stmt)
04071 {
04072    OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > retList;
04073    retList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
04074 
04076    OA::OA_ptr<OA::MemRefHandleIterator> msetIter;
04077    msetIter = getAllMemRefs(stmt);
04078    for ( ; msetIter->isValid(); (*msetIter)++ ) {
04079         OA::MemRefHandle memref = msetIter->current();
04080 
04082         if(mStmtToIndexExprs[stmt].find(memref) != 
04083            mStmtToIndexExprs[stmt].end()) {
04084            continue;
04085         }
04086 
04088         OA::OA_ptr<OA::MemRefExprIterator> mreIter;
04089         mreIter = getMemRefExprIterator(memref); 
04090         for ( ; mreIter->isValid(); (*mreIter)++ )
04091         {
04092              OA::OA_ptr<OA::MemRefExpr> mre;
04093              mre = mreIter->current();
04094 
04095              if(mre->isaRefOp()) {
04096                 OA::OA_ptr<OA::RefOp> refop = mre.convert<OA::RefOp>();
04097                 if(refop->isaAddressOf()) {
04098                    continue;
04099                 }
04100              }
04101 
04102              if (mre->isUse()) {
04103                  retList->push_back(mre);
04104                  break;
04105              }
04106         }
04107    }
04108 
04109    OA::OA_ptr<Open64MemRefExprIterator> retval;
04110    retval = new Open64MemRefExprIterator(retList);
04111    return retval;
04112 }
04113 
04114 
04117 OA::OA_ptr<OA::MemRefExprIterator> 
04118 Open64IRInterface::getMemRefExprIterator(OA::MemRefHandle memref)
04119 {
04120     // will assert if haven't seen MemRefHandle yet
04121     setCurrentProcToProcContext(memref);
04122 
04123     OA::OA_ptr<std::list<OA::OA_ptr<OA::MemRefExpr> > > retList;
04124     retList = new std::list<OA::OA_ptr<OA::MemRefExpr> >;
04125 
04126     // iterate over set of MemRefExpr's associated with
04127     // the given MemRefHandle and put them in our list
04128     set<OA::OA_ptr<OA::MemRefExpr> >::iterator mreIter;
04129     
04130 
04131     for (mreIter = sMemref2mreSetMap[memref].begin();
04132          mreIter != sMemref2mreSetMap[memref].end(); mreIter++ ) 
04133     {
04134         retList->push_back(*mreIter);
04135     }
04136     
04137     OA::OA_ptr<Open64MemRefExprIterator> retval;
04138     retval = new Open64MemRefExprIterator(retList);
04139     return retval;
04140 }
04141 
04142 //-------------------------------------------------------------------------
04143 // ICFGIRInterface
04144 //-------------------------------------------------------------------------
04145 
04147 OA::ProcHandle Open64IRInterface::getProcHandle(OA::SymHandle sym)
04148 {
04149     return Open64IRInterface::sCallSymToProc[sym];
04150 }
04151   
04152 //---------------------------------------------------------------------------
04153 // XAIFIRInterface
04154 //---------------------------------------------------------------------------
04155 
04156 //---------------------------------------------------------------------------
04157 // Context state
04158 //---------------------------------------------------------------------------
04159 
04160 void
04161 Open64IRInterface::initContextState(PU_Info* pu_forest)
04162 {
04163   // if context hasn't already been set for this program then call
04164   // helper routine that sets up context
04165   if (Open64IRInterface::sContextInit==false) { 
04166     Open64IRProcIterator procIt(pu_forest);
04167     Open64IRInterface::initProcContext(pu_forest, procIt);
04168     Open64IRInterface::initCallSymToProcMap(procIt);
04169     Open64IRInterface::initProcToSymRefSetMap(procIt);
04170   }
04171 }
04172 
04173 
04174 //***************************************************************************
04175 // Helpers
04176 //***************************************************************************
04177 
04178 // NOTE: Could be relocated to a more general library
04179 
04180 // This function will Call itself recursively until it finds
04181 // MemRefHandle mapped to sMemref2mreSetMap.
04182 // For the case where ParamBinding returns &0:S2:0:anon_ptr
04183 // and we are looking for MemRefHandle = S2:0:anon_ptr mapped
04184 // to sMemref2mreSetMap. Please notice corresponding changes in
04185 // createExprTree in the switch option : OPERATOR_is_load(opr).
04186 
04187 
04188 
04189 
04190 OA::MemRefHandle Open64IRInterface::findTopMemRefHandle(WN *wn)
04191 {
04192   OA::MemRefHandle h = OA::MemRefHandle(0);
04193 
04194   if (wn==0 ||  (WN_operator(wn) == OPR_CALL) ) {
04195     return OA::MemRefHandle(0);
04196   }
04197   h = (OA::irhandle_t)wn;
04198 
04199   if(h == OA::MemRefHandle(0)) {
04200      return OA::MemRefHandle(0);
04201   }
04202 
04203   if(sMemref2mreSetMap.find(h) == sMemref2mreSetMap.end()) {
04204 
04205       if((WN_operator(wn) == OPR_ISTORE) ||   
04206          (WN_operator(wn) == OPR_PSTORE) ||   
04207          (WN_operator(wn) == OPR_MSTORE))
04208       {
04209          wn  =  WN_kid1(wn);
04210       } else if(WN_operator(wn) == OPR_INTRINSIC_CALL &&
04211             strcmp(IntrinsicInfo::intrinsicBaseName(WN_intrinsic(wn)), "CONCATEXPR")==0) {
04212 
04213             return OA::MemRefHandle(0);
04214        } else if ( (WN_operator(wn) == OPR_ILOAD) ||
04215               (WN_operator(wn) == OPR_LDID)  ||
04216               (WN_operator(wn) == OPR_STID)  ||
04217               (WN_operator(wn) == OPR_PSTID) ||
04218               (WN_operator(wn) == OPR_ARRAY) ||
04219               (WN_operator(wn) == OPR_ARRAYEXP) ||
04220               (WN_operator(wn) == OPR_LDA) ||
04221               (WN_operator(wn) == OPR_INTRINSIC_CALL) ||
04222               (WN_operator(wn) == OPR_ISTORE) ||
04223               (WN_operator(wn) == OPR_ARRSECTION) ||
04224               (WN_operator(wn) == OPR_PARM) ||
04225               (WN_operator(wn) == OPR_STRCTFLD) ||
04226               (WN_operator(wn) == OPR_MLOAD)
04227             )
04228       {
04229          wn =  WN_kid0(wn);
04230       } else {
04231          // INTCONST, Parameter as expression
04232         return OA::MemRefHandle(0);
04233       }
04234 
04235       h=findTopMemRefHandle(wn);
04236   } else {
04237       return h;
04238   }
04239 
04240   return h;
04241 }
04242 
04243 // createExprTree: Given 'wn' return a possibly empty expression tree.
04244 OA::OA_ptr<OA::ExprTree>
04245 Open64IRInterface::createExprTree(WN* wn)
04246 {
04247   OA::OA_ptr<OA::ExprTree> exprTree;
04248   exprTree = new OA::ExprTree;
04249   createExprTree(exprTree, wn);
04250   return exprTree;
04251 }
04252 
04253 
04254 
04255 bool Open64IRInterface::ExprTree_hack_for_MPI(OA::MemRefHandle h, OA::OA_ptr<OA::ExprTree> tree) 
04256 { 
04257     bool retval=false; 
04258     OA::OA_ptr<OA::ExprTree::Node> root; 
04259     root = NULL; 
04260     string strMemRef; 
04261     WN* wn = (WN*)h.hval(); 
04262     std::ostringstream oss; 
04263     DumpWNMemRef(wn, oss); 
04264     strMemRef = oss.str(); 
04265     string strMWC = "MPI_COMM_WORLD"; 
04266     if (strMemRef.compare(0,strMWC.length(),strMWC) == 0) { 
04267       INT64 i64value = (INT64)91; 
04268       WN* wnic = WN_CreateIntconst(OPC_I4INTCONST,i64value); 
04269       OA::ConstValHandle cvh((OA::irhandle_t)wnic); 
04270       root = new OA::ExprTree::ConstValNode(cvh); 
04271       tree->addNode(root); 
04272       retval=true; 
04273     } 
04274     return retval; 
04275 } 
04276  
04277 
04278 // createExprTree: Given a tree container 'tree' and 'wn', builds tree 
04279 // nodes for wn, adds them to 'tree' and returns the root node of the 
04280 // newly created tree nodes 
04281  
04282 OA::OA_ptr<OA::ExprTree::Node> 
04283 Open64IRInterface::createExprTree(OA::OA_ptr<OA::ExprTree> tree, WN* wn) 
04284 { 
04286     OA::OA_ptr<OA::ExprTree::Node> root; 
04287     root = NULL; 
04288  
04290     if (!wn) { 
04291         std::cout << "NULL" << std::endl;
04292         return root; 
04293     } 
04294  
04296     OPERATOR opr = WN_operator(wn); 
04297     OA::MemRefHandle h((OA::irhandle_t)wn);
04298  
04299     if (IntrinsicInfo::isIntrinsic(wn)) {
04300  
04303           OA::OpHandle h((OA::irhandle_t)wn); 
04304           root = new OA::ExprTree::OpNode(h); 
04305           tree->addNode(root); 
04306 
04308           for (INT kidno=0; kidno<=WN_kid_count(wn)-1; kidno++) { 
04309  
04310                WN* kid_wn  = WN_kid(wn,kidno); 
04311 
04313                OA::OA_ptr<OA::ExprTree::Node> child = createExprTree(tree, kid_wn); 
04314                if (! child.ptrEqual(NULL)) { 
04316                    tree->connect(root, child); 
04317                } 
04318           } 
04319           
04320     } else if(OPERATOR_is_call(opr)) { 
04321  
04324           OA::CallHandle h((OA::irhandle_t)wn); 
04325           root = new OA::ExprTree::CallNode(h); 
04326           tree->addNode(root); 
04327  
04328     }else if (opr == OPR_CONST || opr == OPR_INTCONST) { 
04329  
04332           OA::ConstValHandle h((OA::irhandle_t)wn); 
04333           root = new OA::ExprTree::ConstValNode(h); 
04334           tree->addNode(root); 
04335  
04336     } else if (OPERATOR_has_sym(opr) && ST_class(WN_st(wn)) == CLASS_CONST) { 
04337 
04340           OA::ConstValHandle h((OA::irhandle_t)wn); 
04341           root = new OA::ExprTree::ConstValNode(h); 
04342           tree->addNode(root); 
04343  
04344     } else if(sMemref2mreSetMap.find(h) != sMemref2mreSetMap.end()) {
04345 
04358 
04361           //Barbara's hack
04362           if(!ExprTree_hack_for_MPI(h,tree)) {
04363 
04364               root = new OA::ExprTree::MemRefNode(h);
04365               tree->addNode(root);
04366 
04367           }
04368 
04369     } else if (opr == OPR_ARRAYEXP) {
04370         
04373           return createExprTree(tree, WN_kid0(wn));
04374         
04375     } else if (opr == OPR_SRCTRIPLET){
04379           OA::ConstValHandle h((OA::irhandle_t)wn);
04380           root = new OA::ExprTree::ConstValNode(h);
04381           tree->addNode(root);
04382           
04383     } else { 
04384 
04387           if(WN_kid_count(wn) > 1) { assert(0); }
04388 
04390           return createExprTree(tree, WN_kid0(wn)); 
04391  
04392     } 
04393 
04394     return root; 
04395 } 
04396 
04397 
04398 
04399 
04400 
04401 #if 0 // eraxxon: save this for possible later use
04402 // createExprTree: Given a tree container 'tree' and 'wn', builds tree
04403 // nodes for wn, adds them to 'tree' and returns the root node of the
04404 // newly created tree nodes
04405 OA::OA_ptr<OA::ExprTree::Node>
04406 Open64IRInterface::createExprTree(OA::OA_ptr<OA::ExprTree::ExprTree> tree, WN* wn)
04407 {
04408   using namespace OA::ExprTree;
04409 
04410   OA::OA_ptr<ExprTree::Node> root; root = NULL;
04411   if (!wn) { return root; }
04412   
04413   // 1. Sanity checking.  (In the context of expressions, OPR_STID
04414   // represents the LHS of the assignment.)
04415   OPERATOR opr = WN_operator(wn);
04416   if ( !(opr == OPR_STID || OPERATOR_is_call(opr) 
04417          || OPERATOR_is_expression(opr)) ) {
04418     return root;
04419   }
04420   
04421   // 1a. FIXME: For now, eliminate PARM nodes from tree.
04422   if (opr == OPR_PARM) {
04423     if (WN_kid_count(wn) == 0) {
04424       return root;
04425     } 
04426     else {
04427       return createExprTree(tree, WN_kid0(wn));
04428     }
04429   }
04430   
04431   // 2. Create a parent tree node for the curent WN.  Note that order
04432   // is important here.  *Note* OPR_ICALL and OPR_VFCALL will be
04433   // classified as calls instead of mem-refs.
04434   if (OPERATOR_is_call(opr)) {
04435     OA::ExprHandle h((OA::irhandle_t)wn);
04436     root = new ExprTree::CallNode(h);
04437   }
04438   else if (opr == OPR_CONST || opr == OPR_INTCONST) {
04439     OA::ConstValHandle h((OA::irhandle_t)wn);
04440     root = new ExprTree::ConstValNode(h);
04441   }
04442   else if (OPERATOR_has_sym(opr) && ST_class(WN_st(wn)) == CLASS_CONST) {
04443     OA::ConstSymHandle h((OA::irhandle_t)WN_st(wn));
04444     root = new ExprTree::ConstSymNode(h);
04445   }
04446   else if (opr == OPR_STID || OPERATOR_is_load(opr)
04447            || opr == OPR_ARRAY || opr == OPR_ARRSECTION 
04448            || opr == OPR_ARRAYEXP) {
04449     OA::MemRefHandle h((OA::irhandle_t)wn);
04450     // HACK! ALERT! BK:
04451     // mfef90 is not distributing the constant values beyond the
04452     // main procudure to all subroutines.  Until this is fixed in 
04453     // mfef90, we need to cause all memrefs that refer to the
04454     // constant named MPI_COMM_WORLD with the constant value 91 (this
04455     // is the value from the mpif.h file we are using with our 
04456     // experiment application programs.
04457     //
04458     // before HACK, there was just the following line:
04459     //   root = new ExprTree::MemRefNode(h);
04460     //
04461     string strMemRef;
04462     {
04463       WN* wn = (WN*)h.hval();
04464       std::ostringstream oss;
04465       DumpWNMemRef(wn, oss);
04466       strMemRef = oss.str();
04467     }
04468     string strMWC = "MPI_COMM_WORLD";
04469     if (strMemRef.compare(0,strMWC.length(),strMWC) == 0) {
04470       INT64 i64value = (INT64)91;
04471       WN* wnic = WN_CreateIntconst(OPC_I4INTCONST,i64value);
04472       OA::ConstValHandle cvh((OA::irhandle_t)wnic);
04473       root = new ExprTree::ConstValNode(cvh);
04474     } else {
04475       root = new ExprTree::MemRefNode(h);
04476     }
04477     //
04478     // end of HACK!
04479 
04480   }
04481   else /*if ()*/ { 
04482     // Note: for now we just make everything else an operator
04483     // is expr, not a const, not a mem-ref (&& not a type conversion)
04484     OA::OpHandle h((OA::irhandle_t)wn);
04485     root = new ExprTree::OpNode(h);
04486   }
04487   //else {
04488   //  root = Node();
04489   //}
04490   tree->addNode(root);
04491   
04492   // 3. Create sub trees for each child and link them to the parent
04493   // node (we know this will never be OPR_BLOCK)
04494   if ( !(OPERATOR_is_leaf(opr) || opr == OPR_STID) ) {
04495     for (INT kidno = 0; kidno < WN_kid_count(wn); kidno++) {
04496       WN* kid_wn = WN_kid(wn, kidno);
04497       
04498       OA::OA_ptr<ExprTree::Node> child = createExprTree(tree, kid_wn);
04499       tree->connect(root, child);
04500     }
04501   }
04502   
04503   return root;
04504 }
04505 #endif
04506 
04507 
04508 // Given a ST of CLASS_CONST, return a ConstValBasicInterface representation.
04509 OA::OA_ptr<OA::ConstValBasicInterface>
04510 Open64IRInterface::getConstValBasicFromST(ST* st)
04511 {
04512   OA::OA_ptr<OA::ConstValBasicInterface> cvb; cvb = NULL;
04513   if (!st) { return cvb; }
04514   
04515   TCON& tcon = ST_tcon_val(st);
04516   TYPE_ID mty = TCON_ty(tcon);
04517   
04518   //if (MTYPE_is_complex(mty)) { }
04519   //else if (MTYPE_is_float(mty)) { double x = Targ_To_Host_Float(tcon); }
04520   if (MTYPE_is_integral(mty)) {
04521     INT64 val = Targ_To_Host(tcon);
04522     if (val < INT_MIN || val > INT_MAX) {
04523       cvb = NULL; // no current representation for this
04524     } else {
04525       cvb = new Open64IntegerConstVal((int)val);
04526     }
04527   }
04528   else {
04529     cvb = NULL; // no current representation for this
04530   }
04531 
04532   return cvb;
04533 }
04534 
04535 bool Open64IRInterface::isPassByReference(WN* opr_parm_wn) 
04536 {
04537     bool retval;
04538     assert(opr_parm_wn!=0);
04539 
04540     OA::ExprHandle opr_parm = ((OA::irhandle_t)opr_parm_wn);
04541 
04542     // if this is a call to an undefined function then just return true
04543     // to be conservatively correct, don't know if the parameter is a
04544     // reference or not
04545     OA::ProcHandle callee = getProcHandle( 
04546                                 getSymHandle( sParamToCallMap[opr_parm]));
04547     if (callee == OA::ProcHandle(0)) {
04548         return true;
04549     }
04550 
04551     // get the formal symbol for this actual parameter
04552     // we stored which call this is associated with mapped
04553     // to the wn for the opr_parm
04554     OA::SymHandle formal = getFormalForActual(
04555                               sProcContext[opr_parm],
04556                               sParamToCallMap[opr_parm],
04557                               callee,
04558                               opr_parm );
04559 
04560     // the symbol table entry for the formal parameter
04561     setCurrentProcToProcContext(formal);
04562 
04563     // FIXME: this might be overly conservative in C programs
04564     // because of how isRefParam is implemented
04565     if (isRefParam(formal)) {
04566         retval= true;
04567     } else {
04568         retval= false;
04569     }
04570  
04571     // set context back to caller
04572     setCurrentProcToProcContext(opr_parm);
04573     return retval;
04574 }
04575 
04576 
04580 const char* Open64IRInterface::createCharStarForST(ST* st)
04581 {
04582     const char* nm = NULL;
04583 
04584     if (ST_class(st) == CLASS_CONST) {
04585         TCON& tcon = STC_val(st);
04586         if (TCON_ty(tcon) == MTYPE_STR) {
04587             STR_IDX idx = TCON_str_idx(tcon);
04588         } else {
04589             nm = Targ_Print(NULL, tcon);
04590         }
04591     } else { nm = ST_name(st); }
04592 
04593     if (nm==NULL) {
04594         nm = "<no-symbol>";
04595     }
04596 
04597     return nm;
04598 }
04599 
04600 //---------------------------------------------------------------------------
04601 // Visualize Whirl expressions in a compact way.
04602 //
04603 // This is strictly for debugging. It does not attempt, for example, to
04604 // properly parenthesize expressions, etc.
04605 //---------------------------------------------------------------------------
04606 
04607 void
04608 Open64IRInterface::DumpWN(WN* wn, ostream& os)
04609 {
04610   if (!wn) { os << "NULL"; return; }
04611 
04612   // Printing scope of WN i.e. Name of the procedure
04613   // it belongs to
04614   /*
04615   PU_Info* origPU = Current_PU_Info;
04616   if(origPU != NULL) {
04617      ST_IDX idx = PU_Info_proc_sym(origPU);
04618      char* procname = ST_name(idx);
04619      std::cout << std::endl << "ProcName" << procname << std::endl;
04620   }
04621   */
04622   
04623   OPERATOR opr = WN_operator(wn);
04624   string op;
04625   switch (opr) {
04626 
04627   // Leaf operations and memory operations.
04628   case OPR_LDA:
04629     // Perhaps strange, but Whirl has the notion of the address of a
04630     // constant.  The FORTRAN call foo(2) in Whirl is foo(OPR_LDA(2)).
04631     if (ST_sym_class(WN_st(wn)) == CLASS_CONST) {
04632       os << Targ_Print(NULL, WN_val(wn));
04633     } else {
04634       DumpWNLeaf(wn, os);
04635     }
04636     break;
04637   case OPR_IDNAME:
04638   case OPR_LDMA:
04639   case OPR_LDID:
04640     DumpWNLeaf(wn, os);
04641     break;
04642   case OPR_ILOAD:
04643   case OPR_ILOADX:
04644     DumpWNMemRefLeaf(wn, os);
04645     DumpWN(WN_kid0(wn), os);
04646     break;
04647     
04648   case OPR_CONST:
04649     os << Targ_Print(NULL, WN_val(wn));
04650     break;
04651   case OPR_INTCONST:
04652     os << WN_const_val(wn);
04653     break;
04654 
04655   case OPR_ISTORE:
04656   case OPR_ISTOREX:
04657     DumpWN(WN_kid1(wn), os);
04658     os << " = ";
04659     DumpWN(WN_kid0(wn), os);
04660     break;
04661   case OPR_STID:
04662     DumpWNLeaf(wn, os);
04663     os << " = ";
04664     DumpWN(WN_kid0(wn), os);
04665     break;
04666 
04667   // Unary expression operations.
04668   case OPR_CVT:
04669   case OPR_CVTL:
04670   case OPR_TAS:
04671     os << OPCODE_name(WN_opcode(wn)) << "(";
04672     DumpWN(WN_kid0(wn), os);
04673     os << ")";
04674     break;
04675   case OPR_PARM:
04676     if (WN_flag(wn) & WN_PARM_BY_REFERENCE)
04677       os << "&"; 
04678     DumpWN(WN_kid0(wn), os);
04679     break;
04680   case OPR_ABS:
04681     os << "ABS(";
04682     DumpWN(WN_kid0(wn), os);
04683     os << ")";
04684     break;
04685   case OPR_SQRT:
04686     os << "SQRT(";
04687     DumpWN(WN_kid0(wn), os);
04688     os << ")";
04689     break;
04690   case OPR_RSQRT:
04691     os << "RSQRT(";
04692     DumpWN(WN_kid0(wn), os);
04693     os << ")";
04694     break;
04695   case OPR_RECIP:
04696     os << "RECIP(";
04697     DumpWN(WN_kid0(wn), os);
04698     os << ")";
04699     break;
04700   case OPR_PAREN:
04701     os << "(";
04702     DumpWN(WN_kid0(wn), os);
04703     os << ")";
04704     break;
04705   case OPR_RND:
04706     os << "RND(";
04707     DumpWN(WN_kid0(wn), os);
04708     os << ")";
04709     break;
04710   case OPR_TRUNC:
04711     os << "TRUNC(";
04712     DumpWN(WN_kid0(wn), os);
04713     os << ")";
04714     break;
04715   case OPR_CEIL:
04716     os << "CEIL(";
04717     DumpWN(WN_kid0(wn), os);
04718     os << ")";
04719     break;
04720   case OPR_FLOOR:
04721     os << "FLOOR(";
04722     DumpWN(WN_kid0(wn), os);
04723     os << ")";
04724     break;
04725   case OPR_NEG:
04726     op = "-";
04727     goto print_generic_unary;
04728   case OPR_BNOT:
04729     op = "~";
04730     goto print_generic_unary;
04731   case OPR_LNOT:
04732     op = "!";
04733     goto print_generic_unary;
04734 print_generic_unary:
04735     os << op;
04736     DumpWN(WN_kid0(wn), os);
04737     break;
04738 
04739   // Binary expression operations.
04740   case OPR_ADD:
04741     op = "+";
04742     goto print_generic_binary;
04743   case OPR_SUB:
04744     op = "-";
04745     goto print_generic_binary;
04746   case OPR_MPY:
04747     op = "*";
04748     goto print_generic_binary;
04749   case OPR_DIV:
04750     op = "/";
04751     goto print_generic_binary;
04752   case OPR_MOD:
04753     os << "MOD(";
04754     DumpWN(WN_kid0(wn), os);
04755     os << ",";
04756     DumpWN(WN_kid1(wn), os);
04757     os << ")";
04758     break;
04759   case OPR_REM:
04760     op = "%";
04761     goto print_generic_binary;
04762   case OPR_EQ:
04763     op = "==";
04764     goto print_generic_binary;
04765   case OPR_NE:
04766     op = "!=";
04767     goto print_generic_binary;
04768   case OPR_GE:
04769     op = ">=";
04770     goto print_generic_binary;
04771   case OPR_LE:
04772     op = "<=";
04773     goto print_generic_binary;
04774   case OPR_GT:
04775     op = '>';
04776     goto print_generic_binary;
04777   case OPR_LT:
04778     op = '<';
04779     goto print_generic_binary;
04780   case OPR_MAX:
04781     os << "MAX(";
04782     DumpWN(WN_kid0(wn), os);
04783     os << ",";
04784     DumpWN(WN_kid1(wn), os);
04785     os << ")";
04786     break;
04787   case OPR_MIN:
04788     os << "MIN(";
04789     DumpWN(WN_kid0(wn), os);
04790     os << ",";
04791     DumpWN(WN_kid1(wn), os);
04792     os << ")";
04793     break;
04794   case OPR_SHL:
04795     op = "<<";
04796     goto print_generic_binary;
04797   case OPR_ASHR:
04798   case OPR_LSHR:
04799     op = ">>";
04800     goto print_generic_binary;
04801   case OPR_LAND:
04802     op = "&&";
04803     goto print_generic_binary;
04804   case OPR_LIOR:
04805     op = "||";
04806     goto print_generic_binary;
04807   case OPR_BAND:
04808     op = "&";
04809     goto print_generic_binary;
04810   case OPR_BIOR:
04811     op = "|";
04812     goto print_generic_binary;
04813   case OPR_BXOR:
04814     op = "^";
04815 print_generic_binary:
04816     DumpWN(WN_kid0(wn), os);
04817     os << op;
04818     DumpWN(WN_kid1(wn), os);
04819     break;
04820 
04821   // Ternary operations.
04822   case OPR_SELECT:
04823     DumpWN(WN_kid0(wn), os);
04824     os << " ? "; 
04825     DumpWN(WN_kid1(wn), os);
04826     os << " : "; 
04827     DumpWN(WN_kid2(wn), os);
04828     break;
04829   case OPR_MADD:
04830     os << "(";
04831     DumpWN(WN_kid0(wn), os);
04832     os << "*";
04833     DumpWN(WN_kid1(wn), os);
04834     os << ")+";
04835     DumpWN(WN_kid2(wn), os);
04836     break;
04837   case OPR_MSUB:
04838     os << "(";
04839     DumpWN(WN_kid0(wn), os);
04840     os << "*";
04841     DumpWN(WN_kid1(wn), os);
04842     os << ")-";
04843     DumpWN(WN_kid2(wn), os);
04844     break;
04845   case OPR_NMADD:
04846     os << "-((";
04847     DumpWN(WN_kid0(wn), os);
04848     os << "*";
04849     DumpWN(WN_kid1(wn), os);
04850     os << ")+";
04851     DumpWN(WN_kid2(wn), os);
04852     os << ")";
04853     break;
04854   case OPR_NMSUB:
04855     os << "-((";
04856     DumpWN(WN_kid0(wn), os);
04857     os << "*";
04858     DumpWN(WN_kid1(wn), os);
04859     os << ")-";
04860     DumpWN(WN_kid2(wn), os);
04861     os << ")";
04862     break;
04863 
04864   // N-ary operations.
04865   case OPR_ARRAY: {
04866     int ndims = WN_kid_count(wn) >> 1;
04867     DumpWN(WN_kid0(wn), os);
04868     os << "(";
04869     for (int i = 0; i < ndims; i++) {
04870       DumpWN(WN_kid(wn, i+ndims+1), os);
04871       if (i < ndims-1) 
04872         os << ",";
04873     }
04874     os << ")";
04875     break;
04876   }
04877   case OPR_TRIPLET: // Output as LB:UB:STRIDE
04878     DumpWN(WN_kid0(wn), os);
04879     os << ":";
04880     DumpWN(WN_kid2(wn), os);
04881     os << ":";
04882     DumpWN(WN_kid1(wn), os);
04883     break; 
04884   case OPR_IMPLICIT_BND: // Output as nothing
04885     break; 
04886   case OPR_SRCTRIPLET: // Output as LB:UB:STRIDE
04887     DumpWN(WN_kid0(wn), os);
04888     os << ":";
04889     DumpWN(WN_kid2(wn), os);
04890     os << ":";
04891     DumpWN(WN_kid1(wn), os);
04892     break; 
04893   case OPR_ARRAYEXP:
04894     DumpWN(WN_kid0(wn), os);
04895     break; 
04896   case OPR_ARRSECTION: {
04897     int ndims = WN_kid_count(wn) >> 1;
04898     DumpWN(WN_kid0(wn), os);
04899     os << "(";
04900     for (int i = 0; i < ndims; i++) {
04901       DumpWN(WN_kid(wn, i+ndims+1), os);
04902       if (i < ndims-1) 
04903         os << ",";
04904     }
04905     os << ")";
04906     break;
04907   }
04908 
04909   // Control flow constructs
04910   case OPR_DO_LOOP:
04911     // In OA, the DO_LOOP node represents the loop condition.
04912     os << "do_loop (";
04913     DumpWN(WN_end(wn), os);
04914     os << ")"; 
04915     break;
04916   case OPR_DO_WHILE:
04917     // In OA, the DO_WHILE node represents the loop condition.
04918     os << "do_while (";
04919     DumpWN(WN_while_test(wn), os);
04920     os << ")"; 
04921     break;
04922   case OPR_WHILE_DO:
04923     // In OA, the WHILE_DO node represents the loop condition.
04924     os << "while_do ("; 
04925     DumpWN(WN_while_test(wn), os);
04926     os << ")";
04927     break;
04928   case OPR_IF:
04929     // In OA, the IF node represents the condition.
04930     os << "if ("; 
04931     DumpWN(WN_if_test(wn), os);
04932     os << ")"; 
04933     break;
04934   case OPR_TRUEBR:
04935     // In OA, the TRUEBR node represents the condition.
04936     os << "truebr ("; 
04937     DumpWN(WN_kid0(wn), os);
04938     os << "), L" << WN_label_number(wn); 
04939     break;
04940   case OPR_FALSEBR:
04941     // In OA, the FALSEBR node represents the condition.
04942     os << "falsebr (";
04943     DumpWN(WN_kid0(wn), os);
04944     os << "), L" << WN_label_number(wn); 
04945     break;
04946   case OPR_RETURN:
04947     os << "return";
04948     break;
04949   case OPR_RETURN_VAL:
04950     os << "return (";
04951     DumpWN(WN_kid0(wn), os);
04952     os << ")";
04953     break;
04954   case OPR_CALL:
04955     os << createCharStarForST(WN_st (wn)) << "(";
04956     for (int kid = 0; kid < WN_kid_count(wn); kid++) {
04957       DumpWN(WN_kid(wn, kid), os);
04958       if (kid < WN_kid_count(wn)-1)
04959         os << ", ";
04960     } // for kids
04961     os << ")";
04962     break;
04963   case OPR_INTRINSIC_CALL:
04964   case OPR_INTRINSIC_OP:
04965     os << INTRINSIC_name ((INTRINSIC) WN_intrinsic (wn)) << "(";
04966     for (int kid = 0; kid < WN_kid_count(wn); kid++) {
04967       DumpWN(WN_kid(wn, kid), os);
04968       if (kid < WN_kid_count(wn)-1)
04969         os << ", ";
04970     } // for kids
04971     os << ")";
04972     break;
04973   case OPR_FUNC_ENTRY:
04974     os << "Subroutine(";
04975     for (int kid = 0; kid < WN_kid_count(wn); kid++) {
04976       DumpWN(WN_kid(wn, kid), os);
04977       if (kid < WN_kid_count(wn)-1)
04978         os << ", ";
04979     } // for kids
04980     os << ")";
04981     break;
04982   case OPR_BLOCK:
04983     os << "(";
04984     for (int kid = 0; kid < WN_kid_count(wn); kid++) {
04985       DumpWN(WN_kid(wn, kid), os);
04986       if (kid < WN_kid_count(wn)-1)
04987         os << ", ";
04988     } // for kids
04989     os << ")";
04990     break;
04991   case OPR_PAIR:
04992     os << "cmplx(";
04993     for (int kid = 0; kid < WN_kid_count(wn); kid++) {
04994       DumpWN(WN_kid(wn, kid), os);
04995       if (kid < WN_kid_count(wn)-1)
04996         os << ", ";
04997     } // for kids
04998     os << ")";
04999     break;
05000   case OPR_STRCTFLD: { 
05001     DumpWN(WN_kid(wn, 0), os);
05002     os << "%";
05003     TY_IDX ty2 = WN_load_addr_ty(wn);
05004     UINT field_id = WN_field_id(wn);
05005     FLD_HANDLE fld = TY_fld(ty2); 
05006     field_id--;
05007     while (field_id && !FLD_last_field(fld)) {
05008         --field_id ;
05009         fld = FLD_next(fld);
05010     }
05011     os <<  FLD_name(fld);
05012     break;
05013   }
05014   default:
05015     fprintf(stderr,"DumpWN: no logic for :");  
05016     fdump_wn(stderr, wn); // or fdump_tree()
05017 
05018     std::cout << std::endl << std::endl;
05019 
05020     //fdump_wn(stdout, wn); // or fdump_tree()
05021     break;
05022   }
05023 }
05024 
05025 
05026 void 
05027 Open64IRInterface::DumpWNLeaf(WN* wn, ostream& os) 
05028 {
05029   if (!wn) { return; }
05030   DumpWNMemRefLeaf(wn, os);
05031 }
05032 
05033 
05034 // DumpWNMemRef: Dump a mem-ref in a form that allows a hash to be
05035 // done on the output string.  (This implies that WHIRL operators must
05036 // not be part of the output.)  Note that STOREs represent the
05037 // left-hand-side memory-ref.  This function is similar to DumpWN but
05038 // contains special handling for STORES.
05039 void 
05040 Open64IRInterface::DumpWNMemRef(WN* wn, ostream& os)
05041 {
05042   if (!wn) { return; }
05043   
05044   OPERATOR opr = WN_operator(wn);
05045   if (OPERATOR_is_store(opr)) {
05046     if (WN_kid_count(wn) > 1) {
05047       DumpWN(WN_kid1(wn), os); // left-hand-side
05048     }
05049     else {
05050       DumpWNMemRefLeaf(wn, os);
05051     }
05052   } 
05053   else {
05054     DumpWN(wn, os);
05055   }
05056 }
05057 
05058 
05059 void 
05060 Open64IRInterface::DumpWNMemRefLeaf(WN* wn, ostream& os) 
05061 {
05062   if (!wn) { return; }
05063 
05064   OPERATOR opr = WN_operator(wn);
05065   if (OPERATOR_has_sym(opr)) {
05066     os << createCharStarForST(WN_st(wn)) << ":";
05067   } 
05068   if (OPERATOR_has_offset(opr)) {
05069     os << WN_offset(wn) << ":";
05070   }
05071   if (OPERATOR_has_1ty(opr)) {
05072     os << TY_name(WN_ty(wn));
05073   }
05074 }
05075 
05076 
05079 void Open64IRInterface::initCallSymToProcMap(Open64IRProcIterator &procIter)
05080 {
05081     // create an instance of Open64IRInterface so that we have access
05082     // to all methods
05083     Open64IRInterface tempIR;
05084     
05085     // Iterate over procedures in program
05086     OA::ProcHandle proc;
05087     for (procIter.reset(); procIter.isValid(); procIter++) {
05088         proc = procIter.current();
05089         OA::SymHandle sym = tempIR.getSymHandle(proc);
05090         Open64IRInterface::sCallSymToProc[sym] = proc;
05091     }
05092 }
05093 
05101 void Open64IRInterface::initProcToSymRefSetMap(Open64IRProcIterator &procIter)
05102 {
05103     // create an instance of Open64IRInterface so that we have access
05104     // to all methods
05105     Open64IRInterface tempIR;
05106     
05107     // Iterate over procedures in program
05108     OA::ProcHandle proc;
05109     for (procIter.reset(); procIter.isValid(); procIter++) {
05110         proc = procIter.current();
05111         OA::OA_ptr<OA::IRSymIterator> symIter = tempIR.getRefSymIterator(proc);
05112         std::set<OA::SymHandle> refSet;
05113 
05114         for ( ; symIter->isValid(); (*symIter)++ ) {
05115             sProcToSymRefSetMap[proc].insert(symIter->current());
05116         }
05117     }
05118 }
05119 
05120 
05121         
05126 void Open64IRInterface::setCurrentProcToProcContext(OA::IRHandle h) 
05127 {
05128     if (h.hval()!=0) {
05129 
05130       std::map<OA::IRHandle,OA::ProcHandle>::iterator fi=sProcContext.find(h);
05131       if (fi==sProcContext.end()) { 
05132         std::cout << "missing entry " << h.hval() << " in sProcContext" << std::endl;  
05133         std::cout << " could be a OPC : " <<  OPCODE_name(WN_opcode((WN*)(h.hval()))) << std::endl;
05134       }  
05135       assert(fi!=sProcContext.end());
05136       PU_Info *pu = (PU_Info*)((*fi).second.hval());
05137       assert(pu!=NULL);
05138       // have to check what Open64 thinks is current context
05139       if ( Current_PU_Info  != pu && pu != NULL ) {
05140         PU_SetGlobalState(pu);
05141       }
05142     }
05143 }
05144 
05145 OA::ProcHandle Open64IRInterface::getCurrentProcContext()
05146 {
05147     return (OA::irhandle_t)Current_PU_Info;
05148 }
05149 
05150 void Open64IRInterface::setCurrentProcContext(OA::ProcHandle proc)
05151 {
05152     PU_Info *pu = (PU_Info*)proc.hval();
05153     // have to check what Open64 thinks is current context
05154     if ( Current_PU_Info  != pu && pu != NULL ) {
05155         PU_SetGlobalState(pu);
05156     }
05157 }
05158 
05159 
05162 fully_qualified_name Open64IRInterface::create_fqn(OA::SymHandle sym)
05163 {
05164     ST* st = (ST*)sym.hval();
05165     assert(Stab_Is_Based_At_Common_Block(st)
05166            ||
05167            (ST_is_in_module(st) && ST_sym_class(st)==CLASS_VAR));
05168     ST* base_st=st;
05169     if (Stab_Is_Based_At_Common_Block(st)) {
05170       while (!Stab_Is_Common_Block(base_st)) {
05171         base_st = ST_base(base_st);
05172       }
05173     }
05174     else { // is a module variable
05175       while (base_st!=ST_base(base_st)) {
05176         base_st = ST_base(base_st);
05177       }
05178     }
05179     // make a pair for fully-qualified name
05180     return  fully_qualified_name(createCharStarForST(st), createCharStarForST(base_st));
05181 }
05182 
05188 void Open64IRInterface::initProcContext(PU_Info* pu_forest, 
05189                                         Open64IRProcIterator &procIter)
05190 {
05191     // create an instance of Open64IRInterface so that we have access
05192     // to all methods
05193     Open64IRInterface tempIR;
05194     
05195     // Indicate that context has been initialized
05196     sContextInit = true;
05197     
05198     // should not be setting up context on more than one program
05199     assert(sProgContext==NULL || sProgContext==pu_forest);
05200     sProgContext = pu_forest;
05201 
05202     // Iterate over procedures in program
05203     bool globalSymsVisitFlag = false;
05204     OA::ProcHandle proc;
05205     procIter.reset();
05206     for (; procIter.isValid(); procIter++) {
05207         proc = procIter.current();
05208         PU_Info* pu = (PU_Info*)proc.hval();
05209         WN *wn_pu = PU_Info_tree_ptr(pu);
05210         
05211         // 1. Add Whirl symbols to map
05212 
05213         // NOTE: Do not use tempIR.getVisibleSymIterator(proc) or it
05214         // will kill performance.  Instead just get symbols at the
05215         // global level once and for each procedure just get symbols
05216         // on all levels higher than global
05217         std::list<ST*> symlist;
05218         int stopLevel;
05219         if ( globalSymsVisitFlag==false ) {
05220             stopLevel = GLOBAL_SYMTAB;
05221             globalSymsVisitFlag = true;
05222         } else { 
05223             stopLevel = GLOBAL_SYMTAB+1;
05224         }
05225         // inserts all symbols at corresponding symbol table levels
05226         // into symlist
05227         for (SYMTAB_IDX lvl = CURRENT_SYMTAB; lvl >= stopLevel; --lvl) {
05228             For_all(St_Table, lvl, insert_ST(symlist));
05229         }
05230         std::list<ST*>::iterator symIter;
05231         for (symIter = symlist.begin(); symIter!=symlist.end(); symIter++ ) { 
05232             ST* st = *symIter;
05233             OA::SymHandle sym((OA::irhandle_t)st);
05234 
05235             // set the procedure context for the symbol
05236             sProcContext[sym] = proc;
05237             if (debug) {
05238                 std::cout << "sProcContext[" << sym.hval() << ":symbol=" << createCharStarForST(st) << "] = " 
05239                           << proc.hval() << ":PU=" <<  ST_name(ST_ptr(PU_Info_proc_sym((PU_Info*)proc.hval()))) << "" <<  std::endl;
05240             }
05241 
05242             // store the string for the symbol
05243             const char* nm = createCharStarForST(st);
05244             sSymToVarStringMap[sym] = nm;
05245 
05246             // store symbols based on fully qualified name as well
05247             // if they are module or common block variables
05248             if (Stab_Is_Based_At_Common_Block(st) 
05249                 ||
05250                 (ST_is_in_module(st) && ST_sym_class(st)==CLASS_VAR)) {
05251               fully_qualified_name fqn = create_fqn(sym);
05252               sGlobalVarMap[fqn].insert(sym);
05253               sSymToFQNMap[sym] = fqn;
05254               if (debug) {
05255                 std::cout << "create_fqn(" << createCharStarForST(st) 
05256                           << ") yields: ("
05257                           << fqn.mVar << "," << fqn.mContext << ")" << std::endl;
05258                 std::cout << "\tsym = " << tempIR.toString(sym)
05259                           << ", hval= " << sym.hval()
05260                           << ", st = " << (unsigned long)st << std::endl;
05261               }
05262             }
05263         }
05264 
05265         // 2. Add Whirl AST nodes to map
05266         WN_TREE_CONTAINER<PRE_ORDER> wtree(wn_pu);
05267         WN_TREE_CONTAINER<PRE_ORDER>::iterator it;
05268         for (it = wtree.begin(); it != wtree.end(); ++it) {
05269           WN* curWN = it.Wn();
05270           OA::IRHandle h((OA::irhandle_t)curWN);
05271           sProcContext[h] = proc;
05272           if (debug) {
05273             std::cout << "sProcContext[" << h.hval() << ":OPC=" << OPCODE_name(WN_opcode(curWN)) << "] = " 
05274                       << proc.hval() << ":PU=" <<  ST_name(ST_ptr(PU_Info_proc_sym((PU_Info*)proc.hval()))) << "" <<  std::endl;
05275           }
05276         }
05277     }
05278 
05279     // the last procedure is the one that is the currentProc context
05280     //sCurrentProc = (PU_Info*)proc.hval();
05281 }
05282 
05283 void Open64IRInterface::setIgnoreBlackBoxRoutines() { 
05284   ourIgnoreBlackBoxRoutines=true;
05285 } 
05286 
05287 bool Open64IRInterface::ignoreBlackBoxRoutines() { 
05288   return ourIgnoreBlackBoxRoutines;
05289 } 
05290 
05291 bool Open64IRInterface::haveDefinition(WN* wn) { 
05292   static std::set<string> reportedNames;  // for warnings
05293   if (WN_operator(wn) == OPR_ICALL) {
05294     return false;
05295   }
05296   assert(WN_has_sym(wn));
05297   if (true) { 
05298     if (sCallSymToProc[OA::SymHandle((OA::irhandle_t)WN_st(wn))]==OA::ProcHandle(0)) { 
05299       std::string name=ST_name(WN_st(wn));
05300       if (reportedNames.find(name)==reportedNames.end()) { 
05301         reportedNames.insert(name);
05302         // we don't show these calls to OpenAnalysis which translates to 
05303         // making the optimistic assumption that there are no side effects 
05304         DBGMSG_PUB(0, "Warning: assuming no sideeffects for undefined routine %s",name.c_str());
05305       }
05306     }
05307   }
05308   return (sCallSymToProc[OA::SymHandle((OA::irhandle_t)WN_st(wn))]!=OA::ProcHandle(0));
05309 } 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines