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 /* ==================================================================== 00037 * ==================================================================== 00038 * 00039 * 00040 * Revision history: 00041 * 12-Aug-96 - Original Version 00042 * 00043 * Description: 00044 * 00045 * Translate a pragma WN node to Fortran! The corresponding header 00046 * declaration for for WN2F_pragma() can be found in wn2f_pragma.h. 00047 * 00048 * ==================================================================== 00049 * ==================================================================== 00050 */ 00051 00052 #ifdef _KEEP_RCS_ID 00053 /*REFERENCED*/ 00054 #endif 00055 00056 #include <cctype> 00057 #include <algorithm> 00058 00059 #include "alloca.h" 00060 #include "whirl2f_common.h" 00061 #include "w2cf_parentize.h" /* For W2CF_Get_Parent */ 00062 #include "const.h" /* For FOR_ALL_CONSTANTS */ 00063 #include "pf_cg.h" 00064 #include "PUinfo.h" /* In be/whirl2c directory */ 00065 #include "wn2f.h" 00066 #include "st2f.h" 00067 #include "ty2f.h" 00068 #include "tcon2f.h" 00069 #include "wn2f_pragma.h" 00070 #include "wn2f_stmt.h" 00071 00072 extern BOOL Run_w2fc_early; /* Defined in be.so */ 00073 extern WN_MAP *W2F_Construct_Map; /* Defined in w2f_driver.c */ 00074 extern BOOL W2F_Prompf_Emission; /* Defined in w2f_driver.c */ 00075 extern BOOL W2F_Emit_Omp; /* Emitting OMP spellings of pragmas */ 00076 00077 const std::string filePragma("file_start"); 00078 00079 extern void WN2F_Append_Purple_Funcinfo(TOKEN_BUFFER tokens); 00080 /* from wn2f_stmt.c */ 00081 00082 #define WN_pragma_nest(wn) WN_pragma_arg1(wn) 00083 #define WN_max_nest_level(wn) WN_pragma_arg2(wn) 00084 #define WN_mp_schedtype(wn) (WN_PRAGMA_SCHEDTYPE_KIND)WN_pragma_arg1(wn) 00085 00086 #define EMIT_ARG_NUMBERS1(tokens, val1) \ 00087 Append_Arg_Numbers((tokens), (val1), -1) 00088 00089 #define EMIT_ARG_NUMBERS2(tokens, val1, val2) \ 00090 Append_Arg_Numbers((tokens), (val1), (val2)) 00091 00092 #define PARENTHESIZE_ARG_NUMBERS1(tokens, val1) \ 00093 Append_Token_Special((tokens), '('); \ 00094 EMIT_ARG_NUMBERS1((tokens), (val1)); \ 00095 Append_Token_Special((tokens), ')') 00096 00097 #define PARENTHESIZE_ARG_NUMBERS2(tokens, val1, val2) \ 00098 Append_Token_Special((tokens), '('); \ 00099 EMIT_ARG_NUMBERS2((tokens), (val1), (val2)); \ 00100 Append_Token_Special((tokens), ')') 00101 00102 00103 typedef struct Array_Distribution 00104 { 00105 INT current_dimension; /* Enumerated dimension number in C order */ 00106 WN *base; /* PRAGMA starting description of this dimension */ 00107 WN *cyclic_expr; /* XPRAGMA holding a cyclic expression (or NULL) */ 00108 WN *dimension_bound; /* XPRAGMA holding the bounds expression */ 00109 } ARRAY_DISTRIBUTION; 00110 00111 00112 #define MAX_PRAGMAS_TO_SKIP 50 00113 static struct Set_Of_Pragmas_To_Skip 00114 { 00115 INT start, end; 00116 WN *array[MAX_PRAGMAS_TO_SKIP]; 00117 } Pragmas_To_Skip = {0, 0, 00118 {NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, 00119 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, 00120 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, 00121 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, 00122 NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL}}; 00123 00124 00125 typedef struct Local_Preg /* Used in Get_Implicit_Locals() */ 00126 { 00127 ST * st; 00128 PREG_IDX preg_idx; 00129 } LOCAL_PREG; 00130 00131 00132 static WN * WN2F_Prompf_Subsection = NULL; 00133 00134 00135 /* ======================= Prompf utilities ======================= */ 00136 /* ================================================================ */ 00137 00138 inline BOOL 00139 WN2F_is_omp(const WN *pragma) 00140 { 00141 return (WN_pragma_omp(pragma) || 00142 (W2F_Emit_Omp && WN_pragma_compiler_generated(pragma))); 00143 } 00144 00145 static void 00146 WN2F_Start_Prompf_Construct(TOKEN_BUFFER tokens, WN *pragma) 00147 { 00148 INT32 construct_id = WN_MAP32_Get(*W2F_Construct_Map, pragma); 00149 00150 Append_F77_Directive_Newline(tokens, sgi_comment_str); 00151 Append_Token_String(tokens, "start"); 00152 Append_Token_String(tokens, Number_as_String(construct_id, "%llu")); 00153 } /* WN2F_End_Prompf_Construct */ 00154 00155 00156 static void 00157 WN2F_End_Prompf_Construct(TOKEN_BUFFER tokens, WN *pragma) 00158 { 00159 INT32 construct_id = WN_MAP32_Get(*W2F_Construct_Map, pragma); 00160 00161 Append_F77_Directive_Newline(tokens, sgi_comment_str); 00162 Append_Token_String(tokens, "end"); 00163 Append_Token_String(tokens, Number_as_String(construct_id, "%llu")); 00164 } /* WN2F_End_Prompf_Construct */ 00165 00166 00167 static void 00168 WN2F_Directive_Newline(TOKEN_BUFFER tokens, 00169 const char *directive_prefix, 00170 SRCPOS srcpos) 00171 { 00172 Append_F77_Directive_Newline(tokens, directive_prefix); 00173 if (W2F_File[W2F_LOC_FILE] != NULL) 00174 Append_Srcpos_Map(tokens, srcpos); 00175 } /* WN2F_Directive_Newline */ 00176 00177 00178 /* ======================= Static Functions ======================= */ 00179 /* ================================================================ */ 00180 00181 00182 static void 00183 WN2F_Append_Pragma_Preamble(TOKEN_BUFFER tokens,WN * apragma) 00184 { 00185 /* 00186 * appends a PAR or OMP depending on the setting of 00187 * the omp flag on the pragma node 00188 * 00189 */ 00190 00191 if (WN2F_is_omp(apragma)) 00192 Append_Token_String(tokens, "OMP"); 00193 else 00194 Append_Token_String(tokens, "PAR"); 00195 } 00196 00197 00198 /* we use this function instead WN2F_Append_Pragma_Preamble to generate OMP and PAR directives */ 00199 /* the directive prefix needs to be C$OMP or C$PAR, otherwise the continuation line prefix is wrong */ 00200 /* e.g. continuation line prefix is $& instead of $OMP& ([email protected]) */ 00201 static void 00202 WN2F_OMP_or_PAR_Directive_Newline(TOKEN_BUFFER tokens,WN * apragma) 00203 { 00204 if (WN2F_is_omp(apragma)) 00205 WN2F_Directive_Newline(tokens, "C$OMP", WN_Get_Linenum(apragma)); 00206 else 00207 WN2F_Directive_Newline(tokens, "C$PAR", WN_Get_Linenum(apragma)); 00208 /* force a space after the directive prefix ([email protected]) */ 00209 /* this is not automatically emited because of MIPSpro C$ directive prefix */ 00210 //Append_Token_String(tokens, " "); 00211 } 00212 00213 00214 static void 00215 Append_Reduction_Operator(TOKEN_BUFFER tokens,OPERATOR op) 00216 { 00217 /* 00218 * appends a symbol representing an OMP reduction operator. 00219 */ 00220 00221 char * p; 00222 00223 switch(op) 00224 { 00225 case OPR_MAX: 00226 p = "MAX"; 00227 break; 00228 00229 case OPR_MIN: 00230 p = "MIN"; 00231 break; 00232 00233 case OPR_BAND: 00234 p = "IAND"; 00235 break; 00236 00237 case OPR_BIOR: 00238 p = "IOR"; 00239 break; 00240 00241 case OPR_BXOR: 00242 p = "IEOR"; 00243 break; 00244 00245 case OPR_LAND: 00246 p = ".AND."; 00247 break; 00248 00249 case OPR_LIOR: 00250 p = ".OR."; 00251 break; 00252 00253 case OPR_EQ: 00254 p = ".EQV."; 00255 break; 00256 00257 case OPR_NE: 00258 p = ".NEQV."; 00259 break; 00260 00261 case OPR_ADD: 00262 p = "+"; 00263 break; 00264 00265 case OPR_MPY: 00266 p = "*"; 00267 break; 00268 00269 case OPR_SUB: 00270 p = "-"; 00271 break; 00272 00273 default: 00274 p = "?" ; 00275 } 00276 Append_Token_String(tokens, p); 00277 Append_Token_Special(tokens,':'); 00278 } 00279 00280 static BOOL 00281 Is_Valid_Doacross(WN *doacross) 00282 { 00283 /* Return TRUE if the enclosing region has a body containing nothing 00284 * other than an OPR_DO_LOOP node. Only when returning TRUE may a 00285 * DOACROSS directive be emipwdtted prior to the region body. 00286 */ 00287 const WN *region = W2CF_Get_Parent(W2CF_Get_Parent(doacross)); 00288 WN *region_body; 00289 00290 ASSERT_DBG_FATAL(WN_operator(region) == OPR_REGION, 00291 (DIAG_W2F_UNEXPECTED_OPC, "Is_Valid_Doacross")); 00292 00293 region_body = WN_region_body(region); 00294 return (WN_operator(WN_first(region_body)) == OPR_DO_LOOP && 00295 WN_first(region_body) == WN_last(region_body)); 00296 } /* Is_Valid_Doacross */ 00297 00298 00299 static void 00300 Put_Pragma_Start_With_Caveats(TOKEN_BUFFER tokens, WN *apragma, BOOL warn) 00301 { 00302 /* It may be transformations have stuffed some code before 00303 * a doacross, pdo or parallel do. This is not strictly allowed 00304 * when compiling (ie: w2f output), so warn about the 00305 * misplaced items, if warn is set. eg: if ENDDO etc comes through, 00306 * omit the warning. 00307 */ 00308 00309 if (Is_Valid_Doacross(apragma)) 00310 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 00311 else if (W2F_Prompf_Emission) 00312 WN2F_Directive_Newline(tokens, "CC$", WN_Get_Linenum(apragma)); 00313 else 00314 { 00315 WN2F_Directive_Newline(tokens,"C<misplaced>$", WN_Get_Linenum(apragma)); 00316 00317 if ( warn ) 00318 { 00319 if (WN_pragma(apragma) == WN_PRAGMA_DOACROSS) 00320 ASSERT_WARN(FALSE, (DIAG_W2F_MISPLACED_PRAGMA, "DOACROSS")); 00321 else if (WN_pragma(apragma) == WN_PRAGMA_PDO_BEGIN) 00322 ASSERT_WARN(FALSE, (DIAG_W2F_MISPLACED_PRAGMA, "PDO")); 00323 else 00324 ASSERT_WARN(FALSE, (DIAG_W2F_MISPLACED_PRAGMA, "PARALLEL DO")); 00325 } 00326 } 00327 } 00328 00329 static BOOL 00330 Preg_Is_In_Clause_List(const WN *clause_list, ST *preg_st, PREG_IDX preg_idx) 00331 { 00332 /* Returns TRUE when the given preg is already referenced in a LOCAL, 00333 * LASTLOCAL, SHARED or REDUCTION clause in the given clause list; 00334 * otherwise we return FALSE. 00335 */ 00336 BOOL found = FALSE; 00337 00338 while (!found && clause_list != NULL) 00339 { 00340 switch (WN_pragma(clause_list)) 00341 { 00342 case WN_PRAGMA_LOCAL: 00343 case WN_PRAGMA_LASTLOCAL: 00344 case WN_PRAGMA_SHARED: 00345 case WN_PRAGMA_FIRSTPRIVATE: 00346 case WN_PRAGMA_REDUCTION: 00347 case WN_PRAGMA_COPYPRIVATE: 00348 if (WN_operator(clause_list) != OPR_XPRAGMA && 00349 WN_st(clause_list) == preg_st && 00350 WN_pragma_arg1(clause_list) == preg_idx) 00351 { 00352 found = TRUE; 00353 } 00354 break; 00355 default: 00356 break; 00357 } 00358 clause_list = WN_next(clause_list); 00359 } 00360 return found; 00361 } /* Preg_Is_In_Clause_List */ 00362 00363 00364 static void 00365 Get_Implicit_Locals(WN_PRAGMA_ID kind, /* in */ 00366 const WN *wn, /* in */ 00367 const WN *clauses, /* in */ 00368 LOCAL_PREG **ptr_to_local_list, /* in/out */ 00369 UINT *next_local, /* in/out */ 00370 UINT *max_locals) /* in/out */ 00371 { 00372 /* Puts the implicit locals into the local_list. Every element of the 00373 * local list must represent a unique preg. 00374 */ 00375 OPERATOR opr = WN_operator(wn); 00376 ST *st; 00377 PREG_IDX preg_idx; 00378 00379 /* Get the preg attributes (st, offset) if this is a preg reference 00380 */ 00381 switch (opr) 00382 { 00383 case OPR_LDA: 00384 st = WN_st(wn); 00385 preg_idx = WN_lda_offset(wn); 00386 break; 00387 case OPR_LDID: 00388 st = WN_st(wn); 00389 preg_idx = WN_load_offset(wn); 00390 break; 00391 case OPR_STID: 00392 st = WN_st(wn); 00393 preg_idx = WN_store_offset(wn); 00394 break; 00395 default: 00396 st = NULL; 00397 preg_idx = 0; 00398 } 00399 00400 /* Add a preg reference to the local_list. 00401 */ 00402 if (st != NULL && 00403 ST_sym_class(st) == CLASS_PREG && 00404 !Preg_Is_In_Clause_List(clauses, st, preg_idx)) 00405 { 00406 /* Unless the preg is already in the local list, add it. 00407 */ 00408 INT i; 00409 BOOL found = FALSE; 00410 LOCAL_PREG *local_list = *ptr_to_local_list; 00411 00412 for (i = 0; !found && i < *next_local; i++) 00413 if (local_list[i].st == st && local_list[i].preg_idx == preg_idx) 00414 found = TRUE; 00415 00416 if (!found) 00417 { 00418 if (*next_local >= *max_locals) 00419 { 00420 /* Need to reallocate the local_list buffer. Use increments 00421 * of 200 elements for each reallocation. 00422 */ 00423 *max_locals += 200; 00424 local_list = TYPE_ALLOC_N(LOCAL_PREG, *max_locals); 00425 00426 /* Copy old values into new list, and free up the old list. 00427 */ 00428 if (*ptr_to_local_list != NULL) 00429 { 00430 for (i = 0; i < *next_local; i++) 00431 local_list[i] = (*ptr_to_local_list)[i]; 00432 FREE(*ptr_to_local_list); 00433 } 00434 *ptr_to_local_list = local_list; 00435 } 00436 00437 /* Enter new element into the local_list. 00438 */ 00439 local_list[*next_local].st = st; 00440 local_list[*next_local].preg_idx = preg_idx; 00441 (*next_local)++; 00442 } 00443 } 00444 00445 /* Look for preg references in kids 00446 */ 00447 if (!OPCODE_is_leaf(WN_opcode(wn))) 00448 { 00449 if (opr == OPR_REGION) 00450 { 00451 /* Skip a pdo or a parallel_do inside a parallel region, since 00452 * such nested regions will be handled independently. 00453 * 00454 * NO LONGER DO THIS, SINCE WE NO LONGER DO IMPLICIT SEARCHES 00455 * ON SUCH NESTED CONSTRUCTS. 00456 * 00457 * WN *pragma = WN_first(WN_region_pragmas(wn)); 00458 * if (kind != WN_PRAGMA_PARALLEL_BEGIN || 00459 * pragma == NULL || 00460 * (WN_pragma(pragma) != WN_PRAGMA_PDO_BEGIN && /may occur / 00461 * WN_pragma(pragma) != WN_PRAGMA_PARALLEL_BEGIN && /impossible?/ 00462 * WN_pragma(pragma) != WN_PRAGMA_PARALLEL_DO && /impossible?/ 00463 * WN_pragma(pragma) != WN_PRAGMA_DOACROSS)) /impossible?/ 00464 *{ 00465 */ 00466 Get_Implicit_Locals(kind, WN_region_body(wn), clauses, 00467 ptr_to_local_list, next_local, max_locals); 00468 } 00469 else if (opr == OPR_BLOCK) 00470 { 00471 const WN* kid = WN_first(wn); 00472 while (kid) 00473 { 00474 Get_Implicit_Locals(kind, kid, clauses, 00475 ptr_to_local_list, next_local, max_locals); 00476 kid = WN_next(kid); 00477 } 00478 } 00479 else 00480 { 00481 INT kidno; 00482 const WN* kid; 00483 for (kidno=0; kidno < WN_kid_count(wn); kidno++) 00484 { 00485 kid = WN_kid (wn, kidno); 00486 if (kid) 00487 { 00488 Get_Implicit_Locals(kind, kid, clauses, 00489 ptr_to_local_list, next_local, max_locals); 00490 } 00491 } 00492 } 00493 } 00494 } /* Get_Implicit_Locals */ 00495 00496 00497 static void 00498 Append_Implicit_Locals(TOKEN_BUFFER tokens, 00499 WN_PRAGMA_ID region_kind, 00500 const WN *region_body, 00501 const WN *region_clauses) 00502 { 00503 /* This will append implicit LOCAL clauses to the tokens, assuming 00504 * the regular clauses already have been appended to the tokens. 00505 */ 00506 LOCAL_PREG *local_list = NULL; 00507 UINT i, number_of_locals = 0, max_number_of_locals = 0; 00508 00509 /* Get the list of implicit locals. 00510 */ 00511 Get_Implicit_Locals(region_kind, region_body, region_clauses, 00512 &local_list, &number_of_locals, &max_number_of_locals); 00513 00514 /* Add make the implicit LOCAL clauses explicit in the token buffer 00515 */ 00516 if (number_of_locals > 0) 00517 { 00518 if (region_clauses != NULL) 00519 Append_Token_Special(tokens, ','); 00520 00521 /* generate valid OpenMP PRIVATE clause ([email protected]) */ 00522 if(! WN2F_is_omp(region_clauses)) 00523 Append_Token_String(tokens, "local"); 00524 else 00525 Append_Token_String(tokens, "private"); 00526 Append_Token_Special(tokens, '('); 00527 for (i = 0; i < number_of_locals; i++) 00528 { 00529 if (i > 0) 00530 Append_Token_Special(tokens, ','); 00531 00532 ST2F_Use_Preg(tokens, 00533 ST_type(local_list[i].st), local_list[i].preg_idx); 00534 } 00535 Append_Token_Special(tokens, ')'); 00536 } 00537 00538 if (local_list != NULL) 00539 FREE(local_list); 00540 } /* Append_Implicit_Locals */ 00541 00542 00543 static BOOL 00544 WN2F_pragma_list_nowait(WN *first_pragma) 00545 { 00546 WN *wn; 00547 BOOL nowait = FALSE; 00548 00549 for (wn = first_pragma; !nowait && wn != NULL; wn = WN_next(wn)) 00550 if ((WN_operator(wn) == OPR_PRAGMA || WN_operator(wn) == OPR_XPRAGMA) && 00551 WN_pragma(wn) == WN_PRAGMA_NOWAIT) 00552 nowait = TRUE; 00553 00554 return nowait; 00555 } /* WN2F_pragma_list_nowait */ 00556 00557 00558 static void 00559 WN2F_Append_Value_Reference(TOKEN_BUFFER tokens, WN *expression) 00560 { 00561 WN2F_CONTEXT context = INIT_WN2F_CONTEXT; 00562 00563 /* Emit memory reference 00564 */ 00565 if (TY_Is_Pointer(WN_Tree_Type(expression))) 00566 set_WN2F_CONTEXT_deref_addr(context); 00567 (void)WN2F_translate(tokens, expression, context); 00568 } // WN2F_Append_Value_Reference 00569 00570 00571 static void 00572 WN2F_Prepend_Value_Reference(TOKEN_BUFFER tokens, WN *expression) 00573 { 00574 WN2F_CONTEXT context = INIT_WN2F_CONTEXT; 00575 TOKEN_BUFFER expr_tokens = New_Token_Buffer(); 00576 00577 /* Emit memory reference 00578 */ 00579 if (TY_Is_Pointer(WN_Tree_Type(expression))) 00580 set_WN2F_CONTEXT_deref_addr(context); 00581 (void)WN2F_translate(expr_tokens, expression, context); 00582 Prepend_And_Reclaim_Token_List(tokens, &expr_tokens); 00583 } // WN2F_Prepend_Value_Reference 00584 00585 00586 /* enhanced to emit proper OpenMP schedule clauses ([email protected]) */ 00587 static void 00588 Append_MP_Schedtype(TOKEN_BUFFER tokens, WN *clause) 00589 { 00590 switch (WN_mp_schedtype(clause)) 00591 { 00592 case WN_PRAGMA_SCHEDTYPE_RUNTIME: 00593 Append_Token_String(tokens, "runtime"); 00594 break; 00595 case WN_PRAGMA_SCHEDTYPE_SIMPLE: 00596 if(WN2F_is_omp(clause)) 00597 Append_Token_String(tokens, "static"); 00598 else 00599 Append_Token_String(tokens, "simple"); 00600 break; 00601 case WN_PRAGMA_SCHEDTYPE_INTERLEAVE: 00602 Append_Token_String(tokens, "interleaved"); 00603 break; 00604 case WN_PRAGMA_SCHEDTYPE_DYNAMIC: 00605 Append_Token_String(tokens, "dynamic"); 00606 break; 00607 case WN_PRAGMA_SCHEDTYPE_GSS: 00608 if(WN2F_is_omp(clause)) 00609 Append_Token_String(tokens, "guided"); 00610 else 00611 Append_Token_String(tokens, "gss"); 00612 break; 00613 case WN_PRAGMA_SCHEDTYPE_PSEUDOLOWERED: 00614 Append_Token_String(tokens, "pseudolowered"); 00615 break; 00616 default: 00617 ASSERT_DBG_FATAL(FALSE, 00618 (DIAG_W2F_UNEXPECTED_OPC, "Append_MP_Schedtype")); 00619 break; 00620 } 00621 } /* Append_MP_Schedtype */ 00622 00623 00624 static void 00625 Append_Arg_Numbers(TOKEN_BUFFER tokens, 00626 INT32 val1, 00627 INT32 val2) 00628 { 00629 if (val1 != -1) 00630 Append_Token_String(tokens, WHIRL2F_number_as_name(val1)); 00631 00632 if (val2 != -1) 00633 { 00634 Append_Token_Special(tokens, ','); 00635 Append_Token_String(tokens, WHIRL2F_number_as_name(val2)); 00636 } 00637 } /* Append_Arg_Numbers */ 00638 00639 00640 static void 00641 Append_Prefetch_Attributes(TOKEN_BUFFER tokens, 00642 WN *prefetch, 00643 INT32 size) 00644 { 00645 INT pflag = WN_prefetch_flag(prefetch); 00646 00647 /* Emit memory reference 00648 */ 00649 Append_Token_Special(tokens, '='); 00650 WN2F_Append_Value_Reference(tokens, WN_kid0(prefetch)); 00651 00652 /* Emit stride and level clauses 00653 */ 00654 Append_Token_Special(tokens, ','); 00655 if (PF_GET_STRIDE_1L(pflag) > 0) 00656 { 00657 if (PF_GET_STRIDE_2L(pflag) > 0) 00658 { 00659 Append_Token_String(tokens, 00660 Concat2_Strings("stride=", 00661 Concat2_Strings(WHIRL2F_number_as_name(PF_GET_STRIDE_1L(pflag)), 00662 Concat2_Strings(",", 00663 WHIRL2F_number_as_name(PF_GET_STRIDE_2L(pflag)))))); 00664 Append_Token_Special(tokens, ','); 00665 Append_Token_String(tokens, "level=1,2"); 00666 } 00667 else 00668 { 00669 Append_Token_String(tokens, 00670 Concat2_Strings("stride=", 00671 WHIRL2F_number_as_name(PF_GET_STRIDE_1L(pflag)))); 00672 Append_Token_Special(tokens, ','); 00673 Append_Token_String(tokens, "level=1"); 00674 } 00675 } 00676 else if (PF_GET_STRIDE_2L(pflag) > 0) 00677 { 00678 Append_Token_String(tokens, 00679 Concat2_Strings("stride=,", 00680 WHIRL2F_number_as_name(PF_GET_STRIDE_2L(pflag)))); 00681 Append_Token_Special(tokens, ','); 00682 Append_Token_String(tokens, "level=,2"); 00683 } 00684 else 00685 { 00686 Append_Token_String(tokens, "stride="); 00687 Append_Token_Special(tokens, ','); 00688 Append_Token_String(tokens, "level="); 00689 } 00690 00691 /* Emit a kind clause 00692 */ 00693 Append_Token_Special(tokens, ','); 00694 if (PF_GET_READ(pflag)) 00695 Append_Token_String(tokens, "kind=rd"); 00696 else 00697 Append_Token_String(tokens, "kind=wr"); 00698 00699 /* Emit a size clause 00700 */ 00701 if (size > 0) 00702 { 00703 Append_Token_Special(tokens, ','); 00704 Append_Token_String(tokens, 00705 Concat2_Strings("size=", WHIRL2F_number_as_name(size))); 00706 } 00707 } /* Append_Prefetch_Attributes */ 00708 00709 00710 static void 00711 Append_Distribution(TOKEN_BUFFER tokens, WN **apragma, WN_PRAGMA_ID id) 00712 { 00713 INT32 dim, num_dims; 00714 ARRAY_DISTRIBUTION distr[MAX_PRAGMAS_TO_SKIP]; 00715 WN *wn = *apragma; 00716 WN2F_CONTEXT context = INIT_WN2F_CONTEXT; 00717 00718 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_PRAGMA, 00719 (DIAG_W2F_UNEXPECTED_OPC, "Append_Distribution")); 00720 00721 /* Accumulate the distribution kind for each dimension. 00722 */ 00723 for (num_dims = 0; 00724 (WN_operator(wn) == OPR_PRAGMA && 00725 WN_pragma(wn) == id && 00726 num_dims == WN_pragma_index(wn)); 00727 num_dims++) 00728 { 00729 /* In reverese order of pragma sequence */ 00730 distr[num_dims].current_dimension = WN_pragma_index(wn); 00731 distr[num_dims].base = wn; 00732 if (WN_pragma_distr_type(wn) == DISTRIBUTE_CYCLIC_EXPR) 00733 distr[num_dims].cyclic_expr = wn = WN_next(wn); 00734 distr[num_dims].dimension_bound = wn = WN_next(wn); 00735 wn = WN_next(wn); 00736 } 00737 00738 /* Skip two stores, which are generated purely for dependency analysis 00739 * purposes. 00740 */ 00741 if (WN_operator(wn)==OPR_STID && ST_class(WN_st(wn))==CLASS_PREG) 00742 { 00743 wn = WN_next(wn); 00744 if (WN_operator(wn)==OPR_STID && ST_class(WN_st(wn))==CLASS_PREG) 00745 wn = WN_next(wn); 00746 } 00747 *apragma = wn; 00748 00749 /* Translate the sequence of distribution kinds, in Fortran order, i.e. 00750 * in reverse order from WHIRL representation. 00751 */ 00752 Append_Token_Special(tokens, '('); 00753 for (dim = num_dims-1; dim >= 0; dim--) 00754 { 00755 switch (WN_pragma_distr_type(distr[dim].base)) 00756 { 00757 case DISTRIBUTE_STAR: 00758 Append_Token_Special(tokens, '*'); 00759 break; 00760 00761 case DISTRIBUTE_BLOCK: 00762 Append_Token_String(tokens, "block"); 00763 break; 00764 00765 case DISTRIBUTE_CYCLIC_EXPR: 00766 Append_Token_String(tokens, "cyclic"); 00767 Append_Token_Special(tokens, '('); 00768 WN2F_translate(tokens, WN_kid0(distr[dim].cyclic_expr), context); 00769 Append_Token_Special(tokens, ')'); 00770 break; 00771 00772 case DISTRIBUTE_CYCLIC_CONST: 00773 Append_Token_String(tokens, "cyclic"); 00774 PARENTHESIZE_ARG_NUMBERS1(tokens, 00775 WN_pragma_preg(distr[dim].base)); 00776 break; 00777 00778 default: 00779 Append_Token_String(tokens, "unknown_distribution"); 00780 break; 00781 } 00782 00783 if (dim > 0) 00784 Append_Token_Special(tokens, ','); 00785 00786 } /* For each dimension */ 00787 Append_Token_Special(tokens, ')'); 00788 00789 } /* Append_Distribution */ 00790 00791 00792 static void 00793 Append_A_Clause_Symbol(TOKEN_BUFFER tokens, WN *clause, WN_OFFSET ofst) 00794 { 00795 ST * const st = WN_st(clause); 00796 00797 if (ST_class(st) == CLASS_PREG) 00798 { 00799 INT32 preg_num = WN_pragma_arg1(clause); 00800 00801 ST2F_Use_Preg(tokens, ST_type(st), preg_num); 00802 } 00803 else 00804 { 00805 const TY_IDX base_ty = ST_type(st); 00806 WN2F_CONTEXT context = INIT_WN2F_CONTEXT; 00807 00808 WN2F_Offset_Symref(tokens, 00809 st, /* base variable */ 00810 Stab_Pointer_To(base_ty), /* base addr */ 00811 base_ty, /* type of reference */ 00812 ofst, /* base offset */ 00813 context); 00814 } 00815 } /* Append_A_Clause_Symbol */ 00816 00817 00818 static void 00819 Append_Clause_Symbols(TOKEN_BUFFER tokens, 00820 WN_PRAGMA_ID id, 00821 WN **next) 00822 { 00823 /* Loop through the pragmas, and emit a ',' separated list 00824 * of the ST attributes for all contiguous pragmas with the 00825 * given "id". Terminate upon reaching a pragma with a 00826 * different "id" or the end of the pragma list. Set *next to 00827 * point to the next node after the last one processed here. 00828 */ 00829 WN *clause; 00830 00831 ASSERT_DBG_FATAL(WN_operator(*next) == OPR_PRAGMA, 00832 (DIAG_W2F_UNEXPECTED_OPC, "Append_Clause_Symbols")); 00833 00834 Append_Token_Special(tokens, '('); 00835 for (clause = *next; 00836 (clause != NULL && 00837 WN_operator(clause) == OPR_PRAGMA && 00838 WN_pragma(clause) == id); 00839 clause = WN_next(clause)) 00840 { 00841 if (clause != *next) 00842 Append_Token_Special(tokens, ','); 00843 00844 Append_A_Clause_Symbol(tokens, clause, 0); 00845 } 00846 Append_Token_Special(tokens, ')'); 00847 *next = clause; 00848 } /* Append_Clause_Symbols */ 00849 00850 00851 static void 00852 Append_Reduction_Clause(TOKEN_BUFFER tokens, 00853 WN_PRAGMA_ID id, 00854 WN **next) 00855 { 00856 /* Loop through the pragmas, and emit a ',' separated list 00857 * of the reduction operator and ST attributes for all 00858 * contiguous pragmas with the given "id". 00859 */ 00860 WN * clause; 00861 WN * const first_clause = *next; 00862 00863 ASSERT_DBG_FATAL(WN_operator(first_clause) == OPR_PRAGMA, 00864 (DIAG_W2F_UNEXPECTED_OPC, "Append_Reduction_Clause")); 00865 00866 Append_Token_String(tokens, "reduction ("); 00867 for (clause = first_clause; 00868 (clause != NULL && 00869 WN_operator(clause) == OPR_PRAGMA && 00870 WN_pragma(clause) == id); 00871 clause = WN_next(clause)) 00872 { 00873 if (WN2F_is_omp(clause) && 00874 WN_pragma(clause) == WN_PRAGMA_REDUCTION && 00875 WN_pragma_arg2(clause) != OPERATOR_UNKNOWN) 00876 { 00877 if (first_clause != clause) 00878 Append_Token_String(tokens, "), reduction ("); 00879 Append_Reduction_Operator(tokens, (OPERATOR) WN_pragma_arg2(clause)); 00880 00881 } 00882 else if (clause != first_clause) 00883 Append_Token_Special(tokens, ','); 00884 00885 Append_A_Clause_Symbol(tokens, clause, 0); 00886 } 00887 00888 Append_Token_Special(tokens, ')'); 00889 *next = clause; 00890 00891 } /* Append_Reduction_Clause */ 00892 00893 00894 static void 00895 Append_Clause_Expressions(TOKEN_BUFFER tokens, 00896 WN_PRAGMA_ID id, 00897 WN **next, 00898 BOOL reverse_order = FALSE) 00899 { 00900 /* Loop through the pragmas, and emit a ',' separated list 00901 * of the ST attributes for all contiguous pragmas with the 00902 * given "id". Terminate upon reaching a pragma with a 00903 * different "id" or the end of the pragma list. Set *next to 00904 * point to the next node after the last one processed here. 00905 */ 00906 TOKEN_BUFFER clause_tokens = New_Token_Buffer(); 00907 WN * clause; 00908 WN * const first_clause = *next; 00909 00910 ASSERT_DBG_FATAL(WN_operator(first_clause) == OPR_XPRAGMA, 00911 (DIAG_W2F_UNEXPECTED_OPC, "Append_Clause_Expressions")); 00912 00913 Append_Token_Special(tokens, '('); 00914 for (clause = first_clause; 00915 (clause != NULL && 00916 WN_operator(clause) == OPR_XPRAGMA && 00917 WN_pragma(clause) == id); 00918 clause = WN_next(clause)) 00919 { 00920 if (clause != first_clause) 00921 { 00922 if (reverse_order) 00923 Prepend_Token_Special(clause_tokens, ','); 00924 else 00925 Append_Token_Special(clause_tokens, ','); 00926 } 00927 00928 00929 if (id == WN_PRAGMA_ONTO && 00930 WN_operator(WN_kid0(clause)) == OPR_INTCONST && 00931 WN_const_val(WN_kid0(clause)) == 0) 00932 { 00933 /* Special case! 00934 */ 00935 if (reverse_order) 00936 Prepend_Token_Special(clause_tokens, '*'); 00937 else 00938 Append_Token_Special(clause_tokens, '*'); 00939 } 00940 else 00941 { 00942 if (reverse_order) 00943 WN2F_Prepend_Value_Reference(tokens, WN_kid0(clause)); 00944 else 00945 WN2F_Append_Value_Reference(tokens, WN_kid0(clause)); 00946 } 00947 } // for each clause 00948 Append_And_Reclaim_Token_List(tokens, &clause_tokens); 00949 Append_Token_Special(tokens, ')'); 00950 *next = clause; 00951 } /* Append_Clause_Expressions */ 00952 00953 00954 static void 00955 Append_Array_Segment(TOKEN_BUFFER tokens, 00956 WN_PRAGMA_ID id, 00957 WN **next) 00958 { 00959 /* Loop through the pragmas, and emit a ',' separated list 00960 * of the ST attributes for all contiguous pragmas with the 00961 * given "id". Terminate upon reaching a pragma with a 00962 * different "id" or the end of the pragma list. Set *next to 00963 * point to the next node after the last one processed here. 00964 */ 00965 WN *clause; 00966 00967 ASSERT_DBG_FATAL(WN_operator(*next) == OPR_XPRAGMA, 00968 (DIAG_W2F_UNEXPECTED_OPC, "Append_Array_Segment")); 00969 00970 Append_Token_Special(tokens, '('); 00971 for (clause = *next; 00972 (clause != NULL && 00973 WN_operator(clause) == OPR_XPRAGMA && 00974 WN_pragma(clause) == id); 00975 clause = WN_next(clause)) 00976 { 00977 if (clause != *next) 00978 Append_Token_Special(tokens, ','); 00979 00980 Append_A_Clause_Symbol(tokens, clause, 0); 00981 Append_Token_Special(tokens, '('); 00982 EMIT_ARG_NUMBERS1(tokens, 1); 00983 Append_Token_Special(tokens, ':'); 00984 WN2F_Append_Value_Reference(tokens, WN_kid0(clause)); 00985 Append_Token_Special(tokens, ')'); 00986 } 00987 Append_Token_Special(tokens, ')'); 00988 00989 *next = clause; 00990 } /* Append_Array_Segment */ 00991 00992 00993 static void 00994 Append_Nest_Clauses(TOKEN_BUFFER tokens, 00995 const WN *nest_region, 00996 INT nest_levels, 00997 WN2F_CONTEXT context) 00998 { 00999 BOOL pattern_error = FALSE; 01000 INT nest; 01001 ST *idx_var; 01002 TY_IDX idx_ty; 01003 const WN *next_stmt = nest_region; 01004 WN_PRAGMA_ID nest_kind = WN_PRAGMA_UNDEFINED; 01005 TOKEN_BUFFER nest_tokens = New_Token_Buffer(); 01006 01007 ASSERT_DBG_FATAL(next_stmt != NULL && 01008 WN_operator(next_stmt) == OPR_REGION && 01009 WN_first(WN_region_pragmas(next_stmt)) != NULL, 01010 (DIAG_W2F_UNEXPECTED_OPC, "Append_Nest_Clauses")); 01011 01012 nest_kind = 01013 (WN_PRAGMA_ID)WN_pragma(WN_first(WN_region_pragmas(next_stmt))); 01014 01015 Append_Token_String(nest_tokens, "nest"); 01016 Append_Token_Special(nest_tokens, '('); 01017 reset_WN2F_CONTEXT(context); 01018 for (nest = 1; !pattern_error && nest <= nest_levels; nest++) 01019 { 01020 /* Get the next nested loop, assuming next_stmt at this point 01021 * refers to a region. 01022 */ 01023 next_stmt = WN_first(WN_region_body(next_stmt)); 01024 while (next_stmt != NULL && WN_operator(next_stmt) != OPR_DO_LOOP) 01025 next_stmt = WN_next(next_stmt); 01026 01027 if (next_stmt == NULL) 01028 pattern_error = TRUE; 01029 else 01030 { 01031 /* Write out the index variable (or preg). 01032 */ 01033 idx_var = WN_st(WN_index(next_stmt)); 01034 idx_ty = ST_type(idx_var); 01035 if (ST_class(idx_var) == CLASS_PREG) 01036 { 01037 ST2F_Use_Preg(nest_tokens, 01038 idx_ty, 01039 WN_idname_offset(WN_index(next_stmt))); 01040 } 01041 else 01042 { 01043 WN2F_Offset_Symref(nest_tokens, 01044 idx_var, /* base variable */ 01045 Stab_Pointer_To(idx_ty), /* base addr */ 01046 idx_ty, /* type of ref */ 01047 0, /* base offset */ 01048 context); 01049 } 01050 01051 /* Emit separator, and search for the next nested region, if 01052 * any is expected. 01053 */ 01054 if (nest < nest_levels) 01055 { 01056 Append_Token_Special(nest_tokens, ','); 01057 01058 next_stmt = WN_first(WN_do_body(next_stmt)); 01059 while (next_stmt != NULL && 01060 WN_operator(next_stmt) != OPR_REGION) 01061 next_stmt = WN_next(next_stmt); 01062 01063 if (next_stmt == NULL || 01064 WN_first(WN_region_pragmas(next_stmt)) == NULL || 01065 WN_pragma(WN_first(WN_region_pragmas(next_stmt))) != 01066 nest_kind) 01067 pattern_error = TRUE; 01068 } 01069 } 01070 } 01071 Append_Token_Special(nest_tokens, ')'); 01072 01073 if (!pattern_error) 01074 Append_And_Reclaim_Token_List(tokens, &nest_tokens); 01075 } /* Append_Nest_Clauses */ 01076 01077 01078 void 01079 Append_ST_String(TOKEN_BUFFER tokens, WN *pragma) 01080 { 01081 // Note: pragma should have symbol of CLASS_CONST and TCON of STR 01082 // Append_A_Clause_Symbol(...) will include quote marks around the 01083 // string 01084 01085 // Append_A_Clause_Symbol effectively does: 01086 // TOKEN_BUFFER tmp_tokens = New_Token_Buffer(); 01087 // TCON2F_translate(tmp_tokens, WN_val(pragma), FALSE/*is_logical*/); 01088 01089 char* tmpval = Targ_Print(NULL, WN_val(pragma)); 01090 01091 // hide the beginning and ending quote marks 01092 char* val = tmpval + 1; 01093 val[strlen(val)-1] = '\0'; 01094 01095 Append_Token_String(tokens, val); 01096 } 01097 01098 01099 static void 01100 Skip_Pragma_Clauses(WN **clause_list, 01101 WN2F_CONTEXT context) 01102 { 01103 /* Also change Append_Pragma_Clauses() when changing this. 01104 */ 01105 WN *clause = *clause_list; 01106 BOOL more; 01107 01108 more = (clause != NULL && 01109 (WN_operator(clause) == OPR_PRAGMA || 01110 WN_operator(clause) == OPR_XPRAGMA)); 01111 01112 while (more) 01113 { 01114 switch (WN_pragma(clause)) 01115 { 01116 case WN_PRAGMA_AFFINITY: 01117 case WN_PRAGMA_DATA_AFFINITY: 01118 case WN_PRAGMA_THREAD_AFFINITY: 01119 case WN_PRAGMA_CHUNKSIZE: 01120 case WN_PRAGMA_IF: 01121 case WN_PRAGMA_LASTLOCAL: 01122 case WN_PRAGMA_LOCAL: 01123 case WN_PRAGMA_MPSCHEDTYPE: 01124 case WN_PRAGMA_ORDERED: 01125 case WN_PRAGMA_REDUCTION: 01126 case WN_PRAGMA_SHARED: 01127 case WN_PRAGMA_ONTO: 01128 case WN_PRAGMA_LASTTHREAD: 01129 case WN_PRAGMA_MPNUM: 01130 case WN_PRAGMA_SYNC_DOACROSS: 01131 case WN_PRAGMA_FIRSTPRIVATE: 01132 /* there is no FLUSH clause in OpenMP */ 01133 /* we fake this clause in order to treat FLUSH directive the same as the others ([email protected]) */ 01134 case WN_PRAGMA_FLUSH: 01135 clause = WN_next(clause); 01136 break; 01137 01138 default: 01139 more = FALSE; 01140 break; 01141 } /* switch */ 01142 01143 more = (more && 01144 clause != NULL && 01145 (WN_operator(clause) == OPR_PRAGMA || 01146 WN_operator(clause) == OPR_XPRAGMA)); 01147 } /* for each attribute pragma */ 01148 01149 *clause_list = clause; 01150 } /* Skip_Pragma_Clauses */ 01151 01152 01153 static void 01154 Skip_Ignored_Clauses(WN *following_clauses, WN **next_clause) 01155 { 01156 BOOL skipped = TRUE; 01157 01158 while (skipped && *next_clause != following_clauses) 01159 { 01160 switch (WN_pragma(*next_clause)) 01161 { 01162 case WN_PRAGMA_DATA_AFFINITY: 01163 case WN_PRAGMA_THREAD_AFFINITY: 01164 case WN_PRAGMA_MPNUM: 01165 case WN_PRAGMA_SYNC_DOACROSS: 01166 *next_clause = WN_next(*next_clause); 01167 break; 01168 default: 01169 skipped = FALSE; 01170 break; 01171 } 01172 } 01173 } /* Skip_Ignored_Clauses */ 01174 01175 01176 static void 01177 Append_Pragma_Clauses(TOKEN_BUFFER tokens, 01178 WN **clause_list, 01179 WN2F_CONTEXT context) 01180 { 01181 /* Loop through the sequence of pragmas, emitting those representing 01182 * attributes to another (already emitted) pragma. Terminate upon 01183 * reaching a non-attribute pragma or the end of the pragma list. 01184 * Also change Skip_Pragma_Clauses() when changing this. Update the 01185 * clause_list, such that it denotes the item following the last one 01186 * processed here. 01187 */ 01188 WN *next; 01189 WN *clause = *clause_list; 01190 WN *wn_after_clauses = *clause_list; 01191 01192 Skip_Pragma_Clauses(&wn_after_clauses, context); 01193 while (clause != wn_after_clauses) 01194 { 01195 BOOL ignored_clause = FALSE; 01196 01197 next = clause; 01198 switch (WN_pragma(clause)) 01199 { 01200 case WN_PRAGMA_DATA_AFFINITY: 01201 case WN_PRAGMA_THREAD_AFFINITY: 01202 case WN_PRAGMA_MPNUM: 01203 case WN_PRAGMA_SYNC_DOACROSS: 01204 case WN_PRAGMA_DEFAULT: 01205 ignored_clause = TRUE; 01206 break; /* Ignore and do not follow with comma */ 01207 01208 case WN_PRAGMA_AFFINITY: 01209 Append_Token_String(tokens, "affinity"); 01210 Append_Clause_Expressions(tokens, WN_PRAGMA_AFFINITY, &clause); 01211 01212 Append_Token_Special(tokens, '='); 01213 if (WN_pragma(clause) == WN_PRAGMA_DATA_AFFINITY) 01214 Append_Token_String(tokens, "data"); 01215 else if (WN_pragma(clause) == WN_PRAGMA_THREAD_AFFINITY) 01216 Append_Token_String(tokens, "thread"); 01217 else 01218 ASSERT_DBG_FATAL(FALSE, 01219 (DIAG_W2F_UNEXPECTED_OPC, 01220 "Append_Pragma_Clauses")); 01221 01222 /* Process the expression associated with the thread/data affinity 01223 * pragma. 01224 */ 01225 Append_Token_Special(tokens, '('); 01226 WN2F_Append_Value_Reference(tokens, WN_kid0(clause)); 01227 Append_Token_Special(tokens, ')'); 01228 clause = WN_next(clause); 01229 break; 01230 01231 case WN_PRAGMA_CHUNKSIZE: 01232 Append_Token_String(tokens, "chunk"); 01233 Append_Token_Special(tokens, '='); 01234 Append_Clause_Expressions(tokens, WN_PRAGMA_CHUNKSIZE, &clause); 01235 break; 01236 01237 case WN_PRAGMA_IF: 01238 Append_Token_String(tokens, "if"); 01239 Append_Clause_Expressions(tokens, WN_PRAGMA_IF, &clause); 01240 break; 01241 01242 case WN_PRAGMA_LASTLOCAL: 01243 if (WN2F_is_omp(clause)) 01244 Append_Token_String(tokens, "lastprivate"); 01245 else 01246 Append_Token_String(tokens, "lastlocal"); 01247 Append_Clause_Symbols(tokens, WN_PRAGMA_LASTLOCAL, &clause); 01248 break; 01249 01250 case WN_PRAGMA_LOCAL: 01251 if (WN2F_is_omp(clause)) 01252 Append_Token_String(tokens, "private"); 01253 else 01254 Append_Token_String(tokens, "local"); 01255 if (WN_operator(clause) == OPR_XPRAGMA) 01256 { 01257 Append_Array_Segment(tokens, WN_PRAGMA_LOCAL, &clause); 01258 } 01259 else 01260 { 01261 Append_Clause_Symbols(tokens, WN_PRAGMA_LOCAL, &clause); 01262 } 01263 break; 01264 01265 case WN_PRAGMA_MPSCHEDTYPE: 01266 /* Can be both a clause and a pragma */ 01267 if (WN2F_is_omp(clause)) 01268 { 01269 Append_Token_String(tokens, "schedule"); 01270 Append_Token_Special(tokens, '('); 01271 Append_MP_Schedtype(tokens, clause); 01272 if (WN_next(clause) != NULL && 01273 WN_pragma(WN_next(clause)) == WN_PRAGMA_CHUNKSIZE) 01274 { 01275 clause = WN_next(clause); 01276 Append_Token_Special(tokens, ','); 01277 WN2F_Append_Value_Reference(tokens, WN_kid0(clause)); 01278 } 01279 Append_Token_Special(tokens, ')'); 01280 clause = WN_next(clause); 01281 } 01282 else 01283 { 01284 Append_Token_String(tokens, "mp_schedtype"); 01285 Append_Token_Special(tokens, '='); 01286 Append_MP_Schedtype(tokens, clause); 01287 } 01288 break; 01289 01290 case WN_PRAGMA_ORDERED: 01291 if (WN2F_is_omp(clause)) 01292 Append_Token_String(tokens, "ordered"); 01293 else 01294 Append_Token_String(tokens, "(ordered)"); 01295 break; 01296 01297 case WN_PRAGMA_REDUCTION: 01298 if (WN_operator(clause) == OPR_XPRAGMA) 01299 { 01300 Append_Token_String(tokens, "reduction"); 01301 Append_Clause_Expressions(tokens, WN_PRAGMA_REDUCTION, &clause); 01302 } 01303 else 01304 { 01305 Append_Reduction_Clause(tokens, WN_PRAGMA_REDUCTION, &clause); 01306 } 01307 break; 01308 01309 case WN_PRAGMA_SHARED: 01310 Append_Token_String(tokens, "shared"); 01311 Append_Clause_Symbols(tokens, WN_PRAGMA_SHARED, &clause); 01312 break; 01313 01314 case WN_PRAGMA_ONTO: 01315 Append_Token_String(tokens, "onto"); 01316 Append_Clause_Expressions(tokens, WN_PRAGMA_ONTO, &clause, 01317 TRUE/*reverse_order*/); 01318 break; 01319 01320 case WN_PRAGMA_LASTTHREAD: 01321 Append_Token_String(tokens, "lastthread"); 01322 Append_Clause_Symbols(tokens, WN_PRAGMA_LASTTHREAD, &clause); 01323 break; 01324 01325 case WN_PRAGMA_FIRSTPRIVATE: 01326 Append_Token_String(tokens, "firstprivate"); 01327 Append_Clause_Symbols(tokens, WN_PRAGMA_FIRSTPRIVATE, &clause); 01328 break; 01329 01330 /* there is no FLUSH clause in OpenMP */ 01331 /* we fake this clause in order to treat FLUSH directive the same as the others ([email protected]) */ 01332 case WN_PRAGMA_FLUSH: 01333 Append_Clause_Symbols(tokens, WN_PRAGMA_FLUSH, &clause); 01334 break; 01335 01336 default: 01337 ASSERT_WARN(FALSE, 01338 (DIAG_W2F_UNEXPECTED_PRAGMA, " Append_Pragma_Clauses")); 01339 break; 01340 } /* switch */ 01341 01342 /* See if we have already advanced to the next pragma, e.g. as a result 01343 * of calling Append_Clause_Expressions() or Append_Clause_Symbols(), 01344 * and if not so, then advance to the next pragma. 01345 */ 01346 if (next == clause) 01347 clause = WN_next(clause); 01348 01349 Skip_Ignored_Clauses(wn_after_clauses, &clause); 01350 if (clause != wn_after_clauses && !ignored_clause) 01351 Append_Token_Special(tokens, ','); /* separate by commas */ 01352 } /* for each attribute pragma */ 01353 01354 *clause_list = clause; 01355 } /* Append_Pragma_Clauses */ 01356 01357 01358 static void 01359 Emit_To_PUinfo_Pragmas(WN **next, WN2F_CONTEXT context) 01360 { 01361 /* This is a special handler for pragmas that must be taken out of 01362 * a statement list context and instead must be appended to the 01363 * PUinfo_pragmas list. 01364 */ 01365 TOKEN_BUFFER tokens = New_Token_Buffer(); 01366 01367 ASSERT_DBG_FATAL(WN_operator(*next) == OPR_PRAGMA || 01368 WN_operator(*next) == OPR_XPRAGMA, 01369 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_pragma")); 01370 01371 switch (WN_pragma(*next)) 01372 { 01373 case WN_PRAGMA_DISTRIBUTE: 01374 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(*next)); 01375 Append_Token_String(tokens, "DISTRIBUTE"); 01376 Append_A_Clause_Symbol(tokens, *next, 0/*ofst*/); 01377 Append_Distribution(tokens, next, WN_PRAGMA_DISTRIBUTE); 01378 Append_Pragma_Clauses(tokens, next, context); 01379 break; 01380 01381 case WN_PRAGMA_DISTRIBUTE_RESHAPE: 01382 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(*next)); 01383 Append_Token_String(tokens, "DISTRIBUTE RESHAPE"); 01384 Append_A_Clause_Symbol(tokens, *next, 0/*ofst*/); 01385 Append_Distribution(tokens, next, WN_PRAGMA_DISTRIBUTE_RESHAPE); 01386 Append_Pragma_Clauses(tokens, next, context); 01387 break; 01388 01389 default: 01390 ASSERT_WARN(FALSE, 01391 (DIAG_W2F_UNEXPECTED_PRAGMA, "Emit_To_PUinfo_Pragmas")); 01392 break; 01393 } 01394 Prepend_And_Reclaim_Token_List(PUinfo_pragmas, &tokens); 01395 } /* Emit_To_PUinfo_Pragmas */ 01396 01397 01398 static WN * 01399 Get_Enclosing_Parallel_Region(const WN *construct) 01400 { 01401 WN *found_parallel = NULL; 01402 01403 construct = W2CF_Get_Parent(construct); 01404 while (found_parallel == NULL && construct != NULL) 01405 { 01406 if (WN_operator(construct) == OPR_REGION) 01407 { 01408 WN *pragma = WN_first(WN_region_pragmas(construct)); 01409 if (WN_pragma(pragma) == WN_PRAGMA_PARALLEL_BEGIN) 01410 found_parallel = pragma; 01411 } 01412 construct = W2CF_Get_Parent(construct); 01413 } 01414 return found_parallel; 01415 } /* Get_Enclosing_Parallel_Region */ 01416 01417 01418 static void 01419 WN2F_process_pragma(TOKEN_BUFFER tokens, WN **next, WN2F_CONTEXT context) 01420 { 01421 /* This procedure will translate the "next" pragma and and any associated 01422 * clauses, such that "next" end up pointing to the WN* after the pragma 01423 * and clauses. 01424 */ 01425 WN *apragma = *next; 01426 WN *this_pragma = apragma; 01427 WN *first_clause; 01428 const WN *surrounding_region; 01429 01430 ASSERT_DBG_FATAL(WN_operator(apragma) == OPR_PRAGMA || 01431 WN_operator(apragma) == OPR_XPRAGMA, 01432 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_process_pragma")); 01433 01434 switch (WN_pragma(apragma)) 01435 { 01436 case WN_PRAGMA_INLINE_DEPTH: 01437 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01438 Append_Token_String(tokens,"INLINE_DEPTH"); 01439 Append_Token_Special(tokens,'='); 01440 EMIT_ARG_NUMBERS1(tokens, WN_pragma_arg1(apragma)); 01441 break; 01442 01443 case WN_PRAGMA_AGGRESSIVE_INNER_LOOP_FISSION: 01444 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01445 Append_Token_String(tokens,"AGGRESSIVE INNER LOOP FISSION"); 01446 break; 01447 01448 case WN_PRAGMA_FISSION: 01449 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01450 Append_Token_String(tokens,"FISSION"); 01451 PARENTHESIZE_ARG_NUMBERS1(tokens, WN_pragma_arg1(apragma)); 01452 break; 01453 01454 case WN_PRAGMA_FISSIONABLE: 01455 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01456 Append_Token_String(tokens,"FISSIONABLE"); 01457 break; 01458 01459 case WN_PRAGMA_FUSE: 01460 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01461 Append_Token_String(tokens,"FUSE"); 01462 PARENTHESIZE_ARG_NUMBERS2(tokens, 01463 WN_pragma_arg1(apragma), 01464 WN_pragma_arg2(apragma)); 01465 break; 01466 01467 case WN_PRAGMA_FUSEABLE: 01468 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01469 Append_Token_String(tokens,"FUSABLE"); 01470 break; 01471 01472 case WN_PRAGMA_NO_FISSION: 01473 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01474 Append_Token_String(tokens,"NO FISSION"); 01475 break; 01476 01477 case WN_PRAGMA_NO_FUSION: 01478 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01479 Append_Token_String(tokens,"NO FUSION"); 01480 break; 01481 01482 case WN_PRAGMA_INTERCHANGE: 01483 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01484 Append_Token_String(tokens, "INTERCHANGE"); 01485 Append_Clause_Symbols(tokens, (WN_PRAGMA_ID)WN_pragma(apragma), 01486 &apragma); 01487 break; 01488 01489 case WN_PRAGMA_NO_INTERCHANGE: 01490 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01491 Append_Token_String(tokens, "NO INTERCHANGE"); 01492 break; 01493 01494 case WN_PRAGMA_BLOCKING_SIZE: 01495 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01496 Append_Token_String(tokens, "BLOCKING SIZE"); 01497 PARENTHESIZE_ARG_NUMBERS2(tokens, 01498 WN_pragma_arg1(apragma), 01499 WN_pragma_arg2(apragma)); 01500 break; 01501 01502 case WN_PRAGMA_NO_BLOCKING: 01503 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01504 Append_Token_String(tokens, "NO BLOCKING"); 01505 break; 01506 01507 case WN_PRAGMA_UNROLL: 01508 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01509 Append_Token_String(tokens, "UNROLL"); 01510 PARENTHESIZE_ARG_NUMBERS2(tokens, 01511 WN_pragma_arg1(apragma), 01512 WN_pragma_arg2(apragma)); 01513 break; 01514 01515 case WN_PRAGMA_BLOCKABLE: 01516 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01517 Append_Token_String(tokens, "BLOCKABLE"); 01518 Append_Clause_Symbols(tokens, (WN_PRAGMA_ID)WN_pragma(apragma), 01519 &apragma); 01520 break; 01521 01522 case WN_PRAGMA_PREFETCH: 01523 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01524 Append_Token_String(tokens, "PREFETCH"); 01525 PARENTHESIZE_ARG_NUMBERS2(tokens, 01526 WN_pragma_arg1(apragma), 01527 WN_pragma_arg2(apragma)); 01528 break; 01529 01530 case WN_PRAGMA_PREFETCH_MANUAL: 01531 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01532 Append_Token_String(tokens, "PREFETCH_MANUAL"); 01533 PARENTHESIZE_ARG_NUMBERS1(tokens, WN_pragma_arg1(apragma)); 01534 break; 01535 01536 case WN_PRAGMA_PREFETCH_REF: 01537 if (WN_next(apragma) != NULL && 01538 WN_operator(WN_next(apragma)) == OPR_PREFETCH) 01539 { 01540 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01541 Append_Token_String(tokens, "PREFETCH_REF"); 01542 Append_Prefetch_Attributes(tokens, 01543 WN_next(apragma), 01544 WN_pragma_arg2(apragma)); 01545 } 01546 break; 01547 01548 case WN_PRAGMA_PREFETCH_REF_DISABLE: 01549 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01550 Append_Token_String(tokens, "PREFETCH_REF_DISABLE"); 01551 Append_Token_Special(tokens, '='); 01552 Append_A_Clause_Symbol(tokens, apragma, 0/*ofst*/); 01553 if (WN_pragma_arg2(apragma) > 0) 01554 { 01555 Append_Token_Special(tokens, ','); 01556 Append_Token_String(tokens, "size"); 01557 Append_Token_Special(tokens, '='); 01558 EMIT_ARG_NUMBERS1(tokens, WN_pragma_arg2(apragma)); 01559 } 01560 break; 01561 01562 case WN_PRAGMA_DISTRIBUTE: 01563 Emit_To_PUinfo_Pragmas(&apragma, context); 01564 break; 01565 01566 case WN_PRAGMA_REDISTRIBUTE: 01567 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01568 Append_Token_String(tokens, "REDISTRIBUTE"); 01569 Append_A_Clause_Symbol(tokens, apragma, 0/*ofst*/); 01570 Append_Distribution(tokens, &apragma, WN_PRAGMA_REDISTRIBUTE); 01571 Append_Pragma_Clauses(tokens, &apragma, context); 01572 break; 01573 01574 case WN_PRAGMA_DISTRIBUTE_RESHAPE: 01575 Emit_To_PUinfo_Pragmas(&apragma, context); 01576 break; 01577 01578 case WN_PRAGMA_DYNAMIC: 01579 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01580 Append_Token_String(tokens, "DYNAMIC"); 01581 Append_A_Clause_Symbol(tokens, apragma, 0/*ofst*/); 01582 break; 01583 01584 case WN_PRAGMA_IVDEP: 01585 WN2F_Directive_Newline(tokens, "CDIR$", WN_Get_Linenum(apragma)); 01586 Append_Token_String(tokens, "IVDEP"); 01587 break; 01588 01589 case WN_PRAGMA_DOACROSS: 01590 /* Ignore deeper nests. 01591 */ 01592 if (WN_pragma_nest(apragma) <= 0 && 01593 !Ignore_Synchronized_Construct(apragma, context)) 01594 { 01595 surrounding_region = W2CF_Get_Parent(W2CF_Get_Parent(apragma)); 01596 first_clause = WN_next(apragma); 01597 01598 Put_Pragma_Start_With_Caveats(tokens,apragma,TRUE); 01599 Append_Token_String(tokens, "DOACROSS"); 01600 if (WN_max_nest_level(apragma) > 1) 01601 Append_Nest_Clauses(tokens, 01602 surrounding_region, 01603 WN_max_nest_level(apragma), 01604 context); 01605 apragma = first_clause; 01606 Append_Pragma_Clauses(tokens, &apragma, context); 01607 Append_Implicit_Locals(tokens, 01608 WN_PRAGMA_DOACROSS, 01609 WN_region_body(surrounding_region), 01610 first_clause); 01611 } 01612 else 01613 { 01614 apragma = WN_next(apragma); 01615 Skip_Pragma_Clauses(&apragma, context); 01616 } 01617 break; 01618 01619 case WN_PRAGMA_MPSCHEDTYPE: 01620 /* Can be both a clause and a pragma. 01621 */ 01622 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01623 if (WN2F_is_omp(apragma)) 01624 { 01625 Append_Token_String(tokens, "SCHEDULE"); 01626 Append_Token_Special(tokens, '('); 01627 Append_MP_Schedtype(tokens, apragma); 01628 if (WN_next(apragma) != NULL && 01629 WN_pragma(WN_next(apragma)) == WN_PRAGMA_CHUNKSIZE) 01630 { 01631 apragma = WN_next(apragma); 01632 Append_Token_Special(tokens, ','); 01633 WN2F_Append_Value_Reference(tokens, WN_kid0(apragma)); 01634 } 01635 Append_Token_Special(tokens, ')'); 01636 apragma = WN_next(apragma); 01637 } 01638 else 01639 { 01640 Append_Token_String(tokens, "MP_SCHEDTYPE"); 01641 Append_Token_Special(tokens, '='); 01642 Append_MP_Schedtype(tokens, apragma); 01643 } 01644 break; 01645 01646 case WN_PRAGMA_BARRIER: 01647 if (W2F_Prompf_Emission) 01648 WN2F_Start_Prompf_Construct(tokens, apragma); 01649 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01650 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01651 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01652 Append_Token_String(tokens, "BARRIER"); 01653 if (W2F_Prompf_Emission) 01654 WN2F_End_Prompf_Construct(tokens, apragma); 01655 break; 01656 01657 case WN_PRAGMA_COPYIN: 01658 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01659 if (WN2F_is_omp(apragma)) 01660 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01661 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01662 Append_Token_String(tokens, "COPYIN"); 01663 if (WN_operator(apragma) == OPR_XPRAGMA) 01664 Append_Clause_Expressions(tokens, 01665 (WN_PRAGMA_ID)WN_pragma(apragma), 01666 &apragma); 01667 else 01668 { 01669 /* A common symbol */ 01670 Append_Token_Special(tokens, '/'); 01671 ST2F_use_translate(tokens, WN_st(apragma)); 01672 Append_Token_Special(tokens, '/'); 01673 } 01674 break; 01675 01676 case WN_PRAGMA_CRITICAL_SECTION_BEGIN: 01677 if (W2F_Prompf_Emission) 01678 WN2F_Start_Prompf_Construct(tokens, apragma); 01679 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01680 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01681 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01682 if (WN2F_is_omp(apragma)) 01683 Append_Token_String(tokens, "CRITICAL"); 01684 else 01685 Append_Token_String(tokens, "CRITICAL SECTION"); 01686 if (WN_operator(apragma) == OPR_XPRAGMA) 01687 Append_Clause_Expressions(tokens, 01688 (WN_PRAGMA_ID)WN_pragma(apragma), 01689 &apragma); 01690 break; 01691 01692 case WN_PRAGMA_CRITICAL_SECTION_END: 01693 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01694 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01695 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01696 if (WN2F_is_omp(apragma)) 01697 Append_Token_String(tokens, "END CRITICAL"); 01698 else 01699 Append_Token_String(tokens, "END CRITICAL SECTION"); 01700 if (W2F_Prompf_Emission) 01701 WN2F_End_Prompf_Construct(tokens, apragma); 01702 break; 01703 01704 case WN_PRAGMA_ORDERED_BEGIN: 01705 if (W2F_Prompf_Emission) 01706 WN2F_Start_Prompf_Construct(tokens, apragma); 01707 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01708 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01709 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01710 Append_Token_String(tokens, "ORDERED"); 01711 if (WN_operator(apragma) == OPR_XPRAGMA) 01712 Append_Clause_Expressions(tokens, 01713 (WN_PRAGMA_ID)WN_pragma(apragma), 01714 &apragma); 01715 break; 01716 01717 case WN_PRAGMA_ORDERED_END: 01718 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01719 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01720 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01721 Append_Token_String(tokens, "END ORDERED"); 01722 if (W2F_Prompf_Emission) 01723 WN2F_End_Prompf_Construct(tokens, apragma); 01724 break; 01725 01726 case WN_PRAGMA_ATOMIC: 01727 if (W2F_Prompf_Emission) 01728 WN2F_Start_Prompf_Construct(tokens, apragma); 01729 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01730 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01731 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01732 Append_Token_String(tokens, "ATOMIC"); 01733 if (WN_operator(apragma) == OPR_XPRAGMA) 01734 Append_Clause_Expressions(tokens, 01735 (WN_PRAGMA_ID)WN_pragma(apragma), 01736 &apragma); 01737 if (W2F_Prompf_Emission) 01738 WN2F_End_Prompf_Construct(tokens, this_pragma); 01739 break; 01740 01741 case WN_PRAGMA_PARALLEL_BEGIN: 01742 /* Ignore deeper nests. 01743 */ 01744 if (!Ignore_Synchronized_Construct(apragma, context)) 01745 { 01746 surrounding_region = W2CF_Get_Parent(W2CF_Get_Parent(apragma)); 01747 first_clause = WN_next(apragma); 01748 01749 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01750 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01751 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01752 Append_Token_String(tokens, "PARALLEL"); 01753 apragma = first_clause; 01754 Append_Pragma_Clauses(tokens, &apragma, context); 01755 Append_Implicit_Locals(tokens, 01756 WN_PRAGMA_PARALLEL_BEGIN, 01757 WN_region_body(surrounding_region), 01758 first_clause); 01759 } 01760 break; 01761 01762 case WN_PRAGMA_PARALLEL_DO: 01763 /* Ignore deeper nests. 01764 */ 01765 if (WN_pragma_nest(apragma) <= 0 && 01766 !Ignore_Synchronized_Construct(apragma, context)) 01767 { 01768 surrounding_region = W2CF_Get_Parent(W2CF_Get_Parent(apragma)); 01769 first_clause = WN_next(apragma); 01770 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01771 //Put_Pragma_Start_With_Caveats(tokens,apragma,TRUE); 01772 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01773 Append_Token_String(tokens, "PARALLEL DO"); 01774 01775 if (WN_max_nest_level(apragma) > 1) 01776 Append_Nest_Clauses(tokens, 01777 surrounding_region, 01778 WN_max_nest_level(apragma), 01779 context); 01780 apragma = first_clause; 01781 Append_Pragma_Clauses(tokens, &apragma, context); 01782 Append_Implicit_Locals(tokens, 01783 WN_PRAGMA_PARALLEL_DO, 01784 WN_region_body(surrounding_region), 01785 first_clause); 01786 } 01787 else 01788 { 01789 apragma = WN_next(apragma); 01790 Skip_Pragma_Clauses(&apragma, context); 01791 } 01792 break; 01793 01794 case WN_PRAGMA_PDO_BEGIN: 01795 /* Ignore deeper nests. 01796 */ 01797 if (WN_pragma_nest(apragma) <= 0 && 01798 !Ignore_Synchronized_Construct(apragma, context)) 01799 { 01800 surrounding_region = W2CF_Get_Parent(W2CF_Get_Parent(apragma)); 01801 first_clause = WN_next(apragma); 01802 01803 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01804 //Put_Pragma_Start_With_Caveats(tokens,apragma,TRUE); 01805 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01806 if (WN2F_is_omp(apragma)) 01807 Append_Token_String(tokens, "DO"); 01808 else 01809 Append_Token_String(tokens, "PDO"); 01810 01811 if (WN_max_nest_level(apragma) > 1) 01812 Append_Nest_Clauses(tokens, 01813 surrounding_region, 01814 WN_max_nest_level(apragma), 01815 context); 01816 apragma = first_clause; 01817 Append_Pragma_Clauses(tokens, &apragma, context); 01818 01819 /* Turn this off for now, since we also need to avoid declaring 01820 * as local variables declared as shared in the enclosing 01821 * parallel region. 01822 * 01823 * Append_Implicit_Locals(tokens, 01824 * WN_PRAGMA_PDO_BEGIN, 01825 * WN_region_body(surrounding_region), 01826 * first_clause); 01827 */ 01828 } 01829 else 01830 { 01831 apragma = WN_next(apragma); 01832 Skip_Pragma_Clauses(&apragma, context); 01833 } 01834 break; 01835 01836 /* region construct => construct id on region..*/ 01837 01838 case WN_PRAGMA_PARALLEL_SECTIONS: 01839 case WN_PRAGMA_PSECTION_BEGIN: 01840 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01841 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01842 //WN2F_Append_Pragma_Preamble(tokens,apragma); 01843 if (WN2F_is_omp(apragma)) 01844 Append_Token_String(tokens, "PARALLEL SECTIONS"); 01845 else 01846 Append_Token_String(tokens, "PSECTIONS"); 01847 apragma = WN_next(apragma); 01848 Append_Pragma_Clauses(tokens, &apragma, context); 01849 break; 01850 01851 case WN_PRAGMA_SECTION: 01852 if (W2F_Prompf_Emission) 01853 { 01854 if (WN2F_Prompf_Subsection != NULL) 01855 { 01856 // End a the previous SECTION directive seen! 01857 // 01858 WN2F_End_Prompf_Construct(tokens, WN2F_Prompf_Subsection); 01859 } 01860 WN2F_Prompf_Subsection = apragma; 01861 WN2F_Start_Prompf_Construct(tokens, apragma); 01862 } 01863 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01864 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01865 //WN2F_Append_Pragma_Preamble(tokens,apragma); 01866 Append_Token_String(tokens, "SECTION"); 01867 break; 01868 01869 case WN_PRAGMA_PARALLEL_WORKSHARE: 01870 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01871 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01872 //WN2F_Append_Pragma_Preamble(tokens,apragma); 01873 Append_Token_String(tokens, "PARALLEL WORKSHARE"); 01874 apragma = WN_next(apragma); 01875 Append_Pragma_Clauses(tokens, &apragma, context); 01876 break; 01877 01878 case WN_PRAGMA_WORKSHARE: 01879 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01880 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01881 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01882 Append_Token_String(tokens, "WORKSHARE"); 01883 break; 01884 01885 /* region construct => construct id on region..*/ 01886 01887 case WN_PRAGMA_SINGLE_PROCESS_BEGIN: 01888 if (!Ignore_Synchronized_Construct(apragma, context)) 01889 { 01890 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01891 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01892 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01893 if (WN2F_is_omp(apragma)) 01894 Append_Token_String(tokens, "SINGLE"); 01895 else 01896 Append_Token_String(tokens, "SINGLE PROCESS"); 01897 apragma = WN_next(apragma); 01898 Append_Pragma_Clauses(tokens, &apragma, context); 01899 } 01900 break; 01901 01902 /* region construct => construct id on region..*/ 01903 01904 case WN_PRAGMA_MASTER_BEGIN: 01905 if (!Ignore_Synchronized_Construct(apragma, context)) 01906 { 01907 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01908 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01909 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01910 if (WN2F_is_omp(apragma)) 01911 Append_Token_String(tokens, "MASTER"); 01912 else 01913 Append_Token_String(tokens, "MASTER PROCESS"); 01914 } 01915 break; 01916 01917 case WN_PRAGMA_FLUSH: 01918 WN2F_OMP_or_PAR_Directive_Newline(tokens,apragma); 01919 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01920 //WN2F_Append_Pragma_Preamble(tokens,apragma) ; 01921 Append_Token_String(tokens, "FLUSH"); 01922 apragma = WN_next(apragma); 01923 Append_Pragma_Clauses(tokens, &apragma, context); 01924 break; 01925 01926 case WN_PRAGMA_NUMTHREADS: 01927 /* Should only appear for C, but if we ever see it, we also emit 01928 * it for Fortran. 01929 */ 01930 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01931 Append_Token_String(tokens, "NUMTHREADS"); 01932 Append_Clause_Expressions(tokens, 01933 (WN_PRAGMA_ID)WN_pragma(apragma), 01934 &apragma); 01935 break; 01936 01937 case WN_PRAGMA_PAGE_PLACE: 01938 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(apragma)); 01939 Append_Token_String(tokens, "PAGE_PLACE"); 01940 Append_Clause_Expressions(tokens, 01941 (WN_PRAGMA_ID)WN_pragma(apragma), 01942 &apragma); 01943 break; 01944 01945 case WN_PRAGMA_NORECURRENCE: 01946 WN2F_Directive_Newline(tokens, "CDIR$", WN_Get_Linenum(apragma)); 01947 Append_Token_String(tokens, "NO RECURRENCE"); 01948 break; 01949 01950 case WN_PRAGMA_NEXT_SCALAR: 01951 WN2F_Directive_Newline(tokens, "CDIR$", WN_Get_Linenum(apragma)); 01952 Append_Token_String(tokens, "NEXT SCALAR"); 01953 break; 01954 01955 case WN_PRAGMA_KAP_CONCURRENTIZE: 01956 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01957 Append_Token_String(tokens, "CONCURRENTIZE"); 01958 break; 01959 01960 case WN_PRAGMA_KAP_NOCONCURRENTIZE: 01961 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01962 Append_Token_String(tokens, "NO CONCURRENTIZE"); 01963 break; 01964 01965 case WN_PRAGMA_KAP_ASSERT_PERMUTATION: 01966 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01967 Append_Token_String(tokens, "ASSERT PERMUTATION"); 01968 Append_A_Clause_Symbol(tokens, apragma, 0/*ofst*/); 01969 break; 01970 01971 case WN_PRAGMA_CRI_CNCALL: 01972 case WN_PRAGMA_KAP_ASSERT_CONCURRENT_CALL: 01973 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01974 Append_Token_String(tokens, "ASSERT CONCURRENT CALL"); 01975 break; 01976 01977 case WN_PRAGMA_KAP_ASSERT_DO: 01978 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01979 if (WN_pragma_arg1(apragma) == ASSERT_DO_CONCURRENT) 01980 Append_Token_String(tokens, "ASSERT DO (CONCURRENT)"); 01981 else 01982 Append_Token_String(tokens, "ASSERT DO (SERIAL)"); 01983 break; 01984 01985 case WN_PRAGMA_KAP_ASSERT_DOPREFER: 01986 WN2F_Directive_Newline(tokens, "C*$*", WN_Get_Linenum(apragma)); 01987 if (WN_pragma_arg1(apragma) == ASSERT_DO_CONCURRENT) 01988 Append_Token_String(tokens, "ASSERT DO PREFER (CONCURRENT)"); 01989 else 01990 Append_Token_String(tokens, "ASSERT DO PREFER (SERIAL)"); 01991 break; 01992 01993 /* eraxxon: OpenAD specific pragmas */ 01994 case WN_PRAGMA_OPENAD_XXX: { 01995 if (WN_has_sym(apragma)) { 01996 std::string pragmaName(Targ_Print(NULL, WN_val(apragma))); 01997 std::transform(pragmaName.begin(), 01998 pragmaName.end(), 01999 pragmaName.begin(), 02000 static_cast < int(*)(int) > (tolower)); 02001 if (pragmaName.compare(1,filePragma.length(),filePragma)==0) { 02002 break; 02003 } 02004 } 02005 WN2F_Directive_Newline(tokens, "C$OPENAD XXX", WN_Get_Linenum(apragma)); 02006 Append_Token_Special(tokens, ' '); 02007 Append_ST_String(tokens, apragma); 02008 break; 02009 } 02010 02011 case WN_PRAGMA_OPENAD_DEPENDENT: { 02012 WN2F_Directive_Newline(tokens, "C$OPENAD DEPENDENT(", WN_Get_Linenum(apragma)); 02013 ST* st = WN_st(apragma); 02014 const char* name = ST_name(st); 02015 Append_Token_String(tokens,name); 02016 Append_Token_Special(tokens, ')'); 02017 break; 02018 } 02019 case WN_PRAGMA_OPENAD_INDEPENDENT: { 02020 WN2F_Directive_Newline(tokens, "C$OPENAD INDEPENDENT(", WN_Get_Linenum(apragma)); 02021 ST* st = WN_st(apragma); 02022 const char* name = ST_name(st); 02023 Append_Token_String(tokens,name); 02024 Append_Token_Special(tokens, ')'); 02025 break; 02026 } 02027 02028 default: 02029 /* The others are always clauses that are processed as part of other 02030 * pragmas, or they are not to be emitted. 02031 */ 02032 break; 02033 02034 } /* switch on pragma cases */ 02035 02036 /* See if we have already advanced to the next pragma, e.g. as a result 02037 * of calling Append_Pragma_Clauses() or Append_Clause_Symbols(), 02038 * and if not so, then advance to the next pragma. 02039 */ 02040 if (apragma == *next) 02041 *next = WN_next(apragma); 02042 else 02043 *next = apragma; 02044 02045 } /* WN2F_process_pragma */ 02046 02047 02048 /* ====================== Exported Functions ====================== */ 02049 /* ================================================================ */ 02050 02051 02052 BOOL 02053 WN2F_Skip_Pragma_Stmt(WN *wn) 02054 { 02055 /* This assumes that any pragma related nodes to be skipped will be 02056 * accessed in sequence, and that this routine will be called at most 02057 * once per such node. 02058 */ 02059 BOOL found = (Pragmas_To_Skip.array[Pragmas_To_Skip.start] == wn); 02060 02061 if (found) 02062 { 02063 if (Pragmas_To_Skip.end - Pragmas_To_Skip.start == 1) 02064 { 02065 Pragmas_To_Skip.start = Pragmas_To_Skip.end = 0; 02066 Pragmas_To_Skip.array[0] = NULL; 02067 } 02068 else 02069 { 02070 Pragmas_To_Skip.start++; 02071 } 02072 } 02073 return found; 02074 } /* WN2F_Skip_Pragma_Stmt */ 02075 02076 02077 WN2F_STATUS 02078 WN2F_pragma(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context) 02079 { 02080 WN *skip; 02081 WN *next = wn; 02082 02083 ASSERT_DBG_FATAL(WN_operator(wn) == OPR_PRAGMA || 02084 WN_operator(wn) == OPR_XPRAGMA, 02085 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_pragma")); 02086 02087 /* If this is a purple code-extraction, insert a placeholder 02088 * for purple-specific initialization. 02089 */ 02090 if (W2F_Purple_Emission && WN_pragma(wn) == WN_PRAGMA_PREAMBLE_END) 02091 { 02092 /* <#PRP_XSYM:INIT name, id, sclass, export#> 02093 */ 02094 Append_F77_Indented_Newline(tokens, 1, NULL/*label*/); 02095 Append_Token_String(tokens, "<#PRP_XSYM:INIT_STMT"); 02096 WN2F_Append_Purple_Funcinfo(tokens); 02097 Append_Token_String(tokens, "#>"); 02098 next = WN_next(wn); 02099 } 02100 else 02101 { 02102 WN2F_process_pragma(tokens, &next, context); 02103 } 02104 02105 ASSERT_FATAL(Pragmas_To_Skip.end == 0, 02106 (DIAG_W2F_BUFFER_ERROR, 02107 "Unexpected index for Pragmas_To_Skip in WN2F_pragma()")); 02108 02109 /* For pragmas inlined in code, we need to keep track of the pragmas 02110 * that have already been processed. 02111 */ 02112 for (skip = WN_next(wn); skip != next; skip = WN_next(skip)) 02113 { 02114 ASSERT_FATAL(Pragmas_To_Skip.end < MAX_PRAGMAS_TO_SKIP, 02115 (DIAG_W2F_BUFFER_ERROR, 02116 "Too many pragmas in sequence in WN2F_pragma()")); 02117 02118 Pragmas_To_Skip.array[Pragmas_To_Skip.end++] = skip; 02119 } 02120 02121 return EMPTY_WN2F_STATUS; 02122 } /* WN2F_pragma */ 02123 02124 02125 WN2F_STATUS 02126 WN2F_pragma_list_begin(TOKEN_BUFFER tokens, 02127 WN *first_pragma, 02128 WN2F_CONTEXT context) 02129 { 02130 /* This is called for a region or a func_entry, which has a separate 02131 * block to hold a pragma-list. 02132 */ 02133 WN *next_pragma = first_pragma; 02134 02135 while (next_pragma != NULL) 02136 { 02137 if (WN_operator(next_pragma) == OPR_PRAGMA || 02138 WN_operator(next_pragma) == OPR_XPRAGMA) 02139 WN2F_process_pragma(tokens, &next_pragma, context); 02140 else if (WN_operator(next_pragma) == OPR_INTERFACE) { 02141 WN2F_interface_blk(tokens,next_pragma, context); 02142 next_pragma = WN_next(next_pragma); 02143 } 02144 else 02145 next_pragma = WN_next(next_pragma); 02146 } 02147 return EMPTY_WN2F_STATUS; 02148 } /* WN2F_pragma_list_begin */ 02149 02150 02151 WN2F_STATUS 02152 WN2F_pragma_list_end(TOKEN_BUFFER tokens, 02153 WN *first_pragma, 02154 WN2F_CONTEXT context) 02155 { 02156 /* This is called for a region or a func_entry, which has a separate 02157 * block to hold a pragma-list. 02158 */ 02159 BOOL emitted = TRUE; 02160 02161 /* Skip code inserted into the pragma region (may occur for C++, so 02162 * why not for other languages?). 02163 */ 02164 while (first_pragma != NULL && 02165 WN_operator(first_pragma) != OPR_PRAGMA && 02166 WN_operator(first_pragma) != OPR_XPRAGMA) 02167 { 02168 first_pragma = WN_next(first_pragma); 02169 } 02170 02171 if (first_pragma != NULL) 02172 { 02173 ASSERT_DBG_FATAL(WN_operator(first_pragma) == OPR_PRAGMA || 02174 WN_operator(first_pragma) == OPR_XPRAGMA, 02175 (DIAG_W2F_UNEXPECTED_OPC, "WN2F_pragma_list_end")); 02176 02177 switch (WN_pragma(first_pragma)) 02178 { 02179 case WN_PRAGMA_PARALLEL_BEGIN: 02180 if (!Ignore_Synchronized_Construct(first_pragma, context)) 02181 { 02182 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02183 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(first_pragma)); 02184 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02185 Append_Token_String(tokens, "END PARALLEL"); 02186 } 02187 break; 02188 02189 case WN_PRAGMA_DOACROSS: 02190 case WN_PRAGMA_PARALLEL_DO: 02191 break; 02192 02193 case WN_PRAGMA_PDO_BEGIN: 02194 if (WN_pragma_nest(first_pragma) <= 0 && 02195 !Ignore_Synchronized_Construct(first_pragma, context)) 02196 { 02197 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02198 //Put_Pragma_Start_With_Caveats(tokens,first_pragma,FALSE); 02199 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02200 if (WN2F_is_omp(first_pragma)) 02201 Append_Token_String(tokens, "END DO"); 02202 else 02203 Append_Token_String(tokens, "END PDO"); 02204 } 02205 break; 02206 02207 case WN_PRAGMA_PARALLEL_SECTIONS: 02208 case WN_PRAGMA_PSECTION_BEGIN: 02209 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02210 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(first_pragma)); 02211 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02212 // correctly end the OpenMP PARALLEL SECTIONS ([email protected]) 02213 if (WN2F_is_omp(first_pragma)) 02214 { 02215 Append_Token_String(tokens, "END PARALLEL SECTIONS"); 02216 if (WN2F_Prompf_Subsection != NULL) 02217 { 02218 // End a the last SECTION directive seen! 02219 // 02220 WN2F_End_Prompf_Construct(tokens, WN2F_Prompf_Subsection); 02221 WN2F_Prompf_Subsection = NULL; 02222 } 02223 } 02224 else 02225 Append_Token_String(tokens, "END PSECTION"); 02226 break; 02227 02228 case WN_PRAGMA_PARALLEL_WORKSHARE: 02229 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02230 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(first_pragma)); 02231 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02232 Append_Token_String(tokens, "END PARALLEL WORKSHARE"); 02233 break; 02234 02235 case WN_PRAGMA_WORKSHARE: 02236 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02237 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(first_pragma)); 02238 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02239 Append_Token_String(tokens, "END WORKSHARE"); 02240 break; 02241 02242 case WN_PRAGMA_SINGLE_PROCESS_BEGIN: 02243 if (!Ignore_Synchronized_Construct(first_pragma, context)) 02244 { 02245 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02246 //WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(first_pragma)); 02247 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02248 if (WN2F_is_omp(first_pragma)) 02249 Append_Token_String(tokens, "END SINGLE"); 02250 else 02251 Append_Token_String(tokens, "END SINGLE PROCESS"); 02252 /* append clause COPYPRIVATE ([email protected]) */ 02253 WN *wn = first_pragma; 02254 while(wn != NULL) 02255 if ((WN_operator(wn) == OPR_PRAGMA || WN_operator(wn) == OPR_XPRAGMA) && 02256 WN_pragma(wn) == WN_PRAGMA_COPYPRIVATE) 02257 { 02258 Append_Token_String(tokens, "copyprivate"); 02259 Append_Clause_Symbols(tokens, WN_PRAGMA_COPYPRIVATE, &wn); 02260 } 02261 else 02262 wn = WN_next(wn); 02263 } 02264 break; 02265 02266 case WN_PRAGMA_MASTER_BEGIN: 02267 if (!Ignore_Synchronized_Construct(first_pragma, context)) 02268 { 02269 WN2F_Directive_Newline(tokens, "C$", WN_Get_Linenum(first_pragma)); 02270 WN2F_OMP_or_PAR_Directive_Newline(tokens,first_pragma); 02271 //WN2F_Append_Pragma_Preamble(tokens,first_pragma); 02272 //Append_Token_String(tokens, "END MASTER"); 02273 } 02274 break; 02275 02276 default: 02277 emitted = FALSE; 02278 break; /* Not a region that needs an END pragma */ 02279 } 02280 02281 if (emitted && WN2F_pragma_list_nowait(first_pragma)) 02282 Append_Token_String(tokens, "nowait"); 02283 } 02284 return EMPTY_WN2F_STATUS; 02285 } /* WN2F_pragma_list_end */ 02286 02287 02288 BOOL 02289 Ignore_Synchronized_Construct(WN *construct_pragma, 02290 WN2F_CONTEXT context) 02291 { 02292 /* This can be TRUE for DOACROSS, PARALLEL, and any paralellization 02293 * related construct that may occur within a parallel region. 02294 * It only applies for prompf/mplist (i.e. when Run_w2fc_early). 02295 */ 02296 BOOL ignore_construct; 02297 02298 Is_True(WN_operator(construct_pragma) == OPR_PRAGMA, 02299 ("Unexpected WHIRL tree in Ignore_Synchronized_Construct")); 02300 02301 if (!Run_w2fc_early) 02302 { 02303 ignore_construct = FALSE; 02304 } 02305 else 02306 { 02307 if (WN_pragma(construct_pragma) != WN_PRAGMA_DOACROSS) 02308 construct_pragma = Get_Enclosing_Parallel_Region(construct_pragma); 02309 02310 if (construct_pragma == NULL) 02311 ignore_construct = FALSE; 02312 else 02313 { 02314 WN *clause = WN_next(construct_pragma); 02315 WN *beyond_last_clause = clause; 02316 02317 Skip_Pragma_Clauses(&beyond_last_clause, context); 02318 while (clause != beyond_last_clause && 02319 WN_pragma(clause) != WN_PRAGMA_SYNC_DOACROSS) 02320 clause = WN_next(clause); 02321 ignore_construct = (clause != beyond_last_clause); 02322 } 02323 } 02324 return ignore_construct; 02325 } /* Ignore_Synchronized_Construct */ 02326