Open64IRInterface.cpp

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