Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wn2f_pragma.cxx
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines