Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
cwh_dope.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 h/erein, 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  *  dd-mmm-95 - Original Version
00042  *
00043  * Description: contains routines to manipulate dope vectors. Although
00044  *              the FLDs of the type contain offset and size information,
00045  *              these routines rely on defines to avoid repetition of 
00046  *              the same search. The definitions are in cwh_types.h.
00047  *
00048  * ====================================================================
00049  * ====================================================================
00050  */
00051 
00052 static char *source_file = __FILE__;
00053 
00054 #ifdef _KEEP_RCS_ID
00055 /*REFERENCED*/
00056 #endif /* _KEEP_RCS_ID */
00057 
00058 /* sgi includes */
00059 
00060 #include "defs.h"
00061 #include "glob.h"  
00062 #include "symtab.h"
00063 #include "strtab.h"
00064 #include "errors.h"
00065 #include "config_targ.h"
00066 #include "wn.h"
00067 #include "wn_util.h"
00068 #include "f90_utils.h"
00069 
00070 /* Cray includes */
00071 
00072 #include "i_cvrt.h"
00073 
00074 
00075 /* conversion includes */
00076 
00077 #include "cwh_defines.h"
00078 #include "cwh_stk.h"
00079 #include "cwh_stmt.h"
00080 #include "cwh_types.h"
00081 #include "cwh_expr.h"
00082 #include "cwh_addr.h"
00083 
00084 
00085 #define opc_dim OPC_I8INTCONST
00086 
00087 static void  cwh_dope_store_bound(INT32 offset, INT32 dim) ;
00088 static void  cwh_dope_read_bound(INT32 offset, INT32 dim) ;
00089 static void  cwh_dope_initialize(ST *st, WN * wa, TY_IDX ty, WN *dp[DOPE_USED],WN **bd, INT16 num_bnds ) ;
00090 static void  cwh_dope_store (ST *st, WN *wa, OFFSET_64 off, TY_IDX  ty, WN *rhs) ;
00091 
00092 
00093 /*===============================================
00094  *
00095  * fei_dv_def
00096  *
00097  * Dope vector initialization. The stack has
00098  * the dope fields, or nulls for empty slots
00099  * and these should be stored into the address
00100  * at the base of the stack. Unused fields in
00101  * the descriptor were not pushed onto the stack.
00102  *
00103  * Push a null operation for fei_store to ignore.
00104  *
00105  *===============================================
00106  */ 
00107 extern void 
00108 fei_dv_def(INT32 num_dims )
00109 {
00110   WN * dp[DOPE_USED];
00111   WN * bd[BOUND_NM * MAX_ARY_DIMS];
00112   ST * st   ;
00113   WN * wa;
00114   FLD_IDX fld ;
00115   TY_IDX ty;
00116 
00117   INT16 n,i;
00118 
00119   n = num_dims * BOUND_NM ;
00120 
00121   for( i = n-1 ; i >= 0  ; i --) 
00122     bd[i] = cwh_expr_operand(NULL);
00123 
00124   for( i = DOPE_USED-1 ; i >= 1 ; i--)
00125     dp[i] = cwh_expr_operand(NULL);
00126   
00127   dp[0] = cwh_expr_address(f_NONE);
00128 
00129   if (cwh_stk_get_class() == ST_item || cwh_stk_get_class() == ST_item_whole_array) {
00130      st = cwh_stk_pop_ST();
00131      wa = NULL;
00132      ty = 0;
00133 
00134   } else if (cwh_stk_get_class() == FLD_item) {
00135      fld = cwh_stk_pop_FLD();
00136      cwh_stk_push((void *) fld,FLD_item);
00137      ty = FLD_type(FLD_HANDLE (fld));
00138      wa = cwh_expr_address(f_NONE);
00139      st = NULL;
00140 
00141   } else {
00142      wa = cwh_expr_address(f_NONE);
00143      st = NULL;
00144      ty = 0;
00145   }
00146   cwh_dope_initialize(st,wa,ty,dp,bd,n);
00147 
00148   /* These are going to be ignored */
00149   cwh_stk_push(st,ST_item);
00150   cwh_stk_push(NULL,WN_item);
00151 
00152 }
00153 
00154 /*===============================================
00155  *
00156  * fei_get_dv_low_bnd
00157  *
00158  * Get low bound for dimension dim.
00159  *
00160  *===============================================
00161  */ 
00162 extern void 
00163 fei_get_dv_low_bnd(INT32 dim,INT32 expand)
00164 {
00165   cwh_dope_read_bound(0,dim);
00166 }
00167 
00168 /*===============================================
00169  *
00170  * fei_get_dv_extent
00171  *
00172  * Get extent for dimension dim.
00173  *
00174  *===============================================
00175  */ 
00176 extern void 
00177 fei_get_dv_extent(INT32 dim,INT32 expand)
00178 {
00179   cwh_dope_read_bound(DOPE_bound_sz,dim);
00180 }
00181 
00182 /*===============================================
00183  *
00184  * fei_get_dv_str_mult
00185  *
00186  * Get extent for dimension dim.
00187  *
00188  *===============================================
00189  */ 
00190 extern void 
00191 fei_get_dv_str_mult(INT32 dim,INT32 expand)
00192 {
00193   cwh_dope_read_bound((2 * DOPE_bound_sz),dim);
00194 }
00195 
00196 /*===============================================
00197  *
00198  * fei_set_dv_low_bnd
00199  *
00200  * Set low bound for dimension dim.
00201  *
00202  *===============================================
00203  */ 
00204 extern void 
00205 fei_set_dv_low_bnd(INT32 dim)
00206 {
00207   cwh_dope_store_bound(0,dim);
00208 }
00209 
00210 /*===============================================
00211  *
00212  * fei_set_dv_extent
00213  *
00214  * Set extent for dimension dim.
00215  *
00216  *===============================================
00217  */ 
00218 extern void 
00219 fei_set_dv_extent(INT32 dim)
00220 {
00221   cwh_dope_store_bound(DOPE_bound_sz,dim);
00222 }
00223 
00224 /*===============================================
00225  *
00226  * fei_set_dv_str_mult
00227  *
00228  * Set extent for dimension dim.
00229  *
00230  *===============================================
00231  */ 
00232 extern void 
00233 fei_set_dv_str_mult(INT32 dim)
00234 {
00235   cwh_dope_store_bound((2 * DOPE_bound_sz),dim);
00236 }
00237 
00238 /*===============================================
00239  *
00240  * fei_dv_deref
00241  *
00242  * get the address of the space pointed to by
00243  * the dope. Assumes address is 1st field.
00244  * If it's an assumed shape dummy then load the
00245  * address first.
00246  *
00247  *===============================================
00248  */ 
00249 extern void 
00250 fei_dv_deref(TYPE result)
00251 {
00252   ST  * st ;
00253   WN  * wn ;
00254   WN  * wa;
00255   TY_IDX  ty, tp ;
00256   FLD_IDX  fld;
00257   TY_IDX dope_ty;
00258   char *field_name;
00259 
00260   if (cwh_stk_get_class() == ST_item || cwh_stk_get_class() == ST_item_whole_array) {
00261      st = cwh_stk_pop_ST();
00262      dope_ty = ST_type(st);
00263      
00264      if (ST_sclass(st) == SCLASS_FORMAL) {
00265         dope_ty = cwh_types_array_TY(dope_ty); 
00266      }
00267      ty = FLD_type(TY_fld(Ty_Table[dope_ty]));
00268      wn  = cwh_addr_load_ST(st,ADDR_OFFSET,ty);
00269 
00270   } else if (cwh_stk_get_class() == FLD_item) {
00271 
00272      field_name = cwh_stk_fld_name();
00273      fld = cwh_stk_pop_FLD();
00274      cwh_stk_push((void *)fld,FLD_item);
00275      wn = cwh_expr_address(f_NONE);
00276      dope_ty = FLD_type(FLD_HANDLE (fld)); /* get the dope TY_IDX */
00277      ty = FLD_type(TY_fld(Ty_Table[dope_ty]));
00278      if (cwh_addr_f90_pointer_reference(wn)) {
00279         tp = cwh_types_mk_f90_pointer_ty(ty);
00280      } else {
00281         tp = cwh_types_make_pointer_type(dope_ty, FALSE);
00282      }
00283      
00284      wn = WN_CreateIload (OPCODE_make_op(OPR_ILOAD,Pointer_Mtype,Pointer_Mtype),
00285                           ADDR_OFFSET,ty,tp,wn);
00286      SET_ARRAY_NAME_MAP(wn,field_name);
00287   } else {
00288 
00289      wn = cwh_expr_operand(NULL);
00290      dope_ty = 0;
00291   }
00292   cwh_stk_push_typed(wn,DEREF_item,dope_ty);
00293 }
00294 
00295 /*===============================================
00296  *
00297  * fei_get_dv_hdr_fld 
00298  *
00299  * get the appropriate field information from a dope vector
00300  * Assumes dope vector is on the stack.
00301  *
00302  *===============================================
00303  */ 
00304 extern void 
00305 fei_get_dv_hdr_fld(INT32 field)
00306 {
00307    INT32 offset;
00308    INT32 rshift;
00309    INT64 mask;
00310    TYPE_ID ty;
00311 
00312    ST *st;
00313    WN *wn;
00314 
00315    /* Get the information about the appropriate fields needed */
00316    cwh_types_get_dope_info(field, &offset, &rshift, &mask, &ty);
00317    
00318    switch(cwh_stk_get_class()) {
00319     case ST_item:
00320     case ST_item_whole_array:
00321       st = cwh_stk_pop_ST();
00322       wn = cwh_addr_load_ST(st,offset,Be_Type_Tbl(ty));
00323       break ;
00324       
00325     case WN_item:
00326     case WN_item_whole_array:
00327     case FLD_item:
00328       wn = cwh_expr_address(f_NONE);
00329       wn = cwh_addr_load_WN(wn,offset,Be_Type_Tbl(ty)); 
00330       break ;
00331       
00332     default:
00333       DevAssert((0),(" Odd dope load"));
00334       break;
00335    }
00336 
00337    /* See if we need to shift and mask */
00338    if (rshift != 0) {
00339       wn = cwh_expr_bincalc(OPR_LSHR,wn,WN_Intconst(MTYPE_I4,rshift));
00340    }
00341    if (mask != 0) {
00342       wn = cwh_expr_bincalc(OPR_BAND,wn,WN_Intconst(ty,mask));
00343    }
00344 
00345    cwh_stk_push(wn,WN_item);
00346 }
00347 
00348 /*===============================================
00349  *
00350  * fei_set_dv_hdr_fld 
00351  *
00352  * set the appropriate field information into a dope vector
00353  * Assumes dope vector is on the stack.
00354  *
00355  *===============================================
00356  */ 
00357 extern void 
00358 fei_set_dv_hdr_fld(INT32 field)
00359 {
00360    INT32 offset;
00361    INT32 rshift;
00362    INT64 mask,mask_complement;
00363    TYPE_ID ty;
00364    TYPE_ID addr_ty;
00365    BOOL needs_load;
00366    FLD_HANDLE fl;
00367 
00368    ST *st;
00369    WN *wn;
00370    WN *arg,*old_value;
00371 
00372    /* Get the information about the appropriate fields needed */
00373    cwh_types_get_dope_info(field, &offset, &rshift, &mask, &ty);
00374    mask_complement = mask;
00375    needs_load = FALSE;
00376 
00377    /* Special cases for 1 and 9 base_address and orig_base */
00378    if (field == 1 || field == 9) {
00379       arg = cwh_expr_address(f_NONE);
00380    } else {
00381       arg = cwh_expr_operand(NULL);
00382    }
00383 
00384    /* Get arg in the right place if need be */
00385    if (mask != 0) {
00386       arg = cwh_expr_bincalc(OPR_BAND,arg,WN_Intconst(ty,mask));
00387       needs_load = TRUE;
00388    }
00389    if (rshift != 0) {
00390       arg = cwh_expr_bincalc(OPR_SHL,arg,WN_Intconst(MTYPE_I4,rshift));
00391       mask_complement <<= rshift;
00392       needs_load = TRUE;
00393    }
00394    mask_complement = ~mask_complement;
00395       
00396    switch(cwh_stk_get_class()) {
00397     case ST_item:
00398     case ST_item_whole_array:
00399 
00400       addr_ty = cwh_stk_get_TY();
00401 
00402       st = cwh_stk_pop_ST();
00403 
00404       if (! addr_ty) {
00405          addr_ty = ST_type(st);
00406       }
00407 
00408       if (needs_load) {
00409          old_value = cwh_addr_load_ST(st,offset,Be_Type_Tbl(ty));
00410          if (mask != 0) {
00411             old_value = cwh_expr_bincalc(OPR_BAND,old_value,WN_Intconst(ty,mask_complement));
00412             arg = cwh_expr_bincalc(OPR_BIOR,arg,old_value);
00413          }
00414       }
00415 
00416       if (field == 1 || field == 9) {
00417          if (TY_kind(addr_ty) == KIND_POINTER) addr_ty = TY_pointed(addr_ty);
00418 
00419          /* addr_ty should be the TY of a dope vector Dope */
00420 
00421          TY & tt = Ty_Table[addr_ty];
00422          fl = TY_fld(tt);
00423          addr_ty = FLD_type(fl);
00424          DevAssert((TY_kind(addr_ty) == KIND_POINTER),(" base not pointer "));
00425       } else {
00426          addr_ty = Be_Type_Tbl(ty);
00427       }
00428       cwh_addr_store_ST(st,offset,addr_ty,arg);
00429       break ;
00430       
00431     case WN_item:
00432     case WN_item_whole_array:
00433     case FLD_item:
00434 
00435       if (cwh_stk_get_class() == FLD_item) {
00436          addr_ty = cwh_stk_get_FLD_TY();
00437       } else {
00438          addr_ty = cwh_stk_get_TY();
00439       }
00440 
00441       wn = cwh_expr_address(f_NONE);
00442 
00443       if (! addr_ty) {
00444          addr_ty = cwh_types_WN_TY(wn, TRUE);
00445       }
00446 
00447       if (needs_load) {
00448          old_value = cwh_addr_load_WN(WN_COPY_Tree(wn),offset,Be_Type_Tbl(ty));
00449          if (mask != 0) {
00450             old_value = cwh_expr_bincalc(OPR_BAND,old_value,WN_Intconst(ty,mask_complement));
00451             arg = cwh_expr_bincalc(OPR_BIOR,arg,old_value);
00452          }
00453       }
00454 
00455       if (field == 1 || field == 9) {
00456          if (TY_kind(addr_ty) == KIND_POINTER) addr_ty = TY_pointed(addr_ty);
00457 
00458          /* addr_ty should be the TY of a dope vector Dope */
00459 
00460          TY & tt = Ty_Table[addr_ty];
00461          fl = TY_fld(tt);
00462          addr_ty = FLD_type(fl);
00463          DevAssert((TY_kind(addr_ty) == KIND_POINTER),(" base not pointer "));
00464       } else {
00465          addr_ty = Be_Type_Tbl(ty);
00466       }
00467       cwh_addr_store_WN(wn,offset,addr_ty,arg); 
00468       break ;
00469       
00470     default:
00471       DevAssert((0),(" Odd dope store"));
00472       break;
00473    }
00474 }
00475 
00476 
00477 
00478 /*===============================================
00479  *
00480  * arrsection_to_array 
00481  *
00482  * Turn ARRSECTION nodes into ARRAY nodes pointing at the 
00483  * base address of the arrsection. Expects as input an ARRSECTION
00484  * or ARRAY node. Does its work in place.
00485  * 
00486  *===============================================
00487  */ 
00488 static void arrsection_to_array(WN *addr)
00489 {
00490    INT i,ndim;
00491    WN *temp;
00492    OPERATOR opr;
00493 
00494    opr = WNOPR(addr);
00495 
00496    if (opr == OPR_ARRSECTION || opr == OPR_ARRAY) {
00497       WN_set_opcode(addr,OPCODE_make_op(OPR_ARRAY,Pointer_Mtype,MTYPE_V));
00498       arrsection_to_array(WN_kid0(addr));
00499       ndim = (WN_kid_count(addr)-1)/2;
00500       for (i=ndim+1; i < 2*ndim + 1; i++) {
00501          if (WNOPR(WN_kid(addr,i)) == OPR_TRIPLET) {
00502             temp = WN_kid(addr,i);
00503             WN_kid(addr,i) = WN_kid0(temp);
00504             WN_DELETE_Tree(WN_kid1(temp));
00505             WN_DELETE_Tree(WN_kid2(temp));
00506             WN_Delete(temp);
00507          }
00508       }
00509    } else if (opr == OPR_ADD || opr == OPR_MPY || opr == OPR_SUB) {
00510       /* character(*) case */
00511       arrsection_to_array(WN_kid0(addr));
00512       arrsection_to_array(WN_kid1(addr));
00513    }
00514    return;
00515 }
00516 
00517 /*===============================================
00518  *
00519  * fei_dv_ptr_asg 
00520  *
00521  * Set the address field in a dope vector.
00522  * Assumes dope vector is on the stack.
00523  *
00524  *===============================================
00525  */ 
00526 extern void 
00527 fei_dv_ptr_asg(void)
00528 {
00529    WN *addr;
00530    
00531    /* Probably should set the address/taken/saved bit */
00532    addr = cwh_expr_address(f_T_SAVED);
00533    arrsection_to_array(addr);
00534    cwh_stk_push(addr,WN_item);
00535    fei_set_dv_hdr_fld(1); /* store it */
00536 }
00537 
00538 /*===============================================
00539  *
00540  * cwh_dope_read_bound
00541  *
00542  * Read a  bound of dimension dim. The offset is
00543  * the extra for a lb,extent or stride, in addition
00544  * to the basic dimension,
00545  *
00546  *===============================================
00547  */ 
00548 static void
00549 cwh_dope_read_bound(INT32 offset, INT32 dim)
00550 {
00551   WN  * wa ;
00552   WN  * wn ;
00553   ST  * st ;
00554   WN_OFFSET off;
00555 
00556   off = DOPE_dim_offset + offset + (DIM_SZ * (dim-1)) ;
00557 
00558   switch(cwh_stk_get_class()) {
00559   case ST_item:
00560   case ST_item_whole_array:
00561     st = cwh_stk_pop_ST();
00562     wn = cwh_addr_load_ST(st,off,DOPE_bound_ty);
00563     break ;
00564 
00565   case WN_item:
00566   case WN_item_whole_array:
00567   case FLD_item:
00568     wa = cwh_expr_address(f_NONE);
00569     wn = cwh_addr_load_WN(wa,off,DOPE_bound_ty); 
00570     break ;
00571 
00572   default:
00573     DevAssert((0),(" Odd dope load"));
00574     break;
00575   }
00576 
00577   wn = cwh_convert_to_ty(wn,cwh_bound_int_typeid);
00578 
00579   cwh_stk_push(wn,WN_item);
00580 }
00581 
00582 /*===============================================
00583  *
00584  * cwh_dope_store_bound
00585  *
00586  * Store a bound of dimension dim. The offset is 
00587  * the extra for a lb,extent or stride, in addition
00588  * to the basic dimension,
00589  *
00590  *===============================================
00591  */ 
00592 static void
00593 cwh_dope_store_bound(INT32 offset, INT32 dim)
00594 {
00595   WN  * wn ;
00596   WN  * wa ;
00597   ST  * st ;
00598   OFFSET_64 off;
00599 
00600   off = DOPE_dim_offset + offset + (DIM_SZ * (dim-1)) ;
00601   wn  = cwh_expr_operand(NULL);
00602 
00603   switch(cwh_stk_get_class()) {
00604   case ST_item:
00605   case ST_item_whole_array:
00606     st = cwh_stk_pop_ST();
00607     cwh_addr_store_ST(st,off,DOPE_bound_ty,wn);
00608     break ;
00609 
00610   case WN_item:
00611   case WN_item_whole_array:
00612   case FLD_item:
00613     wa = cwh_expr_address(f_NONE);
00614     cwh_addr_store_WN(wa,off,DOPE_bound_ty,wn); 
00615     break ;
00616 
00617   default:
00618     DevAssert((0),(" Odd dope store"));
00619     break;
00620   }
00621 }
00622 
00623 
00624 /*================================================================
00625  *
00626  * cwh_dope_get_dope_fudge_factor
00627  *
00628  * This routine returns 1 for INTEGER(1) base types, 2 for INTEGER(2)
00629  * base types, and 4 for everything else. It is needed to interpret
00630  * the stride in dope vectors.
00631  *
00632  * Stride is in word (4 byte) elements for types whose size is >= I4, 
00633  * unless it's a character-only thing, when bytes are used. 
00634  * I1,I2,L1,L2 get element size stride (1 or 2 bytes).
00635  *
00636  *================================================================
00637  */
00638 
00639 static INT64
00640 cwh_dope_get_dope_fudge_factor(TY_IDX ty)
00641 {
00642    TY_IDX base_ty;
00643    TYPE_ID t;
00644 
00645    TY& tt = Ty_Table[ty];
00646    if (TY_kind(ty) == KIND_ARRAY) {
00647       return (cwh_dope_get_dope_fudge_factor(TY_etype(tt))); 
00648    } else if (TY_kind(ty) == KIND_STRUCT) {
00649       if (TY_is_packed(tt)) return(1);
00650       return (4);
00651    } else if (TY_kind(ty) == KIND_SCALAR) {
00652       base_ty = ty;
00653    } else {
00654       DevAssert((0),("Do not know what to do with type"));
00655    }
00656 
00657    if (TY_is_character(Ty_Table[base_ty])) {
00658       return (1);
00659    }
00660    t = TY_mtype(base_ty);
00661    if (MTYPE_byte_size(t) < 4) {
00662       return (MTYPE_byte_size(t));
00663    }
00664    return (4);
00665 }
00666 
00667 /*===============================================
00668  *
00669  * cwh_dope_from_expression
00670  *
00671  * expr must be an ILOAD, an MLOAD, or any expression which represents the
00672  * address of something. If array is NULL expr must contain exactly one
00673  * ARRSECTION node. If array is non-null, expr must not contain an
00674  * ARRSECTION. If char_len is non-null, the dope vector will be made to
00675  * represent a character expression of length char_len. 
00676  * 
00677  * tarray is the TY of the array object the dope is for - the 
00678  * base expression may be from a structure.
00679  *
00680  *================================================================
00681  */
00682 
00683 extern WN * 
00684 cwh_dope_from_expression(WN *expr, WN *array, WN *char_len, TY_IDX tarray,
00685 WN *craytype_wn)
00686 {
00687   WN * wn ;
00688   WN * wt ;
00689   ST * st ;
00690   TY_IDX  tc ;
00691   TY_IDX  ty ;
00692   WN * se;
00693   WN * lower_bound;
00694   WN * stride_mult_accum;
00695   WN * address_fixup;
00696   INT64 element_size_multiplier;
00697   INT64 craytype;
00698   WN_ESIZE element_size;
00699   BOOL     non_contig;
00700   INT64  offset;
00701   
00702   FLD_IDX  fl ;
00703 
00704   WN * dp[DOPE_USED];
00705   WN * bd[BOUND_NM * MAX_ARY_DIMS];
00706 
00707   INT32 nd ;
00708   INT16 i,j ;
00709 
00710   if (WNOPR(expr) == OPR_ILOAD || WNOPR(expr) == OPR_MLOAD) {
00711      /* 
00712       * Get the offset and the scalar type, 
00713       * then clean up expr and set it to point to tha address child.
00714       */
00715      offset = WN_offset(expr);
00716      if (WN_kid_count(expr)==2) {
00717         WN_DELETE_Tree(WN_kid1(expr));
00718      }
00719      se = WN_kid0(expr);
00720      WN_Delete(expr);
00721      expr = se;
00722   } else {
00723      offset = 0;
00724   }
00725 
00726   se = cwh_addr_find_section(expr,p_RETURN_SECTION);
00727   if (!se) {
00728      se = array;
00729   }
00730 
00731   DevAssert((se),("Can't find an array section or an array to use"));
00732   DevAssert((tarray != NULL),("Missing TY"));
00733   
00734   element_size = WN_element_size(se);
00735   if (element_size < 0) {
00736      element_size = -element_size;
00737      non_contig = TRUE;
00738   } else {
00739      non_contig = FALSE;
00740   }
00741   nd = WN_num_dim(se);
00742 
00743   /* Step 1: get the stride multiplier scale factor */
00744   element_size_multiplier = element_size/cwh_dope_get_dope_fudge_factor(tarray);
00745   if (element_size_multiplier == 0) element_size_multiplier = 1; 
00746 
00747   if (char_len) {
00748      dp[1] = WN_COPY_Tree(char_len);
00749      /* The stride multiplier is in bytes for this type */
00750      stride_mult_accum = WN_Intconst(cwh_bound_int_typeid,element_size);
00751   } else {
00752      dp[1] = WN_Intconst(Pointer_Mtype,element_size*8);
00753      stride_mult_accum = WN_Intconst(cwh_bound_int_typeid,element_size_multiplier);
00754   }
00755 
00756   /* Step 2, build up the lbound, extents, and stride_multiplier fields, 
00757    * and alter the section node to be an ARRAY node.
00758    * bounds from section - these are always
00759    * simple triplets or scalar subscripts. 
00760   */
00761   
00762   j = 0 ;
00763 
00764   for (i = 2*nd; i >= nd+1 ; i --) {
00765      wt = WN_kid(se,i) ;
00766      if (WNOPR(wt) == OPR_TRIPLET) {
00767         /* Replace a TRIPLET node in the section with its lower bound */
00768         WN_kid(se,i) = WN_kid0(wt);
00769         /* Copy the extent to the dope vector */
00770         bd[j+1] = cwh_expr_bincalc(OPR_MAX,WN_kid2(wt),WN_Zerocon(cwh_bound_int_typeid));
00771         if (non_contig) {
00772            bd[j+2] = cwh_expr_bincalc(OPR_MPY,WN_COPY_Tree(WN_kid(se,i-nd)),
00773                                       WN_kid1(wt));
00774            /* Correct for character, etc, in derived types */
00775            bd[j+2] = cwh_expr_bincalc(OPR_MPY,bd[j+2],WN_Intconst(cwh_bound_int_typeid,
00776                                                                   element_size_multiplier));
00777         } else {
00778            bd[j+2] = cwh_expr_bincalc(OPR_MPY,WN_kid1(wt),WN_COPY_Tree(stride_mult_accum));
00779         }
00780         /* Don't need the triplet anymore */
00781         WN_Delete(wt);
00782      } else {
00783         /* Extent = 1 */
00784         bd[j+1] = WN_Intconst(cwh_bound_int_typeid,1);
00785         if (non_contig) {
00786            bd[j+2] = WN_COPY_Tree(WN_kid(se,i-nd));
00787            /* Correct for character, etc, in derived types */
00788            bd[j+2] = cwh_expr_bincalc(OPR_MPY,bd[j+2],WN_Intconst(cwh_bound_int_typeid,
00789                                                                   element_size_multiplier));
00790         } else {
00791            bd[j+2] = WN_COPY_Tree(stride_mult_accum);
00792         }
00793      }
00794      bd[j] = WN_Intconst(cwh_bound_int_typeid,1);
00795      j+= BOUND_NM;
00796      if (i != nd+1 && !non_contig) {
00797         stride_mult_accum = cwh_expr_bincalc(OPR_MPY,stride_mult_accum,WN_COPY_Tree(WN_kid(se,i-nd)));
00798      }
00799   }
00800   WN_DELETE_Tree(stride_mult_accum);
00801 
00802   /* Turn the ARRSECTION into an ARRAY node */ 
00803   WN_set_opcode(se,OPCODE_make_op(OPR_ARRAY,Pointer_Mtype,MTYPE_V));
00804   /* Add the constant offset to the expression */
00805   expr = cwh_expr_bincalc(OPR_ADD,expr,WN_Intconst(Pointer_Mtype,offset));
00806   
00807   /* Set the base address */
00808   dp[0] = expr;
00809 
00810   /* Step 3, fill in the flag fields of the dope vector */
00811   /* contig, ptr flags, rank; assume non-contiguous, associated non-pointer */
00812 
00813   dp[2] = WN_Intconst(MTYPE_U4,1); /* associated */
00814   dp[3] = WN_Intconst(MTYPE_U4,0); /* allocated by pointer */
00815   dp[4] = WN_Intconst(MTYPE_U4,0); /* p_or_a */
00816   dp[5] = WN_Intconst(MTYPE_U4,0); /* contig */
00817   dp[6] = WN_Intconst(MTYPE_U4,nd);
00818 
00819   if (craytype_wn == NULL) {
00820       /* type code  **FIX */
00821       if (!char_len) {
00822          craytype = cwh_cray_type_from_TY(tarray);
00823       } else {
00824          f90_type_t *f90_type_ptr;
00825          f90_type_ptr = (f90_type_t *)&craytype;
00826          craytype = 0;
00827          f90_type_ptr->type = 6;
00828          f90_type_ptr->int_len = 8;
00829       }
00830       craytype_wn = WN_Intconst(MTYPE_U8,craytype);
00831   }
00832 
00833   dp[7] = WN_COPY_Tree(craytype_wn);
00834 
00835   /* original base and address - 0 unless allocatable */
00836   dp[8] = WN_Intconst(Pointer_Mtype,0);
00837   dp[9] = WN_Intconst(Pointer_Mtype,0);
00838 
00839   /* Create the dope vector */
00840   ty = cwh_types_dope_TY(nd,tarray,FALSE,FALSE);
00841   wn = cwh_expr_temp(ty,NULL,f_T_PASSED);
00842   cwh_dope_initialize(WN_st(wn),NULL,0,dp,bd,nd*BOUND_NM);  
00843   return(wn);
00844 
00845 }
00846 
00847 /*===============================================
00848  *
00849  * cwh_dope_initialize_body
00850  *
00851  * Given the ST of a dope vector, initialize
00852  * all fields except the bounds.
00853  *
00854  *===============================================
00855  */ 
00856 static void
00857 cwh_dope_initialize(ST *st, WN *wa, TY_IDX dope_ty, WN *dp[DOPE_USED],WN **bd, INT16 num_bnds )
00858 {
00859   INT16  i ;
00860   INT16 sz ;
00861 
00862   FLD_HANDLE  fli ;
00863   FLD_HANDLE  fl ;
00864   FLD_HANDLE  ft ;
00865   TY_IDX ty ;
00866   WN  * wr ;
00867   WN  * wt ;
00868 
00869   OFFSET_64 off;
00870   OFFSET_64 invar_off;
00871   INT shift;
00872 
00873   if (dope_ty == 0) {
00874      if ( wa == NULL ) {
00875         fli = TY_fld(Ty_Table[ST_type(st)]);
00876      } else {
00877         fli = TY_fld(Ty_Table[cwh_types_WN_TY(wa, FALSE)]);
00878      }
00879   } else {
00880      fli = TY_fld(Ty_Table[dope_ty]);
00881   }
00882 
00883   /* address, element len */
00884 
00885   if (dp[0] != NULL )
00886       cwh_dope_store(st,wa,FLD_ofst(fli),FLD_type(fli),dp[0]) ;
00887 
00888   fli = FLD_next(fli);
00889   invar_off = FLD_ofst(fli);
00890   fl = TY_fld(Ty_Table[FLD_type(fli)]);
00891   if (dp[1] != NULL )
00892      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),dp[1]);
00893   
00894   /* assoc, ptr_alloc,ptr_or_a, a_contig */
00895   
00896   wr = NULL;
00897   fl = FLD_next(fl);
00898   sz = MTYPE_size_best(TY_mtype(FLD_type(fl)));
00899   ft = fl ;
00900   
00901 # ifdef linux
00902   {
00903     dope_header1_type   dh1;
00904  
00905   // assoc 
00906     if (dp[2] != NULL)
00907       dh1.assoc = WN_const_val(dp[2]);
00908     else
00909       dh1.assoc = 0;
00910      ft = FLD_next(ft);
00911 
00912   // ptr_alloc
00913 
00914     if (dp[3] != NULL)
00915       dh1.ptr_alloc = WN_const_val(dp[3]);
00916     else
00917       dh1.ptr_alloc = 0;
00918      ft = FLD_next(ft);
00919 
00920   // ptr_or_a
00921 
00922     if (dp[4] != NULL)
00923       dh1.p_or_a = WN_const_val(dp[4]);
00924     else
00925       dh1.p_or_a = 0;
00926      ft = FLD_next(ft);
00927 
00928   // a_contig
00929     if (dp[5] != NULL)
00930       dh1.a_contig = WN_const_val(dp[5]);
00931     else
00932       dh1.a_contig = 0;
00933      ft = FLD_next(ft);
00934 
00935     dh1.unused = 0;
00936 
00937     wr = WN_Intconst(MTYPE_U4,*(UINT32*)&dh1);
00938 
00939   }
00940 # else
00941   for (i = 0 ; i < 4 ; i ++ ) {
00942      if (dp[i+2] != NULL ) {
00943         shift = sz - FLD_bofst(ft) - FLD_bsize(ft);
00944         if (shift != 0) {
00945            wt = WN_Intconst(MTYPE_U4,shift);
00946            wt = cwh_expr_bincalc(OPR_SHL,dp[i+2],wt);
00947         } else {
00948            wt = dp[i+2];
00949         }
00950         
00951         if (wr == NULL) 
00952            wr = wt ;
00953         else
00954            wr = cwh_expr_bincalc(OPR_BIOR,wr,wt);
00955      }
00956      ft = FLD_next(ft);
00957   }
00958 # endif
00959   
00960   if (wr != NULL) 
00961      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),wr);    
00962   
00963   /* ignore unused fields & add in rank */
00964   fl = FLD_next(ft);
00965   
00966   if (dp[6] != NULL ) {
00967 # ifdef linux
00968      dope_header2_type dh2;
00969 
00970      dh2.unused = 0;
00971      dh2.n_dim = WN_const_val(dp[6]);
00972      wr = WN_Intconst(MTYPE_U4,*(UINT32*)&dh2);
00973      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),wr);
00974 # else
00975      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),dp[6]);    
00976 # endif
00977   }
00978   
00979 //  /* Initialize the first four unused bytes of the f90_type structure */
00980 //  fl = FLD_next(fl);
00981 //  cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),
00982 //               WN_Intconst(MTYPE_U4,0));
00983   
00984   /* type code */
00985   fl = FLD_next(fl);
00986   
00987   if (dp[7] != NULL) 
00988      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),dp[7]);    
00989   
00990   /* original base and address */
00991   
00992   fl = FLD_next(fl);
00993   if (dp[8] != NULL) 
00994      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),dp[8]);    
00995   
00996   fl = FLD_next(fl);
00997   if (dp[9] != NULL) 
00998      cwh_dope_store(st,wa,invar_off + FLD_ofst(fl),FLD_type(fl),dp[9]);
00999   
01000   
01001   /* add bounds - assumes all same size */
01002   
01003   if (num_bnds > 0 ) {
01004      
01005      fli  = FLD_next(fli) ;
01006      off = FLD_ofst(fli) ;
01007      ty  = DOPE_bound_ty     ;
01008      sz  = bit_to_byte(MTYPE_size_best(TY_mtype(ty)));
01009      
01010      for (i = 0 ; i < num_bnds  ; i ++ ) {
01011         if (bd[i] != NULL ) 
01012            cwh_dope_store(st,wa,off,ty,bd[i]);
01013       off += sz ;
01014      }
01015   }
01016 }
01017 
01018 /*===============================================
01019  *
01020  * cwh_dope_store
01021  *
01022  * Utility routine to store dope fields for 
01023  * an address, or an ST.
01024  *
01025  *===============================================
01026  */ 
01027 static void
01028 cwh_dope_store (ST *st, WN *wa, OFFSET_64 off, TY_IDX  ty, WN *rhs)
01029 {
01030   if (wa == NULL) {
01031      cwh_addr_store_ST(st,off,ty,rhs);
01032   } else {
01033      wa = F90_Wrap_ARREXP(WN_COPY_Tree(wa));
01034      cwh_addr_store_WN(wa,off,ty,rhs);
01035   }
01036 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines