Open64 (mfef90, whirl2f, and IR tools)
TAG: version-openad; SVN changeset: 916
|
00001 /* 00002 00003 Copyright (C) 2000, 2001 Silicon Graphics, Inc. All Rights Reserved. 00004 00005 This program is free software; you can redistribute it and/or modify it 00006 under the terms of version 2 of the GNU General Public License as 00007 published by the Free Software Foundation. 00008 00009 This program is distributed in the hope that it would be useful, but 00010 WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00012 00013 Further, this software is distributed without any warranty that it is 00014 free of the rightful claim of any third person regarding infringement 00015 or the like. Any license provided herein, whether implied or 00016 otherwise, applies only to this software file. Patent licenses, if 00017 any, provided herein do not apply to combinations of this program with 00018 other software, or any other product whatsoever. 00019 00020 You should have received a copy of the GNU General Public License along 00021 with this program; if not, write the Free Software Foundation, Inc., 59 00022 Temple Place - Suite 330, Boston MA 02111-1307, USA. 00023 00024 Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pky, 00025 Mountain View, CA 94043, or: 00026 00027 http://www.sgi.com 00028 00029 For further information regarding this notice, see: 00030 00031 http://oss.sgi.com/projects/GenInfo/NoticeExplan 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 // Forward declaration. 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 // NAME: IPL_EX_New_Constant 00062 // FUNCTION: Add a new integer constant of value 'constant_value' to 'sv'. 00063 // Return the index of the newly created VALUE. 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 // NAME: IPL_EX_New_Value_Expr 00081 // FUNCTION: Create a new EXPR in 'sx' which has the value of 'sv_index' 00082 // in the corresponding DYN_ARRAY<SUMMARY_VALUE>. Return the index of 00083 // the newly created EXPR. 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 // NAME: IPL_EX_New_Expr_Expr 00105 // FUNCTION: Create a new EXPR which applies the operator 'opr' to the 00106 // EXPRs at indices 'sx_index_one' and 'sx_index_two'. Return the 00107 // index of the newly created EXPR. 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 // NAME: IPL_EX_Copy_Value 00132 // FUNCTION: Create a new VALUE for 'sv' which is a copy of the 00133 // 'sv_old_index'th VALUE in 'sv'. Return the index of the newly created 00134 // VALUE. 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 // NAME: IPL_EX_Copy_Expr 00149 // FUNCTION: Create a new EXPR for 'sx' which is a copy of the 00150 // 'sx_old_index'th EXPR in 'sx'. Return the index of the newly created 00151 // EXPR. 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 // NAME: IPL_EX_Set_Expr_Index 00166 // FUNCTION: Create either a new VALUE or a new EXPR as appropriate which 00167 // is a copy of the 'kid'th part of the 'sx_old_index'th EXPR in the 00168 // ('sv','sx') pair. Return the index of the newly added VALUE or EXPR. 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 // NAME: IPL_EX_Copy_Expr_Tree 00194 // FUNCTION: Copy the 'sx_old_index'th EXPR in the ('sv','sx') pair. 00195 // Return the index of the newly created EXPR in 'sx'. 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 // NAME: SUMMARY_EXPR::Equal 00224 // FUNCTION: Return TRUE if the SUMMARY_VALUE 'this' is equal to the 00225 // SUMMARY_VALUE 'sv'. Return FALSE otherwise. 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 // NAME: SUMMARY_EXPR::Equal_Node 00289 // FUNCTION: Return TRUE if the 'kid'th part of the SUMMARY_EXPR 'this' 00290 // is equal to the 'kid'th part of SUMMARY_EXPR 'sx'. Return FALSE 00291 // otherwise. 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 // NAME: SUMMARY_EXPR::Equal 00312 // FUNCTION: Return TRUE if the SUMMARY_EXPR 'this' is equal to the 00313 // SUMMARY_EXPR 'sx'. Return FALSE otherwise. 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 // NAME: Substitute_Expr 00346 // FUNCTION: Substitute the EXPR index 'expr_new_index' for the EXPR index 00347 // 'expr_old_index' in 'sx'. 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 // NAME: Eliminate_Expr 00374 // FUNCTION: Eliminate all occurrences of 'expr_index' in 'sx'. 00375 // NOTE: Shrink the 'sx' appropriately. 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 // NAME: Substitute_Expr_Value 00407 // FUNCTION: Substitute all occurrences of EXPR index 'expr_old_index' 00408 // with VALUE index 'value_new_index' in the pair ('sv','sx'). 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 // NAME: Substitute_Value 00442 // FUNCTION: Substitute all occurrences of VALUE index 'old_value_index' 00443 // with VALUE index 'new_value_index' in the pair ('sv','sx'). 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 // NAME: IPL_EX_Eliminate_Value 00466 // FUNCTION: Eliminate all occurrences of the VALUE index 'value_index' 00467 // for the pair ('sv','sx'), shrinking the size of 'sv' and 'sx' 00468 // appropriately. 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 // NAME: IPL_EXS_Sort_Exprs 00503 // FUNCTION: Sort the EXPRs in 'sx' so that each EXPR refers only to 00504 // EXPRs whose indices are lower valued than itself. 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 // NAME: IPL_EXS_Too_Complicated 00587 // FUNCTION: Return TRUE if the number of VALUEs or the number of EXPRs 00588 // in the ('sv','sx') pair are greater than 'multiplier' times as many 00589 // as the (MAX_VALUE_COUNT, MAX_EXPR_COUNT). 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 // NAME: IPL_EXS_Chop_Down_Estimate 00602 // FUNCTION: Replace the ('sv','sx') pair with a single constant estimate 00603 // which is the square of DEFAULT_TRIP_COUNT. 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 // NAME: Find_Useless_Exprs_Traverse 00619 // FUNCTION: Search the pair ('sv','sx') starting at EXPR index 'expr_index' 00620 // At the end of the seach, 'sv_used[i]' is TRUE if the i-th VALUE is 00621 // used in the 'expr_index'th EXPR and 'sx_used[i]' is TRUE if the i-th 00622 // VALUE is used in the 'expr_index'th EXPR. Otherwise, these bits are 00623 // set to FALSE. 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 // NAME: Find_Useless_Exprs 00661 // FUNCTION: Search the pair ('sv','sx') for useless expressions. Set 00662 // 'sv_used[i]' to TRUE if the i-th VALUE in 'sv' is used. Set 00663 // 'sx_used[i]' to TRUE if the i-th EXPR in 'sx' is used. Otherwise, 00664 // set these bits to FALSE. 00665 // NOTE: The cost value respresented by the pair ('sv','sx') is repre- 00666 // sented by the highest index entry in 'sx'. 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 // NAME: IPL_EXS_Useless 00681 // FUNCTION: Remove all of the useless expressions and values in the 00682 // ('sv','sx') pair. 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 // NAME: IPL_EX_Value_Evaluate 00719 // FUNCTION: If the 'sv_index'th VALUE in 'sv' evaluates to a constant, 00720 // return the value of that constant. Otherwise, set 'valid' to FALSE 00721 // and return -1. 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 // NAME: IPL_EX_Expr_Evaluate 00743 // FUNCTION: If the 'sx_index'th EXPR in the pair ('sv','sx') evaluates 00744 // to a constant, return the value of that constant. Otherwise, set 00745 // 'valid' to FALSE and return -1. 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 // NAME: IPL_EX_Reassociate 00808 // FUNCTION: Simplify the pair ('sv','sx') by reassociating expressions 00809 // of the form (sx + value1) + value2 to get sx + (value1 + value2). 00810 // Also change (sx - value1) + value2 to sx + (value2 - value1), and 00811 // apply other similar used reassociations. 00812 // NOTE: This is particularly useful because many trip count expressions 00813 // initially look like (N - 1) + 1. 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 // NAME: IPL_EXS_Outer_Fold 00907 // FUNCTION: Simplify the pair ('sv','sx') by replacing EXPRs which 00908 // evaluate to a constant VALUE with a canonical expr (VALUE + 0). 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 // NAME: IPL_EXS_Eliminate_Duplicate_Values 00998 // FUNCTION: Simplify 'sv' by replacing VALUEs which are equal to one 00999 // another with a single canonical representative, and eliminating the 01000 // non-canonical versions. 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 // NAME: IPL_EXS_Eliminate_Duplicate_Exprs 01028 // FUNCTION: Simplify 'sx' by replacing EXPRs which are equal to 01029 // one another with a single canonical representative, and eliminating 01030 // the non-canonical versions. 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 // NAME: IPL_EX_Inner_Fold 01058 // FUNCTION: Simplify the ('sv','sx') pair by folding the values of 01059 // expressions that have constant value into the constant field of 01060 // expressions. 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 // NAME: IPL_EXS_Eliminate_Expr_Identities 01130 // FUNCTION: Simplify the pair ('sv','sx') by applying the identities: 01131 // sxx + 0 == sxx, 0 + sxx == sxx, sxx - 0 == sxx, sxx * 1 == sxx, 01132 // 1 * sxx == sxx, sxx / 1 == sxx. 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 // NAME: IPL_EX_Collapse_Trip_Counts 01182 // FUNCTION: Replace each reference to a trip count in the ('sv','sx') 01183 // with a DEFAULT_TRIP_COUNT constant value. 01184 // NOTE: This is generally done when the expressions get too complicated 01185 // or can't otherwise be evaluated. 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 // NAME: IPL_EX_Simplify 01230 // FUNCTION: Apply a number of simple optimizations to reduce the size 01231 // of the pair ('sv','sx'). 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 // Sort out of order expressions 01248 IPL_EXS_Sort_Exprs(sv, sx); 01249 // Mark and eliminate useless values and expressions 01250 IPL_EXS_Useless(sv, sx); 01251 #ifdef Is_True_On 01252 Check_Exprs(sv, sx, stdout); 01253 #endif 01254 // Reassociate constants, grouping them together 01255 IPL_EXS_Reassociate(sv, sx); 01256 // Fold together "const" OPR "const" 01257 IPL_EXS_Outer_Fold(sv, sx); 01258 // Eliminate duplicate SUMMARY_VALUEs 01259 IPL_EXS_Eliminate_Duplicate_Values(sv, sx); 01260 // Eliminate duplicate SUMMARY_EXPRs 01261 IPL_EXS_Eliminate_Duplicate_Exprs(sv, sx); 01262 // Fold constants into expressions 01263 IPL_EXS_Inner_Fold(sv, sx); 01264 // Eliminate useless identity exprs 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 // NAME: IPL_EX_Add_Value_Offsets 01273 // FUNCTION: Adjust the indices in 'sv' by adding 'formal_offset' to each 01274 // FORMAL index and 'global_offset' to each GLOBAL index. 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 // NAME: IPL_EX_Add_Expr_Offsets 01292 // FUNCTION: Adjust the indices in 'sx' by adding 'value_offset' to each 01293 // VALUE index and 'expr_offset' to each EXPR index. 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 // NAME: Print_Exprs 01325 // FUNCTION: Print a representation of the pair ('sv','sx') to the file 01326 // 'fp'. 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 // NAME: Check_Trip_Counts_Traverse 01348 // FUNCTION: Check the EXPR at index 'expr_index' in the pair ('sv','sx') 01349 // by setting 'sv_used[i]' to TRUE if it is used in the expression 01350 // and setting 'sx_used[i]' to TRUE if it is used in the expression. 01351 // Set these bits to FALSE otherwise. 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 // NAME: Check_Trip_Counts 01393 // FUNCTION: Check the pair ('sv','sx') for trip count errors. Print 01394 // errors to the file 'fp'. Return the number of errors found. 01395 // NOTE: An error here is any VALUE which is not either (1) constant, 01396 // (2) representing a callsite, or (3) part of a trip count. 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 // NAME: Check_Exprs 01440 // FUNCTION: Check the integrity of the pair ('sv','sx'). Print error 01441 // messages to the file 'fp'. Return the number of errors found. 01442 // NOTE: The errors we are looking for are VALUE or EXPR indices which 01443 // are out of range and trip count errors as defined in Check_Trip_Counts(). 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