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
00059
00060
00061 #define __STDC_LIMIT_MACROS
00062 #include <stdint.h>
00063 #ifdef USE_PCH
00064 #include "lno_pch.h"
00065 #endif // USE_PCH
00066 #pragma hdrstop
00067
00068 #include "call_info.h"
00069 #include "lwn_util.h"
00070 #include "targ_const.h"
00071 #include "opt_du.h"
00072 #include "debug.h"
00073 #include "tlog.h"
00074 #include "ipa_lno_read.h"
00075
00076 extern MEM_POOL ARA_memory_pool;
00077
00078 void CALL_INFO::Print(FILE *fp)
00079 {
00080 fprintf(fp, "CALL %s FROM %s AT 0x%p. ", WB_Whirl_Symbol(_wn_call),
00081 ST_name(WN_st(Current_Func_Node)), _wn_call);
00082 if (_needs_evaluation)
00083 fprintf(fp, "Needs evaluation. ");
00084 if (_needs_evaluation) {
00085 if (_is_evaluated)
00086 fprintf(fp, "Evaluated. ");
00087 else
00088 fprintf(fp, "Unevaluated. ");
00089 }
00090 fprintf(fp, "\n");
00091 _ara_call->CI_Print(fp);
00092 if (_value != NULL) {
00093 for (INT i = 0; i <= _value->Lastidx(); i++)
00094 (*_value)[i].WB_Print(fp, i);
00095 } else {
00096 fprintf(fp, "NULL SUMMARY_VALUEs\n");
00097 }
00098 if (_expr != NULL) {
00099 for (INT i = 0; i <= _expr->Lastidx(); i++)
00100 (*_expr)[i].WB_Print(fp, i);
00101 } else {
00102 fprintf(fp, "NULL SUMMARY_EXPRs\n");
00103 }
00104 }
00105
00106 void CALL_INFO::Tlog_Print()
00107 {
00108 char bf[MAX_TLOG_CHARS];
00109 INT new_ccount = 0;
00110 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "CALL ");
00111 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS,
00112 (char*) WB_Whirl_Symbol(_wn_call));
00113 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, " FROM ");
00114 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS,
00115 ST_name(WN_st(Current_Func_Node)));
00116 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, ". ");
00117 Generate_Tlog("LNO", "Call_Info", (SRCPOS) 0, "", "", "", bf);
00118 new_ccount = 0;
00119 if (_needs_evaluation)
00120 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS,
00121 "Needs evaluation. ");
00122 if (_needs_evaluation) {
00123 if (_is_evaluated)
00124 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "Evaluated. ");
00125 else
00126 new_ccount = snprintfs(bf, new_ccount, MAX_TLOG_CHARS, "Unevaluated. ");
00127 }
00128 if (new_ccount > 0)
00129 Generate_Tlog("LNO", "Call_Info", (SRCPOS) 0, "", "", "", bf);
00130 _ara_call->Tlog_CI_Print();
00131
00132 }
00133
00134
00135
00136
00137 static ACCESS_VECTOR *Wn_To_Access_Vector(
00138 WN* wn, INT16 loop_depth, DOLOOP_STACK *loop_stack)
00139 {
00140 ST* st=WN_st(wn);
00141 ACCESS_VECTOR* av=
00142 CXX_NEW(ACCESS_VECTOR((INT64)loop_depth,&ARA_memory_pool),
00143 &ARA_memory_pool);
00144 av->Too_Messy=FALSE;
00145 if (ST_class(st)==CLASS_CONST) {
00146 av->Const_Offset=Targ_To_Host(STC_val(st));
00147 } else {
00148 SYMBOL sym(wn);
00149 av->Add_Symbol(1,sym,loop_stack,wn);
00150 }
00151 return av;
00152 }
00153
00154
00155
00156 static ACCESS_ARRAY *Create_Dummy_Access_Array(INT16 dim, INT16 loop_depth)
00157 {
00158 ACCESS_ARRAY* kernel=
00159 CXX_NEW(ACCESS_ARRAY(dim,loop_depth,&ARA_memory_pool),
00160 &ARA_memory_pool);
00161 for (INT i=0; i<dim; i++)
00162 for (INT j=0; j<loop_depth; j++) {
00163 kernel->Dim(i)->Set_Loop_Coeff(j,0);
00164 kernel->Dim(i)->Too_Messy=FALSE;
00165 }
00166 kernel->Too_Messy=FALSE;
00167 return kernel;
00168 }
00169
00170
00171
00172 static void Prepare_Axle(
00173 WN* lb_wn, WN* ub_wn, WN* stride_wn,
00174 INT16 loop_depth, DOLOOP_STACK* loop_stack,
00175 REGION* array_reg, INT16 axle_id)
00176 {
00177 ST* stride_st=WN_st(stride_wn);
00178
00179 ACCESS_VECTOR* lbav=Wn_To_Access_Vector(lb_wn,loop_depth,loop_stack);
00180 if (lbav->Has_Loop_Coeff()) {
00181 BOOL* is_independent=array_reg->_kernel->Get_Independent_Loops();
00182 for (INT k=0; k<loop_depth; k++)
00183 if (lbav->Loop_Coeff(k))
00184 is_independent[k]=FALSE;
00185 }
00186 CON_PAIR* lbcp=CXX_NEW(CON_PAIR(lbav),&ARA_memory_pool);
00187
00188 ACCESS_VECTOR* ubav=Wn_To_Access_Vector(ub_wn,loop_depth,loop_stack);
00189 if (ubav->Has_Loop_Coeff()) {
00190 BOOL* is_independent=array_reg->_kernel->Get_Independent_Loops();
00191 for (INT k=0; k<loop_depth; k++)
00192 if (ubav->Loop_Coeff(k))
00193 is_independent[k]=FALSE;
00194 }
00195 CON_PAIR* ubcp=CXX_NEW(CON_PAIR(ubav),&ARA_memory_pool);
00196
00197 INT stride=Targ_To_Host(STC_val(stride_st));
00198
00199 if (*lbav == *ubav) {
00200 array_reg->_axle[axle_id].Set_Axle(lbcp,0,stride,array_reg->Num_Dim());
00201 } else {
00202 array_reg->_axle[axle_id].Set_Axle(lbcp,ubcp,
00203 stride,array_reg->Num_Dim());
00204 }
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 static void Scan_Parameters(WN* call_stmt, ARA_LOOP_INFO* ali)
00217 {
00218 INT16 loop_depth=Do_Loop_Depth(Enclosing_Do_Loop(call_stmt))+1;
00219 DOLOOP_STACK *loop_stack=CXX_NEW(DOLOOP_STACK(&ARA_memory_pool),
00220 &ARA_memory_pool);
00221 Build_Doloop_Stack(call_stmt, loop_stack);
00222 INT16 kidno=0;
00223 while (kidno+5<WN_kid_count(call_stmt)) {
00224 WN* array_wn=WN_kid0(WN_kid(call_stmt,kidno++));
00225 SYMBOL array_sym(array_wn);
00226 ST* array_st=WN_st(array_wn);
00227 TY_IDX array_ty=ST_type(array_st);
00228 if (TY_kind(array_ty)==KIND_POINTER)
00229 array_ty=TY_pointed(array_ty);
00230 INT dim=TY_AR_ndims(array_ty);
00231 WN* read_or_write=WN_kid0(WN_kid(call_stmt,kidno++));
00232 ST* rw_st=WN_st(read_or_write);
00233 BOOL is_read=((*Targ_String_Address(STC_val(rw_st))=='r'));
00234
00235 REGION* array_reg=CXX_NEW(REGION(0,dim),&ARA_memory_pool);
00236 array_reg->_axle=CXX_NEW_ARRAY(AXLE_NODE,dim,&ARA_memory_pool);
00237 array_reg->_type=ARA_NORMAL;
00238 array_reg->_coupled=FALSE;
00239 array_reg->_wn_list.Push(call_stmt);
00240 ACCESS_ARRAY* kernel=Create_Dummy_Access_Array(dim,loop_depth);
00241 array_reg->_kernel=CXX_NEW(KERNEL_IMAGE(kernel), &ARA_memory_pool);
00242
00243 for (INT16 i=0; i<dim; i++) {
00244 WN* lb=WN_kid0(WN_kid(call_stmt,kidno++));
00245 WN* ub=WN_kid0(WN_kid(call_stmt,kidno++));
00246 WN* stride=WN_kid0(WN_kid(call_stmt,kidno++));
00247 Prepare_Axle(lb,ub,stride, loop_depth, loop_stack, array_reg, i);
00248 }
00249 REGION* new_region=CXX_NEW(REGION(*array_reg),&ARA_memory_pool);
00250 array_reg->_kernel->Set_Region(new_region);
00251
00252 ARA_REF* new_ref=CXX_NEW(ARA_REF(&array_sym, array_reg, ali, TRUE),
00253 &ARA_memory_pool);
00254 if (is_read)
00255 ali->Add_Use(new_ref);
00256 else
00257 ali->Add_Def(new_ref);
00258
00259 }
00260 }
00261
00262
00263
00264
00265 void Process_Call(WN* call_stmt)
00266 {
00267 char* name=ST_name(WN_st(call_stmt));
00268 if (strncmp(name,"lno_test",8))
00269 return;
00270 ARA_LOOP_INFO* ali=CXX_NEW(ARA_LOOP_INFO(call_stmt, NULL, TRUE),
00271 &ARA_memory_pool);
00272 Scan_Parameters(call_stmt,ali);
00273 ali->Print(stdout);
00274 CALL_INFO* call_info=CXX_NEW(CALL_INFO(ali, call_stmt, FALSE,
00275 &ARA_memory_pool), &ARA_memory_pool);
00276 Set_Call_Info(call_stmt, call_info);
00277 }
00278
00279 extern void Call_Info_Walk(WN* root)
00280 {
00281 WN* call_stmt=root;
00282 while (call_stmt=LWN_Get_Next_Stmt_Node(call_stmt)) {
00283
00284 if (WN_operator(call_stmt)==OPR_CALL)
00285 Process_Call(call_stmt);
00286 }
00287
00288 }
00289
00290
00291
00292
00293
00294
00295
00296 static void IPA_LNO_Evaluate_Scalar_Formals(WN* wn_call,
00297 INT formal_number,
00298 SCALAR_STACK* st_scalar)
00299 {
00300 WN* wn_symbol = NULL;
00301 WN* wn_parm = WN_kid(wn_call, formal_number);
00302 FmtAssert(WN_operator(wn_parm) == OPR_PARM,
00303 ("IPA_LNO_Evaluate_Scalar_Formals: Expecting PARM node"));
00304 WN* wn_lda = WN_kid0(wn_parm);
00305 if (WN_operator(wn_lda) == OPR_INTCONST)
00306 return;
00307 for (INT i = 0; i < st_scalar->Elements(); i++) {
00308 SCALAR_NODE* sn = st_scalar->Bottom_nth(i);
00309 DYN_ARRAY<WN*> wn_list(&LNO_local_pool);
00310 DYN_ARRAY<INT> int_list(&LNO_local_pool);
00311 INT64 const_value = 0;
00312 if (sn->_scalar.Is_Formal() &&
00313 sn->_scalar.Formal_Number() == formal_number) {
00314 if (WN_operator(wn_lda) == OPR_LDA || WN_operator(wn_lda) == OPR_LDID) {
00315 SYMBOL sym_lda(WN_st(wn_lda), WN_offset(wn_lda), sn->_scalar.Type);
00316 WN* wn_single = Single_Definition_Temp(wn_lda);
00317 if (wn_single != NULL && Scalar_Expr(wn_single))
00318 Add_Scalars_In_Expr(wn_single, st_scalar);
00319 st_scalar->Add_Scalar(wn_lda, &sym_lda, 0);
00320 } else if (Scalar_Expr(wn_lda) && Linear_Expr(wn_lda, &wn_list,
00321 &int_list, &const_value)) {
00322 Add_Scalars_In_Expr(wn_lda, st_scalar);
00323 } else {
00324 FmtAssert(FALSE,
00325 ("IPA_LNO_Read_Formal: Expecting LDA, LDID, INTCONST, or S-LIN Exp"));
00326 }
00327 }
00328 st_scalar->Clear_Formal(formal_number);
00329 }
00330 }
00331
00332
00333
00334
00335
00336
00337
00338
00339 static WN* IPA_LNO_Find_Formal_Value(WN* wn_call,
00340 INT formal_number)
00341 {
00342 WN* wn_use = WN_kid(wn_call, formal_number);
00343 FmtAssert(WN_operator(wn_use) == OPR_PARM,
00344 ("IPA_LNO_Find_Formal_Value: Expecting PARM node"));
00345 if (WN_Parm_By_Reference(wn_use)) {
00346 LWN_ITER* itr = LWN_WALK_TreeIter(wn_use);
00347 DEF_LIST *def_list = Du_Mgr->Ud_Get_Def(wn_use);
00348 if (def_list == NULL)
00349 return NULL;
00350 DEF_LIST_ITER iter(def_list);
00351 const DU_NODE* node = NULL;
00352 WN* wn_def = NULL;
00353 for (node = iter.First(); !iter.Is_Empty(); node = iter.Next()) {
00354 if (wn_def != NULL)
00355 return NULL;
00356 wn_def = node->Wn();
00357 }
00358 if (wn_def == NULL)
00359 return NULL;
00360 wn_use = WN_kid0(wn_def);
00361 } else {
00362 wn_use = WN_kid0(wn_use);
00363 }
00364 return wn_use;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374 static void IPA_LNO_Evaluate_Array_Formals(ARA_REF_ST* st,
00375 WN* wn_call,
00376 INT formal_number)
00377 {
00378 WN* wn_use = NULL;
00379 DOLOOP_STACK* stack = NULL;
00380 for (INT i = 0; i < st->Elements(); i++) {
00381 ARA_REF* ar = st->Bottom_nth(i);
00382 REGION_UN* rgun = &ar->Image();
00383 if (rgun == NULL)
00384 continue;
00385 REGION_ITER iter(rgun);
00386 for (REGION* rg = iter.First(); !iter.Is_Empty(); iter.Next()) {
00387 if (rg->_type == ARA_TOP || rg->_type == ARA_BOTTOM
00388 || rg->_type == ARA_TOO_MESSY)
00389 continue;
00390 for (INT i = 0; i < rg->_dim; i++) {
00391 AXLE_NODE* ax = &rg->_axle[i];
00392 CON_PAIR* cp_lo = ax->lo;
00393
00394 if (cp_lo != NULL) {
00395 ACCESS_VECTOR* av_lo = cp_lo->_ac_v;
00396 if (av_lo != NULL) {
00397 if (wn_use == NULL) {
00398 wn_use = IPA_LNO_Find_Formal_Value(wn_call, formal_number);
00399 if (wn_use != NULL) {
00400 stack = CXX_NEW(DOLOOP_STACK(&LNO_local_pool),&LNO_local_pool);
00401 Build_Doloop_Stack(LWN_Get_Parent(wn_use), stack);
00402 LNO_Build_Access(wn_use, stack, &LNO_default_pool);
00403 }
00404 }
00405 av_lo->Substitute(formal_number, wn_use, stack,
00406 LNO_Allow_Nonlinear);
00407 }
00408 }
00409 CON_PAIR* cp_up = ax->up;
00410 if (cp_up != NULL) {
00411 ACCESS_VECTOR* av_up = cp_up->_ac_v;
00412 if (av_up != NULL) {
00413 if (wn_use == NULL) {
00414 wn_use = IPA_LNO_Find_Formal_Value(wn_call, formal_number);
00415 if (wn_use != NULL) {
00416 stack = CXX_NEW(DOLOOP_STACK(&LNO_local_pool), &LNO_local_pool); Build_Doloop_Stack(LWN_Get_Parent(wn_use), stack);
00417 LNO_Build_Access(wn_use, stack, &LNO_default_pool);
00418 }
00419 }
00420 av_up->Substitute(formal_number, wn_use, stack,
00421 LNO_Allow_Nonlinear);
00422 }
00423 }
00424 }
00425 }
00426 }
00427 }
00428
00429
00430
00431
00432
00433
00434
00435 static void IPA_LNO_Evaluate_Formal_Symbols(WN* wn_call)
00436 {
00437 if (!Has_Call_Info(wn_call))
00438 return;
00439 CALL_INFO* ci = Get_Call_Info(wn_call);
00440 ARA_LOOP_INFO* ali = ci->Call_Ara_Info();
00441 for (INT i = 0; i < WN_kid_count(wn_call); i++) {
00442 SCALAR_STACK* st_sdef = &ali->SCALAR_MAY_DEF();
00443 IPA_LNO_Evaluate_Scalar_Formals(wn_call, i, st_sdef);
00444 SCALAR_STACK* st_suse = &ali->SCALAR_USE();
00445 IPA_LNO_Evaluate_Scalar_Formals(wn_call, i, st_suse);
00446 ARA_REF_ST* st_def = &ali->MAY_DEF();
00447 IPA_LNO_Evaluate_Array_Formals(st_def, wn_call, i);
00448 ARA_REF_ST* st_use = &ali->USE();
00449 IPA_LNO_Evaluate_Array_Formals(st_use, wn_call, i);
00450 }
00451 if (Get_Trace(TP_LNOPT2, TT_CALL_INFO)) {
00452 fprintf(stdout, "==========\n");
00453 fprintf(stdout, "EVALUATING %s AT 0x%p\n", WB_Whirl_Symbol(wn_call),
00454 wn_call);
00455 CALL_INFO* call_info = (CALL_INFO *) WN_MAP_Get(LNO_Info_Map, wn_call);
00456 call_info->Print(stdout);
00457 }
00458 }
00459
00460
00461
00462
00463
00464
00465 void CALL_INFO::Evaluate()
00466 {
00467 if (!_needs_evaluation)
00468 return;
00469 if (_is_evaluated) {
00470 DevWarn("CALL_INFO::Evaluate: Already evaluated");
00471 return;
00472 }
00473 FmtAssert(_wn_call != NULL,
00474 ("CALL_INFO::Evaluate: Must be assigned to particular call"));
00475
00476 _ara_call_save = CXX_NEW(ARA_LOOP_INFO(_ara_call), _pool);
00477 ARA_LOOP_INFO* ali = Call_Ara_Info();
00478 for (INT i = 0; i < WN_kid_count(_wn_call); i++) {
00479 SCALAR_STACK* st_sdef = &ali->SCALAR_MAY_DEF();
00480 IPA_LNO_Evaluate_Scalar_Formals(_wn_call, i, st_sdef);
00481 SCALAR_STACK* st_suse = &ali->SCALAR_USE();
00482 IPA_LNO_Evaluate_Scalar_Formals(_wn_call, i, st_suse);
00483 ARA_REF_ST* st_def = &ali->MAY_DEF();
00484 IPA_LNO_Evaluate_Array_Formals(st_def, _wn_call, i);
00485 ARA_REF_ST* st_use = &ali->USE();
00486 IPA_LNO_Evaluate_Array_Formals(st_use, _wn_call, i);
00487 }
00488 _is_evaluated = TRUE;
00489 }
00490
00491
00492
00493
00494
00495
00496 void CALL_INFO::Unevaluate()
00497 {
00498 if (!_needs_evaluation)
00499 return;
00500 if (!_is_evaluated) {
00501 DevWarn("CALL_INFO::Unevaluate: Already unevaluated");
00502 return;
00503 }
00504 CXX_DELETE(_ara_call, _pool);
00505 _ara_call = _ara_call_save;
00506 _ara_call_save = NULL;
00507 _is_evaluated = FALSE;
00508 }
00509
00510
00511
00512
00513
00514
00515 CALL_INFO::CALL_INFO(CALL_INFO* ci)
00516 {
00517 FmtAssert(ci != NULL,
00518 ("CALL_INFO constructor: Called with NULL pointer"));
00519 _is_evaluated = ci->_is_evaluated;
00520 _needs_evaluation = ci->_needs_evaluation;
00521 _wn_call = ci->_wn_call;
00522 _pool = ci->_pool;
00523 FmtAssert(_pool == &ARA_memory_pool,
00524 ("CALL_INFO::CALL_INFO: can only allocate from ARA_memory_pool"));
00525 if (_ara_call != NULL)
00526 _ara_call = CXX_NEW(ARA_LOOP_INFO(ci->_ara_call), _pool);
00527 if (_ara_call_save != NULL)
00528 _ara_call_save = CXX_NEW(ARA_LOOP_INFO(ci->_ara_call_save), _pool);
00529 _value = CXX_NEW(DYN_ARRAY<SUMMARY_VALUE>(_pool), _pool);
00530 INT i;
00531 for (i = 0; i <= ci->_value->Lastidx(); i++)
00532 _value->AddElement((*(ci->_value))[i]);
00533 _expr = CXX_NEW(DYN_ARRAY<SUMMARY_EXPR>(_pool), _pool);
00534 for (i = 0; i <= ci->_expr->Lastidx(); i++)
00535 _expr->AddElement((*(ci->_expr))[i]);
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 BOOL CALL_INFO::Has_Formal_Parameter()
00548 {
00549 ARA_LOOP_INFO* ali = Call_Ara_Info();
00550 if (ali == NULL)
00551 return FALSE;
00552 SCALAR_STACK* st_scalar = &ali->SCALAR_MAY_DEF();
00553 INT i;
00554 for (i = 0; i < st_scalar->Elements(); i++) {
00555 SCALAR_NODE* sn = st_scalar->Bottom_nth(i);
00556 if (sn->_scalar.Is_Formal())
00557 return TRUE;
00558 }
00559 st_scalar = &ali->SCALAR_USE();
00560 for (i = 0; i < st_scalar->Elements(); i++) {
00561 SCALAR_NODE* sn = st_scalar->Bottom_nth(i);
00562 if (sn->_scalar.Is_Formal())
00563 return TRUE;
00564 }
00565 for (i = 0; i < ali->MAY_DEF().Elements(); i++) {
00566 ARA_REF* ara_ref = ali->MAY_DEF().Bottom_nth(i);
00567 if (ara_ref->Has_Formal_Parameter())
00568 return TRUE;
00569 }
00570 for (i = 0; i < ali->USE().Elements(); i++) {
00571 ARA_REF* ara_ref = ali->USE().Bottom_nth(i);
00572 if (ara_ref->Has_Formal_Parameter())
00573 return TRUE;
00574 }
00575 return FALSE;
00576 }