Open64 (mfef90, whirl2f, and IR tools)  TAG: version-openad; SVN changeset: 916
ipa_cost_util.cxx
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines