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 #ifdef USE_PCH
00056 #include "lno_pch.h"
00057 #endif // USE_PCH
00058 #pragma hdrstop
00059
00060 #include "lnopt_main.h"
00061 #include "lwn_util.h"
00062 #include "lego_util.h"
00063 #include "stab.h"
00064 #include "strtab.h"
00065 #include "stblock.h"
00066 #include "pad.h"
00067 typedef HASH_TABLE<ST*,BOOL> S_HTABLE;
00068
00069 static ST* Create_Local_Array_ST (TY_IDX elem_ty, INT num,char *name) {
00070 ST *st;
00071 TY *arr_ty;
00072
00073 UINT32 elem_size = TY_size(elem_ty);
00074
00075 TY_IDX ty_idx;
00076 TY& ty = New_TY (ty_idx);
00077 TY_Init(ty, elem_size * num, KIND_ARRAY, MTYPE_UNKNOWN,
00078 Save_Str (name));
00079 ARB_HANDLE arb = New_ARB ();
00080 ARB_Init (arb, 0, num-1, elem_size);
00081 Set_ARB_first_dimen (arb);
00082 Set_ARB_last_dimen (arb);
00083 Set_TY_etype(ty,elem_ty);
00084
00085 Set_TY_arb (ty, arb);
00086 Set_TY_align_exp (ty_idx, 8);
00087
00088 st = New_ST(CURRENT_SYMTAB);
00089
00090 ST_Init (st,
00091 Save_Str(name),
00092 CLASS_VAR,
00093 SCLASS_AUTO,
00094 EXPORT_LOCAL,
00095 ty_idx);
00096 Set_ST_is_temp_var(st);
00097 Set_ST_pt_to_unique_mem(st);
00098
00099 return st;
00100 }
00101
00102 static INT Array_Pad_Size(INT column_size)
00103 {
00104
00105
00106 INT bad_dim_size = 256*8;
00107 INT min_size = 230*8;
00108 INT mod = column_size % bad_dim_size;
00109 if ((column_size > min_size) && (mod < bad_dim_size/20)) {
00110 return (bad_dim_size/20 - mod);
00111 } else if ((column_size > bad_dim_size) &&
00112 ((bad_dim_size - mod) < bad_dim_size/20)) {
00113 return (bad_dim_size/20 + (bad_dim_size - mod));
00114 }
00115
00116 bad_dim_size = 128*8;
00117 min_size = 115*8;
00118 mod = column_size % bad_dim_size;
00119 if ((column_size > min_size) && (mod < bad_dim_size/20)) {
00120 return (bad_dim_size/20 - mod);
00121 } else if ((column_size > bad_dim_size) &&
00122 ((bad_dim_size - mod) < bad_dim_size/20)) {
00123 return (bad_dim_size/20 + (bad_dim_size - mod));
00124 } else {
00125 return 0;
00126 }
00127 }
00128
00129 TY_IDX Create_New_Array_Type(TY_IDX old_array_ty)
00130 {
00131 TY_IDX new_array_ty = Copy_TY(old_array_ty);
00132 ARB_HANDLE old_arb_base = TY_arb(old_array_ty);
00133 INT old_arb_idx=0;
00134 BOOL first_time = TRUE;
00135 ARB_HANDLE first_arb;
00136 BOOL done = FALSE;
00137 while (!done) {
00138 ARB_HANDLE tmp = old_arb_base[old_arb_idx];
00139 ARB_HANDLE arb = New_ARB ();
00140 if (first_time) {
00141 first_arb = arb;
00142 first_time = FALSE;
00143 }
00144 ARB_copy(arb,tmp);
00145 old_arb_idx++;
00146 done = ARB_last_dimen(tmp);
00147 };
00148
00149 Set_TY_arb (new_array_ty, first_arb);
00150
00151 return new_array_ty;
00152 }
00153
00154
00155
00156
00157 static void Pad_Arrays(WN* wn)
00158 {
00159 OPCODE opc = WN_opcode(wn);
00160 if (OPCODE_operator(opc) == OPR_ARRAY && (WN_num_dim(wn) > 1)) {
00161 WN *base = WN_array_base(wn);
00162 if (WN_operator(base) == OPR_LDA) {
00163 WN *last_dim = WN_array_dim(wn,WN_num_dim(wn)-1);
00164 if (WN_operator(last_dim) == OPR_INTCONST) {
00165 ST *st = WN_st(base);
00166 INT st_size =
00167 TY_AR_stride_val(ST_type(st), TY_AR_ndims(ST_type(st))-2) / WN_element_size(wn);
00168 if (WN_const_val(last_dim) != st_size) {
00169 WN_const_val(last_dim) = st_size;
00170 if (TY_pointed(WN_ty(base)) != ST_type(st) &&
00171 TY_kind(TY_pointed(WN_ty(base))) == KIND_ARRAY)
00172 WN_set_ty(base, Make_Pointer_Type(ST_type(st)));
00173 }
00174 }
00175 }
00176 }
00177 if (opc == OPC_BLOCK) {
00178 for (WN* tmp = WN_first(wn); tmp; tmp = WN_next(tmp)) {
00179 Pad_Arrays(tmp);
00180 }
00181 } else {
00182 for (INT kid=0; kid<WN_kid_count(wn); kid++) {
00183 Pad_Arrays(WN_kid(wn,kid));
00184 }
00185 }
00186 }
00187
00188 static BOOL Local_Multid_Array(ST *st)
00189 {
00190 return ((ST_sclass(st) == SCLASS_AUTO) &&
00191 ST_base_idx(st) == ST_st_idx(st) &&
00192 (ST_class(st) == CLASS_VAR) && !ST_is_not_used(st) &&
00193 !ST_has_nested_ref(st) &&
00194 (TY_kind(ST_type(st)) == KIND_ARRAY) &&
00195 (TY_kind(TY_etype(ST_type(st))) == KIND_SCALAR) &&
00196 (TY_AR_ndims(ST_type(st)) > 1) &&
00197 (TY_size(ST_type(st)) > 0) &&
00198 (!ST_is_reshaped(st)) &&
00199 (!ST_is_fill_align(st)) &&
00200 (!ST_is_initialized(st)));
00201 }
00202
00203
00204 static BOOL IO_element_read(WN *item)
00205 {
00206 if (WN_operator(item) == OPR_IO_ITEM) {
00207 if (WN_io_item(item) == IOL_VAR) {
00208 WN *parent = LWN_Get_Parent(item);
00209 if (WN_opcode(parent) == OPC_IO) {
00210 if (WN_io_statement(parent) == IOS_READ) {
00211 return TRUE;
00212 } else if (WN_io_statement(parent) == IOS_CR_FRF) {
00213 return TRUE;
00214 } else if (WN_io_statement(parent) == IOS_CR_FRU) {
00215 return TRUE;
00216 }
00217 }
00218 }
00219 }
00220 return FALSE;
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233 static BOOL Has_Variable_Bounds(WN* wn_array)
00234 {
00235 FmtAssert(WN_operator(wn_array) == OPR_ARRAY,
00236 ("Has_Variable_Bounds: Expecting an OPR_ARRAY node"));
00237 for (INT i = 0; i < WN_num_dim(wn_array); i++) {
00238 WN* wn = WN_array_dim(wn_array, i);
00239 if (WN_operator(wn) != OPR_INTCONST)
00240 return TRUE;
00241 }
00242 return FALSE;
00243 }
00244
00245
00246
00247
00248
00249 static void Check_Arrays(WN *wn,S_HTABLE *bad_behaved)
00250 {
00251 OPCODE opc = WN_opcode(wn);
00252 if (opc == OPC_BLOCK) {
00253 WN *kid=WN_first(wn);
00254 while (kid) {
00255 Check_Arrays(kid,bad_behaved);
00256 kid = WN_next(kid);
00257 }
00258 } else if (OPCODE_operator(opc) == OPR_LDA) {
00259 if (Local_Multid_Array(WN_st(wn))) {
00260 TY_IDX array_ty = Get_Array_Type(WN_st(wn));
00261 BOOL ok = FALSE;
00262 WN *parent = LWN_Get_Parent(wn);
00263 if ((WN_operator(parent) == OPR_ARRAY) &&
00264 (wn == WN_array_base(parent)) &&
00265 (!WN_offset(wn)) &&
00266 (WN_element_size(parent) > 0) &&
00267 (!Has_Variable_Bounds(parent)) &&
00268 (TY_AR_ndims(array_ty) == WN_num_dim(parent)) &&
00269
00270 (abs(WN_offset(wn)) < TY_AR_stride_val(array_ty,TY_AR_ndims(array_ty)-1))) {
00271 WN *grandparent = LWN_Get_Parent(parent);
00272 OPCODE gopc = WN_opcode(grandparent);
00273 if (OPCODE_is_load(gopc) ||
00274 ((OPCODE_operator(gopc) == OPR_ISTORE) &&
00275 (parent == WN_kid1(grandparent)))
00276
00277 ||
00278 (IO_element_read(grandparent))) {
00279 ok = TRUE;
00280 }
00281 }
00282 if (!ok) {
00283 bad_behaved->Enter_If_Unique(WN_st(wn),1);
00284 }
00285 }
00286 } else {
00287 for (INT kidno=0; kidno<WN_kid_count(wn); kidno++) {
00288 Check_Arrays(WN_kid(wn,kidno),bad_behaved);
00289 }
00290 }
00291 }
00292
00293
00294
00295
00296 inline INT64
00297 Is_Const_Bounds(ARB_HANDLE arb)
00298 {
00299 return (ARB_const_ubnd(arb) && ARB_const_lbnd(arb) &&
00300 ARB_const_stride(arb));
00301 }
00302
00303
00304
00305
00306
00307 inline INT64
00308 Num_Elements(ARB_HANDLE arb)
00309 {
00310 Is_True((ARB_const_ubnd(arb) && ARB_const_lbnd(arb) && ARB_const_stride(arb)), ("Expecting constant bounds in Num_Elements\n"));
00311
00312 return abs(ARB_ubnd_val(arb) - ARB_lbnd_val(arb) + 1);
00313 }
00314
00315
00316
00317
00318
00319 static BOUNDS_ARRAY*
00320 Store_Orig_Dims(ST* s)
00321 {
00322 Is_True((TY_kind(ST_type(s)) == KIND_ARRAY), (" Expecting KIND_ARRAY in Store_Orig_Dims \n"));
00323
00324 BOUNDS_ARRAY* b = CXX_NEW(BOUNDS_ARRAY(&LNO_local_pool), &LNO_local_pool);
00325
00326 INT lower, upper, stride;
00327 INT num_dims =
00328 ARB_dimension(TY_arb(ST_type(s)));
00329 ARB_HANDLE arb_base = TY_arb(ST_type(s));
00330
00331 if (num_dims > 1) {
00332 for (INT i=0; i<num_dims; ++i)
00333 {
00334 const ARB_HANDLE arb = arb_base[num_dims-1-i];
00335 if (ARB_const_lbnd(arb) && ARB_const_ubnd(arb) &&
00336 ARB_const_stride(arb))
00337 {
00338 lower = ARB_lbnd_val(arb);
00339 upper = ARB_ubnd_val(arb);
00340 stride = ARB_stride_val(arb);
00341 INT id = b->Newidx();
00342 BOUNDS *belement = &(*b)[id];
00343 belement->Init(upper, lower,stride);
00344 belement->Set_Constant();
00345 }
00346 else
00347 {
00348 INT id = b->Newidx();
00349 BOUNDS *belement = &(*b)[id];
00350 belement->Init();
00351 }
00352 }
00353 }
00354 return b;
00355 }
00356
00357
00358
00359
00360
00361 static BOOL
00362 Padding_Threshold(INT64 pad_size, INT pad_dim, BOUNDS_ARRAY *b,
00363 ARB_HANDLE arb_in)
00364 {
00365 Is_True(pad_dim <= b->Lastidx(), ("pad dim is TOO high in Padding Threshold \n"));
00366 BOUNDS *belement = &(*b)[pad_dim];
00367 ARB_HANDLE arb = arb_in[b->Lastidx()-pad_dim];
00368 Is_True((ARB_const_ubnd(arb) && ARB_const_lbnd(arb) && ARB_const_stride(arb)), ("constant bounds expected \n"));
00369
00370 INT size = abs(ARB_ubnd_val(arb) - ARB_lbnd_val(arb) + 1);
00371 float padt = ((pad_size/(*b)[0].Get_Stride() + size)*100)/size;
00372 if (padt > 110) {
00373 return FALSE;
00374 }
00375 return TRUE;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384 INT64
00385 Pad_Size(INT pad_dim, INT padding, INT end_dim,
00386 BOUNDS_ARRAY *bounds, BOOL extra_pad)
00387 {
00388 INT size = 1;
00389 INT size2 = 1;
00390 INT pad_dim_size = 1;
00391 if (end_dim == 0)
00392 return padding;
00393 for (INT i=0; i<=end_dim; ++i) {
00394 BOUNDS *b = &(*bounds)[i];
00395 INT upper = b->Get_Upper();
00396 INT lower = b->Get_Lower();
00397 if (i != pad_dim)
00398 size = size* abs(upper-lower+1);
00399 else
00400 pad_dim_size = (upper-lower+1);
00401 size2 = size2*abs(upper-lower+1);
00402 }
00403 INT total_size = size2+(padding/(*bounds)[0].Get_Stride());
00404 float fpad_size = float(total_size/size - pad_dim_size);
00405 if (fpad_size > 0.001)
00406 fpad_size = fpad_size - .001;
00407 INT64 pad_size;
00408 if (extra_pad)
00409 pad_size = (INT64)(fpad_size+2)*(*bounds)[0].Get_Stride();
00410 else
00411 pad_size = (INT64)(fpad_size+1)*(*bounds)[0].Get_Stride();
00412 if (pad_size == 0)
00413 return (*bounds)[0].Get_Stride();
00414 else
00415 return pad_size;
00416 }
00417
00418
00419
00420
00421
00422
00423 static
00424 BOOL Pad_Dim(BOUNDS *b)
00425 {
00426 Is_True(b->Is_Constant(), ("Expecting constant bounds in Pad_Dim \n"));
00427 INT one_count = 0;
00428 INT size = abs (b->Get_Upper() - b->Get_Lower() + 1);
00429 while (size != 0)
00430 {
00431 size = size >> 1;
00432 if (size & 1)
00433 ++one_count;
00434 }
00435 if (one_count > 1)
00436 return FALSE;
00437 return TRUE;
00438 }
00439
00440
00441
00442
00443
00444 static INT
00445 Get_Pad_Dim(INT last_dim, INT element_size, BOUNDS_ARRAY *b)
00446 {
00447 INT size, lower, upper, max_element, max_dim;
00448 max_element = 0;
00449 max_dim = last_dim;
00450
00451
00452
00453 INT last_dim_size = abs((*b)[last_dim].Get_Upper() -
00454 (*b)[last_dim].Get_Lower() + 1);
00455 for (INT i=last_dim; i >= 0; --i)
00456 {
00457 BOUNDS* bounds_elem = &(*b)[i];
00458 lower = bounds_elem->Get_Lower();
00459 upper = bounds_elem->Get_Upper();
00460 size = abs(upper-lower+1);
00461
00462 if (((size*element_size) % (128*8)) == 0)
00463 return i;
00464 if (size > max_element)
00465 {
00466 if (size > (last_dim_size*130)/100)
00467 {
00468 max_element = size;
00469 max_dim = i;
00470 }
00471 else
00472 {
00473 max_element = last_dim_size;
00474 max_dim = last_dim;
00475 }
00476 }
00477 }
00478 return max_dim;
00479 }
00480
00481
00482
00483
00484
00485 static TY_IDX
00486 Create_New_Array_Type_To_Pad(TY_IDX old_array_ty)
00487 {
00488 INT num_dims = TY_AR_ndims(old_array_ty);
00489 TY_IDX etype_idx = TY_etype(old_array_ty);
00490 const TY& etype = Ty_Table[etype_idx];
00491
00492 TY_IDX new_array_ty =
00493 Make_Array_Type(TY_mtype(etype), num_dims, 1);
00494
00495 Set_TY_name_idx(Ty_Table[new_array_ty], TY_name_idx(Ty_Table[old_array_ty]));
00496 Set_TY_size(Ty_Table[new_array_ty],TY_size(Ty_Table[old_array_ty]));
00497
00498 num_dims = TY_AR_ndims(new_array_ty);
00499 ARB_HANDLE arb_base = TY_arb(new_array_ty);
00500 ARB_HANDLE old_arb_base = TY_arb(old_array_ty);
00501 for (UINT i = 0; i < num_dims ; ++i)
00502 {
00503 ARB_HANDLE arb = arb_base[i];
00504 ARB_HANDLE old_arb = old_arb_base[i];
00505 ARB_Init(arb, ARB_lbnd_val(old_arb),
00506 ARB_ubnd_val(old_arb),
00507 ARB_stride_val(old_arb));
00508 Set_ARB_dimension(arb, num_dims-i);
00509 if (i==0)
00510 Set_ARB_first_dimen(arb_base[0]);
00511 if (i == num_dims-1)
00512 Set_ARB_last_dimen(arb_base[i]);
00513 }
00514
00515 return new_array_ty;
00516 }
00517
00518
00519
00520
00521
00522 static TY_IDX
00523 Create_Multi_Dim_Array_Type(TY_IDX old_array_ty, BOUNDS_ARRAY *bounds)
00524 {
00525 TY_IDX ty_index = Create_New_Array_Type_To_Pad(old_array_ty);
00526
00527 TY& new_array_ty = Ty_Table[ty_index];
00528
00529 INT num_dims = TY_AR_ndims(new_array_ty);
00530 ARB_HANDLE arb_base = TY_arb(new_array_ty);
00531 INT64 element_size = ARB_stride_val(arb_base[num_dims-1]);
00532 INT64 new_stride = element_size;
00533
00534 for (UINT i = 0; i < num_dims ; ++i)
00535 {
00536
00537 ARB_HANDLE arb = arb_base[num_dims-i-1];
00538 BOUNDS *belement = &(*bounds)[i];
00539 INT64 upper = belement->Get_Upper();
00540 Set_ARB_ubnd_val(arb,upper);
00541 Set_ARB_stride_val(arb,new_stride);
00542 new_stride = new_stride*Num_Elements(arb);
00543 }
00544 return ty_index;
00545 }
00546
00547
00548
00549
00550
00551 static INT64
00552 Update_Pad_Size(INT last_dim, BOUNDS_ARRAY *barray)
00553 {
00554 INT64 pad_size = 1;
00555 for (INT i=0; i<= last_dim; ++i)
00556 {
00557 INT upper = (*barray)[i].Get_Upper();
00558 INT lower = (*barray)[i].Get_Lower();
00559
00560 pad_size = pad_size* (abs(upper - lower + 1));
00561 }
00562
00563 return pad_size;
00564 }
00565
00566
00567
00568
00569
00570 static void
00571 Update_Bounds_After_Padding(INT64 pad_size,
00572 INT pad_dim,
00573 BOUNDS_ARRAY *barray)
00574 {
00575 INT64 element_size = (*barray)[0].Get_Stride();
00576 INT64 stride = (*barray)[pad_dim].Get_Stride();
00577
00578 for (INT i = pad_dim; i < barray->Elements(); ++i) {
00579 BOUNDS& bounds = (*barray)[i];
00580 if (i == pad_dim) {
00581
00582 pad_size = (LNO_Local_Pad_Size != (UINT32)-1) ?
00583 LNO_Local_Pad_Size :
00584 (pad_size + element_size) / element_size;
00585 bounds.Set_Upper(pad_size + bounds.Get_Upper());
00586 }
00587 bounds.Set_Stride(stride);
00588 stride *= abs(bounds.Get_Upper() - bounds.Get_Lower() + 1);
00589 }
00590 }
00591
00592
00593
00594
00595
00596
00597
00598
00599 static INT64
00600 Get_New_Size_Padding(TY_IDX new_array_ty_idx, TY_IDX old_array_ty_idx,
00601 INT32 start_dim)
00602 {
00603 TY& new_array_ty = Ty_Table[new_array_ty_idx];
00604 TY& old_array_ty = Ty_Table[old_array_ty_idx];
00605
00606 INT64 old_size = 1;
00607 INT64 new_size = 1;
00608 INT num_dims = TY_AR_ndims(new_array_ty);
00609 ARB_HANDLE old_arb_base = TY_arb(old_array_ty);
00610 ARB_HANDLE new_arb_base = TY_arb(new_array_ty);
00611
00612 Is_True((start_dim < num_dims), ("start dim = %d , num_dims = %d in Get_New_Size_Padding \n", start_dim, num_dims));
00613
00614 for (INT i=start_dim; i<num_dims; ++i)
00615 {
00616 ARB_HANDLE old_arb = old_arb_base[i];
00617 ARB_HANDLE new_arb = new_arb_base[i];
00618 old_size = old_size*Num_Elements(old_arb);
00619 new_size = new_size*Num_Elements(new_arb);
00620 }
00621 new_size = new_size - old_size;
00622 return new_size;
00623 }
00624
00625
00626
00627
00628
00629 static void
00630 Pad_Local_ST(ST* s, BOUNDS_ARRAY *bounds)
00631 {
00632 Is_True((TY_kind(ST_type(s)) == KIND_ARRAY) && (ST_sclass(s) ==SCLASS_AUTO),("Expecting a local ARRAY in Pad_Local_ST \n"));
00633 ;
00634
00635 TY_IDX old_array_ty_idx = ST_type(s);
00636 TY_IDX new_array_ty_idx =
00637 Create_Multi_Dim_Array_Type(ST_type(s), bounds);
00638
00639 TY& new_array_ty = Ty_Table[new_array_ty_idx];
00640 TY& old_array_ty = Ty_Table[old_array_ty_idx];
00641 TY_IDX etype_idx = TY_etype(old_array_ty);
00642
00643 INT64 add_size = Get_New_Size_Padding(new_array_ty_idx,
00644 old_array_ty_idx,0);
00645 add_size = add_size*TY_size(etype_idx);
00646 Set_TY_size(new_array_ty, TY_size(old_array_ty) + add_size);
00647 Set_ST_type(*s, new_array_ty_idx);
00648 }
00649
00650
00651
00652
00653
00654 static void
00655 Pad_Local_Array(ST* s)
00656 {
00657 Is_True((TY_kind(ST_type(s)) == KIND_ARRAY) && (ST_sclass(s)==SCLASS_AUTO),("Expecting a local ARRAY in Pad_Local_Array \n"));
00658
00659 BOUNDS_ARRAY *bounds_array = Store_Orig_Dims(s);
00660 Is_True(bounds_array!=NULL, (" NULL bounds array in Pad_Local_Array \n"));
00661 BOOL to_pad = FALSE;
00662 INT64 lower, upper, stride;
00663 INT num_dims = ARB_dimension(TY_arb(ST_type(s)));
00664 ARB_HANDLE arb_base = TY_arb(ST_type(s));
00665 if (num_dims > 1) {
00666 INT64 pad_size = 1;
00667 INT64 padding;
00668 INT pad_dim;
00669 BOUNDS *b = &(*bounds_array)[0];
00670 if (b->Is_Constant()) {
00671 pad_size = abs(b->Get_Upper() - b->Get_Lower() + 1);
00672 }
00673 else return;
00674 pad_size = 1;
00675 for (INT i=0; i<num_dims-1; ++i) {
00676 b = &(*bounds_array)[i];
00677 if (b->Is_Constant()) {
00678 lower = b->Get_Lower();
00679 upper = b->Get_Upper();
00680 pad_size = pad_size * abs(upper-lower+1);
00681 padding =
00682 Array_Pad_Size(pad_size*(*bounds_array)[0].Get_Stride());
00683 if (padding) {
00684 INT element_size = (*bounds_array)[0].Get_Stride();
00685 if (padding) {
00686 if ((8 % element_size) == 0) {
00687 if (((pad_size*(*bounds_array)[0].Get_Stride() + padding)
00688 % 16) == 0) {
00689 padding += 8;
00690 }
00691 }
00692 for (INT j =i; j >= 0; --j) {
00693 if ((j != i) && Pad_Dim(&(*bounds_array)[j]))
00694 pad_dim = j;
00695 else
00696 pad_dim =
00697 Get_Pad_Dim(i,((*bounds_array)[0]).Get_Stride(),bounds_array);
00698 INT pad_size1=0;
00699 if (j == i)
00700 pad_size1 = Pad_Size(pad_dim,padding,i,bounds_array,TRUE);
00701 else if (Pad_Dim(&(*bounds_array)[j]))
00702 pad_size1 =
00703 Pad_Size(pad_dim,padding,i,bounds_array,FALSE);
00704
00705 if (Padding_Threshold(pad_size1,pad_dim,bounds_array,arb_base))
00706 {
00707 to_pad = TRUE;
00708 Update_Bounds_After_Padding(pad_size1, pad_dim, bounds_array);
00709 pad_size = Update_Pad_Size(i,bounds_array);
00710 }
00711 }
00712 }
00713 }
00714 }
00715 }
00716 }
00717 if (to_pad)
00718 {
00719 Pad_Local_ST(s, bounds_array);
00720 }
00721 }
00722
00723
00724
00725
00726
00727 static void
00728 Pad_Local_Arrays_In_Whirl(WN* func_nd,S_HTABLE *bad_behaved)
00729 {
00730
00731 OPCODE opc = WN_opcode(func_nd);
00732 if (OPCODE_operator(opc) == OPR_ARRAY &&
00733 (WN_num_dim(func_nd) > 1) &&
00734
00735 WN_element_size(func_nd) > 0) {
00736 WN *base = WN_array_base(func_nd);
00737 if (OPCODE_operator(WN_opcode(base)) == OPR_LDA) {
00738 if (Local_Multid_Array(WN_st(base)) && !bad_behaved->Find(WN_st(base))) {
00739 ARB_HANDLE arb_base = TY_arb(ST_type(WN_st(base)));
00740 BOOL set_base = FALSE;
00741 for (INT i=0; i<WN_num_dim(func_nd); ++i) {
00742 WN *dim = WN_array_dim(func_nd,i);
00743 if (OPCODE_operator(WN_opcode(dim)) == OPR_INTCONST) {
00744 ST *st = WN_st(base);
00745 INT num_dim = WN_num_dim(func_nd);
00746 ARB_HANDLE arb = arb_base[i];
00747 if (Is_Const_Bounds(arb)) {
00748 INT64 st_size = Num_Elements(arb);
00749 if (WN_const_val(dim) != st_size) {
00750 WN_const_val(dim) = st_size;
00751 if ((TY_pointed(WN_ty(base)) != ST_type(st)) &&
00752 (TY_kind(TY_pointed(WN_ty(base))) == KIND_ARRAY))
00753 {
00754 if (!set_base) {
00755 TY_IDX idx = Make_Pointer_Type(ST_type(st));
00756 WN_set_ty(base, idx);
00757 set_base = TRUE;
00758 }
00759 }
00760 }
00761 }
00762 }
00763 }
00764 }
00765 }
00766 }
00767 if (opc == OPC_BLOCK) {
00768 for (WN* wn = WN_first(func_nd); wn; wn = WN_next(wn)) {
00769 Pad_Local_Arrays_In_Whirl(wn,bad_behaved);
00770 }
00771 } else {
00772 for (INT kid=0; kid<WN_kid_count(func_nd); kid++) {
00773 Pad_Local_Arrays_In_Whirl(WN_kid(func_nd,kid),bad_behaved);
00774 }
00775 }
00776 }
00777
00778
00779
00780
00781
00782
00783
00784 extern void
00785 Pad_Multi_Dim(WN* func_nd)
00786 {
00787 MEM_POOL_Push(&LNO_local_pool);
00788 S_HTABLE *bad_behaved =
00789 CXX_NEW(S_HTABLE(50,&LNO_local_pool),&LNO_local_pool);
00790 Check_Arrays(func_nd,bad_behaved);
00791
00792
00793 ST *st;
00794 INT i;
00795 FOREACH_SYMBOL (CURRENT_SYMTAB,st,i) {
00796 if (Local_Multid_Array(st) && !bad_behaved->Find(st)) {
00797 Pad_Local_Array(st);
00798 }
00799 }
00800 Pad_Local_Arrays_In_Whirl(func_nd,bad_behaved);
00801
00802 MEM_POOL_Pop(&LNO_local_pool);
00803 }
00804
00805
00806
00807
00808
00809
00810
00811 extern void Pad_First_Dim_Degenerates(WN *func_nd)
00812 {
00813 Pad_Multi_Dim(func_nd);
00814 }
00815
00816
00817
00818 extern void Pad_Degenerates()
00819 {
00820 ST *st;
00821
00822 INT i;
00823 FOREACH_SYMBOL (CURRENT_SYMTAB,st,i) {
00824 if ((ST_sclass(st) == SCLASS_AUTO) &&
00825 (ST_class(st) == CLASS_VAR) && !ST_is_not_used(st) &&
00826 (TY_size(ST_type(st)) > 0) &&
00827 !ST_is_fill_align(st) &&
00828 !ST_has_nested_ref(st) &&
00829 (TY_kind(ST_type(st)) == KIND_ARRAY) &&
00830 (!ST_is_reshaped(st))) {
00831 INT size = TY_size(ST_type(st));
00832 INT set_size = 256*1024;
00833 INT mod = size % set_size;
00834 INT pad_size=0;
00835 if ((size > 0.9*set_size) && (mod < set_size/20)) {
00836 pad_size = set_size/20 - mod;
00837 } else if ((size > 0.9*set_size) && ((set_size - mod) < set_size/20)) {
00838 pad_size = set_size/20 + (set_size - mod);
00839 }
00840 size += pad_size;
00841 set_size = 16*1024;
00842 mod = size % set_size;
00843 if ((size > 0.9*set_size) && (mod < set_size/20)) {
00844 pad_size += set_size/20 - mod;
00845 } else if ((size > 0.9*set_size) && ((set_size - mod) < set_size/20)) {
00846 pad_size += set_size/20 + (set_size - mod);
00847 }
00848 size += pad_size;
00849 #ifdef TARG_X8664
00850
00851 if (!Is_Target_Anyx86() &&
00852 !Is_Target_EM64T() &&
00853
00854 !Is_Target_Pentium4() &&
00855 size >= 4096) {
00856 UINT tmp = size;
00857 tmp = ~tmp;
00858 tmp += 1;
00859 tmp = ~tmp;
00860 if ((tmp & size) == 0) {
00861 pad_size += 64;
00862 size += pad_size;
00863 }
00864 }
00865 #endif
00866 if (pad_size) {
00867 static INT count;
00868 char name[64];
00869 sprintf (name, "pad_%d", count);
00870 count++;
00871 ST *pad_symbol =
00872 Create_Local_Array_ST(Be_Type_Tbl(MTYPE_I1),size,name);
00873 St_Block_Union(st,pad_symbol);
00874 }
00875 }
00876 }
00877 }
00878