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 "anl_common.h" 00039 #include "anl_diagnostics.h" // For warnings and errors 00040 #include "anl_file_mngr.h" // For managing files 00041 #include "w2cf_translator.h" // For translating WHIRL into high-level-language 00042 #include "anl_varlist.h" // For emitting attributes of symbol references 00043 #include "anl_pragma_attribute.h" // For <dir> entries 00044 #include "anl_func_entry.h" 00045 #include "anl_pragma_construct.h" 00046 00047 extern ANL_DIAGNOSTICS *Anl_Diag; // Defined in anl_driver.cxx 00048 00049 00050 // ================ Class Utility Functions =============== 00051 // ======================================================== 00052 00053 BOOL 00054 ANL_PRAGMA_CONSTRUCT::Is_ProMpf_Pragma_Construct(WN *stmt) 00055 { 00056 BOOL predicate = (stmt != NULL && 00057 (WN_operator(stmt) == OPR_PRAGMA || 00058 WN_operator(stmt) == OPR_XPRAGMA)); 00059 00060 if (predicate) 00061 switch (WN_pragma(stmt)) 00062 { 00063 00064 case WN_PRAGMA_SECTION: 00065 case WN_PRAGMA_BARRIER: 00066 case WN_PRAGMA_CRITICAL_SECTION_BEGIN: 00067 case WN_PRAGMA_ORDERED_BEGIN: 00068 case WN_PRAGMA_ATOMIC: 00069 break; 00070 00071 default: 00072 predicate = FALSE; 00073 break; 00074 } 00075 return predicate; 00076 } // ANL_PRAGMA_CONSTRUCT::Is_ProMpf_Pragma_Construct 00077 00078 00079 BOOL 00080 ANL_PRAGMA_CONSTRUCT::Is_Valid_Dir(ANL_PRAGMA_ATTRIBUTE *dir, 00081 INT32 construct_level) 00082 { 00083 return dir->Is_Pragma_Construct_Attribute(construct_level); 00084 } 00085 00086 00087 // =============== Private Member Functions =============== 00088 // ======================================================== 00089 00090 00091 // Is there an end of construct marker ie: a pragma, available? 00092 // if called with a context of 'for_id', it implies _pragma_end 00093 // may be given an ID & must be an end of construct marker to get 00094 // a T result. If it's just for evaluating a line number, then 00095 // for_id is FALSE and T may be returned on the grounds _pragma_end 00096 // is just a line marker. for_id matters only for ATOMIC, just now. 00097 00098 BOOL 00099 ANL_PRAGMA_CONSTRUCT::_End_Is_Part_Of_Construct(BOOL for_id) 00100 { 00101 // PRECONDITION: Must have done _Find_Pragma_End_Stmt() 00102 // 00103 BOOL predicate; 00104 00105 if (_pragma_end != NULL) 00106 { 00107 switch (_pragma_kind) 00108 { 00109 case ANL_SECTION_PRAGMA: 00110 predicate = FALSE; 00111 break; 00112 00113 case ANL_BARRIER_PRAGMA: 00114 predicate = TRUE; // _pragma_end == _pragma_begin 00115 break; 00116 00117 case ANL_ATOMIC_PRAGMA: 00118 predicate = !for_id; 00119 break; 00120 00121 case ANL_CRITICAL_SECTION_PRAGMA: 00122 predicate = 00123 (WN_pragma(_pragma_end) == WN_PRAGMA_CRITICAL_SECTION_END); 00124 break; 00125 00126 case ANL_ORDERED_PRAGMA: 00127 predicate = 00128 (WN_pragma(_pragma_end) == WN_PRAGMA_ORDERED_END); 00129 break; 00130 00131 default: 00132 predicate = FALSE; 00133 break; 00134 } 00135 } 00136 else // (_pragma_end == NULL) 00137 { 00138 predicate = FALSE; 00139 } 00140 return predicate; 00141 } // ANL_PRAGMA_CONSTRUCT::_End_Is_Part_Of_Construct 00142 00143 00144 void 00145 ANL_PRAGMA_CONSTRUCT::_Find_Pragma_End_Stmt() 00146 { 00147 // We allow two ways of ending a pragma delimited region 00148 // of statements. This function finds any such statement, returns 00149 // "pragma_begin" if not applicable (e.g. for BARRIER), and NULL if 00150 // none is found. The exact values returned here have consequences 00151 // for the algorithms used elsewhere (w.g. for _Get_Max_Construct_Srcpos). 00152 // 00153 WN_PRAGMA_ID end_id[2] = {WN_PRAGMA_UNDEFINED, 00154 WN_PRAGMA_UNDEFINED}; 00155 00156 BOOL search_loop = (_pragma_end != _pragma_begin) ; 00157 00158 switch (_pragma_kind) 00159 { 00160 00161 case ANL_SECTION_PRAGMA: 00162 end_id[0] = WN_PRAGMA_SECTION; 00163 end_id[1] = WN_PRAGMA_PSECTION_END; 00164 break; 00165 00166 case ANL_BARRIER_PRAGMA: 00167 _pragma_end = _pragma_begin; // Does not bracket any statements. 00168 search_loop = FALSE; 00169 break; 00170 00171 case ANL_ATOMIC_PRAGMA: 00172 _pragma_end = WN_next(_pragma_begin); 00173 _pr_end_part_of_body = TRUE; 00174 search_loop = FALSE; 00175 break ; 00176 00177 case ANL_CRITICAL_SECTION_PRAGMA: 00178 end_id[0] = WN_PRAGMA_CRITICAL_SECTION_END; 00179 break; 00180 00181 case ANL_ORDERED_PRAGMA: 00182 end_id[0] = WN_PRAGMA_ORDERED_END; 00183 break; 00184 00185 default: 00186 Anl_Diag->Error("Unexpected pragma in _Find_Pragma_End_Stmt()!!"); 00187 break; 00188 } 00189 00190 if (search_loop) 00191 { 00192 // Search for a pragma that matches the expected END pragma, 00193 // or end up with (pragma_end == NULL) when none is found. 00194 // 00195 WN *stmt; 00196 00197 for (stmt = WN_next(_pragma_begin); 00198 (stmt != NULL && 00199 !((WN_operator(stmt) == OPR_PRAGMA || 00200 WN_operator(stmt) == OPR_XPRAGMA) && 00201 (WN_pragma(stmt) == end_id[0] || 00202 WN_pragma(stmt) == end_id[1]))); 00203 stmt = WN_next(stmt)); 00204 _pragma_end = stmt; 00205 } 00206 } // ANL_PRAGMA_CONSTRUCT::_Find_Pragma_End_Stmt 00207 00208 00209 void 00210 ANL_PRAGMA_CONSTRUCT::_Get_Max_Construct_Srcpos(ANL_SRCPOS *max) 00211 { 00212 ANL_SRCPOS min(_pragma_begin); 00213 00214 *max = ANL_SRCPOS(_pragma_begin); 00215 for (WN *stmt = _pragma_begin; 00216 stmt != _pragma_end; 00217 stmt = WN_next(stmt)) 00218 { 00219 Adjust_Srcpos_Range(stmt, &min, max); 00220 } 00221 00222 if (_End_Is_Part_Of_Construct(FALSE)) 00223 Adjust_Srcpos_Range(_pragma_end, &min, max); 00224 } // ANL_PRAGMA_CONSTRUCT::_Get_Max_Construct_Srcpos 00225 00226 00227 void 00228 ANL_PRAGMA_CONSTRUCT::_Write_Pragma_Directives(ANL_CBUF *cbuf) 00229 { 00230 WN *next_stmt = WN_next(_pragma_begin); 00231 ANL_CBUF clause_list(_pool); 00232 ANL_SRCPOS begin_pos; 00233 ANL_SRCPOS begin_extent; 00234 ANL_SRCPOS end_pos; 00235 00236 // Some preliminiaries. 00237 // 00238 _Get_Max_Construct_Srcpos(&end_pos); 00239 _func_entry->Get_Pragma_Srcpos_Range(_pragma_begin, 00240 &begin_pos, &begin_extent); 00241 00242 clause_list.Write_Char(' '); 00243 _func_entry->Pu_Translator()-> 00244 ClauseList_To_String(&clause_list, &next_stmt); 00245 00246 // The idir clause. 00247 // 00248 cbuf->Write_String("idir "); 00249 cbuf->Write_Int(_id); 00250 cbuf->Write_Char(' '); 00251 begin_pos.Write(cbuf); 00252 cbuf->Write_Char('-'); 00253 begin_extent.Write(cbuf); 00254 00255 cbuf->Append_Pragma_Preamble((BOOL) WN_pragma_omp(_pragma_begin),FALSE); 00256 00257 switch (_pragma_kind) 00258 { 00259 case ANL_SECTION_PRAGMA: 00260 cbuf->Write_String("SECTION "); 00261 break; 00262 case ANL_BARRIER_PRAGMA: 00263 cbuf->Write_String("BARRIER "); 00264 break; 00265 case ANL_CRITICAL_SECTION_PRAGMA: 00266 cbuf->Write_String("CRITICAL SECTION "); 00267 if (WN_operator(_pragma_begin) == OPR_XPRAGMA) 00268 { 00269 cbuf->Write_Char('('); 00270 _func_entry->Pu_Translator()-> 00271 A_Pragma_Expr_To_String(cbuf, _pragma_begin); 00272 cbuf->Write_Char(')'); 00273 } 00274 else if (WN_st(_pragma_begin) != NULL) 00275 { 00276 /* 00277 * In OMP code the pragma has a string const ST 00278 * whose value is the name of the locking varbl. 00279 */ 00280 00281 ST * st = WN_st( _pragma_begin); 00282 if (ST_class(st) == CLASS_CONST) 00283 { 00284 cbuf->Write_Char('('); 00285 cbuf->Write_String(Targ_String_Address(STC_val(st))); 00286 cbuf->Write_Char(')'); 00287 } 00288 } 00289 cbuf->Write_Char(' '); 00290 break; 00291 case ANL_ORDERED_PRAGMA: 00292 cbuf->Write_String("ORDERED "); 00293 break; 00294 case ANL_ATOMIC_PRAGMA: 00295 cbuf->Write_String("ATOMIC "); 00296 break; 00297 default: 00298 cbuf->Write_String("<WHATPRAGMA??> "); 00299 break; 00300 } 00301 cbuf->Write_String(clause_list.Chars()); 00302 cbuf->Write_String("\n"); 00303 00304 if (_pragma_end != _pragma_begin && 00305 _End_Is_Part_Of_Construct(TRUE) && 00306 !_func_entry->Pu_Translator()->Language_is_C()) 00307 { 00308 cbuf->Write_String("edir "); 00309 cbuf->Write_Int(_id); 00310 cbuf->Write_String(" "); 00311 end_pos.Write(cbuf); 00312 00313 cbuf->Append_Pragma_Preamble((BOOL) WN_pragma_omp(_pragma_begin),FALSE); 00314 00315 switch (_pragma_kind) 00316 { 00317 case ANL_CRITICAL_SECTION_PRAGMA: 00318 cbuf->Write_String("END CRITICAL SECTION\n"); 00319 break; 00320 case ANL_ORDERED_PRAGMA: 00321 cbuf->Write_String("END_ORDERED\n"); 00322 break; 00323 case ANL_ATOMIC_PRAGMA: 00324 cbuf->Write_String("END ATOMIC\n"); 00325 break; 00326 00327 default: 00328 cbuf->Write_String("<WHAT_PRAGMA_END??>\n"); 00329 break; 00330 } 00331 } 00332 } // ANL_PRAGMA_CONSTRUCT::_Write_Pragma_Directives 00333 00334 00335 // =============== Public Member Functions ================ 00336 // ======================================================== 00337 00338 00339 ANL_PRAGMA_CONSTRUCT::ANL_PRAGMA_CONSTRUCT(WN *pragma_begin, 00340 INT32 construct_level, 00341 ANL_FUNC_ENTRY *func_entry, 00342 MEM_POOL *pool): 00343 _pragma_begin(pragma_begin), 00344 _construct_level(construct_level), 00345 _pragma_end((WN *)-1), // To catch errors 00346 _pr_end_part_of_body(FALSE), 00347 _func_entry(func_entry), 00348 _pool(pool) 00349 { 00350 _is_omp = FALSE ; 00351 00352 if (WN_operator(pragma_begin) == OPR_PRAGMA || 00353 WN_operator(pragma_begin) == OPR_XPRAGMA) 00354 { 00355 _is_omp = WN_pragma_omp(pragma_begin); 00356 00357 switch (WN_pragma(pragma_begin)) 00358 { 00359 case WN_PRAGMA_SECTION: 00360 _pragma_kind = ANL_SECTION_PRAGMA; 00361 break; 00362 case WN_PRAGMA_BARRIER: 00363 _pragma_kind = ANL_BARRIER_PRAGMA; 00364 break; 00365 case WN_PRAGMA_CRITICAL_SECTION_BEGIN: 00366 _pragma_kind = ANL_CRITICAL_SECTION_PRAGMA; 00367 break; 00368 case WN_PRAGMA_ORDERED_BEGIN: 00369 _pragma_kind = ANL_ORDERED_PRAGMA; 00370 break; 00371 case WN_PRAGMA_ATOMIC: 00372 _pragma_kind = ANL_ATOMIC_PRAGMA; 00373 break; 00374 default: 00375 _pragma_kind = ANL_UNKNOWN_PRAGMA; 00376 break; 00377 } 00378 _id = _func_entry->Next_Construct_Id()->Post_Incr(); 00379 func_entry->Set_Construct_Id(pragma_begin, _id); 00380 00381 _Find_Pragma_End_Stmt(); 00382 if (_End_Is_Part_Of_Construct(TRUE)) 00383 func_entry->Set_Construct_Id(_pragma_end, _id); 00384 } 00385 else 00386 { 00387 _pragma_kind = ANL_UNKNOWN_PRAGMA; 00388 _id = -1; 00389 } 00390 } // ANL_PRAGMA_CONSTRUCT::ANL_PRAGMA_CONSTRUCT 00391 00392 00393 WN * 00394 ANL_PRAGMA_CONSTRUCT::Next_Stmt() 00395 { 00396 WN *next; 00397 00398 if (_End_Is_Part_Of_Construct(TRUE)) 00399 next = WN_next(_pragma_end); 00400 else 00401 next = _pragma_end; 00402 return next; 00403 } // ANL_PRAGMA_CONSTRUCT::Next_Stmt 00404 00405 00406 void 00407 ANL_PRAGMA_CONSTRUCT::Write(ANL_CBUF *cbuf) 00408 { 00409 if (_pragma_kind != ANL_UNKNOWN_PRAGMA) 00410 { 00411 ANL_CBUF varlist_cbuf(_pool); 00412 ANL_CBUF nested_cbuf(_pool); 00413 ANL_SRCPOS min_srcpos(_pragma_begin); 00414 ANL_SRCPOS max_srcpos; 00415 ANL_VARLIST varlist(_pool, _func_entry); 00416 WN *stmt; 00417 00418 // Write out the pragma construct header 00419 // 00420 _Get_Max_Construct_Srcpos(&max_srcpos); 00421 cbuf->Append_Pragma_Preamble(_is_omp,TRUE); 00422 00423 switch (_pragma_kind) 00424 { 00425 case ANL_SECTION_PRAGMA: 00426 cbuf->Write_String("section "); 00427 cbuf->Write_Int(_id); 00428 cbuf->Write_String(" \"parallel subsection\""); 00429 break; 00430 case ANL_BARRIER_PRAGMA: 00431 cbuf->Write_String("barrier "); 00432 cbuf->Write_Int(_id); 00433 cbuf->Write_String(" \"barrier\""); 00434 break; 00435 case ANL_CRITICAL_SECTION_PRAGMA: 00436 cbuf->Write_String("critsect "); 00437 cbuf->Write_Int(_id); 00438 cbuf->Write_String(" \""); 00439 if (WN_operator(_pragma_begin) == OPR_XPRAGMA) 00440 { 00441 _func_entry->Pu_Translator()-> 00442 A_Pragma_Expr_To_String(cbuf, _pragma_begin); 00443 } 00444 cbuf->Write_Char('\"'); 00445 break; 00446 case ANL_ORDERED_PRAGMA: 00447 cbuf->Write_String("ordered "); 00448 cbuf->Write_Int(_id); 00449 cbuf->Write_String(" \"sequential section\""); 00450 break; 00451 case ANL_ATOMIC_PRAGMA: 00452 cbuf->Write_String("atomic "); 00453 cbuf->Write_Int(_id); 00454 cbuf->Write_String(" \"atomic store\""); 00455 break; 00456 default: 00457 cbuf->Write_String("<WHATPRAGMA??> "); 00458 cbuf->Write_Int(_id); 00459 cbuf->Write_String(" \"???\""); 00460 break; 00461 } 00462 cbuf->Write_String(" range "); 00463 min_srcpos.Write(cbuf); 00464 cbuf->Write_Char('-'); 00465 max_srcpos.Write(cbuf); 00466 cbuf->Write_Char('\n'); 00467 00468 // Write out the region directives 00469 // 00470 _Write_Pragma_Directives(cbuf); 00471 00472 // Determine variable references within the statements belonging to the 00473 // loop, and write them out to a temporary buffer. Sometimes (atomic) 00474 // need to look at _pragma_end too. 00475 00476 for (stmt = _pragma_begin; stmt != _pragma_end; stmt = WN_next(stmt)) 00477 { 00478 varlist.Insert_Var_Refs(stmt); 00479 } 00480 if (_pr_end_part_of_body) 00481 varlist.Insert_Var_Refs(stmt); 00482 00483 varlist.Write(&varlist_cbuf, _id); 00484 varlist_cbuf.Write_Char('\n'); 00485 00486 // Write nested constructs to temporary buffer 00487 // 00488 if (_End_Is_Part_Of_Construct(FALSE)) 00489 stmt = _pragma_end; 00490 else 00491 for (stmt = _pragma_begin; 00492 WN_next(stmt) != _pragma_end; 00493 stmt = WN_next(stmt)); 00494 _func_entry->Emit_Nested_Original_Constructs(&nested_cbuf, 00495 WN_next(_pragma_begin), 00496 stmt); 00497 00498 // Write out any applicable <dir> entries (i.e. those that were 00499 // not attributed to nested constructs). 00500 // 00501 _func_entry-> 00502 Emit_Dir_Entries(cbuf, _id, _construct_level, 00503 &ANL_PRAGMA_CONSTRUCT::Is_Valid_Dir); 00504 00505 // Write the varlist and nested constructs. 00506 // 00507 if (varlist_cbuf.Size() > 0) 00508 cbuf->Write_String(varlist_cbuf.Chars()); 00509 if (nested_cbuf.Size() > 0) 00510 cbuf->Write_String(nested_cbuf.Chars()); 00511 00512 // Finish writing the construct descriptor 00513 // 00514 cbuf->Append_Pragma_Preamble(_is_omp,TRUE); 00515 switch (_pragma_kind) 00516 { 00517 case ANL_SECTION_PRAGMA: 00518 cbuf->Write_String("end_section "); 00519 break; 00520 case ANL_BARRIER_PRAGMA: 00521 cbuf->Write_String("end_barrier "); 00522 break; 00523 case ANL_CRITICAL_SECTION_PRAGMA: 00524 cbuf->Write_String("end_critsect "); 00525 break; 00526 case ANL_ORDERED_PRAGMA: 00527 cbuf->Write_String("end_ordered "); 00528 break; 00529 case ANL_ATOMIC_PRAGMA: 00530 cbuf->Write_String("end_atomic "); 00531 break; 00532 default: 00533 cbuf->Write_String("<ENDWHATPRAGMA??> \"???\" "); 00534 break; 00535 } 00536 cbuf->Write_Int(_id); 00537 cbuf->Write_String("\n"); // Start next construct on a new line 00538 } 00539 } // ANL_PRAGMA_CONSTRUCT::Write 00540