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 #define __STDC_LIMIT_MACROS
00041 #include <stdint.h>
00042 #if defined(BUILD_OS_DARWIN)
00043 #include <darwin_elf.h>
00044 #else
00045 #include <elf.h>
00046 #endif
00047 #include "ipl_summary.h"
00048 #include "ipa_cg.h"
00049 #include "ipa_section_main.h"
00050 #include "ipa_section_annot.h"
00051 #include "ipa_cost_util.h"
00052 #include "be_util.h"
00053 #include "ipa_option.h"
00054 #include "ipaa.h"
00055
00056
00057
00058 static INT IPA_EX_Copy_Expr_Tree(IPA_NODE* ipan_caller,
00059 SUMMARY_VALUE* sv_old,
00060 SUMMARY_EXPR* sx_old,
00061 DYN_ARRAY<SUMMARY_VALUE>* sv_new,
00062 DYN_ARRAY<SUMMARY_EXPR>* sx_new,
00063 INT sx_old_index);
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 static void Convert_Global_To_St_Idx(IPA_NODE* ipan,
00074 SUMMARY_VALUE* svv)
00075 {
00076 FmtAssert(svv->Is_global(),
00077 ("Convert_Global_To_St_Idx: Expecting a global value"));
00078 FmtAssert(!svv->Is_global_st_idx(),
00079 ("Convert_Global_To_St_Idx: Expecting global in symbol index format"));
00080 INT symbol_index = svv->Get_global_index();
00081 SUMMARY_SYMBOL* symbol_array = IPA_get_symbol_array(ipan);
00082 SUMMARY_SYMBOL* ss = &symbol_array[symbol_index];
00083 ST_IDX st_idx = ss->St_idx();
00084 svv->Set_global_index(-1);
00085 svv->Set_is_global_st_idx();
00086 svv->Set_global_st_idx(st_idx);
00087 }
00088
00089
00090
00091
00092
00093
00094
00095 extern void Update_Execution_Cost(IPA_NODE* ipan,
00096 MEM_POOL* mem_pool)
00097 {
00098 DYN_ARRAY<SUMMARY_VALUE>* sv
00099 = CXX_NEW(DYN_ARRAY<SUMMARY_VALUE>(mem_pool), mem_pool);
00100 DYN_ARRAY<SUMMARY_EXPR>* sx
00101 = CXX_NEW(DYN_ARRAY<SUMMARY_EXPR>(mem_pool), mem_pool);
00102 IPA_NODE_SECTION_INFO* si = ipan->Section_Annot();
00103 si->Set_value(sv);
00104 si->Set_expr(sx);
00105 SUMMARY_PROCEDURE* sp = ipan->Summary_Proc();
00106 INT value_index = sp->Get_ex_value_index();
00107 INT value_count = sp->Get_ex_value_count();
00108 INT expr_index = sp->Get_ex_expr_index();
00109 INT expr_count = sp->Get_ex_expr_count();
00110 INT formal_index = sp->Get_formal_index();
00111 INT global_index = sp->Get_global_index();
00112 SUMMARY_VALUE* value_array = IPA_get_value_array(ipan);
00113 INT i;
00114
00115 for (i = value_index; i < value_index + value_count; i++) {
00116 SUMMARY_VALUE* svv = value_array + i;
00117 sv->AddElement(*svv);
00118 }
00119 SUMMARY_EXPR* expr_array = IPA_get_expr_array(ipan);
00120 for (i = expr_index; i < expr_index + expr_count; i++) {
00121 SUMMARY_EXPR* sxx = expr_array + i;
00122 sx->AddElement(*sxx);
00123 }
00124 IPL_EX_Add_Value_Offsets(sv, -formal_index, -global_index);
00125 IPL_EX_Add_Expr_Offsets(sx, -value_index, -expr_index);
00126
00127 for (i = 0; i <= sv->Lastidx(); i++) {
00128 SUMMARY_VALUE* svv = &(*sv)[i];
00129 if (svv->Is_global())
00130 Convert_Global_To_St_Idx(ipan, svv);
00131 }
00132 }
00133
00134
00135
00136
00137
00138
00139
00140
00141 static BOOL Execution_Count_Evaluated(IPA_NODE* ipan)
00142 {
00143 IPA_NODE_SECTION_INFO* si = ipan->Section_Annot();
00144 DYN_ARRAY<SUMMARY_VALUE>* sv = si->Get_value();
00145 for (INT i = 0; i <= sv->Lastidx(); i++) {
00146 SUMMARY_VALUE* svv = &(*sv)[i];
00147 if (svv->Is_callsite())
00148 return FALSE;
00149 }
00150 return TRUE;
00151 }
00152
00153
00154
00155
00156
00157
00158
00159 static BOOL IPA_EX_Valid_Opcode(OPCODE opcode)
00160 {
00161 switch (opcode) {
00162 case OPC_I4ADD:
00163 case OPC_I4MPY:
00164 case OPC_I4NEG:
00165 case OPC_I4SUB:
00166 case OPC_I4DIV:
00167 return TRUE;
00168 default:
00169 return FALSE;
00170 }
00171 }
00172
00173
00174
00175
00176
00177
00178
00179 static BOOL Is_Exported(ST_IDX st_idx)
00180 {
00181 ST_EXPORT st_export = ST_export(St_Table[st_idx]);
00182 return st_export != EXPORT_LOCAL && st_export != EXPORT_LOCAL_INTERNAL;
00183 }
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 static BOOL IPA_EX_Valid_Value(IPA_NODE* ipan_caller,
00195 INT value_index)
00196 {
00197 SUMMARY_VALUE* value_array = IPA_get_value_array(ipan_caller);
00198 SUMMARY_VALUE* svv = &value_array[value_index];
00199 if (svv->Is_global()) {
00200 FmtAssert(!svv->Is_global_st_idx(),
00201 ("IPA_EX_Valid_Value: Expecting global in symbol index format"));
00202 IPAA_NODE_INFO* ipaa = ipan_caller->Mod_Ref_Info();
00203 SUMMARY_VALUE svv_test;
00204 bcopy(svv, &svv_test, sizeof(SUMMARY_VALUE));
00205 Convert_Global_To_St_Idx(ipan_caller, &svv_test);
00206 ST_IDX st_idx = svv_test.Get_global_st_idx();
00207 ST_IDX st_idx_test = 0;
00208 if (ST_is_split_common(St_Table[st_idx])) {
00209 st_idx_test = ST_full_idx(St_Table[st_idx]);
00210 } else {
00211 for (st_idx_test = st_idx;
00212 ST_base_idx(St_Table[st_idx_test]) != st_idx_test
00213 && !Is_Exported(st_idx_test);
00214 st_idx_test = ST_base_idx(St_Table[st_idx_test]));
00215 if (!Is_Exported(st_idx_test))
00216 return FALSE;
00217 }
00218 UINT32 mod_ref_key = ST_IDX_index(st_idx_test);
00219 if (ipaa->Is_def_elmt(mod_ref_key))
00220 return FALSE;
00221 return TRUE;
00222 }
00223 return svv->Is_int_const() || svv->Is_const_st() || svv->Is_formal();
00224 }
00225
00226
00227
00228
00229
00230
00231
00232 static BOOL IPA_EX_Valid_Expr(IPA_NODE* ipan,
00233 INT expr_index)
00234 {
00235 SUMMARY_EXPR* expr_array = IPA_get_expr_array(ipan);
00236 SUMMARY_EXPR* sxx = &expr_array[expr_index];
00237 if (!IPA_EX_Valid_Opcode(sxx->Get_opcode()))
00238 return FALSE;
00239 if (sxx->Has_const_operand()) {
00240 if (sxx->Is_expr_value(0))
00241 return IPA_EX_Valid_Value(ipan, sxx->Get_node_index(0));
00242 else if (sxx->Is_expr_expr(0))
00243 return IPA_EX_Valid_Expr(ipan, sxx->Get_node_index(0));
00244 return FALSE;
00245 } else {
00246 if (sxx->Is_expr_value(0)) {
00247 if (!IPA_EX_Valid_Value(ipan, sxx->Get_node_index(0)))
00248 return FALSE;
00249 } else if (sxx->Is_expr_expr(0)) {
00250 if (!IPA_EX_Valid_Expr(ipan, sxx->Get_node_index(0)))
00251 return FALSE;
00252 } else {
00253 return FALSE;
00254 }
00255 if (sxx->Is_expr_value(1)) {
00256 if (!IPA_EX_Valid_Value(ipan, sxx->Get_node_index(1)))
00257 return FALSE;
00258 } else if (sxx->Is_expr_expr(1)) {
00259 if (!IPA_EX_Valid_Expr(ipan, sxx->Get_node_index(1)))
00260 return FALSE;
00261 } else {
00262 return FALSE;
00263 }
00264 }
00265 return TRUE;
00266 }
00267
00268
00269
00270
00271
00272
00273
00274 static BOOL IPA_EX_Value_Expr_Tree(IPA_NODE* ipan,
00275 SUMMARY_VALUE* svv)
00276 {
00277 if (!svv->Is_expr())
00278 return FALSE;
00279 return IPA_EX_Valid_Expr(ipan, svv->Get_expr_index());
00280 }
00281
00282
00283
00284
00285
00286
00287
00288
00289 static INT IPA_EX_Copy_Value(IPA_NODE* ipan_caller,
00290 SUMMARY_VALUE* sv_old,
00291 DYN_ARRAY<SUMMARY_VALUE>* sv_new,
00292 INT sv_old_index)
00293 {
00294 INT sv_new_index = sv_new->Newidx();
00295 SUMMARY_VALUE* svv_old = &sv_old[sv_old_index];
00296 SUMMARY_VALUE* svv_new = &(*sv_new)[sv_new_index];
00297 bcopy(svv_old, svv_new, sizeof(SUMMARY_VALUE));
00298 if (svv_new->Is_formal()) {
00299 SUMMARY_PROCEDURE* sp_caller = ipan_caller->Summary_Proc();
00300 INT base_caller_formal = sp_caller->Get_formal_index();
00301 INT new_formal_index = svv_new->Get_formal_index() - base_caller_formal;
00302 svv_new->Set_formal_index(new_formal_index);
00303 } else if (svv_new->Is_global()) {
00304 Convert_Global_To_St_Idx(ipan_caller, svv_new);
00305 }
00306 return sv_new_index;
00307 }
00308
00309
00310
00311
00312
00313
00314
00315 static INT IPA_EX_Copy_Expr(SUMMARY_EXPR* sx_old,
00316 DYN_ARRAY<SUMMARY_EXPR>* sx_new,
00317 INT sx_old_index)
00318 {
00319 INT sx_new_index = sx_new->Newidx();
00320 SUMMARY_EXPR* sxx_old = &sx_old[sx_old_index];
00321 SUMMARY_EXPR* sxx_new = &(*sx_new)[sx_new_index];
00322 bcopy(sxx_old, sxx_new, sizeof(SUMMARY_EXPR));
00323 return sx_new_index;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 static INT IPA_EX_Set_Expr_Index(IPA_NODE* ipan_caller,
00335 SUMMARY_VALUE* sv_old,
00336 SUMMARY_EXPR* sx_old,
00337 DYN_ARRAY<SUMMARY_VALUE>* sv_new,
00338 DYN_ARRAY<SUMMARY_EXPR>* sx_new,
00339 SUMMARY_EXPR* sxx_old,
00340 INT kid)
00341 {
00342 if (sxx_old->Is_expr_value(kid)) {
00343 INT sv_old_index = sxx_old->Get_node_index(kid);
00344 INT sv_new_index = IPA_EX_Copy_Value(ipan_caller, sv_old, sv_new,
00345 sv_old_index);
00346 return sv_new_index;
00347 } else if (sxx_old->Is_expr_expr(kid)) {
00348 INT sxx_old_index = sxx_old->Get_node_index(kid);
00349 INT sxx_new_index = IPA_EX_Copy_Expr_Tree(ipan_caller, sv_old, sx_old,
00350 sv_new, sx_new, sxx_old_index);
00351 return sxx_new_index;
00352 } else {
00353 FmtAssert(FALSE,
00354 ("IPA_EX_Set_Expr_Index: Not handling this case yet"));
00355 return -1;
00356 }
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366 static INT IPA_EX_Copy_Expr_Tree(IPA_NODE* ipan_caller,
00367 SUMMARY_VALUE* sv_old,
00368 SUMMARY_EXPR* sx_old,
00369 DYN_ARRAY<SUMMARY_VALUE>* sv_new,
00370 DYN_ARRAY<SUMMARY_EXPR>* sx_new,
00371 INT sx_old_index)
00372 {
00373 SUMMARY_EXPR* sxx_old = &sx_old[sx_old_index];
00374 INT sx_expr_one = -1;
00375 INT sx_expr_two = -1;
00376 INT sx_new_index = -1;
00377 if (sxx_old->Has_const_operand()) {
00378 sx_expr_one = IPA_EX_Set_Expr_Index(ipan_caller, sv_old, sx_old,
00379 sv_new, sx_new, sxx_old, 0);
00380 sx_new_index = IPA_EX_Copy_Expr(sx_old, sx_new, sx_old_index);
00381 SUMMARY_EXPR* sxx_new = &(*sx_new)[sx_new_index];
00382 sxx_new->Set_node_index(0, sx_expr_one);
00383 } else {
00384 sx_expr_one = IPA_EX_Set_Expr_Index(ipan_caller, sv_old, sx_old,
00385 sv_new, sx_new, sxx_old, 0);
00386 sx_expr_two = IPA_EX_Set_Expr_Index(ipan_caller, sv_old, sx_old,
00387 sv_new, sx_new, sxx_old, 1);
00388 sx_new_index = IPA_EX_Copy_Expr(sx_old, sx_new, sx_old_index);
00389 SUMMARY_EXPR* sxx_new = &(*sx_new)[sx_new_index];
00390 sxx_new->Set_node_index(0, sx_expr_one);
00391 sxx_new->Set_node_index(1, sx_expr_two);
00392 }
00393 return sx_new_index;
00394 }
00395
00396
00397
00398
00399
00400
00401
00402
00403 static BOOL IPA_EX_Can_Evaluate_At_Callsite(IPA_NODE* ipan_caller,
00404 IPA_NODE* ipan_callee,
00405 DYN_ARRAY<SUMMARY_VALUE>*
00406 sv_callee,
00407 SUMMARY_CALLSITE* cs)
00408 {
00409 if (ipan_caller->Has_Recursive_In_Edge())
00410 return FALSE;
00411 SUMMARY_PROCEDURE* sp_callee = ipan_callee->Summary_Proc();
00412 for (INT i = 0; i <= sv_callee->Lastidx(); i++) {
00413 SUMMARY_VALUE* svv = &(*sv_callee)[i];
00414 if (svv->Is_formal()) {
00415 INT formal_index = svv->Get_formal_index();
00416 FmtAssert(formal_index >= 0,
00417 ("IPA_EX_Can_Evaluate_At_Callsite: Expecting nonnegative formal idx"));
00418 INT actual_index = cs->Get_actual_index() + formal_index;
00419 FmtAssert(actual_index >= 0,
00420 ("IPA_EX_Can_Evaluate_At_Callsite: Expecting nonnegative actual idx"));
00421 SUMMARY_ACTUAL* sa = IPA_get_actual_array(ipan_caller) + actual_index;
00422 FmtAssert(sa != NULL,
00423 ("IPA_EX_Can_Evaluate_At_Callsite: NULL SUMMARY_ACTUAL"));
00424 if (sa->Get_value_index() == -1)
00425 return FALSE;
00426 SUMMARY_VALUE* sv = IPA_get_value_array(ipan_caller)
00427 + sa->Get_value_index();
00428 if (!sv->Is_int_const() && !sv->Is_const_st() && !sv->Is_formal()
00429 && !sv->Is_expr())
00430 return FALSE;
00431 if (sv->Is_expr() && !IPA_EX_Value_Expr_Tree(ipan_caller, sv))
00432 return FALSE;
00433 }
00434 }
00435 return TRUE;
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445 static void IPA_EX_Evaluate_At_Callsite(IPA_NODE* ipan_caller,
00446 IPA_NODE* ipan_callee,
00447 DYN_ARRAY<SUMMARY_VALUE>* sv_callee,
00448 DYN_ARRAY<SUMMARY_EXPR>* sx_callee,
00449 SUMMARY_CALLSITE* cs)
00450 {
00451 SUMMARY_PROCEDURE* sp_callee = ipan_callee->Summary_Proc();
00452 INT original_value_count = sv_callee->Lastidx() + 1;
00453 for (INT i = 0; i < original_value_count; i++) {
00454 SUMMARY_VALUE* svv = &(*sv_callee)[i];
00455 if (svv->Is_int_const() || svv->Is_two_consts() || svv->Is_const_st())
00456 continue;
00457 if (svv->Is_formal()) {
00458 INT formal_index = svv->Get_formal_index();
00459 INT actual_index = cs->Get_actual_index() + formal_index;
00460 SUMMARY_ACTUAL* sa = IPA_get_actual_array(ipan_caller) + actual_index;
00461 SUMMARY_VALUE* sv = sa->Get_value_index() == -1 ? NULL
00462 : IPA_get_value_array(ipan_caller) + sa->Get_value_index();
00463 FmtAssert(sv != NULL,
00464 ("IPA_EX_Evaluate_At_Callsite: Expecting SUMMARY_VALUE index"));
00465 if (sv->Is_int_const()) {
00466 svv->Set_int_const();
00467 svv->Set_int_const_value(sv->Get_int_const_value());
00468 } else if (sv->Is_const_st()) {
00469 INT64 int_value = -1;
00470 if (St_Idx_Is_Intconst(sv->Get_const_st_idx(), &int_value)) {
00471 svv->Set_int_const();
00472 svv->Set_int_const_value(int_value);
00473 } else {
00474 svv->Set_const_st();
00475 svv->Set_const_st_idx(sv->Get_const_st_idx());
00476 }
00477 } else if (sv->Is_formal()) {
00478 SUMMARY_PROCEDURE* sp_caller = ipan_caller->Summary_Proc();
00479 INT base_caller_formal = sp_caller->Get_formal_index();
00480 INT new_formal_index = sv->Get_formal_index() - base_caller_formal;
00481 svv->Set_formal_index(new_formal_index);
00482 } else if (sv->Is_expr()) {
00483 SUMMARY_VALUE* sv_from = IPA_get_value_array(ipan_caller);
00484 SUMMARY_EXPR* sx_from = IPA_get_expr_array(ipan_caller);
00485 INT expr_index = IPA_EX_Copy_Expr_Tree(ipan_caller, sv_from, sx_from,
00486 sv_callee, sx_callee, sv->Get_expr_index());
00487 SUMMARY_EXPR* sxx = &(*sx_callee)[expr_index];
00488 sxx->Set_is_trip_count();
00489 } else if (sv->Is_global()) {
00490 Fail_FmtAssertion("VALUE_GLOBALs not supported in execution costs");
00491 } else {
00492 FmtAssert(FALSE,
00493 ("IPA_EX_Evaluate_At_Callsite: Not expecting other VALUE types"));
00494 }
00495 } else if (!svv->Is_global()) {
00496 FmtAssert(FALSE,
00497 ("IPA_EX_Evaluate_At_Callsite: Not expecting other VALUE types"));
00498 }
00499 }
00500 }
00501
00502
00503
00504
00505
00506
00507
00508 static void IPL_EX_Replace_Value_With_Expr(DYN_ARRAY<SUMMARY_EXPR>* sx,
00509 INT value_index,
00510 INT expr_index)
00511 {
00512 for (INT i = 0; i <= sx->Lastidx(); i++) {
00513 SUMMARY_EXPR* sxx = &(*sx)[i];
00514 if (sxx->Is_expr_value(0) && sxx->Get_node_index(0) == value_index) {
00515 sxx->Set_expr_expr(0);
00516 sxx->Set_node_index(0, expr_index);
00517 }
00518 if (sxx->Is_expr_value(1) && sxx->Get_node_index(1) == value_index) {
00519 sxx->Set_expr_expr(1);
00520 sxx->Set_node_index(1, expr_index);
00521 }
00522 }
00523 }
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533 static void IPL_EX_Substitute(DYN_ARRAY<SUMMARY_VALUE>* sv_caller,
00534 DYN_ARRAY<SUMMARY_EXPR>* sx_caller,
00535 DYN_ARRAY<SUMMARY_VALUE>* sv_callee,
00536 DYN_ARRAY<SUMMARY_EXPR>* sx_callee,
00537 INT caller_value_index,
00538 MEM_POOL* mem_pool)
00539 {
00540 if (sv_callee->Lastidx() == -1 && sx_callee->Lastidx() == -1) {
00541 SUMMARY_VALUE* svv = &(*sv_caller)[caller_value_index];
00542 svv->Set_int_const();
00543 svv->Set_int_const_value(DEFAULT_CALL_COST);
00544 svv->Set_mtype(MTYPE_I4);
00545 svv->Clear_is_addr_of();
00546 svv->Clear_is_trip_count();
00547 } else {
00548 INT i;
00549
00550 DYN_ARRAY<SUMMARY_VALUE> sv_result(mem_pool);
00551 DYN_ARRAY<SUMMARY_EXPR> sx_result(mem_pool);
00552
00553 for (i = 0; i <= sv_callee->Lastidx(); i++) {
00554 SUMMARY_VALUE* svv = &(*sv_callee)[i];
00555 sv_result.AddElement(*svv);
00556 }
00557
00558 for (i = 0; i <= sx_callee->Lastidx(); i++) {
00559 SUMMARY_EXPR* sxx = &(*sx_callee)[i];
00560 sx_result.AddElement(*sxx);
00561 }
00562
00563 INT value_offset = sv_callee->Lastidx() + 1;
00564 INT expr_offset = sx_callee->Lastidx() + 1;
00565 IPL_EX_Add_Expr_Offsets(sx_caller, value_offset, expr_offset);
00566
00567 for (i = 0; i <= sv_caller->Lastidx(); i++) {
00568 SUMMARY_VALUE* svv = &(*sv_caller)[i];
00569 sv_result.AddElement(*svv);
00570 }
00571
00572 for (i = 0; i <= sx_caller->Lastidx(); i++) {
00573 SUMMARY_EXPR* sxx = &(*sx_caller)[i];
00574 sx_result.AddElement(*sxx);
00575 }
00576
00577 INT callsite_expr_index = sx_callee->Lastidx();
00578 INT new_caller_value_index = caller_value_index + value_offset;
00579
00580 IPL_EX_Replace_Value_With_Expr(&sx_result, new_caller_value_index,
00581 callsite_expr_index);
00582 IPL_EX_Eliminate_Value(&sv_result, &sx_result, new_caller_value_index);
00583 sv_caller->Resetidx();
00584 sx_caller->Resetidx();
00585
00586 for (i = 0; i <= sv_result.Lastidx(); i++)
00587 sv_caller->AddElement(sv_result[i]);
00588
00589 for (i = 0; i <= sx_result.Lastidx(); i++)
00590 sx_caller->AddElement(sx_result[i]);
00591 }
00592 }
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602 static void IPL_EX_Remove_Calls(DYN_ARRAY<SUMMARY_VALUE>* sv,
00603 DYN_ARRAY<SUMMARY_EXPR>* sx)
00604 {
00605 for (INT i = sv->Lastidx(); i >= 0; i--) {
00606 SUMMARY_VALUE* svv = &(*sv)[i];
00607 if (svv->Is_callsite()) {
00608 INT64 constant_value = DEFAULT_CALL_COST;
00609 INT sv_index = IPL_EX_New_Constant(sv, constant_value);
00610 INT sx_index = IPL_EX_New_Value_Expr(sx, sv_index);
00611 IPL_EX_Replace_Value_With_Expr(sx, i, sx_index);
00612 }
00613 }
00614 }
00615
00616
00617
00618
00619
00620
00621
00622 extern BOOL Merge_Execution_Cost(IPA_NODE* ipan_caller,
00623 MEM_POOL* mem_pool)
00624 {
00625 if (Execution_Count_Evaluated(ipan_caller))
00626 return FALSE;
00627 BOOL change = FALSE;
00628 IPA_NODE_SECTION_INFO* si_caller = ipan_caller->Section_Annot();
00629 DYN_ARRAY<SUMMARY_VALUE>* sv_caller = si_caller->Get_value();
00630 DYN_ARRAY<SUMMARY_EXPR>* sx_caller = si_caller->Get_expr();
00631 if (Get_Trace(TP_IPA, IPA_TRACE_EXCOST)) {
00632 fprintf(stdout, "BEFORE SUBSTITUTION: \n");
00633 Print_Exprs(stdout, sv_caller, sx_caller);
00634 }
00635 IPA_SUCC_ITER edge_iter(IPA_Call_Graph, ipan_caller);
00636 for (edge_iter.First(); !edge_iter.Is_Empty(); edge_iter.Next()) {
00637 IPA_EDGE* ipa_edge = edge_iter.Current_Edge();
00638 if (ipa_edge == NULL)
00639 continue;
00640 IPA_NODE* ipan_callee = IPA_Call_Graph->Callee(ipa_edge);
00641 IPA_NODE_SECTION_INFO* si_callee = ipan_callee->Section_Annot();
00642 SUMMARY_CALLSITE* sc = ipa_edge->Summary_Callsite();
00643 if (!Execution_Count_Evaluated(ipan_callee))
00644 continue;
00645
00646 INT callsite_index = sc - IPA_get_callsite_array(ipan_caller);
00647 INT i;
00648
00649 for (i = 0; i <= sv_caller->Lastidx(); i++) {
00650 SUMMARY_VALUE* svv = &(*sv_caller)[i];
00651 if (svv->Is_callsite()
00652 && svv->Get_callsite_index() == callsite_index)
00653 break;
00654 }
00655 if (i > sv_caller->Lastidx())
00656 continue;
00657 change = TRUE;
00658 INT callsite_value_index = i;
00659 DYN_ARRAY<SUMMARY_VALUE>* sv_callee = si_callee->Get_value();
00660 DYN_ARRAY<SUMMARY_EXPR>* sx_callee = si_callee->Get_expr();
00661
00662 DYN_ARRAY<SUMMARY_VALUE>* sv_callee_copy
00663 = CXX_NEW(DYN_ARRAY<SUMMARY_VALUE>(mem_pool), mem_pool);
00664 for (i = 0; i <= sv_callee->Lastidx(); i++) {
00665 SUMMARY_VALUE* svv_callee = &(*sv_callee)[i];
00666 sv_callee_copy->AddElement(*svv_callee);
00667 }
00668 DYN_ARRAY<SUMMARY_EXPR>* sx_callee_copy
00669 = CXX_NEW(DYN_ARRAY<SUMMARY_EXPR>(mem_pool), mem_pool);
00670 for (i = 0; i <= sx_callee->Lastidx(); i++) {
00671 SUMMARY_EXPR* sxx_callee = &(*sx_callee)[i];
00672 sx_callee_copy->AddElement(*sxx_callee);
00673 }
00674 if (IPA_EX_Can_Evaluate_At_Callsite(ipan_caller, ipan_callee,
00675 sv_callee_copy, sc)) {
00676
00677 IPA_EX_Evaluate_At_Callsite(ipan_caller, ipan_callee,
00678 sv_callee_copy, sx_callee_copy, sc);
00679 } else {
00680
00681 IPL_EX_Collapse_Trip_Counts(sv_callee_copy, sx_callee_copy);
00682 }
00683 IPL_EX_Substitute(sv_caller, sx_caller, sv_callee_copy,
00684 sx_callee_copy, callsite_value_index, mem_pool);
00685 }
00686 IPL_EX_Remove_Calls(sv_caller, sx_caller);
00687 IPL_EX_Simplify(sv_caller, sx_caller);
00688 if (Get_Trace(TP_IPA, IPA_TRACE_EXCOST)) {
00689 fprintf(stdout, "AFTER SUBSTITUTION: \n");
00690 Print_Exprs(stdout, sv_caller, sx_caller);
00691 }
00692 return change;
00693 }