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