Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 /* -*-Mode: c++;-*- (Tell emacs to use c++ mode) */ 00037 00038 #include "wn_tree_util.h" 00039 #include "anl_common.h" 00040 #include "anl_diagnostics.h" // For warnings and errors 00041 #include "w2c_driver.h" // For whirl2c.so utilities 00042 #include "w2f_driver.h" // For whirl2f.so utilities 00043 #include "anl_file_mngr.h" // For managing files 00044 #include "w2cf_translator.h" 00045 00046 extern ANL_DIAGNOSTICS *Anl_Diag; // Defined in anl_driver.cxx 00047 00048 // Remove any direct dependence on whirl2f.so and whirl2c.so 00049 // 00050 #pragma weak W2C_Push_PU 00051 #pragma weak W2C_Pop_PU 00052 #pragma weak W2C_Translate_Wn 00053 #pragma weak W2C_Translate_Stid_Lhs 00054 #pragma weak W2C_Translate_Istore_Lhs 00055 #pragma weak W2C_Process_Command_Line 00056 #pragma weak W2C_Init 00057 #pragma weak W2C_Translate_Wn_Str 00058 #pragma weak W2C_Object_Name 00059 #pragma weak W2F_Push_PU 00060 #pragma weak W2F_Pop_PU 00061 #pragma weak W2F_Translate_Wn 00062 #pragma weak W2F_Translate_Stid_Lhs 00063 #pragma weak W2F_Translate_Istore_Lhs 00064 #pragma weak W2F_Process_Command_Line 00065 #pragma weak W2F_Init 00066 #pragma weak W2F_Translate_Wn_Str 00067 #pragma weak W2F_Object_Name 00068 00069 // ============== General Purpose Utilities =============== 00070 // ======================================================== 00071 00072 #define NEXT_ANL_POINTER(p) TY_pointer(p) 00073 00074 00075 // Class used in combination with TREE_WALK to determine number 00076 // of WN_st references to a given ST from WHIRL nodes of the given 00077 // operator. 00078 // 00079 class NUM_ST_REFS 00080 { 00081 private: 00082 const OPERATOR _opr; 00083 ST * const _st; 00084 INT _num_nodes; 00085 public: 00086 NUM_ST_REFS(OPERATOR opr, ST *st): _opr(opr), _st(st), _num_nodes(0) {} 00087 INT num_nodes() const {return _num_nodes;} 00088 00089 void operator()(WN* wn) 00090 { 00091 if (WN_operator(wn) == _opr && WN_st(wn) == _st) 00092 ++_num_nodes; 00093 } 00094 }; // NUM_ST_REFS 00095 00096 00097 // ==================== Class Members ===================== 00098 // ======================================================== 00099 00100 const INT W2CF_TRANSLATOR::_Max_W2cf_String_Size = 1024*5; 00101 00102 00103 void 00104 W2CF_TRANSLATOR::_Get_Ftn_Name(ANL_CBUF *cbuf, const ST *st) 00105 { 00106 // PRECONDITION: ST_name(st) != NULL 00107 // 00108 const char *name_ptr = ST_name(st); 00109 00110 if (ST_EXTERNAL_LINKAGE(st) && 00111 !ST_IS_BASED_AT_COMMON_OR_EQUIVALENCE(st) && 00112 !(ST_sym_class(st) == CLASS_VAR && ST_is_namelist(st))) 00113 { 00114 // Here we deal with a curiosity of the Fortran naming scheme for 00115 // external names: 00116 // 00117 // + If the name ends with a '_', the name was without the '_' 00118 // in the original Fortran source. 00119 // 00120 // + If the name ends without a '_', the name was with a '$' 00121 // suffix in the original Fortran source. 00122 // 00123 // + If the name begins with a '_', always emit a trailing '$'. 00124 // 00125 const char first_char = name_ptr[0]; 00126 00127 while (*name_ptr != '\0') 00128 { 00129 if (first_char != '_' && name_ptr[0] == '_') 00130 { 00131 if (name_ptr[1] == '\0') 00132 { 00133 // Ignore ending underscore. 00134 name_ptr += 1; 00135 } 00136 else if (name_ptr[1] == '_' && name_ptr[2] == '\0') 00137 { 00138 // Ignore ending two underscores. 00139 name_ptr += 2; 00140 } 00141 else 00142 { 00143 // make underscore part of the name 00144 // 00145 cbuf->Write_Char(name_ptr[0]); 00146 name_ptr += 1; 00147 } 00148 } 00149 else 00150 { 00151 cbuf->Write_Char(name_ptr[0]); 00152 name_ptr += 1; 00153 if (name_ptr[0] == '\0') 00154 cbuf->Write_Char('$'); // Ends with '$' 00155 } 00156 } // While more characters 00157 } 00158 else if (name_ptr != NULL) 00159 { 00160 cbuf->Write_String(name_ptr); 00161 } 00162 } // W2CF_TRANSLATOR::_Get_Ftn_Name 00163 00164 00165 BOOL 00166 W2CF_TRANSLATOR::_Is_Ptr_Expr(WN *wn) 00167 { 00168 BOOL predicate; 00169 00170 switch (WN_operator(wn)) 00171 { 00172 case OPR_LDID: 00173 case OPR_ILOAD: 00174 predicate = TY_IS_POINTER(WN_ty(wn)); 00175 break; 00176 00177 case OPR_ARRAY: 00178 predicate = TRUE; 00179 break; 00180 00181 case OPR_LDA: 00182 predicate = TRUE; 00183 break; 00184 00185 case OPR_ADD: 00186 predicate = _Is_Ptr_Expr(WN_kid0(wn)) || _Is_Ptr_Expr(WN_kid1(wn)); 00187 break; 00188 00189 default: 00190 predicate = FALSE; 00191 break; 00192 } 00193 return predicate; 00194 } // W2CF_TRANSLATOR::_Is_Ptr_Expr 00195 00196 00197 TY_IDX 00198 W2CF_TRANSLATOR::_Get_Expr_Pointed_Ty(WN *wn) 00199 { 00200 // PRECONDITION: _Is_Ptr_Expr(wn) == TRUE 00201 // 00202 // Returns the type pointed to by the given pointer expression 00203 // 00204 TY_IDX ty; 00205 00206 switch (WN_operator(wn)) 00207 { 00208 case OPR_LDID: 00209 case OPR_ILOAD: 00210 ty = TY_pointed(WN_ty(wn)); 00211 break; 00212 00213 case OPR_ARRAY: 00214 ty = _Get_Expr_Pointed_Ty(WN_kid0(wn)); 00215 if (TY_IS_ARRAY(ty)) 00216 ty = TY_AR_etype(ty); 00217 break; 00218 00219 case OPR_LDA: 00220 ty = TY_pointed(WN_ty(wn)); 00221 break; 00222 00223 case OPR_ADD: 00224 if (_Is_Ptr_Expr(WN_kid0(wn))) 00225 ty = _Get_Expr_Pointed_Ty(WN_kid0(wn)); 00226 else if (_Is_Ptr_Expr(WN_kid1(wn))) 00227 ty = _Get_Expr_Pointed_Ty(WN_kid1(wn)); 00228 else 00229 ty = NULL; 00230 break; 00231 00232 default: 00233 ty = NULL; 00234 break; 00235 } 00236 return ty; 00237 } // W2CF_TRANSLATOR::_Get_Expr_Pointed_Ty 00238 00239 00240 // ==================== Hidden Members ==================== 00241 // ======================================================== 00242 // 00243 // In the 7.2 version of the symtab, pseudo-TY entries were 00244 // created & linked together. They were created in a pool local 00245 // to ANL. As this can't be done in the new symbol table, we do 00246 // not reuse pointers anymore and just add new pointers to the 00247 // symbol table as appropriate. As only character 00248 // objects (strings?) get these pointer TYs, overhead shouldn't be 00249 // too bad. See _Reuse_Ptr in revision 1.18 of this file and 00250 // revision 1.9 of w2cf_translator.h. 00251 //========================================================== 00252 00253 void 00254 W2CF_TRANSLATOR::_Istore_Lhs_To_String(ANL_CBUF *cbuf, 00255 WN *lhs, 00256 STAB_OFFSET ofst, 00257 TY_IDX ty, 00258 MTYPE mtype) 00259 00260 { 00261 if (_translate_to_c) 00262 { 00263 W2C_Push_PU(_pu, lhs); 00264 W2C_Translate_Istore_Lhs(_strbuf, _Max_W2cf_String_Size, 00265 lhs, ofst, ty, mtype); 00266 W2C_Pop_PU(); 00267 } 00268 else 00269 { 00270 W2F_Push_PU(_pu, lhs); 00271 W2F_Translate_Istore_Lhs(_strbuf, _Max_W2cf_String_Size, 00272 lhs, ofst, ty, mtype); 00273 W2F_Pop_PU(); 00274 } 00275 cbuf->Write_String(_strbuf); 00276 } // W2CF_TRANSLATOR::_Istore_Lhs_To_String 00277 00278 00279 void 00280 W2CF_TRANSLATOR::_Mp_Schedtype_To_String(ANL_CBUF *cbuf, 00281 WN_PRAGMA_SCHEDTYPE_KIND kind) 00282 { 00283 switch (kind) 00284 { 00285 case WN_PRAGMA_SCHEDTYPE_RUNTIME: 00286 cbuf->Write_String("runtime"); 00287 break; 00288 case WN_PRAGMA_SCHEDTYPE_SIMPLE: 00289 cbuf->Write_String("simple"); 00290 break; 00291 case WN_PRAGMA_SCHEDTYPE_INTERLEAVE: 00292 cbuf->Write_String("interleaved"); 00293 break; 00294 case WN_PRAGMA_SCHEDTYPE_DYNAMIC: 00295 cbuf->Write_String("dynamic"); 00296 break; 00297 case WN_PRAGMA_SCHEDTYPE_GSS: 00298 cbuf->Write_String("gss"); 00299 break; 00300 case WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED: 00301 cbuf->Write_String("pseudolowered"); 00302 break; 00303 default: 00304 cbuf->Write_String("<mpschedtype??>"); 00305 break; 00306 } 00307 } // W2CF_TRANSLATOR::_Mp_Schedtype_To_String 00308 00309 00310 00311 void 00312 W2CF_TRANSLATOR::_Default_Kind_To_String (ANL_CBUF *cbuf, 00313 WN_PRAGMA_DEFAULT_KIND kind) 00314 { 00315 // print a string associated with a WN_PRAGMA_DEFAULT 00316 00317 switch (kind) 00318 { 00319 case WN_PRAGMA_DEFAULT_NONE: 00320 cbuf->Write_String(" none ") ; 00321 break; 00322 case WN_PRAGMA_DEFAULT_SHARED: 00323 cbuf->Write_String(" shared ") ; 00324 break; 00325 case WN_PRAGMA_DEFAULT_PRIVATE: 00326 cbuf->Write_String(" private ") ; 00327 break; 00328 default: 00329 cbuf->Write_String("<default kind??>"); 00330 break; 00331 } 00332 00333 } // W2CF_TRANSLATOR::_Default_Kind_To_String 00334 00335 00336 00337 void 00338 W2CF_TRANSLATOR::_Clause_Exprs_To_String(ANL_CBUF *cbuf, 00339 WN_PRAGMA_ID id, 00340 WN **next_clause) 00341 { 00342 BOOL first_clause = TRUE; 00343 WN *clause; 00344 00345 cbuf->Write_Char('('); 00346 for (clause = *next_clause; 00347 (clause != NULL && 00348 WN_operator(clause) == OPR_XPRAGMA && 00349 WN_pragma(clause) == id); 00350 clause = WN_next(clause)) 00351 { 00352 if (first_clause) 00353 first_clause = FALSE; 00354 else 00355 cbuf->Write_String(", "); 00356 00357 A_Pragma_Expr_To_String(cbuf, clause); 00358 } 00359 cbuf->Write_Char(')'); 00360 *next_clause = clause; 00361 } // W2CF_TRANSLATOR::_Clause_Exprs_To_String 00362 00363 00364 void 00365 W2CF_TRANSLATOR::_Rev_Clause_Exprs_To_String(ANL_CBUF *cbuf, 00366 WN_PRAGMA_ID id, 00367 WN **next_clause) 00368 { 00369 WN *first_clause = *next_clause; 00370 WN *last_clause = NULL; 00371 WN *clause; 00372 00373 for (clause = first_clause; 00374 (clause != NULL && 00375 WN_operator(clause) == OPR_XPRAGMA && 00376 WN_pragma(clause) == id); 00377 clause = WN_next(clause)) 00378 { 00379 last_clause = clause; 00380 } 00381 00382 cbuf->Write_Char('('); 00383 for (clause = last_clause; 00384 clause != NULL && clause != WN_prev(first_clause); 00385 clause = WN_prev(clause)) 00386 { 00387 if (clause != last_clause) 00388 cbuf->Write_String(", "); 00389 00390 if (id == WN_PRAGMA_ONTO && 00391 WN_operator(WN_kid0(clause)) == OPR_INTCONST && 00392 WN_const_val(WN_kid0(clause)) == 0) 00393 { 00394 cbuf->Write_Char('*'); // Special case! 00395 } 00396 else 00397 A_Pragma_Expr_To_String(cbuf, clause); 00398 } 00399 cbuf->Write_Char(')'); 00400 *next_clause = WN_next(last_clause); 00401 } // W2CF_TRANSLATOR::_Rev_Clause_Exprs_To_String 00402 00403 00404 void 00405 W2CF_TRANSLATOR::_Clause_Symbols_To_String(ANL_CBUF *cbuf, 00406 WN_PRAGMA_ID id, 00407 WN **next_clause) 00408 { 00409 BOOL first_clause = TRUE; 00410 WN *clause; 00411 00412 cbuf->Write_Char('('); 00413 for (clause = *next_clause; 00414 (clause != NULL && 00415 WN_operator(clause) == OPR_PRAGMA && 00416 WN_pragma(clause) == id); 00417 clause = WN_next(clause)) 00418 { 00419 ST * const st = WN_st(clause); 00420 00421 if (ST_class(st) != CLASS_PREG) // Pregs are not in original source 00422 { 00423 if (first_clause) 00424 first_clause = FALSE; 00425 else 00426 cbuf->Write_String(", "); 00427 00428 Original_Symname_To_String(cbuf, st); 00429 } 00430 } 00431 cbuf->Write_Char(')'); 00432 *next_clause = clause; 00433 } // W2CF_TRANSLATOR::_Clause_Symbols_To_String 00434 00435 00436 void 00437 W2CF_TRANSLATOR::_Array_Segment_To_String(ANL_CBUF *cbuf, 00438 WN_PRAGMA_ID id, 00439 WN **next_clause) 00440 { 00441 BOOL first_clause = TRUE; 00442 WN *clause; 00443 00444 cbuf->Write_Char('('); 00445 for (clause = *next_clause; 00446 (clause != NULL && 00447 WN_operator(clause) == OPR_XPRAGMA && 00448 WN_pragma(clause) == id); 00449 clause = WN_next(clause)) 00450 { 00451 ST * const st = WN_st(clause); 00452 00453 if (ST_class(st) != CLASS_PREG) // Pregs are not in original source 00454 { 00455 if (first_clause) 00456 first_clause = FALSE; 00457 else 00458 cbuf->Write_String(", "); 00459 00460 Original_Symname_To_String(cbuf, st); 00461 cbuf->Write_Char('('); 00462 if (_translate_to_c) 00463 cbuf->Write_Int(0); 00464 else 00465 cbuf->Write_Int(1); 00466 cbuf->Write_Char(':'); 00467 A_Pragma_Expr_To_String(cbuf, clause); 00468 if (_translate_to_c) 00469 { 00470 cbuf->Write_Char('-'); 00471 cbuf->Write_Int(1); 00472 } 00473 cbuf->Write_Char(')'); 00474 } 00475 } 00476 cbuf->Write_Char(')'); 00477 *next_clause = clause; 00478 } // W2CF_TRANSLATOR::_Array_Segment_To_String 00479 00480 00481 void 00482 W2CF_TRANSLATOR::_Skip_Ignored_Clauses(WN **next_clause) 00483 { 00484 BOOL skipped = TRUE; 00485 00486 while (skipped && Is_A_Pragma_Clause(*next_clause)) 00487 { 00488 if (WN_pragma_compiler_generated(*next_clause)) 00489 { 00490 *next_clause = WN_next(*next_clause); 00491 } 00492 else 00493 { 00494 switch (WN_pragma(*next_clause)) 00495 { 00496 case WN_PRAGMA_DATA_AFFINITY: 00497 case WN_PRAGMA_THREAD_AFFINITY: 00498 case WN_PRAGMA_MPNUM: 00499 case WN_PRAGMA_SYNC_DOACROSS: 00500 case WN_PRAGMA_DEFAULT: 00501 *next_clause = WN_next(*next_clause); 00502 break; 00503 default: 00504 skipped = FALSE; 00505 break; 00506 } 00507 } 00508 } 00509 } // W2CF_TRANSLATOR::_Skip_Ignored_Clauses 00510 00511 00512 // =============== Public Member Functions ================ 00513 // ======================================================== 00514 00515 W2CF_TRANSLATOR::W2CF_TRANSLATOR(WN *pu, 00516 MEM_POOL *pool, 00517 BOOL translate_to_c): 00518 _pu(pu), 00519 _pool(pool), 00520 _translate_to_c(translate_to_c) 00521 { 00522 _strbuf = CXX_NEW_ARRAY(char, _Max_W2cf_String_Size, _pool); 00523 } // W2CF_TRANSLATOR::W2CF_TRANSLATOR 00524 00525 00526 W2CF_TRANSLATOR::~W2CF_TRANSLATOR() 00527 { 00528 TY *ptr; 00529 00530 CXX_DELETE_ARRAY(_strbuf, _pool); 00531 } // W2CF_TRANSLATOR::~W2CF_TRANSLATOR 00532 00533 00534 BOOL 00535 W2CF_TRANSLATOR::Is_A_Pragma_Clause(WN *clause) const 00536 { 00537 // Always keep this in synch with ClauseList_To_String(). 00538 // 00539 BOOL predicate = (clause != NULL && 00540 (WN_operator(clause) == OPR_PRAGMA || 00541 WN_operator(clause) == OPR_XPRAGMA)); 00542 00543 if (predicate) 00544 { 00545 switch (WN_pragma(clause)) 00546 { 00547 case WN_PRAGMA_AFFINITY: 00548 case WN_PRAGMA_DATA_AFFINITY: 00549 case WN_PRAGMA_THREAD_AFFINITY: 00550 case WN_PRAGMA_CHUNKSIZE: 00551 case WN_PRAGMA_IF: 00552 case WN_PRAGMA_LASTLOCAL: 00553 case WN_PRAGMA_LOCAL: 00554 case WN_PRAGMA_MPSCHEDTYPE: 00555 case WN_PRAGMA_ORDERED: 00556 case WN_PRAGMA_REDUCTION: 00557 case WN_PRAGMA_SHARED: 00558 case WN_PRAGMA_ONTO: 00559 case WN_PRAGMA_LASTTHREAD: 00560 case WN_PRAGMA_MPNUM: 00561 case WN_PRAGMA_SYNC_DOACROSS: 00562 case WN_PRAGMA_FIRSTPRIVATE: 00563 case WN_PRAGMA_DEFAULT: 00564 break; 00565 00566 case WN_PRAGMA_NOWAIT: 00567 predicate = _translate_to_c; 00568 break; 00569 00570 default: 00571 predicate = FALSE; 00572 break; 00573 } 00574 } 00575 return predicate; 00576 } // W2CF_TRANSLATOR::Is_A_Pragma_Clause 00577 00578 00579 TY_IDX 00580 W2CF_TRANSLATOR::Get_Pointer_To(TY_IDX pointed_ty) 00581 { 00582 TY_IDX ptr = TY_pointer(pointed_ty); 00583 00584 if (ptr == NULL) 00585 { 00586 ptr = Make_Pointer_Type(pointed_ty,FALSE); 00587 } 00588 return ptr; 00589 } // W2CF_TRANSLATOR::Get_Pointer_To 00590 00591 00592 BOOL 00593 W2CF_TRANSLATOR::Whileloop_Looks_Like_Forloop(WN *stmt) const 00594 { 00595 BOOL pred = FALSE; 00596 WN * const prev_stmt = WN_prev(stmt); 00597 00598 if (_translate_to_c && 00599 (WN_operator(stmt) == OPR_DO_WHILE || 00600 WN_operator(stmt) == OPR_WHILE_DO) && 00601 prev_stmt != NULL && 00602 WN_operator(prev_stmt) == OPR_STID) 00603 { 00604 ST * const st = WN_st(prev_stmt); 00605 ANL_SRCPOS stid_srcpos(prev_stmt); 00606 ANL_SRCPOS while_srcpos(stmt); 00607 NUM_ST_REFS loads_in_test(OPR_LDID, st); 00608 NUM_ST_REFS stores_in_body(OPR_STID, st); 00609 00610 if (ST_sym_class(st) != CLASS_PREG && 00611 stid_srcpos >= while_srcpos && 00612 WN_TREE_walk_pre_order(WN_while_test(stmt), 00613 loads_in_test).num_nodes() == 1 && 00614 WN_TREE_walk_pre_order(WN_while_body(stmt), 00615 stores_in_body).num_nodes() >= 1) 00616 { 00617 pred = TRUE; 00618 } 00619 } 00620 return pred; 00621 } // W2CF_TRANSLATOR::Whileloop_Looks_Like_Forloop 00622 00623 00624 void 00625 W2CF_TRANSLATOR::Expr_To_File(ANL_FILE_MNGR *file_mngr, WN *expr) 00626 { 00627 if (_translate_to_c) 00628 { 00629 W2C_Push_PU(_pu, expr); 00630 W2C_Translate_Wn(file_mngr->File(), expr); 00631 W2C_Pop_PU(); 00632 } 00633 else 00634 { 00635 W2F_Push_PU(_pu, expr); 00636 W2F_Translate_Wn(file_mngr->File(), expr); 00637 W2F_Pop_PU(); 00638 } 00639 } // W2CF_TRANSLATOR::Expr_To_File 00640 00641 00642 void 00643 W2CF_TRANSLATOR::Expr_To_String(ANL_CBUF *cbuf, WN *expr) 00644 { 00645 if (_translate_to_c) 00646 { 00647 W2C_Push_PU(_pu, expr); 00648 W2C_Translate_Wn_Str(_strbuf, _Max_W2cf_String_Size, expr); 00649 W2C_Pop_PU(); 00650 } 00651 else 00652 { 00653 W2F_Push_PU(_pu, expr); 00654 W2F_Translate_Wn_Str(_strbuf, _Max_W2cf_String_Size, expr); 00655 W2F_Pop_PU(); 00656 } 00657 cbuf->Write_String(_strbuf); 00658 } // W2CF_TRANSLATOR::Expr_To_String 00659 00660 00661 void 00662 W2CF_TRANSLATOR::Stid_Lhs_To_String(ANL_CBUF *cbuf, 00663 ST *st, 00664 STAB_OFFSET ofst, 00665 TY_IDX ty, 00666 MTYPE mtype) 00667 { 00668 if (_translate_to_c) 00669 { 00670 W2C_Push_PU(_pu, WN_func_body(_pu)); 00671 W2C_Translate_Stid_Lhs(_strbuf, _Max_W2cf_String_Size, 00672 st, ofst, ty, mtype); 00673 W2C_Pop_PU(); 00674 } 00675 else 00676 { 00677 W2F_Push_PU(_pu, WN_func_body(_pu)); 00678 W2F_Translate_Stid_Lhs(_strbuf, _Max_W2cf_String_Size, 00679 st, ofst, ty, mtype); 00680 W2F_Pop_PU(); 00681 } 00682 cbuf->Write_String(_strbuf); 00683 } // W2CF_TRANSLATOR::Stid_Lhs_To_String 00684 00685 00686 void 00687 W2CF_TRANSLATOR::Original_Symname_To_String(ANL_CBUF *cbuf, ST *st) 00688 { 00689 // Do not use whirl2c.so or whirl2f.so, since they will not give correct 00690 // names for aliases. Aliases will be resolved to unique names with 00691 // numeric suffixes by flist and clist, but we wish to avoid that here. 00692 // 00693 if (ST_name(st) == NULL) 00694 cbuf->Write_String("<????>"); 00695 else if (_translate_to_c) 00696 cbuf->Write_String(ST_name(st)); 00697 else 00698 _Get_Ftn_Name(cbuf, st); 00699 } // W2CF_TRANSLATOR::Original_Symname_To_String 00700 00701 00702 void 00703 W2CF_TRANSLATOR::Transformed_Symname_To_String(ANL_CBUF *cbuf, ST *st) 00704 { 00705 // Express the names as whirl2f understand them 00706 // 00707 if (_translate_to_c) 00708 { 00709 W2C_Push_PU(_pu, WN_func_body(_pu)); 00710 cbuf->Write_String(W2C_Object_Name(st)); 00711 W2C_Pop_PU(); 00712 } 00713 else 00714 { 00715 W2F_Push_PU(_pu, WN_func_body(_pu)); 00716 cbuf->Write_String(W2F_Object_Name(st)); 00717 W2F_Pop_PU(); 00718 } 00719 } // W2CF_TRANSLATOR::Transformed_Symname_To_String 00720 00721 void 00722 W2CF_TRANSLATOR::A_Pragma_Expr_To_String(ANL_CBUF *cbuf, WN *apragma) 00723 { 00724 if (_Is_Ptr_Expr(WN_kid0(apragma))) 00725 { 00726 TY_IDX pointed = _Get_Expr_Pointed_Ty(WN_kid0(apragma)); 00727 TY_IDX pointer = Get_Pointer_To(pointed); 00728 _Istore_Lhs_To_String(cbuf, WN_kid0(apragma), 0 /*offset*/, 00729 pointer, TY_mtype(pointed)); 00730 } 00731 else 00732 { 00733 Expr_To_String(cbuf, WN_kid0(apragma)); 00734 } 00735 } // W2CF_TRANSLATOR::A_Pragma_Expr_To_String 00736 00737 void 00738 W2CF_TRANSLATOR::ClauseList_To_String(ANL_CBUF *cbuf, WN **clause_list) 00739 { 00740 // PRECONDITION: clause == OPR_PRAGMA or OPR_XPRAGMA node. 00741 // 00742 // Translate the given sequence of clauses into C or Fortran 00743 // (modelled after wn2f_pragma.c). 00744 // 00745 // 00746 WN *this_clause; 00747 WN *next_clause = *clause_list; 00748 00749 _Skip_Ignored_Clauses(&next_clause); 00750 while (Is_A_Pragma_Clause(next_clause)) 00751 { 00752 this_clause = next_clause; 00753 00754 // Should have been skipped by _Skip_Ignored_Clauses() 00755 // 00756 Is_True(!WN_pragma_compiler_generated(next_clause), 00757 ("Attempt to emit compiler generated clause in " 00758 "W2CF_TRANSLATOR::ClauseList_To_String")); 00759 00760 switch (WN_pragma(next_clause)) 00761 { 00762 case WN_PRAGMA_DATA_AFFINITY: 00763 case WN_PRAGMA_THREAD_AFFINITY: 00764 case WN_PRAGMA_MPNUM: 00765 case WN_PRAGMA_SYNC_DOACROSS: 00766 case WN_PRAGMA_DEFAULT: 00767 // Should have been skipped by _Skip_Ignored_Clauses(). 00768 // 00769 Is_True(FALSE, 00770 ("Unexpected case in " 00771 "W2CF_TRANSLATOR::ClauseList_To_String")); 00772 break; 00773 00774 case WN_PRAGMA_NOWAIT: 00775 cbuf->Write_String("nowait"); 00776 next_clause = WN_next(next_clause); 00777 break; 00778 00779 case WN_PRAGMA_AFFINITY: 00780 cbuf->Write_String("affinity"); 00781 _Clause_Exprs_To_String(cbuf, WN_PRAGMA_AFFINITY, &next_clause); 00782 cbuf->Write_String(" = "); 00783 if (WN_pragma(next_clause) == WN_PRAGMA_DATA_AFFINITY) 00784 cbuf->Write_String("data"); 00785 else if (WN_pragma(next_clause) == WN_PRAGMA_THREAD_AFFINITY) 00786 cbuf->Write_String("thread"); 00787 else 00788 cbuf->Write_String("<unknown_affinity??>"); 00789 00790 // Process the expression associated with the thread/data affinity 00791 // pragma. 00792 // 00793 cbuf->Write_String("\"("); 00794 A_Pragma_Expr_To_String(cbuf, next_clause); 00795 cbuf->Write_String(")\""); 00796 next_clause = WN_next(next_clause); 00797 break; 00798 00799 case WN_PRAGMA_CHUNKSIZE: 00800 cbuf->Write_String("chunk="); 00801 _Clause_Exprs_To_String(cbuf, 00802 (WN_PRAGMA_ID)WN_pragma(next_clause), 00803 &next_clause); 00804 break; 00805 00806 case WN_PRAGMA_IF: 00807 cbuf->Write_String("if"); 00808 _Clause_Exprs_To_String(cbuf, 00809 (WN_PRAGMA_ID)WN_pragma(next_clause), 00810 &next_clause); 00811 break; 00812 00813 case WN_PRAGMA_LASTLOCAL: 00814 cbuf->Write_String("lastlocal"); 00815 _Clause_Symbols_To_String(cbuf, 00816 (WN_PRAGMA_ID)WN_pragma(next_clause), 00817 &next_clause); 00818 break; 00819 00820 case WN_PRAGMA_LOCAL: 00821 cbuf->Write_String("local"); 00822 if (WN_operator(next_clause) == OPR_XPRAGMA) 00823 { 00824 _Array_Segment_To_String(cbuf, 00825 (WN_PRAGMA_ID)WN_pragma(next_clause), 00826 &next_clause); 00827 } 00828 else 00829 { 00830 _Clause_Symbols_To_String(cbuf, 00831 (WN_PRAGMA_ID)WN_pragma(next_clause), 00832 &next_clause); 00833 } 00834 break; 00835 00836 case WN_PRAGMA_MPSCHEDTYPE: 00837 /* Can be both a clause and a pragma */ 00838 cbuf->Write_String("mp_schedtype = "); 00839 _Mp_Schedtype_To_String(cbuf, 00840 (WN_PRAGMA_SCHEDTYPE_KIND)WN_pragma_arg1(next_clause)); 00841 break; 00842 00843 case WN_PRAGMA_ORDERED: 00844 cbuf->Write_String("(ordered)"); 00845 break; 00846 00847 case WN_PRAGMA_REDUCTION: 00848 cbuf->Write_String("reduction"); 00849 if (WN_operator(next_clause) == OPR_XPRAGMA) 00850 _Clause_Exprs_To_String(cbuf, 00851 (WN_PRAGMA_ID)WN_pragma(next_clause), 00852 &next_clause); 00853 else 00854 _Clause_Symbols_To_String(cbuf, 00855 (WN_PRAGMA_ID)WN_pragma(next_clause), 00856 &next_clause); 00857 break; 00858 00859 case WN_PRAGMA_SHARED: 00860 cbuf->Write_String("shared"); 00861 _Clause_Symbols_To_String(cbuf, 00862 (WN_PRAGMA_ID)WN_pragma(next_clause), 00863 &next_clause); 00864 break; 00865 00866 case WN_PRAGMA_ONTO: 00867 cbuf->Write_String("onto"); 00868 _Rev_Clause_Exprs_To_String(cbuf, 00869 (WN_PRAGMA_ID)WN_pragma(next_clause), 00870 &next_clause); 00871 break; 00872 00873 case WN_PRAGMA_LASTTHREAD: 00874 cbuf->Write_String("lastthread"); 00875 _Clause_Symbols_To_String(cbuf, 00876 (WN_PRAGMA_ID)WN_pragma(next_clause), 00877 &next_clause); 00878 break; 00879 00880 case WN_PRAGMA_FIRSTPRIVATE: 00881 cbuf->Write_String("firstprivate"); 00882 _Clause_Symbols_To_String(cbuf, 00883 (WN_PRAGMA_ID)WN_pragma(next_clause), 00884 &next_clause); 00885 break; 00886 00887 // case WN_PRAGMA_DEFAULT: 00888 // the .anl file doesn't need the string just now. 00889 // 00890 // cbuf->Write_String("default"); 00891 // _Default_Kind_To_String(cbuf, 00892 // (WN_PRAGMA_DEFAULT_KIND)WN_pragma_arg1(next_clause)); 00893 // break; 00894 00895 default: 00896 // This should never occur! 00897 // 00898 break; 00899 00900 } // switch 00901 00902 if (this_clause == next_clause) 00903 next_clause = WN_next(this_clause); // Avoid inifinite loop 00904 00905 _Skip_Ignored_Clauses(&next_clause); 00906 if (Is_A_Pragma_Clause(next_clause)) 00907 cbuf->Write_String(", "); // separate by commas 00908 } // while there are more pragma clauses 00909 00910 *clause_list = next_clause; // Indicate how many clauses we have processed 00911 00912 } // W2CF_TRANSLATOR::ClauseList_To_String 00913 00914 00915 void 00916 W2CF_TRANSLATOR::Nest_Clauses_To_String(ANL_CBUF *cbuf, 00917 WN *nest_region, 00918 INT nest_levels) 00919 { 00920 // We need to get index variables for "nest_levels" number 00921 // of DO loops, and emit the corresponding "nest" clause. 00922 // 00923 WN *next_stmt = nest_region; 00924 WN_PRAGMA_ID nest_kind = WN_PRAGMA_UNDEFINED; 00925 00926 if (next_stmt == NULL || 00927 WN_operator(next_stmt) != OPR_REGION || 00928 WN_first(WN_region_pragmas(next_stmt)) == NULL) 00929 Anl_Diag->Error("Unexpected do-nest in PROMPF!!"); 00930 else 00931 nest_kind = 00932 (WN_PRAGMA_ID)WN_pragma(WN_first(WN_region_pragmas(next_stmt))); 00933 00934 cbuf->Write_String("nest("); 00935 for (INT nest = 1; nest <= nest_levels; nest++) 00936 { 00937 if (WN_operator(next_stmt) != OPR_REGION || 00938 WN_first(WN_region_pragmas(next_stmt)) == NULL || 00939 WN_pragma(WN_first(WN_region_pragmas(next_stmt))) != nest_kind) 00940 Anl_Diag->Error("Unexpected do-nest in PROMPF!!"); 00941 00942 // Get the next nested loop, assuming next_stmt at this point 00943 // refers to a region. 00944 // 00945 next_stmt = WN_first(WN_region_body(next_stmt)); 00946 while (WN_operator(next_stmt) != OPR_DO_LOOP) 00947 next_stmt = WN_next(next_stmt); 00948 00949 // Write out the index variable. 00950 // 00951 Original_Symname_To_String(cbuf, WN_st(WN_index(next_stmt))); 00952 00953 // Emit separator, and search for the next nested region, if 00954 // any is expected. 00955 // 00956 if (nest < nest_levels) 00957 { 00958 cbuf->Write_Char(','); 00959 00960 next_stmt = WN_first(WN_do_body(next_stmt)); 00961 while (next_stmt != NULL && WN_operator(next_stmt) != OPR_REGION) 00962 next_stmt = WN_next(next_stmt); 00963 00964 if (next_stmt == NULL || 00965 WN_operator(next_stmt) != OPR_REGION || 00966 WN_first(WN_region_pragmas(next_stmt)) == NULL || 00967 WN_pragma(WN_first(WN_region_pragmas(next_stmt))) != nest_kind) 00968 Anl_Diag->Error("Unexpected do-nest in PROMPF!!"); 00969 } 00970 } 00971 cbuf->Write_Char(')'); 00972 } // W2CF_TRANSLATOR::ClauseList_To_String 00973 00974 00975 void 00976 W2CF_TRANSLATOR::Prefetch_Attributes_To_String(ANL_CBUF *cbuf, 00977 WN *prefetch, 00978 INT32 size) 00979 { 00980 INT pflag = WN_prefetch_flag(prefetch); 00981 00982 // Emit memory reference 00983 // 00984 cbuf->Write_Char('='); 00985 if (_Is_Ptr_Expr(WN_kid0(prefetch))) 00986 { 00987 TY_IDX pointed = _Get_Expr_Pointed_Ty(WN_kid0(prefetch)); 00988 TY_IDX pointer = Get_Pointer_To(pointed); 00989 00990 _Istore_Lhs_To_String(cbuf, WN_kid0(prefetch), 0 /*offset*/, 00991 pointer, TY_mtype(pointed)); 00992 } 00993 else 00994 Expr_To_String(cbuf, WN_kid0(prefetch)); 00995 00996 // Emit stride and level clauses 00997 // 00998 cbuf->Write_Char(','); 00999 if (PF_GET_STRIDE_1L(pflag) > 0) 01000 { 01001 if (PF_GET_STRIDE_2L(pflag) > 0) 01002 { 01003 cbuf->Write_String("stride="); 01004 cbuf->Write_Int(PF_GET_STRIDE_1L(pflag)); 01005 cbuf->Write_Char(','); 01006 cbuf->Write_Int(PF_GET_STRIDE_2L(pflag)); 01007 cbuf->Write_Char(','); 01008 cbuf->Write_String("level=1,2"); 01009 } 01010 else 01011 { 01012 cbuf->Write_String("stride="); 01013 cbuf->Write_Int(PF_GET_STRIDE_1L(pflag)); 01014 cbuf->Write_Char(','); 01015 cbuf->Write_String("level=1"); 01016 } 01017 } 01018 else if (PF_GET_STRIDE_2L(pflag) > 0) 01019 { 01020 cbuf->Write_String("stride="); 01021 cbuf->Write_Int(PF_GET_STRIDE_2L(pflag)); 01022 cbuf->Write_Char(','); 01023 cbuf->Write_String("level=,2"); 01024 } 01025 else 01026 { 01027 cbuf->Write_String("stride=,level="); 01028 } 01029 01030 // Emit a kind clause 01031 // 01032 cbuf->Write_Char(','); 01033 if (PF_GET_READ(pflag)) 01034 cbuf->Write_String("kind=rd"); 01035 else 01036 cbuf->Write_String("kind=wr"); 01037 01038 // Emit a size clause 01039 // 01040 if (size > 0) 01041 { 01042 cbuf->Write_Char(','); 01043 cbuf->Write_String("size="); 01044 cbuf->Write_Int(size); 01045 } 01046 } // W2CF_TRANSLATOR::Prefetch_Attributes_To_String 01047