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 <elf.h>
00037 #include <sys/elf_whirl.h>
00038 #include <sys/types.h>
00039 #include "defs.h"
00040 #include "mtypes.h"
00041 #include "access_vector.h"
00042 #include "ipl_lno_util.h"
00043 #include "ipl_summary.h"
00044 #include <alloca.h>
00045 #include "ipa_cost_util.h"
00046 #include "be_util.h"
00047
00048 #ifdef IPA_SUMMARY
00049 #include "ipl_summary.h"
00050 #else
00051 #include "ipa_trace.h"
00052 #endif
00053
00054
00055
00056 static INT IPL_EX_Copy_Expr_Tree(DYN_ARRAY<SUMMARY_VALUE>* sv,
00057 DYN_ARRAY<SUMMARY_EXPR>* sx,
00058 INT sx_old_index);
00059
00060
00061
00062
00063
00064
00065
00066 extern INT IPL_EX_New_Constant(DYN_ARRAY<SUMMARY_VALUE>* sv,
00067 INT64 constant_value)
00068 {
00069 INT sv_index = sv->Newidx();
00070 SUMMARY_VALUE* svv = &(*sv)[sv_index];
00071 svv->Set_int_const();
00072 svv->Set_int_const_value(constant_value);
00073 svv->Set_mtype(MTYPE_I4);
00074 svv->Clear_is_addr_of();
00075 svv->Clear_is_trip_count();
00076 return sv_index;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086 extern INT IPL_EX_New_Value_Expr(DYN_ARRAY<SUMMARY_EXPR>* sx,
00087 INT sv_index)
00088 {
00089 INT index = sx->Newidx();
00090 SUMMARY_EXPR* sxx = &(*sx)[index];
00091 sxx->Clear_is_trip_count();
00092 sxx->Set_has_const_operand();
00093 sxx->Set_const_value((INT64) 0);
00094 TYPE_ID type = MTYPE_I4;
00095 OPCODE opcode = OPCODE_make_op(OPR_ADD, type, MTYPE_V);
00096 sxx->Set_opcode(opcode);
00097 sxx->Set_expr_value(0);
00098 sxx->Set_node_index(0, sv_index);
00099 sxx->Set_mtype(type);
00100 return index;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110 extern INT IPL_EX_New_Expr_Expr(DYN_ARRAY<SUMMARY_EXPR>* sx,
00111 OPERATOR opr,
00112 INT sx_index_one,
00113 INT sx_index_two)
00114 {
00115 INT index = sx->Newidx();
00116 SUMMARY_EXPR* sxx = &(*sx)[index];
00117 sxx->Clear_is_trip_count();
00118 sxx->Clear_has_const_operand();
00119 TYPE_ID type = MTYPE_I4;
00120 OPCODE opcode = OPCODE_make_op(opr, type, MTYPE_V);
00121 sxx->Set_opcode(opcode);
00122 sxx->Set_expr_expr(0);
00123 sxx->Set_expr_expr(1);
00124 sxx->Set_node_index(0, sx_index_one);
00125 sxx->Set_node_index(1, sx_index_two);
00126 sxx->Set_mtype(type);
00127 return index;
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137 static INT IPL_EX_Copy_Value(DYN_ARRAY<SUMMARY_VALUE>* sv,
00138 INT sv_old_index)
00139 {
00140 INT sv_new_index = sv->Newidx();
00141 SUMMARY_VALUE* svv_old = &(*sv)[sv_old_index];
00142 SUMMARY_VALUE* svv_new = &(*sv)[sv_new_index];
00143 bcopy(svv_old, svv_new, sizeof(SUMMARY_VALUE));
00144 return sv_new_index;
00145 }
00146
00147
00148
00149
00150
00151
00152
00153
00154 static INT IPL_EX_Copy_Expr(DYN_ARRAY<SUMMARY_EXPR>* sx,
00155 INT sx_old_index)
00156 {
00157 INT sx_new_index = sx->Newidx();
00158 SUMMARY_EXPR* sxx_old = &(*sx)[sx_old_index];
00159 SUMMARY_EXPR* sxx_new = &(*sx)[sx_new_index];
00160 bcopy(sxx_old, sxx_new, sizeof(SUMMARY_EXPR));
00161 return sx_new_index;
00162 }
00163
00164
00165
00166
00167
00168
00169
00170
00171 static INT IPL_EX_Set_Expr_Index(DYN_ARRAY<SUMMARY_VALUE>* sv,
00172 DYN_ARRAY<SUMMARY_EXPR>* sx,
00173 INT sx_old_index,
00174 INT kid)
00175 {
00176 SUMMARY_EXPR* sxx_old = &(*sx)[sx_old_index];
00177 if (sxx_old->Is_expr_value(kid)) {
00178 INT sv_old_index = sxx_old->Get_node_index(kid);
00179 INT sv_new_index = IPL_EX_Copy_Value(sv, sv_old_index);
00180 return sv_new_index;
00181 } else if (sxx_old->Is_expr_expr(kid)) {
00182 INT sxx_old_index = sxx_old->Get_node_index(kid);
00183 INT sxx_new_index = IPL_EX_Copy_Expr_Tree(sv, sx, sxx_old_index);
00184 return sxx_new_index;
00185 } else {
00186 FmtAssert(FALSE,
00187 ("IPL_EX_Set_Expr_Index: Not handling this case yet"));
00188 return -1;
00189 }
00190 }
00191
00192
00193
00194
00195
00196
00197
00198 static INT IPL_EX_Copy_Expr_Tree(DYN_ARRAY<SUMMARY_VALUE>* sv,
00199 DYN_ARRAY<SUMMARY_EXPR>* sx,
00200 INT sx_old_index)
00201 {
00202 SUMMARY_EXPR* sxx_old = &(*sx)[sx_old_index];
00203 INT sx_expr_one = -1;
00204 INT sx_expr_two = -1;
00205 INT sx_new_index = -1;
00206 if (sxx_old->Has_const_operand()) {
00207 sx_expr_one = IPL_EX_Set_Expr_Index(sv, sx, sx_old_index, 0);
00208 sx_new_index = IPL_EX_Copy_Expr(sx, sx_old_index);
00209 SUMMARY_EXPR* sxx_new = &(*sx)[sx_new_index];
00210 sxx_new->Set_node_index(0, sx_expr_one);
00211 } else {
00212 sx_expr_one = IPL_EX_Set_Expr_Index(sv, sx, sx_old_index, 0);
00213 sx_expr_two = IPL_EX_Set_Expr_Index(sv, sx, sx_old_index, 1);
00214 sx_new_index = IPL_EX_Copy_Expr(sx, sx_old_index);
00215 SUMMARY_EXPR* sxx_new = &(*sx)[sx_new_index];
00216 sxx_new->Set_node_index(0, sx_expr_one);
00217 sxx_new->Set_node_index(1, sx_expr_two);
00218 }
00219 return sx_new_index;
00220 }
00221
00222
00223
00224
00225
00226
00227
00228 BOOL SUMMARY_VALUE::Equal(SUMMARY_VALUE* sv)
00229 {
00230 if (Get_mtype() != sv->Get_mtype())
00231 return FALSE;
00232 if (Target_mtype() != sv->Target_mtype())
00233 return FALSE;
00234 if (Get_const_type() != sv->Get_const_type())
00235 return FALSE;
00236 if (Is_int_const()) {
00237 if (Get_int_const_value() != sv->Get_int_const_value())
00238 return FALSE;
00239 } else if (Is_two_consts()) {
00240 if (Get_first_of_two_values() != sv->Get_first_of_two_values())
00241 return FALSE;
00242 if (Get_second_of_two_values() != sv->Get_second_of_two_values())
00243 return FALSE;
00244 } else if (Is_const_st()) {
00245 if (Get_const_st_idx() != sv->Get_const_st_idx())
00246 return FALSE;
00247 if (Get_tcon_idx() != sv->Get_tcon_idx())
00248 return FALSE;
00249 } else if (Is_formal()) {
00250 if (Get_formal_index() != sv->Get_formal_index())
00251 return FALSE;
00252 } else if (Is_global()) {
00253 if (Is_global_st_idx()) {
00254 if (Get_global_st_idx() != sv->Get_global_st_idx())
00255 return FALSE;
00256 } else {
00257 if (Get_global_index() != sv->Get_global_index())
00258 return FALSE;
00259 if (Get_global_index() == -1) {
00260 if (Get_global_st_idx() != sv->Get_global_st_idx())
00261 return FALSE;
00262 }
00263 }
00264 } else if (Is_symbol()) {
00265 if (Get_symbol_index() != sv->Get_symbol_index())
00266 return FALSE;
00267 } else if (Is_expr()) {
00268 if (Get_expr_index() != sv->Get_expr_index())
00269 return FALSE;
00270 } else if (Is_phi()) {
00271 if (Get_phi_index() != sv->Get_phi_index())
00272 return FALSE;
00273 } else if (Is_chi()) {
00274 if (Get_chi_index() != sv->Get_chi_index())
00275 return FALSE;
00276 } else if (Is_callsite()) {
00277 if (Get_callsite_index() != sv->Get_callsite_index())
00278 return FALSE;
00279 }
00280 if (Is_remove_param() != sv->Is_remove_param())
00281 return FALSE;
00282 if (Is_convertible_to_global() != sv->Is_convertible_to_global())
00283 return FALSE;
00284 return TRUE;
00285 }
00286
00287
00288
00289
00290
00291
00292
00293
00294 BOOL SUMMARY_EXPR::Equal_Node(INT kid,
00295 SUMMARY_EXPR* sx)
00296 {
00297 if (Is_expr_value(kid) != sx->Is_expr_value(kid))
00298 return FALSE;
00299 if (Is_expr_phi(kid) != sx->Is_expr_phi(kid))
00300 return FALSE;
00301 if (Is_expr_expr(kid) != sx->Is_expr_expr(kid))
00302 return FALSE;
00303 if (Is_expr_chi(kid) != sx->Is_expr_chi(kid))
00304 return FALSE;
00305 if (Get_node_index(kid) != sx->Get_node_index(kid))
00306 return FALSE;
00307 return TRUE;
00308 }
00309
00310
00311
00312
00313
00314
00315
00316 BOOL SUMMARY_EXPR::Equal(SUMMARY_EXPR* sx)
00317 {
00318 if (Has_const_operand() != sx->Has_const_operand())
00319 return FALSE;
00320 if (Is_trip_count() != sx->Is_trip_count())
00321 return FALSE;
00322 if (Get_kid() != sx->Get_kid())
00323 return FALSE;
00324 if (Is_expr_unknown() != sx->Is_expr_unknown())
00325 return FALSE;
00326 if (Get_mtype() != sx->Get_mtype())
00327 return FALSE;
00328 if (Get_opcode() != sx->Get_opcode())
00329 return FALSE;
00330 if (Has_const_operand()) {
00331 if (!Equal_Node(0, sx))
00332 return FALSE;
00333 if (Get_const_value() != sx->Get_const_value())
00334 return FALSE;
00335 } else {
00336 if (!Equal_Node(0, sx))
00337 return FALSE;
00338 if (!Equal_Node(1, sx))
00339 return FALSE;
00340 }
00341 return TRUE;
00342 }
00343
00344
00345
00346
00347
00348
00349
00350 static void Substitute_Expr(DYN_ARRAY<SUMMARY_EXPR>* sx,
00351 INT expr_old_index,
00352 INT expr_new_index)
00353 {
00354 SUMMARY_EXPR* sxx_old = &(*sx)[expr_old_index];
00355 SUMMARY_EXPR* sxx_new = &(*sx)[expr_new_index];
00356 if (sxx_old->Is_trip_count())
00357 sxx_new->Set_is_trip_count();
00358 for (INT i = 0; i <= sx->Lastidx(); i++) {
00359 SUMMARY_EXPR* sxx = &(*sx)[i];
00360 if (sxx->Has_const_operand()) {
00361 if (sxx->Is_expr_expr(0) && sxx->Get_node_index(0) == expr_old_index)
00362 sxx->Set_node_index(0, expr_new_index);
00363 } else {
00364 if (sxx->Is_expr_expr(0) && sxx->Get_node_index(0) == expr_old_index)
00365 sxx->Set_node_index(0, expr_new_index);
00366 if (sxx->Is_expr_expr(1) && sxx->Get_node_index(1) == expr_old_index)
00367 sxx->Set_node_index(1, expr_new_index);
00368 }
00369 }
00370 }
00371
00372
00373
00374
00375
00376
00377
00378 static void Eliminate_Expr(DYN_ARRAY<SUMMARY_EXPR>* sx,
00379 INT expr_index)
00380 {
00381 INT i;
00382
00383 for (i = 0; i <= sx->Lastidx(); i++) {
00384 SUMMARY_EXPR* sxx = &(*sx)[i];
00385 if (sxx->Has_const_operand()) {
00386 if (sxx->Is_expr_expr(0) && sxx->Get_node_index(0) > expr_index)
00387 sxx->Set_node_index(0, sxx->Get_node_index(0) - 1);
00388 } else {
00389 if (sxx->Is_expr_expr(0) && sxx->Get_node_index(0) > expr_index)
00390 sxx->Set_node_index(0, sxx->Get_node_index(0) - 1);
00391 if (sxx->Is_expr_expr(1) && sxx->Get_node_index(1) > expr_index)
00392 sxx->Set_node_index(1, sxx->Get_node_index(1) - 1);
00393 }
00394 }
00395
00396 for (i = expr_index + 1; i <= sx->Lastidx(); i++) {
00397 SUMMARY_EXPR* sxx_old = &(*sx)[i];
00398 SUMMARY_EXPR* sxx_new = &(*sx)[i-1];
00399 bcopy(sxx_old, sxx_new, sizeof(SUMMARY_EXPR));
00400 }
00401
00402 sx->Decidx();
00403 }
00404
00405
00406
00407
00408
00409
00410
00411 static void Substitute_Expr_Value(DYN_ARRAY<SUMMARY_VALUE>* sv,
00412 DYN_ARRAY<SUMMARY_EXPR>* sx,
00413 INT expr_old_index,
00414 INT value_new_index)
00415 {
00416 SUMMARY_EXPR* sxx = &(*sx)[expr_old_index];
00417 SUMMARY_VALUE* svv = &(*sv)[value_new_index];
00418 if (sxx->Is_trip_count())
00419 svv->Set_is_trip_count();
00420 for (INT i = 0; i <= sx->Lastidx(); i++) {
00421 SUMMARY_EXPR* sxx = &(*sx)[i];
00422 if (sxx->Has_const_operand()) {
00423 if (sxx->Is_expr_expr(0) && sxx->Get_node_index(0) == expr_old_index) {
00424 sxx->Set_expr_value(0);
00425 sxx->Set_node_index(0, value_new_index);
00426 }
00427 } else {
00428 if (sxx->Is_expr_expr(0) && sxx->Get_node_index(0) == expr_old_index) {
00429 sxx->Set_expr_value(0);
00430 sxx->Set_node_index(0, value_new_index);
00431 }
00432 if (sxx->Is_expr_expr(1) && sxx->Get_node_index(1) == expr_old_index) {
00433 sxx->Set_expr_value(1);
00434 sxx->Set_node_index(1, value_new_index);
00435 }
00436 }
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446 static void Substitute_Value(DYN_ARRAY<SUMMARY_VALUE>* sv,
00447 DYN_ARRAY<SUMMARY_EXPR>* sx,
00448 INT old_value_index,
00449 INT new_value_index)
00450 {
00451 SUMMARY_VALUE* svv_old = &(*sv)[old_value_index];
00452 SUMMARY_VALUE* svv_new = &(*sv)[new_value_index];
00453 if (svv_old->Is_trip_count())
00454 svv_new->Set_is_trip_count();
00455 for (INT i = 0; i <= sx->Lastidx(); i++) {
00456 SUMMARY_EXPR* sxx = &(*sx)[i];
00457 if (sxx->Is_expr_value(0) && sxx->Get_node_index(0) == old_value_index)
00458 sxx->Set_node_index(0, new_value_index);
00459 if (sxx->Is_expr_value(1) && sxx->Get_node_index(1) == old_value_index)
00460 sxx->Set_node_index(1, new_value_index);
00461 }
00462 }
00463
00464
00465
00466
00467
00468
00469
00470
00471 extern void IPL_EX_Eliminate_Value(DYN_ARRAY<SUMMARY_VALUE>* sv,
00472 DYN_ARRAY<SUMMARY_EXPR>* sx,
00473 INT value_index)
00474 {
00475 INT i;
00476
00477 for (i = value_index + 1; i <= sv->Lastidx(); i++) {
00478 SUMMARY_VALUE* svv_old = &(*sv)[i];
00479 SUMMARY_VALUE* svv_new = &(*sv)[i-1];
00480 bcopy(svv_old, svv_new, sizeof(SUMMARY_VALUE));
00481 }
00482
00483 sv->Decidx();
00484 for (i = 0; i <= sx->Lastidx(); i++) {
00485 SUMMARY_EXPR* sxx = &(*sx)[i];
00486 if (sxx->Has_const_operand()) {
00487 if (sxx->Is_expr_value(0))
00488 if (sxx->Get_node_index(0) > value_index)
00489 sxx->Set_node_index(0, sxx->Get_node_index(0) - 1);
00490 } else {
00491 if (sxx->Is_expr_value(0))
00492 if (sxx->Get_node_index(0) > value_index)
00493 sxx->Set_node_index(0, sxx->Get_node_index(0) - 1);
00494 if (sxx->Is_expr_value(1))
00495 if (sxx->Get_node_index(1) > value_index)
00496 sxx->Set_node_index(1, sxx->Get_node_index(1) - 1);
00497 }
00498 }
00499 }
00500
00501
00502
00503
00504
00505
00506
00507 static void IPL_EXS_Sort_Exprs(DYN_ARRAY<SUMMARY_VALUE>* sv,
00508 DYN_ARRAY<SUMMARY_EXPR>* sx)
00509 {
00510 #ifdef IPA_SUMMARY
00511 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
00512 #else
00513 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
00514 #endif
00515 fprintf(stdout, "BEFORE SORTING EXPRESSIONS: \n");
00516 Print_Exprs(stdout, sv, sx);
00517 }
00518
00519 INT index_count = sx->Lastidx() + 1;
00520 INT* new_index = (INT*) alloca(index_count * sizeof(INT));
00521 INT i;
00522
00523 for (i = 0; i <= sx->Lastidx(); i++)
00524 new_index[i] = -1;
00525
00526 INT new_value = 0;
00527 INT start_index = -1;
00528
00529 for (i = 0; i <= sx->Lastidx(); i++) {
00530 SUMMARY_EXPR* sxx = &(*sx)[i];
00531 if (sxx->Has_const_operand()) {
00532 if (!sxx->Is_expr_expr(0))
00533 new_index[i] = new_value++;
00534 } else {
00535 if (!sxx->Is_expr_expr(0) && !sxx->Is_expr_expr(1))
00536 new_index[i] = new_value++;
00537 }
00538 if (start_index == -1 && new_index[i] == -1)
00539 start_index = i;
00540 }
00541
00542 while (new_value < index_count) {
00543 INT my_start_index = start_index;
00544 start_index = -1;
00545 for (i = my_start_index; i <= sx->Lastidx(); i++) {
00546 if (new_index[i] == -1) {
00547 SUMMARY_EXPR* sxx = &(*sx)[i];
00548 if (sxx->Has_const_operand()) {
00549 if (sxx->Is_expr_expr(0)
00550 && new_index[sxx->Get_node_index(0)] != -1) {
00551 sxx->Set_node_index(0, new_index[sxx->Get_node_index(0)]);
00552 new_index[i] = new_value++;
00553 }
00554 } else {
00555 if ((!sxx->Is_expr_expr(0)
00556 || new_index[sxx->Get_node_index(0)] != -1)
00557 && (!sxx->Is_expr_expr(1)
00558 || new_index[sxx->Get_node_index(1)] != -1)) {
00559 if (sxx->Is_expr_expr(0))
00560 sxx->Set_node_index(0, new_index[sxx->Get_node_index(0)]);
00561 if (sxx->Is_expr_expr(1))
00562 sxx->Set_node_index(1, new_index[sxx->Get_node_index(1)]);
00563 new_index[i] = new_value++;
00564 }
00565 }
00566 if (start_index == -1 && new_index[i] == -1)
00567 start_index = i;
00568 }
00569 }
00570 }
00571
00572 SUMMARY_EXPR* new_exprs
00573 = (SUMMARY_EXPR*) alloca(index_count * sizeof(SUMMARY_EXPR));
00574
00575 for (i = 0; i <= sx->Lastidx(); i++) {
00576 SUMMARY_EXPR* sxx = &(*sx)[i];
00577 bcopy(sxx, &new_exprs[new_index[i]], sizeof(SUMMARY_EXPR));
00578 }
00579
00580 sx->Resetidx();
00581 for (i = 0; i < index_count; i++)
00582 sx->AddElement(new_exprs[i]);
00583 }
00584
00585
00586
00587
00588
00589
00590
00591
00592 extern BOOL IPL_EXS_Too_Complicated(DYN_ARRAY<SUMMARY_VALUE>* sv,
00593 DYN_ARRAY<SUMMARY_EXPR>* sx,
00594 INT multiplier)
00595 {
00596 return sv->Lastidx() + 1 > multiplier * MAX_VALUE_COUNT
00597 || sx->Lastidx() + 1 > multiplier * MAX_EXPR_COUNT;
00598 }
00599
00600
00601
00602
00603
00604
00605
00606 extern INT IPL_EXS_Chop_Down_Estimate(DYN_ARRAY<SUMMARY_VALUE>* sv,
00607 DYN_ARRAY<SUMMARY_EXPR>* sx)
00608 {
00609 sv->Resetidx();
00610 sx->Resetidx();
00611 INT64 constant_value = DEFAULT_TRIP_COUNT * DEFAULT_TRIP_COUNT;
00612 INT sv_index = IPL_EX_New_Constant(sv, constant_value);
00613 INT sx_index = IPL_EX_New_Value_Expr(sx, sv_index);
00614 return sx_index;
00615 }
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626 static void Find_Useless_Exprs_Traverse(INT expr_index,
00627 DYN_ARRAY<SUMMARY_VALUE>* sv,
00628 DYN_ARRAY<SUMMARY_EXPR>* sx,
00629 BOOL* sv_used,
00630 BOOL* sx_used)
00631 {
00632 SUMMARY_EXPR* sxx = &(*sx)[expr_index];
00633 if (sxx->Has_const_operand()) {
00634 if (sxx->Is_expr_value(0)) {
00635 sv_used[sxx->Get_node_index(0)] = TRUE;
00636 } else if (sxx->Is_expr_expr(0)) {
00637 sx_used[sxx->Get_node_index(0)] = TRUE;
00638 Find_Useless_Exprs_Traverse(sxx->Get_node_index(0),
00639 sv, sx, sv_used, sx_used);
00640 }
00641 } else {
00642 if (sxx->Is_expr_value(0)) {
00643 sv_used[sxx->Get_node_index(0)] = TRUE;
00644 } else if (sxx->Is_expr_expr(0)) {
00645 sx_used[sxx->Get_node_index(0)] = TRUE;
00646 Find_Useless_Exprs_Traverse(sxx->Get_node_index(0),
00647 sv, sx, sv_used, sx_used);
00648 }
00649 if (sxx->Is_expr_value(1)) {
00650 sv_used[sxx->Get_node_index(1)] = TRUE;
00651 } else if (sxx->Is_expr_expr(1)) {
00652 sx_used[sxx->Get_node_index(1)] = TRUE;
00653 Find_Useless_Exprs_Traverse(sxx->Get_node_index(1),
00654 sv, sx, sv_used, sx_used);
00655 }
00656 }
00657 }
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669 static void Find_Useless_Exprs(DYN_ARRAY<SUMMARY_VALUE>* sv,
00670 DYN_ARRAY<SUMMARY_EXPR>* sx,
00671 BOOL* sv_used,
00672 BOOL* sx_used)
00673 {
00674 INT expr_index = sx->Lastidx();
00675 sx_used[expr_index] = TRUE;
00676 Find_Useless_Exprs_Traverse(expr_index, sv, sx, sv_used, sx_used);
00677 }
00678
00679
00680
00681
00682
00683
00684
00685 static void IPL_EXS_Useless(DYN_ARRAY<SUMMARY_VALUE>* sv,
00686 DYN_ARRAY<SUMMARY_EXPR>* sx)
00687 {
00688 #ifdef IPA_SUMMARY
00689 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
00690 #else
00691 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
00692 #endif
00693 fprintf(stdout, "BEFORE USELESS EXPR ELIMINATION: \n");
00694 Print_Exprs(stdout, sv, sx);
00695 }
00696 BOOL* sv_used = (BOOL*) alloca((sv->Lastidx() + 1) * sizeof(BOOL));
00697 BOOL* sx_used = (BOOL*) alloca((sx->Lastidx() + 1) * sizeof(BOOL));
00698 INT i;
00699
00700 for (i = 0; i <= sv->Lastidx(); i++)
00701 sv_used[i] = FALSE;
00702
00703 for (i = 0; i <= sx->Lastidx(); i++)
00704 sx_used[i] = FALSE;
00705
00706 Find_Useless_Exprs(sv, sx, sv_used, sx_used);
00707
00708 for (i = sx->Lastidx(); i >= 0; i--)
00709 if (!sx_used[i])
00710 Eliminate_Expr(sx, i);
00711
00712 for (i = sv->Lastidx(); i >= 0; i--)
00713 if (!sv_used[i])
00714 IPL_EX_Eliminate_Value(sv, sx, i);
00715 }
00716
00717
00718
00719
00720
00721
00722
00723
00724 static INT64 IPL_EX_Value_Evaluate(DYN_ARRAY<SUMMARY_VALUE>* sv,
00725 INT sv_index,
00726 BOOL* valid)
00727 {
00728 SUMMARY_VALUE* svv = &(*sv)[sv_index];
00729 if (svv->Is_int_const())
00730 return svv->Get_int_const_value();
00731 if (svv->Is_const_st()) {
00732 INT64 value = -1;
00733 BOOL ok = St_Idx_Is_Intconst(svv->Get_const_st_idx(), &value);
00734 FmtAssert(ok, ("IPL_EX_Value_Evaluate: Expected INT int_const"));
00735 return value;
00736 }
00737 *valid = FALSE;
00738 return -1;
00739 }
00740
00741
00742
00743
00744
00745
00746
00747
00748 static INT64 IPL_EX_Expr_Evaluate(DYN_ARRAY<SUMMARY_VALUE>* sv,
00749 DYN_ARRAY<SUMMARY_EXPR>* sx,
00750 INT sx_index,
00751 BOOL* valid)
00752 {
00753 SUMMARY_EXPR* sxx = &(*sx)[sx_index];
00754 INT64 value_one = -1;
00755 INT64 value_two = -1;
00756 if (sxx->Has_const_operand()) {
00757 if (sxx->Is_expr_value(0)) {
00758 INT sv_index = sxx->Get_node_index(0);
00759 value_one = IPL_EX_Value_Evaluate(sv, sv_index, valid);
00760 value_two = sxx->Get_const_value();
00761 } else if (sxx->Is_expr_expr(0)) {
00762 INT sx_index = sxx->Get_node_index(0);
00763 value_one = IPL_EX_Expr_Evaluate(sv, sx, sx_index, valid);
00764 value_two = sxx->Get_const_value();
00765 } else {
00766 *valid = FALSE;
00767 return -1;
00768 }
00769 } else {
00770 if (sxx->Is_expr_value(0)) {
00771 INT sv_index = sxx->Get_node_index(0);
00772 value_one = IPL_EX_Value_Evaluate(sv, sv_index, valid);
00773 } else if (sxx->Is_expr_expr(0)) {
00774 INT sx_index = sxx->Get_node_index(0);
00775 value_one = IPL_EX_Expr_Evaluate(sv, sx, sx_index, valid);
00776 } else {
00777 *valid = FALSE;
00778 return -1;
00779 }
00780 if (sxx->Is_expr_value(1)) {
00781 INT sv_index = sxx->Get_node_index(1);
00782 value_two= IPL_EX_Value_Evaluate(sv, sv_index, valid);
00783 } else if (sxx->Is_expr_expr(1)) {
00784 INT sx_index = sxx->Get_node_index(1);
00785 value_two = IPL_EX_Expr_Evaluate(sv, sx, sx_index, valid);
00786 } else {
00787 *valid = FALSE;
00788 return -1;
00789 }
00790 }
00791 switch (OPCODE_operator(sxx->Get_opcode())) {
00792 case OPR_ADD:
00793 return value_one + value_two;
00794 case OPR_SUB:
00795 return value_one - value_two;
00796 case OPR_MPY:
00797 return value_one * value_two;
00798 case OPR_DIV:
00799 return value_one / value_two;
00800 default:
00801 *valid = FALSE;
00802 return -1;
00803 }
00804 }
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816 static void IPL_EXS_Reassociate(DYN_ARRAY<SUMMARY_VALUE>* sv,
00817 DYN_ARRAY<SUMMARY_EXPR>* sx)
00818 {
00819 #ifdef IPA_SUMMARY
00820 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
00821 #else
00822 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
00823 #endif
00824 fprintf(stdout, "BEFORE REASSOCIATION: \n");
00825 Print_Exprs(stdout, sv, sx);
00826 }
00827 for (INT i = 0; i <= sx->Lastidx(); i++) {
00828 INT expr_index_one = i;
00829 SUMMARY_EXPR* sxx_one = &(*sx)[expr_index_one];
00830 if (sxx_one->Has_const_operand() || !sxx_one->Is_expr_expr(0)
00831 || !sxx_one->Is_expr_expr(1))
00832 continue;
00833 if (OPCODE_operator(sxx_one->Get_opcode()) != OPR_ADD
00834 && OPCODE_operator(sxx_one->Get_opcode()) != OPR_SUB)
00835 continue;
00836 BOOL is_cst_left = TRUE;
00837 BOOL is_cst_right = TRUE;
00838 INT sx_left = sxx_one->Get_node_index(0);
00839 INT sx_right = sxx_one->Get_node_index(1);
00840 INT64 cst_left = IPL_EX_Expr_Evaluate(sv, sx, sx_left, &is_cst_left);
00841 INT64 cst_right = IPL_EX_Expr_Evaluate(sv, sx, sx_right, &is_cst_right);
00842 if (!is_cst_left && !is_cst_right || is_cst_left && is_cst_right)
00843 continue;
00844 sxx_one = &(*sx)[expr_index_one];
00845 INT64 constant_value = 0;
00846 SUMMARY_EXPR* sxx_two = NULL;
00847 INT sxx_two_index = -1;
00848 if (is_cst_left) {
00849 constant_value += OPCODE_operator(sxx_one->Get_opcode()) == OPR_ADD
00850 ? cst_left : -cst_left;
00851 sxx_two_index = sx_right;
00852 sxx_two = &(*sx)[sx_right];
00853 } else {
00854 constant_value += OPCODE_operator(sxx_one->Get_opcode()) == OPR_ADD
00855 ? cst_right : -cst_right;
00856 sxx_two_index = sx_left;
00857 sxx_two = &(*sx)[sx_left];
00858 }
00859 if (sxx_two->Has_const_operand() || !sxx_two->Is_expr_expr(0)
00860 || !sxx_two->Is_expr_expr(1))
00861 continue;
00862 if (OPCODE_operator(sxx_two->Get_opcode()) != OPR_ADD
00863 && OPCODE_operator(sxx_two->Get_opcode()) != OPR_SUB)
00864 continue;
00865 is_cst_left = TRUE;
00866 is_cst_right = TRUE;
00867 sx_left = sxx_two->Get_node_index(0);
00868 sx_right = sxx_two->Get_node_index(1);
00869 cst_left = IPL_EX_Expr_Evaluate(sv, sx, sx_left, &is_cst_left);
00870 cst_right = IPL_EX_Expr_Evaluate(sv, sx, sx_right, &is_cst_right);
00871 if (!is_cst_left && !is_cst_right || is_cst_left && is_cst_right)
00872 continue;
00873 sxx_two = &(*sx)[sxx_two_index];
00874 if (OPCODE_operator(sxx_two->Get_opcode()) == OPR_SUB && !is_cst_right)
00875 continue;
00876 INT sx_expr = -1;
00877 if (is_cst_left) {
00878 constant_value += OPCODE_operator(sxx_two->Get_opcode()) == OPR_ADD
00879 ? cst_left : -cst_left;
00880 sx_expr = sx_right;
00881 } else {
00882 constant_value += OPCODE_operator(sxx_two->Get_opcode()) == OPR_ADD
00883 ? cst_right : -cst_right;
00884 sx_expr = sx_left;
00885 }
00886 INT sx_expr_new = IPL_EX_Copy_Expr_Tree(sv, sx, sx_expr);
00887 INT sv_index = IPL_EX_New_Constant(sv, constant_value);
00888 INT sx_index = IPL_EX_New_Value_Expr(sx, sv_index);
00889 sxx_one = &(*sx)[expr_index_one];
00890 sxx_one->Set_node_index(0, sx_expr_new);
00891 sxx_one->Set_node_index(1, sx_index);
00892 if (IPL_EXS_Too_Complicated(sv, sx, 2)) {
00893 IPL_EXS_Sort_Exprs(sv, sx);
00894 IPL_EXS_Useless(sv, sx);
00895 if (IPL_EXS_Too_Complicated(sv, sx, 1)) {
00896 IPL_EXS_Chop_Down_Estimate(sv, sx);
00897 return;
00898 }
00899 }
00900 }
00901 IPL_EXS_Sort_Exprs(sv, sx);
00902 IPL_EXS_Useless(sv, sx);
00903 }
00904
00905
00906
00907
00908
00909
00910
00911 static void IPL_EXS_Outer_Fold(DYN_ARRAY<SUMMARY_VALUE>* sv,
00912 DYN_ARRAY<SUMMARY_EXPR>* sx)
00913 {
00914 #ifdef IPA_SUMMARY
00915 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
00916 #else
00917 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
00918 #endif
00919 fprintf(stdout, "BEFORE OUTER FOLDING: \n");
00920 Print_Exprs(stdout, sv, sx);
00921 }
00922 for (INT i = sx->Lastidx(); i >= 0; i--) {
00923 BOOL valid = TRUE;
00924 INT64 const_result = -1;
00925 SUMMARY_EXPR* sxx = &(*sx)[i];
00926 if ((*sx)[i].Has_const_operand()) {
00927 if ((*sx)[i].Is_expr_value(0)) {
00928 INT sv_index = (*sx)[i].Get_node_index(0);
00929 INT64 const_one = IPL_EX_Value_Evaluate(sv, sv_index, &valid);
00930 const_result = const_one + (*sx)[i].Get_const_value();
00931 } else if ((*sx)[i].Is_expr_expr(0)) {
00932 INT sx_index = (*sx)[i].Get_node_index(0);
00933 INT64 const_one = IPL_EX_Expr_Evaluate(sv, sx, sx_index, &valid);
00934 const_result = const_one + (*sx)[i].Get_const_value();
00935 }
00936 } else {
00937 INT64 const_one = -1;
00938 INT64 const_two = -1;
00939 if ((*sx)[i].Is_expr_value(0)) {
00940 INT sv_index = (*sx)[i].Get_node_index(0);
00941 const_one = IPL_EX_Value_Evaluate(sv, sv_index, &valid);
00942 } else if ((*sx)[i].Is_expr_expr(0)) {
00943 INT sx_index = (*sx)[i].Get_node_index(0);
00944 const_one = IPL_EX_Expr_Evaluate(sv, sx, sx_index, &valid);
00945 } else {
00946 valid = FALSE;
00947 }
00948 if (valid) {
00949 if ((*sx)[i].Is_expr_value(1)) {
00950 INT sv_index = (*sx)[i].Get_node_index(1);
00951 const_two = IPL_EX_Value_Evaluate(sv, sv_index, &valid);
00952 } else if ((*sx)[i].Is_expr_expr(1)) {
00953 INT sx_index = (*sx)[i].Get_node_index(1);
00954 const_two = IPL_EX_Expr_Evaluate(sv, sx, sx_index, &valid);
00955 } else {
00956 valid = FALSE;
00957 }
00958 if (valid) {
00959 switch (OPCODE_operator((*sx)[i].Get_opcode())) {
00960 case OPR_ADD:
00961 const_result = const_one + const_two;
00962 break;
00963 case OPR_SUB:
00964 const_result = const_one - const_two;
00965 break;
00966 case OPR_MPY:
00967 const_result = const_one * const_two;
00968 break;
00969 case OPR_DIV:
00970 const_result = const_one / const_two;
00971 break;
00972 default:
00973 FmtAssert(FALSE,
00974 ("IPL_EXS_Outer_Fold: Unexpected operator in SUMMARY_EXPR"));
00975 }
00976 }
00977 }
00978 }
00979 if (valid) {
00980 INT sv_index = IPL_EX_New_Constant(sv, const_result);
00981 (*sx)[i].Clear_is_trip_count();
00982 (*sx)[i].Set_has_const_operand();
00983 (*sx)[i].Set_const_value((INT64) 0);
00984 TYPE_ID type = MTYPE_I4;
00985 OPCODE opcode = OPCODE_make_op(OPR_ADD, type, MTYPE_V);
00986 (*sx)[i].Set_opcode(opcode);
00987 (*sx)[i].Set_expr_value(0);
00988 (*sx)[i].Set_node_index(0, sv_index);
00989 (*sx)[i].Set_mtype(type);
00990 }
00991 }
00992 IPL_EXS_Sort_Exprs(sv, sx);
00993 IPL_EXS_Useless(sv, sx);
00994 }
00995
00996
00997
00998
00999
01000
01001
01002
01003 static void IPL_EXS_Eliminate_Duplicate_Values(DYN_ARRAY<SUMMARY_VALUE>* sv,
01004 DYN_ARRAY<SUMMARY_EXPR>* sx)
01005 {
01006 #ifdef IPA_SUMMARY
01007 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
01008 #else
01009 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
01010 #endif
01011 fprintf(stdout, "BEFORE ELIMINATING DUPLICATE VALUES: \n");
01012 Print_Exprs(stdout, sv, sx);
01013 }
01014 for (INT i = 0; i <= sv->Lastidx(); i++) {
01015 SUMMARY_VALUE* sx_one = &(*sv)[i];
01016 for (INT j = i + 1; j <= sv->Lastidx(); j++) {
01017 SUMMARY_VALUE* sx_two = &(*sv)[j];
01018 if (sx_one->Equal(sx_two)) {
01019 Substitute_Value(sv, sx, j, i);
01020 IPL_EX_Eliminate_Value(sv, sx, j--);
01021 }
01022 }
01023 }
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033 static void IPL_EXS_Eliminate_Duplicate_Exprs(DYN_ARRAY<SUMMARY_VALUE>* sv,
01034 DYN_ARRAY<SUMMARY_EXPR>* sx)
01035 {
01036 #ifdef IPA_SUMMARY
01037 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
01038 #else
01039 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
01040 #endif
01041 fprintf(stdout, "BEFORE ELIMINATING DUPLICATE EXPRS: \n");
01042 Print_Exprs(stdout, sv, sx);
01043 }
01044 for (INT i = 0; i <= sx->Lastidx(); i++) {
01045 SUMMARY_EXPR* sx_one = &(*sx)[i];
01046 for (INT j = i + 1; j <= sx->Lastidx(); j++) {
01047 SUMMARY_EXPR* sx_two = &(*sx)[j];
01048 if (sx_one->Equal(sx_two)) {
01049 Substitute_Expr(sx, j, i);
01050 Eliminate_Expr(sx, j--);
01051 }
01052 }
01053 }
01054 }
01055
01056
01057
01058
01059
01060
01061
01062
01063 static void IPL_EXS_Inner_Fold(DYN_ARRAY<SUMMARY_VALUE>* sv,
01064 DYN_ARRAY<SUMMARY_EXPR>* sx)
01065 {
01066 #ifdef IPA_SUMMARY
01067 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
01068 #else
01069 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
01070 #endif
01071 fprintf(stdout, "BEFORE INNER FOLDING: \n");
01072 Print_Exprs(stdout, sv, sx);
01073 }
01074 for (INT i = sx->Lastidx(); i >= 0; i--) {
01075 if ((*sx)[i].Has_const_operand())
01076 continue;
01077 BOOL valid = TRUE;
01078 INT64 const_value = -1;
01079 if ((*sx)[i].Is_expr_value(0)) {
01080 INT sv_index = (*sx)[i].Get_node_index(0);
01081 const_value = IPL_EX_Value_Evaluate(sv, sv_index, &valid);
01082 } else if ((*sx)[i].Is_expr_expr(0)) {
01083 INT sx_index = (*sx)[i].Get_node_index(0);
01084 const_value = IPL_EX_Expr_Evaluate(sv, sx, sx_index, &valid);
01085 } else {
01086 valid = FALSE;
01087 }
01088 if (valid) {
01089 INT index = (*sx)[i].Get_node_index(1);
01090 BOOL expr_value = (*sx)[i].Is_expr_value(1);
01091 (*sx)[i].Set_has_const_operand();
01092 if (expr_value)
01093 (*sx)[i].Set_expr_value(0);
01094 else
01095 (*sx)[i].Set_expr_expr(0);
01096 (*sx)[i].Set_node_index(0, index);
01097 (*sx)[i].Set_const_value(const_value);
01098 continue;
01099 }
01100 valid = TRUE;
01101 const_value = -1;
01102 if ((*sx)[i].Is_expr_value(1)) {
01103 INT sv_index = (*sx)[i].Get_node_index(1);
01104 const_value = IPL_EX_Value_Evaluate(sv, sv_index, &valid);
01105 } else if ((*sx)[i].Is_expr_expr(1)) {
01106 INT sx_index = (*sx)[i].Get_node_index(1);
01107 const_value = IPL_EX_Expr_Evaluate(sv, sx, sx_index, &valid);
01108 } else {
01109 valid = FALSE;
01110 }
01111 if (valid) {
01112 INT index = (*sx)[i].Get_node_index(0);
01113 BOOL expr_value = (*sx)[i].Is_expr_value(0);
01114 (*sx)[i].Set_has_const_operand();
01115 if (expr_value)
01116 (*sx)[i].Set_expr_value(0);
01117 else
01118 (*sx)[i].Set_expr_expr(0);
01119 (*sx)[i].Set_node_index(0, index);
01120 (*sx)[i].Set_const_value(const_value);
01121 continue;
01122 }
01123 }
01124 IPL_EXS_Sort_Exprs(sv, sx);
01125 IPL_EXS_Useless(sv, sx);
01126 }
01127
01128
01129
01130
01131
01132
01133
01134
01135 static void IPL_EXS_Eliminate_Expr_Identities(DYN_ARRAY<SUMMARY_VALUE>* sv,
01136 DYN_ARRAY<SUMMARY_EXPR>* sx)
01137 {
01138 #ifdef IPA_SUMMARY
01139 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
01140 #else
01141 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
01142 #endif
01143 fprintf(stdout, "BEFORE ELIMINATING EXPR IDENTITIES: \n");
01144 Print_Exprs(stdout, sv, sx);
01145 }
01146 for (INT i = 0; i <= sx->Lastidx(); i++) {
01147 SUMMARY_EXPR* sxx = &(*sx)[i];
01148 if (!sxx->Has_const_operand()
01149 || !sxx->Is_expr_expr(0) && !sxx->Is_expr_value(0))
01150 continue;
01151 BOOL can_eliminate = FALSE;
01152 switch (OPCODE_operator(sxx->Get_opcode())) {
01153 case OPR_ADD:
01154 if (sxx->Get_const_value() == 0)
01155 can_eliminate = TRUE;
01156 break;
01157 case OPR_SUB:
01158 if (sxx->Get_const_value() == 0)
01159 can_eliminate = TRUE;
01160 break;
01161 case OPR_MPY:
01162 if (sxx->Get_const_value() == 1)
01163 can_eliminate = TRUE;
01164 break;
01165 case OPR_DIV:
01166 if (sxx->Get_const_value() == 1)
01167 can_eliminate = TRUE;
01168 break;
01169 }
01170 if (can_eliminate) {
01171 if (sxx->Is_expr_expr(0))
01172 Substitute_Expr(sx, i, sxx->Get_node_index(0));
01173 else if (sxx->Is_expr_value(0))
01174 Substitute_Expr_Value(sv, sx, i, sxx->Get_node_index(0));
01175 }
01176 }
01177 IPL_EXS_Useless(sv, sx);
01178 }
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188 extern void IPL_EX_Collapse_Trip_Counts(DYN_ARRAY<SUMMARY_VALUE>* sv,
01189 DYN_ARRAY<SUMMARY_EXPR>* sx)
01190 {
01191 INT i;
01192
01193 for (i = 0; i <= sv->Lastidx(); i++) {
01194 SUMMARY_VALUE* svv = &(*sv)[i];
01195 if (svv->Is_trip_count()) {
01196 svv->Set_int_const();
01197 svv->Set_int_const_value(DEFAULT_TRIP_COUNT);
01198 svv->Set_mtype(MTYPE_I4);
01199 svv->Clear_is_addr_of();
01200 svv->Clear_is_trip_count();
01201 }
01202 }
01203
01204 for (i = 0; i <= sx->Lastidx(); i++) {
01205 SUMMARY_EXPR* sxx = &(*sx)[i];
01206 if (sxx->Is_trip_count()) {
01207 INT sv_index = sv->Newidx();
01208 SUMMARY_VALUE* svv = &(*sv)[sv_index];
01209 svv->Set_int_const();
01210 svv->Set_int_const_value(DEFAULT_TRIP_COUNT);
01211 svv->Set_mtype(MTYPE_I4);
01212 svv->Clear_is_addr_of();
01213 svv->Clear_is_trip_count();
01214 sxx->Clear_is_trip_count();
01215 sxx->Set_has_const_operand();
01216 sxx->Set_const_value((INT64) 0);
01217 OPCODE opcode = OPCODE_make_op(OPR_ADD, MTYPE_I4, MTYPE_V);
01218 sxx->Set_opcode(opcode);
01219 sxx->Set_expr_value(0);
01220 sxx->Set_node_index(0, sv_index);
01221 sxx->Set_mtype(MTYPE_I4);
01222 }
01223 }
01224
01225 IPL_EXS_Useless(sv, sx);
01226 }
01227
01228
01229
01230
01231
01232
01233
01234 extern void IPL_EX_Simplify(DYN_ARRAY<SUMMARY_VALUE>* sv,
01235 DYN_ARRAY<SUMMARY_EXPR>* sx)
01236 {
01237 #ifdef IPA_SUMMARY
01238 if (Get_Trace(TP_IPL, TT_IPL_SIMPLIFY)) {
01239 #else
01240 if (Get_Trace(TP_IPA, IPA_TRACE_SIMPLIFY)) {
01241 #endif
01242 fprintf(stdout, "BEFORE SIMPLIFICATION: \n");
01243 Print_Exprs(stdout, sv, sx);
01244 }
01245 if (IPL_EXS_Too_Complicated(sv, sx, 1))
01246 IPL_EXS_Chop_Down_Estimate(sv, sx);
01247
01248 IPL_EXS_Sort_Exprs(sv, sx);
01249
01250 IPL_EXS_Useless(sv, sx);
01251 #ifdef Is_True_On
01252 Check_Exprs(sv, sx, stdout);
01253 #endif
01254
01255 IPL_EXS_Reassociate(sv, sx);
01256
01257 IPL_EXS_Outer_Fold(sv, sx);
01258
01259 IPL_EXS_Eliminate_Duplicate_Values(sv, sx);
01260
01261 IPL_EXS_Eliminate_Duplicate_Exprs(sv, sx);
01262
01263 IPL_EXS_Inner_Fold(sv, sx);
01264
01265 IPL_EXS_Eliminate_Expr_Identities(sv, sx);
01266 #ifdef Is_True_On
01267 Check_Exprs(sv, sx, stdout);
01268 #endif
01269 }
01270
01271
01272
01273
01274
01275
01276
01277 extern void IPL_EX_Add_Value_Offsets(DYN_ARRAY<SUMMARY_VALUE>* sv,
01278 INT formal_offset,
01279 INT global_offset)
01280 {
01281 for (INT i = 0; i <= sv->Lastidx(); i++) {
01282 SUMMARY_VALUE* svv = &(*sv)[i];
01283 if (svv->Is_formal())
01284 svv->Set_formal_index(formal_offset + svv->Get_formal_index());
01285 else if (svv->Is_global())
01286 svv->Set_global_index(global_offset + svv->Get_global_index());
01287 }
01288 }
01289
01290
01291
01292
01293
01294
01295
01296 extern void IPL_EX_Add_Expr_Offsets(DYN_ARRAY<SUMMARY_EXPR>* sx,
01297 INT value_offset,
01298 INT expr_offset)
01299 {
01300 for (INT i = 0; i <= sx->Lastidx(); i++) {
01301 SUMMARY_EXPR* sxx = &(*sx)[i];
01302 if (sxx->Has_const_operand()) {
01303 if (sxx->Is_expr_expr(0)) {
01304 sxx->Set_node_index(0, sxx->Get_node_index(0) + expr_offset);
01305 } else if (sxx->Is_expr_value(0)) {
01306 sxx->Set_node_index(0, sxx->Get_node_index(0) + value_offset);
01307 }
01308 } else {
01309 if (sxx->Is_expr_expr(0)) {
01310 sxx->Set_node_index(0, sxx->Get_node_index(0) + expr_offset);
01311 } else if (sxx->Is_expr_value(0)) {
01312 sxx->Set_node_index(0, sxx->Get_node_index(0) + value_offset);
01313 }
01314 if (sxx->Is_expr_expr(1)) {
01315 sxx->Set_node_index(1, sxx->Get_node_index(1) + expr_offset);
01316 } else if (sxx->Is_expr_value(1)) {
01317 sxx->Set_node_index(1, sxx->Get_node_index(1) + value_offset);
01318 }
01319 }
01320 }
01321 }
01322
01323
01324
01325
01326
01327
01328
01329 extern void Print_Exprs(FILE* fp,
01330 DYN_ARRAY<SUMMARY_VALUE>* sv,
01331 DYN_ARRAY<SUMMARY_EXPR>* sx)
01332 {
01333 INT i;
01334
01335 for (i = 0; i <= sv->Lastidx(); i++) {
01336 SUMMARY_VALUE* svv = &(*sv)[i];
01337 svv->WB_Print(fp, i);
01338 }
01339
01340 for (i = 0; i <= sx->Lastidx(); i++) {
01341 SUMMARY_EXPR* sxx = &(*sx)[i];
01342 sxx->WB_Print(fp, i);
01343 }
01344 }
01345
01346
01347
01348
01349
01350
01351
01352
01353
01354 static void Check_Trip_Counts_Traverse(DYN_ARRAY<SUMMARY_VALUE>* sv,
01355 DYN_ARRAY<SUMMARY_EXPR>* sx,
01356 BOOL sv_used[],
01357 BOOL sx_used[],
01358 INT expr_index)
01359 {
01360 sx_used[expr_index] = TRUE;
01361 SUMMARY_EXPR* sxx = &(*sx)[expr_index];
01362 if (sxx->Has_const_operand()) {
01363 if (sxx->Is_expr_value(0)) {
01364 INT node_index = sxx->Get_node_index(0);
01365 sv_used[node_index] = TRUE;
01366 } else if (sxx->Is_expr_expr(0)) {
01367 INT node_index = sxx->Get_node_index(0);
01368 sx_used[node_index] = TRUE;
01369 Check_Trip_Counts_Traverse(sv, sx, sv_used, sx_used, node_index);
01370 }
01371 } else {
01372 if (sxx->Is_expr_value(0)) {
01373 INT node_index = sxx->Get_node_index(0);
01374 sv_used[node_index] = TRUE;
01375 } else if (sxx->Is_expr_expr(0)) {
01376 INT node_index = sxx->Get_node_index(0);
01377 sx_used[node_index] = TRUE;
01378 Check_Trip_Counts_Traverse(sv, sx, sv_used, sx_used, node_index);
01379 }
01380 if (sxx->Is_expr_value(1)) {
01381 INT node_index = sxx->Get_node_index(1);
01382 sv_used[node_index] = TRUE;
01383 } else if (sxx->Is_expr_expr(1)) {
01384 INT node_index = sxx->Get_node_index(1);
01385 sx_used[node_index] = TRUE;
01386 Check_Trip_Counts_Traverse(sv, sx, sv_used, sx_used, node_index);
01387 }
01388 }
01389 }
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399 static INT Check_Trip_Counts(DYN_ARRAY<SUMMARY_VALUE>* sv,
01400 DYN_ARRAY<SUMMARY_EXPR>* sx,
01401 FILE* fp)
01402 {
01403 BOOL* sv_used = (BOOL*) alloca((sv->Lastidx() + 1) * sizeof(BOOL));
01404 BOOL* sx_used = (BOOL*) alloca((sx->Lastidx() + 1) * sizeof(BOOL));
01405 INT i;
01406
01407 for (i = 0; i <= sv->Lastidx() + 1; i++)
01408 sv_used[i] = FALSE;
01409
01410 for (i = 0; i <= sx->Lastidx() + 1; i++)
01411 sx_used[i] = FALSE;
01412
01413 for (i = 0; i <= sv->Lastidx(); i++) {
01414 SUMMARY_VALUE* svv = &(*sv)[i];
01415 if (svv->Is_trip_count())
01416 sv_used[i] = TRUE;
01417 }
01418
01419 for (i = 0; i <= sx->Lastidx(); i++) {
01420 SUMMARY_EXPR* sxx = &(*sx)[i];
01421 if (sxx->Is_trip_count()) {
01422 Check_Trip_Counts_Traverse(sv, sx, sv_used, sx_used, i);
01423 }
01424 }
01425
01426 INT error_count = 0;
01427 for (i = 0; i <= sv->Lastidx(); i++) {
01428 SUMMARY_VALUE* svv = &(*sv)[i];
01429 if (!svv->Is_int_const() && !svv->Is_const_st() && !svv->Is_callsite()
01430 && !sv_used[i]) {
01431 fprintf(fp, "VALUE[%d]: Not part of trip count\n", i);
01432 error_count++;
01433 }
01434 }
01435 return error_count;
01436 }
01437
01438
01439
01440
01441
01442
01443
01444
01445
01446 extern INT Check_Exprs(DYN_ARRAY<SUMMARY_VALUE>* sv,
01447 DYN_ARRAY<SUMMARY_EXPR>* sx,
01448 FILE* fp)
01449 {
01450 INT error_count = 0;
01451 INT sv_upper = sv->Lastidx();
01452 INT sx_upper = sx->Lastidx();
01453 for (INT i = 0; i <= sx->Lastidx(); i++) {
01454 SUMMARY_EXPR* sxx = &(*sx)[i];
01455 if (sxx->Is_expr_value(0))
01456 if (sxx->Get_node_index(0) < 0 || sxx->Get_node_index(0) > sv_upper) {
01457 fprintf(fp, "EXPR[%d]: EXPR[%d] INVALID \n",
01458 i, sxx->Get_node_index(0));
01459 error_count++;
01460 }
01461 if (sxx->Is_expr_value(1))
01462 if (sxx->Get_node_index(1) < 0 || sxx->Get_node_index(1) > sv_upper) {
01463 fprintf(fp, "EXPR[%d]: EXPR[%d] INVALID \n",
01464 i, sxx->Get_node_index(1));
01465 error_count++;
01466 }
01467 if (sxx->Is_expr_expr(0))
01468 if (sxx->Get_node_index(0) < 0 || sxx->Get_node_index(0) > sx_upper) {
01469 fprintf(fp, "EXPR[%d]: VALUE[%d] INVALID \n",
01470 i, sxx->Get_node_index(0));
01471 error_count++;
01472 }
01473 if (sxx->Is_expr_expr(1))
01474 if (sxx->Get_node_index(1) < 0 || sxx->Get_node_index(1) > sx_upper) {
01475 fprintf(fp, "EXPR[%d]: VALUE[%d] INVALID \n",
01476 i, sxx->Get_node_index(1));
01477 error_count++;
01478 }
01479 }
01480 error_count += Check_Trip_Counts(sv, sx, fp);
01481 return error_count;
01482 }
01483