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 #include <sys/types.h>
00037 #include <limits.h>
00038 #include <stdio.h>
00039 #include "pu_info.h"
00040 #include "defs.h"
00041 #include "wn.h"
00042 #include "lwn_util.h"
00043 #include "strtab.h"
00044 #include "ipa_section.h"
00045 #include "ipa_lno_summary.h"
00046 #include "ipa_lno_info.h"
00047 #include "ara_loop.h"
00048 #include "lnopt_main.h"
00049 #include "opt_du.h"
00050 #include "debug.h"
00051 #include "ipa_lno_util.h"
00052 #include "ipa_lno_reshape.h"
00053 #include "ipa_section.h"
00054 #include "ipl_lno_util.h"
00055 #include "lnoutils.h"
00056 #include "be_util.h"
00057 #include "dep_graph.h"
00058 #include "ipa_lno_read.h"
00059
00060
00061
00062
00063
00064
00065 void LINEX::LNO_Simplify(IPA_LNO_READ_FILE* IPA_LNO_File,
00066 WN* wn_call)
00067 {
00068 DU_MANAGER* du = Du_Mgr;
00069 MEM_POOL* mem_pool = &LNO_local_pool;
00070 MEM_POOL_Push(mem_pool);
00071 {
00072 STACK<INT> stk_int(mem_pool);
00073 INT64 const_value = 0;
00074 INT i;
00075 for (i = 0; i <= Num_terms(); i++) {
00076 TERM* tm = Get_term(i);
00077 switch (tm->Get_type()) {
00078 case LTKIND_CONST:
00079 const_value += tm->Get_coeff();
00080 stk_int.Push(i);
00081 break;
00082 case LTKIND_IV:
00083 {
00084 IVAR* iv = IPA_LNO_File->Ivar(tm->Get_desc());
00085 if (iv->Is_Formal()) {
00086 INT formal_number = iv->Formal_Position();
00087 FmtAssert(formal_number >= 0
00088 && formal_number < WN_kid_count(wn_call),
00089 ("LNO_Simplify: Formal number out of range"));
00090 WN* wn_parm = WN_kid(wn_call, formal_number);
00091 FmtAssert(WN_operator(wn_parm) == OPR_PARM,
00092 ("Map_Term: Expecting PARAM node"));
00093 WN* wn_lda = WN_kid0(wn_parm);
00094 if (WN_operator(wn_lda) == OPR_LDA
00095 || WN_operator(wn_lda) == OPR_LDID) {
00096 INT64 integer_value = -1;
00097 if (Wn_Is_Intconst(wn_lda, &integer_value)) {
00098 const_value += integer_value;
00099 stk_int.Push(i);
00100 } else {
00101 WN* wn_chain = WN_operator(wn_lda) == OPR_LDA
00102 ? wn_parm : wn_lda;
00103 DEF_LIST* def_list = du->Ud_Get_Def(wn_chain);
00104 if (def_list != NULL && !def_list->Incomplete()) {
00105 DEF_LIST_ITER iter(def_list);
00106 const DU_NODE* node = NULL;
00107 INT def_count = 0;
00108 WN* wn_def = NULL;
00109 for (node = iter.First(); !iter.Is_Empty();
00110 node = iter.Next()) {
00111 wn_def = node->Wn();
00112 def_count++;
00113 }
00114 if (def_count == 1 && WN_kid_count(wn_def) > 0) {
00115 WN* wn_value = WN_kid0(wn_def);
00116 if (WN_operator(wn_value) == OPR_INTCONST) {
00117 const_value += WN_const_val(wn_value);
00118 stk_int.Push(i);
00119 } else if (WN_operator(wn_value) == OPR_LDID
00120 && Wn_Is_Intconst(wn_value, &integer_value)) {
00121 const_value += integer_value;
00122 stk_int.Push(i);
00123 }
00124 }
00125 }
00126 }
00127 }
00128 }
00129 }
00130 break;
00131 default:
00132 break;
00133 }
00134 }
00135 DYN_ARRAY<TERM> new_terms(mem_pool);
00136 for (i = 0; i <= Num_terms(); i++) {
00137 INT j;
00138 for (j = 0; j < stk_int.Elements(); j++)
00139 if (stk_int.Bottom_nth(j) == i)
00140 break;
00141 if (j < stk_int.Elements())
00142 continue;
00143 TERM* tm = Get_term(i);
00144 new_terms.AddElement(*tm);
00145 }
00146 _larray.Resetidx();
00147 for (i = 0; i < new_terms.Elements(); i++) {
00148 TERM* tm = &new_terms[i];
00149 _larray.AddElement(*tm);
00150 }
00151 if (const_value != 0 || new_terms.Elements() == 0)
00152 Set_term(LTKIND_CONST, const_value, CONST_DESC, 0);
00153 }
00154 MEM_POOL_Pop(mem_pool);
00155 }
00156
00157
00158
00159
00160
00161
00162
00163 void PROJECTED_NODE::LNO_Simplify(IPA_LNO_READ_FILE* IPA_LNO_File,
00164 WN* wn_call)
00165 {
00166 if (!Is_messy_lb()) {
00167 LINEX* lx_lower = Get_lower_linex();
00168 lx_lower->LNO_Simplify(IPA_LNO_File, wn_call);
00169 }
00170 if (!Is_messy_ub()) {
00171 LINEX* lx_upper = Get_upper_linex();
00172 lx_upper->LNO_Simplify(IPA_LNO_File, wn_call);
00173 }
00174 if (!Is_messy_step()) {
00175 LINEX* lx_step = Get_step_linex();
00176 lx_step->LNO_Simplify(IPA_LNO_File, wn_call);
00177 }
00178 if (Get_segment_length_linex() != NULL) {
00179 LINEX* lx_segment_length = Get_segment_length_linex();
00180 lx_segment_length->LNO_Simplify(IPA_LNO_File, wn_call);
00181 }
00182 if (Get_segment_stride_linex() != NULL) {
00183 LINEX* lx_segment_stride = Get_segment_stride_linex();
00184 lx_segment_stride->LNO_Simplify(IPA_LNO_File, wn_call);
00185 }
00186 }
00187
00188
00189
00190
00191
00192
00193
00194 void PROJECTED_REGION::LNO_Simplify(IPA_LNO_READ_FILE* IPA_LNO_File,
00195 WN* wn_call)
00196 {
00197 if (Is_messy_region())
00198 return;
00199 for (INT i = 0; i < Get_num_dims(); i++) {
00200 PROJECTED_NODE* pn = Get_projected_node(i);
00201 pn->LNO_Simplify(IPA_LNO_File, wn_call);
00202 }
00203 }
00204
00205
00206
00207
00208
00209
00210
00211 static BOOL Is_Scalar(ST* st_formal)
00212 {
00213 TY_IDX ty_idx_formal = ST_type(st_formal);
00214 if (TY_kind(ty_idx_formal) == KIND_POINTER)
00215 ty_idx_formal = TY_pointed(ty_idx_formal);
00216 if (TY_kind(ty_idx_formal) != KIND_ARRAY)
00217 return TRUE;
00218 return FALSE;
00219 }
00220
00221
00222
00223
00224
00225
00226
00227 static BOOL Can_Map_Term(IPA_LNO_READ_FILE* IPA_LNO_File,
00228 TERM* tm,
00229 WN* wn_call)
00230 {
00231 switch (tm->Get_type()) {
00232 case LTKIND_CONST:
00233 case LTKIND_LINDEX:
00234 case LTKIND_SUBSCR:
00235 return TRUE;
00236 case LTKIND_IV: {
00237 IVAR* iv = IPA_LNO_File->Ivar(tm->Get_desc());
00238 if (iv->Is_Formal()) {
00239 INT formal_number = iv->Formal_Position();
00240 if (formal_number < 0 || formal_number >= WN_kid_count(wn_call))
00241 return FALSE;
00242 WN* wn_parm = WN_kid(wn_call, formal_number);
00243 if (WN_operator(wn_parm) == OPR_PARM) {
00244 WN* wn_lda = WN_kid0(wn_parm);
00245 if (WN_operator(wn_lda) != OPR_LDA &&
00246 WN_operator(wn_lda) != OPR_LDID &&
00247 WN_operator(wn_lda) != OPR_INTCONST) {
00248 DYN_ARRAY<WN*> wn_list(&LNO_local_pool);
00249 DYN_ARRAY<INT> int_list(&LNO_local_pool);
00250 INT64 const_value = 0;
00251 if (!Scalar_Expr(wn_lda) || !Linear_Expr(wn_lda,
00252 &wn_list, &int_list, &const_value))
00253 return FALSE;
00254 }
00255 return TRUE;
00256 } else
00257 return FALSE;
00258 } else {
00259 return TRUE;
00260 }
00261 }
00262 default:
00263 FmtAssert(FALSE, ("Can_Map_Term: Unknown term type"));
00264 break;
00265 }
00266 return FALSE;
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 static BOOL Can_Map_Linex(IPA_LNO_READ_FILE* IPA_LNO_File,
00276 LINEX* lx,
00277 WN* wn_call)
00278 {
00279 for (INT i = 0; i <= lx->Num_terms(); i++)
00280 if (!Can_Map_Term(IPA_LNO_File, lx->Get_term(i), wn_call))
00281 return FALSE;
00282 return TRUE;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 static BOOL Can_Map_Projected_Region(IPA_LNO_READ_FILE* IPA_LNO_File,
00292 PROJECTED_REGION* pr_old,
00293 WN* wn_call)
00294 {
00295 if (pr_old->Is_messy_region())
00296 return FALSE;
00297 for (INT i = 0; i < pr_old->Get_num_dims(); i++) {
00298 PROJECTED_NODE* pn = pr_old->Get_projected_node(i);
00299 if (!pn->Is_messy_ub()) {
00300 LINEX* ub = pn->Get_upper_linex();
00301 if (ub != NULL && !Can_Map_Linex(IPA_LNO_File, ub, wn_call))
00302 return FALSE;
00303 }
00304 if (!pn->Is_messy_lb()) {
00305 LINEX* lb = pn->Get_lower_linex();
00306 if (lb != NULL && !Can_Map_Linex(IPA_LNO_File, lb, wn_call))
00307 return FALSE;
00308 }
00309 if (!pn->Is_messy_step()) {
00310 LINEX* step = pn->Get_step_linex();
00311 if (step != NULL && !Can_Map_Linex(IPA_LNO_File, step, wn_call))
00312 return FALSE;
00313 }
00314 if (pn->Get_segment_length_linex() != NULL) {
00315 LINEX* sl = pn->Get_segment_length_linex();
00316 if (sl != NULL && !Can_Map_Linex(IPA_LNO_File, sl, wn_call))
00317 return FALSE;
00318 }
00319 if (pn->Get_segment_stride_linex() != NULL) {
00320 LINEX* ss = pn->Get_segment_stride_linex();
00321 if (ss != NULL && !Can_Map_Linex(IPA_LNO_File, ss, wn_call))
00322 return FALSE;
00323 }
00324 }
00325 return TRUE;
00326 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 static BOOL Map_Linear_Expr(IPA_LNO_READ_FILE* IPA_LNO_File,
00337 LINEX* lx,
00338 TERM* tm,
00339 WN* wn_expr)
00340 {
00341 IVAR* ivar = IPA_LNO_File->Ivar(tm->Get_desc());
00342 DYN_ARRAY<WN*> wn_list(&LNO_local_pool);
00343 DYN_ARRAY<INT> int_list(&LNO_local_pool);
00344 INT64 const_value = 0;
00345 if (!Scalar_Expr(wn_expr) || !Linear_Expr(wn_expr, &wn_list, &int_list,
00346 &const_value))
00347 return FALSE;
00348 new (tm) TERM(LTKIND_CONST, const_value, CONST_DESC, 0);
00349 for (INT i = 0; i <= wn_list.Lastidx(); i++) {
00350 WN* wn = wn_list[i];
00351 INT coeff = int_list[i];
00352 INT64 integer_value = -1;
00353 if (Wn_Is_Intconst(wn, &integer_value)) {
00354 lx->Set_term(LTKIND_CONST, coeff * integer_value, CONST_DESC, 0);
00355 } else {
00356 IVAR iv_lcl(WN_st(wn), ivar->Offset(), ivar->Mtype());
00357 INT new_ivar_idx = IPA_LNO_File->Add_Translated_Ivar_Unique(iv_lcl);
00358 lx->Set_term(LTKIND_IV, coeff, new_ivar_idx, 0);
00359 }
00360 }
00361 return TRUE;
00362 }
00363
00364
00365
00366
00367
00368
00369
00370 static void Map_Term(IPA_LNO_READ_FILE* IPA_LNO_File,
00371 LINEX* lx,
00372 TERM* tm,
00373 WN* wn_call)
00374 {
00375 switch (tm->Get_type()) {
00376 case LTKIND_CONST:
00377 case LTKIND_LINDEX:
00378 case LTKIND_SUBSCR:
00379 break;
00380 case LTKIND_IV: {
00381 IVAR* ivar = IPA_LNO_File->Ivar(tm->Get_desc());
00382 if (ivar->Is_Formal()) {
00383 INT formal_number = ivar->Formal_Position();
00384 WN* wn_parm = WN_kid(wn_call, formal_number);
00385 FmtAssert(WN_operator(wn_parm) == OPR_PARM,
00386 ("Map_Term: Expecting PARAM node"));
00387 WN* wn_lda = WN_kid0(wn_parm);
00388 if (WN_operator(wn_lda) == OPR_LDA || WN_operator(wn_lda) == OPR_LDID) {
00389 INT64 integer_value = -1;
00390 if (Wn_Is_Intconst(wn_lda, &integer_value)) {
00391 new (tm) TERM(LTKIND_CONST, integer_value, CONST_DESC, 0);
00392 } else {
00393 WN* wn_single = Single_Definition_Temp(wn_lda);
00394 if (wn_single == NULL
00395 || !Map_Linear_Expr(IPA_LNO_File, lx, tm, wn_single)) {
00396 IVAR iv_lcl(WN_st(wn_lda), ivar->Offset(), ivar->Mtype());
00397 INT new_ivar_idx = IPA_LNO_File->Add_Translated_Ivar_Unique(iv_lcl);
00398 tm->Set_desc(new_ivar_idx);
00399 }
00400 }
00401 } else if (WN_operator(wn_lda) == OPR_INTCONST) {
00402 new (tm) TERM(LTKIND_CONST, WN_const_val(wn_lda), CONST_DESC, 0);
00403 } else {
00404 BOOL mapped = Map_Linear_Expr(IPA_LNO_File, lx, tm, wn_lda);
00405 FmtAssert(mapped, ("Map_Term: Non-scalar or non-linear expression"));
00406 }
00407 } else {
00408 INT new_ivar_idx = IPA_LNO_File->Add_Translated_Ivar_Unique(*ivar);
00409 tm->Set_desc(new_ivar_idx);
00410 }
00411 break;
00412 }
00413 default:
00414 FmtAssert(FALSE, ("Map_Term: Unknown type"));
00415 break;
00416 }
00417 }
00418
00419
00420
00421
00422
00423
00424
00425 static void Map_Linex(IPA_LNO_READ_FILE* IPA_LNO_File,
00426 LINEX* lx,
00427 WN* wn_call)
00428 {
00429 for (INT i = 0; i <= lx->Num_terms(); i++)
00430 Map_Term(IPA_LNO_File, lx, lx->Get_term(i), wn_call);
00431 }
00432
00433
00434
00435
00436
00437
00438
00439 extern PROJECTED_REGION* Map_Projected_Region(IPA_LNO_READ_FILE* IPA_LNO_File,
00440 PROJECTED_REGION* pr_memory,
00441 WN* wn_call)
00442 {
00443 if (!Can_Map_Projected_Region(IPA_LNO_File, pr_memory, wn_call)) {
00444 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO)) {
00445 fprintf(stdout,
00446 "SHAPE: Projected Region Problem calling 0x%p\n", wn_call);
00447 }
00448 return NULL;
00449 }
00450 LINEX* lx_simple = NULL;
00451 for (INT i = 0; i < pr_memory->Get_num_dims(); i++) {
00452 PROJECTED_NODE* pn = pr_memory->Get_projected_node(i);
00453 if (!pn->Is_messy_ub()) {
00454 LINEX* ub = pn->Get_upper_linex();
00455 if (ub != NULL)
00456 Map_Linex(IPA_LNO_File, ub, wn_call);
00457 }
00458 if (!pn->Is_messy_lb()) {
00459 LINEX* lb = pn->Get_lower_linex();
00460 if (lb != NULL)
00461 Map_Linex(IPA_LNO_File, lb, wn_call);
00462 }
00463 if (!pn->Is_messy_step()) {
00464 LINEX* step = pn->Get_step_linex();
00465 if (step != NULL)
00466 Map_Linex(IPA_LNO_File, step, wn_call);
00467 }
00468 if (pn->Get_segment_length_linex() != NULL) {
00469 LINEX* lx_segment_length = pn->Get_segment_length_linex();
00470 Map_Linex(IPA_LNO_File, lx_segment_length, wn_call);
00471 }
00472 if (pn->Get_segment_stride_linex() != NULL) {
00473 LINEX* lx_segment_stride = pn->Get_segment_stride_linex();
00474 Map_Linex(IPA_LNO_File, lx_segment_stride, wn_call);
00475 }
00476 }
00477 return pr_memory;
00478 }
00479
00480
00481
00482
00483
00484
00485
00486 static PROJECTED_REGION* Projected_Region_To_Memory(IPA_LNO_READ_FILE*
00487 IPA_LNO_File,
00488 PROJECTED_REGION* pr,
00489 MEM_POOL* mem_pool)
00490 {
00491 PROJECTED_REGION* pr_memory = (PROJECTED_REGION*)
00492 MEM_POOL_Alloc(mem_pool, sizeof(PROJECTED_REGION));
00493 pr_memory->Set_num_dims(pr->Get_num_dims());
00494 pr_memory->Set_type(pr->Get_type());
00495 pr_memory->Set_projected_kernel(NULL);
00496 pr_memory->Set_depth(pr->Get_depth());
00497 if (pr->Is_messy_region()) {
00498 pr_memory->Set_projected_array(NULL);
00499 return pr_memory;
00500 }
00501 PROJECTED_ARRAY* pa = CXX_NEW(PROJECTED_ARRAY(mem_pool), mem_pool);
00502 pr_memory->Set_projected_array(pa);
00503 INT pr_base_index = pr->Get_id();
00504 FmtAssert(pr_base_index >= 0,
00505 ("Projected_Region_To_Memory: Attempt to convert NULL projected region"));
00506 INT pr_count = pr->Get_num_dims();
00507 PROJECTED_NODE* pn = IPA_LNO_File->Projected_Node(pr->Get_id());
00508 PROJECTED_NODE* pn_memory = (PROJECTED_NODE*)
00509 MEM_POOL_Alloc(mem_pool, pr_count * sizeof(PROJECTED_NODE));
00510 bcopy(pn, pn_memory, pr_count * sizeof(PROJECTED_NODE));
00511
00512 INT i;
00513 for (i = 0; i < pr_count; i++)
00514 pn_memory[i].Set_Mem_Pool(mem_pool);
00515 TERM* term_array = IPA_LNO_File->Term(0);
00516 for (i = pr_base_index; i < pr_base_index + pr_count; i++) {
00517 PROJECTED_NODE* pn = IPA_LNO_File->Projected_Node(i);
00518 pn_memory[i - pr_base_index].Create_linex(term_array);
00519 pr_memory->Set_projected_node(&pn_memory[i - pr_base_index]);
00520 }
00521 return pr_memory;
00522 }
00523
00524
00525
00526
00527
00528
00529
00530 extern PROJECTED_REGION* Map_Formal(IPA_LNO_READ_FILE* IPA_LNO_File,
00531 WN* wn_call,
00532 INT idx_formal)
00533 {
00534 IPA_LNO_SUMMARY_FORMAL* sf = IPA_LNO_File->Formal(idx_formal);
00535 INT pr_idx = sf->Decl_Array_Section_Index();
00536 PROJECTED_REGION* pr_original = IPA_LNO_File->Projected_Region(pr_idx);
00537 PROJECTED_REGION* pr_memory = Projected_Region_To_Memory(IPA_LNO_File,
00538 pr_original, &ARA_memory_pool);
00539 PROJECTED_REGION* pr_new = Map_Projected_Region(IPA_LNO_File, pr_memory,
00540 wn_call);
00541 pr_new->Simplify();
00542 pr_new->LNO_Simplify(IPA_LNO_File, wn_call);
00543 return pr_new;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552 extern PROJECTED_REGION* Projected_Region(IPA_LNO_READ_FILE* IPA_LNO_File,
00553 INT idx_pr,
00554 WN* wn_call)
00555 {
00556 PROJECTED_REGION* pr_original = IPA_LNO_File->Projected_Region(idx_pr);
00557 PROJECTED_REGION* pr_memory = Projected_Region_To_Memory(IPA_LNO_File,
00558 pr_original, &ARA_memory_pool);
00559 pr_memory->Simplify();
00560 pr_memory->LNO_Simplify(IPA_LNO_File, wn_call);
00561 return pr_memory;
00562 }
00563
00564
00565
00566
00567
00568
00569
00570 static LINEX* Bound_Difference_To_Linex(IPA_LNO_READ_FILE* IPA_LNO_File,
00571 TY_IDX ty_idx_formal,
00572 INT position)
00573 {
00574 LINEX* lx = CXX_NEW(LINEX(&ARA_memory_pool), &ARA_memory_pool);
00575 if (TY_AR_const_lbnd(ty_idx_formal, position)) {
00576 mINT64 lb_const = TY_AR_lbnd_val(ty_idx_formal, position);
00577 lx->Set_term(LTKIND_CONST, -lb_const, CONST_DESC, 0);
00578 } else {
00579 ST_IDX st_idx = TY_AR_lbnd_var(ty_idx_formal, position);
00580 if (st_idx == ST_IDX_ZERO) {
00581 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00582 fprintf(stdout, "BND LINEX: No lower bound\n");
00583 return NULL;
00584 }
00585 WN* wn_true = True_Bound(Current_Func_Node, st_idx);
00586 if (wn_true == NULL) {
00587 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00588 fprintf(stdout, "BND LINEX: No True_Bound for ST_IDX %d\n",
00589 st_idx);
00590 return NULL;
00591 }
00592 BOOL ok = Exp_To_Linex(wn_true, lx, &ARA_memory_pool, TRUE,
00593 TRUE, IPA_LNO_File);
00594 if (!ok) {
00595 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00596 fprintf(stdout, "BND LINEX: Could not convert exp to linex\n");
00597 return NULL;
00598 }
00599 }
00600 if (TY_AR_const_ubnd(ty_idx_formal, position)) {
00601 mINT64 ub_const = TY_AR_ubnd_val(ty_idx_formal, position);
00602 lx->Set_term(LTKIND_CONST, ub_const, CONST_DESC, 0);
00603 } else {
00604 ST_IDX st_idx = TY_AR_ubnd_var(ty_idx_formal, position);
00605 if (st_idx == ST_IDX_ZERO) {
00606 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00607 fprintf(stdout, "BND LINEX: No upper bound\n");
00608 return NULL;
00609 }
00610 WN* wn_true = True_Bound(Current_Func_Node, st_idx);
00611 if (wn_true == NULL) {
00612 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00613 fprintf(stdout, "BND LINEX: No True_Bound for ST_IDX %d\n",
00614 st_idx);
00615 return NULL;
00616 }
00617 BOOL ok = Exp_To_Linex(wn_true, lx, &ARA_memory_pool, FALSE,
00618 TRUE, IPA_LNO_File);
00619 if (!ok) {
00620 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00621 fprintf(stdout, "BND LINEX: Could not convert exp to linex\n");
00622 return NULL;
00623 }
00624 }
00625 lx->Simplify();
00626 return lx;
00627 }
00628
00629
00630
00631
00632
00633
00634
00635
00636 static BOOL Are_Equal_Dims(IPA_LNO_READ_FILE* IPA_LNO_File,
00637 WN* wn_call,
00638 PROJECTED_REGION* pr,
00639 TY_IDX ty_idx_formal,
00640 INT position)
00641 {
00642 PROJECTED_NODE* pn = pr->Get_projected_node(position);
00643
00644 if (pn->Is_messy_lb() || pn->Is_messy_ub() || pn->Is_messy_step())
00645 return FALSE;
00646 LINEX* lx_ub_st = Bound_Difference_To_Linex(IPA_LNO_File, ty_idx_formal,
00647 position);
00648 if (lx_ub_st == NULL)
00649 return FALSE;
00650 LINEX* lx_ub_pr = pn->Get_upper_linex();
00651 lx_ub_pr->Simplify();
00652 lx_ub_st->Simplify();
00653 lx_ub_pr->LNO_Simplify(IPA_LNO_File, wn_call);
00654 lx_ub_st->LNO_Simplify(IPA_LNO_File, wn_call);
00655 if (!lx_ub_pr->Equivalent(*lx_ub_st))
00656 return FALSE;
00657 return TRUE;
00658 }
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 extern BOOL Shape_Mismatch_At_Formal(IPA_LNO_READ_FILE* IPA_LNO_File,
00670 WN* wn_call,
00671 INT position,
00672 INT idx_formal)
00673 {
00674 if (position < 0 || position >= WN_kid_count(wn_call)) {
00675 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00676 fprintf(stdout,
00677 "SHAPE: Formal/Actual counts do not match for call 0x%p\n", wn_call);
00678 return TRUE;
00679 }
00680 WN* wn_formal = WN_kid(wn_call, position);
00681 char* callee_name = ST_name(WN_st(wn_call));
00682 WN* wn_base = NULL;
00683 WN* wn_argument = wn_formal;
00684 OPCODE op_argument = WN_opcode(wn_formal);
00685 if (OPCODE_operator(op_argument) == OPR_PARM) {
00686 wn_argument = WN_kid0(wn_formal);
00687 op_argument = WN_opcode(WN_kid0(wn_formal));
00688 }
00689 ST* st_argument = NULL;
00690 BOOL scalar_temp = FALSE;
00691 IPA_LNO_SUMMARY_FORMAL* sf = IPA_LNO_File->Formal(idx_formal);
00692 switch (OPCODE_operator(op_argument)) {
00693 case OPR_INTCONST:
00694
00695 return FALSE;
00696 case OPR_ARRAY: {
00697 wn_base = WN_array_base(wn_argument);
00698 OPERATOR opr_base = WN_operator(wn_base);
00699 if (opr_base != OPR_LDID && opr_base != OPR_LDA) {
00700 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO)) {
00701 fprintf(stdout,
00702 "SHAPE: %s ARG %d: Passing complex ARRAY\n",
00703 callee_name, position);
00704 }
00705 return TRUE;
00706 }
00707 st_argument = WN_st(wn_base);
00708 ACCESS_ARRAY* aa = (ACCESS_ARRAY*) WN_MAP_Get(LNO_Info_Map, wn_argument);
00709 if (aa == NULL || Bound_Is_Too_Messy(aa)) {
00710 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00711 fprintf(stdout, "SHAPE: %s ARG %d: NULL or Messy Access Array on Array Section\n",
00712 callee_name, position);
00713 return TRUE;
00714 }
00715 }
00716 break;
00717 case OPR_LDID:
00718 case OPR_LDA: {
00719 if (!sf->Is_May_Kill() && !sf->Is_Use())
00720 return FALSE;
00721 st_argument = WN_st(wn_argument);
00722 }
00723 break;
00724 default: {
00725 DYN_ARRAY<WN*> wn_list(&LNO_local_pool);
00726 DYN_ARRAY<INT> int_list(&LNO_local_pool);
00727 INT64 const_value = 0;
00728 if (!(Scalar_Expr(wn_argument) && Linear_Expr(wn_argument, &wn_list,
00729 &int_list, &const_value))) {
00730 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00731 fprintf(stdout, "SHAPE: %s ARG %d: Odd pass type\n",
00732 callee_name, position);
00733 return TRUE;
00734 } else {
00735 scalar_temp = TRUE;
00736 }
00737 }
00738 }
00739 if (sf->Decl_Array_Section_Index() == -1) {
00740 if (scalar_temp || Is_Scalar(st_argument))
00741 return FALSE;
00742 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00743 fprintf(stdout, "SHAPE: %s ARG %d: Array Passed to Scalar\n",
00744 callee_name, position);
00745 return TRUE;
00746 }
00747 if (sf->Is_Scalar()) {
00748 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00749 fprintf(stdout, "SHAPE: %s ARG %d: Scalar Passed to Array\n",
00750 callee_name, position);
00751 return TRUE;
00752 }
00753 TY_IDX ty_idx_formal = ST_type(st_argument);
00754 if (TY_kind(ty_idx_formal) == KIND_POINTER)
00755 ty_idx_formal = TY_pointed(ty_idx_formal);
00756 if (TY_kind(ty_idx_formal) != KIND_ARRAY) {
00757 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00758 fprintf(stdout, "SHAPE: %s ARG %d: Unusual argument type\n",
00759 callee_name, position);
00760 return TRUE;
00761 }
00762 if (sf->Machine_Type() != Machine_Type(wn_base ? wn_base : wn_argument)) {
00763 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00764 fprintf(stdout, "SHAPE: %s ARG %d: Mismatched machine types\n",
00765 callee_name, position);
00766 return TRUE;
00767 }
00768 return FALSE;
00769 }
00770
00771
00772
00773
00774
00775
00776
00777 extern BOOL Array_Shapes_Match_At_Formal(IPA_LNO_READ_FILE* IPA_LNO_File,
00778 WN* wn_call,
00779 INT position,
00780 PROJECTED_REGION* pr_formal)
00781 {
00782 WN* wn_formal = WN_kid(wn_call, position);
00783 WN* wn_argument = wn_formal;
00784 char* callee_name = ST_name(WN_st(wn_call));
00785 OPCODE op_argument = WN_opcode(wn_formal);
00786 if (OPCODE_operator(op_argument) == OPR_PARM) {
00787 wn_argument = WN_kid0(wn_formal);
00788 op_argument = WN_opcode(WN_kid0(wn_formal));
00789 }
00790 ST* st_argument = NULL;
00791 switch (OPCODE_operator(op_argument)) {
00792 case OPR_ARRAY:
00793 st_argument = WN_st(WN_array_base(wn_argument));
00794 break;
00795 case OPR_LDID:
00796 case OPR_LDA:
00797 st_argument = WN_st(wn_argument);
00798 break;
00799 default:
00800 FmtAssert(FALSE,
00801 ("Array_Shapes_Match_At_Formal: Should have screened these out"));
00802 }
00803 TY_IDX ty_idx_formal = ST_type(st_argument);
00804 if (TY_kind(ty_idx_formal) == KIND_POINTER)
00805 ty_idx_formal = TY_pointed(ty_idx_formal);
00806 FmtAssert(pr_formal != NULL,
00807 ("Array_Shapes_Match_At_Formal: Expecting non-NULL projected region"));
00808 if (TY_AR_ndims(ty_idx_formal) != pr_formal->Get_num_dims()) {
00809 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00810 fprintf(stdout,
00811 "TRY RESHAPE: %s ARG %d: Mismatched Array Dims\n",
00812 callee_name, position);
00813 for (INT i = 0; i < pr_formal->Get_num_dims(); i++) {
00814 PROJECTED_NODE* pn = pr_formal->Get_projected_node(i);
00815 LINEX* lx_lb_pr = pn->Get_lower_linex();
00816 lx_lb_pr->Simplify();
00817 lx_lb_pr->LNO_Simplify(IPA_LNO_File, wn_call);
00818 LINEX* lx_ub_pr = pn->Get_upper_linex();
00819 lx_ub_pr->Simplify();
00820 lx_ub_pr->LNO_Simplify(IPA_LNO_File, wn_call);
00821 }
00822 return FALSE;
00823 }
00824 for (INT i = 1; i < pr_formal->Get_num_dims(); i++) {
00825 if (!Are_Equal_Dims(IPA_LNO_File, wn_call, pr_formal, ty_idx_formal, i)) {
00826 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO))
00827 fprintf(stdout, "TRY RESHAPE: %s ARG %d: Mismatched Array Subs\n",
00828 callee_name, position);
00829 return FALSE;
00830 }
00831 }
00832 return TRUE;
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842 extern BOOL Shape_Mismatch_At_Common(IPA_LNO_READ_FILE* IPA_LNO_File,
00843 INT idx_global)
00844 {
00845 IPA_LNO_SUMMARY_GLOBAL* sc = IPA_LNO_File->Global(idx_global);
00846 if (sc->Is_Scalar())
00847 return FALSE;
00848 return ST_is_equivalenced(ST_ptr(sc->St_Idx()));
00849 }
00850