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