Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 00032 00033 */ 00034 00035 00036 00037 static char USMID[] = "\n@(#)5.0_pl/sources/s_data.c 5.7 09/02/99 17:06:53\n"; 00038 00039 # include "defines.h" /* Machine dependent ifdefs */ 00040 00041 # include "host.m" /* Host machine dependent macros.*/ 00042 # include "host.h" /* Host machine dependent header.*/ 00043 # include "target.m" /* Target machine dependent macros.*/ 00044 # include "target.h" /* Target machine dependent header.*/ 00045 00046 # include "globals.m" 00047 # include "tokens.m" 00048 # include "sytb.m" 00049 # include "debug.m" 00050 # include "s_globals.m" 00051 00052 # include "globals.h" 00053 # include "tokens.h" 00054 # include "sytb.h" 00055 # include "s_globals.h" 00056 # include "s_data.h" 00057 00058 00059 /******************************************************************\ 00060 |* Function prototypes of static functions declared in this file. *| 00061 \******************************************************************/ 00062 00063 static void adjust_char_value_len (int, int, long64, long64); 00064 static void build_loop_tbl (int, boolean); 00065 static boolean check_target_and_value (int, int); 00066 static void data_imp_do_semantics (int, int, boolean, boolean *); 00067 static void fold_all_subscripts (opnd_type *); 00068 static void gen_section_ref(int,long64,int,int,int,long64 *,long64 *, 00069 long64 *); 00070 static boolean good_data_imp_do_expr(int); 00071 static boolean imp_do_metamorphed (int); 00072 static boolean init_whole_array(int, long64 *, int, int, boolean *); 00073 static void interpret_data_imp_do(int); 00074 static void object_semantics (opnd_type *, expr_mode_type, expr_arg_type *, 00075 boolean, boolean); 00076 static boolean optimize_whole_array_init(int); 00077 static void process_data_imp_do_target(int, int, long64); 00078 static void section_semantics (int, opnd_type *, int *); 00079 static void set_global_value_variables (opnd_type *, opnd_type *, int); 00080 static void vv_subscript_semantics(int, int, expr_arg_type *); 00081 00082 # if 0 /* Not used */ 00083 static int reenter_const_as_hollerith(int, int, int, holler_type); 00084 # endif 00085 00086 /******************************************************************************\ 00087 |* *| 00088 |* Description: *| 00089 |* This procedure handles initialization of a whole array, as in: *| 00090 |* *| 00091 |* INTEGER array(10,10) *| 00092 |* DATA array /45*0, 50*1, 5*2/ *| 00093 |* *| 00094 |* It does this by overlaying a single dimension compiler-generated *| 00095 |* array variable on the base array. If the base array is a single *| 00096 |* dimension array, no overlay is made. *| 00097 |* *| 00098 |* On the first call to this procedure for each whole array *| 00099 |* initialization, the size of the array is calculated, the c-g variable *| 00100 |* is generated, and the IR is generated to assign the first (and *| 00101 |* possibly only) set of values to the array. If the values are split *| 00102 |* up like the above example, successive calls to this procedure will *| 00103 |* generate IR representing each [rep-factor*]value. *| 00104 |* *| 00105 |* Input parameters: *| 00106 |* whole_sub_ir_idx : index of the Whole_Subscript IR *| 00107 |* dup_count : number of values available to be assigned to the *| 00108 |* array on this pass through the array *| 00109 |* root_ir_idx : if the Whole_Subscript IR is not the root IR of *| 00110 |* the reference tree, root_ir_idx points to the *| 00111 |* root IR *| 00112 |* init_ir_idx : index of the Init IR *| 00113 |* *| 00114 |* Output parameters: *| 00115 |* optimized : TRUE if the value list was converted to a single *| 00116 |* typeless glob of bits *| 00117 |* *| 00118 |* Returns: *| 00119 |* NONE *| 00120 |* *| 00121 |* Algorithm notes: *| 00122 |* value_opnd is only used when the CRI extension is being processed *| 00123 |* *| 00124 \******************************************************************************/ 00125 00126 static boolean init_whole_array(int whole_sub_ir_idx, 00127 long64 *dup_count, 00128 int root_ir_idx, 00129 int init_ir_idx, 00130 boolean *optimized) 00131 00132 { 00133 static int attr_idx; 00134 int bd_idx; 00135 static long64 curr_subscript; 00136 int curr_subscript_idx; 00137 int eq_idx; 00138 int eq_tmp_idx; 00139 boolean first_call; 00140 int il_idx; 00141 int ir_idx; 00142 size_offset_type length; 00143 boolean long_value; 00144 boolean ok = TRUE; 00145 opnd_type opnd; 00146 int overlay_attr_idx; 00147 size_offset_type result; 00148 int var_attr_idx; 00149 boolean word_size_target; 00150 00151 # if defined(_SEPARATE_NONCOMMON_EQUIV_GROUPS) 00152 int sb_idx; 00153 # endif 00154 00155 00156 TRACE(Func_Entry, "init_whole_array", NULL); 00157 00158 if (obj_count == 0) { 00159 first_call = TRUE; 00160 00161 /* If a single dimension array is being initialized, we can just use */ 00162 /* the array itself. Otherwise, generate a single dimension temp array */ 00163 /* and overlay it on the actual array because we can generate many */ 00164 /* fewer calls to PDGCS by using a single dimension array. For example,*/ 00165 /* the DATA statement DATA ((array(i,j), i=1,10), j=1,10) /100*0/ */ 00166 /* would generate 10 calls (one for each iteration of J) if left as a */ 00167 /* multidimension array because CCG only understands a single stride. */ 00168 /* But only a single call is generated if it is overlayed with a single */ 00169 /* dimension array. */ 00170 /* gen_compiler_tmp is used to generate an Attr with a temp name. Since*/ 00171 /* the base array Attr is just copied on top of it, any temp type can */ 00172 /* be used in the call. gen_compiler_tmp must be used because the temp */ 00173 /* counter used to create the name is local to it. */ 00174 00175 if (IR_FLD_L(whole_sub_ir_idx) == AT_Tbl_Idx) { 00176 attr_idx = IR_IDX_L(whole_sub_ir_idx); 00177 } 00178 else { 00179 attr_idx = IR_IDX_R(IR_IDX_L(whole_sub_ir_idx)); 00180 } 00181 00182 obj_count = CN_INT_TO_C(BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx))); 00183 00184 if (BD_RANK(ATD_ARRAY_IDX(attr_idx)) == 1 ) { 00185 curr_subscript_idx = BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), 1); 00186 curr_subscript = CN_INT_TO_C(curr_subscript_idx); 00187 } 00188 else { 00189 AT_DEFINED(attr_idx) = TRUE; 00190 00191 overlay_attr_idx = gen_compiler_tmp(IR_LINE_NUM_L(whole_sub_ir_idx), 00192 IR_COL_NUM_L(whole_sub_ir_idx), 00193 Shared, TRUE); 00194 00195 ATD_TYPE_IDX(overlay_attr_idx) = ATD_TYPE_IDX(attr_idx); 00196 ATD_STOR_BLK_IDX(overlay_attr_idx) = ATD_STOR_BLK_IDX(attr_idx); 00197 ATD_EQUIV(overlay_attr_idx) = TRUE; 00198 AT_REFERENCED(overlay_attr_idx) = Referenced; 00199 AT_SEMANTICS_DONE(overlay_attr_idx) = TRUE; 00200 /* AT_MODULE_OBJECT(overlay_attr_idx) = AT_MODULE_OBJECT(attr_idx);June*/ 00201 00202 if (ATD_CLASS(attr_idx) != Struct_Component) { 00203 00204 ATD_OFFSET_FLD(overlay_attr_idx) = ATD_OFFSET_FLD(attr_idx); 00205 ATD_OFFSET_IDX(overlay_attr_idx) = ATD_OFFSET_IDX(attr_idx); 00206 ATD_OFFSET_ASSIGNED(overlay_attr_idx) = 00207 ATD_OFFSET_ASSIGNED(attr_idx); 00208 00209 /* The overlay tmp and the variable must have the same offset. */ 00210 /* Find the equivalence group for the variable and add the tmp to */ 00211 /* the equivalence group. To do this, create a new equivalence */ 00212 /* table entry, add it to the group and make ATD_OFFSET be the */ 00213 /* same for both. (ATD_OFFSET can be set, even if ATD_OFFSET */ 00214 /* ASSIGNED is FALSE because this is the equivalence group */ 00215 /* offset). */ 00216 00217 if (ATD_EQUIV(attr_idx)) { 00218 eq_idx = SCP_FIRST_EQUIV_GRP(curr_scp_idx); 00219 00220 while (eq_idx != NULL_IDX) { 00221 eq_tmp_idx = eq_idx; 00222 eq_idx = EQ_NEXT_EQUIV_GRP(eq_idx); 00223 00224 while (eq_tmp_idx != NULL_IDX) { 00225 00226 if (EQ_ATTR_IDX(eq_tmp_idx) == attr_idx) { /* Found */ 00227 NTR_EQ_TBL(eq_idx); 00228 COPY_TBL_NTRY(equiv_tbl, eq_idx, eq_tmp_idx); 00229 EQ_NEXT_EQUIV_OBJ(eq_tmp_idx) = eq_idx; 00230 EQ_ATTR_IDX(eq_idx) = overlay_attr_idx; 00231 ATD_OFFSET_FLD(overlay_attr_idx)= 00232 ATD_OFFSET_FLD(attr_idx); 00233 ATD_OFFSET_IDX(overlay_attr_idx)= 00234 ATD_OFFSET_IDX(attr_idx); 00235 ATD_EQUIV(attr_idx) = TRUE; 00236 goto FOUND; 00237 } 00238 eq_tmp_idx = EQ_NEXT_EQUIV_OBJ(eq_tmp_idx); 00239 } 00240 } 00241 } 00242 00243 /* It is not in an equivalence group or it is not */ 00244 /* equivalenced, so make its own equivalence group. */ 00245 00246 NTR_EQ_TBL(eq_idx); 00247 NTR_EQ_TBL(eq_tmp_idx); 00248 00249 EQ_NEXT_EQUIV_GRP(eq_idx) = SCP_FIRST_EQUIV_GRP(curr_scp_idx); 00250 SCP_FIRST_EQUIV_GRP(curr_scp_idx) = eq_idx; 00251 EQ_ATTR_IDX(eq_idx) = attr_idx; 00252 EQ_ATTR_IDX(eq_tmp_idx) = overlay_attr_idx; 00253 EQ_NEXT_EQUIV_OBJ(eq_idx) = eq_tmp_idx; 00254 ATD_EQUIV(attr_idx) = TRUE; 00255 ATD_VARIABLE_TMP_IDX(attr_idx) = overlay_attr_idx; 00256 ATD_FLD(attr_idx) = AT_Tbl_Idx; 00257 00258 # if defined(_SEPARATE_NONCOMMON_EQUIV_GROUPS) 00259 00260 sb_idx = ATD_STOR_BLK_IDX(attr_idx); 00261 if (sb_idx == NULL_IDX || 00262 /* (!SB_MODULE(sb_idx) && !SB_IS_COMMON(sb_idx))) { */ 00263 00264 /* keep SB_MODULE variable keep similiar form with subroutine */ 00265 00266 !SB_IS_COMMON(sb_idx)) { 00267 00268 if (SB_HOSTED_STATIC(sb_idx)) { 00269 sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx)); 00270 SB_HOSTED_STATIC(sb_idx) = TRUE; 00271 } 00272 else { 00273 sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx)); 00274 } 00275 00276 ATD_STOR_BLK_IDX(attr_idx) = sb_idx; 00277 ATD_STOR_BLK_IDX(overlay_attr_idx) = sb_idx; 00278 } 00279 # endif 00280 00281 } 00282 else { 00283 00284 ATD_OFFSET_FLD(overlay_attr_idx) = ATD_OFFSET_FLD(attr_idx); 00285 ATD_OFFSET_IDX(overlay_attr_idx) = ATD_CPNT_OFFSET_IDX(attr_idx); 00286 ATD_OFFSET_ASSIGNED(overlay_attr_idx) = 00287 ATD_OFFSET_ASSIGNED(attr_idx); 00288 00289 /* If the array being initialized is a structure component, we */ 00290 /* must calculate its offset within the structure here because */ 00291 /* the derived type definition could be shared by a number of */ 00292 /* structures. (Different structures sharing it means the */ 00293 /* derived type could appear at different offsets within the */ 00294 /* different structures.) Add its offset inside the structure */ 00295 /* to the variable's offset. This is the offset for the overlay */ 00296 /* tmp. If this is in a common block, set ATD_OFFSET for the */ 00297 /* tmp to the component offset and then add it to an equivalence */ 00298 /* group. Equivalence processing for common blocks expects */ 00299 /* offsets for equivalence groups to be in ATD_OFFSET when */ 00300 /* ATD_OFFSET_ASSIGNED is FALSE. */ 00301 00302 ir_idx = IR_IDX_L(whole_sub_ir_idx); 00303 00304 if (ATD_OFFSET_IDX(overlay_attr_idx) == NULL_IDX) { 00305 ATD_OFFSET_FLD(overlay_attr_idx) = CN_Tbl_Idx; 00306 ATD_OFFSET_IDX(overlay_attr_idx) = CN_INTEGER_ZERO_IDX; 00307 } 00308 00309 # if defined(_DEBUG) 00310 00311 /* Must be a constant length. */ 00312 00313 if (ATD_OFFSET_FLD(overlay_attr_idx) != CN_Tbl_Idx) { 00314 PRINTMSG(AT_DEF_LINE(overlay_attr_idx), 1201, Internal, 00315 AT_DEF_COLUMN(overlay_attr_idx), 00316 AT_OBJ_NAME_PTR(overlay_attr_idx)); 00317 } 00318 # endif 00319 00320 result.fld = ATD_OFFSET_FLD(overlay_attr_idx); 00321 result.idx = ATD_OFFSET_IDX(overlay_attr_idx); 00322 00323 while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) { /* Must be Struct IR.*/ 00324 ir_idx = IR_IDX_L(ir_idx); 00325 length.fld = ATD_OFFSET_FLD(IR_IDX_R(ir_idx)); 00326 length.idx = ATD_CPNT_OFFSET_IDX(IR_IDX_R(ir_idx)); 00327 00328 if (!size_offset_binary_calc(&length, 00329 &result, 00330 Plus_Opr, 00331 &result)) { 00332 break; 00333 } 00334 } 00335 00336 if (result.fld == NO_Tbl_Idx) { 00337 ATD_OFFSET_FLD(overlay_attr_idx) = CN_Tbl_Idx; 00338 ATD_OFFSET_IDX(overlay_attr_idx) = ntr_const_tbl(result.type_idx, 00339 FALSE, 00340 result.constant); 00341 } 00342 else { 00343 ATD_OFFSET_FLD(overlay_attr_idx) = result.fld; 00344 ATD_OFFSET_IDX(overlay_attr_idx) = result.idx; 00345 } 00346 00347 var_attr_idx = IR_IDX_L(ir_idx); 00348 ATD_OFFSET_ASSIGNED(overlay_attr_idx) = FALSE; 00349 ATD_DATA_INIT(overlay_attr_idx) = TRUE; 00350 00351 ATD_STOR_BLK_IDX(overlay_attr_idx) = ATD_STOR_BLK_IDX(var_attr_idx); 00352 00353 if (ATD_EQUIV(var_attr_idx)) { 00354 eq_idx = SCP_FIRST_EQUIV_GRP(curr_scp_idx); 00355 00356 while (eq_idx != NULL_IDX) { 00357 eq_tmp_idx = eq_idx; 00358 eq_idx = EQ_NEXT_EQUIV_GRP(eq_idx); 00359 00360 while (eq_tmp_idx != NULL_IDX) { 00361 00362 if (EQ_ATTR_IDX(eq_tmp_idx) == var_attr_idx) { 00363 00364 if (ATD_OFFSET_IDX(var_attr_idx) == NULL_IDX) { 00365 ATD_OFFSET_FLD(var_attr_idx) = CN_Tbl_Idx; 00366 ATD_OFFSET_IDX(var_attr_idx) = CN_INTEGER_ZERO_IDX; 00367 } 00368 NTR_EQ_TBL(eq_idx); 00369 COPY_TBL_NTRY(equiv_tbl, eq_idx, eq_tmp_idx); 00370 EQ_NEXT_EQUIV_OBJ(eq_tmp_idx) = eq_idx; 00371 EQ_ATTR_IDX(eq_idx) = overlay_attr_idx; 00372 00373 result.fld = EQ_OFFSET_FLD(eq_idx); 00374 result.idx = EQ_OFFSET_IDX(eq_idx); 00375 length.fld = ATD_OFFSET_FLD(overlay_attr_idx); 00376 length.idx = ATD_OFFSET_IDX(overlay_attr_idx); 00377 00378 if (!size_offset_binary_calc(&result, 00379 &length, 00380 Plus_Opr, 00381 &result)) { 00382 break; 00383 } 00384 00385 if (result.fld == NO_Tbl_Idx) { 00386 EQ_OFFSET_FLD(eq_idx) = CN_Tbl_Idx; 00387 EQ_OFFSET_IDX(eq_idx) = ntr_const_tbl( 00388 result.type_idx, 00389 FALSE, 00390 result.constant); 00391 } 00392 else if (result.fld == CN_Tbl_Idx) { 00393 EQ_OFFSET_FLD(eq_idx) = result.fld; 00394 EQ_OFFSET_IDX(eq_idx) = result.idx; 00395 } 00396 00397 result.fld = ATD_OFFSET_FLD(var_attr_idx); 00398 result.idx = ATD_OFFSET_IDX(var_attr_idx); 00399 00400 if (!size_offset_binary_calc(&length, 00401 &result, 00402 Plus_Opr, 00403 &result)) { 00404 break; 00405 } 00406 00407 if (result.fld == NO_Tbl_Idx) { 00408 ATD_OFFSET_FLD(overlay_attr_idx) = CN_Tbl_Idx; 00409 ATD_OFFSET_IDX(overlay_attr_idx) = ntr_const_tbl( 00410 result.type_idx, 00411 FALSE, 00412 result.constant); 00413 } 00414 else { 00415 ATD_OFFSET_FLD(overlay_attr_idx) = result.fld; 00416 ATD_OFFSET_IDX(overlay_attr_idx) = result.idx; 00417 } 00418 00419 ATD_EQUIV(var_attr_idx) = TRUE; 00420 goto FOUND; 00421 } 00422 eq_tmp_idx = EQ_NEXT_EQUIV_OBJ(eq_tmp_idx); 00423 } 00424 } 00425 } 00426 00427 /* It is not in an equivalence group or it is not */ 00428 /* equivalenced, so make its own equivalence group. */ 00429 00430 NTR_EQ_TBL(eq_idx); 00431 NTR_EQ_TBL(eq_tmp_idx); 00432 00433 EQ_NEXT_EQUIV_GRP(eq_idx) = SCP_FIRST_EQUIV_GRP(curr_scp_idx); 00434 SCP_FIRST_EQUIV_GRP(curr_scp_idx)= eq_idx; 00435 EQ_OFFSET_IDX(eq_tmp_idx) = ATD_OFFSET_IDX(overlay_attr_idx); 00436 EQ_OFFSET_FLD(eq_tmp_idx) = ATD_OFFSET_FLD(overlay_attr_idx); 00437 EQ_ATTR_IDX(eq_idx) = var_attr_idx; 00438 EQ_ATTR_IDX(eq_tmp_idx) = overlay_attr_idx; 00439 EQ_NEXT_EQUIV_OBJ(eq_idx) = eq_tmp_idx; 00440 ATD_EQUIV(var_attr_idx) = TRUE; 00441 00442 # if defined(_SEPARATE_NONCOMMON_EQUIV_GROUPS) 00443 00444 sb_idx = ATD_STOR_BLK_IDX(var_attr_idx); 00445 00446 if (sb_idx == NULL_IDX || 00447 (!SB_MODULE(sb_idx) && !SB_IS_COMMON(sb_idx))) { 00448 00449 if (SB_HOSTED_STATIC(sb_idx)) { 00450 sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx)); 00451 SB_HOSTED_STATIC(sb_idx) = TRUE; 00452 } 00453 else { 00454 sb_idx = create_equiv_stor_blk(attr_idx, SB_BLK_TYPE(sb_idx)); 00455 } 00456 00457 ATD_STOR_BLK_IDX(var_attr_idx) = sb_idx; 00458 ATD_STOR_BLK_IDX(overlay_attr_idx) = sb_idx; 00459 } 00460 # endif 00461 00462 NTR_IR_LIST_TBL(il_idx); 00463 IL_IDX(il_idx) = overlay_attr_idx; 00464 IL_FLD(il_idx) = AT_Tbl_Idx; 00465 IL_LINE_NUM(il_idx) = stmt_start_line; 00466 IL_COL_NUM(il_idx) = stmt_start_col; 00467 00468 if (ATD_FLD(var_attr_idx) == NO_Tbl_Idx) { 00469 ATD_FLD(var_attr_idx) = IL_Tbl_Idx; 00470 IL_LIST_CNT(il_idx) = 1; 00471 } 00472 else { 00473 IL_LIST_CNT(il_idx) = 1 + 00474 IL_LIST_CNT(ATD_VARIABLE_TMP_IDX(var_attr_idx)); 00475 IL_NEXT_LIST_IDX(il_idx) = ATD_VARIABLE_TMP_IDX(var_attr_idx); 00476 } 00477 ATD_VARIABLE_TMP_IDX(var_attr_idx) = il_idx; 00478 } 00479 00480 FOUND:; 00481 00482 /* Create new bound entry as a one-dimension array. */ 00483 00484 bd_idx = reserve_array_ntry(1); 00485 BD_RESOLVED(bd_idx) = TRUE; 00486 BD_LEN_FLD(bd_idx) = CN_Tbl_Idx; 00487 BD_LEN_IDX(bd_idx) = BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx)); 00488 BD_RANK(bd_idx) = 1; 00489 BD_ARRAY_CLASS(bd_idx) = Explicit_Shape; 00490 BD_ARRAY_SIZE(bd_idx) = Constant_Size; 00491 BD_LINE_NUM(bd_idx) = IR_LINE_NUM_L(whole_sub_ir_idx); 00492 BD_COLUMN_NUM(bd_idx) = IR_COL_NUM_L(whole_sub_ir_idx); 00493 BD_LB_FLD(bd_idx,1) = CN_Tbl_Idx; 00494 BD_LB_IDX(bd_idx,1) = CN_INTEGER_ONE_IDX; 00495 BD_UB_FLD(bd_idx,1) = CN_Tbl_Idx; 00496 BD_UB_IDX(bd_idx,1) = BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx)); 00497 BD_XT_FLD(bd_idx,1) = CN_Tbl_Idx; 00498 BD_XT_IDX(bd_idx,1) = BD_LEN_IDX(ATD_ARRAY_IDX(attr_idx)); 00499 BD_SM_FLD(bd_idx,1) = CN_Tbl_Idx; 00500 BD_SM_IDX(bd_idx,1) = BD_SM_IDX(ATD_ARRAY_IDX(attr_idx),1); 00501 00502 ATD_ARRAY_IDX(overlay_attr_idx) = ntr_array_in_bd_tbl(bd_idx); 00503 00504 curr_subscript = 1; 00505 curr_subscript_idx = CN_INTEGER_ONE_IDX; 00506 00507 attr_idx = overlay_attr_idx; 00508 } 00509 } 00510 else { 00511 first_call = FALSE; 00512 curr_subscript += *dup_count; 00513 curr_subscript_idx = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 00514 curr_subscript); 00515 } 00516 00517 word_size_target = FALSE; 00518 00519 if (TYP_LINEAR(ATD_TYPE_IDX(attr_idx)) == INTEGER_DEFAULT_TYPE || 00520 TYP_LINEAR(ATD_TYPE_IDX(attr_idx)) == REAL_DEFAULT_TYPE) { 00521 00522 if (storage_bit_size_tbl[TYP_LINEAR(ATD_TYPE_IDX(attr_idx))] == 00523 TARGET_BITS_PER_WORD) { 00524 word_size_target = TRUE; 00525 } 00526 } 00527 00528 long_value = FALSE; 00529 00530 if (value_desc.type == Typeless) { 00531 00532 if (TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) > 00533 TARGET_BITS_PER_WORD) { 00534 long_value = TRUE; 00535 } 00536 } 00537 else if (value_desc.type == Character) { 00538 00539 if (CN_INT_TO_C(TYP_IDX(value_desc.type_idx)) > TARGET_CHARS_PER_WORD) { 00540 long_value = TRUE; 00541 } 00542 } 00543 00544 if (word_size_target && long_value) { 00545 PRINTMSG(OPND_LINE_NUM(value_opnd), 733, Error, OPND_COL_NUM(value_opnd)); 00546 } 00547 else { 00548 00549 /* If */ 00550 /* (1) this is the first initialization action for this array, */ 00551 /* (2) it is not a structure component (this restriction can be */ 00552 /* adjusted with experience), and */ 00553 /* (3) it is not an array of structures (that is, it is an intrinsic */ 00554 /* type, */ 00555 /* then see if the whole array init can be turned into the assignment */ 00556 /* of an array constructor value to the array. If the value list is all*/ 00557 /* individual values, this transformation changes the internal form from*/ 00558 /* <n> individual assignments to a single assignment of one large */ 00559 /* typeless blob to the array. */ 00560 00561 if (first_call && 00562 IR_FLD_L(IR_IDX_L(init_ir_idx)) == AT_Tbl_Idx && 00563 TYP_TYPE(ATD_TYPE_IDX(IR_IDX_L(IR_IDX_L(init_ir_idx)))) != 00564 Structure) { 00565 00566 if (ATD_CLASS(attr_idx) == Compiler_Tmp) { 00567 IR_IDX_L(IR_IDX_L(init_ir_idx)) = attr_idx; 00568 } 00569 00570 if (TYP_TYPE(CN_TYPE_IDX(OPND_IDX(value_opnd))) == Character && 00571 (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Integer || 00572 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Real)) { 00573 *optimized = FALSE; 00574 } 00575 else { 00576 *optimized = optimize_whole_array_init(init_ir_idx); 00577 } 00578 00579 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 00580 ok = FALSE; 00581 goto EXIT; 00582 } 00583 00584 if (*optimized) { 00585 goto EXIT; 00586 } 00587 } 00588 else { 00589 *optimized = FALSE; 00590 } 00591 } 00592 00593 00594 /* Make a copy of the reference IR tree. Locate the Whole_Subscript IR */ 00595 /* and change it to a Subscript IR. Use the IL to which the Triplet IR is */ 00596 /* attached to indicate the element at which the initialization is to */ 00597 /* begin. (The Triplet IR is abandoned.) */ 00598 /* LRR: Should we go to the work to free up the space for the Triplet IR */ 00599 /* and its ILs? */ 00600 00601 gen_opnd(&opnd, root_ir_idx, IR_Tbl_Idx, stmt_start_line, stmt_start_col); 00602 copy_subtree(&opnd, &opnd); 00603 ir_idx = OPND_IDX(opnd); 00604 IR_FLD_L(init_ir_idx) = IR_Tbl_Idx; 00605 IR_IDX_L(init_ir_idx) = ir_idx; 00606 00607 while (IR_OPR(ir_idx) != Whole_Subscript_Opr) { 00608 ir_idx = IR_IDX_L(ir_idx); 00609 } 00610 00611 IR_OPR(ir_idx) = Subscript_Opr; 00612 IR_RANK(ir_idx) = 1; 00613 00614 00615 /* If attr_idx is pointing at a compiler temp, it means a multidimension */ 00616 /* array has been overlayed. If the left operand of the Subscript IR is */ 00617 /* an Attr index, just update the index to point at the temp's Attr. */ 00618 /* If the left operand is another IR, it had better be a Struct IR. It */ 00619 /* means the temp is overlaying a multidimensional structure component, so */ 00620 /* replace the whole reference to the component with a reference to the */ 00621 /* temp's Attr. */ 00622 00623 if (ATD_CLASS(attr_idx) == Compiler_Tmp) { 00624 00625 if (IR_FLD_L(ir_idx) == AT_Tbl_Idx) { 00626 IR_IDX_L(ir_idx) = attr_idx; 00627 } 00628 else { /* Had better be a Struct IR. */ 00629 IR_FLD_L(ir_idx) = AT_Tbl_Idx; 00630 IR_IDX_L(ir_idx) = attr_idx; 00631 IR_LINE_NUM_L(ir_idx) = stmt_start_line; 00632 IR_COL_NUM_L(ir_idx) = stmt_start_col; 00633 } 00634 } 00635 00636 il_idx = IR_IDX_R(ir_idx); 00637 IL_NEXT_LIST_IDX(il_idx) = NULL_IDX; 00638 IR_LIST_CNT_R(ir_idx) = 1; 00639 00640 IL_FLD(il_idx) = CN_Tbl_Idx; 00641 IL_IDX(il_idx) = curr_subscript_idx; 00642 IL_LINE_NUM(il_idx) = stmt_start_line; 00643 IL_COL_NUM(il_idx) = stmt_start_col; 00644 00645 00646 EXIT: 00647 00648 TRACE(Func_Exit, "init_whole_array", NULL); 00649 00650 return(ok); 00651 00652 } /* init_whole_array */ 00653 00654 00655 00656 /******************************************************************************\ 00657 |* *| 00658 |* Description: *| 00659 |* Perform semantic checks for the DATA statement and generate IR for *| 00660 |* the PDGCS interface. *| 00661 |* *| 00662 |* Input parameters: *| 00663 |* NONE *| 00664 |* *| 00665 |* Output parameters: *| 00666 |* NONE *| 00667 |* *| 00668 |* Returns: *| 00669 |* NONE *| 00670 |* *| 00671 \******************************************************************************/ 00672 00673 void data_stmt_semantics(void) 00674 { 00675 int array_ir_idx; 00676 int attr_idx; 00677 int column; 00678 boolean compiler_gen_imp_do; 00679 int const_il_idx; 00680 int dim_item_idx; 00681 int dup_cnt_il_idx; 00682 opnd_type dup_cnt_opnd; 00683 long64 dup_count; 00684 boolean dup_count_calculated = FALSE; 00685 boolean first_obj = TRUE; 00686 int first_triplet_idx; 00687 int i; 00688 int il_idx; 00689 int init_ir_idx; 00690 int ir_idx; 00691 size_offset_type length; 00692 int line; 00693 boolean metamorphed; 00694 expr_arg_type obj_desc; 00695 opnd_type obj_opnd; 00696 boolean optimized; 00697 opnd_type rep_factor_opnd; 00698 int root_ir_idx; 00699 long64 section_inc_value; 00700 long64 section_start_value = 0; 00701 int stride_il_idx; 00702 size_offset_type stride_in_bits; 00703 opnd_type stride_opnd; 00704 int struct_ir_idx; 00705 /* int substring_ir_idx; */ 00706 int target_attr_idx; 00707 boolean vv_sub_present; 00708 00709 00710 TRACE (Func_Entry, "data_stmt_semantics", NULL); 00711 00712 OPND_IDX(rep_factor_opnd) = NULL_IDX; 00713 init_ir_idx = SH_IR_IDX(curr_stmt_sh_idx); 00714 obj_il_idx = IR_IDX_L(init_ir_idx); 00715 value_il_idx = IR_IDX_R(init_ir_idx); 00716 metamorphed = FALSE; 00717 obj_count = 0; 00718 rep_factor = 0; 00719 00720 while (obj_il_idx != NULL_IDX) { 00721 00722 if (first_obj) { 00723 first_obj = FALSE; 00724 } 00725 else { 00726 gen_sh(After, Data_Stmt, IL_LINE_NUM(obj_il_idx), 00727 IL_COL_NUM(obj_il_idx), FALSE, FALSE, TRUE); 00728 00729 NTR_IR_TBL(init_ir_idx); 00730 SH_IR_IDX(curr_stmt_sh_idx) = init_ir_idx; 00731 IR_OPR(init_ir_idx) = Init_Opr; 00732 IR_TYPE_IDX(init_ir_idx) = TYPELESS_DEFAULT_TYPE; 00733 IR_LINE_NUM(init_ir_idx) = IL_LINE_NUM(obj_il_idx); 00734 IR_COL_NUM(init_ir_idx) = IL_COL_NUM(obj_il_idx); 00735 } 00736 00737 RESTART: 00738 00739 if (obj_count == 0) { 00740 stride_opnd = null_opnd; 00741 array_ir_idx = NULL_IDX; 00742 struct_ir_idx = NULL_IDX; 00743 /* substring_ir_idx = NULL_IDX; */ 00744 target_attr_idx = NULL_IDX; 00745 obj_desc.rank = 0; 00746 compiler_gen_imp_do = FALSE; 00747 vv_sub_present = FALSE; 00748 00749 COPY_OPND(obj_opnd, IL_OPND(obj_il_idx)); 00750 00751 if (OPND_FLD(obj_opnd) == AT_Tbl_Idx || 00752 (OPND_FLD(obj_opnd) == IR_Tbl_Idx && 00753 IR_OPR(OPND_IDX(obj_opnd)) != Implied_Do_Opr)) { 00754 object_semantics(&obj_opnd, 00755 Data_Stmt_Target, 00756 &obj_desc, 00757 TRUE, 00758 metamorphed); 00759 00760 if (OPND_FLD(obj_opnd) == AT_Tbl_Idx) { 00761 root_ir_idx = NULL_IDX; 00762 } 00763 else { 00764 root_ir_idx = OPND_IDX(obj_opnd); 00765 00766 /* 00767 if (IR_OPR(root_ir_idx) == Whole_Substring_Opr || 00768 IR_OPR(root_ir_idx) == Substring_Opr) { 00769 substring_ir_idx = root_ir_idx; 00770 } 00771 */ 00772 00773 /* Get to the Attr for the item actually being initialized. */ 00774 00775 ir_idx = OPND_IDX(obj_opnd); 00776 00777 while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) { 00778 00779 if (IR_OPR(ir_idx) == Struct_Opr) { 00780 break; 00781 } 00782 else { 00783 ir_idx = IR_IDX_L(ir_idx); 00784 } 00785 } 00786 00787 target_attr_idx = (IR_OPR(ir_idx) == Struct_Opr) ? 00788 IR_IDX_R(ir_idx) : IR_IDX_L(ir_idx); 00789 } 00790 00791 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 00792 COPY_OPND(IR_OPND_L(init_ir_idx), obj_opnd); 00793 } 00794 else { 00795 goto EXIT; 00796 } 00797 } 00798 } 00799 00800 /* We have to keep processing the DATA stmt even if there are no values */ 00801 /* left (value_il_idx is NULL_IDX) to make sure that all remaining */ 00802 /* targets (including implied-DOs) are zero-sized (because zero-sized */ 00803 /* don't contribute any variables to the target list). */ 00804 /* If rep_factor is not 0, it means part of the value was not used up */ 00805 /* a previous target. */ 00806 00807 if (rep_factor == 0) { 00808 set_global_value_variables(&rep_factor_opnd, 00809 &dup_cnt_opnd, 00810 target_attr_idx); 00811 00812 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 00813 goto EXIT; 00814 } 00815 } 00816 00817 /* If the target item is a whole array or section, the "array" IR is */ 00818 /* the one that is of interest. Otherwise, get down through possible */ 00819 /* Whole_Substring, Substring, or Struct IR to the Attr for the scalar */ 00820 /* item actually being initialized. If the target is character, we'll */ 00821 /* deal with blank padding after the target is initially processed. */ 00822 00823 PROCESS_THE_TARGET: 00824 00825 /* NULL initializations are thrown out after semantics are done. We */ 00826 /* initialize pointers to NULL by default, so we do not have to gen */ 00827 /* code to do it. Just make sure the object is a pointer. */ 00828 00829 if (obj_desc.rank > 0 && !obj_desc.pointer) { 00830 00831 /* Find the IR (either Whole_Subscript or Section_Subscript) that */ 00832 /* produces the nonzero rank. */ 00833 00834 if (array_ir_idx == NULL_IDX) { 00835 array_ir_idx = OPND_IDX(obj_opnd); 00836 00837 while (IR_OPR(array_ir_idx) != Whole_Subscript_Opr && 00838 IR_OPR(array_ir_idx) != Section_Subscript_Opr) { 00839 00840 /* 00841 if (IR_OPR(array_ir_idx) == Substring_Opr || 00842 IR_OPR(array_ir_idx) == Whole_Substring_Opr) { 00843 substring_ir_idx = array_ir_idx; 00844 } 00845 */ 00846 00847 if (IR_OPR(array_ir_idx) == Struct_Opr) { 00848 struct_ir_idx = array_ir_idx; 00849 } 00850 00851 array_ir_idx = IR_IDX_L(array_ir_idx); 00852 } 00853 } 00854 00855 if (IR_OPR(array_ir_idx) == Whole_Subscript_Opr) { 00856 00857 /* A zero-sized array contributes no variables to the list so */ 00858 /* just iterate to the next object if the array is zero-sized. */ 00859 00860 if (IR_FLD_L(array_ir_idx) == AT_Tbl_Idx) { 00861 dim_item_idx = IR_IDX_L(array_ir_idx); 00862 } 00863 else { 00864 00865 /* If there was no Struct IR ahead of the Whole_Subscript IR, */ 00866 /* it means we're processing a component that is an array. */ 00867 /* The Whole_Subscript IR must be pointing at a Struct IR. */ 00868 /* If there WAS a Struct IR ahead of the Whole_Subscript IR, */ 00869 /* it means we're processing a component out of each element */ 00870 /* of an array of structures. */ 00871 00872 if (struct_ir_idx == NULL_IDX) { 00873 dim_item_idx = IR_IDX_R(IR_IDX_L(array_ir_idx)); 00874 } 00875 else { 00876 ir_idx = IR_IDX_L(array_ir_idx); 00877 00878 while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) { 00879 ir_idx = IR_IDX_L(ir_idx); 00880 } 00881 00882 dim_item_idx = IR_IDX_L(ir_idx); 00883 } 00884 00885 } 00886 00887 if (compare_cn_and_value(BD_LEN_IDX(ATD_ARRAY_IDX(dim_item_idx)), 00888 0, Eq_Opr)) { 00889 SH_IR_IDX(curr_stmt_sh_idx) = NULL_IDX; 00890 obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx); 00891 continue; /* the big obj_il_idx loop */ 00892 } 00893 00894 if (struct_ir_idx == NULL_IDX || 00895 (struct_ir_idx != NULL_IDX && obj_desc.rank == 1)) { 00896 00897 if (init_whole_array(array_ir_idx, 00898 &dup_count, 00899 root_ir_idx, 00900 init_ir_idx, 00901 &optimized)) { 00902 00903 if (optimized) { 00904 obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx); 00905 continue; /* the big obj_il_idx loop */ 00906 } 00907 } 00908 else { 00909 goto EXIT; 00910 } 00911 } 00912 else { 00913 IR_OPR(array_ir_idx) = Section_Subscript_Opr; 00914 goto PROCESS_THE_TARGET; 00915 } 00916 } 00917 else { 00918 00919 /* Process the Section_Subscript IR. */ 00920 00921 if (obj_count == 0) { 00922 il_idx = IR_IDX_R(array_ir_idx); 00923 00924 for (i = 1; i <= IR_LIST_CNT_R(array_ir_idx); ++i) { 00925 00926 if (IL_VECTOR_SUBSCRIPT(il_idx)) { 00927 vv_sub_present = TRUE; 00928 break; 00929 } 00930 00931 il_idx = IL_NEXT_LIST_IDX(il_idx); 00932 } 00933 00934 /* If there is at least one vector valued subscript present, */ 00935 /* just turn the whole reference into a (perhaps nested) set */ 00936 /* of implied-DOs. Then call data_imp_do_semantics to verify */ 00937 /* that all the values are assignment compatible with the */ 00938 /* target. */ 00939 00940 if (vv_sub_present) { 00941 vv_subscript_semantics(init_ir_idx, 00942 array_ir_idx, 00943 &obj_desc); 00944 00945 data_imp_do_semantics(init_ir_idx, 00946 IR_IDX_L(init_ir_idx), 00947 TRUE, 00948 &metamorphed); 00949 00950 obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx); 00951 continue; /* the big obj_il_idx loop */ 00952 } 00953 else { 00954 section_semantics(array_ir_idx, 00955 &stride_opnd, 00956 &first_triplet_idx); 00957 } 00958 } 00959 00960 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 00961 goto EXIT; 00962 } 00963 00964 if (obj_count != 0) { 00965 gen_section_ref( array_ir_idx, 00966 rep_factor, 00967 first_triplet_idx, 00968 root_ir_idx, 00969 init_ir_idx, 00970 &dup_count, 00971 §ion_start_value, 00972 §ion_inc_value); 00973 dup_count_calculated = TRUE; 00974 } 00975 else { 00976 SH_IR_IDX(curr_stmt_sh_idx) = NULL_IDX; 00977 obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx); 00978 continue; /* the big obj_il_idx loop */ 00979 } 00980 } 00981 } 00982 else { 00983 00984 /* We are dealing with a scalar target or an implied-DO. */ 00985 00986 if (OPND_FLD(obj_opnd) == AT_Tbl_Idx) { 00987 obj_count = 1; 00988 target_attr_idx = OPND_IDX(obj_opnd); 00989 } 00990 else { 00991 00992 /* OPND_FLD(obj_opnd) must be IR_Tbl_Idx. */ 00993 00994 if (IR_OPR(OPND_IDX(obj_opnd)) == Implied_Do_Opr) { 00995 00996 data_imp_do_semantics(init_ir_idx, 00997 IL_IDX(obj_il_idx), 00998 compiler_gen_imp_do, 00999 &metamorphed); 01000 01001 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 01002 goto EXIT; 01003 } 01004 01005 if (metamorphed) { 01006 IL_FLD(obj_il_idx) = IL_FLD(IR_IDX_L(init_ir_idx)); 01007 IL_IDX(obj_il_idx) = IL_IDX(IR_IDX_L(init_ir_idx)); 01008 goto RESTART; 01009 } 01010 01011 COPY_OPND(IR_OPND_L(init_ir_idx), obj_opnd); 01012 obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx); 01013 01014 continue; /* the big obj_il_idx loop */ 01015 } 01016 else { 01017 01018 /* Here if object is a character item (due to Whole_Substring */ 01019 /* or Substring IR), an array element, or a structure */ 01020 /* component. */ 01021 01022 obj_count = 1; 01023 01024 /* 01025 if (OPND_FLD(obj_opnd) == IR_Tbl_Idx && 01026 (IR_OPR(OPND_IDX(obj_opnd)) == Substring_Opr || 01027 IR_OPR(OPND_IDX(obj_opnd)) == Whole_Substring_Opr)) { 01028 01029 substring_ir_idx = OPND_IDX(obj_opnd); 01030 } 01031 */ 01032 } 01033 } 01034 } 01035 01036 /* Have we run out of values but not out of targets? */ 01037 01038 if (value_il_idx == NULL_IDX) { 01039 find_opnd_line_and_column(&obj_opnd, &line, &column); 01040 PRINTMSG(line, 667, Error, column); 01041 goto EXIT; 01042 } 01043 01044 /* Verify that the value is assignment compatible with the target. */ 01045 01046 if (! check_target_and_value(target_attr_idx, init_ir_idx)) { 01047 goto EXIT; 01048 } 01049 01050 /* Generate the IL that holds the value. */ 01051 01052 NTR_IR_LIST_TBL(const_il_idx); 01053 IR_LIST_CNT_R(init_ir_idx) = 3; 01054 IR_FLD_R(init_ir_idx) = IL_Tbl_Idx; 01055 IR_IDX_R(init_ir_idx) = const_il_idx; 01056 COPY_OPND(IL_OPND(const_il_idx), value_opnd); 01057 01058 /* Generate the IL that holds the repetition count. */ 01059 01060 NTR_IR_LIST_TBL(dup_cnt_il_idx); 01061 IL_PREV_LIST_IDX(dup_cnt_il_idx) = const_il_idx; 01062 IL_NEXT_LIST_IDX(const_il_idx) = dup_cnt_il_idx; 01063 01064 if (OPND_IDX(rep_factor_opnd) == NULL_IDX) { 01065 find_opnd_line_and_column(&value_opnd, &line, &column); 01066 IL_LINE_NUM(dup_cnt_il_idx) = line; 01067 IL_COL_NUM(dup_cnt_il_idx) = column; 01068 IL_FLD(dup_cnt_il_idx) = CN_Tbl_Idx; 01069 IL_IDX(dup_cnt_il_idx) = CN_INTEGER_ONE_IDX; 01070 dup_count = 1; 01071 } 01072 else { 01073 01074 if (dup_count_calculated) { 01075 dup_count_calculated = FALSE; 01076 } 01077 else { 01078 dup_count = (obj_count <= rep_factor) ? obj_count : rep_factor; 01079 } 01080 01081 OPND_IDX(dup_cnt_opnd) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 01082 dup_count); 01083 COPY_OPND(IL_OPND(dup_cnt_il_idx), dup_cnt_opnd); 01084 } 01085 01086 /* Generate the IR that holds the stride value. A single item has a */ 01087 /* stride of 0. */ 01088 01089 NTR_IR_LIST_TBL(stride_il_idx); 01090 IL_PREV_LIST_IDX(stride_il_idx) = dup_cnt_il_idx; 01091 IL_NEXT_LIST_IDX(dup_cnt_il_idx) = stride_il_idx; 01092 01093 if (dup_count == 1 || 01094 (OPND_IDX(stride_opnd) == NULL_IDX && array_ir_idx == NULL_IDX)) { 01095 find_opnd_line_and_column(&obj_opnd, &line, &column); 01096 IL_LINE_NUM(stride_il_idx) = line; 01097 IL_COL_NUM(stride_il_idx) = column; 01098 IL_FLD(stride_il_idx) = CN_Tbl_Idx; 01099 IL_IDX(stride_il_idx) = CN_INTEGER_ZERO_IDX; 01100 } 01101 else { 01102 01103 /* If the stride has not yet been computed, compute it in bits. */ 01104 /* Note: OPND_FLD is used rather than OPND_IDX. Section processing */ 01105 /* sets OPND_IDX but leaves OPND_FLD as NO_Tbl_Idx to signal that */ 01106 /* the actual bit stride has not yet been calculated. */ 01107 01108 if (OPND_FLD(stride_opnd) == NO_Tbl_Idx) { 01109 01110 if (struct_ir_idx == NULL_IDX) { 01111 attr_idx = (IR_FLD_L(array_ir_idx) == AT_Tbl_Idx) ? 01112 IR_IDX_L(array_ir_idx) : 01113 IR_IDX_R(IR_IDX_L(array_ir_idx)); 01114 } 01115 else { 01116 ir_idx = array_ir_idx; 01117 01118 while (IR_FLD_L(ir_idx) == IR_Tbl_Idx) { 01119 ir_idx = IR_IDX_L(ir_idx); 01120 } 01121 01122 attr_idx = IR_IDX_L(ir_idx); 01123 } 01124 01125 stride_in_bits = stor_bit_size_of(attr_idx, FALSE, FALSE); 01126 01127 if (OPND_IDX(stride_opnd) != NULL_IDX) { 01128 length.fld = CN_Tbl_Idx; 01129 length.idx = OPND_IDX(stride_opnd); 01130 01131 size_offset_binary_calc(&stride_in_bits, 01132 &length, 01133 Mult_Opr, 01134 &stride_in_bits); 01135 } 01136 01137 if (stride_in_bits.fld == NO_Tbl_Idx) { 01138 OPND_FLD(stride_opnd) = CN_Tbl_Idx; 01139 OPND_IDX(stride_opnd) = ntr_const_tbl(stride_in_bits.type_idx, 01140 FALSE, 01141 stride_in_bits.constant); 01142 } 01143 else { 01144 OPND_FLD(stride_opnd) = stride_in_bits.fld; 01145 OPND_IDX(stride_opnd) = stride_in_bits.idx; 01146 } 01147 01148 OPND_LINE_NUM(stride_opnd) = stmt_start_line; 01149 OPND_COL_NUM(stride_opnd) = stmt_start_col; 01150 } 01151 01152 COPY_OPND(IL_OPND(stride_il_idx), stride_opnd); 01153 } 01154 01155 /* If the item is type character, see if the initialization value needs */ 01156 /* to be blank padded. */ 01157 01158 if (TYP_TYPE(ATD_TYPE_IDX(target_attr_idx)) == Character) { 01159 adjust_char_value_len(init_ir_idx, 01160 array_ir_idx, 01161 section_start_value, 01162 section_inc_value); 01163 } 01164 01165 /* If we have assigned values to all the (possibly expanded) objects */ 01166 /* represented by the current object IL, move ahead to the next object */ 01167 /* IL. Similarly, if we've used up all the values represented by the */ 01168 /* current value IL, move ahead to the next value IL. */ 01169 01170 if ((obj_count -= dup_count) == 0) { 01171 obj_il_idx = IL_NEXT_LIST_IDX(obj_il_idx); 01172 } 01173 01174 if ((rep_factor -= dup_count) == 0) { 01175 value_il_idx = IL_NEXT_LIST_IDX(value_il_idx); 01176 /* BHJ */ 01177 if (value_il_idx != NULL_IDX) { 01178 IL_PREV_LIST_IDX(value_il_idx) = NULL_IDX; 01179 } 01180 01181 if (value_il_idx == NULL_IDX && obj_count != 0) { 01182 01183 /* If obj_count != 0, it means we're still working on an array */ 01184 /* reference of some kind. CF77 has an outmoded feature that */ 01185 /* allows the number of values in the constant list to be less */ 01186 /* than the number of targets as long as the last target is a */ 01187 /* whole array reference. Do not extend this extension by */ 01188 /* considering it OK if the whole array reference is not the last */ 01189 /* thing in the target list but everything following it is zero- */ 01190 /* sized. */ 01191 01192 if (OPND_FLD(obj_opnd) == IR_Tbl_Idx && 01193 IR_OPR(OPND_IDX(obj_opnd)) == Whole_Subscript_Opr && 01194 IL_NEXT_LIST_IDX(obj_il_idx) == NULL_IDX) { 01195 01196 if (IR_OPR(init_ir_idx) == Init_Opr) { 01197 PRINTMSG(IR_LINE_NUM_L(OPND_IDX(obj_opnd)), 698, Ansi, 01198 IR_COL_NUM_L(OPND_IDX(obj_opnd))); 01199 } 01200 01201 break; 01202 } 01203 else { 01204 find_opnd_line_and_column(&obj_opnd, &line, &column); 01205 PRINTMSG(line, 667, Error, column); 01206 obj_il_idx = NULL_IDX; 01207 } 01208 } 01209 } 01210 01211 } /* while (obj_il_idx != NULL_IDX) */ 01212 01213 if (value_il_idx != NULL_IDX) { 01214 PRINTMSG(IL_LINE_NUM(value_il_idx), 668, Error, IL_COL_NUM(value_il_idx)); 01215 } 01216 01217 EXIT: 01218 01219 TRACE (Func_Exit, "data_stmt_semantics", NULL); 01220 01221 return; 01222 01223 } /* data_stmt_semantics */ 01224 01225 01226 /******************************************************************************\ 01227 |* *| 01228 |* Description: *| 01229 |* This procedure performs semantic analysis on the current object. *| 01230 |* *| 01231 |* Input parameters: *| 01232 |* obj_opnd : the operand representing the object *| 01233 |* target_expr_mode : the expr_semantics mode in which the DATA should *| 01234 |* be evaluated *| 01235 |* fold_subscripts : TRUE if subscripts are to be folded (the target is *| 01236 |* NOT an implied-DO target; implied-DO targets are *| 01237 |* handled by the interface) *| 01238 |* metamorphed : TRUE if an implied-DO has been metamorphed into *| 01239 |* a whole array or section ref initialization *| 01240 |* *| 01241 |* Output parameters: *| 01242 |* obj_opnd : the updated operand *| 01243 |* obj_desc : the expression descriptor returned by expr_semantics *| 01244 |* *| 01245 |* Returns: *| 01246 |* NONE *| 01247 |* *| 01248 \******************************************************************************/ 01249 01250 static void object_semantics(opnd_type *obj_opnd, 01251 expr_mode_type target_expr_mode, 01252 expr_arg_type *obj_desc, 01253 boolean fold_subscripts, 01254 boolean metamorphed) 01255 01256 { 01257 int attr_idx; 01258 opnd_type data_obj; 01259 01260 01261 TRACE (Func_Entry, "object_semantics", NULL); 01262 01263 /* Get down to the Attr for the target. */ 01264 /* If there's something wrong with the target, just give up. */ 01265 01266 COPY_OPND(data_obj, *obj_opnd); 01267 01268 while (OPND_FLD(data_obj) == IR_Tbl_Idx) { 01269 COPY_OPND(data_obj, IR_OPND_L(OPND_IDX(data_obj))); 01270 } 01271 01272 if (AT_DCL_ERR(OPND_IDX(data_obj))) { 01273 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 01274 goto EXIT; 01275 } 01276 01277 /* Evaluate the target. */ 01278 01279 expr_mode = target_expr_mode; 01280 obj_desc->rank = 0; 01281 01282 /* Add 100 to the "modification" value to signal the item is being */ 01283 /* initialized. */ 01284 01285 xref_state = (metamorphed) ? CIF_No_Usage_Rec : 01286 (cif_usage_code_type) 01287 (CIF_Symbol_Modification + 100); 01288 01289 if (expr_semantics(obj_opnd, obj_desc)) { 01290 01291 COPY_OPND(data_obj, *obj_opnd); 01292 01293 while (OPND_FLD(data_obj) == IR_Tbl_Idx) { 01294 COPY_OPND(data_obj, IR_OPND_L(OPND_IDX(data_obj))); 01295 } 01296 01297 attr_idx = OPND_IDX(data_obj); 01298 01299 /* Constraint checks: */ 01300 /* * A variable that is a member of blank common should not be */ 01301 /* initialized. */ 01302 /* * A variable that is a member of a named common block should only be */ 01303 /* initialized in a block data program unit. */ 01304 /* * A variable that is a member of a task common block must not be */ 01305 /* initialized. */ 01306 /* * From a CF77 SPR: If an object in a Block Data program unit is NOT */ 01307 /* in a common block (and is not equivalenced to an object in common) */ 01308 /* but IS initialized, issue a warning. */ 01309 /* * F95 -> An item must not be specified in a DATA statement if it is */ 01310 /* of a default initialized type. */ 01311 01312 if (ATD_IN_COMMON(attr_idx)) { 01313 01314 if (SB_BLK_TYPE(ATD_STOR_BLK_IDX(attr_idx)) == Common) { 01315 01316 if (! metamorphed) { 01317 01318 if (SB_BLANK_COMMON(ATD_STOR_BLK_IDX(attr_idx))) { 01319 PRINTMSG(OPND_LINE_NUM(data_obj), 1109, Ansi, 01320 OPND_COL_NUM(data_obj)); 01321 } 01322 else if (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) != Blockdata) { 01323 01324 # if defined(_ALLOW_DATA_INIT_OF_COMMON) 01325 PRINTMSG(OPND_LINE_NUM(data_obj), 692, Ansi, 01326 OPND_COL_NUM(data_obj)); 01327 # else 01328 PRINTMSG(OPND_LINE_NUM(data_obj), 1542, Warning, 01329 OPND_COL_NUM(data_obj)); 01330 # endif 01331 } 01332 } 01333 } 01334 else if (SB_BLK_TYPE(ATD_STOR_BLK_IDX(attr_idx)) == Task_Common) { 01335 PRINTMSG(OPND_LINE_NUM(data_obj), 851, Error, 01336 OPND_COL_NUM(data_obj)); 01337 } 01338 } 01339 else if (ATP_PGM_UNIT(SCP_ATTR_IDX(curr_scp_idx)) == Blockdata && 01340 !(ATD_EQUIV(attr_idx) && 01341 SB_IS_COMMON(ATD_STOR_BLK_IDX(attr_idx)))) { 01342 PRINTMSG(OPND_LINE_NUM(data_obj), 825, Warning, 01343 OPND_COL_NUM(data_obj)); 01344 } 01345 01346 01347 /* There is no way to initialize a CRI character pointer. */ 01348 01349 if (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == CRI_Ch_Ptr) { 01350 # ifdef _EXTENDED_CRI_CHAR_POINTER 01351 transform_cri_ch_ptr(obj_opnd); 01352 # else 01353 PRINTMSG(OPND_LINE_NUM(data_obj), 695, Error, OPND_COL_NUM(data_obj)); 01354 # endif 01355 } 01356 01357 if (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) == Structure && 01358 ATT_DEFAULT_INITIALIZED(TYP_IDX(ATD_TYPE_IDX(attr_idx)))) { 01359 PRINTMSG(OPND_LINE_NUM(data_obj), 1589, Error, 01360 OPND_COL_NUM(data_obj), 01361 AT_OBJ_NAME_PTR(attr_idx), 01362 AT_OBJ_NAME_PTR(TYP_IDX(ATD_TYPE_IDX(attr_idx)))); 01363 } 01364 01365 /* If the target is subscripted, fold the subscript expressions that */ 01366 /* may have been too complicated for expr_semantics to have folded when */ 01367 /* the target reference was evaluated. */ 01368 /* Note that object_semantics is only called for a scalar target or a */ 01369 /* a target of an implied-DO. fold_all_subscripts is only called for a */ 01370 /* scalar target. */ 01371 01372 if (OPND_FLD((*obj_opnd)) == IR_Tbl_Idx && fold_subscripts) { 01373 fold_all_subscripts(obj_opnd); 01374 } 01375 } 01376 01377 EXIT: 01378 01379 expr_mode = Regular_Expr; 01380 01381 TRACE (Func_Exit, "object_semantics", NULL); 01382 01383 return; 01384 01385 } /* object_semantics */ 01386 01387 01388 /******************************************************************************\ 01389 |* *| 01390 |* Description: *| 01391 |* This procedure sets up rep_factor_opnd, value_desc, and advances *| 01392 |* value_il_idx in some situations. *| 01393 |* *| 01394 |* Input parameters: *| 01395 |* NONE *| 01396 |* *| 01397 |* Output parameters: *| 01398 |* rep_factor_opnd : the opnd representing the rep factor *| 01399 |* dup_cnt_opnd : a copy of the rep factor opnd *| 01400 |* *| 01401 |* Returns: *| 01402 |* NONE *| 01403 |* *| 01404 \******************************************************************************/ 01405 01406 static void set_global_value_variables(opnd_type *rep_factor_opnd, 01407 opnd_type *dup_cnt_opnd, 01408 int target_attr_idx) 01409 { 01410 expr_arg_type expr_desc; 01411 int rep_count_ir_idx; 01412 01413 01414 TRACE (Func_Entry, "set_global_value_variables", NULL); 01415 01416 /* Loop even though the rep factor is 0 because a value with a rep factor */ 01417 /* of 0 contributes no values to the list. */ 01418 01419 while (rep_factor == 0 && value_il_idx != NULL_IDX) { 01420 01421 if (IL_FLD(value_il_idx) == IR_Tbl_Idx && 01422 IR_OPR(IL_IDX(value_il_idx)) == Rep_Count_Opr) { 01423 rep_count_ir_idx = IL_IDX(value_il_idx); 01424 COPY_OPND(*rep_factor_opnd, IR_OPND_L(rep_count_ir_idx)); 01425 01426 # ifdef _DEBUG 01427 01428 if (OPND_FLD((*rep_factor_opnd)) != CN_Tbl_Idx) { 01429 PRINTMSG(IR_LINE_NUM(rep_count_ir_idx), 626, Internal, 01430 IR_COL_NUM(rep_count_ir_idx), 01431 "CN_Tbl_Idx", "set_global_value_variables"); 01432 } 01433 01434 # endif 01435 01436 expr_desc.type_idx = CN_TYPE_IDX(OPND_IDX((*rep_factor_opnd))); 01437 expr_desc.type = TYP_TYPE(expr_desc.type_idx); 01438 expr_desc.linear_type = TYP_LINEAR(expr_desc.type_idx); 01439 01440 rep_factor = CN_INT_TO_C(OPND_IDX((*rep_factor_opnd))); 01441 01442 if (rep_factor > 0) { 01443 COPY_OPND(*dup_cnt_opnd, *rep_factor_opnd); 01444 COPY_OPND(value_opnd, IR_OPND_R(rep_count_ir_idx)); 01445 } 01446 else if (rep_factor == 0) { 01447 OPND_IDX((*rep_factor_opnd)) = NULL_IDX; 01448 01449 if (IL_PREV_LIST_IDX(value_il_idx) != NULL_IDX) { 01450 IL_NEXT_LIST_IDX(IL_PREV_LIST_IDX(value_il_idx)) = 01451 IL_NEXT_LIST_IDX(value_il_idx); 01452 } 01453 01454 if (IL_NEXT_LIST_IDX(value_il_idx) != NULL_IDX) { 01455 IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(value_il_idx)) = 01456 IL_PREV_LIST_IDX(value_il_idx); 01457 } 01458 01459 value_il_idx = IL_NEXT_LIST_IDX(value_il_idx); 01460 continue; 01461 } 01462 else { /* Must be positive or zero */ 01463 PRINTMSG(OPND_LINE_NUM((*rep_factor_opnd)), 679, Error, 01464 OPND_COL_NUM((*rep_factor_opnd))); 01465 goto EXIT; 01466 } 01467 } 01468 else { 01469 COPY_OPND(value_opnd, IL_OPND(value_il_idx)); 01470 rep_factor = 1; 01471 OPND_IDX((*rep_factor_opnd)) = NULL_IDX; 01472 rep_count_ir_idx = NULL_IDX; 01473 } 01474 01475 } /* while (rep_factor == 0 && value_il_idx != NULL_IDX) */ 01476 01477 if (value_il_idx == NULL_IDX) { 01478 goto EXIT; 01479 } 01480 01481 01482 /* value_opnd contains either the value that was in the value list or the */ 01483 /* value to the right of the rep factor. */ 01484 01485 if (OPND_FLD(value_opnd) == CN_Tbl_Idx) { 01486 value_desc.type_idx = CN_TYPE_IDX(OPND_IDX(value_opnd)); 01487 value_desc.type = TYP_TYPE(value_desc.type_idx); 01488 value_desc.linear_type = TYP_LINEAR(value_desc.type_idx); 01489 } 01490 else if (OPND_FLD(value_opnd) == AT_Tbl_Idx && 01491 AT_OBJ_CLASS(OPND_IDX(value_opnd)) == Data_Obj && 01492 ATD_CLASS(OPND_IDX(value_opnd)) == Compiler_Tmp && 01493 ATD_FLD(OPND_IDX(value_opnd)) == CN_Tbl_Idx) { 01494 01495 value_desc.type_idx = ATD_TYPE_IDX(OPND_IDX(value_opnd)); 01496 value_desc.type = TYP_TYPE(value_desc.type_idx); 01497 value_desc.linear_type = TYP_LINEAR(value_desc.type_idx); 01498 01499 OPND_FLD(value_opnd) = CN_Tbl_Idx; 01500 OPND_IDX(value_opnd) = ATD_TMP_IDX(OPND_IDX(value_opnd)); 01501 01502 if (rep_count_ir_idx == NULL_IDX) { 01503 COPY_OPND(IL_OPND(value_il_idx), value_opnd); 01504 } 01505 else { 01506 COPY_OPND(IR_OPND_R(rep_count_ir_idx), value_opnd); 01507 } 01508 } 01509 else if (OPND_FLD(value_opnd) == IR_Tbl_Idx && 01510 IR_OPR(OPND_IDX(value_opnd)) == Null_Intrinsic_Opr) { 01511 value_desc.type_idx = ATD_TYPE_IDX(target_attr_idx); 01512 value_desc.type = TYP_TYPE(ATD_TYPE_IDX(target_attr_idx)); 01513 value_desc.linear_type = TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)); 01514 } 01515 01516 # ifdef _DEBUG 01517 01518 else { 01519 PRINTMSG(IR_LINE_NUM(rep_count_ir_idx), 626, Internal, 01520 IR_COL_NUM(rep_count_ir_idx), 01521 "CN_Tbl_Idx or AT_Tbl_Idx", "set_global_value_variables"); 01522 } 01523 01524 # endif 01525 01526 01527 EXIT: 01528 01529 TRACE (Func_Exit, "set_global_value_variables", NULL); 01530 01531 return; 01532 01533 } /* set_global_value_variables */ 01534 01535 01536 01537 /******************************************************************************\ 01538 |* *| 01539 |* Description: *| 01540 |* This procedure sets up the loop_tbl and calculates the number of *| 01541 |* targets represented by the section reference. *| 01542 |* *| 01543 |* Input parameters: *| 01544 |* section_sub_ir_idx : the index of the Section_Subscript IR *| 01545 |* *| 01546 |* Output parameters: *| 01547 |* stride_opnd : set to the stride value from the first section *| 01548 |* triplet *| 01549 |* first_triplet_idx : the index of the first loop_tbl entry that *| 01550 |* represents a triplet section subscript *| 01551 |* *| 01552 |* Returns: *| 01553 |* NONE *| 01554 |* *| 01555 \******************************************************************************/ 01556 01557 static void section_semantics(int section_sub_ir_idx, 01558 opnd_type *stride_opnd, 01559 int *first_triplet_idx) 01560 01561 { 01562 long64 actual_stride; 01563 int attr_idx; 01564 int bd_idx; 01565 long64 dcl_lb; 01566 long64 dcl_ub; 01567 int end_il_idx; 01568 boolean error_found; 01569 expr_arg_type expr_desc; 01570 opnd_type expr_opnd; 01571 int i; 01572 int ignore_this_arg; 01573 int ignore_this_arg_too; 01574 int il_idx; 01575 int last_triplet_idx = NULL_IDX; 01576 long64 num_iterations; 01577 int start_il_idx; 01578 int stride_il_idx; 01579 01580 01581 TRACE(Func_Entry, "section_semantics", NULL); 01582 01583 obj_count = 1; 01584 *first_triplet_idx = NULL_IDX; 01585 01586 /* Capture the subscript info in the loop_tbl. */ 01587 01588 expr_desc = init_exp_desc; 01589 expr_desc.type = Integer; 01590 expr_desc.type_idx = INTEGER_DEFAULT_TYPE; 01591 expr_desc.linear_type = INTEGER_DEFAULT_TYPE; 01592 01593 il_idx = IR_IDX_R(section_sub_ir_idx); 01594 01595 for (lt_idx = 1; lt_idx <= IR_LIST_CNT_R(section_sub_ir_idx); ++lt_idx) { 01596 loop_tbl[lt_idx].sibling_idx = NULL_IDX; 01597 01598 if (IL_FLD(il_idx) == CN_Tbl_Idx) { 01599 loop_tbl[lt_idx].curr_value = CN_INT_TO_C(IL_IDX(il_idx)); 01600 } 01601 else if (IL_FLD(il_idx) == IR_Tbl_Idx) { 01602 01603 /* Had better be a Triplet IR. */ 01604 01605 if (IR_OPR(IL_IDX(il_idx)) != Triplet_Opr) { 01606 PRINTMSG(IL_LINE_NUM(il_idx), 704, Internal, IL_COL_NUM(il_idx)); 01607 } 01608 01609 error_found = FALSE; 01610 01611 01612 /* Get the declared lower and upper bounds for this dimension. */ 01613 /* (Bound info might be associated with a structure component.) */ 01614 /* find_base_attr does NOT change the opnd. */ 01615 01616 attr_idx = find_base_attr(&IR_OPND_L(section_sub_ir_idx), 01617 &ignore_this_arg, 01618 &ignore_this_arg_too); 01619 01620 dcl_lb = CN_INT_TO_C(BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), lt_idx)); 01621 dcl_ub = CN_INT_TO_C(BD_UB_IDX(ATD_ARRAY_IDX(attr_idx), lt_idx)); 01622 01623 01624 /* Capture the start value. */ 01625 01626 start_il_idx = IR_IDX_L(IL_IDX(il_idx)); 01627 01628 if (IL_FLD(start_il_idx) == CN_Tbl_Idx) { 01629 /* Nuttin' to do. */ 01630 } 01631 else if (IL_FLD(start_il_idx) == IR_Tbl_Idx) { 01632 COPY_OPND(expr_opnd, IL_OPND(start_il_idx)); 01633 01634 if (fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) { 01635 COPY_OPND(IL_OPND(start_il_idx), expr_opnd); 01636 } 01637 else { 01638 PRINTMSG(IR_LINE_NUM(IL_IDX(start_il_idx)), 01639 861, 01640 Internal, 01641 IR_COL_NUM(IL_IDX(start_il_idx)), 01642 "section_semantics"); 01643 } 01644 } 01645 else { 01646 PRINTMSG(IR_LINE_NUM(IL_IDX(start_il_idx)), 01647 704, 01648 Internal, 01649 IR_COL_NUM(IL_IDX(start_il_idx))); 01650 } 01651 01652 loop_tbl[lt_idx].start_value = CN_INT_TO_C(IL_IDX(start_il_idx)); 01653 loop_tbl[lt_idx].curr_value = loop_tbl[lt_idx].start_value; 01654 01655 01656 /* Capture the end value. */ 01657 01658 end_il_idx = IL_NEXT_LIST_IDX(start_il_idx); 01659 01660 if (IL_FLD(end_il_idx) == CN_Tbl_Idx) { 01661 /* Nuttin' to do. */ 01662 } 01663 else if (IL_FLD(end_il_idx) == IR_Tbl_Idx) { 01664 COPY_OPND(expr_opnd, IL_OPND(end_il_idx)); 01665 01666 if (fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) { 01667 COPY_OPND(IL_OPND(end_il_idx), expr_opnd); 01668 } 01669 else { 01670 PRINTMSG(IR_LINE_NUM(IL_IDX(end_il_idx)), 01671 861, 01672 Internal, 01673 IR_COL_NUM(IL_IDX(end_il_idx)), 01674 "section_semantics"); 01675 } 01676 } 01677 else { 01678 PRINTMSG(IR_LINE_NUM(IL_IDX(end_il_idx)), 01679 704, 01680 Internal, 01681 IR_COL_NUM(IL_IDX(end_il_idx))); 01682 } 01683 01684 loop_tbl[lt_idx].end_value = CN_INT_TO_C(IL_IDX(end_il_idx)); 01685 01686 01687 /* Capture the stride value. */ 01688 01689 stride_il_idx = IL_NEXT_LIST_IDX(end_il_idx); 01690 01691 if (IL_FLD(stride_il_idx) == CN_Tbl_Idx) { 01692 /* Nuttin' to do. */ 01693 } 01694 else if (IL_FLD(stride_il_idx) == IR_Tbl_Idx) { 01695 COPY_OPND(expr_opnd, IL_OPND(stride_il_idx)); 01696 01697 if (fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) { 01698 COPY_OPND(IL_OPND(stride_il_idx), expr_opnd); 01699 } 01700 else { 01701 PRINTMSG(IR_LINE_NUM(IL_IDX(stride_il_idx)), 01702 861, 01703 Internal, 01704 IR_COL_NUM(IL_IDX(stride_il_idx)), 01705 "section_semantics"); 01706 } 01707 } 01708 else { 01709 PRINTMSG(IR_LINE_NUM(IL_IDX(stride_il_idx)), 01710 704, 01711 Internal, 01712 IR_COL_NUM(IL_IDX(stride_il_idx))); 01713 } 01714 01715 loop_tbl[lt_idx].inc_value = CN_INT_TO_C(IL_IDX(stride_il_idx)); 01716 01717 01718 /* Check on the values of the start, end, and stride values. */ 01719 01720 if (loop_tbl[lt_idx].inc_value > 0) { 01721 01722 if (loop_tbl[lt_idx].start_value < dcl_lb) { 01723 01724 /* The start value of the section subscript triplet is less */ 01725 /* than the declared lower bound. */ 01726 01727 PRINTMSG(IL_LINE_NUM(start_il_idx), 01728 841, 01729 Error, 01730 IL_COL_NUM(start_il_idx)); 01731 error_found = TRUE; 01732 } 01733 01734 if (loop_tbl[lt_idx].start_value > dcl_ub) { 01735 01736 /* The start value of the section subscript triplet is greater */ 01737 /* than the declared upper bound. */ 01738 01739 PRINTMSG(IL_LINE_NUM(start_il_idx), 01740 849, 01741 Error, 01742 IL_COL_NUM(start_il_idx)); 01743 error_found = TRUE; 01744 } 01745 01746 num_iterations = 01747 (loop_tbl[lt_idx].end_value - loop_tbl[lt_idx].start_value + 01748 loop_tbl[lt_idx].inc_value) / 01749 loop_tbl[lt_idx].inc_value; 01750 01751 if (num_iterations > 0) { 01752 obj_count *= num_iterations; 01753 01754 if ((loop_tbl[lt_idx].start_value + 01755 (num_iterations - 1)*loop_tbl[lt_idx].inc_value) > dcl_ub) { 01756 01757 /* The section subscript triplet produces a subscript value */ 01758 /* greater than the declared upper bound. */ 01759 01760 PRINTMSG(IL_LINE_NUM(start_il_idx), 01761 905, 01762 Error, 01763 IL_COL_NUM(start_il_idx)); 01764 error_found = TRUE; 01765 } 01766 } 01767 else { 01768 obj_count = 0; 01769 } 01770 } 01771 else if (loop_tbl[lt_idx].inc_value < 0) { 01772 01773 if (loop_tbl[lt_idx].start_value > dcl_ub) { 01774 01775 /* The start value of the section subscript triplet is greater */ 01776 /* than the declared upper bound. */ 01777 01778 PRINTMSG(IL_LINE_NUM(start_il_idx), 01779 849, 01780 Error, 01781 IL_COL_NUM(start_il_idx)); 01782 error_found = TRUE; 01783 } 01784 01785 if (loop_tbl[lt_idx].start_value < dcl_lb) { 01786 01787 /* The start value of the section subscript triplet is less */ 01788 /* than the declared lower bound. */ 01789 01790 PRINTMSG(IL_LINE_NUM(start_il_idx), 01791 841, 01792 Error, 01793 IL_COL_NUM(start_il_idx)); 01794 error_found = TRUE; 01795 } 01796 01797 num_iterations = 01798 (loop_tbl[lt_idx].end_value - loop_tbl[lt_idx].start_value + 01799 loop_tbl[lt_idx].inc_value) / 01800 loop_tbl[lt_idx].inc_value; 01801 01802 if (num_iterations > 0) { 01803 obj_count *= num_iterations; 01804 01805 if ((loop_tbl[lt_idx].start_value + 01806 (num_iterations - 1)*loop_tbl[lt_idx].inc_value) < dcl_lb) { 01807 01808 /* The section subscript triplet produces an end value less */ 01809 /* than the declared lower bound. */ 01810 01811 PRINTMSG(IL_LINE_NUM(start_il_idx), 01812 997, 01813 Error, 01814 IL_COL_NUM(start_il_idx)); 01815 error_found = TRUE; 01816 } 01817 } 01818 else { 01819 obj_count = 0; 01820 } 01821 } 01822 else { 01823 01824 /* The stride value of the section subscript must be nonzero. */ 01825 01826 PRINTMSG(IL_LINE_NUM(stride_il_idx), 01827 998, 01828 Error, 01829 IL_COL_NUM(stride_il_idx)); 01830 error_found = TRUE; 01831 } 01832 01833 if (! error_found) { 01834 01835 /* Save information about the first triplet subscript because this*/ 01836 /* is the only one we can use as a "loop" (the CRI back-end only */ 01837 /* accepts a single stride value). */ 01838 /* Note: OPND_FLD is set to NO_Tbl_Idx to indicate that the */ 01839 /* stride was calculated by section processing. See the code in */ 01840 /* data_stmt_semantics that generates the stride IL. */ 01841 01842 if (*first_triplet_idx == NULL_IDX) { 01843 *first_triplet_idx = lt_idx; 01844 COPY_OPND(*stride_opnd, IL_OPND(stride_il_idx)); 01845 OPND_FLD((*stride_opnd)) = NO_Tbl_Idx; 01846 01847 if (lt_idx != 1) { 01848 actual_stride = CN_INT_TO_C(IL_IDX(stride_il_idx)); 01849 bd_idx = ATD_ARRAY_IDX(IR_IDX_L(section_sub_ir_idx)); 01850 01851 for (i = 1; i < lt_idx; ++i) { 01852 actual_stride *= CN_INT_TO_C(BD_XT_IDX(bd_idx, i)); 01853 } 01854 01855 OPND_IDX((*stride_opnd)) =C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 01856 actual_stride); 01857 } 01858 } 01859 else { 01860 loop_tbl[last_triplet_idx].sibling_idx = lt_idx; 01861 } 01862 01863 last_triplet_idx = lt_idx; 01864 } 01865 } 01866 01867 il_idx = IL_NEXT_LIST_IDX(il_idx); 01868 01869 } /* for loop */ 01870 01871 TRACE(Func_Exit, "section_semantics", NULL); 01872 01873 return; 01874 01875 } /* section_semantics */ 01876 01877 01878 /******************************************************************************\ 01879 |* *| 01880 |* Description: *| 01881 |* This procedure generates the Subscript IR to represent where *| 01882 |* initialization is to begin for a piece of an array section. *| 01883 |* *| 01884 |* Input parameters: *| 01885 |* section_sub_ir_idx : The index to the original Section_Subscript IR *| 01886 |* that represents the section reference as seen in *| 01887 |* the user program. *| 01888 |* value_count : The number of values available to be used to *| 01889 |* initialize the section (or portion of it). *| 01890 |* first_triplet_idx : The index into the loop_tbl of the first section *| 01891 |* subscript. *| 01892 |* root_ir_idx : NULL_IDX if the Section_Subscript IR is the root *| 01893 |* IR; otherwise, index of the root IR. *| 01894 |* init_ir_idx : Index of the Init IR. *| 01895 |* *| 01896 |* Output parameters: *| 01897 |* dup_count : The number of elements that can be initialized *| 01898 |* on this pass through the section. The maximum *| 01899 |* number is the extent of the first section *| 01900 |* subscript. *| 01901 |* section_start_value : If the target needs to be blank padded, an *| 01902 |* implied-DO is needed. This value is needed as *| 01903 |* the implied-DO start value. *| 01904 |* section_inc_value : If the target needs to be blank padded, an *| 01905 |* implied-DO is needed. This value is needed as *| 01906 |* the implied-DO inc value. *| 01907 |* *| 01908 |* Returns: *| 01909 |* NONE *| 01910 |* *| 01911 \******************************************************************************/ 01912 01913 static void gen_section_ref(int section_sub_ir_idx, 01914 long64 value_count, 01915 int first_triplet_idx, 01916 int root_ir_idx, 01917 int init_ir_idx, 01918 long64 *dup_count, 01919 long64 *section_start_value, 01920 long64 *section_inc_value) 01921 01922 { 01923 int i; 01924 int il_idx; 01925 int last_il_idx; 01926 long64 local_obj_count; 01927 int ir_idx; 01928 opnd_type opnd; 01929 01930 01931 TRACE(Func_Entry, "gen_section_ref", NULL); 01932 01933 /* Make a copy of the reference IR tree. Locate the Section_Subscript IR */ 01934 /* and change it to a Subscript IR. Use one of the ILs attached to the */ 01935 /* Triplet IR to indicate the element at which the initialization is to */ 01936 /* begin. */ 01937 01938 gen_opnd(&opnd, root_ir_idx, IR_Tbl_Idx, stmt_start_line, stmt_start_col); 01939 copy_subtree(&opnd, &opnd); 01940 ir_idx = OPND_IDX(opnd); 01941 IR_FLD_L(init_ir_idx) = IR_Tbl_Idx; 01942 IR_IDX_L(init_ir_idx) = ir_idx; 01943 01944 while (IR_OPR(ir_idx) != Section_Subscript_Opr) { 01945 ir_idx = IR_IDX_L(ir_idx); 01946 } 01947 01948 IR_OPR(ir_idx) = Subscript_Opr; 01949 IR_RANK(ir_idx) = 1; 01950 01951 NTR_IR_LIST_TBL(il_idx); 01952 IR_FLD_R(ir_idx) = IL_Tbl_Idx; 01953 IR_IDX_R(ir_idx) = il_idx; 01954 IL_FLD(il_idx) = CN_Tbl_Idx; 01955 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 01956 loop_tbl[1].curr_value); 01957 IL_LINE_NUM(il_idx) = stmt_start_line; 01958 IL_COL_NUM(il_idx) = stmt_start_col; 01959 01960 last_il_idx = il_idx; 01961 01962 for (i = 2; i <= IR_LIST_CNT_R(section_sub_ir_idx); ++i) { 01963 NTR_IR_LIST_TBL(il_idx); 01964 IL_NEXT_LIST_IDX(last_il_idx) = il_idx; 01965 IL_PREV_LIST_IDX(il_idx) = last_il_idx; 01966 last_il_idx = il_idx; 01967 IL_FLD(il_idx) = CN_Tbl_Idx; 01968 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 01969 loop_tbl[i].curr_value); 01970 IL_LINE_NUM(il_idx) = stmt_start_line; 01971 IL_COL_NUM(il_idx) = stmt_start_col; 01972 } 01973 01974 /* Before loop_tbl[first_triplet_idx].curr_value gets updated, capture it */ 01975 /* to pass it out. It will be needed if the target needs to be blank */ 01976 /* padded. */ 01977 01978 *section_start_value = loop_tbl[first_triplet_idx].curr_value; 01979 *section_inc_value = loop_tbl[first_triplet_idx].inc_value; 01980 01981 /* Calculate the number of elements to be initialized. The maximum that */ 01982 /* can be initialized at one time is the extent of the first section */ 01983 /* subscript. */ 01984 01985 local_obj_count = (loop_tbl[first_triplet_idx].end_value - 01986 loop_tbl[first_triplet_idx].curr_value + 01987 loop_tbl[first_triplet_idx].inc_value) / 01988 loop_tbl[first_triplet_idx].inc_value; 01989 01990 /* If the number of values available exceeds the number of elements */ 01991 /* available, it means we'll use up all (remaining) elements of the first */ 01992 /* triplet so we need to reset the triplet to its start value and increment*/ 01993 /* triplets to the right as necessary. */ 01994 /* If the number of elements exceeds the number of values, just increment */ 01995 /* the leftmost triplet so it's ready on the next pass through this */ 01996 /* procedure. */ 01997 01998 if (local_obj_count <= value_count) { 01999 *dup_count = local_obj_count; 02000 02001 if (obj_count != local_obj_count) { 02002 loop_tbl[first_triplet_idx].curr_value = 02003 loop_tbl[first_triplet_idx].start_value; 02004 lt_idx = loop_tbl[first_triplet_idx].sibling_idx; 02005 02006 while (lt_idx != NULL_IDX) { 02007 loop_tbl[lt_idx].curr_value += loop_tbl[lt_idx].inc_value; 02008 02009 if ((loop_tbl[lt_idx].inc_value > 0 && 02010 loop_tbl[lt_idx].curr_value <= loop_tbl[lt_idx].end_value) || 02011 (loop_tbl[lt_idx].inc_value < 0 && 02012 loop_tbl[lt_idx].curr_value >= loop_tbl[lt_idx].end_value)) { 02013 break; 02014 } 02015 02016 loop_tbl[lt_idx].curr_value = loop_tbl[lt_idx].start_value; 02017 lt_idx = loop_tbl[lt_idx].sibling_idx; 02018 } 02019 02020 } 02021 } 02022 else { 02023 *dup_count = value_count; 02024 loop_tbl[first_triplet_idx].curr_value += 02025 value_count * loop_tbl[first_triplet_idx].inc_value; 02026 } 02027 02028 TRACE(Func_Exit, "gen_section_ref", NULL); 02029 02030 return; 02031 02032 } /* gen_section_ref */ 02033 02034 02035 /******************************************************************************\ 02036 |* *| 02037 |* Description: *| 02038 |* This procedure generates implied-DOs to represent a section *| 02039 |* initialization when at least one subscript is a vector valued *| 02040 |* subscript. *| 02041 |* *| 02042 |* Input parameters: *| 02043 |* init_ir_idx : index of the Init IR *| 02044 |* array_ir_idx : index of the Section_Subscript IR *| 02045 |* obj_desc : expression descriptor for the target *| 02046 |* *| 02047 |* Output parameters: *| 02048 |* NONE *| 02049 |* *| 02050 |* Returns: *| 02051 |* NONE *| 02052 |* *| 02053 \******************************************************************************/ 02054 02055 static void vv_subscript_semantics(int init_ir_idx, 02056 int array_ir_idx, 02057 expr_arg_type *obj_desc) 02058 { 02059 int do_var_il_idx; 02060 int end_il_idx; 02061 int i; 02062 int il_idx; 02063 int imp_do_ir_idx; 02064 int inc_il_idx; 02065 expr_arg_type shape_desc; 02066 int shape_idx; 02067 opnd_type shape_opnd; 02068 int start_il_idx; 02069 int subscript_il_idx; 02070 int tmp_idx; 02071 int triplet_ir_idx; 02072 02073 02074 TRACE (Func_Entry, "vv_subscript_semantics", NULL); 02075 02076 /* Loop through the subscripts of the Section_Subscript IR to find out */ 02077 /* which ones represent vector valued subscripts and which ones represent */ 02078 /* triplet subscripts or constants (if any). */ 02079 02080 shape_idx = -1; 02081 subscript_il_idx = IR_IDX_R(array_ir_idx); 02082 02083 for (i = 1; i <= IR_LIST_CNT_R(array_ir_idx); ++i) { 02084 02085 switch (IL_FLD(subscript_il_idx)) { 02086 02087 case CN_Tbl_Idx: 02088 break; 02089 02090 case IR_Tbl_Idx: 02091 02092 /* Since the subscript is represented by IR, it must be a vector */ 02093 /* valued subscript (possibly an expression like (V + 1) where V */ 02094 /* is a vector), or it must be a Triplet IR. */ 02095 /* */ 02096 /* Generate an Implied_Do IR and its left operand IL. As we move */ 02097 /* "left" to "right" through the subscript list, we are building */ 02098 /* up inner to outer loops so the Implied_Do IR is always */ 02099 /* attached to the left operand of the Init IR. Whatever was */ 02100 /* formerly attached to the left operand of the Init IR then */ 02101 /* becomes the object of the new implied-DO. */ 02102 02103 ++shape_idx; 02104 02105 NTR_IR_TBL(imp_do_ir_idx); 02106 IR_OPR(imp_do_ir_idx) = Implied_Do_Opr; 02107 IR_TYPE_IDX(imp_do_ir_idx) = TYPELESS_DEFAULT_TYPE; 02108 IR_LINE_NUM(imp_do_ir_idx) = IR_LINE_NUM(init_ir_idx); 02109 IR_COL_NUM(imp_do_ir_idx) = IR_COL_NUM(init_ir_idx); 02110 02111 NTR_IR_LIST_TBL(il_idx); 02112 IR_LIST_CNT_L(imp_do_ir_idx) = 1; 02113 IR_FLD_L(imp_do_ir_idx) = IL_Tbl_Idx; 02114 IR_IDX_L(imp_do_ir_idx) = il_idx; 02115 02116 COPY_OPND(IL_OPND(il_idx), IR_OPND_L(init_ir_idx)); 02117 02118 IR_IDX_L(init_ir_idx) = imp_do_ir_idx; 02119 02120 /* If this is a Triplet IR, save its index. Its index will be */ 02121 /* used later to get at the ILs attached to it. */ 02122 02123 if (IR_OPR(IL_IDX(subscript_il_idx)) == Triplet_Opr) { 02124 triplet_ir_idx = IL_IDX(subscript_il_idx); 02125 } 02126 02127 /* Generate an integer temp to serve as the DO variable of the */ 02128 /* implied-DO. Generate the IL for the DO variable (the temp) */ 02129 /* and attach the IL to the right operand of the Implied_Do IR. */ 02130 /* If the subscript is a vector valued subscript, go into the */ 02131 /* expression descriptor and generate the implied-DO's start, */ 02132 /* end, and inc values from the shape of the current subscript */ 02133 /* (start and inc are always 1). If the subscript is a triplet, */ 02134 /* let the start, end, and inc values be the values that were */ 02135 /* attached to the Triplet IR. */ 02136 02137 tmp_idx = gen_compiler_tmp(IR_LINE_NUM(imp_do_ir_idx), 02138 IR_COL_NUM(imp_do_ir_idx), 02139 Priv, TRUE); 02140 AT_SEMANTICS_DONE(tmp_idx) = TRUE; 02141 ATD_TYPE_IDX(tmp_idx) = INTEGER_DEFAULT_TYPE; 02142 ATD_STOR_BLK_IDX(tmp_idx) = SCP_SB_STACK_IDX(curr_scp_idx); 02143 ATD_LCV_IS_CONST(tmp_idx) = TRUE; 02144 02145 /* clear the referenced field so that this tmp does */ 02146 /* not get sent to mif. BHJ */ 02147 02148 AT_REFERENCED(tmp_idx) = Not_Referenced; 02149 02150 NTR_IR_LIST_TBL(do_var_il_idx); 02151 IL_LINE_NUM(do_var_il_idx) = IR_LINE_NUM(imp_do_ir_idx); 02152 IL_COL_NUM(do_var_il_idx) = IR_COL_NUM(imp_do_ir_idx); 02153 IL_FLD(do_var_il_idx) = AT_Tbl_Idx; 02154 IL_IDX(do_var_il_idx) = tmp_idx; 02155 02156 if (IL_VECTOR_SUBSCRIPT(subscript_il_idx)) { 02157 NTR_IR_LIST_TBL(start_il_idx); 02158 IL_NEXT_LIST_IDX(do_var_il_idx) = start_il_idx; 02159 IL_PREV_LIST_IDX(start_il_idx) = do_var_il_idx; 02160 IL_LINE_NUM(start_il_idx) = IR_LINE_NUM(init_ir_idx); 02161 IL_COL_NUM(start_il_idx) = IR_COL_NUM(init_ir_idx); 02162 IL_FLD(start_il_idx) = CN_Tbl_Idx; 02163 IL_IDX(start_il_idx) = CN_INTEGER_ONE_IDX; 02164 02165 NTR_IR_LIST_TBL(end_il_idx); 02166 IL_NEXT_LIST_IDX(start_il_idx) = end_il_idx; 02167 IL_PREV_LIST_IDX(end_il_idx) = start_il_idx; 02168 02169 if (obj_desc->shape[shape_idx].fld != CN_Tbl_Idx) { 02170 COPY_OPND(shape_opnd, obj_desc->shape[shape_idx]); 02171 02172 shape_desc = init_exp_desc; 02173 shape_desc.type = Integer; 02174 shape_desc.type_idx = INTEGER_DEFAULT_TYPE; 02175 shape_desc.linear_type = INTEGER_DEFAULT_TYPE; 02176 02177 if (fold_aggragate_expression(&shape_opnd, 02178 &shape_desc, 02179 TRUE)) { 02180 COPY_OPND(IL_OPND(end_il_idx), shape_opnd); 02181 } 02182 else { 02183 PRINTMSG(obj_desc->shape[shape_idx].line_num, 02184 861, 02185 Internal, 02186 obj_desc->shape[shape_idx].col_num, 02187 "vv_subscript_semantics"); 02188 } 02189 } 02190 else { 02191 IL_LINE_NUM(end_il_idx) = IR_LINE_NUM(init_ir_idx); 02192 IL_COL_NUM(end_il_idx) = IR_COL_NUM(init_ir_idx); 02193 IL_FLD(end_il_idx) = CN_Tbl_Idx; 02194 IL_IDX(end_il_idx) = obj_desc->shape[shape_idx].idx; 02195 } 02196 02197 NTR_IR_LIST_TBL(inc_il_idx); 02198 IL_NEXT_LIST_IDX(end_il_idx) = inc_il_idx; 02199 IL_PREV_LIST_IDX(inc_il_idx) = end_il_idx; 02200 IL_LINE_NUM(inc_il_idx) = IR_LINE_NUM(init_ir_idx); 02201 IL_COL_NUM(inc_il_idx) = IR_COL_NUM(init_ir_idx); 02202 IL_FLD(inc_il_idx) = CN_Tbl_Idx; 02203 IL_IDX(inc_il_idx) = CN_INTEGER_ONE_IDX; 02204 02205 /* Generate a special 5th IL to point at the vector valued */ 02206 /* subscript tree so that the PDGCS interface can get each */ 02207 /* value in the vector. */ 02208 02209 NTR_IR_LIST_TBL(il_idx); 02210 IL_NEXT_LIST_IDX(inc_il_idx) = il_idx; 02211 IL_PREV_LIST_IDX(il_idx) = inc_il_idx; 02212 COPY_OPND(IL_OPND(il_idx), IL_OPND(subscript_il_idx)); 02213 02214 IR_LIST_CNT_R(imp_do_ir_idx) = 5; 02215 } 02216 else { 02217 IL_NEXT_LIST_IDX(do_var_il_idx) = IR_IDX_L(triplet_ir_idx); 02218 IR_LIST_CNT_R(imp_do_ir_idx) = 4; 02219 } 02220 02221 IR_FLD_R(imp_do_ir_idx) = IL_Tbl_Idx; 02222 IR_IDX_R(imp_do_ir_idx) = do_var_il_idx; 02223 02224 IL_FLD(subscript_il_idx) = AT_Tbl_Idx; 02225 IL_IDX(subscript_il_idx) = tmp_idx; 02226 IL_LINE_NUM(subscript_il_idx) = IR_LINE_NUM(init_ir_idx); 02227 IL_COL_NUM(subscript_il_idx) = IR_COL_NUM(init_ir_idx); 02228 02229 break; 02230 02231 default: 02232 PRINTMSG(IR_LINE_NUM(init_ir_idx), 179, Internal, 02233 IR_COL_NUM(init_ir_idx), "vv_section_semantics"); 02234 } 02235 02236 subscript_il_idx = IL_NEXT_LIST_IDX(subscript_il_idx); 02237 } 02238 02239 TRACE (Func_Exit, "vv_subscript_semantics", NULL); 02240 02241 return; 02242 02243 } /* vv_subscript_semantics */ 02244 02245 02246 /******************************************************************************\ 02247 |* *| 02248 |* Description: *| 02249 |* This procedure handles the optimized initialization of a whole *| 02250 |* array, as in: *| 02251 |* *| 02252 |* INTEGER array(500) *| 02253 |* DATA array / <500 individual values> / *| 02254 |* *| 02255 |* It does this by overlaying a single dimension compiler-generated *| 02256 |* array variable on the base array. If the base array is a single *| 02257 |* dimension array, no overlay is made. *| 02258 |* *| 02259 |* Input parameters: *| 02260 |* init_ir_idx : index of the Init IR *| 02261 |* *| 02262 |* Output parameters: *| 02263 |* optimized : a flag passed back to the caller indicating *| 02264 |* whether or not we were able to transform the *| 02265 |* initialization *| 02266 |* Returns: *| 02267 |* NONE *| 02268 |* *| 02269 \******************************************************************************/ 02270 02271 static boolean optimize_whole_array_init(int init_ir_idx) 02272 { 02273 int attr_idx; 02274 int i; 02275 opnd_type ignore_this_opnd; 02276 int ir_idx; 02277 expr_arg_type loc_exp_desc; 02278 opnd_type opnd; 02279 boolean optimized = TRUE; 02280 opnd_type rep_factor_opnd; 02281 boolean save_insert_subs_ok; 02282 opnd_type save_left_opnd; 02283 long64 save_rep_factor; 02284 opnd_type save_right_opnd; 02285 expr_arg_type save_value_desc; 02286 int save_value_il_idx; 02287 opnd_type save_value_opnd; 02288 02289 02290 TRACE(Func_Entry, "optimize_whole_array_init", NULL); 02291 02292 if (value_il_idx == NULL_IDX) { 02293 optimized = FALSE; 02294 goto EXIT; 02295 } 02296 02297 COPY_OPND(save_left_opnd, IR_OPND_L(init_ir_idx)); 02298 COPY_OPND(save_right_opnd, IR_OPND_R(init_ir_idx)); 02299 COPY_OPND(save_value_opnd, value_opnd); 02300 save_value_il_idx = value_il_idx; 02301 save_value_desc = value_desc; 02302 save_rep_factor = rep_factor; 02303 02304 IR_LIST_CNT_R(init_ir_idx) = 0; 02305 02306 if (IR_FLD_R(init_ir_idx) == NO_Tbl_Idx) { 02307 IR_FLD_R(init_ir_idx) = IL_Tbl_Idx; 02308 IR_IDX_R(init_ir_idx) = value_il_idx; 02309 } 02310 02311 COPY_OPND(opnd, IR_OPND_L(init_ir_idx)); 02312 02313 while (OPND_FLD(opnd) == IR_Tbl_Idx) { 02314 02315 if (IR_OPR(OPND_IDX(opnd)) == Substring_Opr || 02316 IR_OPR(OPND_IDX(opnd)) == Whole_Substring_Opr) { 02317 break; 02318 } 02319 02320 COPY_OPND(opnd, IR_OPND_L(OPND_IDX(opnd))); 02321 } 02322 02323 attr_idx = IR_IDX_L(IR_IDX_L(init_ir_idx)); 02324 02325 for (i = 1; i <= obj_count; ++i) { 02326 02327 /* Someday we have to duplicate some of the main line DATA code to eat */ 02328 /* up as values as we need and leave the Rep_Count IR in shape for the */ 02329 /* next target if there are any values left in it. */ 02330 /* For now, if we see an IR index, we assume it's a Rep_Count IR, we */ 02331 /* restore everything to what it was when we came in, and we give up. */ 02332 if (IL_FLD(value_il_idx) == IR_Tbl_Idx) { 02333 optimized = FALSE; 02334 COPY_OPND(IR_OPND_L(init_ir_idx), save_left_opnd); 02335 COPY_OPND(IR_OPND_R(init_ir_idx), save_right_opnd); 02336 COPY_OPND(value_opnd, save_value_opnd); 02337 value_il_idx = save_value_il_idx; 02338 value_desc = save_value_desc; 02339 rep_factor = save_rep_factor; 02340 goto EXIT; 02341 } 02342 02343 if (check_target_and_value(attr_idx, init_ir_idx)) { 02344 --rep_factor; 02345 02346 if (rep_factor == 0) { 02347 ++IR_LIST_CNT_R(init_ir_idx); 02348 value_il_idx = IL_NEXT_LIST_IDX(value_il_idx); 02349 02350 if (value_il_idx == NULL_IDX) { 02351 break; 02352 } 02353 else { 02354 set_global_value_variables(&rep_factor_opnd, 02355 &ignore_this_opnd, 02356 attr_idx); 02357 02358 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 02359 goto EXIT; 02360 } 02361 } 02362 } 02363 } 02364 else { 02365 goto EXIT; 02366 } 02367 } 02368 02369 if (value_il_idx != NULL_IDX) { 02370 IL_NEXT_LIST_IDX(IL_PREV_LIST_IDX(value_il_idx)) = NULL_IDX; 02371 IL_PREV_LIST_IDX(value_il_idx) = NULL_IDX; 02372 } 02373 02374 02375 /* CF77 (and thus our little compiler) has an outmoded feature that allows */ 02376 /* the number of values in the constant list to be less than the number of */ 02377 /* target elements as long as the target array is the last item in the */ 02378 /* DATA target list. */ 02379 02380 if (IR_LIST_CNT_R(init_ir_idx) < obj_count) { 02381 02382 if (IL_NEXT_LIST_IDX(obj_il_idx) == NULL_IDX) { 02383 PRINTMSG(IR_LINE_NUM_L(init_ir_idx), 698, Ansi, 02384 IR_COL_NUM_L(init_ir_idx)); 02385 } 02386 else { 02387 PRINTMSG(IR_LINE_NUM_L(init_ir_idx), 667, Error, 02388 IR_COL_NUM_L(init_ir_idx)); 02389 optimized = FALSE; 02390 obj_il_idx = NULL_IDX; 02391 goto EXIT; 02392 } 02393 } 02394 02395 02396 /* Convert the value list to an array constructor. */ 02397 /* target_array_idx, target_type_idx, and insert_subs_ok are global */ 02398 /* variables used by array constructor code. */ 02399 02400 OPND_FLD(init_target_opnd) = AT_Tbl_Idx; 02401 OPND_IDX(init_target_opnd) = attr_idx; 02402 OPND_LINE_NUM(init_target_opnd) = stmt_start_line; 02403 OPND_COL_NUM(init_target_opnd) = stmt_start_col; 02404 02405 target_array_idx = ATD_ARRAY_IDX(attr_idx); 02406 target_type_idx = ATD_TYPE_IDX(attr_idx); 02407 check_type_conversion = TRUE; 02408 save_insert_subs_ok = insert_subs_ok; 02409 insert_subs_ok = FALSE; 02410 02411 NTR_IR_TBL(ir_idx); 02412 IR_OPR(ir_idx) = Constant_Array_Construct_Opr; 02413 IR_LINE_NUM(ir_idx) = stmt_start_line; 02414 IR_COL_NUM(ir_idx) = stmt_start_col; 02415 IR_TYPE_IDX(ir_idx) = target_type_idx; 02416 02417 COPY_OPND(IR_OPND_R(ir_idx), IR_OPND_R(init_ir_idx)); 02418 02419 OPND_IDX(opnd) = ir_idx; 02420 OPND_FLD(opnd) = IR_Tbl_Idx; 02421 02422 loc_exp_desc = init_exp_desc; 02423 loc_exp_desc.type_idx = target_type_idx; 02424 loc_exp_desc.type = TYP_TYPE(target_type_idx); 02425 loc_exp_desc.linear_type = TYP_LINEAR(target_type_idx); 02426 loc_exp_desc.rank = 1; 02427 02428 if (IR_LIST_CNT_R(init_ir_idx) == obj_count) { 02429 loc_exp_desc.shape[0].fld = BD_XT_FLD(target_array_idx, 1); 02430 loc_exp_desc.shape[0].idx = BD_XT_IDX(target_array_idx, 1); 02431 } 02432 else { 02433 loc_exp_desc.shape[0].fld = CN_Tbl_Idx; 02434 loc_exp_desc.shape[0].idx = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 02435 IR_LIST_CNT_R(init_ir_idx)); 02436 } 02437 02438 loc_exp_desc.constructor_size_level = Simple_Expr_Size; 02439 02440 create_constructor_constant(&opnd, &loc_exp_desc); 02441 02442 init_target_opnd = null_opnd; 02443 target_array_idx = NULL_IDX; 02444 insert_subs_ok = save_insert_subs_ok; 02445 02446 remove_sh(curr_stmt_sh_idx); 02447 curr_stmt_sh_idx = SH_PREV_IDX(curr_stmt_sh_idx); 02448 02449 obj_count = 0; 02450 02451 EXIT: 02452 02453 TRACE(Func_Exit, "optimize_whole_array_init", NULL); 02454 02455 return(optimized); 02456 02457 } /* optimize_whole_array_init */ 02458 02459 02460 /******************************************************************************\ 02461 |* *| 02462 |* Description: *| 02463 |* This procedure drives the processing of a DATA implied-DO and nested *| 02464 |* loops, if any exist. *| 02465 |* *| 02466 |* Input parameters: *| 02467 |* init_ir_idx : the index of the current Init IR *| 02468 |* imp_do_idx : the index of the current Implied_Do IR *| 02469 |* compiler_gen_imp_do : TRUE if the compiler produced this implied-DO *| 02470 |* *| 02471 |* Output parameters: *| 02472 |* metamorphed : TRUE if the implied-DO underwent metamorphosis into a *| 02473 |* whole array or array section initialization. *| 02474 |* *| 02475 |* Returns: *| 02476 |* NONE *| 02477 |* *| 02478 \******************************************************************************/ 02479 02480 static void data_imp_do_semantics(int init_ir_idx, 02481 int imp_do_idx, 02482 boolean compiler_gen_imp_do, 02483 boolean *metamorphed) 02484 02485 { 02486 int il_idx; 02487 int local_rep_count_ir_idx; 02488 long64 local_rep_factor; 02489 int local_value_il_idx; 02490 int rep_count_ir_idx; 02491 boolean save_runtime_bounds; 02492 02493 02494 TRACE (Func_Entry, "data_imp_do_semantics", NULL); 02495 save_runtime_bounds = cdir_switches.bounds; 02496 cdir_switches.bounds = TRUE; 02497 02498 *metamorphed = FALSE; 02499 02500 02501 /* The expression descriptor for each implied-DO expression must be saved */ 02502 /* if the expression is truly an expression (involving IR). There is a */ 02503 /* dynamic table where copies of the expression descriptors can be saved. */ 02504 /* The table is reset to "empty" after each statement. Capture its base */ 02505 /* now. Entries will be added to it by build_loop_tbl. */ 02506 02507 arg_info_list_base = arg_info_list_top; 02508 02509 02510 /* Build the loop_tbl entry for this loop level. */ 02511 02512 last_lt_idx = NULL_IDX; 02513 curr_parent_idx = NULL_IDX; 02514 02515 build_loop_tbl(imp_do_idx, compiler_gen_imp_do); 02516 02517 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 02518 goto EXIT; 02519 } 02520 02521 02522 /* See if the implied-DO can be metamorphed into a much more efficient */ 02523 /* whole array or array section initialization (it must be the only or */ 02524 /* last item in the original DATA statement; see imp_do_metamorphed for */ 02525 /* further explanation). */ 02526 02527 if (IL_NEXT_LIST_IDX(obj_il_idx) == NULL_IDX) { 02528 02529 if (imp_do_metamorphed(init_ir_idx)) { 02530 *metamorphed = TRUE; 02531 goto EXIT; 02532 } 02533 } 02534 02535 02536 /* First, if the current value is a rep-factor/value pair and a */ 02537 /* previous target has used some of the values, make sure that the current */ 02538 /* value of *rep_factor is represented by the Rep_Count IR because the */ 02539 /* implied-DO could use the Rep_Count IR directly. */ 02540 02541 if (IL_FLD(value_il_idx) == IR_Tbl_Idx && 02542 rep_factor != CN_INT_TO_C(IR_IDX_L(IL_IDX(value_il_idx)))) { 02543 02544 IR_IDX_L(IL_IDX(value_il_idx)) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 02545 rep_factor); 02546 } 02547 02548 /* Now match the targets against the values. If the implied-DO is part of */ 02549 /* a DATA statement that contains other targets, split out the values that */ 02550 /* will be assigned to the implied-DO target(s). */ 02551 /* The rep factor and value for the first value have already been */ 02552 /* processed by data_stmt_semantics so they are ready for use. */ 02553 02554 IR_LIST_CNT_R(init_ir_idx) = 1; 02555 IR_FLD_R(init_ir_idx) = IL_Tbl_Idx; 02556 IR_IDX_R(init_ir_idx) = value_il_idx; 02557 02558 lt_idx = 1; 02559 02560 interpret_data_imp_do(init_ir_idx); 02561 02562 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 02563 goto EXIT; 02564 } 02565 02566 if (rep_factor == 0) { 02567 02568 /* BHJ, LRR what is this ? */ 02569 02570 if (value_il_idx != NULL_IDX) { 02571 IL_NEXT_LIST_IDX(IL_PREV_LIST_IDX(value_il_idx)) = NULL_IDX; 02572 } 02573 } 02574 else if (IL_FLD(value_il_idx) == IR_Tbl_Idx) { 02575 02576 /* A single value has a rep_factor of 1. The above test is asking if */ 02577 /* there was originally a user-specified rep factor. */ 02578 /* Since the rep_factor has not been counted down to 0, there are some */ 02579 /* values left over. If the number of values used is greater than 1, */ 02580 /* make of copy of the original Rep_Count IR and attach it to the */ 02581 /* implied-DO's value chain to represent the number of values used. */ 02582 /* Otherwise, if the number of values used is 1, just copy the value */ 02583 /* from the original value IL. */ 02584 02585 rep_count_ir_idx = IL_IDX(value_il_idx); 02586 02587 local_rep_factor = CN_INT_TO_C(IR_IDX_L(rep_count_ir_idx)) - rep_factor; 02588 02589 local_value_il_idx = IL_PREV_LIST_IDX(value_il_idx); 02590 02591 NTR_IR_LIST_TBL(il_idx); 02592 02593 if (IR_LIST_CNT_R(init_ir_idx) == 1) { 02594 IR_IDX_R(init_ir_idx) = il_idx; 02595 } 02596 else { 02597 IL_NEXT_LIST_IDX(local_value_il_idx) = il_idx; 02598 IL_PREV_LIST_IDX(il_idx) = local_value_il_idx; 02599 } 02600 02601 local_value_il_idx = il_idx; 02602 02603 if (local_rep_factor > 1) { 02604 NTR_IR_TBL(local_rep_count_ir_idx); 02605 IR_TYPE_IDX(local_rep_count_ir_idx) = TYPELESS_DEFAULT_TYPE; 02606 IL_FLD(local_value_il_idx) = IR_Tbl_Idx; 02607 IL_IDX(local_value_il_idx) = local_rep_count_ir_idx; 02608 COPY_TBL_NTRY(ir_tbl, local_rep_count_ir_idx, rep_count_ir_idx); 02609 02610 IR_IDX_L(local_rep_count_ir_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 02611 local_rep_factor); 02612 COPY_OPND(IR_OPND_R(local_rep_count_ir_idx), value_opnd); 02613 } 02614 else { 02615 COPY_OPND(IL_OPND(local_value_il_idx), value_opnd); 02616 } 02617 02618 /* If rep_factor is now 1, make the original value IL point directly at */ 02619 /* the value (abandon the original Rep_Count IR). Otherwise, replace */ 02620 /* the left operand (rep factor) of the original Rep_Count IR with the */ 02621 /* new rep_factor value. */ 02622 02623 if (rep_factor == 1) { 02624 COPY_OPND(IL_OPND(value_il_idx), IR_OPND_R(rep_count_ir_idx)); 02625 } 02626 else { 02627 IR_IDX_L(rep_count_ir_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 02628 rep_factor); 02629 } 02630 } 02631 02632 EXIT: 02633 02634 cdir_switches.bounds = save_runtime_bounds; 02635 02636 TRACE (Func_Exit, "data_imp_do_semantics", NULL); 02637 02638 return; 02639 02640 } /* data_imp_do_semantics */ 02641 02642 02643 /******************************************************************************\ 02644 |* *| 02645 |* Description: *| 02646 |* This procedure fills in the loop_tbl that represents the implied-DO *| 02647 |* loops. *| 02648 |* *| 02649 |* Input parameters: *| 02650 |* imp_do_idx : the index of the current Implied_Do IR. *| 02651 |* compiler_gen_imp_do : TRUE if the compiler generated the implied-DO *| 02652 |* *| 02653 |* Output parameters: *| 02654 |* NONE *| 02655 |* *| 02656 |* Returns: *| 02657 |* NONE *| 02658 |* *| 02659 |* Algorithm note: *| 02660 |* This procedure is recursive. *| 02661 |* *| 02662 \******************************************************************************/ 02663 02664 static void build_loop_tbl(int imp_do_idx, 02665 boolean compiler_gen_imp_do) 02666 02667 { 02668 int attr_idx; 02669 int column; 02670 int do_var_tmp_idx; 02671 expr_arg_type expr_desc; 02672 int il_idx; 02673 int lcv_col; 02674 int lcv_line; 02675 int line; 02676 opnd_type opnd; 02677 boolean save_in_implied_do; 02678 boolean save_imp_do_lcv; 02679 int search_idx; 02680 boolean semantics_ok; 02681 int target_idx; 02682 int temp_ir_idx; 02683 02684 02685 TRACE (Func_Entry, "build_loop_tbl", NULL); 02686 02687 if (++last_lt_idx > LOOP_TBL_SIZE) { 02688 PRINTMSG(IR_LINE_NUM(imp_do_idx), 237, Internal, IR_COL_NUM(imp_do_idx), 02689 "DATA implied-DO loop_tbl"); 02690 } 02691 02692 lt_idx = last_lt_idx; 02693 02694 /* Initialize fields of the current table entry. If we're at the outermost*/ 02695 /* loop, indicate there is no parent. Otherwise, "link" the current */ 02696 /* table entry to its parent (and sibling, if it exists). */ 02697 /* NOTE: curr_value is used by this procedure to locate the last sibling */ 02698 /* in a sibling chain so we don't have to search to the end to */ 02699 /* attach a subsequent sibling. */ 02700 /* 02701 ------------------------------------------------------------------------- 02702 | lcv_idx | | target_list | num_ 8| 02703 | 24 | 8 | 24 | targets | 02704 |-----------------------------------------------------------------------| 02705 | start_idx | start_ | start_expr_desc_idx | parent_ | 02706 | 24 | fld 8 | | idx 8| 02707 |-----------------------------------------------------------------------| 02708 | end_idx | end_ | end_expr_desc_idx |sibling_ | 02709 | 24 | fld 8 | |idx 8| 02710 |-----------------------------------------------------------------------| 02711 | inc_idx | inc_ | inc_expr_desc_idx |offspring| 02712 | 24 | fld 8 | |_idx 8| 02713 |-----------------------------------------------------------------------| 02714 | start_value | 02715 |-----------------------------------------------------------------------| 02716 | end_value | 02717 |-----------------------------------------------------------------------| 02718 | inc_value | 02719 |-----------------------------------------------------------------------| 02720 | curr_value | 02721 ------------------------------------------------------------------------- 02722 02723 */ 02724 02725 loop_tbl[lt_idx].num_targets = 0; 02726 loop_tbl[lt_idx].sibling_idx = NULL_IDX; 02727 loop_tbl[lt_idx].offspring_idx = NULL_IDX; 02728 loop_tbl[lt_idx].target_list = NULL_IDX; 02729 loop_tbl[lt_idx].curr_value = NULL_IDX; 02730 02731 if (curr_parent_idx == NULL_IDX) { 02732 loop_tbl[lt_idx].parent_idx = NULL_IDX; 02733 } 02734 else { 02735 loop_tbl[lt_idx].parent_idx = curr_parent_idx; 02736 02737 if (loop_tbl[curr_parent_idx].offspring_idx == NULL_IDX) { 02738 loop_tbl[curr_parent_idx].offspring_idx = lt_idx; 02739 } 02740 else { 02741 loop_tbl[loop_tbl[curr_parent_idx].curr_value].sibling_idx = lt_idx; 02742 } 02743 02744 loop_tbl[curr_parent_idx].curr_value = lt_idx; 02745 } 02746 02747 attr_idx = NULL_IDX; 02748 02749 02750 /* Capture the start value. If it's a constant, get it's value. If it's */ 02751 /* an Attr index it should be a loop control variable of an outer loop. */ 02752 /* Search back through the parent table entries to find the loop control */ 02753 /* variable and get its current value. If it's an expression, point to */ 02754 /* the expression tree. */ 02755 /* Note: expr_sem is called rather than expr_semantics so that subobjects */ 02756 /* of named constants will not be folded. If the expression is a */ 02757 /* tree when it comes back from expr_sem, we need to check it to */ 02758 /* see if it contains any subobjects of named constants. */ 02759 02760 il_idx = IL_NEXT_LIST_IDX(IR_IDX_R(imp_do_idx)); 02761 02762 if (compiler_gen_imp_do) { 02763 loop_tbl[lt_idx].start_value = CN_INT_TO_C(IL_IDX(il_idx)); 02764 } 02765 else { 02766 COPY_OPND(opnd, IL_OPND(il_idx)); 02767 expr_mode = Restricted_Imp_Do_Expr; 02768 expr_desc.rank = 0; 02769 xref_state = CIF_Symbol_Reference; 02770 02771 if (! expr_sem(&opnd, &expr_desc)) { 02772 02773 /* It is possible for expr_sem to return a value of false without */ 02774 /* issuing an error message. */ 02775 02776 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 02777 goto EXIT; 02778 } 02779 02780 if (expr_desc.linear_type == Short_Typeless_Const) { 02781 OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd), 02782 INTEGER_DEFAULT_TYPE, 02783 OPND_LINE_NUM(opnd), 02784 OPND_COL_NUM(opnd)); 02785 expr_desc.type_idx = INTEGER_DEFAULT_TYPE; 02786 expr_desc.type = Integer; 02787 expr_desc.linear_type = INTEGER_DEFAULT_TYPE; 02788 } 02789 02790 02791 if (expr_desc.rank == 0 && 02792 expr_desc.type == Integer) { 02793 COPY_OPND(IL_OPND(il_idx), opnd); 02794 loop_tbl[lt_idx].start_fld = IL_FLD(il_idx); 02795 loop_tbl[lt_idx].start_idx = IL_IDX(il_idx); 02796 02797 switch (loop_tbl[lt_idx].start_fld) { 02798 02799 case CN_Tbl_Idx: 02800 loop_tbl[lt_idx].start_value = CN_INT_TO_C(IL_IDX(il_idx)); 02801 break; 02802 02803 case AT_Tbl_Idx: 02804 search_idx = loop_tbl[lt_idx].parent_idx; 02805 02806 while (search_idx != NULL_IDX) { 02807 02808 if (loop_tbl[search_idx].lcv_idx == IL_IDX(il_idx)) { 02809 loop_tbl[lt_idx].start_idx = search_idx; 02810 break; 02811 } 02812 else { 02813 search_idx = loop_tbl[search_idx].parent_idx; 02814 } 02815 02816 } 02817 02818 if (search_idx == NULL_IDX) { 02819 PRINTMSG(IL_LINE_NUM(il_idx), 658, Error, IL_COL_NUM(il_idx), 02820 AT_OBJ_NAME_PTR(IL_IDX(il_idx))); 02821 goto EXIT; 02822 } 02823 02824 break; 02825 02826 case IR_Tbl_Idx: 02827 if (good_data_imp_do_expr(loop_tbl[lt_idx].start_idx)) { 02828 arg_info_list_top = arg_info_list_base + 1; 02829 02830 loop_tbl[lt_idx].start_expr_desc_idx = arg_info_list_top; 02831 02832 if (arg_info_list_top > arg_info_list_size) { 02833 enlarge_info_list_table(); 02834 } 02835 02836 arg_info_list[arg_info_list_top] = init_arg_info; 02837 arg_info_list[arg_info_list_top].ed = expr_desc; 02838 } 02839 02840 break; 02841 02842 default: 02843 PRINTMSG(IR_LINE_NUM(imp_do_idx), 179, Internal, 02844 IR_COL_NUM(imp_do_idx), "build_loop_tbl"); 02845 } 02846 } 02847 else { 02848 PRINTMSG(IL_LINE_NUM(il_idx), 936, Error, IL_COL_NUM(il_idx)); 02849 } 02850 } 02851 02852 02853 /* Capture the end value. The processing is the same as for the start */ 02854 /* value. */ 02855 02856 il_idx = IL_NEXT_LIST_IDX(il_idx); 02857 02858 if (compiler_gen_imp_do) { 02859 loop_tbl[lt_idx].end_value = CN_INT_TO_C(IL_IDX(il_idx)); 02860 } 02861 else { 02862 COPY_OPND(opnd, IL_OPND(il_idx)); 02863 expr_desc.rank = 0; 02864 xref_state = CIF_Symbol_Reference; 02865 02866 if (! expr_sem(&opnd, &expr_desc)) { 02867 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 02868 goto EXIT; 02869 } 02870 02871 if (expr_desc.linear_type == Short_Typeless_Const) { 02872 OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd), 02873 INTEGER_DEFAULT_TYPE, 02874 OPND_LINE_NUM(opnd), 02875 OPND_COL_NUM(opnd)); 02876 expr_desc.type_idx = INTEGER_DEFAULT_TYPE; 02877 expr_desc.type = Integer; 02878 expr_desc.linear_type = INTEGER_DEFAULT_TYPE; 02879 } 02880 02881 if (expr_desc.rank == 0 && 02882 expr_desc.type == Integer) { 02883 02884 COPY_OPND(IL_OPND(il_idx), opnd); 02885 loop_tbl[lt_idx].end_fld = IL_FLD(il_idx); 02886 loop_tbl[lt_idx].end_idx = IL_IDX(il_idx); 02887 02888 switch (loop_tbl[lt_idx].end_fld) { 02889 02890 case CN_Tbl_Idx: 02891 loop_tbl[lt_idx].end_value = CN_INT_TO_C(IL_IDX(il_idx)); 02892 break; 02893 02894 case AT_Tbl_Idx: 02895 search_idx = loop_tbl[lt_idx].parent_idx; 02896 02897 while (search_idx != NULL_IDX) { 02898 02899 if (loop_tbl[search_idx].lcv_idx == IL_IDX(il_idx)) { 02900 loop_tbl[lt_idx].end_idx = search_idx; 02901 break; 02902 } 02903 else { 02904 search_idx = loop_tbl[search_idx].parent_idx; 02905 } 02906 02907 } 02908 02909 if (search_idx == NULL_IDX) { 02910 PRINTMSG(IL_LINE_NUM(il_idx), 658, Error, IL_COL_NUM(il_idx), 02911 AT_OBJ_NAME_PTR(IL_IDX(il_idx))); 02912 goto EXIT; 02913 } 02914 02915 break; 02916 02917 case IR_Tbl_Idx: 02918 if (good_data_imp_do_expr(loop_tbl[lt_idx].end_idx)) { 02919 arg_info_list_top = arg_info_list_base + 1; 02920 02921 loop_tbl[lt_idx].end_expr_desc_idx = arg_info_list_top; 02922 02923 if (arg_info_list_top > arg_info_list_size) { 02924 enlarge_info_list_table(); 02925 } 02926 02927 arg_info_list[arg_info_list_top] = init_arg_info; 02928 arg_info_list[arg_info_list_top].ed = expr_desc; 02929 } 02930 02931 break; 02932 02933 default: 02934 PRINTMSG(IR_LINE_NUM(imp_do_idx), 179, Internal, 02935 IR_COL_NUM(imp_do_idx), "build_loop_tbl"); 02936 } 02937 } 02938 else { 02939 PRINTMSG(IL_LINE_NUM(il_idx), 936, Error, IL_COL_NUM(il_idx)); 02940 } 02941 } 02942 02943 02944 /* If no increment value was supplied, use 1. Otherwise, capture the */ 02945 /* value in the same way the start and end values were captured. */ 02946 /* Generate an IL to represent the value 1 for the interface's convenience.*/ 02947 02948 if (IL_NEXT_LIST_IDX(il_idx) == NULL_IDX) { 02949 loop_tbl[lt_idx].inc_fld = CN_Tbl_Idx; 02950 loop_tbl[lt_idx].inc_idx = CN_INTEGER_ONE_IDX; 02951 loop_tbl[lt_idx].inc_value = CN_INT_TO_C(CN_INTEGER_ONE_IDX); 02952 02953 NTR_IR_LIST_TBL(IL_NEXT_LIST_IDX(il_idx)); 02954 IL_PREV_LIST_IDX(IL_NEXT_LIST_IDX(il_idx)) = il_idx; 02955 il_idx = IL_NEXT_LIST_IDX(il_idx); 02956 IL_LINE_NUM(il_idx) = IL_LINE_NUM(IL_PREV_LIST_IDX(il_idx)); 02957 IL_COL_NUM(il_idx) = IL_COL_NUM(IL_PREV_LIST_IDX(il_idx)); 02958 IL_FLD(il_idx) = CN_Tbl_Idx; 02959 IL_IDX(il_idx) = CN_INTEGER_ONE_IDX; 02960 ++IR_LIST_CNT_R(imp_do_idx); 02961 } 02962 else if (compiler_gen_imp_do) { 02963 il_idx = IL_NEXT_LIST_IDX(il_idx); 02964 loop_tbl[lt_idx].inc_value = CN_INT_TO_C(IL_IDX(il_idx)); 02965 } 02966 else { 02967 il_idx = IL_NEXT_LIST_IDX(il_idx); 02968 COPY_OPND(opnd, IL_OPND(il_idx)); 02969 expr_desc.rank = 0; 02970 xref_state = CIF_Symbol_Reference; 02971 02972 if (! expr_sem(&opnd, &expr_desc)) { 02973 SH_ERR_FLG(curr_stmt_sh_idx) = TRUE; 02974 goto EXIT; 02975 } 02976 02977 if (expr_desc.linear_type == Short_Typeless_Const) { 02978 OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd), 02979 INTEGER_DEFAULT_TYPE, 02980 OPND_LINE_NUM(opnd), 02981 OPND_COL_NUM(opnd)); 02982 expr_desc.type_idx = INTEGER_DEFAULT_TYPE; 02983 expr_desc.type = Integer; 02984 expr_desc.linear_type = INTEGER_DEFAULT_TYPE; 02985 } 02986 02987 if (expr_desc.rank == 0 && 02988 expr_desc.type == Integer) { 02989 02990 COPY_OPND(IL_OPND(il_idx), opnd); 02991 loop_tbl[lt_idx].inc_fld = IL_FLD(il_idx); 02992 loop_tbl[lt_idx].inc_idx = IL_IDX(il_idx); 02993 02994 switch (loop_tbl[lt_idx].inc_fld) { 02995 02996 case CN_Tbl_Idx: 02997 if (fold_relationals(IL_IDX(il_idx), 02998 CN_INTEGER_ZERO_IDX, 02999 Eq_Opr)) { 03000 PRINTMSG(IL_LINE_NUM(il_idx), 1084, Error, 03001 IL_COL_NUM(il_idx)); 03002 } 03003 else { 03004 loop_tbl[lt_idx].inc_value = CN_INT_TO_C(IL_IDX(il_idx)); 03005 } 03006 03007 break; 03008 03009 case AT_Tbl_Idx: 03010 search_idx = loop_tbl[lt_idx].parent_idx; 03011 03012 while (search_idx != NULL_IDX) { 03013 03014 if (loop_tbl[search_idx].lcv_idx == IL_IDX(il_idx)) { 03015 loop_tbl[lt_idx].inc_idx = search_idx; 03016 break; 03017 } 03018 else { 03019 search_idx = loop_tbl[search_idx].parent_idx; 03020 } 03021 03022 } 03023 03024 if (search_idx == NULL_IDX) { 03025 PRINTMSG(IL_LINE_NUM(il_idx), 658, Error, IL_COL_NUM(il_idx), 03026 AT_OBJ_NAME_PTR(IL_IDX(il_idx))); 03027 goto EXIT; 03028 } 03029 03030 break; 03031 03032 case IR_Tbl_Idx: 03033 if (good_data_imp_do_expr(loop_tbl[lt_idx].inc_idx)) { 03034 arg_info_list_top = arg_info_list_base + 1; 03035 03036 loop_tbl[lt_idx].inc_expr_desc_idx = arg_info_list_top; 03037 03038 if (arg_info_list_top > arg_info_list_size) { 03039 enlarge_info_list_table(); 03040 } 03041 03042 arg_info_list[arg_info_list_top] = init_arg_info; 03043 arg_info_list[arg_info_list_top].ed = expr_desc; 03044 } 03045 03046 break; 03047 03048 default: 03049 PRINTMSG(IR_LINE_NUM(imp_do_idx), 179, Internal, 03050 IR_COL_NUM(imp_do_idx), "build_loop_tbl"); 03051 } 03052 } 03053 else { 03054 PRINTMSG(IL_LINE_NUM(il_idx), 936, Error, IL_COL_NUM(il_idx)); 03055 } 03056 } 03057 03058 03059 /* Resolve the loop control variable. If an Attr for the same name exists */ 03060 /* at an outer level, apply the semantic checks to that Attr; else use the */ 03061 /* implied-DO local Attr. Verify that the entity is a data object of type */ 03062 /* integer and that it does not have the same name as a named constant. */ 03063 03064 il_idx = IR_IDX_R(imp_do_idx); 03065 03066 if (compiler_gen_imp_do) { 03067 loop_tbl[lt_idx].lcv_idx = IL_IDX(il_idx); 03068 } 03069 else { 03070 COPY_OPND(opnd, IL_OPND(il_idx)); 03071 expr_desc.rank = 0; 03072 expr_mode = Regular_Expr; 03073 xref_state = CIF_No_Usage_Rec; 03074 save_in_implied_do = in_implied_do; 03075 in_implied_do = FALSE; 03076 03077 lcv_line = OPND_LINE_NUM(opnd); 03078 lcv_col = OPND_COL_NUM(opnd); 03079 attr_idx = find_base_attr(&opnd, &lcv_line, &lcv_col); 03080 03081 if (AT_OBJ_CLASS(attr_idx) == Data_Obj) { 03082 save_imp_do_lcv = ATD_IMP_DO_LCV(attr_idx); 03083 ATD_IMP_DO_LCV(attr_idx) = TRUE; 03084 } 03085 03086 semantics_ok = expr_semantics(&opnd, &expr_desc); 03087 03088 COPY_OPND(IL_OPND(il_idx), opnd); 03089 in_implied_do = save_in_implied_do; 03090 03091 if (AT_OBJ_CLASS(attr_idx) == Data_Obj) { 03092 ATD_IMP_DO_LCV(attr_idx) = save_imp_do_lcv; 03093 } 03094 03095 if (expr_desc.reference) { 03096 03097 if (expr_desc.type != Integer) { 03098 find_opnd_line_and_column(&opnd, &line, &column); 03099 PRINTMSG(line, 675, Error, column); 03100 semantics_ok = FALSE; 03101 } 03102 03103 if (OPND_FLD(opnd) == IR_Tbl_Idx && 03104 IR_OPR(OPND_IDX(opnd)) == Whole_Subscript_Opr) { 03105 COPY_OPND(opnd, IR_OPND_L(OPND_IDX(opnd))); 03106 } 03107 03108 if (OPND_FLD(opnd) == IR_Tbl_Idx && 03109 IR_OPR(OPND_IDX(opnd)) == Dv_Deref_Opr) { 03110 COPY_OPND(opnd, IR_OPND_L(OPND_IDX(opnd))); 03111 } 03112 03113 /* The implied-DO variable must be an unqualified name. */ 03114 03115 if (semantics_ok && OPND_FLD(opnd) != AT_Tbl_Idx) { 03116 find_opnd_line_and_column(&opnd, &line, &column); 03117 PRINTMSG(line, 199, Error, column); 03118 semantics_ok = FALSE; 03119 } 03120 else { 03121 attr_idx = OPND_IDX(opnd); 03122 } 03123 03124 if (semantics_ok && expr_desc.rank != 0) { 03125 find_opnd_line_and_column(&opnd, &line, &column); 03126 PRINTMSG(line, 837, Ansi, column); 03127 } 03128 } 03129 else { 03130 03131 /* The implied-DO variable must be a variable (as opposed to an */ 03132 /* expression or a constant, for instance). */ 03133 03134 find_opnd_line_and_column(&opnd, &line, &column); 03135 PRINTMSG(line, 675, Error, column); 03136 semantics_ok = FALSE; 03137 } 03138 03139 if (semantics_ok) { 03140 find_opnd_line_and_column(&opnd, &line, &column); 03141 03142 if (AT_ATTR_LINK(attr_idx)) { 03143 PRINTMSG(line, 533, Error, column, 03144 AT_OBJ_NAME_PTR(attr_idx)); 03145 semantics_ok = FALSE; 03146 } 03147 else { 03148 do_var_tmp_idx = gen_compiler_tmp(line, column, Priv, TRUE); 03149 AT_SEMANTICS_DONE(do_var_tmp_idx) = TRUE; 03150 ATD_TYPE_IDX(do_var_tmp_idx) = ATD_TYPE_IDX(attr_idx); 03151 ATD_STOR_BLK_IDX(do_var_tmp_idx) = SCP_SB_STACK_IDX(curr_scp_idx); 03152 03153 AT_ATTR_LINK(attr_idx) = do_var_tmp_idx; 03154 AT_IGNORE_ATTR_LINK(attr_idx) = TRUE; 03155 03156 ATD_IMP_DO_LCV(do_var_tmp_idx) = TRUE; 03157 ATD_LCV_IS_CONST(do_var_tmp_idx) = TRUE; 03158 ATD_TMP_NEEDS_CIF(do_var_tmp_idx) = TRUE; 03159 03160 /* change name to original name */ 03161 AT_NAME_IDX(do_var_tmp_idx) = AT_NAME_IDX(attr_idx); 03162 AT_NAME_LEN(do_var_tmp_idx) = AT_NAME_LEN(attr_idx); 03163 03164 /* clear the referenced field so that this tmp does */ 03165 /* not get sent to mif. BHJ */ 03166 03167 AT_REFERENCED(do_var_tmp_idx) = Not_Referenced; 03168 03169 IL_FLD(il_idx) = AT_Tbl_Idx; 03170 IL_IDX(il_idx) = do_var_tmp_idx; 03171 IL_LINE_NUM(il_idx) = line; 03172 IL_COL_NUM(il_idx) = column; 03173 03174 loop_tbl[lt_idx].lcv_idx = do_var_tmp_idx; 03175 03176 /* issue a usage rec if needed */ 03177 if ((cif_flags & XREF_RECS) != 0) { 03178 cif_usage_rec(do_var_tmp_idx, AT_Tbl_Idx, line, column, 03179 CIF_Symbol_Modification); 03180 } 03181 03182 } 03183 } 03184 } 03185 03186 03187 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 03188 goto EXIT; 03189 } 03190 03191 /* Count the number of target variables at this level of implied-DO. */ 03192 /* Example: DATA ((tgt(i,j), i=1,10), a1(j), a2(j), j=1,3,2) */ 03193 /* The inner loop has one target and the outer has two. */ 03194 03195 in_implied_do = TRUE; 03196 target_idx = IR_IDX_L(imp_do_idx); 03197 loop_tbl[lt_idx].target_list = target_idx; 03198 03199 while (target_idx != NULL_IDX) { 03200 ++loop_tbl[lt_idx].num_targets; 03201 03202 if (IL_FLD(target_idx) == IR_Tbl_Idx && 03203 IR_OPR(IL_IDX(target_idx)) == Implied_Do_Opr) { 03204 curr_parent_idx = lt_idx; 03205 build_loop_tbl(IL_IDX(target_idx), compiler_gen_imp_do); 03206 } 03207 else if (! compiler_gen_imp_do) { 03208 COPY_OPND(opnd, IL_OPND(target_idx)); 03209 object_semantics(&opnd, 03210 Restricted_Imp_Do_Target, 03211 &expr_desc, 03212 FALSE, 03213 FALSE); 03214 03215 if (! SH_ERR_FLG(curr_stmt_sh_idx)) { 03216 03217 /* An implied-DO target can only be an array element or a scalar */ 03218 /* structure component reference (note that there is no rule */ 03219 /* that the component reference must have an interior subscript */ 03220 /* list). */ 03221 03222 if (expr_desc.rank != 0 || OPND_FLD(opnd) != IR_Tbl_Idx) { 03223 find_opnd_line_and_column(&opnd, &line, &column); 03224 PRINTMSG(line, 709, Error, column); 03225 goto EXIT; 03226 } 03227 03228 /* The Whole_Substring or Substring IR is annoyingly at the top */ 03229 /* of the reference tree so they must be skipped over to really */ 03230 /* tell what kind of reference we have. */ 03231 03232 temp_ir_idx = OPND_IDX(opnd); 03233 03234 if (IR_OPR(temp_ir_idx) == Whole_Substring_Opr || 03235 IR_OPR(temp_ir_idx) == Substring_Opr) { 03236 temp_ir_idx = IR_IDX_L(temp_ir_idx); 03237 } 03238 03239 if (IR_OPR(temp_ir_idx) != Subscript_Opr && 03240 IR_OPR(temp_ir_idx) != Struct_Opr) { 03241 find_opnd_line_and_column(&opnd, &line, &column); 03242 PRINTMSG(line, 709, Error, column); 03243 goto EXIT; 03244 } 03245 03246 COPY_OPND(IL_OPND(target_idx), opnd); 03247 } 03248 } 03249 03250 target_idx = IL_NEXT_LIST_IDX(target_idx); 03251 } 03252 03253 03254 /* Pop out to the containing implied-DO, if there is one. */ 03255 03256 lt_idx = curr_parent_idx; 03257 03258 if (curr_parent_idx != NULL_IDX) { 03259 curr_parent_idx = loop_tbl[lt_idx].parent_idx; 03260 } 03261 03262 03263 EXIT: 03264 03265 03266 /* This implied-DO is done so clear the AT_ATTR_LINK field of the */ 03267 /* implied-DO variable so no processing will go on to the temp. */ 03268 03269 if (semantics_ok && attr_idx != NULL_IDX) { 03270 AT_ATTR_LINK(attr_idx) = NULL_IDX; 03271 AT_IGNORE_ATTR_LINK(attr_idx) = FALSE; 03272 } 03273 03274 in_implied_do = save_in_implied_do; 03275 expr_mode = Regular_Expr; 03276 03277 TRACE (Func_Exit, "build_loop_tbl", NULL); 03278 03279 return; 03280 03281 } /* build_loop_tbl */ 03282 03283 03284 /******************************************************************************\ 03285 |* *| 03286 |* Description: *| 03287 |* This procedure checks to see that an IR tree returned from expr_sem *| 03288 |* for a DATA implied-DO loop control expression does not contain a *| 03289 |* subobject of a named constant. *| 03290 |* *| 03291 |* Input parameters: *| 03292 |* ir_do_idx : the index of the IR tree *| 03293 |* *| 03294 |* Output parameters: *| 03295 |* NONE *| 03296 |* *| 03297 |* Returns: *| 03298 |* TRUE if the expression does not contain a subobject designator *| 03299 |* *| 03300 \******************************************************************************/ 03301 03302 static boolean good_data_imp_do_expr(int ir_idx) 03303 03304 { 03305 boolean result = TRUE; 03306 03307 03308 TRACE (Func_Entry, "good_data_imp_do_expr", NULL); 03309 03310 switch (IR_OPR(ir_idx)) { 03311 03312 case Power_Opr: 03313 case Mult_Opr: 03314 case Div_Opr: 03315 case Uplus_Opr: 03316 case Uminus_Opr: 03317 case Plus_Opr: 03318 case Minus_Opr: 03319 case Paren_Opr: 03320 case Cvrt_Opr: 03321 case Cvrt_Unsigned_Opr: 03322 if (IR_FLD_L(ir_idx) == IR_Tbl_Idx) { 03323 03324 if (! good_data_imp_do_expr(IR_IDX_L(ir_idx))) { 03325 result = FALSE; 03326 } 03327 } 03328 03329 if (IR_FLD_R(ir_idx) == IR_Tbl_Idx) { 03330 03331 if (! good_data_imp_do_expr(IR_IDX_R(ir_idx))) { 03332 result = FALSE; 03333 } 03334 } 03335 03336 break; 03337 03338 case Struct_Opr: 03339 case Subscript_Opr: 03340 PRINTMSG(IR_LINE_NUM(ir_idx), 1081, Error, IR_COL_NUM(ir_idx)); 03341 result = FALSE; 03342 break; 03343 03344 default: 03345 PRINTMSG(IR_LINE_NUM(ir_idx), 179, Internal, 0, 03346 "good_data_imp_do_expr"); 03347 } 03348 03349 TRACE (Func_Exit, "good_data_imp_do_expr", NULL); 03350 03351 return(result); 03352 03353 } /* good_data_imp_do_expr */ 03354 03355 03356 /******************************************************************************\ 03357 |* *| 03358 |* Description: *| 03359 |* Due to the characteristics of the PDGCS interface for implied-DOs, *| 03360 |* implied-DOs that initialize many array elements can take an *| 03361 |* excruciatingly long time to complete. On the other hand, whole array *| 03362 |* and array section initialization forms run significantly faster. So *| 03363 |* this procedure is called to snoop through an implied-DO to see if it *| 03364 |* can undergo metamorphosis from a nasty, crawling implied-DO *| 03365 |* caterpillar to a lovely, dainty whole array butterfly or at least to *| 03366 |* a less elegant (but yet winged) array section moth. In order for the *| 03367 |* metamorphosis to take place, a number of environmental conditions *| 03368 |* must be met: *| 03369 |* *| 03370 |* 1. The innermost loop can only have a single target and all outer *| 03371 |* loops can only be used to drive the innermost loop. That is, *| 03372 |* a loop of the form: *| 03373 |* *| 03374 |* DATA ((arr(i,j), i = 1, 10), j = 1, 10) /.../ *| 03375 |* *| 03376 |* can undergo metamorphosis but a loop of either of the following *| 03377 |* forms can not: *| 03378 |* *| 03379 |* DATA ((a1(i,j), a2(i,j), i = 1, 10), j = 1, 10) /.../ *| 03380 |* DATA ((a1(i,j), i = 1, 10), a2(j), j = 1, 10) /.../ *| 03381 |* *| 03382 |* 2. The target must be of numeric or logical type. All of the loops *| 03383 |* that cause the compiler problems at this point are FORTRAN 77 *| 03384 |* implied-DOs. We don't need to worry yet about a program that *| 03385 |* tries to initialize a large number of elements of a large array *| 03386 |* of structures. Likely if people start using arrays of *| 03387 |* structures, they will also use other Fortran 90 initialization *| 03388 |* concepts such as whole array initialization or initialization on *| 03389 |* the type declaration statement. *| 03390 |* *| 03391 |* 3. The target must be a simple array element reference. Again, all *| 03392 |* of the problem implied-DOs are 77-style loops. Therefore, we *| 03393 |* should not have to worry about initialization of a structure *| 03394 |* component that is a large array or initializing an array *| 03395 |* constructed by taking one component from each element of an *| 03396 |* array of structures. This rule eliminates having to dig through *| 03397 |* an arbitrarily complex structure reference tree to find the *| 03398 |* entity that's actually being initialized. *| 03399 |* *| 03400 |* 4. Each subscript in the array element reference must be an *| 03401 |* implied-DO variable or a constant. An expression prevents *| 03402 |* metamorphosis because it can't be translated into a whole array *| 03403 |* initialization and sometimes not even into an array section *| 03404 |* section initialization. It's too much work to allow in SOME *| 03405 |* expressions because it's too much work to see if they are *| 03406 |* satisfactory. For example, the first implied-DO below can be *| 03407 |* metamorphed but the second can not: *| 03408 |* *| 03409 |* DATA (arr(i + 1), i = 1, 10) /.../ *| 03410 |* DATA ((arr(i + j, j), i = 1, 10), j = 1, 10) /.../ *| 03411 |* *| 03412 |* 5. Each subscript that is an implied-DO variable must be in the *| 03413 |* same order as the loop nest. That is, the subscripts that are *| 03414 |* variables must vary the fastest from the left to the right (from *| 03415 |* the innermost loop to the outermost) because this is the way *| 03416 |* whole array and section subscripting works. For example, the *| 03417 |* first implied-DO below can be metamorphed but the second can *| 03418 |* not: *| 03419 |* *| 03420 |* DATA ((arr(i,2,j), i = 1, 10), j = 1, 10) /.../ *| 03421 |* DATA ((arr(j,i), i = 1, 10), j = 1, 10) /.../ *| 03422 |* *| 03423 |* 6. Every loop control expression of every loop in the nest must be *| 03424 |* constant. Again, due to the way subscripting works in a whole *| 03425 |* array or section reference, a loop control expression can not *| 03426 |* involve an implied-DO variable from an outer loop. *| 03427 |* *| 03428 |* 7. No value in the value list can be a long Hollerith or character *| 03429 |* constant. We don't do whole array initializations or array *| 03430 |* section initializations when the values are character forms so *| 03431 |* we can't change an implied-DO into either one. And it's too *| 03432 |* darn much work to sift through the values matching them to see *| 03433 |* that the character values do or do not get assigned to the *| 03434 |* implied-DO target so we take the easier route of quitting if a *| 03435 |* character value shows up anywhere in the value list. *| 03436 |* *| 03437 |* 8. The number of array elements being initialized must be equal to *| 03438 |* the number of values in the value list. The Cray version of *| 03439 |* this compiler has an extension whereby when a whole array is *| 03440 |* being initialized, if it is the only array or the last array in *| 03441 |* the object list, the number of values can be less than the *| 03442 |* of array elements. If we do not make the count comparison in *| 03443 |* this rule and change an implied-DO into a whole array init, we *| 03444 |* could lose the count mismatch diagnostic and would thereby allow *| 03445 |* an otherwise invalid implied-DO through. *| 03446 |* *| 03447 |* If all the above requirements are met then if each loop range matches *| 03448 |* the declared bounds of the target array, the implied-DO caterpillar *| 03449 |* will undergo metamorphosis to a whole array butterfly; otherwise, it *| 03450 |* will become an array section moth. *| 03451 |* *| 03452 |* Input parameters: *| 03453 |* init_ir_idx : The index of the Init IR that heads the implied-DO. *| 03454 |* *| 03455 |* Output parameters: *| 03456 |* NONE *| 03457 |* *| 03458 |* Returns: *| 03459 |* TRUE if the implied-DO underwent metamorphosis. *| 03460 |* *| 03461 \******************************************************************************/ 03462 03463 static boolean imp_do_metamorphed(int init_ir_idx) 03464 { 03465 int attr_idx; 03466 expr_arg_type expr_desc; 03467 opnd_type expr_opnd; 03468 int i; 03469 int il_idx; 03470 int ir_idx; 03471 int iter_count_ir_idx; 03472 int local_lt_idx; 03473 boolean loops_match_bounds; 03474 boolean metamorphed; 03475 int num_elements_idx; 03476 long num_single_values; 03477 int num_single_values_idx; 03478 int num_values_idx; 03479 int result_type_idx; 03480 long_type result_value[MAX_WORDS_FOR_NUMERIC]; 03481 int subscript_ir_idx; 03482 int triplet_ir_idx; 03483 int t1_il_idx; 03484 int t2_il_idx; 03485 03486 03487 TRACE (Func_Entry, "imp_do_metamorphed", NULL); 03488 03489 metamorphed = FALSE; 03490 num_elements_idx = CN_INTEGER_ONE_IDX; 03491 num_values_idx = CN_INTEGER_ZERO_IDX; 03492 num_single_values = 0; 03493 num_single_values_idx = CN_INTEGER_ZERO_IDX; 03494 03495 03496 /* 1. The innermost loop can only have a single target and all outer loops */ 03497 /* can only be used to drive the innermost loop (therefore, each loop */ 03498 /* in the nest can only have a single target). */ 03499 03500 for (i = 1; i <= last_lt_idx; ++i) { 03501 03502 if (loop_tbl[i].num_targets != 1) { 03503 goto EXIT; 03504 } 03505 } 03506 03507 03508 /* 2. The target must be of numeric or logical type. */ 03509 /* */ 03510 /* 3. The target must be a simple array element reference. */ 03511 03512 subscript_ir_idx = IL_IDX(loop_tbl[last_lt_idx].target_list); 03513 03514 if (IR_OPR(subscript_ir_idx) != Subscript_Opr || 03515 IR_FLD_L(subscript_ir_idx) != AT_Tbl_Idx) { 03516 goto EXIT; 03517 } 03518 03519 attr_idx = IR_IDX_L(subscript_ir_idx); 03520 03521 if (TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Integer && 03522 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Real && 03523 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Complex && 03524 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Logical) { 03525 goto EXIT; 03526 } 03527 03528 03529 /* 4. Each subscript in the array element reference must be an implied-DO */ 03530 /* variable or a constant. */ 03531 /* */ 03532 /* 5. Each subscript that is an implied-DO variable must be in the same */ 03533 /* order as the loop nest. */ 03534 /* */ 03535 /* 6. Every loop control expression of every loop in the nest must be */ 03536 /* constant. */ 03537 03538 loops_match_bounds = TRUE; 03539 local_lt_idx = last_lt_idx; 03540 il_idx = IR_IDX_R(subscript_ir_idx); 03541 03542 03543 for (i = 1; i <= IR_LIST_CNT_R(subscript_ir_idx); ++i) { 03544 03545 if (IL_FLD(il_idx) == AT_Tbl_Idx) { 03546 03547 if (IL_IDX(il_idx) != loop_tbl[local_lt_idx].lcv_idx) { 03548 goto EXIT; 03549 } 03550 03551 if (loop_tbl[local_lt_idx].start_fld == CN_Tbl_Idx && 03552 loop_tbl[local_lt_idx].end_fld == CN_Tbl_Idx && 03553 loop_tbl[local_lt_idx].inc_fld == CN_Tbl_Idx) { 03554 03555 if (fold_relationals(loop_tbl[local_lt_idx].start_idx, 03556 BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), i), 03557 Ne_Opr) || 03558 fold_relationals(loop_tbl[local_lt_idx].end_idx, 03559 BD_UB_IDX(ATD_ARRAY_IDX(attr_idx), i), 03560 Ne_Opr) || 03561 fold_relationals(loop_tbl[local_lt_idx].inc_idx, 03562 CN_INTEGER_ONE_IDX, 03563 Ne_Opr)) { 03564 loops_match_bounds = FALSE; 03565 } 03566 03567 03568 /* Build an IR tree to calculate the number of times the loop */ 03569 /* will execute. */ 03570 03571 NTR_IR_TBL(iter_count_ir_idx); 03572 IR_OPR(iter_count_ir_idx) = Minus_Opr; 03573 IR_TYPE_IDX(iter_count_ir_idx) = INTEGER_DEFAULT_TYPE; 03574 IR_LINE_NUM(iter_count_ir_idx) = stmt_start_line; 03575 IR_COL_NUM(iter_count_ir_idx) = stmt_start_col; 03576 IR_FLD_L(iter_count_ir_idx) = CN_Tbl_Idx; 03577 IR_IDX_L(iter_count_ir_idx) = loop_tbl[local_lt_idx].end_idx; 03578 IR_LINE_NUM_L(iter_count_ir_idx) = stmt_start_line; 03579 IR_COL_NUM_L(iter_count_ir_idx) = stmt_start_col; 03580 IR_FLD_R(iter_count_ir_idx) = CN_Tbl_Idx; 03581 IR_IDX_R(iter_count_ir_idx) = loop_tbl[local_lt_idx].start_idx; 03582 IR_LINE_NUM_R(iter_count_ir_idx) = stmt_start_line; 03583 IR_COL_NUM_R(iter_count_ir_idx) = stmt_start_col; 03584 03585 NTR_IR_TBL(ir_idx); 03586 IR_OPR(ir_idx) = Plus_Opr; 03587 IR_TYPE_IDX(ir_idx) = INTEGER_DEFAULT_TYPE; 03588 IR_LINE_NUM(ir_idx) = stmt_start_line; 03589 IR_COL_NUM(ir_idx) = stmt_start_col; 03590 IR_FLD_L(ir_idx) = IR_Tbl_Idx; 03591 IR_IDX_L(ir_idx) = iter_count_ir_idx; 03592 IR_FLD_R(ir_idx) = CN_Tbl_Idx; 03593 IR_IDX_R(ir_idx) = loop_tbl[local_lt_idx].inc_idx; 03594 IR_LINE_NUM_R(ir_idx) = stmt_start_line; 03595 IR_COL_NUM_R(ir_idx) = stmt_start_col; 03596 03597 NTR_IR_TBL(iter_count_ir_idx); 03598 IR_OPR(iter_count_ir_idx) = Div_Opr; 03599 IR_TYPE_IDX(iter_count_ir_idx) = INTEGER_DEFAULT_TYPE; 03600 IR_LINE_NUM(iter_count_ir_idx) = stmt_start_line; 03601 IR_COL_NUM(iter_count_ir_idx) = stmt_start_col; 03602 IR_FLD_L(iter_count_ir_idx) = IR_Tbl_Idx; 03603 IR_IDX_L(iter_count_ir_idx) = ir_idx; 03604 IR_FLD_R(iter_count_ir_idx) = CN_Tbl_Idx; 03605 IR_IDX_R(iter_count_ir_idx) = loop_tbl[local_lt_idx].inc_idx; 03606 IR_LINE_NUM_R(iter_count_ir_idx) = stmt_start_line; 03607 IR_COL_NUM_R(iter_count_ir_idx) = stmt_start_col; 03608 03609 OPND_FLD(expr_opnd) = IR_Tbl_Idx; 03610 OPND_IDX(expr_opnd) = iter_count_ir_idx; 03611 03612 if (! expr_semantics(&expr_opnd, &expr_desc)) { 03613 PRINTMSG(IR_LINE_NUM(init_ir_idx), 857, Internal, 03614 IR_COL_NUM(init_ir_idx)); 03615 } 03616 03617 03618 /* Add in this loop's iteration count to the total. */ 03619 03620 result_type_idx = INTEGER_DEFAULT_TYPE; 03621 03622 if (folder_driver( (char *) &CN_CONST(num_elements_idx), 03623 CN_TYPE_IDX(num_elements_idx), 03624 (char *) &CN_CONST(OPND_IDX(expr_opnd)), 03625 expr_desc.type_idx, 03626 result_value, 03627 &result_type_idx, 03628 IR_LINE_NUM(init_ir_idx), 03629 IR_COL_NUM(init_ir_idx), 03630 2, 03631 Mult_Opr)) { 03632 num_elements_idx = ntr_const_tbl(INTEGER_DEFAULT_TYPE, 03633 FALSE, 03634 result_value); 03635 } 03636 else { 03637 PRINTMSG(IR_LINE_NUM(init_ir_idx), 1024, Internal, 03638 IR_COL_NUM(init_ir_idx)); 03639 } 03640 03641 --local_lt_idx; 03642 } 03643 else { 03644 goto EXIT; 03645 } 03646 } 03647 else if (IL_FLD(il_idx) == CN_Tbl_Idx) { 03648 loops_match_bounds = FALSE; 03649 } 03650 else { 03651 goto EXIT; 03652 } 03653 03654 il_idx = IL_NEXT_LIST_IDX(il_idx); 03655 } 03656 03657 03658 /* 7. No value in the value list can be a long Hollerith or a character */ 03659 /* constant. */ 03660 /* */ 03661 /* The value can be a stand-alone value or it can be the object of a rep */ 03662 /* factor (the right operand of a Rep_Count IR). */ 03663 03664 il_idx = value_il_idx; 03665 03666 while (il_idx != NULL_IDX) { 03667 03668 if (IL_FLD(il_idx) == CN_Tbl_Idx) { 03669 03670 if (TYP_TYPE(CN_TYPE_IDX(IL_IDX(il_idx))) != Character && 03671 TYP_LINEAR(CN_TYPE_IDX(IL_IDX(il_idx))) != Long_Typeless) { 03672 ++num_single_values; 03673 } 03674 else { 03675 goto EXIT; 03676 } 03677 } 03678 else if (IL_FLD(il_idx) == IR_Tbl_Idx) { 03679 ir_idx = IL_IDX(il_idx); 03680 03681 if (IR_OPR(ir_idx) == Rep_Count_Opr) { 03682 03683 if (IR_FLD_R(ir_idx) == CN_Tbl_Idx && 03684 (TYP_TYPE(CN_TYPE_IDX(IR_IDX_R(ir_idx))) == Character || 03685 TYP_LINEAR(CN_TYPE_IDX(IR_IDX_R(ir_idx))) == Long_Typeless)) { 03686 goto EXIT; 03687 } 03688 03689 /* Add the repetition count to the total number of values. */ 03690 03691 result_type_idx = INTEGER_DEFAULT_TYPE; 03692 03693 if (folder_driver( (char *) &CN_CONST(num_values_idx), 03694 CN_TYPE_IDX(num_values_idx), 03695 (char *) &CN_CONST(IR_IDX_L(ir_idx)), 03696 CN_TYPE_IDX(IR_IDX_L(ir_idx)), 03697 result_value, 03698 &result_type_idx, 03699 IR_LINE_NUM(ir_idx), 03700 IR_COL_NUM(ir_idx), 03701 2, 03702 Plus_Opr)) { 03703 num_values_idx = ntr_const_tbl(INTEGER_DEFAULT_TYPE, 03704 FALSE, 03705 result_value); 03706 } 03707 else { 03708 PRINTMSG(IL_LINE_NUM(il_idx), 1024, Internal, 03709 IL_COL_NUM(il_idx)); 03710 } 03711 } 03712 else { 03713 03714 /* Assume it is a unary + or - operator. */ 03715 03716 if (TYP_TYPE(CN_TYPE_IDX(IR_IDX_L(ir_idx))) != Character && 03717 TYP_LINEAR(CN_TYPE_IDX(IR_IDX_L(ir_idx))) != Long_Typeless) { 03718 ++num_single_values; 03719 } 03720 else { 03721 goto EXIT; 03722 } 03723 } 03724 } 03725 03726 il_idx = IL_NEXT_LIST_IDX(il_idx); 03727 } 03728 03729 03730 /* 8. The number of array elements being initialized must be equal to the */ 03731 /* the number of values in the value list. */ 03732 03733 num_single_values_idx = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 03734 num_single_values); 03735 03736 if (num_single_values_idx != CN_INTEGER_ZERO_IDX && 03737 num_values_idx != CN_INTEGER_ZERO_IDX) { 03738 03739 result_type_idx = INTEGER_DEFAULT_TYPE; 03740 03741 if (folder_driver( (char *) &CN_CONST(num_single_values_idx), 03742 CG_INTEGER_DEFAULT_TYPE, 03743 (char *) &CN_CONST(num_values_idx), 03744 CN_TYPE_IDX(num_values_idx), 03745 result_value, 03746 &result_type_idx, 03747 IR_LINE_NUM(init_ir_idx), 03748 IR_COL_NUM(init_ir_idx), 03749 2, 03750 Plus_Opr)) { 03751 03752 num_values_idx = ntr_const_tbl(INTEGER_DEFAULT_TYPE, 03753 FALSE, 03754 result_value); 03755 } 03756 else { 03757 PRINTMSG(IR_LINE_NUM(init_ir_idx), 1024, Internal, 03758 IR_COL_NUM(init_ir_idx)); 03759 } 03760 } 03761 03762 if (fold_relationals(num_values_idx, CN_INTEGER_ZERO_IDX, Eq_Opr)) { 03763 num_values_idx = num_single_values_idx; 03764 } 03765 03766 if (fold_relationals(num_elements_idx, num_values_idx, Ne_Opr)) { 03767 goto EXIT; 03768 } 03769 03770 03771 /* If control gets here, all the rules have been met so the implied-DO can */ 03772 /* be metamorphed. */ 03773 03774 metamorphed = TRUE; 03775 03776 PRINTMSG(IR_LINE_NUM(init_ir_idx), 1021, Note, IR_COL_NUM(init_ir_idx)); 03777 03778 if (loops_match_bounds) { 03779 03780 /* The loop can be transformed into a whole array initialization. */ 03781 /* If the implied-DO is the first item or the only item in the list, */ 03782 /* the Init IR's left operand will be pointing at the IL that in turn */ 03783 /* points at the implied-DO IR tree. To fake out data_stmt_semantics, */ 03784 /* put the array name in the IL attached to the Init IR. */ 03785 /* If the implied-DO is NOT the first or the only item in the list, a */ 03786 /* new, empty Init IR was generated by data_stmt_semantics. To fake */ 03787 /* out data_stmt_semantics, attach an IL to the Init IR's left operand */ 03788 /* and put the array name in the IL. */ 03789 03790 if (IR_FLD_L(init_ir_idx) == NO_Tbl_Idx) { 03791 NTR_IR_LIST_TBL(IR_IDX_L(init_ir_idx)); 03792 IR_LIST_CNT_L(init_ir_idx) = 1; 03793 IR_FLD_L(init_ir_idx) = IL_Tbl_Idx; 03794 03795 } 03796 03797 IL_FLD(IR_IDX_L(init_ir_idx)) = AT_Tbl_Idx; 03798 IL_IDX(IR_IDX_L(init_ir_idx)) = attr_idx; 03799 IL_LINE_NUM(IR_IDX_L(init_ir_idx)) = IR_LINE_NUM(init_ir_idx); 03800 IL_COL_NUM(IR_IDX_L(init_ir_idx)) = IR_COL_NUM(init_ir_idx); 03801 } 03802 else { 03803 03804 /* The loop can be transformed into an array section initialization. */ 03805 /* To fake out data_stmt_semantics, change the Subscript IR that's the */ 03806 /* target of the implied-DO into a section reference and attach it to */ 03807 /* the IL attached to the Init IR. */ 03808 03809 IL_FLD(IR_IDX_L(init_ir_idx)) = IR_Tbl_Idx; 03810 IL_IDX(IR_IDX_L(init_ir_idx)) = subscript_ir_idx; 03811 03812 local_lt_idx = last_lt_idx; 03813 il_idx = IR_IDX_R(subscript_ir_idx); 03814 03815 for (i = 1; i <= IR_LIST_CNT_R(subscript_ir_idx); ++i) { 03816 03817 if (IL_FLD(il_idx) == AT_Tbl_Idx) { 03818 NTR_IR_TBL(triplet_ir_idx); 03819 IL_FLD(il_idx) = IR_Tbl_Idx; 03820 IL_IDX(il_idx) = triplet_ir_idx; 03821 03822 IR_OPR(triplet_ir_idx) = Triplet_Opr; 03823 IR_TYPE_IDX(triplet_ir_idx) = TYPELESS_DEFAULT_TYPE; 03824 IR_LINE_NUM(triplet_ir_idx) = IL_LINE_NUM(il_idx); 03825 IR_COL_NUM(triplet_ir_idx) = IL_COL_NUM(il_idx); 03826 03827 NTR_IR_LIST_TBL(t1_il_idx); 03828 03829 IR_LIST_CNT_L(triplet_ir_idx) = 1; 03830 IR_FLD_L(triplet_ir_idx) = IL_Tbl_Idx; 03831 IR_IDX_L(triplet_ir_idx) = t1_il_idx; 03832 03833 IL_LINE_NUM(t1_il_idx) = IL_LINE_NUM(il_idx); 03834 IL_COL_NUM(t1_il_idx) = IL_COL_NUM(il_idx); 03835 IL_FLD(t1_il_idx) = CN_Tbl_Idx; 03836 IL_IDX(t1_il_idx) = loop_tbl[local_lt_idx].start_idx; 03837 03838 NTR_IR_LIST_TBL(t2_il_idx); 03839 03840 ++IR_LIST_CNT_L(triplet_ir_idx); 03841 IL_NEXT_LIST_IDX(t1_il_idx) = t2_il_idx; 03842 IL_PREV_LIST_IDX(t2_il_idx) = t1_il_idx; 03843 03844 IL_LINE_NUM(t2_il_idx) = IL_LINE_NUM(il_idx); 03845 IL_COL_NUM(t2_il_idx) = IL_COL_NUM(il_idx); 03846 IL_FLD(t2_il_idx) = CN_Tbl_Idx; 03847 IL_IDX(t2_il_idx) = loop_tbl[local_lt_idx].end_idx; 03848 03849 t1_il_idx = t2_il_idx; 03850 03851 NTR_IR_LIST_TBL(t2_il_idx); 03852 03853 ++IR_LIST_CNT_L(triplet_ir_idx); 03854 IL_NEXT_LIST_IDX(t1_il_idx) = t2_il_idx; 03855 IL_PREV_LIST_IDX(t2_il_idx) = t1_il_idx; 03856 03857 IL_LINE_NUM(t2_il_idx) = IL_LINE_NUM(il_idx); 03858 IL_COL_NUM(t2_il_idx) = IL_COL_NUM(il_idx); 03859 IL_FLD(t2_il_idx) = CN_Tbl_Idx; 03860 IL_IDX(t2_il_idx) = loop_tbl[local_lt_idx].inc_idx; 03861 03862 --local_lt_idx; 03863 } 03864 03865 il_idx = IL_NEXT_LIST_IDX(il_idx); 03866 } 03867 } 03868 03869 EXIT: 03870 03871 TRACE (Func_Exit, "imp_do_metamorphed", NULL); 03872 03873 return(metamorphed); 03874 03875 } /* imp_do_metamorphed */ 03876 03877 03878 /******************************************************************************\ 03879 |* *| 03880 |* Description: *| 03881 |* Interpret the DATA implied-DO to match its targets and values. *| 03882 |* *| 03883 |* Input parameters: *| 03884 |* init_ir_idx : the index to the current Init IR *| 03885 |* *| 03886 |* Output parameters: *| 03887 |* NONE *| 03888 |* *| 03889 |* Returns: *| 03890 |* NONE *| 03891 |* *| 03892 \******************************************************************************/ 03893 03894 static void interpret_data_imp_do(int init_ir_idx) 03895 { 03896 03897 expr_arg_type expr_desc; 03898 opnd_type expr_opnd; 03899 boolean first_offspring_imp_do; 03900 int i; 03901 long_type loc_value[MAX_WORDS_FOR_NUMERIC]; 03902 long64 num_iterations; 03903 int sister_idx; 03904 int target_il_idx; 03905 03906 03907 TRACE (Func_Entry, "interpret_data_imp_do", NULL); 03908 03909 03910 /* Save the guts of the lcv_idx attr. Store them in a Constant entry */ 03911 /* pointed to by ATD_TMP_IDX(lcv_idx). */ 03912 03913 GET_LCV_CONST(loop_tbl[lt_idx].lcv_idx, loc_value[0], /* target const */ 03914 num_host_wds[TYP_LINEAR(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx))]); 03915 03916 ATD_FLD(loop_tbl[lt_idx].lcv_idx) = CN_Tbl_Idx; 03917 ATD_TMP_IDX(loop_tbl[lt_idx].lcv_idx) = 03918 ntr_const_tbl(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx), 03919 FALSE, 03920 loc_value); 03921 03922 03923 OPND_FLD(expr_opnd) = IR_Tbl_Idx; 03924 03925 if (loop_tbl[lt_idx].start_fld == AT_Tbl_Idx) { 03926 loop_tbl[lt_idx].start_value = 03927 loop_tbl[loop_tbl[lt_idx].start_idx].curr_value; 03928 } 03929 else if (loop_tbl[lt_idx].start_fld == IR_Tbl_Idx) { 03930 OPND_IDX(expr_opnd) = loop_tbl[lt_idx].start_idx; 03931 03932 expr_desc = arg_info_list[loop_tbl[lt_idx].start_expr_desc_idx].ed; 03933 03934 if (! fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) { 03935 goto EXIT; 03936 } 03937 03938 loop_tbl[lt_idx].start_value = CN_INT_TO_C(OPND_IDX(expr_opnd)); 03939 } 03940 03941 if (loop_tbl[lt_idx].end_fld == AT_Tbl_Idx) { 03942 loop_tbl[lt_idx].end_value = 03943 loop_tbl[loop_tbl[lt_idx].end_idx].curr_value; 03944 } 03945 else if (loop_tbl[lt_idx].end_fld == IR_Tbl_Idx) { 03946 OPND_IDX(expr_opnd) = loop_tbl[lt_idx].end_idx; 03947 03948 expr_desc = arg_info_list[loop_tbl[lt_idx].end_expr_desc_idx].ed; 03949 03950 if (! fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) { 03951 goto EXIT; 03952 } 03953 03954 loop_tbl[lt_idx].end_value = CN_INT_TO_C(OPND_IDX(expr_opnd)); 03955 } 03956 03957 if (loop_tbl[lt_idx].inc_fld == AT_Tbl_Idx) { 03958 loop_tbl[lt_idx].inc_value = 03959 loop_tbl[loop_tbl[lt_idx].inc_idx].curr_value; 03960 } 03961 else if (loop_tbl[lt_idx].inc_fld == IR_Tbl_Idx) { 03962 OPND_IDX(expr_opnd) = loop_tbl[lt_idx].inc_idx; 03963 03964 expr_desc = arg_info_list[loop_tbl[lt_idx].inc_expr_desc_idx].ed; 03965 03966 if (! fold_aggragate_expression(&expr_opnd, &expr_desc, TRUE)) { 03967 goto EXIT; 03968 } 03969 03970 loop_tbl[lt_idx].inc_value = CN_INT_TO_C(OPND_IDX(expr_opnd)); 03971 } 03972 03973 num_iterations = 03974 (loop_tbl[lt_idx].end_value - loop_tbl[lt_idx].start_value + 03975 loop_tbl[lt_idx].inc_value) / 03976 loop_tbl[lt_idx].inc_value; 03977 03978 if (num_iterations < 0) { 03979 num_iterations = 0; 03980 } 03981 03982 if (num_iterations == 0) { 03983 goto EXIT; 03984 } 03985 03986 for (loop_tbl[lt_idx].curr_value = loop_tbl[lt_idx].start_value; 03987 (loop_tbl[lt_idx].inc_value > 0) ? 03988 loop_tbl[lt_idx].curr_value <= loop_tbl[lt_idx].end_value : 03989 loop_tbl[lt_idx].curr_value >= loop_tbl[lt_idx].end_value; 03990 loop_tbl[lt_idx].curr_value += loop_tbl[lt_idx].inc_value) { 03991 03992 C_TO_F_INT(loc_value, 03993 loop_tbl[lt_idx].curr_value, 03994 TYP_LINEAR(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx))); 03995 03996 SET_LCV_CONST(loop_tbl[lt_idx].lcv_idx, 03997 (loc_value[0]), 03998 num_host_wds[TYP_LINEAR(ATD_TYPE_IDX( 03999 loop_tbl[lt_idx].lcv_idx))]); 04000 04001 target_il_idx = loop_tbl[lt_idx].target_list; 04002 first_offspring_imp_do = TRUE; 04003 04004 for (i = 1; i <= loop_tbl[lt_idx].num_targets; ++i) { 04005 04006 if (IR_OPR(IL_IDX(target_il_idx)) == Implied_Do_Opr) { 04007 04008 /* If this is the first offspring that is an implied-DO, get the */ 04009 /* lt_idx from the offspring_idx field of the current loop_tbl */ 04010 /* entry and save the index to its sibling (which might be 0). */ 04011 /* Otherwise, use the saved sibling index to get to the next */ 04012 /* child of this implied-DO. */ 04013 04014 if (first_offspring_imp_do) { 04015 lt_idx = loop_tbl[lt_idx].offspring_idx; 04016 sister_idx = loop_tbl[lt_idx].sibling_idx; 04017 first_offspring_imp_do = FALSE; 04018 } 04019 else { 04020 lt_idx = sister_idx; 04021 sister_idx = loop_tbl[lt_idx].sibling_idx; 04022 } 04023 04024 04025 interpret_data_imp_do(init_ir_idx); 04026 04027 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 04028 goto EXIT; 04029 } 04030 } 04031 else { 04032 04033 process_data_imp_do_target(init_ir_idx, 04034 target_il_idx, 04035 num_iterations); 04036 04037 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 04038 goto EXIT; 04039 } 04040 04041 if (loop_tbl[lt_idx].num_targets == 1) { 04042 goto EXIT; 04043 } 04044 } 04045 04046 target_il_idx = IL_NEXT_LIST_IDX(target_il_idx); 04047 } 04048 } 04049 04050 EXIT: 04051 04052 /* Restore the guts of the LCV temp Attr. */ 04053 04054 SET_LCV_CONST(loop_tbl[lt_idx].lcv_idx, 04055 CN_CONST(ATD_TMP_IDX(loop_tbl[lt_idx].lcv_idx)), 04056 num_host_wds[TYP_LINEAR(ATD_TYPE_IDX(loop_tbl[lt_idx].lcv_idx))]); 04057 04058 lt_idx = loop_tbl[lt_idx].parent_idx; 04059 04060 TRACE (Func_Exit, "interpret_data_imp_do", NULL); 04061 04062 return; 04063 04064 } /* interpret_data_imp_do */ 04065 04066 04067 /******************************************************************************\ 04068 |* *| 04069 |* Description: *| 04070 |* See enormously long description below. *| 04071 |* *| 04072 |* *| 04073 |* Input parameters: *| 04074 |* init_ir_idx : the index of the Init IR *| 04075 |* target_il_idx : IL index of current target *| 04076 |* num_iterations : the number of times the current implied-DO will be *| 04077 |* executed *| 04078 |* *| 04079 |* Output parameters: *| 04080 |* NONE *| 04081 |* *| 04082 |* Returns: *| 04083 |* NONE *| 04084 |* *| 04085 \******************************************************************************/ 04086 04087 /******************************************************************************\ 04088 N O T E S 04089 04090 Among the basic design tenets of DATA processing are the following which 04091 directly relate to the relationship between the Semantics Pass and the 04092 (PDGCS) Interface: 04093 04094 * The Interface expects each implied-DO target to have a corresponding 04095 value. This means that the Semantics Pass must ensure that the *number* 04096 of targets matches the number of values. 04097 04098 * The Interface should not have to contend with DATA statement semantics 04099 (error checking). This means that the Semantics Pass must ensure that 04100 the *type* of each value is suitable for assignment to the corresponding 04101 target. 04102 04103 Normally, this is relatively straightforward because this relationship 04104 (expectations) between the Interface and the Semantics Pass reflects the 04105 standard. However, CF77 has an extension that allows a long string (either 04106 a Hollerith or character literal constant) to be assigned piecemeal to 04107 targets of an implied-DO or array initialization. This procedure 04108 (process_data_imp_do_target) exists to match a target with a value (in some 04109 cases match a number of targets with a number of values) and to ensure that 04110 the target(s) and value(s) are assignment compatible. (CF77 only allows 04111 initialization of multiple word-length items with long string constants. 04112 This means, for example, that double precision and complex items can *not* 04113 be initialized with a long string. And CF77 only allows initialization of 04114 word-length targets with word-length (or less) values, so, for example, a 04115 double precision variable can not be initialized with a character/Hollerith 04116 constant. CF90 relaxes the latter rule in 2.0 and beyond because programs 04117 exist that are intended to be run on 32-bit machines and that initialize 04118 multi-word numeric items with Hollerith strings. However, CF90 will *not* 04119 enhance the "long string" extension to work with multi-word targets. And 04120 since CF77 does not support array section notation in DATA statements, CF90 04121 does *not* support initialization of array sections with long strings. And 04122 finally, since CF77 does not support initialization on type declaration 04123 statements, CF90 does *not* support the "long string" extension in that 04124 context either. 04125 04126 Since a long string can be split up among arbitrary implied-DO targets, 04127 a number of the bookkeeping variables like value_count are 04128 static, wither by being global to this file or static in this procedure. 04129 For whole array initialization, the long string is *not* split across 04130 multiple targets. This means you can *not* do the following: 04131 04132 integer i(2), k(2) 04133 data i, k /'abcdef123456ABCDEF654321'/ 04134 04135 The long string is broken down into word-size pieces and each piece is 04136 reentered into the Constant Table. Note that the last piece may be less 04137 than a word in length. If the implied-DO does not finish off the long 04138 string, the remainder is set up as the next value (for the target 04139 following the implied-DO) by data_imp_do_semantics (when the (outermost) 04140 implied-DO is completely finished). This is not done for whole array 04141 initialization. That is, the "remainder" is not passed on to another 04142 variable. The value must break down into the number of values required by 04143 the target array (except if the array is the last thing in the list, in 04144 which case another CRI extension is invoked whereby the last array in the 04145 list need not be completely initialized). 04146 04147 The following general rule was deduced from CF77 by running variations on a 04148 number of programs: 04149 04150 A long string can be utilized by any combination of numeric targets 04151 at any level of nesting. The string can slop over onto an 04152 initialization following the implied-DO. The initialization rules 04153 for the item following the implied-DO are then in effect. 04154 04155 There is a minor difference between the CF77 and CF90 implementations of 04156 the "long string" extension. In an initialization of the form: 04157 04158 INTEGER array(3) 04159 DATA (array(i), i = 1, 3), k /2 * 16H1234567887654321/ 04160 04161 CF77 issues an error message saying that there are too few values because 04162 it does not use whatever is left over in the string when the implied-DO 04163 completes IF THERE IS A REP FACTOR PRESENT. If the example was written as: 04164 04165 INTEGER array(2) 04166 DATA (array(i), i = 1, 2), k /24H1234567887654321zzzzzzzz/ 04167 04168 CF77 WOULD use the remaining part of the string as the value to be assigned 04169 to K. CF90 always uses all of the string in a consistent manner. 04170 04171 04172 This procedure has two basic processing sections: 04173 04174 * If the current implied-DO (which may be an inner implied-DO of a 04175 nested set) has only a single target (a typical case so it's worth 04176 the optimization), control remains in this procedure for all of the 04177 iterations of the current implied-DO. That is, this routine will 04178 continue advancing through the values until the current implied-DO 04179 runs out of targets. For example, 04180 04181 CHARACTER*8 array(4096) 04182 DATA (array(i), i = 1, 4096) 04183 & /1000*'a', 1000*'b', 1000*'c', 1000*'d', 96*' '/ 04184 04185 This procedure will process the entire value list for the implied-DO 04186 before it returns to interpret_data_imp_do. This is also true for 04187 the inner loop of an example of the form: 04188 04189 INTEGER k1(10,10), k2(10) 04190 DATA ((k1(i,j), i = 1, 10), k2(j), j = 1, 10) /500*0, 500*1/ 04191 04192 That is, 10 values will be processed for K1 then control will return. 04193 When this procedure is entered again, a single value will be processed 04194 for K2. And when the procedure is entered for the third time, another 04195 10 values will be processed for K1 and so on. 04196 04197 * Otherwise, the current implied-DO has more than one target. "More 04198 than one target" means a single implied-DO loop has multiple array 04199 element targets or an implied-DO contains at least one nested 04200 implied-DO. For these cases, this procedure is called once for each 04201 target (which is why the case above that checks for a single target 04202 exists: to reduce the number of calls to this procedure). 04203 04204 \******************************************************************************/ 04205 static void process_data_imp_do_target(int init_ir_idx, 04206 int target_il_idx, 04207 long64 num_iterations) 04208 { 04209 opnd_type ignore_this_opnd; 04210 int il_idx; 04211 boolean long_value; 04212 int ir_idx; 04213 opnd_type rep_factor_opnd; 04214 int target_attr_idx; 04215 boolean word_size_target; 04216 04217 04218 TRACE (Func_Entry, "process_data_imp_do_target", NULL); 04219 04220 ir_idx = IL_IDX(target_il_idx); 04221 04222 if (IR_OPR(ir_idx) == Whole_Substring_Opr || 04223 IR_OPR(ir_idx) == Substring_Opr) { 04224 ir_idx = IR_IDX_L(ir_idx); 04225 } 04226 04227 /* Section_Subscript_Opr gets into the act if this is a compiler-gen'd */ 04228 /* implied-DO to represent an array initialization where the array has at */ 04229 /* one vector valued subscript. */ 04230 04231 if (IR_OPR(ir_idx) == Subscript_Opr || 04232 IR_OPR(ir_idx) == Section_Subscript_Opr) { 04233 04234 /* Subscript must be pointing at Attr entry or Struct IR. */ 04235 04236 target_attr_idx = (IR_FLD_L(ir_idx) == AT_Tbl_Idx) ? 04237 IR_IDX_L(ir_idx) : IR_IDX_R(IR_IDX_L(ir_idx)); 04238 } 04239 else { 04240 target_attr_idx = IR_IDX_R(ir_idx); /* Must be Struct IR. */ 04241 } 04242 04243 if (loop_tbl[lt_idx].num_targets == 1) { 04244 04245 /* Implied-DO contains a single target. Process all iterations of this */ 04246 /* implied-DO. */ 04247 04248 obj_count = num_iterations * loop_tbl[lt_idx].num_targets; 04249 04250 while (obj_count > 0) { 04251 04252 if (rep_factor == 0) { 04253 set_global_value_variables(&rep_factor_opnd, 04254 &ignore_this_opnd, 04255 target_attr_idx); 04256 04257 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 04258 goto EXIT; 04259 } 04260 04261 ++IR_LIST_CNT_R(init_ir_idx); 04262 } 04263 04264 word_size_target = FALSE; 04265 04266 if (TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)) == 04267 INTEGER_DEFAULT_TYPE || 04268 TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)) == 04269 REAL_DEFAULT_TYPE) { 04270 04271 if (storage_bit_size_tbl[ 04272 TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx))] == 04273 TARGET_BITS_PER_WORD) { 04274 word_size_target = TRUE; 04275 } 04276 } 04277 04278 long_value = FALSE; 04279 04280 if (value_desc.type == Typeless) { 04281 if (TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) > 04282 TARGET_BITS_PER_WORD) { 04283 long_value = TRUE; 04284 } 04285 } 04286 else if (value_desc.type == Character) { 04287 04288 if (CN_INT_TO_C(TYP_IDX(value_desc.type_idx)) > 04289 TARGET_CHARS_PER_WORD) { 04290 long_value = TRUE; 04291 } 04292 } 04293 04294 if (word_size_target && long_value) { 04295 PRINTMSG(OPND_LINE_NUM(value_opnd), 733, Error, 04296 OPND_COL_NUM(value_opnd)); 04297 04298 --IR_LIST_CNT_R(init_ir_idx); 04299 04300 04301 /* Hollerith constants are always a word multiple in length. */ 04302 /* They are padded on the right or on the left with blanks */ 04303 /* or nulls, depending on the Hollerith specifier. */ 04304 04305 if (TYP_TYPE(CN_TYPE_IDX(OPND_IDX(value_opnd))) == Typeless) { 04306 ls_word_len = 04307 TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) / 04308 TARGET_BITS_PER_WORD; 04309 } 04310 else { 04311 ls_word_len = 04312 CN_INT_TO_C(TYP_IDX(CN_TYPE_IDX(OPND_IDX(value_opnd)))) / 04313 TARGET_CHARS_PER_WORD; 04314 04315 if ((long) 04316 CN_INT_TO_C(TYP_IDX(CN_TYPE_IDX(OPND_IDX(value_opnd)))) % 04317 TARGET_CHARS_PER_WORD) { 04318 ++ls_word_len; 04319 } 04320 } 04321 } 04322 04323 check_target_and_value(target_attr_idx, init_ir_idx); 04324 04325 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 04326 goto EXIT; 04327 } 04328 04329 if (obj_count == rep_factor) { 04330 obj_count = 0; 04331 rep_factor = 0; 04332 04333 if (IL_FLD(value_il_idx) == CN_Tbl_Idx) { 04334 IL_IDX(value_il_idx) = OPND_IDX(value_opnd); 04335 } 04336 else { 04337 IR_IDX_R(IL_IDX(value_il_idx)) = OPND_IDX(value_opnd); 04338 } 04339 04340 value_il_idx = IL_NEXT_LIST_IDX(value_il_idx); 04341 } 04342 else if (obj_count > rep_factor) { 04343 obj_count -= rep_factor; 04344 rep_factor = 0; 04345 04346 if (IL_FLD(value_il_idx) == CN_Tbl_Idx) { 04347 IL_IDX(value_il_idx) = OPND_IDX(value_opnd); 04348 } 04349 else { 04350 IR_IDX_R(IL_IDX(value_il_idx)) = OPND_IDX(value_opnd); 04351 } 04352 04353 value_il_idx = IL_NEXT_LIST_IDX(value_il_idx); 04354 04355 if (value_il_idx == NULL_IDX) { 04356 PRINTMSG(IR_LINE_NUM(init_ir_idx), 667, Error, 04357 IR_COL_NUM(init_ir_idx)); 04358 goto EXIT; 04359 } 04360 } 04361 else { 04362 04363 /* This case (where there are values left over) is taken care */ 04364 /* of upon return to data_imp_do_semantics. */ 04365 04366 rep_factor -= obj_count; 04367 obj_count = 0; 04368 } 04369 } 04370 } 04371 else { 04372 04373 /* Implied-DO has more than one target. Process only the current */ 04374 /* target. */ 04375 04376 if (rep_factor == 0) { 04377 set_global_value_variables(&rep_factor_opnd, 04378 &ignore_this_opnd, 04379 target_attr_idx); 04380 04381 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 04382 goto EXIT; 04383 } 04384 04385 ++IR_LIST_CNT_R(init_ir_idx); 04386 } 04387 04388 /* CRI extension: (same as described above) */ 04389 if ((TYP_TYPE(ATD_TYPE_IDX(target_attr_idx)) == Integer || 04390 TYP_LINEAR(ATD_TYPE_IDX(target_attr_idx)) == REAL_DEFAULT_TYPE) && 04391 (value_desc.linear_type == Long_Typeless || 04392 (CN_HOLLERITH_TYPE(OPND_IDX(value_opnd)) != Not_Hollerith && 04393 TYP_BIT_LEN(CN_TYPE_IDX(OPND_IDX(value_opnd))) > 04394 TARGET_BITS_PER_WORD) || 04395 (value_desc.type == Character && 04396 CN_INT_TO_C(TYP_IDX(value_desc.type_idx)) > 04397 TARGET_CHARS_PER_WORD))){ 04398 04399 PRINTMSG(OPND_LINE_NUM(value_opnd), 04400 733, Error, 04401 OPND_COL_NUM(value_opnd)); 04402 } 04403 04404 check_target_and_value(target_attr_idx, init_ir_idx); 04405 04406 if (rep_factor == 1) { 04407 rep_factor = 0; 04408 value_il_idx = IL_NEXT_LIST_IDX(value_il_idx); 04409 } 04410 else { /* rep_factor must be > 1 */ 04411 --rep_factor; 04412 } 04413 } 04414 04415 EXIT: 04416 04417 /* In order to get an IR display, restore the correct value in */ 04418 /* IR_LIST_CNT_R (because it was set to 1 earlier and in the normal case */ 04419 /* will be incremented as each value IL is used). */ 04420 04421 if (SH_ERR_FLG(curr_stmt_sh_idx)) { 04422 il_idx = IR_IDX_R(init_ir_idx); 04423 IR_LIST_CNT_R(init_ir_idx) = 1; 04424 04425 while (IL_NEXT_LIST_IDX(il_idx) != NULL_IDX) { 04426 il_idx = IL_NEXT_LIST_IDX(il_idx); 04427 ++IR_LIST_CNT_R(init_ir_idx); 04428 } 04429 } 04430 04431 TRACE (Func_Exit, "process_data_imp_do_target", NULL); 04432 04433 return; 04434 04435 } /* process_data_imp_do_target */ 04436 04437 04438 /******************************************************************************\ 04439 |* *| 04440 |* Description: *| 04441 |* Verify that the target and value are assignment compatible. If the *| 04442 |* target is type character and the value is shorter than the target, *| 04443 |* calculate the number of padding blanks needed. *| 04444 |* *| 04445 |* This routine is extern'd (in globals.h) so that the implied-DO code *| 04446 |* in the PDGCS interface can call it. *| 04447 |* *| 04448 |* Input parameters: *| 04449 |* attr_idx : the target's Attr table index *| 04450 |* *| 04451 |* Output parameters: *| 04452 |* NONE *| 04453 |* *| 04454 |* Returns: *| 04455 |* TRUE if the target and value are compatible. *| 04456 |* *| 04457 \******************************************************************************/ 04458 04459 static boolean check_target_and_value(int attr_idx, 04460 int init_ir_idx) 04461 04462 { 04463 long_type another_constant[MAX_WORDS_FOR_NUMERIC]; 04464 int column; 04465 int line; 04466 boolean result = TRUE; 04467 int type_idx; 04468 04469 04470 TRACE (Func_Entry, "check_target_and_value", NULL); 04471 04472 if (value_desc.linear_type == Long_Typeless) { 04473 PRINTMSG(OPND_LINE_NUM(value_opnd), 1133, Error, 04474 OPND_COL_NUM(value_opnd)); 04475 result = FALSE; 04476 goto EXIT; 04477 } 04478 04479 if (check_asg_semantics(ATD_TYPE_IDX(attr_idx), 04480 value_desc.type_idx, 04481 OPND_LINE_NUM(value_opnd), 04482 OPND_COL_NUM(value_opnd))) { 04483 04484 if ((ATD_POINTER(attr_idx) && 04485 (OPND_FLD(value_opnd) != IR_Tbl_Idx || 04486 IR_OPR(OPND_IDX(value_opnd)) != Null_Intrinsic_Opr)) || 04487 04488 (!ATD_POINTER(attr_idx) && 04489 OPND_FLD(value_opnd) == IR_Tbl_Idx && 04490 IR_OPR(OPND_IDX(value_opnd)) == Null_Intrinsic_Opr)) { 04491 find_opnd_line_and_column(&value_opnd, &line, &column); 04492 PRINTMSG(line, 1559, Error, column); 04493 } 04494 04495 if (ATD_POINTER(attr_idx) && 04496 OPND_FLD(value_opnd) == IR_Tbl_Idx && 04497 IR_OPR(OPND_IDX(value_opnd)) == Null_Intrinsic_Opr) { 04498 IR_OPR(init_ir_idx) = Null_Opr; 04499 } 04500 04501 if (CN_BOZ_CONSTANT(OPND_IDX(value_opnd)) && 04502 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Integer) { 04503 04504 PRINTMSG(OPND_LINE_NUM(value_opnd), 729, Ansi, 04505 OPND_COL_NUM(value_opnd), 04506 AT_OBJ_NAME_PTR(attr_idx)); 04507 } 04508 04509 if ((TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != Character && 04510 value_desc.type == Character) || 04511 value_desc.linear_type == Short_Typeless_Const) { 04512 04513 /* Cast the typeless or character (boolean) constant to the */ 04514 /* type of the target. */ 04515 04516 OPND_IDX(value_opnd) = cast_typeless_constant(OPND_IDX(value_opnd), 04517 ATD_TYPE_IDX(attr_idx), 04518 OPND_LINE_NUM(value_opnd), 04519 OPND_COL_NUM(value_opnd)); 04520 value_desc.type = TYP_TYPE(ATD_TYPE_IDX(attr_idx)); 04521 value_desc.type_idx = ATD_TYPE_IDX(attr_idx); 04522 value_desc.linear_type = TYP_LINEAR(ATD_TYPE_IDX(attr_idx)); 04523 } 04524 else if (TYP_LINEAR(value_desc.type_idx) != 04525 TYP_LINEAR(ATD_TYPE_IDX(attr_idx)) && 04526 TYP_TYPE(value_desc.type_idx) != Character && 04527 TYP_TYPE(value_desc.type_idx) != Typeless && 04528 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != CRI_Ptr && 04529 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != CRI_Parcel_Ptr && 04530 TYP_TYPE(ATD_TYPE_IDX(attr_idx)) != CRI_Ch_Ptr) { 04531 04532 /* PDGCS does not like it if the value is not the same size as the */ 04533 /* target; for example, the value is a double precision constant and */ 04534 /* the target is a single precision variable. So explicitly convert */ 04535 /* the value to the type and kind type parameter of the target for */ 04536 /* all combinations to be consistent. */ 04537 04538 type_idx = ATD_TYPE_IDX(attr_idx); 04539 04540 if (folder_driver( (char *) &CN_CONST(OPND_IDX(value_opnd)), 04541 value_desc.type_idx, 04542 NULL, 04543 NULL_IDX, 04544 another_constant, 04545 &type_idx, 04546 OPND_LINE_NUM(value_opnd), 04547 OPND_COL_NUM(value_opnd), 04548 1, 04549 Cvrt_Opr)) { 04550 04551 value_desc.type_idx = type_idx; 04552 value_desc.linear_type = TYP_LINEAR(type_idx); 04553 value_desc.type = TYP_TYPE(type_idx); 04554 OPND_IDX(value_opnd) = ntr_const_tbl(ATD_TYPE_IDX(attr_idx), 04555 FALSE, 04556 another_constant); 04557 } 04558 } 04559 } 04560 else { 04561 find_opnd_line_and_column(&value_opnd, &line, &column); 04562 PRINTMSG(line, 97, Error, column, AT_OBJ_NAME_PTR(attr_idx)); 04563 result = FALSE; 04564 } 04565 04566 EXIT: 04567 04568 TRACE (Func_Exit, "check_target_and_value", NULL); 04569 04570 return(result); 04571 04572 } /* check_target_and_value" */ 04573 04574 04575 /******************************************************************************\ 04576 |* *| 04577 |* Description: *| 04578 |* Make sure the character-valued initialization value is the same *| 04579 |* length as the target. If necessary, generate a secondary DATA stmt *| 04580 |* to blank pad the initialization value. *| 04581 |* *| 04582 |* Input parameters: *| 04583 |* init_ir_idx : the index of the Init IR *| 04584 |* array_ir_idx : contains an IR index only if the target is an *| 04585 |* array *| 04586 |* section_start_value : if the target is a section, this is the current *| 04587 |* value of the first section triplet subscript *| 04588 |* section_inc_value : if the target is a section, this is inc value *| 04589 |* in the first section triplet subscript *| 04590 |* *| 04591 |* Output parameters: *| 04592 |* NONE *| 04593 |* *| 04594 |* Returns: *| 04595 |* NONE *| 04596 |* *| 04597 \******************************************************************************/ 04598 04599 static void adjust_char_value_len(int init_ir_idx, 04600 int array_ir_idx, 04601 long64 section_start_value, 04602 long64 section_inc_value) 04603 { 04604 04605 int end_il_idx; 04606 long64 i; 04607 int il_idx; 04608 int imp_do_ir_idx; 04609 int inc_il_idx; 04610 int ir_idx; 04611 int new_init_ir_idx; 04612 int new_str_idx; 04613 char *new_str_ptr; 04614 long64 numeric_value; 04615 char *old_str_ptr; 04616 opnd_type opnd; 04617 int original_end_il_idx; 04618 long64 original_end_val; 04619 long64 original_start_val; 04620 long64 rep_count; 04621 int rep_count_il_idx; 04622 int rep_count_ir_idx; 04623 int start_il_idx; 04624 int substring_ir_idx; 04625 long64 target_length; 04626 int temp_idx; 04627 int type_idx; 04628 int value_idx; 04629 long64 value_length; 04630 04631 04632 /* ------------------- Problematic code warning ------------------------ */ 04633 /* */ 04634 /* By design, each entry in the Constant Table must start on a word */ 04635 /* boundary. The following declaration pushes the single character */ 04636 /* value to the LEFT end of the word. Some architectures may prefer it */ 04637 /* to be on the right end so someone may later have to ifdef the following */ 04638 /* declaration to work on those other architectures. LRR */ 04639 /* */ 04640 /* ------------------- Problematic code warning ------------------------ */ 04641 04642 04643 04644 # if defined(_HOST_LITTLE_ENDIAN) 04645 long_type single_blank = (long_type)' '; 04646 #else 04647 long_type single_blank = (long_type)' ' << 04648 (sizeof(long_type)*CHAR_BIT - CHAR_BIT); 04649 # endif 04650 04651 04652 TRACE (Func_Entry, "adjust_char_value_len", NULL); 04653 04654 substring_ir_idx = IR_IDX_L(init_ir_idx); 04655 il_idx = IR_IDX_R(substring_ir_idx); 04656 original_start_val = CN_INT_TO_C(IL_IDX(il_idx)); 04657 original_end_il_idx = IL_NEXT_LIST_IDX(il_idx); 04658 original_end_val = CN_INT_TO_C(IL_IDX(original_end_il_idx)); 04659 target_length = original_end_val - original_start_val + 1; 04660 04661 if (target_length > 0) { 04662 value_idx = IL_IDX(IR_IDX_R(init_ir_idx)); 04663 value_length = CN_INT_TO_C(TYP_IDX(CN_TYPE_IDX(value_idx))); 04664 04665 if (target_length == value_length) { 04666 goto EXIT; 04667 } 04668 04669 if (target_length < value_length) { 04670 04671 /* Need to replace the initialization value with a shorter length */ 04672 /* string to match the length of the target. */ 04673 04674 CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX); 04675 TYP_TYPE(TYP_WORK_IDX) = Character; 04676 TYP_LINEAR(TYP_WORK_IDX) = CHARACTER_DEFAULT_TYPE; 04677 TYP_CHAR_CLASS(TYP_WORK_IDX) = Const_Len_Char; 04678 TYP_FLD(TYP_WORK_IDX) = CN_Tbl_Idx; 04679 TYP_IDX(TYP_WORK_IDX) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04680 target_length); 04681 type_idx = ntr_type_tbl(); 04682 04683 /* Call ntr_const_tbl with NULL for the incoming constant so it will */ 04684 /* just allocate the amount of space needed. Copy the original */ 04685 /* string to the new string by hand. */ 04686 /* Replace the value's Constant table index with the Constant table */ 04687 /* index of the shortened string. */ 04688 04689 new_str_idx = ntr_const_tbl(type_idx, TRUE, NULL); 04690 new_str_ptr = (char *) &CN_CONST(new_str_idx); /* KAYKAY */ 04691 old_str_ptr = (char *) &CN_CONST(value_idx); 04692 04693 for (i = 0; i < target_length; i++) { 04694 new_str_ptr[i] = old_str_ptr[i]; 04695 } 04696 04697 while (target_length % TARGET_BYTES_PER_WORD != 0) { 04698 new_str_ptr[target_length] = ' '; 04699 target_length++; 04700 } 04701 04702 IL_IDX(IR_IDX_R(init_ir_idx)) = new_str_idx; 04703 } 04704 else { 04705 04706 /* Future optimizations: */ 04707 /* - If the target is a scalar and the value is "small", reenter */ 04708 /* the constant with blank padding rather than generating the */ 04709 /* implied-DO to do the blank padding. */ 04710 /* - If the value is a zero-length constant, no tree duplication */ 04711 /* needs to be done. */ 04712 /* */ 04713 /* Must do blank padding. There are two ways to do this: */ 04714 /* (a) generate a new value (char constant) that is the same */ 04715 /* length as the target and is blank padded, or */ 04716 /* (b) generate an implied-DO to do the blank padding. For the */ 04717 /* array case, the implied-DO makes a second pass through the */ 04718 /* array (after the value is assigned to each element via */ 04719 /* whole array or section initialization) adding the blanks. */ 04720 /* It is a design trade-off for array initialization between eating */ 04721 /* up time by running through an implied-DO in the interface vs. */ 04722 /* potentially eating up a lot of CN table space if a number of new */ 04723 /* character constants need to be built. The "if" stmt below */ 04724 /* controls when we'll switch from the implied-DO method to the new */ 04725 /* constant method. As it stands now, there is both an array element*/ 04726 /* count threshhold and an array element length threshhold. As we */ 04727 /* learn more about trade-offs between the implied-DO method and the */ 04728 /* new constant method, the threshholds can easily be changed. They */ 04729 /* are currently set to switch to the new constant method if at */ 04730 /* least 100 array elements are being initialized where the length */ 04731 /* of each element is no more than 256 characters. The numbers were */ 04732 /* essentially chosen at random but with an eye to performance on */ 04733 /* both Crays and workstations. */ 04734 04735 rep_count_il_idx = IL_NEXT_LIST_IDX(IR_IDX_R(init_ir_idx)); 04736 rep_count = CN_INT_TO_C(IL_IDX(rep_count_il_idx)); 04737 04738 if (array_ir_idx != NULL_IDX && rep_count >= 100 && 04739 target_length <= 256) { 04740 04741 CLEAR_TBL_NTRY(type_tbl, TYP_WORK_IDX); 04742 TYP_TYPE(TYP_WORK_IDX) = Character; 04743 TYP_LINEAR(TYP_WORK_IDX) = CHARACTER_DEFAULT_TYPE; 04744 TYP_CHAR_CLASS(TYP_WORK_IDX)= Const_Len_Char; 04745 TYP_FLD(TYP_WORK_IDX) = CN_Tbl_Idx; 04746 TYP_IDX(TYP_WORK_IDX) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04747 target_length); 04748 type_idx = ntr_type_tbl(); 04749 04750 /* Call ntr_const_tbl with NULL for the incoming constant so it */ 04751 /* will just allocate the amount of space needed. Copy the */ 04752 /* original string to the new string by hand and blank pad the */ 04753 /* new string by hand. */ 04754 /* Replace the value's Constant table index with the Constant */ 04755 /* table index of the padded string. */ 04756 04757 new_str_idx = ntr_const_tbl(type_idx, TRUE, NULL); 04758 new_str_ptr = (char *) &CN_CONST(new_str_idx); 04759 old_str_ptr = (char *) &CN_CONST(value_idx); 04760 04761 for (i = 0; i < value_length; i++) { 04762 new_str_ptr[i] = old_str_ptr[i]; 04763 } 04764 04765 for (i = value_length; i < target_length; i++) { 04766 new_str_ptr[i] = ' '; 04767 } 04768 04769 while (target_length % TARGET_BYTES_PER_WORD != 0) { 04770 new_str_ptr[target_length] = ' '; 04771 target_length++; 04772 } 04773 04774 IL_IDX(IR_IDX_R(init_ir_idx)) = new_str_idx; 04775 } 04776 else { 04777 04778 /* Use the implied-DO method. */ 04779 /* - Generate a DATA stmt SH following the current SH. */ 04780 /* - Change the substring operator to Substring_Opr in case it */ 04781 /* was originally Whole_Substring_Opr. */ 04782 /* - If a single target is being initialized, the original */ 04783 /* initialization IR tree can be duplicated and altered to do */ 04784 /* blank padding. Otherwise, the padding must be done by */ 04785 /* generating implied-DO IR. */ 04786 04787 gen_sh(After, Data_Stmt, 04788 IR_LINE_NUM(init_ir_idx), IR_COL_NUM(init_ir_idx), 04789 FALSE, FALSE, TRUE); 04790 04791 if (rep_count == 1) { 04792 gen_opnd(&opnd, init_ir_idx, IR_Tbl_Idx, 04793 IR_LINE_NUM(init_ir_idx), 04794 IR_COL_NUM(init_ir_idx)); 04795 04796 copy_subtree(&opnd, &opnd); 04797 new_init_ir_idx = OPND_IDX(opnd); 04798 SH_IR_IDX(curr_stmt_sh_idx) = new_init_ir_idx; 04799 04800 substring_ir_idx = IR_IDX_L(new_init_ir_idx); 04801 IR_OPR(substring_ir_idx) = Substring_Opr; 04802 04803 /* In the new tree, replace the value's Constant table index */ 04804 /* with the Constant table index of a single blank. */ 04805 04806 il_idx = IR_IDX_R(new_init_ir_idx); 04807 IL_IDX(il_idx) = ntr_const_tbl(CHARACTER_DEFAULT_TYPE, 04808 FALSE, 04809 (long_type *) &single_blank); 04810 04811 /* In the new tree, update the rep count. */ 04812 04813 il_idx = IL_NEXT_LIST_IDX(il_idx); 04814 numeric_value = target_length - value_length; 04815 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04816 numeric_value); 04817 04818 /* In the new tree, set the stride to 8 (bits). */ 04819 04820 il_idx = IL_NEXT_LIST_IDX(il_idx); 04821 numeric_value = 8; 04822 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04823 numeric_value); 04824 04825 /* Pick up common processing below the implied-DO code. */ 04826 } 04827 else { 04828 04829 /* Generate a new Init IR and set up the value list attached */ 04830 /* to it to represent the blank padding. The value list is a */ 04831 /* single IL. The IL points at a Rep_Count IR whose left */ 04832 /* operand is the number of array elements to initialize. */ 04833 /* Its right operand points at another Rep_Count IR that */ 04834 /* represents the number of padding blanks needed. */ 04835 04836 NTR_IR_TBL(new_init_ir_idx); 04837 SH_IR_IDX(curr_stmt_sh_idx) = new_init_ir_idx; 04838 IR_OPR(new_init_ir_idx) = Init_Opr; 04839 IR_TYPE_IDX(new_init_ir_idx) = TYPELESS_DEFAULT_TYPE; 04840 IR_LINE_NUM(new_init_ir_idx) = IR_LINE_NUM(init_ir_idx); 04841 IR_COL_NUM(new_init_ir_idx) = IR_COL_NUM(init_ir_idx); 04842 04843 NTR_IR_LIST_TBL(il_idx); 04844 IR_LIST_CNT_R(new_init_ir_idx) = 1; 04845 IR_FLD_R(new_init_ir_idx) = IL_Tbl_Idx; 04846 IR_IDX_R(new_init_ir_idx) = il_idx; 04847 04848 NTR_IR_TBL(rep_count_ir_idx); 04849 IL_FLD(il_idx) = IR_Tbl_Idx; 04850 IL_IDX(il_idx) = rep_count_ir_idx; 04851 IR_OPR(rep_count_ir_idx) = Rep_Count_Opr; 04852 IR_TYPE_IDX(rep_count_ir_idx) = TYPELESS_DEFAULT_TYPE; 04853 IR_LINE_NUM(rep_count_ir_idx) = IR_LINE_NUM(init_ir_idx); 04854 IR_COL_NUM(rep_count_ir_idx) = IR_COL_NUM(init_ir_idx); 04855 04856 COPY_OPND(IR_OPND_L(rep_count_ir_idx), 04857 IL_OPND(rep_count_il_idx)); 04858 04859 NTR_IR_TBL(ir_idx); 04860 IR_FLD_R(rep_count_ir_idx) = IR_Tbl_Idx; 04861 IR_IDX_R(rep_count_ir_idx) = ir_idx; 04862 IR_OPR(ir_idx) = Rep_Count_Opr; 04863 IR_TYPE_IDX(ir_idx) = TYPELESS_DEFAULT_TYPE; 04864 IR_LINE_NUM(ir_idx) = IR_LINE_NUM(init_ir_idx); 04865 IR_COL_NUM(ir_idx) = IR_COL_NUM(init_ir_idx); 04866 04867 IR_FLD_L(ir_idx) = CN_Tbl_Idx; 04868 numeric_value = target_length - value_length; 04869 IR_IDX_L(ir_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04870 numeric_value); 04871 IR_LINE_NUM_L(ir_idx) = IR_LINE_NUM(init_ir_idx); 04872 IR_COL_NUM_L(ir_idx) = IR_COL_NUM(init_ir_idx); 04873 04874 IR_FLD_R(ir_idx) = CN_Tbl_Idx; 04875 IR_IDX_R(ir_idx) = ntr_const_tbl(CHARACTER_DEFAULT_TYPE, 04876 FALSE, 04877 (long_type *) &single_blank); 04878 IR_LINE_NUM_R(ir_idx) = IR_LINE_NUM(init_ir_idx); 04879 IR_COL_NUM_R(ir_idx) = IR_COL_NUM(init_ir_idx); 04880 04881 /* Generate an implied-DO to loop through the target array */ 04882 /* elements. */ 04883 04884 NTR_IR_TBL(imp_do_ir_idx); 04885 IR_FLD_L(new_init_ir_idx) = IR_Tbl_Idx; 04886 IR_IDX_L(new_init_ir_idx) = imp_do_ir_idx; 04887 IR_OPR(imp_do_ir_idx) = Implied_Do_Opr; 04888 IR_TYPE_IDX(imp_do_ir_idx) = TYPELESS_DEFAULT_TYPE; 04889 IR_LINE_NUM(imp_do_ir_idx) = IR_LINE_NUM(init_ir_idx); 04890 IR_COL_NUM(imp_do_ir_idx) = IR_COL_NUM(init_ir_idx); 04891 04892 /* The 4 IL's attached to the right opnd of the implied-DO IR */ 04893 /* are: */ 04894 /* - implied-DO variable : a temp */ 04895 /* - start value : the value from the IL attached to*/ 04896 /* the Subscript IR in the original */ 04897 /* tree */ 04898 /* - end value : start value + rep count (of array*/ 04899 /* elements) - 1 */ 04900 /* - increment value : 1 */ 04901 04902 temp_idx = gen_compiler_tmp(IR_LINE_NUM(init_ir_idx), 04903 IR_COL_NUM(init_ir_idx), 04904 Priv, TRUE); 04905 AT_SEMANTICS_DONE(temp_idx) = TRUE; 04906 ATD_TYPE_IDX(temp_idx) = INTEGER_DEFAULT_TYPE; 04907 ATD_STOR_BLK_IDX(temp_idx) = SCP_SB_STACK_IDX(curr_scp_idx); 04908 ATD_LCV_IS_CONST(temp_idx) = TRUE; 04909 04910 /* clear the referenced field so that this tmp does */ 04911 /* not get sent to mif. BHJ */ 04912 04913 AT_REFERENCED(temp_idx) = Not_Referenced; 04914 04915 04916 NTR_IR_LIST_TBL(il_idx); 04917 IR_LIST_CNT_R(imp_do_ir_idx) = 1; 04918 IR_FLD_R(imp_do_ir_idx) = IL_Tbl_Idx; 04919 IR_IDX_R(imp_do_ir_idx) = il_idx; 04920 IL_FLD(il_idx) = AT_Tbl_Idx; 04921 IL_IDX(il_idx) = temp_idx; 04922 IL_LINE_NUM(il_idx) = stmt_start_line; 04923 IL_COL_NUM(il_idx) = stmt_start_col; 04924 04925 /* Produce the ILs that will hold the implied-DO start, end, */ 04926 /* and increment values. They get filled differently depending*/ 04927 /* on whether the implied-DO is being generated due to a whole */ 04928 /* array or a section initialization. */ 04929 04930 NTR_IR_LIST_TBL(start_il_idx); 04931 IR_LIST_CNT_R(imp_do_ir_idx) = 2; 04932 IL_NEXT_LIST_IDX(il_idx) = start_il_idx; 04933 IL_PREV_LIST_IDX(start_il_idx) = il_idx; 04934 04935 NTR_IR_LIST_TBL(end_il_idx); 04936 IR_LIST_CNT_R(imp_do_ir_idx) = 3; 04937 IL_NEXT_LIST_IDX(start_il_idx) = end_il_idx; 04938 IL_PREV_LIST_IDX(end_il_idx) = start_il_idx; 04939 04940 NTR_IR_LIST_TBL(inc_il_idx); 04941 IR_LIST_CNT_R(imp_do_ir_idx) = 4; 04942 IL_NEXT_LIST_IDX(end_il_idx) = inc_il_idx; 04943 IL_PREV_LIST_IDX(inc_il_idx) = end_il_idx; 04944 04945 if (section_start_value == 0) { 04946 ir_idx = IR_IDX_L(substring_ir_idx); 04947 04948 while (IR_OPR(ir_idx) != Subscript_Opr) { 04949 ir_idx = IR_IDX_L(ir_idx); 04950 } 04951 04952 COPY_OPND(IL_OPND(start_il_idx), IL_OPND(IR_IDX_R(ir_idx))); 04953 04954 numeric_value = CN_INT_TO_C(IL_IDX(start_il_idx))+rep_count-1; 04955 04956 IL_FLD(end_il_idx) = CN_Tbl_Idx; 04957 IL_IDX(end_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04958 numeric_value); 04959 IL_LINE_NUM(end_il_idx) = stmt_start_line; 04960 IL_COL_NUM(end_il_idx) = stmt_start_col; 04961 04962 IL_FLD(inc_il_idx) = CN_Tbl_Idx; 04963 IL_IDX(inc_il_idx) = CN_INTEGER_ONE_IDX; 04964 IL_LINE_NUM(inc_il_idx) = stmt_start_line; 04965 IL_COL_NUM(inc_il_idx) = stmt_start_col; 04966 } 04967 else { 04968 04969 /* We're processing a section reference. */ 04970 /* section_start_value and section_inc_value are used for */ 04971 /* the loop start and inc values. The loop end value is */ 04972 /* calculated. */ 04973 04974 IL_FLD(start_il_idx) = CN_Tbl_Idx; 04975 IL_IDX(start_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04976 section_start_value); 04977 IL_LINE_NUM(start_il_idx) = stmt_start_line; 04978 IL_COL_NUM(start_il_idx) = stmt_start_col; 04979 04980 numeric_value = 04981 section_start_value + (rep_count - 1)*section_inc_value; 04982 04983 IL_FLD(end_il_idx) = CN_Tbl_Idx; 04984 IL_IDX(end_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04985 numeric_value); 04986 IL_LINE_NUM(end_il_idx) = stmt_start_line; 04987 IL_COL_NUM(end_il_idx) = stmt_start_col; 04988 04989 IL_FLD(inc_il_idx) = CN_Tbl_Idx; 04990 IL_IDX(inc_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 04991 section_inc_value); 04992 IL_LINE_NUM(inc_il_idx) = stmt_start_line; 04993 IL_COL_NUM(inc_il_idx) = stmt_start_col; 04994 } 04995 04996 /* Make a copy of the original reference IR tree and attach it */ 04997 /* to the left operand of the implied-DO IR via an IL. */ 04998 04999 NTR_IR_LIST_TBL(il_idx); 05000 IR_LIST_CNT_L(imp_do_ir_idx) = 1; 05001 IR_FLD_L(imp_do_ir_idx) = IL_Tbl_Idx; 05002 IR_IDX_L(imp_do_ir_idx) = il_idx; 05003 05004 copy_subtree(&IR_OPND_L(init_ir_idx), &opnd); 05005 COPY_OPND(IL_OPND(il_idx), opnd); 05006 05007 substring_ir_idx = IL_IDX(il_idx); 05008 IR_OPR(substring_ir_idx) = Substring_Opr; 05009 } 05010 05011 IR_OPR(IR_IDX_L(init_ir_idx)) = Substring_Opr; 05012 05013 /* In the original tree, replace the substring end value. */ 05014 05015 numeric_value = original_start_val + value_length - 1; 05016 IL_IDX(original_end_il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 05017 numeric_value); 05018 05019 /* In the original tree, update the substring length to be the */ 05020 /* length of the initialization value. */ 05021 05022 il_idx = IL_NEXT_LIST_IDX(original_end_il_idx); 05023 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 05024 value_length); 05025 05026 /* In the new tree, update the substring start value, end value */ 05027 /* (end value == start value), and length. */ 05028 05029 ++numeric_value; 05030 05031 il_idx = IR_IDX_R(substring_ir_idx); 05032 IL_IDX(il_idx) = C_INT_TO_CN(CG_INTEGER_DEFAULT_TYPE, 05033 numeric_value); 05034 05035 il_idx = IL_NEXT_LIST_IDX(il_idx); 05036 IL_IDX(il_idx) = IL_IDX(IL_PREV_LIST_IDX(il_idx)); 05037 05038 il_idx = IL_NEXT_LIST_IDX(il_idx); 05039 IL_IDX(il_idx) = CN_INTEGER_ONE_IDX; 05040 05041 if (rep_count > 1) { 05042 05043 /* An implied-DO IR was generated. Change the target's */ 05044 /* subscript to point at the implied-DO temp. */ 05045 05046 ir_idx = IR_IDX_L(substring_ir_idx); 05047 05048 while (IR_OPR(ir_idx) != Subscript_Opr) { 05049 ir_idx = IR_IDX_L(ir_idx); 05050 } 05051 05052 IL_FLD(IR_IDX_R(ir_idx)) = AT_Tbl_Idx; 05053 IL_IDX(IR_IDX_R(ir_idx)) = temp_idx; 05054 IL_LINE_NUM(IR_IDX_R(ir_idx)) = stmt_start_line; 05055 IL_COL_NUM(IR_IDX_R(ir_idx)) = stmt_start_col; 05056 05057 } 05058 } 05059 } 05060 } 05061 else { 05062 05063 /* Future optimization: If the target is zero-length, can we just eat */ 05064 /* the current value and eliminate the DATA SH and IR? */ 05065 05066 } 05067 05068 EXIT: 05069 05070 TRACE (Func_Exit, "adjust_char_value_len", NULL); 05071 05072 return; 05073 05074 } /* adjust_char_value_len */ 05075 05076 05077 /******************************************************************************\ 05078 |* *| 05079 |* Description: *| 05080 |* Climb the DATA target reference tree to find all subscript expressions*| 05081 |* that were too complicated for expr_semantics to fold. Fold them now. *| 05082 |* *| 05083 |* Input parameters: *| 05084 |* NONE *| 05085 |* *| 05086 |* Output parameters: *| 05087 |* NONE *| 05088 |* *| 05089 |* Returns: *| 05090 |* NONE *| 05091 |* *| 05092 \******************************************************************************/ 05093 05094 static void fold_all_subscripts(opnd_type *opnd) 05095 { 05096 int attr_idx; 05097 expr_arg_type expr_desc; 05098 int i; 05099 int il_idx; 05100 int ir_idx; 05101 opnd_type local_opnd; 05102 opnd_type my_opnd; 05103 05104 05105 TRACE (Func_Entry, "fold_all_subscripts", NULL); 05106 05107 COPY_OPND(local_opnd, (*opnd)); 05108 05109 expr_desc = init_exp_desc; 05110 expr_desc.type = Integer; 05111 expr_desc.type_idx = INTEGER_DEFAULT_TYPE; 05112 expr_desc.linear_type = INTEGER_DEFAULT_TYPE; 05113 05114 while (OPND_FLD(local_opnd) == IR_Tbl_Idx) { 05115 05116 ir_idx = OPND_IDX(local_opnd); 05117 05118 switch (IR_OPR(ir_idx)) { 05119 05120 case Subscript_Opr: 05121 05122 attr_idx = (IR_FLD_L(ir_idx) == AT_Tbl_Idx) ? 05123 IR_IDX_L(ir_idx) : 05124 IR_IDX_R(IR_IDX_L(ir_idx)); 05125 05126 il_idx = IR_IDX_R(ir_idx); 05127 05128 for (i = 1; i <= IR_LIST_CNT_R(ir_idx); ++i) { 05129 05130 # ifdef COARRAY_FORTRAN 05131 if (IL_PE_SUBSCRIPT(il_idx)) { 05132 continue; 05133 } 05134 # endif 05135 05136 if (IL_FLD(il_idx) == IR_Tbl_Idx) { 05137 COPY_OPND(my_opnd, IL_OPND(il_idx)); 05138 fold_all_subscripts(&my_opnd); 05139 05140 if (IL_FLD(il_idx) == IR_Tbl_Idx) { 05141 05142 if (fold_aggragate_expression(&my_opnd, 05143 &expr_desc, 05144 TRUE)) { 05145 COPY_OPND(IL_OPND(il_idx), my_opnd); 05146 } 05147 else { 05148 PRINTMSG(IR_LINE_NUM(IL_IDX(il_idx)), 05149 861, 05150 Internal, 05151 IR_COL_NUM(IL_IDX(il_idx)), 05152 "object semantics"); 05153 } 05154 } 05155 } 05156 05157 if (fold_relationals(IL_IDX(il_idx), 05158 BD_LB_IDX(ATD_ARRAY_IDX(attr_idx), i), 05159 Lt_Opr)) { 05160 PRINTMSG(IL_LINE_NUM(il_idx), 05161 831, 05162 Error, 05163 IL_COL_NUM(il_idx)); 05164 } 05165 05166 if (fold_relationals(IL_IDX(il_idx), 05167 BD_UB_IDX(ATD_ARRAY_IDX(attr_idx), i), 05168 Gt_Opr)) { 05169 PRINTMSG(IL_LINE_NUM(il_idx), 05170 996, 05171 Error, 05172 IL_COL_NUM(il_idx)); 05173 } 05174 05175 il_idx = IL_NEXT_LIST_IDX(il_idx); 05176 } 05177 05178 COPY_OPND(local_opnd, IR_OPND_L(ir_idx)); 05179 05180 break; 05181 05182 case Struct_Opr: 05183 case Whole_Substring_Opr: 05184 case Substring_Opr: 05185 COPY_OPND(local_opnd, IR_OPND_L(ir_idx)); 05186 break; 05187 05188 default: 05189 goto EXIT; 05190 } 05191 } 05192 05193 EXIT: 05194 05195 TRACE (Func_Exit, "fold_all_subscripts", NULL); 05196 05197 return; 05198 05199 } /* fold_all_subscripts */ 05200 05201 05202 /******************************************************************************\ 05203 |* *| 05204 |* Description: *| 05205 |* When a long hollerith is broken up between data targets, the rest of *| 05206 |* the constant is entered back into the constant table. It must be *| 05207 |* entered as hollerith, so this wrapper routine is needed. *| 05208 |* *| 05209 |* Input parameters: *| 05210 |* NONE *| 05211 |* *| 05212 |* Output parameters: *| 05213 |* NONE *| 05214 |* *| 05215 |* Returns: *| 05216 |* NOTHING *| 05217 |* *| 05218 \******************************************************************************/ 05219 # if 0 05220 05221 static int reenter_const_as_hollerith(int value_idx, 05222 int offset, 05223 int type_idx, 05224 holler_type hollerith_type) 05225 05226 { 05227 int cn_idx; 05228 long64 i; 05229 long64 words; 05230 05231 TRACE (Func_Entry, "reenter_const_as_hollerith", NULL); 05232 05233 cn_idx = ntr_const_tbl(type_idx, 05234 (TYP_TYPE(type_idx) == Character ? TRUE : FALSE), 05235 NULL); 05236 05237 if (TYP_TYPE(type_idx) == Typeless) { 05238 words = TARGET_BITS_TO_WORDS(TYP_BIT_LEN(type_idx)); 05239 } 05240 else if (TYP_TYPE(type_idx) == Character) { 05241 words = TARGET_BYTES_TO_WORDS(CN_INT_TO_C(TYP_IDX(type_idx))); 05242 } 05243 05244 for (i = 0; i < words; i++) { 05245 CP_CONSTANT(CN_POOL_IDX(cn_idx) + i) = 05246 CP_CONSTANT(CN_POOL_IDX(value_idx) + offset + i); 05247 } 05248 05249 CN_HOLLERITH_TYPE(cn_idx) = hollerith_type; 05250 05251 TRACE (Func_Exit, "reenter_const_as_hollerith", NULL); 05252 05253 return(cn_idx); 05254 05255 } /* reenter_const_as_hollerith */ 05256 05257 # endif 05258 05259 05260 /******************************************************************************\ 05261 |* *| 05262 |* Description: *| 05263 |* This procedure performs semantic analysis on the data-stmt-repeat *| 05264 |* *| 05265 |* Input parameters: *| 05266 |* repeat_ir_idx -> IR index of parsed repeat. *| 05267 |* *| 05268 |* Output parameters: *| 05269 |* NONE *| 05270 |* *| 05271 |* Returns: *| 05272 |* NONE *| 05273 |* *| 05274 \******************************************************************************/ 05275 05276 void data_repeat_semantics(int repeat_ir_idx) 05277 05278 { 05279 int column; 05280 expr_arg_type expr_desc; 05281 int line; 05282 int ok = TRUE; 05283 opnd_type opnd; 05284 int save_attr = NULL_IDX; 05285 expr_mode_type save_expr_mode = expr_mode; 05286 05287 05288 TRACE (Func_Entry, "data_repeat_semantics", NULL); 05289 05290 COPY_OPND(opnd, IR_OPND_L(repeat_ir_idx)); 05291 05292 expr_desc.rank = 0; 05293 xref_state = CIF_Symbol_Reference; 05294 05295 /* Any subscripts must be initialization expressions */ 05296 05297 expr_mode = Initialization_Expr; 05298 05299 switch (OPND_FLD(opnd)) { 05300 05301 case IR_Tbl_Idx: 05302 05303 if (IR_OPR(OPND_IDX(opnd)) == Paren_Opr) { 05304 05305 if (IR_FLD_L(OPND_IDX(opnd)) == AT_Tbl_Idx && 05306 AT_OBJ_CLASS(IR_IDX_L(OPND_IDX(opnd))) == Data_Obj) { 05307 save_attr = IR_IDX_L(OPND_IDX(opnd)); 05308 ATD_PARENT_OBJECT(save_attr) = TRUE; 05309 } 05310 } 05311 break; 05312 05313 case AT_Tbl_Idx: 05314 05315 if (AT_OBJ_CLASS(OPND_IDX(opnd)) == Data_Obj) { 05316 save_attr = OPND_IDX(opnd); 05317 ATD_PARENT_OBJECT(save_attr) = TRUE; 05318 } 05319 } 05320 05321 05322 if (expr_semantics(&opnd, &expr_desc)) { 05323 find_opnd_line_and_column(&opnd, &line, &column); 05324 05325 /* If the rep factor is represented by an Attr table entry, */ 05326 /* the only thing it can be is a scalar named constant. */ 05327 05328 switch (OPND_FLD(opnd)) { 05329 case CN_Tbl_Idx: /* Great - ok */ 05330 break; 05331 05332 case AT_Tbl_Idx: 05333 ok = FALSE; 05334 PRINTMSG(line, 677, Error, column); /* Must be a constant */ 05335 break; 05336 05337 default: 05338 ok = FALSE; 05339 PRINTMSG(line, 678, Error, column); /* Must be a int scalar constant */ 05340 break; 05341 } 05342 05343 if (!ok) { 05344 05345 /* Intentionally blank */ 05346 05347 } 05348 else if (expr_desc.type != Integer && expr_desc.type != Typeless) { 05349 PRINTMSG(line, 678, Error, column); 05350 } 05351 else if (expr_desc.linear_type == Long_Typeless) { 05352 PRINTMSG(line, 1133, Error, column); 05353 } 05354 else if (expr_desc.rank > 0) { 05355 PRINTMSG(line, 678, Error, column); 05356 } 05357 else if (expr_desc.linear_type == Short_Typeless_Const) { 05358 OPND_IDX(opnd) = cast_typeless_constant(OPND_IDX(opnd), 05359 INTEGER_DEFAULT_TYPE, 05360 line, 05361 column); 05362 } 05363 } 05364 05365 COPY_OPND(IR_OPND_L(repeat_ir_idx), opnd); 05366 05367 expr_mode = save_expr_mode; 05368 05369 if (save_attr != NULL_IDX) { 05370 ATD_PARENT_OBJECT(save_attr) = FALSE; 05371 } 05372 05373 TRACE (Func_Exit, "data_repeat_semantics", NULL); 05374 05375 return; 05376 05377 } /* data_repeat_semantics */ 05378 05379 05380 /******************************************************************************\ 05381 |* *| 05382 |* Description: *| 05383 |* This procedure performs semantic analysis on the data-stmt-constant *| 05384 |* *| 05385 |* Input parameters: *| 05386 |* const_ir_idx -> IR index of parsed constant. *| 05387 |* *| 05388 |* Output parameters: *| 05389 |* NONE *| 05390 |* *| 05391 |* Returns: *| 05392 |* NONE *| 05393 |* *| 05394 \******************************************************************************/ 05395 05396 void constant_value_semantics(opnd_type *opnd, 05397 int uopr_ir_idx) 05398 05399 { 05400 int boz_const_col_num; 05401 int boz_const_line_num = 0; 05402 int column; 05403 expr_arg_type expr_desc; 05404 boolean have_null = FALSE; 05405 int line; 05406 int save_attr = NULL_IDX; 05407 expr_mode_type save_expr_mode = expr_mode; 05408 05409 05410 TRACE (Func_Entry, "constant_value_semantics", NULL); 05411 05412 switch (OPND_FLD((*opnd))) { 05413 case IR_Tbl_Idx: 05414 find_opnd_line_and_column(opnd, &line, &column); 05415 05416 if (IR_OPR(OPND_IDX((*opnd))) == Call_Opr && 05417 AT_IS_INTRIN(IR_IDX_L(OPND_IDX((*opnd)))) && 05418 strcmp(AT_OBJ_NAME_PTR(IR_IDX_L(OPND_IDX((*opnd)))), "NULL") == 0) { 05419 have_null = TRUE; 05420 05421 if (IR_IDX_R(OPND_IDX((*opnd))) != NULL_IDX) { /* MOLD is specified */ 05422 PRINTMSG(line, 1573, Error, column); 05423 IR_OPND_R(OPND_IDX((*opnd))) = null_opnd; /* Clear the argument */ 05424 } 05425 } 05426 05427 if (IR_OPR(OPND_IDX((*opnd))) == Paren_Opr) { 05428 05429 if (IR_FLD_L(OPND_IDX((*opnd))) == AT_Tbl_Idx && 05430 AT_OBJ_CLASS(IR_IDX_L(OPND_IDX((*opnd)))) == Data_Obj) { 05431 save_attr = IR_IDX_L(OPND_IDX((*opnd))); 05432 ATD_PARENT_OBJECT(save_attr) = TRUE; 05433 } 05434 } 05435 05436 if (uopr_ir_idx != NULL_IDX) { 05437 05438 /* expr_semantics treats a unary minus on a BOZ constant as */ 05439 /* an expression which means the column pointer comes back */ 05440 /* pointing to the minus sign rather than to the BOZ */ 05441 /* constant. Save the line and column here and use them in */ 05442 /* the result opnd below. */ 05443 05444 boz_const_line_num = line; 05445 boz_const_col_num = column; 05446 05447 COPY_OPND(IR_OPND_L(uopr_ir_idx), (*opnd)); 05448 OPND_FLD((*opnd)) = IR_Tbl_Idx; 05449 OPND_IDX((*opnd)) = uopr_ir_idx; 05450 } 05451 break; 05452 05453 case AT_Tbl_Idx: 05454 05455 if (AT_OBJ_CLASS(OPND_IDX((*opnd))) == Data_Obj) { 05456 save_attr = OPND_IDX((*opnd)); 05457 ATD_PARENT_OBJECT(save_attr) = TRUE; 05458 } 05459 05460 if (uopr_ir_idx != NULL_IDX) { 05461 PRINTMSG(IR_LINE_NUM(uopr_ir_idx), 958, Error, 05462 IR_COL_NUM(uopr_ir_idx)); 05463 } 05464 break; 05465 05466 case CN_Tbl_Idx: 05467 05468 if (uopr_ir_idx != NULL_IDX) { 05469 05470 if (CN_BOZ_CONSTANT(OPND_IDX((*opnd)))) { 05471 PRINTMSG(IR_LINE_NUM(uopr_ir_idx), 957, Ansi, 05472 IR_COL_NUM(uopr_ir_idx)); 05473 } 05474 else if (TYP_TYPE(CN_TYPE_IDX(OPND_IDX((*opnd)))) != Integer && 05475 TYP_TYPE(CN_TYPE_IDX(OPND_IDX((*opnd)))) != Real && 05476 ! CN_BOOLEAN_CONSTANT(OPND_IDX((*opnd)))) { 05477 05478 /* A sign is only permitted for integer or real literal constants */ 05479 05480 PRINTMSG(IR_LINE_NUM(uopr_ir_idx), 958, Error, 05481 IR_COL_NUM(uopr_ir_idx)); 05482 } 05483 COPY_OPND(IR_OPND_L(uopr_ir_idx), (*opnd)); 05484 OPND_FLD((*opnd)) = IR_Tbl_Idx; 05485 OPND_IDX((*opnd)) = uopr_ir_idx; 05486 } 05487 break; 05488 } /* end switch */ 05489 05490 /* Any subscripts must be initialization expressions */ 05491 05492 expr_desc.rank = 0; 05493 expr_mode = Initialization_Expr; 05494 xref_state = CIF_Symbol_Reference; 05495 05496 /* set comp_gen_expr to TRUE. This forces the fold of REAL */ 05497 /* constant expressions. When -Oieeeconform is specified, */ 05498 /* the folding of Real and Complex expressions is prevented. */ 05499 05500 comp_gen_expr = TRUE; 05501 05502 if (expr_semantics(opnd, &expr_desc)) { 05503 find_opnd_line_and_column(opnd, &line, &column); 05504 05505 switch (OPND_FLD((*opnd))) { 05506 case CN_Tbl_Idx: 05507 05508 if (boz_const_line_num != 0) { 05509 OPND_LINE_NUM((*opnd)) = boz_const_line_num; 05510 OPND_COL_NUM((*opnd)) = boz_const_col_num; 05511 line = boz_const_line_num; 05512 column = boz_const_col_num; 05513 } 05514 05515 break; 05516 05517 case AT_Tbl_Idx: 05518 05519 if (AT_OBJ_CLASS(OPND_IDX((*opnd))) == Data_Obj && 05520 ATD_CLASS(OPND_IDX((*opnd))) == Compiler_Tmp && 05521 ATD_FLD(OPND_IDX((*opnd))) == CN_Tbl_Idx) { 05522 05523 if (!expr_desc.constant) { 05524 PRINTMSG(line, 906, Error, column); 05525 *opnd = null_opnd; 05526 } 05527 } 05528 else { 05529 PRINTMSG(line, 1101, Error, column); 05530 } 05531 break; 05532 05533 case IR_Tbl_Idx: 05534 05535 if (!have_null) { 05536 PRINTMSG(line, 1648, Error, column); 05537 *opnd = null_opnd; 05538 } 05539 break; 05540 05541 } /* End switch */ 05542 } 05543 05544 if (save_attr != NULL_IDX) { 05545 ATD_PARENT_OBJECT(save_attr) = FALSE; 05546 } 05547 05548 /* reset comp_gen_expr to FALSE. end of */ 05549 /* compiler generated expression */ 05550 05551 comp_gen_expr = FALSE; 05552 expr_mode = save_expr_mode; 05553 05554 TRACE (Func_Exit, "constant_value_semantics", NULL); 05555 05556 return; 05557 05558 } /* constant_value_semantics */