00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084 #ifdef USE_PCH
00085 #include "lno_pch.h"
00086 #endif // USE_PCH
00087 #pragma hdrstop
00088
00089 static const char *source_file = __FILE__;
00090 static const char *rcs_id = "$Source: be/lno/SCCS/s.dead.cxx $ $Revision: 1.5 $";
00091
00092 #include <sys/types.h>
00093 #include "lnopt_main.h"
00094 #include "dep_graph.h"
00095 #include "lwn_util.h"
00096 #include "opt_du.h"
00097 #include "dead.h"
00098 #include "lnoutils.h"
00099
00100 static BOOL Dominates_and_Reverse_Postdominates(WN *wn1, WN *wn2);
00101 static BOOL Intervening_Ref(INT, VINDEX16, VINDEX16 ,ARRAY_DIRECTED_GRAPH16 *);
00102
00103
00104
00105 static BOOL Vertex_Is_In_Expr(WN* wn_tree,
00106 VINDEX16 vertex,
00107 ARRAY_DIRECTED_GRAPH16* dg)
00108 {
00109 if (dg->Get_Vertex(wn_tree) == vertex)
00110 return TRUE;
00111 for (INT i = 0; i < WN_kid_count(wn_tree); i++)
00112 if (Vertex_Is_In_Expr(WN_kid(wn_tree, i), vertex, dg))
00113 return TRUE;
00114 return FALSE;
00115 }
00116
00117 void Dead_Store_Eliminate_Arrays(ARRAY_DIRECTED_GRAPH16 *dep_graph)
00118 {
00119 if (Get_Trace(TP_LNOPT,TT_LNO_DEAD)) {
00120 fprintf(TFile,"Dead Store Eliminating Arrays\n");
00121 }
00122
00123
00124 VINDEX16 v,next_v=0;
00125 for (v = dep_graph->Get_Vertex(); v; v = next_v) {
00126 next_v = dep_graph->Get_Next_Vertex(v);
00127 WN *wn = dep_graph->Get_Wn(v);
00128 OPCODE opcode = WN_opcode(wn);
00129 if (OPCODE_is_store(opcode) && (WN_kid_count(wn) == 2)) {
00130 WN *array = WN_kid1(wn);
00131 if (WN_operator(array) == OPR_ARRAY) {
00132 WN *base = WN_array_base(array);
00133 OPERATOR base_oper = WN_operator(base);
00134 if ((base_oper == OPR_LDID) || (base_oper == OPR_LDA)) {
00135 while (next_v != 0 && Vertex_Is_In_Expr(wn, next_v, dep_graph))
00136 next_v = dep_graph->Get_Next_Vertex(next_v);
00137 Process_Store(wn,v,dep_graph);
00138 }
00139 }
00140 }
00141 }
00142 }
00143
00144
00145
00146 extern void Process_Store(WN *store_wn, VINDEX16 v,
00147 ARRAY_DIRECTED_GRAPH16 *dep_graph)
00148 {
00149 if (Inside_Loop_With_Goto(store_wn)) return;
00150 INT debug = Get_Trace(TP_LNOPT,TT_LNO_DEAD);
00151
00152 WN_OFFSET preg_num=0;
00153 ST *preg_st=0;
00154 WN *preg_store = NULL;
00155
00156 ACCESS_ARRAY *store =
00157 (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,WN_kid1(store_wn));
00158 #ifdef KEY //bug 5970: see explanation below
00159 if(!store) return;
00160 #endif
00161 if (debug) {
00162 fprintf(TFile,"Processing the store ");
00163 store->Print(TFile);
00164 fprintf(TFile,"\n");
00165 }
00166
00167 char preg_name[20];
00168 TYPE_ID type = WN_desc(store_wn);
00169
00170 EINDEX16 e,next_e=0;
00171 for (e = dep_graph->Get_Out_Edge(v); e; e=next_e) {
00172 next_e = dep_graph->Get_Next_Out_Edge(e);
00173 VINDEX16 sink = dep_graph->Get_Sink(e);
00174 WN *store2_wn = dep_graph->Get_Wn(sink);
00175 OPCODE opcode = WN_opcode(store2_wn);
00176 if (OPCODE_is_store(opcode) && (store2_wn != store_wn)) {
00177 if (OPCODE_operator(opcode) != OPR_STID) {
00178 ACCESS_ARRAY *store2 = (ACCESS_ARRAY *)
00179 WN_MAP_Get(LNO_Info_Map,WN_kid1(store2_wn));
00180 #ifdef KEY
00181
00182
00183
00184 if (!store2) continue;
00185 #endif
00186 if (Equivalent_Access_Arrays(store,store2,store_wn,store2_wn) &&
00187 (WN_offset(store_wn) == WN_offset(store2_wn)) &&
00188 (DEPV_COMPUTE::Base_Test(store_wn,NULL,store2_wn,NULL) ==
00189 DEP_CONTINUE)) {
00190 if (Dominates_and_Reverse_Postdominates(store_wn,store2_wn)) {
00191 if (!Intervening_Ref(dep_graph->Depv_Array(e)->Max_Level(),
00192 v,sink,dep_graph)) {
00193 if (debug) {
00194 fprintf(TFile,"Removing the store");
00195 store->Print(TFile);
00196 fprintf(TFile,"\n");
00197 }
00198 LWN_Delete_Tree(store_wn);
00199 return;
00200 }
00201 } else {
00202 WN *grandparent = LWN_Get_Parent(LWN_Get_Parent(store2_wn));
00203 if ((WN_opcode(grandparent) == OPC_IF) &&
00204 Dominates_and_Reverse_Postdominates(store_wn,grandparent)) {
00205 if (!Intervening_Ref(dep_graph->Depv_Array(e)->Max_Level(),
00206 v,sink,dep_graph)) {
00207 if (debug) {
00208 fprintf(TFile,"Partial dead store eliminating ");
00209 store->Print(TFile);
00210 fprintf(TFile,"\n");
00211 }
00212
00213 BOOL in_then =
00214 (LWN_Get_Parent(store2_wn) == WN_then(grandparent));
00215
00216
00217 preg_st = MTYPE_To_PREG(type);
00218 char *array_name =
00219 ST_name(WN_st(WN_array_base(WN_kid1(store_wn))));
00220 INT length = strlen(array_name);
00221 if (length < 18) {
00222 strcpy(preg_name,array_name);
00223 preg_name[length] = '_';
00224 preg_name[length+1] = '1';
00225 preg_name[length+2] = 0;
00226 #ifdef _NEW_SYMTAB
00227 preg_num = Create_Preg(type,preg_name);
00228 } else {
00229 preg_num = Create_Preg(type, NULL);
00230 }
00231 #else
00232 preg_num = Create_Preg(type,preg_name, NULL);
00233 } else {
00234 preg_num = Create_Preg(type, NULL, NULL);
00235 }
00236 #endif
00237
00238
00239 OPCODE preg_s_opcode = OPCODE_make_op(OPR_STID,MTYPE_V,type);
00240 preg_store = LWN_CreateStid(preg_s_opcode,preg_num,
00241 preg_st, Be_Type_Tbl(type),WN_kid0(store_wn));
00242 WN_Set_Linenum(preg_store,WN_Get_Linenum(store_wn));
00243 LWN_Insert_Block_Before(LWN_Get_Parent(store_wn),
00244 store_wn,preg_store);
00245
00246
00247 OPCODE preg_l_opcode = OPCODE_make_op(OPR_LDID,
00248 Promote_Type(type),type);
00249 WN *preg_load = WN_CreateLdid(preg_l_opcode,preg_num,
00250 preg_st, Be_Type_Tbl(type));
00251 WN_kid0(store_wn) = preg_load;
00252 LWN_Set_Parent(preg_load,store_wn);
00253 LWN_Extract_From_Block(store_wn);
00254 if (in_then) {
00255 LWN_Insert_Block_After(WN_else(grandparent),NULL,store_wn);
00256 } else {
00257 LWN_Insert_Block_After(WN_then(grandparent),NULL,store_wn);
00258 }
00259 Du_Mgr->Add_Def_Use(preg_store,preg_load);
00260
00261 return;
00262 }
00263 }
00264 }
00265 }
00266 }
00267 }
00268 }
00269 }
00270
00271
00272
00273
00274
00275 static BOOL Dominates_and_Reverse_Postdominates(WN *wn1, WN *wn2)
00276 {
00277 Is_True(!OPCODE_is_expression(WN_opcode(wn1)),
00278 ("Non statement 1 in Dominates"));
00279 Is_True(!OPCODE_is_expression(WN_opcode(wn2)),
00280 ("Non statement 2 in Dominates"));
00281
00282
00283 if (LWN_Get_Parent(wn1) != LWN_Get_Parent(wn2)) {
00284 return FALSE;
00285 }
00286
00287
00288 WN *tmp = WN_next(wn1);
00289 while (tmp && (tmp != wn2)) tmp = WN_next(tmp);
00290 return (tmp == wn2);
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304 static BOOL Intervening_Ref(INT level, VINDEX16 store1_v,
00305 VINDEX16 store2_v,ARRAY_DIRECTED_GRAPH16 *dep_graph)
00306 {
00307 EINDEX16 e;
00308 for (e=dep_graph->Get_In_Edge(store2_v);e;e=dep_graph->Get_Next_In_Edge(e)) {
00309 INT level2 = dep_graph->Depv_Array(e)->Max_Level();
00310 if (level2 > level) {
00311 return TRUE;
00312 } else if (level2 == level) {
00313 VINDEX16 ref_v = dep_graph->Get_Source(e);
00314 EINDEX16 ref_store_edge = dep_graph->Get_Edge(store1_v,ref_v);
00315 if (ref_store_edge) {
00316 INT ref_store_level =
00317 dep_graph->Depv_Array(ref_store_edge)->Max_Level();
00318 if (ref_store_level >= level) {
00319 return TRUE;
00320 }
00321 }
00322 }
00323 }
00324 return FALSE;
00325 }
00326