Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided 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 }