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 #ifdef USE_PCH
00084 #include "lno_pch.h"
00085 #endif // USE_PCH
00086 #pragma hdrstop
00087
00088 const static char *source_file = __FILE__;
00089 const static char *rcs_id = "$Source: be/lno/SCCS/s.sclrze.cxx $ $Revision: 1.7 $";
00090
00091 #include <sys/types.h>
00092 #include "lnopt_main.h"
00093 #include "dep_graph.h"
00094 #include "lwn_util.h"
00095 #include "opt_du.h"
00096 #include "reduc.h"
00097 #include "sclrze.h"
00098 #include "lnoutils.h"
00099
00100 static void Process_Store(WN *, VINDEX16 , ARRAY_DIRECTED_GRAPH16 *, BOOL,
00101 BOOL, REDUCTION_MANAGER *red_manager);
00102 static BOOL Dominates(WN *wn1, WN *wn2);
00103 static BOOL Intervening_Write(INT,VINDEX16,
00104 VINDEX16 ,ARRAY_DIRECTED_GRAPH16 *);
00105 static BOOL Is_Invariant(ACCESS_ARRAY *store, WN *store_wn);
00106 static BOOL MP_Problem(WN *wn1, WN *wn2);
00107
00108 void Scalarize_Arrays(ARRAY_DIRECTED_GRAPH16 *dep_graph,
00109 BOOL do_variants, BOOL do_invariants, REDUCTION_MANAGER *red_manager)
00110 {
00111 if (Get_Trace(TP_LNOPT,TT_LNO_SCLRZE)) {
00112 fprintf(TFile,"Scalarizing arrays \n");
00113 }
00114
00115
00116 VINDEX16 v;
00117 for (v = dep_graph->Get_Vertex(); v; v = dep_graph->Get_Next_Vertex(v)) {
00118 WN *wn = dep_graph->Get_Wn(v);
00119 OPCODE opcode = WN_opcode(wn);
00120 if (OPCODE_is_store(opcode) && (WN_kid_count(wn) == 2)) {
00121 WN *array = WN_kid1(wn);
00122 if (WN_operator(array) == OPR_ARRAY) {
00123 WN *base = WN_array_base(array);
00124 OPERATOR base_oper = WN_operator(base);
00125 if ((base_oper == OPR_LDID) || (base_oper == OPR_LDA)) {
00126 ST *st = WN_st(base);
00127
00128 #ifdef _NEW_SYMTAB
00129 if (ST_level(st) == CURRENT_SYMTAB) {
00130 #else
00131 if (ST_symtab_id(st) == SYMTAB_id(Current_Symtab)) {
00132 #endif
00133 if (ST_sclass(st) == SCLASS_AUTO &&
00134 ST_base_idx(st) == ST_st_idx(st)) {
00135 if (!ST_has_nested_ref(st)) {
00136 Process_Store(wn,v,dep_graph,do_variants,do_invariants,
00137 red_manager);
00138 }
00139 }
00140 }
00141 }
00142 }
00143 }
00144 }
00145 }
00146
00147
00148 static void Process_Store(WN *store_wn, VINDEX16 v,
00149 ARRAY_DIRECTED_GRAPH16 *dep_graph, BOOL do_variants,
00150 BOOL do_invariants, REDUCTION_MANAGER *red_manager)
00151 {
00152 #ifdef TARG_X8664
00153
00154 if (MTYPE_is_vector(WN_desc(store_wn))) return;
00155 #endif
00156 #ifdef KEY // Bug 6162 - can not scalarize to MTYPE_M pregs.
00157 if (WN_desc(store_wn) == MTYPE_M) return;
00158 #endif
00159 if (Inside_Loop_With_Goto(store_wn)) return;
00160 INT debug = Get_Trace(TP_LNOPT,TT_LNO_SCLRZE);
00161
00162 BOOL scalarized_this_store = FALSE;
00163 WN_OFFSET preg_num=0;
00164 ST *preg_st=0;
00165 WN *preg_store = NULL;
00166
00167 ACCESS_ARRAY *store =
00168 (ACCESS_ARRAY *) WN_MAP_Get(LNO_Info_Map,WN_kid1(store_wn));
00169
00170 if (debug) {
00171 fprintf(TFile,"Processing the store ");
00172 store->Print(TFile);
00173 fprintf(TFile,"\n");
00174 }
00175
00176 BOOL is_invariant = Is_Invariant(store,store_wn);
00177 if (!do_variants && !is_invariant) {
00178 return;
00179 }
00180 if (!do_invariants && is_invariant) {
00181 return;
00182 }
00183
00184
00185 if (red_manager && (red_manager->Which_Reduction(store_wn) != RED_NONE)) {
00186 return;
00187 }
00188
00189 char preg_name[20];
00190 TYPE_ID store_type = WN_desc(store_wn);
00191 TYPE_ID type = Promote_Type(store_type);
00192
00193 EINDEX16 e,next_e=0;
00194 for (e = dep_graph->Get_Out_Edge(v); e; e=next_e) {
00195 next_e = dep_graph->Get_Next_Out_Edge(e);
00196 VINDEX16 sink = dep_graph->Get_Sink(e);
00197 WN *load_wn = dep_graph->Get_Wn(sink);
00198 OPCODE opcode = WN_opcode(load_wn);
00199 if (OPCODE_is_load(opcode)) {
00200 if (OPCODE_operator(opcode) != OPR_LDID) {
00201 ACCESS_ARRAY *load = (ACCESS_ARRAY *)
00202 WN_MAP_Get(LNO_Info_Map,WN_kid0(load_wn));
00203 if (WN_operator(WN_kid0(load_wn)) == OPR_ARRAY &&
00204 Equivalent_Access_Arrays(store,load,store_wn,load_wn) &&
00205 (DEPV_COMPUTE::Base_Test(store_wn,NULL,load_wn,NULL) ==
00206 DEP_CONTINUE)
00207 #ifdef KEY
00208 &&
00209
00210 WN_field_id(store_wn)==WN_field_id(load_wn)
00211 #endif
00212 ) {
00213 if (Dominates(store_wn,load_wn)) {
00214 if (!red_manager ||
00215 (red_manager->Which_Reduction(store_wn) == RED_NONE)) {
00216 if (!Intervening_Write(dep_graph->Depv_Array(e)->Max_Level(),
00217 v,sink,dep_graph)) {
00218 if (!MP_Problem(store_wn,load_wn)) {
00219 if (!scalarized_this_store) {
00220 if (debug) {
00221 fprintf(TFile,"Scalarizing the load ");
00222 load->Print(TFile);
00223 fprintf(TFile,"\n");
00224 }
00225
00226 preg_st = MTYPE_To_PREG(type);
00227 char *array_name =
00228 ST_name(WN_st(WN_array_base(WN_kid1(store_wn))));
00229 INT length = strlen(array_name);
00230 if (length < 18) {
00231 strcpy(preg_name,array_name);
00232 preg_name[length] = '_';
00233 preg_name[length+1] = '1';
00234 preg_name[length+2] = 0;
00235 #ifdef _NEW_SYMTAB
00236 preg_num = Create_Preg(type,preg_name);
00237 } else {
00238 preg_num = Create_Preg(type, NULL);
00239 }
00240 #else
00241 preg_num = Create_Preg(type,preg_name, NULL);
00242 } else {
00243 preg_num = Create_Preg(type, NULL, NULL);
00244 }
00245 #endif
00246
00247 OPCODE preg_s_opcode = OPCODE_make_op(OPR_STID,MTYPE_V,type);
00248
00249 WN *wn_value = WN_kid0(store_wn);
00250 if (MTYPE_byte_size(store_type) < MTYPE_byte_size(type))
00251 wn_value = LWN_Int_Type_Conversion(wn_value, store_type);
00252 preg_store = LWN_CreateStid(preg_s_opcode,preg_num,
00253 preg_st, Be_Type_Tbl(type),wn_value);
00254 WN_Set_Linenum(preg_store,WN_Get_Linenum(store_wn));
00255 LWN_Copy_Frequency_Tree(preg_store,store_wn);
00256 LWN_Insert_Block_Before(LWN_Get_Parent(store_wn),
00257 store_wn,preg_store);
00258 OPCODE preg_l_opcode = OPCODE_make_op(OPR_LDID, type,type);
00259 WN *preg_load = WN_CreateLdid(preg_l_opcode,preg_num,
00260 preg_st, Be_Type_Tbl(type));
00261 LWN_Copy_Frequency(preg_load,store_wn);
00262 WN_kid0(store_wn) = preg_load;
00263 LWN_Set_Parent(preg_load,store_wn);
00264
00265 Du_Mgr->Add_Def_Use(preg_store,preg_load);
00266 }
00267 scalarized_this_store = TRUE;
00268
00269
00270 WN *new_load = WN_CreateLdid(OPCODE_make_op(OPR_LDID,
00271 type,type),preg_num,preg_st,Be_Type_Tbl(type));
00272 LWN_Copy_Frequency_Tree(new_load,load_wn);
00273
00274 WN *parent = LWN_Get_Parent(load_wn);
00275 for (INT i = 0; i < WN_kid_count(parent); i++) {
00276 if (WN_kid(parent,i) == load_wn) {
00277 WN_kid(parent,i) = new_load;
00278 LWN_Set_Parent(new_load,parent);
00279 LWN_Delete_Tree(load_wn);
00280 break;
00281 }
00282 }
00283
00284
00285 Du_Mgr->Add_Def_Use(preg_store,new_load);
00286 }
00287 }
00288 }
00289 }
00290 }
00291 }
00292 }
00293 }
00294 }
00295
00296
00297
00298 static BOOL Dominates(WN *wn1, WN *wn2)
00299 {
00300 Is_True(!OPCODE_is_expression(WN_opcode(wn1)),
00301 ("Non statement 1 in Dominates"));
00302
00303
00304 WN *parent1 = LWN_Get_Parent(wn1);
00305 WN *ancestor2 = LWN_Get_Parent(wn2);
00306 WN *kid2 = wn2;
00307 while (ancestor2 && (ancestor2 != parent1)) {
00308 kid2 = ancestor2;
00309 ancestor2 = LWN_Get_Parent(ancestor2);
00310 }
00311 if (!ancestor2) return FALSE;
00312
00313
00314
00315
00316 wn1 = WN_next(wn1);
00317 while (wn1) {
00318 if (wn1 == kid2) {
00319 return TRUE;
00320 }
00321 wn1 = WN_next(wn1);
00322 }
00323 return FALSE;
00324 }
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 static BOOL Intervening_Write(INT level,VINDEX16 store_v,
00338 VINDEX16 load_v,ARRAY_DIRECTED_GRAPH16 *dep_graph)
00339 {
00340 EINDEX16 e;
00341 for (e=dep_graph->Get_In_Edge(load_v); e; e=dep_graph->Get_Next_In_Edge(e)) {
00342 INT level2 = dep_graph->Depv_Array(e)->Max_Level();
00343 if (level2 > level) {
00344 return TRUE;
00345 } else if (level2 == level) {
00346 VINDEX16 store2_v = dep_graph->Get_Source(e);
00347 EINDEX16 store_store_edge = dep_graph->Get_Edge(store_v,store2_v);
00348 if (store_store_edge) {
00349 INT store_store_level =
00350 dep_graph->Depv_Array(store_store_edge)->Max_Level();
00351 if (store_store_level >= level) {
00352 return TRUE;
00353 }
00354 }
00355 }
00356 }
00357 return FALSE;
00358 }
00359
00360
00361 static BOOL Is_Invariant(ACCESS_ARRAY *store, WN *store_wn)
00362 {
00363
00364 WN *wn = LWN_Get_Parent(store_wn);
00365 while (WN_opcode(wn) != OPC_DO_LOOP) {
00366 wn = LWN_Get_Parent(wn);
00367 }
00368 DO_LOOP_INFO *dli = Get_Do_Loop_Info(wn);
00369 INT depth = dli->Depth;
00370 if (store->Too_Messy || (store->Non_Const_Loops() > depth)) {
00371 return FALSE;
00372 }
00373
00374 for (INT i=0; i<store->Num_Vec(); i++) {
00375 ACCESS_VECTOR *av = store->Dim(i);
00376 if (av->Too_Messy || av->Loop_Coeff(depth)) {
00377 return FALSE;
00378 }
00379 }
00380 return TRUE;
00381 }
00382
00383
00384 static BOOL MP_Problem(WN *wn1, WN *wn2)
00385 {
00386 if (Contains_MP) {
00387 WN *mp1 = LWN_Get_Parent(wn1);
00388 while (mp1 && (!Is_Mp_Region(mp1)) &&
00389 ((WN_opcode(mp1) != OPC_DO_LOOP) || !Do_Loop_Is_Mp(mp1))) {
00390 mp1 = LWN_Get_Parent(mp1);
00391 }
00392 WN *mp2 = LWN_Get_Parent(wn2);
00393 while (mp2 && (!Is_Mp_Region(mp2)) &&
00394 ((WN_opcode(mp2) != OPC_DO_LOOP) || !Do_Loop_Is_Mp(mp2))) {
00395 mp2 = LWN_Get_Parent(mp2);
00396 }
00397 if ((mp1 || mp2) && (mp1 != mp2)) return TRUE;
00398 }
00399 return FALSE;
00400 }