Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
wn2f.h
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 #ifndef wn2f_INCLUDED
00037 #define wn2f_INCLUDED
00038 /* ====================================================================
00039  * ====================================================================
00040  *
00041  *
00042  * Revision history:
00043  *  07-Apr-1995 - Original Version
00044  *
00045  * Description:
00046  *
00047  *   WN2F_CONTEXT: Information about the context in which a translation
00048  *           of a WN subtree into Fortran occurs.
00049  *
00050  *   WN2F_STATUS: The status of a translation of a WN subtree into 
00051  *           Fortran.
00052  *
00053  *   WN2F_Can_Assign_Types:
00054  *           This determines whether or not a value of type t1 can
00055  *           be used anywhere we expect a value of type t2.  When
00056  *           this condition is TRUE, yet t1 is different from t2,
00057  *           we expect the implicit Fortran type coersion to transform
00058  *           an object of one type to the other.
00059  *
00060  *   WN2F_Stmt_Newline:
00061  *           Use this to start each statement on a new line.
00062  *
00063  *   WN2F_Address_Of:
00064  *           Generates an expression to explicitly take the address 
00065  *           of the lvalue constituted by the tokens in the given
00066  *           token-buffer.
00067  *
00068  *   WN2F_Offset_Symref:
00069  *           Generate code to access the memory location denoted by
00070  *           the object type, based on the base-symbol, its given
00071  *           address type and the offset from the base of the symbol.
00072  *
00073  *   WN2F_Offset_Memref:
00074  *           Generate code to access the memory location denoted by
00075  *           the object type, based on the base-address expression,
00076  *           its given type and the offset from the base-address.
00077  *
00078  *   WN2F_initialize: This initializes any WN to Fortran translation
00079  *           and must always be called prior to any WN2F_translate()
00080  *           call.
00081  *
00082  *   WN2F_finalize: This finalizes any WN to Fortran translation
00083  *           and should be called after all processing related
00084  *           to a whirl2f translation is complete.
00085  *
00086  *   WN2F_translate:  Translates a WN subtree into a sequence of Fortran
00087  *           tokens, which are added to the given TOKEN_BUFFER.
00088  *
00089  *   WN2F_translate_purple_main:  A rather special translation routine,
00090  *           which ignores the body of the given PU, and translates
00091  *           parameters to become local variables.  It inserts a call
00092  *           to a purple region PU, and inserts placeholders for items
00093  *           to be inserted by purple at a later processing stage.
00094  *
00095  *   WN2F_Emit_End_Stmt: a utility to insert an END statement for
00096  *            an f90 program which contains nested PUs
00097  *
00098  *   WN2F_Sum_Offsets:  Sums any ADD nodes encountered in an address tree
00099  *
00100  * ====================================================================
00101  * ====================================================================
00102  */
00103 
00104 
00105     /* ---- Result status and context of a WN to Fortran translation ---- */
00106     /* ------------------------------------------------------------------ */
00107 
00108 typedef mUINT32 WN2F_STATUS;
00109 #define EMPTY_WN2F_STATUS (WN2F_STATUS)0
00110 
00111 typedef struct WN2F_Context
00112 {
00113    mUINT32 flags;
00114    WN     *wn;
00115 } WN2F_CONTEXT;
00116 #define INIT_WN2F_CONTEXT {0, NULL}
00117 #define reset_WN2F_CONTEXT(c) ((c).flags = 0U, (c).wn = NULL)
00118 
00119 /* Indicates to a block translation that this is the body of a PU.
00120  */
00121 #define WN2F_CONTEXT_NEW_PU 0x000000001
00122 #define WN2F_CONTEXT_new_pu(c) ((c).flags & WN2F_CONTEXT_NEW_PU)
00123 #define set_WN2F_CONTEXT_new_pu(c)\
00124    ((c).flags = (c).flags | WN2F_CONTEXT_NEW_PU)
00125 #define reset_WN2F_CONTEXT_new_pu(c)\
00126    ((c).flags = (c).flags & ~WN2F_CONTEXT_NEW_PU)
00127 
00128 /* Indicates to a block translation that an induction-step must be
00129  * inserted at the end of this block, before the loop-termination
00130  * label.
00131  */
00132 #define WN2F_CONTEXT_INSERT_INDUCTION 0x000000002
00133 #define WN2F_CONTEXT_insert_induction(c)\
00134    ((c).flags & WN2F_CONTEXT_INSERT_INDUCTION)
00135 #define WN2F_CONTEXT_induction_stmt(c) (c).wn
00136 #define set_WN2F_CONTEXT_induction_step(c, stmt)\
00137    ((c).flags = (c).flags | WN2F_CONTEXT_INSERT_INDUCTION,\
00138     (c).wn = stmt)
00139 #define reset_WN2F_CONTEXT_induction_step(c)\
00140    ((c).flags = (c).flags & ~WN2F_CONTEXT_INSERT_INDUCTION,\
00141     (c).wn = NULL)
00142 
00143 /* Indicates that we expect to dereference an address expression.
00144  * LDA or ARRAY nodes should not be translated unless this flag has
00145  * been set, other than when we can use an "address of" operator
00146  * in Fortran.
00147  */
00148 #define WN2F_CONTEXT_DEREF_ADDR 0x000000004
00149 #define WN2F_CONTEXT_deref_addr(c) ((c).flags & WN2F_CONTEXT_DEREF_ADDR)
00150 #define set_WN2F_CONTEXT_deref_addr(c)\
00151    ((c).flags = (c).flags | WN2F_CONTEXT_DEREF_ADDR)
00152 #define reset_WN2F_CONTEXT_deref_addr(c)\
00153    ((c).flags = (c).flags & ~WN2F_CONTEXT_DEREF_ADDR)
00154 
00155 /* Indicates that we should not start the next statement on a new
00156  * line.  This only needs to be taken into account for statement
00157  * types where it is an issue.
00158  */
00159 #define WN2F_CONTEXT_NO_NEWLINE 0x000000008
00160 #define WN2F_CONTEXT_no_newline(c) ((c).flags & WN2F_CONTEXT_NO_NEWLINE)
00161 #define set_WN2F_CONTEXT_no_newline(c)\
00162    ((c).flags = (c).flags | WN2F_CONTEXT_NO_NEWLINE)
00163 #define reset_WN2F_CONTEXT_no_newline(c)\
00164    ((c).flags = (c).flags & ~WN2F_CONTEXT_NO_NEWLINE)
00165 
00166 /* This flag indicates that we are in a context where we expect the
00167  * arguments to the current expression to evaluate to logically typed
00168  * values.
00169  */
00170 #define WN2F_CONTEXT_HAS_LOGICAL_ARG 0x00000010
00171 #define WN2F_CONTEXT_has_logical_arg(c)\
00172    ((c).flags & WN2F_CONTEXT_HAS_LOGICAL_ARG)
00173 #define set_WN2F_CONTEXT_has_logical_arg(c)\
00174    ((c).flags = (c).flags | WN2F_CONTEXT_HAS_LOGICAL_ARG)
00175 #define reset_WN2F_CONTEXT_has_logical_arg(c)\
00176    ((c).flags = (c).flags & ~WN2F_CONTEXT_HAS_LOGICAL_ARG)
00177 
00178 /* This flag indicates that we are in a context where we expect the
00179  * current expression to evaluate to a logically typed arg.
00180  */
00181 //  #define WN2F_CONTEXT_IS_LOGICAL_ARG 0x00000020
00182 
00183 #define WN2F_CONTEXT_IS_LOGICAL_ARG 0x02000000
00184 #define WN2F_CONTEXT_is_logical_arg(c)\
00185    ((c).flags & WN2F_CONTEXT_IS_LOGICAL_ARG)
00186 #define set_WN2F_CONTEXT_is_logical_arg(c)\
00187    ((c).flags = (c).flags | WN2F_CONTEXT_IS_LOGICAL_ARG)
00188 #define reset_WN2F_CONTEXT_is_logical_arg(c)\
00189    ((c).flags = (c).flags & ~WN2F_CONTEXT_IS_LOGICAL_ARG)
00190 
00191 /* this flag indicates that we need to print out logical
00192  * operations such as .eqv. instead of arith operations like .eq.
00193  *   ------fzhao
00194  */
00195 #define WN2F_CONTEXT_IS_LOGICAL_OPERATION 0x00020000
00196 #define WN2F_CONTEXT_is_logical_operation(c)\
00197    ((c).flags & WN2F_CONTEXT_IS_LOGICAL_OPERATION)
00198 #define set_WN2F_CONTEXT_is_logical_operation(c)\
00199    ((c).flags = (c).flags | WN2F_CONTEXT_IS_LOGICAL_OPERATION)
00200 #define reset_WN2F_CONTEXT_is_logical_operation(c)\
00201    ((c).flags = (c).flags & ~WN2F_CONTEXT_IS_LOGICAL_OPERATION)
00202 
00203 
00204 
00205 /* This flag indicates that we are in a context where we need not
00206  * enclose a Fortran expression in parenthesis (subexpressions may
00207  * still be enclosed in parenthesis.
00208  */
00209 #define WN2F_CONTEXT_NO_PARENTHESIS 0x00000020
00210 #define WN2F_CONTEXT_no_parenthesis(c)\
00211    ((c).flags & WN2F_CONTEXT_NO_PARENTHESIS)
00212 #define set_WN2F_CONTEXT_no_parenthesis(c)\
00213    ((c).flags = (c).flags | WN2F_CONTEXT_NO_PARENTHESIS)
00214 #define reset_WN2F_CONTEXT_no_parenthesis(c)\
00215    ((c).flags = (c).flags & ~WN2F_CONTEXT_NO_PARENTHESIS)
00216 /*****************************************
00217  * WN2F_CONTEXT_NO_PARENTHESIS and WN2F_CONTEXT_IS_LOGICAL_ARG
00218  * use same flag---changed!!
00219  ****************************************/
00220 
00221 /* This flag indicates whether or not a Fortran IO control-list
00222  * should be emitted in keyword form.
00223  */
00224 #define WN2F_CONTEXT_KEYWORD_IOCTRL 0x00000040
00225 #define WN2F_CONTEXT_keyword_ioctrl(c)\
00226    ((c).flags & WN2F_CONTEXT_KEYWORD_IOCTRL)
00227 #define set_WN2F_CONTEXT_keyword_ioctrl(c)\
00228    ((c).flags = (c).flags | WN2F_CONTEXT_KEYWORD_IOCTRL)
00229 #define reset_WN2F_CONTEXT_keyword_ioctrl(c)\
00230    ((c).flags = (c).flags & ~WN2F_CONTEXT_KEYWORD_IOCTRL)
00231 
00232 /* This flag indicates whether or not we are inside a Fortran IO statement.
00233  */
00234 #define WN2F_CONTEXT_IO_STMT 0x00000080
00235 #define WN2F_CONTEXT_io_stmt(c)\
00236    ((c).flags & WN2F_CONTEXT_IO_STMT)
00237 #define set_WN2F_CONTEXT_io_stmt(c)\
00238    ((c).flags = (c).flags | WN2F_CONTEXT_IO_STMT)
00239 #define reset_WN2F_CONTEXT_io_stmt(c)\
00240    ((c).flags = (c).flags & ~WN2F_CONTEXT_IO_STMT)
00241 
00242 /* This flag indicates whether or not to dereference IO_ITEMS.
00243  */
00244 #define WN2F_CONTEXT_DEREF_IO_ITEM 0x00000100
00245 #define WN2F_CONTEXT_deref_io_item(c)\
00246    ((c).flags & WN2F_CONTEXT_DEREF_IO_ITEM)
00247 #define set_WN2F_CONTEXT_deref_io_item(c)\
00248    ((c).flags = (c).flags | WN2F_CONTEXT_DEREF_IO_ITEM)
00249 #define reset_WN2F_CONTEXT_deref_io_item(c)\
00250    ((c).flags = (c).flags & ~WN2F_CONTEXT_DEREF_IO_ITEM)
00251 
00252 /* This flag indicates whether or not to replace an OPC_LABEL
00253  * item with an IOC_VARFMT_ORIGFMT item.
00254  */
00255 #define WN2F_CONTEXT_ORIGFMT_IOCTRL 0x00000200
00256 #define WN2F_CONTEXT_origfmt_ioctrl(c)\
00257    ((c).flags & WN2F_CONTEXT_ORIGFMT_IOCTRL)
00258 #define set_WN2F_CONTEXT_origfmt_ioctrl(c)\
00259    ((c).flags = (c).flags | WN2F_CONTEXT_ORIGFMT_IOCTRL)
00260 #define reset_WN2F_CONTEXT_origfmt_ioctrl(c)\
00261    ((c).flags = (c).flags & ~WN2F_CONTEXT_ORIGFMT_IOCTRL)
00262 
00263 /* This flag indicates whether or not it is safe to remove an
00264  * stid where the lhs is identical to the rhs.
00265  */
00266 #define WN2F_CONTEXT_EMIT_STID 0x00000400
00267 #define WN2F_CONTEXT_emit_stid(c)\
00268    ((c).flags & WN2F_CONTEXT_EMIT_STID)
00269 #define set_WN2F_CONTEXT_emit_stid(c)\
00270    ((c).flags = (c).flags | WN2F_CONTEXT_EMIT_STID)
00271 #define reset_WN2F_CONTEXT_emit_stid(c)\
00272    ((c).flags = (c).flags & ~WN2F_CONTEXT_EMIT_STID)
00273 
00274 
00275 
00276 #define WN2F_CONTEXT_TMP_VAR 0x00100400
00277 #define WN2F_CONTEXT_tmp_var(c)\
00278    ((c).flags & WN2F_TMP_VAR)
00279 #define set_WN2F_CONTEXT_tmp_var(c)\
00280    ((c).flags = (c).flags | WN2F_CONTEXT_TMP_VAR) 
00281 #define reset_WN2F_CONTEXT_tmp_var(c)\
00282    ((c).flags = (c).flags & ~WN2F_CONTEXT_TMP_VAR)
00283 
00284 
00285 
00286 
00287 /* This flag indicates whether or not a pragma directive can apply
00288  * to an explicit region.  A pragma directive that can only apply
00289  * to an explicit region in source-code must be ignored if the 
00290  * region to which it belongs is not emitted.
00291  */
00292 #define WN2F_CONTEXT_EXPLICIT_REGION 0x00000800
00293 #define WN2F_CONTEXT_explicit_region(c)\
00294    ((c).flags & WN2F_CONTEXT_EXPLICIT_REGION)
00295 #define set_WN2F_CONTEXT_explicit_region(c)\
00296    ((c).flags = (c).flags | WN2F_CONTEXT_EXPLICIT_REGION)
00297 #define reset_WN2F_CONTEXT_explicit_region(c)\
00298    ((c).flags = (c).flags & ~WN2F_CONTEXT_EXPLICIT_REGION)
00299 
00300 
00301 /* this flag indicates that formatted IO is being processed 
00302  * It allows interpretation of craylibs IO_NONE specifiers
00303  */
00304 #define WN2F_CONTEXT_FMT_IO 0x00001000
00305 #define WN2F_CONTEXT_fmt_io(c)\
00306    ((c).flags & WN2F_CONTEXT_FMT_IO)
00307 #define set_WN2F_CONTEXT_fmt_io(c)\
00308    ((c).flags = (c).flags | WN2F_CONTEXT_FMT_IO)
00309 #define reset_WN2F_CONTEXT_fmt_io(c)\
00310    ((c).flags = (c).flags & ~WN2F_CONTEXT_FMT_IO)
00311 
00312 
00313 /* this flag indicates that IO processing deals with craylibs
00314  * not f77 mips libs.
00315  */
00316 #define WN2F_CONTEXT_CRAY_IO 0x00002000
00317 #define WN2F_CONTEXT_cray_io(c)\
00318    ((c).flags & WN2F_CONTEXT_CRAY_IO)
00319 #define set_WN2F_CONTEXT_cray_io(c)\
00320    ((c).flags = (c).flags | WN2F_CONTEXT_CRAY_IO)
00321 #define reset_WN2F_CONTEXT_cray_io(c)\
00322    ((c).flags = (c).flags & ~WN2F_CONTEXT_CRAY_IO)
00323 
00324 
00325 #define WN2F_CONTEXT_HAS_NO_ARR_ELMT  0x00004000
00326 #define WN2F_CONTEXT_has_no_arr_elmt(c)\
00327    ((c).flags & WN2F_CONTEXT_HAS_NO_ARR_ELMT)
00328 #define set_WN2F_CONTEXT_has_no_arr_elmt(c)\
00329    ((c).flags = (c).flags | WN2F_CONTEXT_HAS_NO_ARR_ELMT)
00330 #define reset_WN2F_CONTEXT_has_no_arr_elmt(c)\
00331    ((c).flags = (c).flags & ~WN2F_CONTEXT_HAS_NO_ARR_ELMT)
00332 
00333 /*add a flag to see if we need issue default UNIT in io stmts
00334  *in READ/WRITE/PRINT stmts,must have UNIT=*
00335  *but in other stmt such as INQUIRE if there already
00336  *is FILE,issue UNIT=* will cause problems
00337  *-----fzhao
00338  */
00339 
00340 #define WN2F_CONTEXT_ISSUE_IOC_UNIT_ASTERISK 0x00008000
00341 #define WN2F_CONTEXT_issue_ioc_asterisk(c)\
00342    ((c).flags & WN2F_CONTEXT_ISSUE_IOC_UNIT_ASTERISK)
00343 #define set_WN2F_CONTEXT_issue_ioc_asterisk(c)\
00344    ((c).flags = (c).flags | WN2F_CONTEXT_ISSUE_IOC_UNIT_ASTERISK)
00345 #define reset_WN2F_CONTEXT_issue_ioc_asterisk(c)\
00346    ((c).flags = (c).flags & ~WN2F_CONTEXT_ISSUE_IOC_UNIT_ASTERISK)
00347 
00348 #define WN2F_CONTEXT_SUBEXP_NO_PARENTHESIS 0x00040000
00349 #define WN2F_CONTEXT_subexp_no_parenthesis(c)\
00350    ((c).flags & WN2F_CONTEXT_SUBEXP_NO_PARENTHESIS)
00351 #define set_WN2F_CONTEXT_subexp_no_parenthesis(c)\
00352    ((c).flags = (c).flags | WN2F_CONTEXT_SUBEXP_NO_PARENTHESIS)
00353 #define reset_WN2F_CONTEXT_subexp_no_parenthesis(c)\
00354    ((c).flags = (c).flags & ~WN2F_CONTEXT_SUBEXP_NO_PARENTHESIS)
00355 
00356 
00357     /* ---- Utilities to aid in WN to Fortran translation ---- */
00358     /* ------------------------------------------------------- */
00359 
00360 // >> WHIRL 0.30: replaced OPC_LNOT, OPC_LAND, OPC_LIOR by OPC_B and OPC_I4 variants
00361 // TODO WHIRL 0.30: get rid of OPC_I4 variants.
00362 #define WN2F_expr_has_boolean_arg(opc) \
00363    ((opc) == OPC_BLNOT || (opc) == OPC_BLAND || (opc) == OPC_BLIOR || \
00364     (opc) == OPC_I4LNOT || (opc) == OPC_I4LAND || (opc) == OPC_I4LIOR)
00365 // << WHIRL 0.30: replaced OPC_LNOT, OPC_LAND, OPC_LIOR by OPC_B and OPC_I4 variants
00366 
00367 
00368 #define WN2F_Can_Assign_Types(t1, t2) \
00369    ((TY_Is_Array(t1) && TY_is_character(t1) && \
00370      TY_Is_Array(t2) && TY_is_character(t2)) || \
00371     Stab_Identical_Types(t1, t2, \
00372                          FALSE, /*check_quals*/ \
00373                          FALSE, /*check_scalars*/ \
00374                          TRUE)) /*ptrs_as_scalars*/
00375 
00376 
00377 void WN2F_Stmt_Newline(TOKEN_BUFFER tokens,
00378                        const char  *label,
00379                        SRCPOS       srcpos,
00380                        WN2F_CONTEXT context);
00381 
00382 
00383 extern void WN2F_Address_Of(TOKEN_BUFFER tokens);
00384 
00385 extern WN2F_STATUS
00386    WN2F_Offset_Memref(TOKEN_BUFFER tokens,
00387                       WN          *addr,        /* Base address */
00388                       TY_IDX       addr_ty,     /* type of base-address */
00389                       TY_IDX       object_ty,   /* type of object referenced */
00390                       STAB_OFFSET  addr_offset, /* offset from base */
00391                       WN2F_CONTEXT context);
00392 
00393 extern WN2F_STATUS
00394    WN2F_Offset_Symref(TOKEN_BUFFER tokens,
00395                       ST          *addr,        /* Base symbol */
00396                       TY_IDX       addr_ty,     /* type of base-symbol-addr */
00397                       TY_IDX       object_ty,   /* type of object referenced */
00398                       STAB_OFFSET  addr_offset, /* offset from base */
00399                       WN2F_CONTEXT context);
00400 
00401 extern WN_OFFSET 
00402    WN2F_Sum_Offsets(WN *addr);
00403 
00404 extern void 
00405    WN2F_Emit_End_Stmt(TOKEN_BUFFER tokens,BOOL start) ;
00406 
00407 
00408 /* the preamble to put out for comments eg: CSGI$ start 1 */
00409 
00410 extern  char * sgi_comment_str ;
00411 
00412 /* -------- Facilities to effect a WN to Fortran translation --------- */
00413    /* ------------------------------------------------------------------- */
00414 
00415 extern void WN2F_initialize(void);
00416 extern void WN2F_finalize(void);
00417 
00418 extern WN2F_STATUS
00419 WN2F_translate(TOKEN_BUFFER tokens, WN *wn, WN2F_CONTEXT context);
00420 
00421 extern WN2F_STATUS 
00422 WN2F_translate_purple_main(TOKEN_BUFFER tokens, 
00423                            WN          *pu, 
00424                            const char  *region_name,
00425                            WN2F_CONTEXT context);
00426 
00427 void  WN2F_dump_context( WN2F_CONTEXT c) ;
00428 
00429 
00430 #endif /* wn2f_INCLUDED */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines