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