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