00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 static const char *source_file = __FILE__;
00059
00060 #ifdef _KEEP_RCS_ID
00061 static char *rcs_id = "$Source: /home/bos/bk/kpro64-pending/crayf90/sgi/SCCS/s.cwh_data.cxx $ $Revision: 1.7 $";
00062 #endif
00063
00064
00065
00066 #include "defs.h"
00067 #include "glob.h"
00068 #include "stab.h"
00069 #include "strtab.h"
00070 #include "erfe90.h"
00071 #include "errors.h"
00072 #include "targ_const.h"
00073 #include "config_targ.h"
00074 #include "const.h"
00075 #include "wn.h"
00076 #include "wn_util.h"
00077 #include "irbdata.h"
00078 #include "cxx_memory.h"
00079
00080
00081
00082 #include "i_cvrt.h"
00083
00084
00085
00086 #include "cwh_defines.h"
00087 #include "cwh_types.h"
00088 #include "cwh_addr.h"
00089 #include "cwh_stmt.h"
00090 #include "cwh_preg.h"
00091 #include "cwh_stab.h"
00092 #include "cwh_auxst.h"
00093 #include "cwh_stk.h"
00094 #include "cwh_expr.h"
00095 #include "cwh_data.h"
00096
00097 #include "cwh_data.i"
00098
00099
00100
00101
00102
00103
00104
00105 extern void
00106 fei_static_base(INTPTR sym_idx)
00107 {
00108 STB_pkt *p ;
00109 ST *base;
00110 INT64 offset;
00111 BOOL init_common_or_module;
00112
00113 p = cast_to_STB(sym_idx);
00114 DevAssert((p->form == is_ST),("Odd object ref"));
00115
00116 current_st = (ST *) p->item;
00117 orig_st = current_st;
00118 current_ty = ST_type(current_st);
00119 current_pos = 0;
00120 array_pos = 0;
00121 init_common_or_module = FALSE;
00122 offset = 0;
00123 base = current_st;
00124
00125 while (ST_base(base) != base) {
00126 offset += ST_ofst(base);
00127 base = ST_base(base);
00128 }
00129
00130
00131
00132 if ((ST_sclass(base) == SCLASS_DGLOBAL) ||
00133 (ST_sclass(base) == SCLASS_COMMON)) {
00134
00135
00136
00137
00138
00139
00140 Set_ST_sclass(base, SCLASS_DGLOBAL);
00141
00142 cwh_data_set_init_flag(base,l_COMLIST);
00143
00144 current_st = base;
00145 current_pos = offset;
00146 init_common_or_module = TRUE;
00147
00148 } else if (base != current_st) {
00149
00150
00151
00152 cwh_data_set_init_flag(base,l_EQVLIST);
00153 current_st = base;
00154 current_pos = offset;
00155 init_common_or_module = TRUE;
00156 }
00157
00158 #ifdef KEY // bug 13276
00159 if (ST_sclass(base) == SCLASS_FORMAL_REF)
00160 return;
00161 #endif
00162
00163 Set_ST_is_initialized(current_st);
00164
00165 if (TY_kind(current_ty) == KIND_ARRAY) {
00166 is_struct_or_array = TRUE;
00167
00168 current_bytesize = TY_size(TY_etype(current_ty));
00169 } else {
00170 if (TY_kind(current_ty) == KIND_STRUCT) {
00171 is_struct_or_array = TRUE;
00172 } else {
00173 is_struct_or_array = FALSE;
00174 }
00175 current_bytesize = TY_size(current_ty);
00176 }
00177 if (init_common_or_module) {
00178 is_struct_or_array = TRUE;
00179 }
00180
00181 current_data_info = ST_auxst_data_info(current_st);
00182 if (!current_data_info) {
00183 current_data_info = CXX_NEW(data_info_s(current_st), Malloc_Mem_Pool);
00184 Set_ST_auxst_data_info(current_st,current_data_info);
00185 }
00186 current_inito = current_data_info->Get_Inito();
00187 return;
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 extern void
00203 fei_static_subscripts( INT64 static_subscripts[STATIC_SUBSCRIPT_SIZE] )
00204 {
00205 INT i;
00206 INT rank;
00207 INT64 offset;
00208
00209
00210 ARB_HANDLE arb;
00211
00212
00213 DevAssert((TY_kind(current_ty)==KIND_ARRAY),("Not an array ty"));
00214 rank = TY_AR_ndims(Ty_Table[current_ty]);
00215 offset = 0;
00216
00217 arb = TY_arb(Ty_Table[current_ty])[rank - 1];
00218
00219 for (i=rank-1; i >= 0; i--) {
00220 offset += (static_subscripts[i] -
00221 ARB_lbnd_val(arb))*
00222 ARB_stride_val(arb);
00223 arb = arb[-1];
00224 }
00225
00226 array_pos += offset;
00227 return;
00228 }
00229
00230
00231
00232
00233
00234
00235 extern void
00236 fei_static_substr( INT32 start)
00237 {
00238
00239
00240
00241 array_pos += start - 1;
00242 return;
00243 }
00244
00245
00246
00247
00248
00249
00250 extern
00251 void fei_static_member (INTPTR st_idx )
00252 {
00253 FLD_IDX fld ;
00254
00255 fld = (FLD_IDX ) (INTPTR)cast_to_void(st_idx);
00256
00257 FLD_HANDLE f (fld);
00258 DevAssert((FLD_bofst(f) == 0),("Can't handle non 0 bofst"));
00259 current_pos += FLD_ofst(f);
00260
00261 current_ty = FLD_type(f);
00262 if (TY_kind(current_ty) == KIND_ARRAY) {
00263 current_bytesize = TY_size(TY_etype(current_ty));
00264 } else {
00265 current_bytesize = TY_size(current_ty);
00266 }
00267 }
00268
00269
00270 static INT32 get_TCON_size(TCON_IDX tc)
00271 {
00272 TYPE_ID t;
00273 INT32 esize;
00274 if (tc == 0) {
00275
00276
00277
00278 esize = Pointer_Size;
00279 } else {
00280 TCON& tcon = Tcon_Table[tc];
00281 t = TCON_ty(tcon);
00282 if (t == MTYPE_STR) {
00283 esize = Targ_String_Length(tcon);
00284 } else {
00285 esize = MTYPE_size_min(t)/8;
00286 }
00287 }
00288 return (esize);
00289 }
00290
00291
00292 static TCON_IDX TCON_from_stack(void)
00293 {
00294 #ifdef KEY
00295 TCON_IDX tcp = 0;
00296 #else
00297 TCON_IDX tcp;
00298 #endif
00299 ST *cst;
00300 WN *slen;
00301 WN *w;
00302 TY_IDX ty;
00303
00304 switch (cwh_stk_get_class()) {
00305 case STR_item:
00306 cwh_stk_pop_STR();
00307 slen = cwh_stk_pop_WN();
00308 WN_DELETE_Tree(slen);
00309 cst = cwh_stk_pop_ST();
00310 tcp = ST_tcon(cst);
00311 break;
00312
00313 case PCONST_item:
00314 cst = (ST *) cwh_stk_pop_PCONST();
00315 tcp = ST_tcon(cst);
00316 break;
00317
00318 case WN_item:
00319 case WN_item_whole_array:
00320 ty = cwh_stk_get_TY();
00321 w = cwh_stk_pop_WN();
00322 if (WNOPR(w) == OPR_INTCONST) {
00323 if (ty) {
00324 tcp = Enter_tcon(Host_To_Targ(TY_mtype(ty),WN_const_val(w)));
00325 } else {
00326 tcp = Enter_tcon(Host_To_Targ(WN_rtype(w),WN_const_val(w)));
00327 }
00328 } else if (WNOPR(w) == OPR_CONST) {
00329 tcp = Enter_tcon(Const_Val(w));
00330 } else {
00331 DevAssert((0),("not a const node"));
00332 }
00333 WN_Delete(w);
00334 break;
00335 }
00336 return (tcp);
00337 }
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350 static
00351 b_and_o get_base_and_offset(WN *wn)
00352 {
00353 b_and_o r,t1,t2;
00354 INT64 offset;
00355 INT ndim,i;
00356 INT64 esize;
00357 INT64 smult;
00358 WN *adim, *aindex;
00359 INT64 adim_val,aindex_val;
00360
00361 r.base = NULL;
00362 r.offset = 0;
00363
00364 switch (WN_operator(wn)) {
00365 case OPR_ADD:
00366 t1 = get_base_and_offset(WN_kid0(wn));
00367 t2 = get_base_and_offset(WN_kid1(wn));
00368 r.offset = t1.offset + t2.offset;
00369 if (t1.base) {
00370 r.base = t1.base;
00371 } else if (t2.base) {
00372 r.base = t2.base;
00373 } else {
00374 DevAssert((0),("No base found"));
00375 }
00376 break;
00377
00378 case OPR_SUB:
00379 t1 = get_base_and_offset(WN_kid0(wn));
00380 t2 = get_base_and_offset(WN_kid1(wn));
00381 r.offset = t1.offset - t2.offset;
00382 if (t1.base) {
00383 r.base = t1.base;
00384 } else {
00385 DevAssert((0),("No base or bad base"));
00386 }
00387 break;
00388
00389 case OPR_INTCONST:
00390 r.base = NULL;
00391 r.offset = WN_const_val(wn);
00392 break;
00393
00394 case OPR_LDA:
00395 r.base = WN_st(wn);
00396 r.offset = WN_offset(wn);
00397
00398 # if (defined(linux) || defined(BUILD_OS_DARWIN))
00399
00400 while (ST_base(r.base) != r.base) {
00401 r.offset += ST_ofst(r.base);
00402 r.base = ST_base(r.base);
00403 }
00404 # endif
00405 break;
00406
00407 case OPR_ARRAYEXP:
00408 r = get_base_and_offset(WN_kid0(wn));
00409 break;
00410
00411 case OPR_ARRAY:
00412 case OPR_ARRSECTION:
00413
00414 r = get_base_and_offset(WN_kid0(wn));
00415 esize = WN_element_size(wn);
00416 ndim = WN_num_dim(wn);
00417 offset = 0;
00418
00419 smult = 1;
00420 for (i = ndim-1; i >= 0; i--) {
00421 aindex = WN_array_index(wn,i);
00422 adim = WN_array_dim(wn,i);
00423 DevAssert((WN_operator(aindex)==OPR_INTCONST),("Non-constant index"));
00424 DevAssert((WN_operator(adim)==OPR_INTCONST),("Non-constant dim"));
00425 aindex_val = WN_const_val(aindex);
00426 adim_val = WN_const_val(adim);
00427 if (esize < 0) {
00428
00429 offset += aindex_val * adim_val;
00430 } else {
00431
00432 offset += aindex_val * smult;
00433 smult *= adim_val;
00434 }
00435 }
00436
00437
00438 if (esize > 0) {
00439 offset *= esize;
00440 } else {
00441 offset *= (-esize);
00442 }
00443
00444 r.offset += offset;
00445 break;
00446
00447 case OPR_COMMA:
00448 r = get_base_and_offset(WN_kid1(wn));
00449 break;
00450
00451 default:
00452
00453 DevAssert((0),("strange offset expression"));
00454 break;
00455 }
00456 return (r);
00457 }
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 static INITV_IDX create_initv(INITO_IDX ino, INT32 repeat, TCON_IDX tc,
00473 b_and_o *bo)
00474 {
00475 if (tc) {
00476 return (Irb_Init_Val(ino, 0, repeat, tc));
00477 } else {
00478 return (Irb_Init_Symoff(ino, 0, repeat, bo->base, bo->offset));
00479 }
00480 }
00481
00482 static
00483 void static_simple_init_helper (INT64 dup_count,
00484 INT64 stride,
00485 TCON_IDX value,
00486 b_and_o *bo)
00487
00488 {
00489 INT64 byte_stride;
00490 INT32 init_size;
00491 INT64 i;
00492 INT64 element_offset;
00493
00494 if (!is_struct_or_array) {
00495 create_initv(current_inito,1,value, bo);
00496 return;
00497 }
00498
00499 if (dup_count == 0) return;
00500 element_offset = array_pos;
00501
00502 byte_stride = stride/8;
00503 if (byte_stride < 0) {
00504
00505 element_offset += byte_stride*(dup_count-1);
00506 byte_stride = -byte_stride;
00507 }
00508
00509 init_size = get_TCON_size(value);
00510 if (byte_stride == 0) byte_stride = init_size;
00511
00512
00513 current_data_info->Reserve(dup_count);
00514 for (i=0; i < dup_count; i++) {
00515 current_data_info->Add_Data_Element(current_pos+element_offset,value,bo,init_size);
00516 element_offset += byte_stride;
00517 }
00518
00519 return;
00520 }
00521
00522
00523 extern
00524 void fei_static_simple_init (INT64 dup_count,
00525 INT64 stride,
00526 INT32 ignore_types,
00527 INT32 string_literal)
00528
00529 {
00530 TCON_IDX value;
00531 value = TCON_from_stack();
00532 static_simple_init_helper(dup_count,stride,value,NULL);
00533 }
00534
00535
00536
00537
00538
00539
00540
00541 extern
00542 void fei_static_next_simple_init ( INT64 bit_increment,
00543 INT64 dup_count,
00544 INT64 init_offset,
00545 INT32 string_literal )
00546 {
00547 array_pos += (init_offset >> 3);
00548 fei_static_simple_init(dup_count,bit_increment,0,string_literal);
00549 }
00550
00551
00552
00553
00554
00555
00556
00557 extern
00558 void fei_static_simple_reloc_init ( INT64 bit_offset,
00559 INT64 dup_count,
00560 INT64 stride,
00561 INT64 bit_size,
00562 INT32 ignore_types )
00563 {
00564 WN *addr;
00565 b_and_o value;
00566
00567
00568
00569 addr = cwh_expr_operand(NULL);
00570 value = get_base_and_offset(addr);
00571 WN_DELETE_Tree(addr);
00572 DevAssert((value.base),("NULL base found"));
00573 cwh_expr_set_flags(value.base,f_T_SAVED);
00574
00575 static_simple_init_helper(dup_count,stride,0,&value);
00576 }
00577
00578
00579
00580
00581
00582
00583
00584
00585 static void emit_inits_for_symbol(ST_IDX st_idx, ST *st)
00586 {
00587 DATA_INFO d;
00588 INITO_IDX inito;
00589 DATA_ELEMENTS *v;
00590 INT vsize,i;
00591 INT64 pos;
00592
00593 INITV_IDX pad;
00594 INITV_IDX initv;
00595 INITV_IDX prev_initv;
00596 INT64 offset;
00597 INT64 init_size;
00598 INT64 pad_size;
00599
00600 if (ST_sym_class(st) != CLASS_VAR) return;
00601
00602 d = ST_auxst_data_info(st);
00603 if (d==NULL) return;
00604 if (d->Get_Data_Elements()==NULL) return;
00605
00606
00607 inito = d->Get_Inito();
00608
00609 d->sort_data(st);
00610 v = d->Get_Data_Elements();
00611
00612
00613 vsize = v->size();
00614 if (vsize == 0) return;
00615
00616 #ifdef DATA_DEBUG
00617 printf("Emitting inits for %s ====================\n",ST_name(st));
00618 #endif
00619
00620 prev_initv = 0;
00621 pos = 0;
00622 for (i = 0; i < vsize; i++) {
00623 if (!(*v)[i].is_valid) continue;
00624 offset = (*v)[i].offset;
00625 init_size = (*v)[i].initv_size;
00626 initv = (*v)[i].create_initv();
00627
00628
00629 pad_size = offset - pos;
00630 if (pad_size > 0) {
00631 pad = Irb_Init_Pad(0,prev_initv,pad_size);
00632 if (prev_initv == 0) {
00633 prev_initv = Irb_Init_Block(inito,0,1);
00634 Set_INITV_blk(prev_initv,pad);
00635 } else {
00636 Set_INITV_next(prev_initv,pad);
00637 }
00638 prev_initv = pad;
00639 }
00640
00641 #ifdef DATA_DEBUG
00642 printf("pad %lld, offset %lld, size %lld, next %lld\n",pad_size,
00643 offset,init_size, offset + init_size);
00644 #endif
00645
00646
00647 if (prev_initv == 0) {
00648 prev_initv = Irb_Init_Block(inito,0,1);
00649 Set_INITV_blk(prev_initv,initv);
00650 } else {
00651 Set_INITV_next(prev_initv,initv);
00652 }
00653 prev_initv = initv;
00654 pos = offset + init_size;
00655 }
00656
00657
00658 pad_size = TY_size(ST_type(st)) - pos;
00659 if (pad_size > 0) {
00660 pad = Irb_Init_Pad(0,prev_initv,pad_size);
00661 }
00662
00663
00664
00665
00666 CXX_DELETE(d,Malloc_Mem_Pool);
00667 Set_ST_auxst_data_info(st,NULL);
00668
00669 return;
00670 }
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680 extern void
00681 cwh_data_emit_symbol_inits(SYMTAB_IDX level)
00682 {
00683 For_all(St_Table, level,&emit_inits_for_symbol);
00684 }
00685
00686
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698 static void
00699 cwh_data_set_init_flag(ST * st, enum list_name list)
00700 {
00701
00702 ITEM * el = NULL;
00703
00704 while ((el = cwh_auxst_next_element(st,el,list)) != NULL) {
00705
00706 ST * el_st = I_element(el);
00707 Set_ST_sclass(el_st, ST_sclass(st));
00708 Set_ST_is_initialized(el_st);
00709
00710 ST * p_st = cwh_auxst_cri_pointee(el_st,0);
00711
00712 if (p_st) {
00713 Set_ST_sclass(p_st, ST_sclass(st));
00714 Set_ST_is_initialized(p_st);
00715 }
00716
00717 if (list == l_COMLIST)
00718 cwh_data_set_init_flag(el_st, l_EQVLIST);
00719 }
00720 }
00721